diff options
author | cperciva <cperciva@FreeBSD.org> | 2010-12-31 17:41:14 +0000 |
---|---|---|
committer | cperciva <cperciva@FreeBSD.org> | 2010-12-31 17:41:14 +0000 |
commit | 0f106c39c9adc30994f9502bda1ffa9cb14cf934 (patch) | |
tree | cb0cdd037b6e2267417923a6973508e0d40609ff | |
parent | fb0632e3bd9c855f43327f53192400418592c392 (diff) | |
download | FreeBSD-src-0f106c39c9adc30994f9502bda1ffa9cb14cf934.zip FreeBSD-src-0f106c39c9adc30994f9502bda1ffa9cb14cf934.tar.gz |
Make i386_set_ldt work on i386/XEN, step 4/5.
Use xen_update_descriptor to update the LDT rather than bcopy. Under Xen,
pages used for holding LDTs must be read-only, so we can't make the change
ourselves.
Ths obvious alternative of "remap the page read-write, make the change, then
map it read-only again" doesn't work since Xen won't allow an LDT page to be
remapped as R/W. An arguably better solution is used by NetBSD: They don't
modify LDTs in-place at all, but instead copy the entire LDT, modify the new
version, then atomically swap.
MFC after: 3 days
-rw-r--r-- | sys/i386/i386/sys_machdep.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c index 4bcf91d..b47679a 100644 --- a/sys/i386/i386/sys_machdep.c +++ b/sys/i386/i386/sys_machdep.c @@ -761,10 +761,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 |