[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 4/4] x86/vmx: Drop vmx_msr_state infrastructure



To avoid leaking host MSR state into guests, guest LSTAR, STAR and
SYSCALL_MASK state is unconditionally loaded when switching into guest
context.

Attempting to dirty-track the state is pointless; host state is always
restoring upon exit from guest context, meaning that guest state is always
considered dirty.

Drop struct vmx_msr_state, enum VMX_INDEX_MSR_* and msr_index[].  The guests
MSR values are stored plainly in arch_vmx_struct, in the same way as shadow_gs
and cstar are.  vmx_restore_guest_msrs() and long_mode_do_msr_write() ensure
that the hardware MSR values are always up-to-date.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Jun Nakajima <jun.nakajima@xxxxxxxxx>
CC: Kevin Tian <kevin.tian@xxxxxxxxx>
---
 xen/arch/x86/hvm/vmx/vmcs.c        |  3 --
 xen/arch/x86/hvm/vmx/vmx.c         | 79 ++++++++++----------------------------
 xen/include/asm-x86/hvm/vmx/vmcs.h | 21 +++-------
 3 files changed, 26 insertions(+), 77 deletions(-)

diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index a6e1294..e28b649 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1088,9 +1088,6 @@ static int construct_vmcs(struct vcpu *v)
             vmx_disable_intercept_for_msr(v, MSR_IA32_BNDCFGS, MSR_TYPE_R | 
MSR_TYPE_W);
     }
 
-    /* All guest MSR state is dirty. */
-    v->arch.hvm_vmx.msr_state.flags = ((1u << VMX_MSR_COUNT) - 1);
-
     /* I/O access bitmap. */
     __vmwrite(IO_BITMAP_A, __pa(d->arch.hvm_domain.io_bitmap));
     __vmwrite(IO_BITMAP_B, __pa(d->arch.hvm_domain.io_bitmap) + PAGE_SIZE);
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 33e18af..ec3193c 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -358,24 +358,10 @@ static void vmx_vcpu_destroy(struct vcpu *v)
     passive_domain_destroy(v);
 }
 
-static const u32 msr_index[VMX_MSR_COUNT] =
-{
-    [VMX_INDEX_MSR_LSTAR]        = MSR_LSTAR,
-    [VMX_INDEX_MSR_STAR]         = MSR_STAR,
-    [VMX_INDEX_MSR_SYSCALL_MASK] = MSR_SYSCALL_MASK
-};
-
-#define WRITE_MSR(address) do {                                         \
-        guest_msr_state->msrs[VMX_INDEX_MSR_ ## address] = msr_content; \
-        __set_bit(VMX_INDEX_MSR_ ## address, &guest_msr_state->flags);  \
-        wrmsrl(MSR_ ## address, msr_content);                           \
-    } while ( 0 )
-
 static enum handler_return
 long_mode_do_msr_read(unsigned int msr, uint64_t *msr_content)
 {
     struct vcpu *v = current;
-    struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state;
 
     switch ( msr )
     {
@@ -392,11 +378,11 @@ long_mode_do_msr_read(unsigned int msr, uint64_t 
*msr_content)
         break;
 
     case MSR_STAR:
-        *msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_STAR];
+        *msr_content = v->arch.hvm_vmx.star;
         break;
 
     case MSR_LSTAR:
-        *msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_LSTAR];
+        *msr_content = v->arch.hvm_vmx.lstar;
         break;
 
     case MSR_CSTAR:
@@ -404,7 +390,7 @@ long_mode_do_msr_read(unsigned int msr, uint64_t 
*msr_content)
         break;
 
     case MSR_SYSCALL_MASK:
-        *msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
+        *msr_content = v->arch.hvm_vmx.sfmask;
         break;
 
     default:
@@ -420,7 +406,6 @@ static enum handler_return
 long_mode_do_msr_write(unsigned int msr, uint64_t msr_content)
 {
     struct vcpu *v = current;
-    struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state;
 
     HVM_DBG_LOG(DBG_LEVEL_MSR, "msr %#x content %#"PRIx64, msr, msr_content);
 
@@ -442,13 +427,15 @@ long_mode_do_msr_write(unsigned int msr, uint64_t 
msr_content)
         break;
 
     case MSR_STAR:
-        WRITE_MSR(STAR);
+        v->arch.hvm_vmx.star = msr_content;
+        wrmsrl(MSR_STAR, msr_content);
         break;
 
     case MSR_LSTAR:
         if ( !is_canonical_address(msr_content) )
             goto uncanonical_address;
-        WRITE_MSR(LSTAR);
+        v->arch.hvm_vmx.lstar = msr_content;
+        wrmsrl(MSR_LSTAR, msr_content);
         break;
 
     case MSR_CSTAR:
@@ -458,7 +445,8 @@ long_mode_do_msr_write(unsigned int msr, uint64_t 
msr_content)
         break;
 
     case MSR_SYSCALL_MASK:
-        WRITE_MSR(SYSCALL_MASK);
+        v->arch.hvm_vmx.sfmask = msr_content;
+        wrmsrl(MSR_SYSCALL_MASK, msr_content);
         break;
 
     default:
@@ -498,26 +486,10 @@ static void vmx_save_guest_msrs(struct vcpu *v)
 
 static void vmx_restore_guest_msrs(struct vcpu *v)
 {
-    struct vmx_msr_state *guest_msr_state;
-    unsigned long guest_flags;
-    int i;
-
-    guest_msr_state = &v->arch.hvm_vmx.msr_state;
-
     wrmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.shadow_gs);
-
-    guest_flags = guest_msr_state->flags;
-
-    while ( guest_flags )
-    {
-        i = find_first_set_bit(guest_flags);
-
-        HVM_DBG_LOG(DBG_LEVEL_2,
-                    "restore guest's index %d msr %x with value %lx",
-                    i, msr_index[i], guest_msr_state->msrs[i]);
-        wrmsrl(msr_index[i], guest_msr_state->msrs[i]);
-        __clear_bit(i, &guest_flags);
-    }
+    wrmsrl(MSR_STAR,           v->arch.hvm_vmx.star);
+    wrmsrl(MSR_LSTAR,          v->arch.hvm_vmx.lstar);
+    wrmsrl(MSR_SYSCALL_MASK,   v->arch.hvm_vmx.sfmask);
 
     if ( (v->arch.hvm_vcpu.guest_efer ^ read_efer()) & EFER_SCE )
     {
@@ -755,30 +727,21 @@ static int vmx_vmcs_restore(struct vcpu *v, struct 
hvm_hw_cpu *c)
 
 static void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
 {
-    struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
-
-    data->shadow_gs = v->arch.hvm_vmx.shadow_gs;
-    data->msr_cstar = v->arch.hvm_vmx.cstar;
-
-    /* save msrs */
+    data->shadow_gs        = v->arch.hvm_vmx.shadow_gs;
     data->msr_flags        = 0;
-    data->msr_lstar        = guest_state->msrs[VMX_INDEX_MSR_LSTAR];
-    data->msr_star         = guest_state->msrs[VMX_INDEX_MSR_STAR];
-    data->msr_syscall_mask = guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
+    data->msr_lstar        = v->arch.hvm_vmx.lstar;
+    data->msr_star         = v->arch.hvm_vmx.star;
+    data->msr_cstar        = v->arch.hvm_vmx.cstar;
+    data->msr_syscall_mask = v->arch.hvm_vmx.sfmask;
 }
 
 static void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
 {
-    struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
-
-    /* restore msrs */
-    guest_state->flags = ((1u << VMX_MSR_COUNT) - 1);
-    guest_state->msrs[VMX_INDEX_MSR_LSTAR]        = data->msr_lstar;
-    guest_state->msrs[VMX_INDEX_MSR_STAR]         = data->msr_star;
-    guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK] = data->msr_syscall_mask;
-
-    v->arch.hvm_vmx.cstar     = data->msr_cstar;
     v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
+    v->arch.hvm_vmx.star      = data->msr_star;
+    v->arch.hvm_vmx.lstar     = data->msr_lstar;
+    v->arch.hvm_vmx.cstar     = data->msr_cstar;
+    v->arch.hvm_vmx.sfmask    = data->msr_syscall_mask;
 }
 
 
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h 
b/xen/include/asm-x86/hvm/vmx/vmcs.h
index 99dde44..199932e 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -40,19 +40,6 @@ struct vmx_msr_entry {
     u64 data;
 };
 
-enum {
-    VMX_INDEX_MSR_LSTAR = 0,
-    VMX_INDEX_MSR_STAR,
-    VMX_INDEX_MSR_SYSCALL_MASK,
-
-    VMX_MSR_COUNT
-};
-
-struct vmx_msr_state {
-    unsigned long flags;
-    unsigned long msrs[VMX_MSR_COUNT];
-};
-
 #define EPT_DEFAULT_MT      MTRR_TYPE_WRBACK
 
 struct ept_data {
@@ -124,9 +111,11 @@ struct arch_vmx_struct {
     u32                  secondary_exec_control;
     u32                  exception_bitmap;
 
-    struct vmx_msr_state msr_state;
-    unsigned long        shadow_gs;
-    unsigned long        cstar;
+    uint64_t             shadow_gs;
+    uint64_t             star;
+    uint64_t             lstar;
+    uint64_t             cstar;
+    uint64_t             sfmask;
 
     unsigned long       *msr_bitmap;
     unsigned int         msr_count;
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.