mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Chao Gao <chao.gao@intel.com>
To: linux-coco@lists.linux.dev, x86@kernel.org, kvm@vger.kernel.org
Cc: seanjc@google.com, pbonzini@redhat.com, eddie.dong@intel.com,
	kirill.shutemov@intel.com, dave.hansen@intel.com,
	dan.j.williams@intel.com, kai.huang@intel.com,
	isaku.yamahata@intel.com, elena.reshetova@intel.com,
	rick.p.edgecombe@intel.com, Chao Gao <chao.gao@intel.com>,
	Farrah Chen <farrah.chen@intel.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH 03/20] x86/virt/seamldr: Introduce a wrapper for P-SEAMLDR SEAMCALLs
Date: Fri, 23 May 2025 02:52:26 -0700	[thread overview]
Message-ID: <20250523095322.88774-4-chao.gao@intel.com> (raw)
In-Reply-To: <20250523095322.88774-1-chao.gao@intel.com>

P-SEAMLDR is another component alongside the TDX module within the
protected SEAM range. Software can invoke its functions by executing the
SEAMCALL instruction with the 63 bit of RAX set to 1. P-SEAMLDR SEAMCALLs
differ from those of the TDX module in terms of error codes and the
handling of the current VMCS.

Add a wrapper for P-SEAMLDR SEAMCALLs based on the SEAMCALL infrastructure.

Intel® Trust Domain CPU Architectural Extensions (May 2021 edition)
Chapter 2.3 states:

SEAMRET from the P-SEAMLDR clears the current VMCS structure pointed to by
the current-VMCS pointer. A VMM that invokes the P-SEAMLDR using SEAMCALL
must reload the current-VMCS, if required, using the VMPTRLD instruction.

So, save and restore the current-VMCS pointer using VMPTRST and VMPTRLD
instructions to avoid breaking KVM, which manages the current-VMCS.

Disable interrupts to prevent KVM code from interfering with P-SEAMLDR
SEAMCALLs. For example, if a vCPU is scheduled before the current VMCS is
restored, it may encounter an invalid current VMCS, causing its VMX
instruction to fail. Additionally, if KVM sends IPIs to invalidate a
current VMCS and the invalidation occurs right after the current VMCS is
saved, that VMCS will be reloaded after P-SEAMLDR SEAMCALLs, leading to
unexpected behavior.

NMIs are not a problem, as the only scenario where instructions relying on
the current-VMCS are used is during guest PMI handling in KVM. This occurs
immediately after VM exits with IRQ and NMI disabled, ensuring no
interference with P-SEAMLDR SEAMCALLs.

Signed-off-by: Chao Gao <chao.gao@intel.com>
Tested-by: Farrah Chen <farrah.chen@intel.com>
---
 arch/x86/Kconfig                | 10 ++++++++
 arch/x86/virt/vmx/tdx/Makefile  |  1 +
 arch/x86/virt/vmx/tdx/seamldr.c | 44 +++++++++++++++++++++++++++++++++
 arch/x86/virt/vmx/vmx.h         | 40 ++++++++++++++++++++++++++++++
 4 files changed, 95 insertions(+)
 create mode 100644 arch/x86/virt/vmx/tdx/seamldr.c
 create mode 100644 arch/x86/virt/vmx/vmx.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 4b9f378e05f6..8b1e0986b7f8 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1932,6 +1932,16 @@ config INTEL_TDX_HOST
 
 	  If unsure, say N.
 
+config INTEL_TDX_MODULE_UPDATE
+	bool "Intel TDX module runtime update"
+	depends on INTEL_TDX_HOST
+	help
+	  This enables the kernel to support TDX module runtime update. This allows
+	  the admin to upgrade the TDX module to a newer one without the need to
+	  terminate running TDX guests.
+
+	  If unsure, say N.
+
 config EFI
 	bool "EFI runtime service support"
 	depends on ACPI
diff --git a/arch/x86/virt/vmx/tdx/Makefile b/arch/x86/virt/vmx/tdx/Makefile
index 90da47eb85ee..26aea3531c36 100644
--- a/arch/x86/virt/vmx/tdx/Makefile
+++ b/arch/x86/virt/vmx/tdx/Makefile
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += seamcall.o tdx.o
+obj-$(CONFIG_INTEL_TDX_MODULE_UPDATE) += seamldr.o
diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamldr.c
new file mode 100644
index 000000000000..a252f1ae3483
--- /dev/null
+++ b/arch/x86/virt/vmx/tdx/seamldr.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(c) 2025 Intel Corporation.
+ *
+ * Intel TDX module runtime update
+ */
+#define pr_fmt(fmt)	"seamldr: " fmt
+
+#include <linux/cleanup.h>
+
+#include "tdx.h"
+#include "../vmx.h"
+
+static __maybe_unused int seamldr_call(u64 fn, struct tdx_module_args *args)
+{
+	u64 vmcs;
+	int ret;
+
+	if (!is_seamldr_call(fn))
+		return -EINVAL;
+
+	/*
+	 * SEAMRET from P-SEAMLDR invalidates the current-VMCS pointer.
+	 * Save/restore current-VMCS pointer across P-SEAMLDR SEAMCALLs so
+	 * that VMX instructions won't fail due to an invalid current-VMCS.
+	 *
+	 * Disable interrupt to prevent SMP call functions from seeing the
+	 * invalid current-VMCS.
+	 */
+	guard(irqsave)();
+
+	ret = cpu_vmcs_store(&vmcs);
+	if (ret)
+		return ret;
+
+	ret = seamldr_prerr(fn, args);
+
+	/* Restore current-VMCS pointer */
+#define INVALID_VMCS   -1ULL
+	if (vmcs != INVALID_VMCS)
+	       WARN_ON_ONCE(cpu_vmcs_load(vmcs));
+
+	return ret;
+}
diff --git a/arch/x86/virt/vmx/vmx.h b/arch/x86/virt/vmx/vmx.h
new file mode 100644
index 000000000000..51e6460fd1fd
--- /dev/null
+++ b/arch/x86/virt/vmx/vmx.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ARCH_X86_VIRT_VMX_H
+#define ARCH_X86_VIRT_VMX_H
+
+#include <linux/printk.h>
+
+static inline int cpu_vmcs_load(u64 vmcs_pa)
+{
+	asm goto("1: vmptrld %0\n\t"
+			  ".byte 0x2e\n\t" /* branch not taken hint */
+			  "jna %l[error]\n\t"
+			  _ASM_EXTABLE(1b, %l[fault])
+			  : : "m" (vmcs_pa) : "cc" : error, fault);
+	return 0;
+
+error:
+	pr_err_once("vmptrld failed: %llx\n", vmcs_pa);
+	return -EIO;
+fault:
+	pr_err_once("vmptrld faulted\n");
+	return -EIO;
+}
+
+static inline int cpu_vmcs_store(u64 *vmcs_pa)
+{
+	int ret = -EIO;
+
+	asm volatile("1: vmptrst %0\n\t"
+		     "mov $0, %1\n\t"
+		     "2:\n\t"
+		     _ASM_EXTABLE(1b, 2b)
+		     : "=m" (*vmcs_pa), "+r" (ret) : :);
+
+	if (ret)
+		pr_err_once("vmptrst faulted\n");
+
+	return ret;
+}
+
+#endif
-- 
2.47.1


  parent reply	other threads:[~2025-05-23  9:53 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-23  9:52 [RFC PATCH 00/20] TD-Preserving updates Chao Gao
2025-05-23  9:52 ` [RFC PATCH 01/20] x86/virt/tdx: Print SEAMCALL leaf numbers in decimal Chao Gao
2025-06-02 23:44   ` Huang, Kai
2025-05-23  9:52 ` [RFC PATCH 02/20] x86/virt/tdx: Prepare to support P-SEAMLDR SEAMCALLs Chao Gao
2025-06-04 12:22   ` Huang, Kai
2025-06-04 13:14     ` Chao Gao
2025-06-05  0:14       ` Huang, Kai
2025-05-23  9:52 ` Chao Gao [this message]
2025-06-03 11:22   ` [RFC PATCH 03/20] x86/virt/seamldr: Introduce a wrapper for " Nikolay Borisov
2025-06-09  7:53     ` Chao Gao
2025-06-09  8:02       ` Nikolay Borisov
2025-06-10  1:03         ` Chao Gao
2025-06-10  6:52           ` Nikolay Borisov
2025-06-10 15:02             ` Dave Hansen
2025-07-11 13:59   ` Sean Christopherson
2025-07-14  9:21     ` Chao Gao
2025-05-23  9:52 ` [RFC PATCH 04/20] x86/virt/tdx: Introduce a "tdx" subsystem and "tsm" device Chao Gao
2025-06-02 23:44   ` Huang, Kai
2025-06-05  8:34     ` Chao Gao
2025-07-31 20:17       ` dan.j.williams
2025-05-23  9:52 ` [RFC PATCH 05/20] x86/virt/tdx: Export tdx module attributes via sysfs Chao Gao
2025-06-02 23:49   ` Huang, Kai
2025-06-10  1:37     ` Chao Gao
2025-06-11  2:09       ` Huang, Kai
2025-06-11  7:45         ` Chao Gao
2025-05-23  9:52 ` [RFC PATCH 06/20] x86/virt/seamldr: Add a helper to read P-SEAMLDR information Chao Gao
2025-05-23  9:52 ` [RFC PATCH 07/20] x86/virt/tdx: Expose SEAMLDR information via sysfs Chao Gao
2025-07-29  4:55   ` Xu Yilun
2025-07-29 10:00     ` Chao Gao
2025-07-31 21:01     ` dan.j.williams
2025-08-01  2:07       ` Xu Yilun
2025-08-01 15:24         ` dan.j.williams
2025-08-04  7:00           ` Xu Yilun
2025-08-05  0:17             ` dan.j.williams
2025-08-05  0:47               ` Sean Christopherson
2025-08-05  4:02                 ` dan.j.williams
2025-08-05 13:49                   ` Sean Christopherson
2025-08-06 16:33                     ` dan.j.williams
2025-08-06  3:03                   ` Xu Yilun
2025-05-23  9:52 ` [RFC PATCH 08/20] x86/virt/seamldr: Implement FW_UPLOAD sysfs ABI for TD-Preserving Updates Chao Gao
2025-06-16 22:55   ` Sagi Shahar
2025-06-17  7:55     ` Chao Gao
2025-05-23  9:52 ` [RFC PATCH 09/20] x86/virt/seamldr: Allocate and populate a module update request Chao Gao
2025-05-23  9:52 ` [RFC PATCH 10/20] x86/virt/seamldr: Introduce skeleton for TD-Preserving updates Chao Gao
2025-05-23  9:52 ` [RFC PATCH 11/20] x86/virt/seamldr: Abort updates if errors occurred midway Chao Gao
2025-06-03 12:04   ` Nikolay Borisov
2025-06-09  2:37     ` Chao Gao
2025-05-23  9:52 ` [RFC PATCH 12/20] x86/virt/seamldr: Shut down the current TDX module Chao Gao
2025-06-03 12:36   ` Nikolay Borisov
2025-06-09  2:10     ` Chao Gao
2025-05-23  9:52 ` [RFC PATCH 13/20] x86/virt/tdx: Reset software states after TDX module shutdown Chao Gao
2025-05-23  9:52 ` [RFC PATCH 14/20] x86/virt/seamldr: Install a new TDX module Chao Gao
2025-05-23  9:52 ` [RFC PATCH 15/20] x86/virt/seamldr: Handle TD-Preserving update failures Chao Gao
2025-05-23  9:52 ` [RFC PATCH 16/20] x86/virt/seamldr: Do TDX cpu init after updates Chao Gao
2025-05-23  9:52 ` [RFC PATCH 17/20] x86/virt/tdx: Establish contexts for the new module Chao Gao
2025-05-23  9:52 ` [RFC PATCH 18/20] x86/virt/tdx: Update tdx_sysinfo and check features post-update Chao Gao
2025-05-23  9:52 ` [RFC PATCH 19/20] x86/virt/seamldr: Verify availability of slots for TD-Preserving updates Chao Gao
2025-05-23  9:52 ` [RFC PATCH 20/20] x86/virt/seamldr: Enable TD-Preserving Updates Chao Gao
2025-06-11 19:56 ` [RFC PATCH 00/20] TD-Preserving updates Sagi Shahar
2025-07-11  8:04 ` Chao Gao
2025-07-11 14:06   ` Sean Christopherson
2025-07-14 10:26     ` Chao Gao
2025-07-15  0:21   ` Paul E. McKenney
2025-07-16  7:30     ` Chao Gao

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=20250523095322.88774-4-chao.gao@intel.com \
    --to=chao.gao@intel.com \
    --cc=bp@alien8.de \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=eddie.dong@intel.com \
    --cc=elena.reshetova@intel.com \
    --cc=farrah.chen@intel.com \
    --cc=hpa@zytor.com \
    --cc=isaku.yamahata@intel.com \
    --cc=kai.huang@intel.com \
    --cc=kirill.shutemov@intel.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=rick.p.edgecombe@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®