summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/ia64/ia64/machdep.c9
-rw-r--r--sys/ia64/ia64/pmap.c65
-rw-r--r--sys/ia64/include/pmap.h2
3 files changed, 39 insertions, 37 deletions
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 18d2083e8750..fab204ac879d 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -217,18 +217,21 @@ cpu_switch(struct thread *old, struct thread *new)
struct pcb *oldpcb, *newpcb;
oldpcb = old->td_pcb;
- oldpcb->pcb_current_pmap = PCPU_GET(current_pmap);
#if IA32
ia32_savectx(oldpcb);
#endif
if (!savectx(oldpcb)) {
newpcb = new->td_pcb;
- pmap_install(newpcb->pcb_current_pmap);
+ oldpcb->pcb_current_pmap =
+ pmap_switch(newpcb->pcb_current_pmap);
PCPU_SET(curthread, new);
#if IA32
ia32_restorectx(newpcb);
#endif
restorectx(newpcb);
+ /* We should not get here. */
+ panic("cpu_switch: restorectx() returned");
+ /* NOTREACHED */
}
}
@@ -238,7 +241,7 @@ cpu_throw(struct thread *old __unused, struct thread *new)
struct pcb *newpcb;
newpcb = new->td_pcb;
- pmap_install(newpcb->pcb_current_pmap);
+ (void)pmap_switch(newpcb->pcb_current_pmap);
PCPU_SET(curthread, new);
#if IA32
ia32_restorectx(newpcb);
diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c
index 998d49f2c0e9..94003f3eedfe 100644
--- a/sys/ia64/ia64/pmap.c
+++ b/sys/ia64/ia64/pmap.c
@@ -264,6 +264,7 @@ static PMAP_INLINE void free_pv_entry(pv_entry_t pv);
static pv_entry_t get_pv_entry(void);
static void ia64_protection_init(void);
+static pmap_t pmap_install(pmap_t);
static void pmap_invalidate_all(pmap_t pmap);
static void pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m);
@@ -2534,45 +2535,43 @@ pmap_activate(struct thread *td)
}
pmap_t
-pmap_install(pmap_t pmap)
+pmap_switch(pmap_t pm)
{
- pmap_t oldpmap;
+ pmap_t prevpm;
int i;
- critical_enter();
-
- oldpmap = PCPU_GET(current_pmap);
- if (oldpmap == pmap) {
- critical_exit();
- return (oldpmap);
- }
-
- if (oldpmap != NULL)
- atomic_clear_32(&oldpmap->pm_active, PCPU_GET(cpumask));
-
- PCPU_SET(current_pmap, pmap);
-
- if (pmap == NULL) {
- /* Invalidate regions 0-4. */
- ia64_set_rr(IA64_RR_BASE(0), (0 << 8)|(PAGE_SHIFT << 2)|1);
- ia64_set_rr(IA64_RR_BASE(1), (1 << 8)|(PAGE_SHIFT << 2)|1);
- ia64_set_rr(IA64_RR_BASE(2), (2 << 8)|(PAGE_SHIFT << 2)|1);
- ia64_set_rr(IA64_RR_BASE(3), (3 << 8)|(PAGE_SHIFT << 2)|1);
- ia64_set_rr(IA64_RR_BASE(4), (4 << 8)|(PAGE_SHIFT << 2)|1);
- critical_exit();
- return (oldpmap);
- }
-
- atomic_set_32(&pmap->pm_active, PCPU_GET(cpumask));
-
- for (i = 0; i < 5; i++) {
- ia64_set_rr(IA64_RR_BASE(i),
- (pmap->pm_rid[i] << 8)|(PAGE_SHIFT << 2)|1);
+ mtx_assert(&sched_lock, MA_OWNED);
+
+ prevpm = PCPU_GET(current_pmap);
+ if (prevpm == pm)
+ return (prevpm);
+ if (prevpm != NULL)
+ atomic_clear_32(&prevpm->pm_active, PCPU_GET(cpumask));
+ if (pm == NULL) {
+ for (i = 0; i < 5; i++) {
+ ia64_set_rr(IA64_RR_BASE(i),
+ (i << 8)|(PAGE_SHIFT << 2)|1);
+ }
+ } else {
+ for (i = 0; i < 5; i++) {
+ ia64_set_rr(IA64_RR_BASE(i),
+ (pm->pm_rid[i] << 8)|(PAGE_SHIFT << 2)|1);
+ }
+ atomic_set_32(&pm->pm_active, PCPU_GET(cpumask));
+ PCPU_SET(current_pmap, pm);
}
+ return (prevpm);
+}
- critical_exit();
+static pmap_t
+pmap_install(pmap_t pm)
+{
+ pmap_t prevpm;
- return (oldpmap);
+ mtx_lock_spin(&sched_lock);
+ prevpm = pmap_switch(pm);
+ mtx_unlock_spin(&sched_lock);
+ return (prevpm);
}
vm_offset_t
diff --git a/sys/ia64/include/pmap.h b/sys/ia64/include/pmap.h
index 4ee712d36e56..d14e4b8108de 100644
--- a/sys/ia64/include/pmap.h
+++ b/sys/ia64/include/pmap.h
@@ -128,7 +128,7 @@ void pmap_unmapdev(vm_offset_t, vm_size_t);
unsigned *pmap_pte(pmap_t, vm_offset_t) __pure2;
void pmap_set_opt (unsigned *);
void pmap_set_opt_bsp (void);
-struct pmap *pmap_install(struct pmap *pmap);
+struct pmap *pmap_switch(struct pmap *pmap);
#endif /* _KERNEL */