mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
pmap_install() needs to be atomic WRT to context switching. Protect
switching user regions (region 0-4) with schedlock. Avoid unnecessary recursion on schedlock by moving the core functionality to another function (pmap_switch()) where we assert schedlock is held. Turn pmap_install() into a wrapper that grabs schedlock. This minimizes the number of callsites that need to be changed. Since we already have schedlock in cpu_switch() and cpu_throw(), have them call pmap_switch() directly. These were also the only two calls to pmap_install() outside pmap.c, so make pmap_install() static and remove its prototype from pmap.h Approved by: re (blanket)
This commit is contained in:
parent
4555a3de62
commit
dc0bde0f18
3 changed files with 38 additions and 36 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
mtx_assert(&sched_lock, MA_OWNED);
|
||||
|
||||
oldpmap = PCPU_GET(current_pmap);
|
||||
if (oldpmap == pmap) {
|
||||
critical_exit();
|
||||
return (oldpmap);
|
||||
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);
|
||||
}
|
||||
|
||||
if (oldpmap != NULL)
|
||||
atomic_clear_32(&oldpmap->pm_active, PCPU_GET(cpumask));
|
||||
static pmap_t
|
||||
pmap_install(pmap_t pm)
|
||||
{
|
||||
pmap_t prevpm;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
critical_exit();
|
||||
|
||||
return (oldpmap);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
prevpm = pmap_switch(pm);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
return (prevpm);
|
||||
}
|
||||
|
||||
vm_offset_t
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue