Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP3:GA
xen.6738
59f32b46-x86-dont-latch-wrong-GS-base-addresses...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 59f32b46-x86-dont-latch-wrong-GS-base-addresses.patch of Package xen.6738
References: bsc#1057493 # Commit a711f6f24a7157ae70d1cc32e61b98f23dc0c584 # Date 2017-10-27 13:49:10 +0100 # Author Jan Beulich <JBeulich@suse.com> # Committer Andrew Cooper <andrew.cooper3@citrix.com> x86: don't latch wrong (stale) GS base addresses load_segments() writes selector registers before doing any of the base address updates. Any of these selector loads can cause a page fault in case it references the LDT, and the LDT page accessed was only recently installed. Therefore the call tree map_ldt_shadow_page() -> guest_get_eff_kern_l1e() -> toggle_guest_mode() would in such a case wrongly latch the outgoing vCPU's GS.base into the incoming vCPU's recorded state. Split page table toggling from GS handling - neither guest_get_eff_kern_l1e() nor guest_io_okay() need more than the page tables being the kernel ones for the memory access they want to do. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1611,7 +1611,7 @@ static int guest_io_okay( { /* If in user mode, switch to kernel mode just to read I/O bitmap. */ int user_mode = !(v->arch.flags & TF_kernel_mode); -#define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v) +#define TOGGLE_MODE() if ( user_mode ) toggle_guest_pt(v) if ( !vm86_mode(regs) && (v->arch.pv_vcpu.iopl >= (guest_kernel_mode(v, regs) ? 1 : 3)) ) --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -278,8 +278,17 @@ void toggle_guest_mode(struct vcpu *v) else v->arch.pv_vcpu.gs_base_user = __rdgsbase(); } - v->arch.flags ^= TF_kernel_mode; asm volatile ( "swapgs" ); + + toggle_guest_pt(v); +} + +void toggle_guest_pt(struct vcpu *v) +{ + if ( is_pv_32bit_vcpu(v) ) + return; + + v->arch.flags ^= TF_kernel_mode; update_cr3(v); #ifdef USER_MAPPINGS_ARE_GLOBAL /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */ --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -75,6 +75,8 @@ void mapcache_override_current(struct vc /* x86/64: toggle guest between kernel and user modes. */ void toggle_guest_mode(struct vcpu *); +/* x86/64: toggle guest page tables between kernel and user modes. */ +void toggle_guest_pt(struct vcpu *); /* * Initialise a hypercall-transfer page. The given pointer must be mapped --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -411,7 +411,7 @@ static inline void guest_get_eff_kern_l1e(struct vcpu *v, unsigned long addr, void *eff_l1e) { int user_mode = !(v->arch.flags & TF_kernel_mode); -#define TOGGLE_MODE() if ( user_mode ) toggle_guest_mode(v) +#define TOGGLE_MODE() if ( user_mode ) toggle_guest_pt(v) TOGGLE_MODE(); guest_get_eff_l1e(v, addr, eff_l1e);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor