KVM: SVM: Software reserved fields
authorVineeth Pillai <viremana@linux.microsoft.com>
Thu, 3 Jun 2021 15:14:37 +0000 (15:14 +0000)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 17 Jun 2021 17:09:37 +0000 (13:09 -0400)
SVM added support for certain reserved fields to be used by
software or hypervisor. Add the following reserved fields:
  - VMCB offset 0x3e0 - 0x3ff
  - Clean bit 31
  - SVM intercept exit code 0xf0000000

Later patches will make use of this for supporting Hyper-V
nested virtualization enhancements.

Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
Message-Id: <a1f17a43a8e9e751a1a9cc0281649d71bdbf721b.1622730232.git.viremana@linux.microsoft.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/svm.h
arch/x86/include/uapi/asm/svm.h
arch/x86/kvm/svm/svm.h

index 772e60e..e322676 100644 (file)
@@ -156,6 +156,12 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
        u64 avic_physical_id;   /* Offset 0xf8 */
        u8 reserved_7[8];
        u64 vmsa_pa;            /* Used for an SEV-ES guest */
+       u8 reserved_8[720];
+       /*
+        * Offset 0x3e0, 32 bytes reserved
+        * for use by hypervisor/software.
+        */
+       u8 reserved_sw[32];
 };
 
 
@@ -314,7 +320,7 @@ struct ghcb {
 
 
 #define EXPECTED_VMCB_SAVE_AREA_SIZE           1032
-#define EXPECTED_VMCB_CONTROL_AREA_SIZE                272
+#define EXPECTED_VMCB_CONTROL_AREA_SIZE                1024
 #define EXPECTED_GHCB_SIZE                     PAGE_SIZE
 
 static inline void __unused_size_checks(void)
@@ -326,7 +332,6 @@ static inline void __unused_size_checks(void)
 
 struct vmcb {
        struct vmcb_control_area control;
-       u8 reserved_control[1024 - sizeof(struct vmcb_control_area)];
        struct vmcb_save_area save;
 } __packed;
 
index 554f75f..efa9693 100644 (file)
 #define SVM_VMGEXIT_GET_AP_JUMP_TABLE          1
 #define SVM_VMGEXIT_UNSUPPORTED_EVENT          0x8000ffff
 
+/* Exit code reserved for hypervisor/software use */
+#define SVM_EXIT_SW                            0xf0000000
+
 #define SVM_EXIT_ERR           -1
 
 #define SVM_EXIT_REASONS \
index a514b49..af09bcd 100644 (file)
 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
 extern bool npt_enabled;
 
+/*
+ * Clean bits in VMCB.
+ * VMCB_ALL_CLEAN_MASK might also need to
+ * be updated if this enum is modified.
+ */
 enum {
        VMCB_INTERCEPTS, /* Intercept vectors, TSC offset,
                            pause filter count */
@@ -48,9 +53,17 @@ enum {
                          * AVIC PHYSICAL_TABLE pointer,
                          * AVIC LOGICAL_TABLE pointer
                          */
-       VMCB_DIRTY_MAX,
+       VMCB_SW = 31,    /* Reserved for hypervisor/software use */
 };
 
+#define VMCB_ALL_CLEAN_MASK (                                  \
+       (1U << VMCB_INTERCEPTS) | (1U << VMCB_PERM_MAP) |       \
+       (1U << VMCB_ASID) | (1U << VMCB_INTR) |                 \
+       (1U << VMCB_NPT) | (1U << VMCB_CR) | (1U << VMCB_DR) |  \
+       (1U << VMCB_DT) | (1U << VMCB_SEG) | (1U << VMCB_CR2) | \
+       (1U << VMCB_LBR) | (1U << VMCB_AVIC) |                  \
+       (1U << VMCB_SW))
+
 /* TPR and CR2 are always written before VMRUN */
 #define VMCB_ALWAYS_DIRTY_MASK ((1U << VMCB_INTR) | (1U << VMCB_CR2))
 
@@ -237,7 +250,7 @@ static inline void vmcb_mark_all_dirty(struct vmcb *vmcb)
 
 static inline void vmcb_mark_all_clean(struct vmcb *vmcb)
 {
-       vmcb->control.clean = ((1 << VMCB_DIRTY_MAX) - 1)
+       vmcb->control.clean = VMCB_ALL_CLEAN_MASK
                               & ~VMCB_ALWAYS_DIRTY_MASK;
 }