diff options
author | Colin Percival <cperciva@FreeBSD.org> | 2011-01-06 22:57:06 +0000 |
---|---|---|
committer | Colin Percival <cperciva@FreeBSD.org> | 2011-01-06 22:57:06 +0000 |
commit | 734510f3bca4f1b5ea1ab71e6ea61128ae30939c (patch) | |
tree | 50b5a208d279829b837e21d61e4feb37cca16b42 | |
parent | 002fe711ccbf70dbc21e9ecfd417defb89cd99a8 (diff) | |
download | src-734510f3bca4f1b5ea1ab71e6ea61128ae30939c.tar.gz src-734510f3bca4f1b5ea1ab71e6ea61128ae30939c.zip |
MFS r217056: Make i386_set_ldt work (rather than panic) on i386/XEN.
Approved by: re (rwatson)
Notes
Notes:
svn path=/releng/8.2/; revision=217084
-rw-r--r-- | sys/i386/i386/sys_machdep.c | 20 | ||||
-rw-r--r-- | sys/i386/include/pmap.h | 1 | ||||
-rw-r--r-- | sys/i386/include/segments.h | 1 | ||||
-rw-r--r-- | sys/i386/xen/pmap.c | 4 |
4 files changed, 21 insertions, 5 deletions
diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c index 2e7abdde25a8..3fb231b7866c 100644 --- a/sys/i386/i386/sys_machdep.c +++ b/sys/i386/i386/sys_machdep.c @@ -450,6 +450,7 @@ user_ldt_alloc(struct mdproc *mdp, int len) new_ldt->ldt_refcnt = 1; new_ldt->ldt_active = 0; + mtx_lock_spin(&dt_lock); if ((pldt = mdp->md_ldt)) { if (len > pldt->ldt_len) len = pldt->ldt_len; @@ -458,8 +459,10 @@ user_ldt_alloc(struct mdproc *mdp, int len) } else { bcopy(ldt, new_ldt->ldt_base, PAGE_SIZE); } + mtx_unlock_spin(&dt_lock); /* XXX kill once pmap locking fixed. */ pmap_map_readonly(kernel_pmap, (vm_offset_t)new_ldt->ldt_base, new_ldt->ldt_len*sizeof(union descriptor)); + mtx_lock_spin(&dt_lock); /* XXX kill once pmap locking fixed. */ return (new_ldt); } #else @@ -520,8 +523,13 @@ user_ldt_free(struct thread *td) } if (td == PCPU_GET(curthread)) { +#ifdef XEN + i386_reset_ldt(&default_proc_ldt); + PCPU_SET(currentldt, (int)&default_proc_ldt); +#else lldt(_default_ldt); PCPU_SET(currentldt, _default_ldt); +#endif } mdp->md_ldt = NULL; @@ -758,10 +766,14 @@ i386_set_ldt_data(struct thread *td, int start, int num, mtx_assert(&dt_lock, MA_OWNED); - /* Fill in range */ - bcopy(descs, - &((union descriptor *)(pldt->ldt_base))[start], - num * sizeof(union descriptor)); + while (num) { + xen_update_descriptor( + &((union descriptor *)(pldt->ldt_base))[start], + descs); + num--; + start++; + descs++; + } return (0); } #else diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h index 3d44d220f03e..7a45aab75f7a 100644 --- a/sys/i386/include/pmap.h +++ b/sys/i386/include/pmap.h @@ -251,7 +251,6 @@ pte_load_store(pt_entry_t *ptep, pt_entry_t v) { pt_entry_t r; - v = xpmap_ptom(v); r = *ptep; PT_SET_VA(ptep, v, TRUE); return (r); diff --git a/sys/i386/include/segments.h b/sys/i386/include/segments.h index 2edcc59073b4..bfc3bb9c82c7 100644 --- a/sys/i386/include/segments.h +++ b/sys/i386/include/segments.h @@ -249,6 +249,7 @@ struct region_descriptor { #ifdef _KERNEL extern int _default_ldt; #ifdef XEN +extern struct proc_ldt default_proc_ldt; extern union descriptor *gdt; extern union descriptor *ldt; #else diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c index 0d2450e234e8..ab4fe054b715 100644 --- a/sys/i386/xen/pmap.c +++ b/sys/i386/xen/pmap.c @@ -3710,7 +3710,9 @@ pmap_map_readonly(pmap_t pmap, vm_offset_t va, int len) for (i = 0; i < npages; i++) { pt_entry_t *pte; pte = pmap_pte(pmap, (vm_offset_t)(va + i*PAGE_SIZE)); + vm_page_lock_queues(); pte_store(pte, xpmap_mtop(*pte & ~(PG_RW|PG_M))); + vm_page_unlock_queues(); PMAP_MARK_PRIV(xpmap_mtop(*pte)); pmap_pte_release(pte); } @@ -3724,7 +3726,9 @@ pmap_map_readwrite(pmap_t pmap, vm_offset_t va, int len) pt_entry_t *pte; pte = pmap_pte(pmap, (vm_offset_t)(va + i*PAGE_SIZE)); PMAP_MARK_UNPRIV(xpmap_mtop(*pte)); + vm_page_lock_queues(); pte_store(pte, xpmap_mtop(*pte) | (PG_RW|PG_M)); + vm_page_unlock_queues(); pmap_pte_release(pte); } } |