| 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | #ifndef _ASM_X86_SHARED_TDX_H |
| 3 | #define _ASM_X86_SHARED_TDX_H |
| 4 | |
| 5 | #include <linux/bits.h> |
| 6 | #include <linux/types.h> |
| 7 | |
| 8 | #define TDX_HYPERCALL_STANDARD 0 |
| 9 | |
| 10 | #define TDX_CPUID_LEAF_ID 0x21 |
| 11 | #define TDX_IDENT "IntelTDX " |
| 12 | |
| 13 | /* TDX module Call Leaf IDs */ |
| 14 | #define TDG_VP_VMCALL 0 |
| 15 | #define TDG_VP_INFO 1 |
| 16 | #define TDG_MR_RTMR_EXTEND 2 |
| 17 | #define TDG_VP_VEINFO_GET 3 |
| 18 | #define TDG_MR_REPORT 4 |
| 19 | #define TDG_MEM_PAGE_ACCEPT 6 |
| 20 | #define TDG_VM_RD 7 |
| 21 | #define TDG_VM_WR 8 |
| 22 | |
| 23 | /* TDX attributes */ |
| 24 | #define TDX_ATTR_DEBUG_BIT 0 |
| 25 | #define TDX_ATTR_DEBUG BIT_ULL(TDX_ATTR_DEBUG_BIT) |
| 26 | #define TDX_ATTR_HGS_PLUS_PROF_BIT 4 |
| 27 | #define TDX_ATTR_HGS_PLUS_PROF BIT_ULL(TDX_ATTR_HGS_PLUS_PROF_BIT) |
| 28 | #define TDX_ATTR_PERF_PROF_BIT 5 |
| 29 | #define TDX_ATTR_PERF_PROF BIT_ULL(TDX_ATTR_PERF_PROF_BIT) |
| 30 | #define TDX_ATTR_PMT_PROF_BIT 6 |
| 31 | #define TDX_ATTR_PMT_PROF BIT_ULL(TDX_ATTR_PMT_PROF_BIT) |
| 32 | #define TDX_ATTR_ICSSD_BIT 16 |
| 33 | #define TDX_ATTR_ICSSD BIT_ULL(TDX_ATTR_ICSSD_BIT) |
| 34 | #define TDX_ATTR_LASS_BIT 27 |
| 35 | #define TDX_ATTR_LASS BIT_ULL(TDX_ATTR_LASS_BIT) |
| 36 | #define TDX_ATTR_SEPT_VE_DISABLE_BIT 28 |
| 37 | #define TDX_ATTR_SEPT_VE_DISABLE BIT_ULL(TDX_ATTR_SEPT_VE_DISABLE_BIT) |
| 38 | #define TDX_ATTR_MIGRTABLE_BIT 29 |
| 39 | #define TDX_ATTR_MIGRTABLE BIT_ULL(TDX_ATTR_MIGRTABLE_BIT) |
| 40 | #define TDX_ATTR_PKS_BIT 30 |
| 41 | #define TDX_ATTR_PKS BIT_ULL(TDX_ATTR_PKS_BIT) |
| 42 | #define TDX_ATTR_KL_BIT 31 |
| 43 | #define TDX_ATTR_KL BIT_ULL(TDX_ATTR_KL_BIT) |
| 44 | #define TDX_ATTR_TPA_BIT 62 |
| 45 | #define TDX_ATTR_TPA BIT_ULL(TDX_ATTR_TPA_BIT) |
| 46 | #define TDX_ATTR_PERFMON_BIT 63 |
| 47 | #define TDX_ATTR_PERFMON BIT_ULL(TDX_ATTR_PERFMON_BIT) |
| 48 | |
| 49 | /* TDX TD-Scope Metadata. To be used by TDG.VM.WR and TDG.VM.RD */ |
| 50 | #define TDCS_CONFIG_FLAGS 0x1110000300000016 |
| 51 | #define TDCS_TD_CTLS 0x1110000300000017 |
| 52 | #define TDCS_NOTIFY_ENABLES 0x9100000000000010 |
| 53 | #define TDCS_TOPOLOGY_ENUM_CONFIGURED 0x9100000000000019 |
| 54 | |
| 55 | /* TDCS_CONFIG_FLAGS bits */ |
| 56 | #define TDCS_CONFIG_FLEXIBLE_PENDING_VE BIT_ULL(1) |
| 57 | |
| 58 | /* TDCS_TD_CTLS bits */ |
| 59 | #define TD_CTLS_PENDING_VE_DISABLE_BIT 0 |
| 60 | #define TD_CTLS_PENDING_VE_DISABLE BIT_ULL(TD_CTLS_PENDING_VE_DISABLE_BIT) |
| 61 | #define TD_CTLS_ENUM_TOPOLOGY_BIT 1 |
| 62 | #define TD_CTLS_ENUM_TOPOLOGY BIT_ULL(TD_CTLS_ENUM_TOPOLOGY_BIT) |
| 63 | #define TD_CTLS_VIRT_CPUID2_BIT 2 |
| 64 | #define TD_CTLS_VIRT_CPUID2 BIT_ULL(TD_CTLS_VIRT_CPUID2_BIT) |
| 65 | #define TD_CTLS_REDUCE_VE_BIT 3 |
| 66 | #define TD_CTLS_REDUCE_VE BIT_ULL(TD_CTLS_REDUCE_VE_BIT) |
| 67 | #define TD_CTLS_LOCK_BIT 63 |
| 68 | #define TD_CTLS_LOCK BIT_ULL(TD_CTLS_LOCK_BIT) |
| 69 | |
| 70 | /* TDX hypercall Leaf IDs */ |
| 71 | #define TDVMCALL_GET_TD_VM_CALL_INFO 0x10000 |
| 72 | #define TDVMCALL_MAP_GPA 0x10001 |
| 73 | #define TDVMCALL_GET_QUOTE 0x10002 |
| 74 | #define TDVMCALL_REPORT_FATAL_ERROR 0x10003 |
| 75 | |
| 76 | /* |
| 77 | * TDG.VP.VMCALL Status Codes (returned in R10) |
| 78 | */ |
| 79 | #define TDVMCALL_STATUS_SUCCESS 0x0000000000000000ULL |
| 80 | #define TDVMCALL_STATUS_RETRY 0x0000000000000001ULL |
| 81 | #define TDVMCALL_STATUS_INVALID_OPERAND 0x8000000000000000ULL |
| 82 | #define TDVMCALL_STATUS_ALIGN_ERROR 0x8000000000000002ULL |
| 83 | |
| 84 | /* |
| 85 | * Bitmasks of exposed registers (with VMM). |
| 86 | */ |
| 87 | #define TDX_RDX BIT(2) |
| 88 | #define TDX_RBX BIT(3) |
| 89 | #define TDX_RSI BIT(6) |
| 90 | #define TDX_RDI BIT(7) |
| 91 | #define TDX_R8 BIT(8) |
| 92 | #define TDX_R9 BIT(9) |
| 93 | #define TDX_R10 BIT(10) |
| 94 | #define TDX_R11 BIT(11) |
| 95 | #define TDX_R12 BIT(12) |
| 96 | #define TDX_R13 BIT(13) |
| 97 | #define TDX_R14 BIT(14) |
| 98 | #define TDX_R15 BIT(15) |
| 99 | |
| 100 | /* |
| 101 | * These registers are clobbered to hold arguments for each |
| 102 | * TDVMCALL. They are safe to expose to the VMM. |
| 103 | * Each bit in this mask represents a register ID. Bit field |
| 104 | * details can be found in TDX GHCI specification, section |
| 105 | * titled "TDCALL [TDG.VP.VMCALL] leaf". |
| 106 | */ |
| 107 | #define TDVMCALL_EXPOSE_REGS_MASK \ |
| 108 | (TDX_RDX | TDX_RBX | TDX_RSI | TDX_RDI | TDX_R8 | TDX_R9 | \ |
| 109 | TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15) |
| 110 | |
| 111 | /* TDX supported page sizes from the TDX module ABI. */ |
| 112 | #define TDX_PS_4K 0 |
| 113 | #define TDX_PS_2M 1 |
| 114 | #define TDX_PS_1G 2 |
| 115 | #define TDX_PS_NR (TDX_PS_1G + 1) |
| 116 | |
| 117 | #ifndef __ASSEMBLER__ |
| 118 | |
| 119 | #include <linux/compiler_attributes.h> |
| 120 | |
| 121 | /* |
| 122 | * Used in __tdcall*() to gather the input/output registers' values of the |
| 123 | * TDCALL instruction when requesting services from the TDX module. This is a |
| 124 | * software only structure and not part of the TDX module/VMM ABI |
| 125 | */ |
| 126 | struct tdx_module_args { |
| 127 | /* callee-clobbered */ |
| 128 | u64 rcx; |
| 129 | u64 rdx; |
| 130 | u64 r8; |
| 131 | u64 r9; |
| 132 | /* extra callee-clobbered */ |
| 133 | u64 r10; |
| 134 | u64 r11; |
| 135 | /* callee-saved + rdi/rsi */ |
| 136 | u64 r12; |
| 137 | u64 r13; |
| 138 | u64 r14; |
| 139 | u64 r15; |
| 140 | u64 rbx; |
| 141 | u64 rdi; |
| 142 | u64 rsi; |
| 143 | }; |
| 144 | |
| 145 | /* Used to communicate with the TDX module */ |
| 146 | u64 __tdcall(u64 fn, struct tdx_module_args *args); |
| 147 | u64 __tdcall_ret(u64 fn, struct tdx_module_args *args); |
| 148 | u64 __tdcall_saved_ret(u64 fn, struct tdx_module_args *args); |
| 149 | |
| 150 | /* Used to request services from the VMM */ |
| 151 | u64 __tdx_hypercall(struct tdx_module_args *args); |
| 152 | |
| 153 | /* |
| 154 | * Wrapper for standard use of __tdx_hypercall with no output aside from |
| 155 | * return code. |
| 156 | */ |
| 157 | static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15) |
| 158 | { |
| 159 | struct tdx_module_args args = { |
| 160 | .r10 = TDX_HYPERCALL_STANDARD, |
| 161 | .r11 = fn, |
| 162 | .r12 = r12, |
| 163 | .r13 = r13, |
| 164 | .r14 = r14, |
| 165 | .r15 = r15, |
| 166 | }; |
| 167 | |
| 168 | return __tdx_hypercall(args: &args); |
| 169 | } |
| 170 | |
| 171 | |
| 172 | /* Called from __tdx_hypercall() for unrecoverable failure */ |
| 173 | void __noreturn __tdx_hypercall_failed(void); |
| 174 | |
| 175 | bool tdx_accept_memory(phys_addr_t start, phys_addr_t end); |
| 176 | |
| 177 | /* |
| 178 | * The TDG.VP.VMCALL-Instruction-execution sub-functions are defined |
| 179 | * independently from but are currently matched 1:1 with VMX EXIT_REASONs. |
| 180 | * Reusing the KVM EXIT_REASON macros makes it easier to connect the host and |
| 181 | * guest sides of these calls. |
| 182 | */ |
| 183 | static __always_inline u64 hcall_func(u64 exit_reason) |
| 184 | { |
| 185 | return exit_reason; |
| 186 | } |
| 187 | |
| 188 | #endif /* !__ASSEMBLER__ */ |
| 189 | #endif /* _ASM_X86_SHARED_TDX_H */ |
| 190 | |