From a1b0eebcd2925baec8ca60117f7a41925cb665e5 Mon Sep 17 00:00:00 2001 From: cperciva Date: Thu, 6 Jan 2011 22:57:06 +0000 Subject: [PATCH] MFS r217056: Make i386_set_ldt work (rather than panic) on i386/XEN. Approved by: re (rwatson) git-svn-id: svn://svn.freebsd.org/base/releng/8.2@217084 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/i386/i386/sys_machdep.c | 20 ++++++++++++++++---- sys/i386/include/pmap.h | 1 - sys/i386/include/segments.h | 1 + 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 2e7abdde..3fb231b7 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 3d44d220..7a45aab7 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 2edcc590..bfc3bb9c 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 0d2450e2..ab4fe054 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); } } -- 2.42.0