diff options
author | Jan Beulich <jbeulich@suse.com> | 2013-10-11 09:28:26 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-10-11 09:28:26 +0200 |
commit | 40d66baa46ca8a9ffa6df3e063a967d08ec92bcf (patch) | |
tree | 551daf93c5e8b6a8bd50cf58f5a30eb1da8ec1dc /xen/arch/x86/domain.c | |
parent | 4c37ed562224295c0f8b00211287d57cae629782 (diff) | |
download | xen-40d66baa46ca8a9ffa6df3e063a967d08ec92bcf.tar.gz xen-40d66baa46ca8a9ffa6df3e063a967d08ec92bcf.tar.bz2 xen-40d66baa46ca8a9ffa6df3e063a967d08ec92bcf.zip |
x86: correct LDT checks
- MMUEXT_SET_LDT should behave as similarly to the LLDT instruction as
possible: fail only if the base address is non-canonical
- instead LDT descriptor accesses should fault if the descriptor
address ends up being non-canonical (by ensuring this we at once
avoid reading an entry from the mach-to-phys table and consider it a
page table entry)
- fault propagation on using LDT selectors must distinguish #PF and #GP
(the latter must be raised for a non-canonical descriptor address,
which also applies to several other uses of propagate_page_fault(),
and hence the problem is being fixed there)
- map_ldt_shadow_page() should properly wrap addresses for 32-bit VMs
At once remove the odd invokation of map_ldt_shadow_page() from the
MMUEXT_SET_LDT handler: There's nothing really telling us that the
first LDT page is going to be preferred over others.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/domain.c')
-rw-r--r-- | xen/arch/x86/domain.c | 20 |
1 files changed, 6 insertions, 14 deletions
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 316ef0452e..52b7a37fec 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -674,12 +674,7 @@ int arch_set_info_guest( fixup_guest_code_selector(d, c.nat->trap_ctxt[i].cs); } - /* LDT safety checks. */ - if ( ((c.nat->ldt_base & (PAGE_SIZE-1)) != 0) || - (c.nat->ldt_ents > 8192) || - !array_access_ok(c.nat->ldt_base, - c.nat->ldt_ents, - LDT_ENTRY_SIZE) ) + if ( !__addr_ok(c.nat->ldt_base) ) return -EINVAL; } else @@ -692,15 +687,12 @@ int arch_set_info_guest( for ( i = 0; i < ARRAY_SIZE(c.cmp->trap_ctxt); i++ ) fixup_guest_code_selector(d, c.cmp->trap_ctxt[i].cs); - - /* LDT safety checks. */ - if ( ((c.cmp->ldt_base & (PAGE_SIZE-1)) != 0) || - (c.cmp->ldt_ents > 8192) || - !compat_array_access_ok(c.cmp->ldt_base, - c.cmp->ldt_ents, - LDT_ENTRY_SIZE) ) - return -EINVAL; } + + /* LDT safety checks. */ + if ( ((c(ldt_base) & (PAGE_SIZE - 1)) != 0) || + (c(ldt_ents) > 8192) ) + return -EINVAL; } v->fpu_initialised = !!(flags & VGCF_I387_VALID); |