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

[PATCH 2/4] x86: Introduce MSR_UNHANDLED



When toolstack updates MSR policy, this MSR offset (which is an invalid
MSR index) is used to indicate hypervisor behavior when a guest accesses
an MSR which is not explicitly emulated.

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
---
 xen/include/xen/lib/x86/msr.h | 17 ++++++++++++++++-
 xen/lib/x86/msr.c             | 16 +++++++++-------
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/xen/include/xen/lib/x86/msr.h b/xen/include/xen/lib/x86/msr.h
index 48ba4a59c036..7911ae31eb48 100644
--- a/xen/include/xen/lib/x86/msr.h
+++ b/xen/include/xen/lib/x86/msr.h
@@ -2,8 +2,21 @@
 #ifndef XEN_LIB_X86_MSR_H
 #define XEN_LIB_X86_MSR_H
 
+/*
+ * Behavior on accesses to MSRs that are not handled by emulation:
+ *  0 = return #GP, warning emitted
+ *  1 = read as 0, writes are dropped, no warning
+ *  2 = read as 0, writes are dropped, warning emitted
+ */
+#define MSR_UNHANDLED_NEVER     0
+#define MSR_UNHANDLED_SILENT    1
+#define MSR_UNHANDLED_VERBOSE   2
+
+/* MSR that is not explicitly processed by emulation */
+#define MSR_UNHANDLED -1
+
 /* Maximum number of MSRs written when serialising msr_policy. */
-#define MSR_MAX_SERIALISED_ENTRIES 2
+#define MSR_MAX_SERIALISED_ENTRIES 3
 
 /* MSR policy object for shared per-domain MSRs */
 struct msr_policy
@@ -45,6 +58,8 @@ struct msr_policy
             bool taa_no:1;
         };
     } arch_caps;
+
+    uint8_t ignore_msrs;
 };
 
 #ifdef __XEN__
diff --git a/xen/lib/x86/msr.c b/xen/lib/x86/msr.c
index 7d71e92a380a..cf53768dfa4e 100644
--- a/xen/lib/x86/msr.c
+++ b/xen/lib/x86/msr.c
@@ -6,11 +6,11 @@
  * Copy a single MSR into the provided msr_entry_buffer_t buffer, performing a
  * boundary check against the buffer size.
  */
-static int copy_msr_to_buffer(uint32_t idx, uint64_t val,
+static int copy_msr_to_buffer(uint32_t idx, uint64_t val, uint32_t flags,
                               msr_entry_buffer_t msrs,
                               uint32_t *curr_entry, const uint32_t nr_entries)
 {
-    const xen_msr_entry_t ent = { .idx = idx, .val = val };
+    const xen_msr_entry_t ent = { .idx = idx, .val = val, .flags = flags };
 
     if ( *curr_entry == nr_entries )
         return -ENOBUFS;
@@ -29,17 +29,18 @@ int x86_msr_copy_to_buffer(const struct msr_policy *p,
     const uint32_t nr_entries = *nr_entries_p;
     uint32_t curr_entry = 0;
 
-#define COPY_MSR(idx, val)                                      \
+#define COPY_MSR(idx, val, flags)                                      \
     ({                                                          \
         int ret;                                                \
                                                                 \
         if ( (ret = copy_msr_to_buffer(                         \
-                  idx, val, msrs, &curr_entry, nr_entries)) )   \
+                  idx, val, flags, msrs, &curr_entry, nr_entries)) )   \
             return ret;                                         \
     })
 
-    COPY_MSR(MSR_INTEL_PLATFORM_INFO, p->platform_info.raw);
-    COPY_MSR(MSR_ARCH_CAPABILITIES,   p->arch_caps.raw);
+    COPY_MSR(MSR_INTEL_PLATFORM_INFO, p->platform_info.raw, 0);
+    COPY_MSR(MSR_ARCH_CAPABILITIES,   p->arch_caps.raw, 0);
+    COPY_MSR(MSR_UNHANDLED, 0, p->ignore_msrs);
 
 #undef COPY_MSR
 
@@ -77,7 +78,7 @@ int x86_msr_copy_from_buffer(struct msr_policy *p,
         if ( copy_from_buffer_offset(&data, msrs, i, 1) )
             return -EFAULT;
 
-        if ( data.flags ) /* .flags MBZ */
+        if ( data.idx != MSR_UNHANDLED && data.flags )
         {
             rc = -EINVAL;
             goto err;
@@ -101,6 +102,7 @@ int x86_msr_copy_from_buffer(struct msr_policy *p,
 
         case MSR_INTEL_PLATFORM_INFO: ASSIGN(platform_info.raw); break;
         case MSR_ARCH_CAPABILITIES:   ASSIGN(arch_caps.raw);     break;
+        case MSR_UNHANDLED:           p->ignore_msrs = data.flags & 0xff;      
 break;
 
 #undef ASSIGN
 
-- 
1.8.3.1




 


Rackspace

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