Several changes to TDX initialization:
- Make early panic message visible to user;
- Relax SEPT_VE_DISABLE for debug TD. It helps to investigate bugs
resulting in access of unaccepted memory.
- Make sure NOTIFY_ENABLES is off to eliminate possible source of random
#VE.
The patchset makes use of ReportFatalError TDVMCALL. The definition of
the TDVMCALL has changed in recent GHCI update[1]. It now requires more
arguments handled by __tdx_hypercall(). The patch that expands
__tdx_hypercall() is the same as the patch included in TDX guest
enabling for Hyper-V.
[1] https://cdrdv2.intel.com/v1/dl/getContent/726790
v2:
- Split the first patch;
- Intoduce is_private_gpa();
- Apply Reviewed-by from Dave;
Kirill A. Shutemov (7):
x86/tdx: Fix typo in comment in __tdx_hypercall()
x86/tdx: Add more registers to struct tdx_hypercall_args
x86/tdx: Refactor __tdx_hypercall() to allow pass down more arguments
x86/tdx: Expand __tdx_hypercall() to handle more arguments
x86/tdx: Use ReportFatalError to report missing SEPT_VE_DISABLE
x86/tdx: Relax SEPT_VE_DISABLE check for debug TD
x86/tdx: Disable NOTIFY_ENABLES
arch/x86/coco/tdx/tdcall.S | 83 ++++++++++++++++++++++---------
arch/x86/coco/tdx/tdx.c | 62 ++++++++++++++++++++++-
arch/x86/include/asm/shared/tdx.h | 6 +++
arch/x86/kernel/asm-offsets.c | 6 +++
4 files changed, 131 insertions(+), 26 deletions(-)
--
2.38.2
struct tdx_hypercall_args is used to pass down hypercall arguments to
__tdx_hypercall() assembly routine.
Currently __tdx_hypercall() handles up to 6 arguments. In preparation to
changes in __tdx_hypercall(), expand the structure to 6 more registers
and generate asm offsets for them.
Signed-off-by: Kirill A. Shutemov <[email protected]>
---
arch/x86/include/asm/shared/tdx.h | 6 ++++++
arch/x86/kernel/asm-offsets.c | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
index e53f26228fbb..8068faa52de1 100644
--- a/arch/x86/include/asm/shared/tdx.h
+++ b/arch/x86/include/asm/shared/tdx.h
@@ -22,12 +22,18 @@
* This is a software only structure and not part of the TDX module/VMM ABI.
*/
struct tdx_hypercall_args {
+ u64 r8;
+ u64 r9;
u64 r10;
u64 r11;
u64 r12;
u64 r13;
u64 r14;
u64 r15;
+ u64 rdi;
+ u64 rsi;
+ u64 rbx;
+ u64 rdx;
};
/* Used to request services from the VMM */
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index 82c783da16a8..8650f29387e0 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -75,12 +75,18 @@ static void __used common(void)
OFFSET(TDX_MODULE_r11, tdx_module_output, r11);
BLANK();
+ OFFSET(TDX_HYPERCALL_r8, tdx_hypercall_args, r8);
+ OFFSET(TDX_HYPERCALL_r9, tdx_hypercall_args, r9);
OFFSET(TDX_HYPERCALL_r10, tdx_hypercall_args, r10);
OFFSET(TDX_HYPERCALL_r11, tdx_hypercall_args, r11);
OFFSET(TDX_HYPERCALL_r12, tdx_hypercall_args, r12);
OFFSET(TDX_HYPERCALL_r13, tdx_hypercall_args, r13);
OFFSET(TDX_HYPERCALL_r14, tdx_hypercall_args, r14);
OFFSET(TDX_HYPERCALL_r15, tdx_hypercall_args, r15);
+ OFFSET(TDX_HYPERCALL_rdi, tdx_hypercall_args, rdi);
+ OFFSET(TDX_HYPERCALL_rsi, tdx_hypercall_args, rsi);
+ OFFSET(TDX_HYPERCALL_rbx, tdx_hypercall_args, rbx);
+ OFFSET(TDX_HYPERCALL_rdx, tdx_hypercall_args, rdx);
BLANK();
OFFSET(BP_scratch, boot_params, scratch);
--
2.38.2
So far __tdx_hypercall() only handles six arguments for VMCALL.
Expanding it to six more register would allow to cover more use-cases
like ReportFatalError() and Hyper-V hypercalls.
With all preparations in place, the expansion is pretty straight
forward.
Signed-off-by: Kirill A. Shutemov <[email protected]>
---
arch/x86/coco/tdx/tdcall.S | 35 ++++++++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 5 deletions(-)
diff --git a/arch/x86/coco/tdx/tdcall.S b/arch/x86/coco/tdx/tdcall.S
index a9bb4cbb8197..5da06d1a9ba3 100644
--- a/arch/x86/coco/tdx/tdcall.S
+++ b/arch/x86/coco/tdx/tdcall.S
@@ -13,6 +13,12 @@
/*
* Bitmasks of exposed registers (with VMM).
*/
+#define TDX_RDX BIT(2)
+#define TDX_RBX BIT(3)
+#define TDX_RSI BIT(6)
+#define TDX_RDI BIT(7)
+#define TDX_R8 BIT(8)
+#define TDX_R9 BIT(9)
#define TDX_R10 BIT(10)
#define TDX_R11 BIT(11)
#define TDX_R12 BIT(12)
@@ -27,9 +33,9 @@
* details can be found in TDX GHCI specification, section
* titled "TDCALL [TDG.VP.VMCALL] leaf".
*/
-#define TDVMCALL_EXPOSE_REGS_MASK ( TDX_R10 | TDX_R11 | \
- TDX_R12 | TDX_R13 | \
- TDX_R14 | TDX_R15 )
+#define TDVMCALL_EXPOSE_REGS_MASK \
+ ( TDX_RDX | TDX_RBX | TDX_RSI | TDX_RDI | TDX_R8 | TDX_R9 | \
+ TDX_R10 | TDX_R11 | TDX_R12 | TDX_R13 | TDX_R14 | TDX_R15 )
/*
* __tdx_module_call() - Used by TDX guests to request services from
@@ -124,6 +130,7 @@ SYM_FUNC_START(__tdx_hypercall)
push %r14
push %r13
push %r12
+ push %rbx
push %rbp
/* Free RDI and RSI to be used as TDVMCALL arguments */
@@ -131,12 +138,18 @@ SYM_FUNC_START(__tdx_hypercall)
movq %rsi, %rbp
/* Copy hypercall registers from arg struct: */
+ movq TDX_HYPERCALL_r8(%rax), %r8
+ movq TDX_HYPERCALL_r9(%rax), %r9
movq TDX_HYPERCALL_r10(%rax), %r10
movq TDX_HYPERCALL_r11(%rax), %r11
movq TDX_HYPERCALL_r12(%rax), %r12
movq TDX_HYPERCALL_r13(%rax), %r13
movq TDX_HYPERCALL_r14(%rax), %r14
movq TDX_HYPERCALL_r15(%rax), %r15
+ movq TDX_HYPERCALL_rdi(%rax), %rdi
+ movq TDX_HYPERCALL_rsi(%rax), %rsi
+ movq TDX_HYPERCALL_rbx(%rax), %rbx
+ movq TDX_HYPERCALL_rdx(%rax), %rdx
push %rax
@@ -178,12 +191,18 @@ SYM_FUNC_START(__tdx_hypercall)
testq $TDX_HCALL_HAS_OUTPUT, %rbp
jz .Lout
+ movq %r8, TDX_HYPERCALL_r8(%rax)
+ movq %r9, TDX_HYPERCALL_r9(%rax)
movq %r10, TDX_HYPERCALL_r10(%rax)
movq %r11, TDX_HYPERCALL_r11(%rax)
movq %r12, TDX_HYPERCALL_r12(%rax)
movq %r13, TDX_HYPERCALL_r13(%rax)
movq %r14, TDX_HYPERCALL_r14(%rax)
movq %r15, TDX_HYPERCALL_r15(%rax)
+ movq %rdi, TDX_HYPERCALL_rdi(%rax)
+ movq %rsi, TDX_HYPERCALL_rsi(%rax)
+ movq %rbx, TDX_HYPERCALL_rbx(%rax)
+ movq %rdx, TDX_HYPERCALL_rdx(%rax)
.Lout:
/* TDVMCALL leaf return code is in R10 */
movq %r10, %rax
@@ -191,14 +210,20 @@ SYM_FUNC_START(__tdx_hypercall)
/*
* Zero out registers exposed to the VMM to avoid speculative execution
* with VMM-controlled values. This needs to include all registers
- * present in TDVMCALL_EXPOSE_REGS_MASK (except R12-R15). R12-R15
- * context will be restored.
+ * present in TDVMCALL_EXPOSE_REGS_MASK, except RBX, and R12-R15 which
+ * will be restored.
*/
+ xor %r8d, %r8d
+ xor %r9d, %r9d
xor %r10d, %r10d
xor %r11d, %r11d
+ xor %rdi, %rdi
+ xor %rsi, %rsi
+ xor %rdx, %rdx
/* Restore callee-saved GPRs as mandated by the x86_64 ABI */
pop %rbp
+ pop %rbx
pop %r12
pop %r13
pop %r14
--
2.38.2