OSDN Git Service

Merge tag 'hyperv-next-signed-20230902' of git://git.kernel.org/pub/scm/linux/kernel...
[tomoyo/tomoyo-test1.git] / arch / x86 / include / asm / mshyperv.h
index fa83d88..033b53f 100644 (file)
@@ -26,6 +26,7 @@
 union hv_ghcb;
 
 DECLARE_STATIC_KEY_FALSE(isolation_type_snp);
+DECLARE_STATIC_KEY_FALSE(isolation_type_tdx);
 
 typedef int (*hyperv_fill_flush_list_func)(
                struct hv_guest_mapping_flush_list *flush,
@@ -40,6 +41,7 @@ static inline unsigned char hv_get_nmi_reason(void)
 
 #if IS_ENABLED(CONFIG_HYPERV)
 extern int hyperv_init_cpuhp;
+extern bool hyperv_paravisor_present;
 
 extern void *hv_hypercall_pg;
 
@@ -47,10 +49,25 @@ extern u64 hv_current_partition_id;
 
 extern union hv_ghcb * __percpu *hv_ghcb_pg;
 
+bool hv_isolation_type_snp(void);
+bool hv_isolation_type_tdx(void);
+u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
+
+/*
+ * DEFAULT INIT GPAT and SEGMENT LIMIT value in struct VMSA
+ * to start AP in enlightened SEV guest.
+ */
+#define HV_AP_INIT_GPAT_DEFAULT                0x0007040600070406ULL
+#define HV_AP_SEGMENT_LIMIT            0xffffffff
+
 int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
 int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);
 int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
 
+/*
+ * If the hypercall involves no input or output parameters, the hypervisor
+ * ignores the corresponding GPA pointer.
+ */
 static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
 {
        u64 input_address = input ? virt_to_phys(input) : 0;
@@ -58,6 +75,19 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
        u64 hv_status;
 
 #ifdef CONFIG_X86_64
+       if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
+               return hv_tdx_hypercall(control, input_address, output_address);
+
+       if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
+               __asm__ __volatile__("mov %4, %%r8\n"
+                                    "vmmcall"
+                                    : "=a" (hv_status), ASM_CALL_CONSTRAINT,
+                                      "+c" (control), "+d" (input_address)
+                                    :  "r" (output_address)
+                                    : "cc", "memory", "r8", "r9", "r10", "r11");
+               return hv_status;
+       }
+
        if (!hv_hypercall_pg)
                return U64_MAX;
 
@@ -101,7 +131,16 @@ static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
        u64 hv_status;
 
 #ifdef CONFIG_X86_64
-       {
+       if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
+               return hv_tdx_hypercall(control, input1, 0);
+
+       if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
+               __asm__ __volatile__(
+                               "vmmcall"
+                               : "=a" (hv_status), ASM_CALL_CONSTRAINT,
+                               "+c" (control), "+d" (input1)
+                               :: "cc", "r8", "r9", "r10", "r11");
+       } else {
                __asm__ __volatile__(CALL_NOSPEC
                                     : "=a" (hv_status), ASM_CALL_CONSTRAINT,
                                       "+c" (control), "+d" (input1)
@@ -146,7 +185,17 @@ static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
        u64 hv_status;
 
 #ifdef CONFIG_X86_64
-       {
+       if (hv_isolation_type_tdx() && !hyperv_paravisor_present)
+               return hv_tdx_hypercall(control, input1, input2);
+
+       if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
+               __asm__ __volatile__("mov %4, %%r8\n"
+                                    "vmmcall"
+                                    : "=a" (hv_status), ASM_CALL_CONSTRAINT,
+                                      "+c" (control), "+d" (input1)
+                                    : "r" (input2)
+                                    : "cc", "r8", "r9", "r10", "r11");
+       } else {
                __asm__ __volatile__("mov %4, %%r8\n"
                                     CALL_NOSPEC
                                     : "=a" (hv_status), ASM_CALL_CONSTRAINT,
@@ -225,20 +274,24 @@ int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector,
 int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
 
 #ifdef CONFIG_AMD_MEM_ENCRYPT
-void hv_ghcb_msr_write(u64 msr, u64 value);
-void hv_ghcb_msr_read(u64 msr, u64 *value);
 bool hv_ghcb_negotiate_protocol(void);
 void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
-void hv_vtom_init(void);
+int hv_snp_boot_ap(int cpu, unsigned long start_ip);
 #else
-static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
-static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
 static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
 static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
-static inline void hv_vtom_init(void) {}
+static inline int hv_snp_boot_ap(int cpu, unsigned long start_ip) { return 0; }
 #endif
 
-extern bool hv_isolation_type_snp(void);
+#if defined(CONFIG_AMD_MEM_ENCRYPT) || defined(CONFIG_INTEL_TDX_GUEST)
+void hv_vtom_init(void);
+void hv_ivm_msr_write(u64 msr, u64 value);
+void hv_ivm_msr_read(u64 msr, u64 *value);
+#else
+static inline void hv_vtom_init(void) {}
+static inline void hv_ivm_msr_write(u64 msr, u64 value) {}
+static inline void hv_ivm_msr_read(u64 msr, u64 *value) {}
+#endif
 
 static inline bool hv_is_synic_reg(unsigned int reg)
 {