]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - arch/x86/include/asm/svm.h
KVM: SVM: Modify 64 bit intercept field to two 32 bit vectors
[mirror_ubuntu-hirsute-kernel.git] / arch / x86 / include / asm / svm.h
index 8a1f5382a4eab234e83c0ad98af1557098e8a477..c2ae1dfb37a47d3590ad632335dcb7192599c3d8 100644 (file)
@@ -3,10 +3,53 @@
 #define __SVM_H
 
 #include <uapi/asm/svm.h>
-
+#include <uapi/asm/kvm.h>
+
+/*
+ * 32-bit intercept words in the VMCB Control Area, starting
+ * at Byte offset 000h.
+ */
+
+enum intercept_words {
+       INTERCEPT_CR = 0,
+       INTERCEPT_DR,
+       INTERCEPT_EXCEPTION,
+       INTERCEPT_WORD3,
+       INTERCEPT_WORD4,
+       MAX_INTERCEPT,
+};
 
 enum {
-       INTERCEPT_INTR,
+       /* Byte offset 000h (word 0) */
+       INTERCEPT_CR0_READ = 0,
+       INTERCEPT_CR3_READ = 3,
+       INTERCEPT_CR4_READ = 4,
+       INTERCEPT_CR8_READ = 8,
+       INTERCEPT_CR0_WRITE = 16,
+       INTERCEPT_CR3_WRITE = 16 + 3,
+       INTERCEPT_CR4_WRITE = 16 + 4,
+       INTERCEPT_CR8_WRITE = 16 + 8,
+       /* Byte offset 004h (word 1) */
+       INTERCEPT_DR0_READ = 32,
+       INTERCEPT_DR1_READ,
+       INTERCEPT_DR2_READ,
+       INTERCEPT_DR3_READ,
+       INTERCEPT_DR4_READ,
+       INTERCEPT_DR5_READ,
+       INTERCEPT_DR6_READ,
+       INTERCEPT_DR7_READ,
+       INTERCEPT_DR0_WRITE = 48,
+       INTERCEPT_DR1_WRITE,
+       INTERCEPT_DR2_WRITE,
+       INTERCEPT_DR3_WRITE,
+       INTERCEPT_DR4_WRITE,
+       INTERCEPT_DR5_WRITE,
+       INTERCEPT_DR6_WRITE,
+       INTERCEPT_DR7_WRITE,
+       /* Byte offset 008h (word 2) */
+       INTERCEPT_EXCEPTION_OFFSET = 64,
+       /* Byte offset 00Ch (word 3) */
+       INTERCEPT_INTR = 96,
        INTERCEPT_NMI,
        INTERCEPT_SMI,
        INTERCEPT_INIT,
@@ -38,7 +81,8 @@ enum {
        INTERCEPT_TASK_SWITCH,
        INTERCEPT_FERR_FREEZE,
        INTERCEPT_SHUTDOWN,
-       INTERCEPT_VMRUN,
+       /* Byte offset 010h (word 4) */
+       INTERCEPT_VMRUN = 128,
        INTERCEPT_VMMCALL,
        INTERCEPT_VMLOAD,
        INTERCEPT_VMSAVE,
@@ -57,11 +101,8 @@ enum {
 
 
 struct __attribute__ ((__packed__)) vmcb_control_area {
-       u32 intercept_cr;
-       u32 intercept_dr;
-       u32 intercept_exceptions;
-       u64 intercept;
-       u8 reserved_1[40];
+       u32 intercepts[MAX_INTERCEPT];
+       u32 reserved_1[15 - MAX_INTERCEPT];
        u16 pause_filter_thresh;
        u16 pause_filter_count;
        u64 iopm_base_pa;
@@ -150,14 +191,14 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
 #define SVM_NESTED_CTL_NP_ENABLE       BIT(0)
 #define SVM_NESTED_CTL_SEV_ENABLE      BIT(1)
 
-struct __attribute__ ((__packed__)) vmcb_seg {
+struct vmcb_seg {
        u16 selector;
        u16 attrib;
        u32 limit;
        u64 base;
-};
+} __packed;
 
-struct __attribute__ ((__packed__)) vmcb_save_area {
+struct vmcb_save_area {
        struct vmcb_seg es;
        struct vmcb_seg cs;
        struct vmcb_seg ss;
@@ -200,20 +241,67 @@ struct __attribute__ ((__packed__)) vmcb_save_area {
        u64 br_to;
        u64 last_excp_from;
        u64 last_excp_to;
-};
 
+       /*
+        * The following part of the save area is valid only for
+        * SEV-ES guests when referenced through the GHCB.
+        */
+       u8 reserved_7[104];
+       u64 reserved_8;         /* rax already available at 0x01f8 */
+       u64 rcx;
+       u64 rdx;
+       u64 rbx;
+       u64 reserved_9;         /* rsp already available at 0x01d8 */
+       u64 rbp;
+       u64 rsi;
+       u64 rdi;
+       u64 r8;
+       u64 r9;
+       u64 r10;
+       u64 r11;
+       u64 r12;
+       u64 r13;
+       u64 r14;
+       u64 r15;
+       u8 reserved_10[16];
+       u64 sw_exit_code;
+       u64 sw_exit_info_1;
+       u64 sw_exit_info_2;
+       u64 sw_scratch;
+       u8 reserved_11[56];
+       u64 xcr0;
+       u8 valid_bitmap[16];
+       u64 x87_state_gpa;
+} __packed;
+
+struct ghcb {
+       struct vmcb_save_area save;
+       u8 reserved_save[2048 - sizeof(struct vmcb_save_area)];
+
+       u8 shared_buffer[2032];
+
+       u8 reserved_1[10];
+       u16 protocol_version;   /* negotiated SEV-ES/GHCB protocol version */
+       u32 ghcb_usage;
+} __packed;
+
+
+#define EXPECTED_VMCB_SAVE_AREA_SIZE           1032
+#define EXPECTED_VMCB_CONTROL_AREA_SIZE                256
+#define EXPECTED_GHCB_SIZE                     PAGE_SIZE
 
 static inline void __unused_size_checks(void)
 {
-       BUILD_BUG_ON(sizeof(struct vmcb_save_area) != 0x298);
-       BUILD_BUG_ON(sizeof(struct vmcb_control_area) != 256);
+       BUILD_BUG_ON(sizeof(struct vmcb_save_area)      != EXPECTED_VMCB_SAVE_AREA_SIZE);
+       BUILD_BUG_ON(sizeof(struct vmcb_control_area)   != EXPECTED_VMCB_CONTROL_AREA_SIZE);
+       BUILD_BUG_ON(sizeof(struct ghcb)                != EXPECTED_GHCB_SIZE);
 }
 
-struct __attribute__ ((__packed__)) vmcb {
+struct vmcb {
        struct vmcb_control_area control;
        u8 reserved_control[1024 - sizeof(struct vmcb_control_area)];
        struct vmcb_save_area save;
-};
+} __packed;
 
 #define SVM_CPUID_FUNC 0x8000000a
 
@@ -240,32 +328,6 @@ struct __attribute__ ((__packed__)) vmcb {
 #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK
 #define SVM_SELECTOR_CODE_MASK (1 << 3)
 
-#define INTERCEPT_CR0_READ     0
-#define INTERCEPT_CR3_READ     3
-#define INTERCEPT_CR4_READ     4
-#define INTERCEPT_CR8_READ     8
-#define INTERCEPT_CR0_WRITE    (16 + 0)
-#define INTERCEPT_CR3_WRITE    (16 + 3)
-#define INTERCEPT_CR4_WRITE    (16 + 4)
-#define INTERCEPT_CR8_WRITE    (16 + 8)
-
-#define INTERCEPT_DR0_READ     0
-#define INTERCEPT_DR1_READ     1
-#define INTERCEPT_DR2_READ     2
-#define INTERCEPT_DR3_READ     3
-#define INTERCEPT_DR4_READ     4
-#define INTERCEPT_DR5_READ     5
-#define INTERCEPT_DR6_READ     6
-#define INTERCEPT_DR7_READ     7
-#define INTERCEPT_DR0_WRITE    (16 + 0)
-#define INTERCEPT_DR1_WRITE    (16 + 1)
-#define INTERCEPT_DR2_WRITE    (16 + 2)
-#define INTERCEPT_DR3_WRITE    (16 + 3)
-#define INTERCEPT_DR4_WRITE    (16 + 4)
-#define INTERCEPT_DR5_WRITE    (16 + 5)
-#define INTERCEPT_DR6_WRITE    (16 + 6)
-#define INTERCEPT_DR7_WRITE    (16 + 7)
-
 #define SVM_EVTINJ_VEC_MASK 0xff
 
 #define SVM_EVTINJ_TYPE_SHIFT 8
@@ -298,4 +360,47 @@ struct __attribute__ ((__packed__)) vmcb {
 
 #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP)
 
+/* GHCB Accessor functions */
+
+#define GHCB_BITMAP_IDX(field)                                                 \
+       (offsetof(struct vmcb_save_area, field) / sizeof(u64))
+
+#define DEFINE_GHCB_ACCESSORS(field)                                           \
+       static inline bool ghcb_##field##_is_valid(const struct ghcb *ghcb)     \
+       {                                                                       \
+               return test_bit(GHCB_BITMAP_IDX(field),                         \
+                               (unsigned long *)&ghcb->save.valid_bitmap);     \
+       }                                                                       \
+                                                                               \
+       static inline void ghcb_set_##field(struct ghcb *ghcb, u64 value)       \
+       {                                                                       \
+               __set_bit(GHCB_BITMAP_IDX(field),                               \
+                         (unsigned long *)&ghcb->save.valid_bitmap);           \
+               ghcb->save.field = value;                                       \
+       }
+
+DEFINE_GHCB_ACCESSORS(cpl)
+DEFINE_GHCB_ACCESSORS(rip)
+DEFINE_GHCB_ACCESSORS(rsp)
+DEFINE_GHCB_ACCESSORS(rax)
+DEFINE_GHCB_ACCESSORS(rcx)
+DEFINE_GHCB_ACCESSORS(rdx)
+DEFINE_GHCB_ACCESSORS(rbx)
+DEFINE_GHCB_ACCESSORS(rbp)
+DEFINE_GHCB_ACCESSORS(rsi)
+DEFINE_GHCB_ACCESSORS(rdi)
+DEFINE_GHCB_ACCESSORS(r8)
+DEFINE_GHCB_ACCESSORS(r9)
+DEFINE_GHCB_ACCESSORS(r10)
+DEFINE_GHCB_ACCESSORS(r11)
+DEFINE_GHCB_ACCESSORS(r12)
+DEFINE_GHCB_ACCESSORS(r13)
+DEFINE_GHCB_ACCESSORS(r14)
+DEFINE_GHCB_ACCESSORS(r15)
+DEFINE_GHCB_ACCESSORS(sw_exit_code)
+DEFINE_GHCB_ACCESSORS(sw_exit_info_1)
+DEFINE_GHCB_ACCESSORS(sw_exit_info_2)
+DEFINE_GHCB_ACCESSORS(sw_scratch)
+DEFINE_GHCB_ACCESSORS(xcr0)
+
 #endif