Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: SVM: Software reserved fields

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>

authored by

Vineeth Pillai and committed by
Paolo Bonzini
59d21d67 3c86c0d3

+25 -4
+7 -2
arch/x86/include/asm/svm.h
··· 156 156 u64 avic_physical_id; /* Offset 0xf8 */ 157 157 u8 reserved_7[8]; 158 158 u64 vmsa_pa; /* Used for an SEV-ES guest */ 159 + u8 reserved_8[720]; 160 + /* 161 + * Offset 0x3e0, 32 bytes reserved 162 + * for use by hypervisor/software. 163 + */ 164 + u8 reserved_sw[32]; 159 165 }; 160 166 161 167 ··· 320 314 321 315 322 316 #define EXPECTED_VMCB_SAVE_AREA_SIZE 1032 323 - #define EXPECTED_VMCB_CONTROL_AREA_SIZE 272 317 + #define EXPECTED_VMCB_CONTROL_AREA_SIZE 1024 324 318 #define EXPECTED_GHCB_SIZE PAGE_SIZE 325 319 326 320 static inline void __unused_size_checks(void) ··· 332 326 333 327 struct vmcb { 334 328 struct vmcb_control_area control; 335 - u8 reserved_control[1024 - sizeof(struct vmcb_control_area)]; 336 329 struct vmcb_save_area save; 337 330 } __packed; 338 331
+3
arch/x86/include/uapi/asm/svm.h
··· 110 110 #define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1 111 111 #define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff 112 112 113 + /* Exit code reserved for hypervisor/software use */ 114 + #define SVM_EXIT_SW 0xf0000000 115 + 113 116 #define SVM_EXIT_ERR -1 114 117 115 118 #define SVM_EXIT_REASONS \
+15 -2
arch/x86/kvm/svm/svm.h
··· 31 31 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; 32 32 extern bool npt_enabled; 33 33 34 + /* 35 + * Clean bits in VMCB. 36 + * VMCB_ALL_CLEAN_MASK might also need to 37 + * be updated if this enum is modified. 38 + */ 34 39 enum { 35 40 VMCB_INTERCEPTS, /* Intercept vectors, TSC offset, 36 41 pause filter count */ ··· 53 48 * AVIC PHYSICAL_TABLE pointer, 54 49 * AVIC LOGICAL_TABLE pointer 55 50 */ 56 - VMCB_DIRTY_MAX, 51 + VMCB_SW = 31, /* Reserved for hypervisor/software use */ 57 52 }; 53 + 54 + #define VMCB_ALL_CLEAN_MASK ( \ 55 + (1U << VMCB_INTERCEPTS) | (1U << VMCB_PERM_MAP) | \ 56 + (1U << VMCB_ASID) | (1U << VMCB_INTR) | \ 57 + (1U << VMCB_NPT) | (1U << VMCB_CR) | (1U << VMCB_DR) | \ 58 + (1U << VMCB_DT) | (1U << VMCB_SEG) | (1U << VMCB_CR2) | \ 59 + (1U << VMCB_LBR) | (1U << VMCB_AVIC) | \ 60 + (1U << VMCB_SW)) 58 61 59 62 /* TPR and CR2 are always written before VMRUN */ 60 63 #define VMCB_ALWAYS_DIRTY_MASK ((1U << VMCB_INTR) | (1U << VMCB_CR2)) ··· 250 237 251 238 static inline void vmcb_mark_all_clean(struct vmcb *vmcb) 252 239 { 253 - vmcb->control.clean = ((1 << VMCB_DIRTY_MAX) - 1) 240 + vmcb->control.clean = VMCB_ALL_CLEAN_MASK 254 241 & ~VMCB_ALWAYS_DIRTY_MASK; 255 242 } 256 243