diff options
-rw-r--r-- | arch/x86/include/asm/tdx.h | 4 | ||||
-rw-r--r-- | arch/x86/virt/vmx/tdx/tdxcall.S | 19 |
2 files changed, 23 insertions, 0 deletions
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index a69bb7d3061b..adcbe3f1de30 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -8,6 +8,7 @@ #include <asm/errno.h> #include <asm/ptrace.h> +#include <asm/trapnr.h> #include <asm/shared/tdx.h> /* @@ -20,6 +21,9 @@ #define TDX_SW_ERROR (TDX_ERROR | GENMASK_ULL(47, 40)) #define TDX_SEAMCALL_VMFAILINVALID (TDX_SW_ERROR | _UL(0xFFFF0000)) +#define TDX_SEAMCALL_GP (TDX_SW_ERROR | X86_TRAP_GP) +#define TDX_SEAMCALL_UD (TDX_SW_ERROR | X86_TRAP_UD) + #ifndef __ASSEMBLY__ /* diff --git a/arch/x86/virt/vmx/tdx/tdxcall.S b/arch/x86/virt/vmx/tdx/tdxcall.S index 3f0b83a9977e..016a2a1ec1d6 100644 --- a/arch/x86/virt/vmx/tdx/tdxcall.S +++ b/arch/x86/virt/vmx/tdx/tdxcall.S @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include <asm/asm-offsets.h> #include <asm/frame.h> +#include <asm/asm.h> #include <asm/tdx.h> /* @@ -85,6 +86,7 @@ .endif /* \saved */ .if \host +.Lseamcall\@: seamcall /* * SEAMCALL instruction is essentially a VMExit from VMX root @@ -191,11 +193,28 @@ .if \host .Lseamcall_vmfailinvalid\@: mov $TDX_SEAMCALL_VMFAILINVALID, %rax + jmp .Lseamcall_fail\@ + +.Lseamcall_trap\@: + /* + * SEAMCALL caused #GP or #UD. By reaching here RAX contains + * the trap number. Convert the trap number to the TDX error + * code by setting TDX_SW_ERROR to the high 32-bits of RAX. + * + * Note cannot OR TDX_SW_ERROR directly to RAX as OR instruction + * only accepts 32-bit immediate at most. + */ + movq $TDX_SW_ERROR, %rdi + orq %rdi, %rax + +.Lseamcall_fail\@: .if \ret && \saved /* pop the unused structure pointer back to RSI */ popq %rsi .endif jmp .Lout\@ + + _ASM_EXTABLE_FAULT(.Lseamcall\@, .Lseamcall_trap\@) .endif /* \host */ .endm |