diff mbox

[1/3] x86: fix GS-base-dirty determination

Message ID 59EA22E10200007800188C16@prv-mh.provo.novell.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Beulich Oct. 20, 2017, 2:22 p.m. UTC
load_segments() writes the two MSRs in their "canonical" positions
(GS_BASE for the user base, SHADOW_GS_BASE for the kernel one) and uses
SWAPGS to switch them around if the incoming vCPU is in kernel mode. In
order to not leave a stale kernel address in GS_BASE when the incoming
guest is in user mode, the check on the outgoing vCPU needs to be
dependent upon the mode it is currently in, rather than blindly looking
at the user base.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

Comments

Andrew Cooper Oct. 20, 2017, 2:49 p.m. UTC | #1
On 20/10/17 15:22, Jan Beulich wrote:
> load_segments() writes the two MSRs in their "canonical" positions
> (GS_BASE for the user base, SHADOW_GS_BASE for the kernel one) and uses
> SWAPGS to switch them around if the incoming vCPU is in kernel mode. In
> order to not leave a stale kernel address in GS_BASE when the incoming
> guest is in user mode, the check on the outgoing vCPU needs to be
> dependent upon the mode it is currently in, rather than blindly looking
> at the user base.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
diff mbox

Patch

--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1479,7 +1479,8 @@  static void save_segments(struct vcpu *v
         if ( regs->gs & ~3 )
             v->arch.pv_vcpu.gs_base_user = 0;
     }
-    if ( v->arch.pv_vcpu.gs_base_user )
+    if ( v->arch.flags & TF_kernel_mode ? v->arch.pv_vcpu.gs_base_kernel
+                                        : v->arch.pv_vcpu.gs_base_user )
         dirty_segment_mask |= DIRTY_GS_BASE_USER;
 
     this_cpu(dirty_segment_mask) = dirty_segment_mask;