[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250523095322.88774-16-chao.gao@intel.com>
Date: Fri, 23 May 2025 02:52:38 -0700
From: Chao Gao <chao.gao@...el.com>
To: linux-coco@...ts.linux.dev,
x86@...nel.org,
kvm@...r.kernel.org
Cc: seanjc@...gle.com,
pbonzini@...hat.com,
eddie.dong@...el.com,
kirill.shutemov@...el.com,
dave.hansen@...el.com,
dan.j.williams@...el.com,
kai.huang@...el.com,
isaku.yamahata@...el.com,
elena.reshetova@...el.com,
rick.p.edgecombe@...el.com,
Chao Gao <chao.gao@...el.com>,
Farrah Chen <farrah.chen@...el.com>,
"Kirill A. Shutemov" <kirill.shutemov@...ux.intel.com>,
Dave Hansen <dave.hansen@...ux.intel.com>,
Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>,
Borislav Petkov <bp@...en8.de>,
"H. Peter Anvin" <hpa@...or.com>,
linux-kernel@...r.kernel.org
Subject: [RFC PATCH 15/20] x86/virt/seamldr: Handle TD-Preserving update failures
Failure encounterred after the module shutdown are unrecoverable. All
subsequent SEAMCALLs will fail and TDs will be killed.
Report the error through sysfs attributes and log a message to clarify that
SEAMCALL errors are expected in this situation.
Signed-off-by: Chao Gao <chao.gao@...el.com>
Tested-by: Farrah Chen <farrah.chen@...el.com>
---
arch/x86/virt/vmx/tdx/seamldr.c | 15 ++++++++++++++-
arch/x86/virt/vmx/tdx/tdx.c | 13 +++++++++++++
arch/x86/virt/vmx/tdx/tdx.h | 1 +
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamldr.c
index 1ecb5d3088af..a18df08a5528 100644
--- a/arch/x86/virt/vmx/tdx/seamldr.c
+++ b/arch/x86/virt/vmx/tdx/seamldr.c
@@ -278,6 +278,14 @@ static void ack_state(void)
}
}
+static void print_update_failure_message(void)
+{
+ static atomic_t printed = ATOMIC_INIT(0);
+
+ if (atomic_inc_return(&printed) == 1)
+ pr_err("update failed, SEAMCALLs will report failure until TDs killed\n");
+}
+
/*
* See multi_cpu_stop() from where this multi-cpu state-machine was
* adopted, and the rationale for touch_nmi_watchdog()
@@ -314,8 +322,13 @@ static int do_seamldr_install_module(void *params)
break;
}
- if (ret)
+ if (ret) {
atomic_inc(&tdp_data.failed);
+ if (curstate >= TDP_CPU_INSTALL) {
+ tdx_module_set_error();
+ print_update_failure_message();
+ }
+ }
ack_state();
} else {
touch_nmi_watchdog();
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 4cdeec0a4128..331c86eeddcf 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1102,6 +1102,13 @@ static ssize_t version_show(struct device *dev, struct device_attribute *attr,
{
const struct tdx_sys_info_versions *v = &tdx_sysinfo.versions;
+ /*
+ * Inform userspace that the TDX module isn't in a usable state,
+ * possibly due to a failed update.
+ */
+ if (tdx_module_status != TDX_MODULE_INITIALIZED)
+ return -ENXIO;
+
return sysfs_emit(buf, "%u.%u.%u\n", v->major_version,
v->minor_version,
v->update_version);
@@ -1377,6 +1384,12 @@ int tdx_module_shutdown(void)
return ret;
}
+void tdx_module_set_error(void)
+{
+ /* Called from stop_machine(). no need to hold tdx_module_lock */
+ tdx_module_status = TDX_MODULE_ERROR;
+}
+
static bool is_pamt_page(unsigned long phys)
{
struct tdmr_info_list *tdmr_list = &tdx_tdmr_list;
diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
index 3830dee4da91..ed3d74c991f6 100644
--- a/arch/x86/virt/vmx/tdx/tdx.h
+++ b/arch/x86/virt/vmx/tdx/tdx.h
@@ -125,5 +125,6 @@ struct tdmr_info_list {
int seamldr_prerr(u64 fn, struct tdx_module_args *args);
int tdx_module_shutdown(void);
+void tdx_module_set_error(void);
#endif
--
2.47.1
Powered by blists - more mailing lists