From: Kai Huang <kai.huang@intel.com>
To: peterz@infradead.org, kirill.shutemov@linux.intel.com,
linux-kernel@vger.kernel.org
Cc: dave.hansen@intel.com, tglx@linutronix.de, bp@alien8.de,
mingo@redhat.com, hpa@zytor.com, x86@kernel.org,
seanjc@google.com, pbonzini@redhat.com, isaku.yamahata@intel.com,
sathyanarayanan.kuppuswamy@linux.intel.com,
n.borisov.lkml@gmail.com, kai.huang@intel.com
Subject: [PATCH v4 11/12] x86/virt/tdx: Make TDX_MODULE_CALL handle SEAMCALL #UD and #GP
Date: Tue, 15 Aug 2023 23:02:05 +1200 [thread overview]
Message-ID: <de975832a367f476aab2d0eb0d9de66019a16b54.1692096753.git.kai.huang@intel.com> (raw)
In-Reply-To: <cover.1692096753.git.kai.huang@intel.com>
SEAMCALL instruction causes #UD if the CPU isn't in VMX operation.
Currently the TDX_MODULE_CALL assembly doesn't handle #UD, thus making
SEAMCALL when VMX is disabled would cause Oops.
Unfortunately, there are legal cases that SEAMCALL can be made when VMX
is disabled. For instance, VMX can be disabled due to emergency reboot
while there are still TDX guests running.
Extend the TDX_MODULE_CALL assembly to return an error code for #UD to
handle this case gracefully, e.g., KVM can then quietly eat all SEAMCALL
errors caused by emergency reboot.
SEAMCALL instruction also causes #GP when TDX isn't enabled by the BIOS.
Use _ASM_EXTABLE_FAULT() to catch both exceptions with the trap number
recorded, and define two new error codes by XORing the trap number to
the TDX_SW_ERROR. This opportunistically handles #GP too while using
the same simple assembly code.
A bonus is when kernel mistakenly calls SEAMCALL when CPU isn't in VMX
operation, or when TDX isn't enabled by the BIOS, or when the BIOS is
buggy, the kernel can get a nicer error code rather than a less
understandable Oops.
This is basically based on Peter's code.
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Kai Huang <kai.huang@intel.com>
---
v3 -> v4:
- Changed changelog to use emergency reboot as justification instead of
the erratum.
- Slight changed patch title to be more precise.
v2 -> v3:
- Added more material to the changelog to explain the TDX erratum
(hoping it can be merged together with this series).
- Changed to use %rdi to hold $TDX_SW_ERROR instead of %r12 as the
latter is callee-saved.
v1 -> v2:
- Skip saving output registers when SEAMCALL #UD/#GP
---
arch/x86/include/asm/tdx.h | 4 ++++
arch/x86/virt/vmx/tdx/tdxcall.S | 19 +++++++++++++++++++
2 files changed, 23 insertions(+)
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
--
2.41.0
next prev parent reply other threads:[~2023-08-15 11:04 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-15 11:01 [PATCH v4 00/12] Unify TDCALL/SEAMCALL and TDVMCALL assembly Kai Huang
2023-08-15 11:01 ` [PATCH v4 01/12] x86/tdx: Zero out the missing RSI in TDX_HYPERCALL macro Kai Huang
2023-08-15 11:01 ` [PATCH v4 02/12] x86/tdx: Skip saving output regs when SEAMCALL fails with VMFailInvalid Kai Huang
2023-08-25 23:25 ` kirill.shutemov
2023-08-15 11:01 ` [PATCH v4 03/12] x86/tdx: Make macros of TDCALLs consistent with the spec Kai Huang
2023-08-15 11:01 ` [PATCH v4 04/12] x86/tdx: Rename __tdx_module_call() to __tdcall() Kai Huang
2023-08-15 11:01 ` [PATCH v4 05/12] x86/tdx: Pass TDCALL/SEAMCALL input/output registers via a structure Kai Huang
2023-08-25 23:28 ` kirill.shutemov
2023-08-15 11:02 ` [PATCH v4 06/12] x86/tdx: Extend TDX_MODULE_CALL to support more TDCALL/SEAMCALL leafs Kai Huang
2023-08-25 23:36 ` kirill.shutemov
2023-08-26 0:52 ` Huang, Kai
2023-08-15 11:02 ` [PATCH v4 07/12] x86/tdx: Make TDX_HYPERCALL asm similar to TDX_MODULE_CALL Kai Huang
2023-08-25 23:35 ` kirill.shutemov
2023-08-26 0:50 ` Huang, Kai
2023-08-26 4:59 ` Huang, Kai
2023-08-30 13:10 ` kirill.shutemov
2023-08-30 22:20 ` Huang, Kai
2023-08-15 11:02 ` [PATCH v4 08/12] x86/tdx: Reimplement __tdx_hypercall() using TDX_MODULE_CALL asm Kai Huang
2023-08-15 11:02 ` [PATCH v4 09/12] x86/tdx: Remove 'struct tdx_hypercall_args' Kai Huang
2023-08-15 11:02 ` [PATCH v4 10/12] x86/virt/tdx: Wire up basic SEAMCALL functions Kai Huang
2023-08-15 11:02 ` Kai Huang [this message]
2023-08-25 23:41 ` [PATCH v4 11/12] x86/virt/tdx: Make TDX_MODULE_CALL handle SEAMCALL #UD and #GP kirill.shutemov
2023-08-15 11:02 ` [PATCH v4 12/12] x86/virt/tdx: Adjust 'struct tdx_module_args' to use x86 "register index" layout Kai Huang
2023-08-25 23:44 ` kirill.shutemov
2023-08-26 0:45 ` Huang, Kai
2023-09-05 23:01 ` [PATCH v4 00/12] Unify TDCALL/SEAMCALL and TDVMCALL assembly Huang, Kai
2023-09-06 11:57 ` Peter Zijlstra
2023-09-06 12:21 ` Huang, Kai
2023-09-14 0:22 ` Isaku Yamahata
2023-09-14 0:45 ` Huang, Kai
2023-09-11 17:08 ` Paolo Bonzini
2023-09-11 22:29 ` Huang, Kai
2023-09-12 0:57 ` Huang, Kai
2023-09-12 13:37 ` Paolo Bonzini
2023-09-14 0:23 ` Isaku Yamahata
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=de975832a367f476aab2d0eb0d9de66019a16b54.1692096753.git.kai.huang@intel.com \
--to=kai.huang@intel.com \
--cc=bp@alien8.de \
--cc=dave.hansen@intel.com \
--cc=hpa@zytor.com \
--cc=isaku.yamahata@intel.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=n.borisov.lkml@gmail.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=sathyanarayanan.kuppuswamy@linux.intel.com \
--cc=seanjc@google.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®