diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-09-24 21:49:20 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-09-24 21:49:20 +0000 |
commit | 1c6d2cd89759c2a388e57f72e7ddcb7eb97e102c (patch) | |
tree | 2a3bc55a3ebaa5964e144b516457442712e4022d | |
parent | 156bcf860cf42b43660850f1ec174c435681f7f2 (diff) | |
download | xen-1c6d2cd89759c2a388e57f72e7ddcb7eb97e102c.tar.gz xen-1c6d2cd89759c2a388e57f72e7ddcb7eb97e102c.tar.bz2 xen-1c6d2cd89759c2a388e57f72e7ddcb7eb97e102c.zip |
bitkeeper revision 1.460 (3f721160CQuzVfl_qVkHJLnLn6yY1A)
ldt.c:
Xenolinux modify_ldt syscall now silently clamps the segment limit to a safe value. This is needed for brainded new linuxthreads versions which specify a 4GB segment limit.
-rw-r--r-- | xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c b/xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c index ca89b694bd..28ae39fd60 100644 --- a/xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c +++ b/xenolinux-2.4.22-sparse/arch/xeno/kernel/ldt.c @@ -68,7 +68,7 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode) { struct mm_struct * mm = current->mm; __u32 entry_1, entry_2, *lp; - unsigned long phys_lp; + unsigned long phys_lp, max_limit; int error; struct modify_ldt_ldt_s ldt_info; @@ -89,6 +89,13 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode) goto out; } + /* + * This makes our tests for overlap with Xen space easier. There's no good + * reason to have a user segment starting this high anyway. + */ + if (ldt_info.base_addr >= PAGE_OFFSET) + goto out; + down_write(&mm->mmap_sem); if (!mm->context.segments) { void * segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); @@ -122,6 +129,13 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode) } } + max_limit = HYPERVISOR_VIRT_START - ldt_info.base_addr; + if ( ldt_info.limit_in_pages ) + max_limit >>= PAGE_SHIFT; + max_limit--; + if ( (ldt_info.limit & 0xfffff) > (max_limit & 0xfffff) ) + ldt_info.limit = max_limit; + entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | (ldt_info.limit & 0x0ffff); entry_2 = (ldt_info.base_addr & 0xff000000) | |