From: Kai Huang <kai.huang@intel.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: seanjc@google.com, pbonzini@redhat.com, dave.hansen@intel.com,
len.brown@intel.com, tony.luck@intel.com,
rafael.j.wysocki@intel.com, reinette.chatre@intel.com,
dan.j.williams@intel.com, peterz@infradead.org,
ak@linux.intel.com, kirill.shutemov@linux.intel.com,
sathyanarayanan.kuppuswamy@linux.intel.com,
isaku.yamahata@intel.com, kai.huang@intel.com
Subject: [PATCH v5 01/22] x86/virt/tdx: Detect TDX during kernel boot
Date: Wed, 22 Jun 2022 23:15:30 +1200 [thread overview]
Message-ID: <062075b36150b119bf2d0a1262de973b0a2b11a7.1655894131.git.kai.huang@intel.com> (raw)
In-Reply-To: <cover.1655894131.git.kai.huang@intel.com>
Intel Trust Domain Extensions (TDX) protects guest VMs from malicious
host and certain physical attacks. TDX introduces a new CPU mode called
Secure Arbitration Mode (SEAM) and a new isolated range pointed by the
SEAM Ranger Register (SEAMRR). A CPU-attested software module called
'the TDX module' runs inside the new isolated range to implement the
functionalities to manage and run protected VMs.
Pre-TDX Intel hardware has support for a memory encryption architecture
called MKTME. The memory encryption hardware underpinning MKTME is also
used for Intel TDX. TDX ends up "stealing" some of the physical address
space from the MKTME architecture for crypto-protection to VMs. BIOS is
responsible for partitioning the "KeyID" space between legacy MKTME and
TDX. The KeyIDs reserved for TDX are called 'TDX private KeyIDs' or
'TDX KeyIDs' for short.
To enable TDX, BIOS needs to configure SEAMRR (core-scope) and TDX
private KeyIDs (package-scope) consistently for all packages. TDX
doesn't trust BIOS. TDX ensures all BIOS configurations are correct,
and if not, refuses to enable SEAMRR on any core. This means detecting
SEAMRR alone on BSP is enough to check whether TDX has been enabled by
BIOS.
To start to support TDX, create a new arch/x86/virt/vmx/tdx/tdx.c for
TDX host kernel support. Add a new Kconfig option CONFIG_INTEL_TDX_HOST
to opt-in TDX host kernel support (to distinguish with TDX guest kernel
support). So far only KVM is the only user of TDX. Make the new config
option depend on KVM_INTEL.
Use early_initcall() to detect whether TDX is enabled by BIOS during
kernel boot, and add a function to report that. Use a function instead
of a new CPU feature bit. This is because the TDX module needs to be
initialized before it can be used to run any TDX guests, and the TDX
module is initialized at runtime by the caller who wants to use TDX.
Explicitly detect SEAMRR but not just only detect TDX private KeyIDs.
Theoretically, a misconfiguration of TDX private KeyIDs can result in
SEAMRR being disabled, but the BSP can still report the correct TDX
KeyIDs. Such BIOS bug can be caught when initializing the TDX module,
but it's better to do more detection during boot to provide a more
accurate result.
Also detect the TDX KeyIDs. This allows userspace to know how many TDX
guests the platform can run w/o needing to wait until TDX is fully
functional.
Signed-off-by: Kai Huang <kai.huang@intel.com>
---
arch/x86/Kconfig | 13 ++++
arch/x86/Makefile | 2 +
arch/x86/include/asm/tdx.h | 7 +++
arch/x86/virt/Makefile | 2 +
arch/x86/virt/vmx/Makefile | 2 +
arch/x86/virt/vmx/tdx/Makefile | 2 +
arch/x86/virt/vmx/tdx/tdx.c | 109 +++++++++++++++++++++++++++++++++
arch/x86/virt/vmx/tdx/tdx.h | 47 ++++++++++++++
8 files changed, 184 insertions(+)
create mode 100644 arch/x86/virt/Makefile
create mode 100644 arch/x86/virt/vmx/Makefile
create mode 100644 arch/x86/virt/vmx/tdx/Makefile
create mode 100644 arch/x86/virt/vmx/tdx/tdx.c
create mode 100644 arch/x86/virt/vmx/tdx/tdx.h
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7021ec725dd3..23f21aa3a5c4 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1967,6 +1967,19 @@ config X86_SGX
If unsure, say N.
+config INTEL_TDX_HOST
+ bool "Intel Trust Domain Extensions (TDX) host support"
+ default n
+ depends on CPU_SUP_INTEL
+ depends on X86_64
+ depends on KVM_INTEL
+ help
+ Intel Trust Domain Extensions (TDX) protects guest VMs from malicious
+ host and certain physical attacks. This option enables necessary TDX
+ support in host kernel to run protected VMs.
+
+ If unsure, say N.
+
config EFI
bool "EFI runtime service support"
depends on ACPI
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 63d50f65b828..2ca3a2a36dc5 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -234,6 +234,8 @@ head-y += arch/x86/kernel/platform-quirks.o
libs-y += arch/x86/lib/
+core-y += arch/x86/virt/
+
# drivers-y are linked after core-y
drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
drivers-$(CONFIG_PCI) += arch/x86/pci/
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index 020c81a7c729..97511b76c1ac 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -87,5 +87,12 @@ static inline long tdx_kvm_hypercall(unsigned int nr, unsigned long p1,
return -ENODEV;
}
#endif /* CONFIG_INTEL_TDX_GUEST && CONFIG_KVM_GUEST */
+
+#ifdef CONFIG_INTEL_TDX_HOST
+bool platform_tdx_enabled(void);
+#else /* !CONFIG_INTEL_TDX_HOST */
+static inline bool platform_tdx_enabled(void) { return false; }
+#endif /* CONFIG_INTEL_TDX_HOST */
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_X86_TDX_H */
diff --git a/arch/x86/virt/Makefile b/arch/x86/virt/Makefile
new file mode 100644
index 000000000000..1e36502cd738
--- /dev/null
+++ b/arch/x86/virt/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y += vmx/
diff --git a/arch/x86/virt/vmx/Makefile b/arch/x86/virt/vmx/Makefile
new file mode 100644
index 000000000000..feebda21d793
--- /dev/null
+++ b/arch/x86/virt/vmx/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_INTEL_TDX_HOST) += tdx/
diff --git a/arch/x86/virt/vmx/tdx/Makefile b/arch/x86/virt/vmx/tdx/Makefile
new file mode 100644
index 000000000000..1bd688684716
--- /dev/null
+++ b/arch/x86/virt/vmx/tdx/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_INTEL_TDX_HOST) += tdx.o
diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
new file mode 100644
index 000000000000..8275007702e6
--- /dev/null
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(c) 2022 Intel Corporation.
+ *
+ * Intel Trusted Domain Extensions (TDX) support
+ */
+
+#define pr_fmt(fmt) "tdx: " fmt
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <asm/cpufeatures.h>
+#include <asm/cpufeature.h>
+#include <asm/msr-index.h>
+#include <asm/msr.h>
+#include <asm/tdx.h>
+#include "tdx.h"
+
+static u32 tdx_keyid_start __ro_after_init;
+static u32 tdx_keyid_num __ro_after_init;
+
+/* Detect whether CPU supports SEAM */
+static int detect_seam(void)
+{
+ u64 mtrrcap, mask;
+
+ /* SEAMRR is reported via MTRRcap */
+ if (!boot_cpu_has(X86_FEATURE_MTRR))
+ return -ENODEV;
+
+ rdmsrl(MSR_MTRRcap, mtrrcap);
+ if (!(mtrrcap & MTRR_CAP_SEAMRR))
+ return -ENODEV;
+
+ /* The MASK MSR reports whether SEAMRR is enabled */
+ rdmsrl(MSR_IA32_SEAMRR_PHYS_MASK, mask);
+ if ((mask & SEAMRR_ENABLED_BITS) != SEAMRR_ENABLED_BITS)
+ return -ENODEV;
+
+ pr_info("SEAMRR enabled.\n");
+ return 0;
+}
+
+static int detect_tdx_keyids(void)
+{
+ u64 keyid_part;
+
+ rdmsrl(MSR_IA32_MKTME_KEYID_PARTITIONING, keyid_part);
+
+ tdx_keyid_num = TDX_KEYID_NUM(keyid_part);
+ tdx_keyid_start = TDX_KEYID_START(keyid_part);
+
+ pr_info("TDX private KeyID range: [%u, %u).\n",
+ tdx_keyid_start, tdx_keyid_start + tdx_keyid_num);
+
+ /*
+ * TDX guarantees at least two TDX KeyIDs are configured by
+ * BIOS, otherwise SEAMRR is disabled. Invalid TDX private
+ * range means kernel bug (TDX is broken).
+ */
+ if (WARN_ON(!tdx_keyid_start || tdx_keyid_num < 2)) {
+ tdx_keyid_start = tdx_keyid_num = 0;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * Detect TDX via detecting SEAMRR during kernel boot.
+ *
+ * To enable TDX, BIOS must configure SEAMRR consistently across all
+ * CPU cores. TDX doesn't trust BIOS. Instead, MCHECK verifies all
+ * configurations from BIOS are correct, and if not, it disables TDX
+ * (SEAMRR is disabled on all cores). This means detecting SEAMRR on
+ * BSP is enough to determine whether TDX has been enabled by BIOS.
+ */
+static int __init tdx_early_detect(void)
+{
+ int ret;
+
+ ret = detect_seam();
+ if (ret)
+ return ret;
+
+ /*
+ * TDX private KeyIDs is only accessible by SEAM software.
+ * Only detect TDX KeyIDs when SEAMRR is enabled.
+ */
+ ret = detect_tdx_keyids();
+ if (ret)
+ return ret;
+
+ pr_info("TDX enabled by BIOS.\n");
+ return 0;
+}
+early_initcall(tdx_early_detect);
+
+/**
+ * platform_tdx_enabled() - Return whether BIOS has enabled TDX
+ *
+ * Return whether BIOS has enabled TDX regardless whether the TDX module
+ * has been loaded or not.
+ */
+bool platform_tdx_enabled(void)
+{
+ return tdx_keyid_num >= 2;
+}
diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
new file mode 100644
index 000000000000..f16055cc25f4
--- /dev/null
+++ b/arch/x86/virt/vmx/tdx/tdx.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _X86_VIRT_TDX_H
+#define _X86_VIRT_TDX_H
+
+#include <linux/bits.h>
+
+/*
+ * This file contains both macros and data structures defined by the TDX
+ * architecture and Linux defined software data structures and functions.
+ * The two should not be mixed together for better readability. The
+ * architectural definitions come first.
+ */
+
+/*
+ * Intel Trusted Domain CPU Architecture Extension spec:
+ *
+ * IA32_MTRRCAP:
+ * Bit 15: The support of SEAMRR
+ *
+ * IA32_SEAMRR_PHYS_MASK (core-scope):
+ * Bit 10: Lock bit
+ * Bit 11: Enable bit
+ */
+#define MTRR_CAP_SEAMRR BIT_ULL(15)
+
+#define MSR_IA32_SEAMRR_PHYS_MASK 0x00001401
+
+#define SEAMRR_PHYS_MASK_ENABLED BIT_ULL(11)
+#define SEAMRR_PHYS_MASK_LOCKED BIT_ULL(10)
+#define SEAMRR_ENABLED_BITS \
+ (SEAMRR_PHYS_MASK_ENABLED | SEAMRR_PHYS_MASK_LOCKED)
+
+/*
+ * IA32_MKTME_KEYID_PARTIONING:
+ * Bit [31:0]: Number of MKTME KeyIDs.
+ * Bit [63:32]: Number of TDX private KeyIDs.
+ *
+ * MKTME KeyIDs start from KeyID 1. TDX private KeyIDs start
+ * after the last MKTME KeyID.
+ */
+#define MSR_IA32_MKTME_KEYID_PARTITIONING 0x00000087
+
+#define TDX_KEYID_START(_keyid_part) \
+ ((u32)(((_keyid_part) & 0xffffffffull) + 1))
+#define TDX_KEYID_NUM(_keyid_part) ((u32)((_keyid_part) >> 32))
+
+#endif
--
2.36.1
next prev parent reply other threads:[~2022-06-22 11:15 UTC|newest]
Thread overview: 114+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-22 11:15 [PATCH v5 00/22] TDX host kernel support Kai Huang
2022-06-22 11:15 ` Kai Huang [this message]
2022-06-23 5:57 ` [PATCH v5 01/22] x86/virt/tdx: Detect TDX during kernel boot Chao Gao
2022-06-23 9:23 ` Kai Huang
2022-08-02 2:01 ` [PATCH v5 1/22] " Wu, Binbin
2022-08-03 9:25 ` Kai Huang
2022-06-22 11:15 ` [PATCH v5 02/22] cc_platform: Add new attribute to prevent ACPI CPU hotplug Kai Huang
2022-06-22 11:42 ` Rafael J. Wysocki
2022-06-23 0:01 ` Kai Huang
2022-06-27 8:01 ` Igor Mammedov
2022-06-28 10:04 ` Kai Huang
2022-06-28 11:52 ` Igor Mammedov
2022-06-28 17:33 ` Rafael J. Wysocki
2022-06-28 23:41 ` Kai Huang
2022-06-24 18:57 ` Dave Hansen
2022-06-27 5:05 ` Kai Huang
2022-07-13 11:09 ` Kai Huang
2022-07-19 17:46 ` Dave Hansen
2022-07-19 23:54 ` Kai Huang
2022-08-03 3:40 ` Binbin Wu
2022-08-03 9:20 ` Kai Huang
2022-06-29 5:33 ` Christoph Hellwig
2022-06-29 9:09 ` Kai Huang
2022-08-03 3:55 ` Binbin Wu
2022-08-03 9:21 ` Kai Huang
2022-06-22 11:15 ` [PATCH v5 03/22] cc_platform: Add new attribute to prevent ACPI memory hotplug Kai Huang
2022-06-22 11:45 ` Rafael J. Wysocki
2022-06-23 0:08 ` Kai Huang
2022-06-28 17:55 ` Rafael J. Wysocki
2022-06-28 12:01 ` Igor Mammedov
2022-06-28 23:49 ` Kai Huang
2022-06-29 8:48 ` Igor Mammedov
2022-06-29 9:13 ` Kai Huang
2022-06-22 11:16 ` [PATCH v5 04/22] x86/virt/tdx: Prevent ACPI CPU hotplug and " Kai Huang
2022-06-24 1:41 ` Chao Gao
2022-06-24 11:21 ` Kai Huang
2022-06-29 8:35 ` Yuan Yao
2022-06-29 9:17 ` Kai Huang
2022-06-29 14:22 ` Dave Hansen
2022-06-29 23:02 ` Kai Huang
2022-06-30 15:44 ` Dave Hansen
2022-06-30 22:45 ` Kai Huang
2022-06-22 11:16 ` [PATCH v5 05/22] x86/virt/tdx: Prevent hot-add driver managed memory Kai Huang
2022-06-24 2:12 ` Chao Gao
2022-06-24 11:23 ` Kai Huang
2022-06-24 19:01 ` Dave Hansen
2022-06-27 5:27 ` Kai Huang
2022-06-22 11:16 ` [PATCH v5 06/22] x86/virt/tdx: Add skeleton to initialize TDX on demand Kai Huang
2022-06-24 2:39 ` Chao Gao
2022-06-24 11:27 ` Kai Huang
2022-06-22 11:16 ` [PATCH v5 07/22] x86/virt/tdx: Implement SEAMCALL function Kai Huang
2022-06-24 18:38 ` Dave Hansen
2022-06-27 5:23 ` Kai Huang
2022-06-27 20:58 ` Dave Hansen
2022-06-27 22:10 ` Kai Huang
2022-07-19 19:39 ` Dan Williams
2022-07-19 23:28 ` Kai Huang
2022-07-20 10:18 ` Kai Huang
2022-07-20 16:48 ` Dave Hansen
2022-07-21 1:52 ` Kai Huang
2022-07-27 0:34 ` Kai Huang
2022-07-27 0:50 ` Dave Hansen
2022-07-27 12:46 ` Kai Huang
2022-08-03 2:37 ` Kai Huang
2022-08-03 14:20 ` Dave Hansen
2022-08-03 22:35 ` Kai Huang
2022-08-04 10:06 ` Kai Huang
2022-06-22 11:16 ` [PATCH v5 08/22] x86/virt/tdx: Shut down TDX module in case of error Kai Huang
2022-06-24 18:50 ` Dave Hansen
2022-06-27 5:26 ` Kai Huang
2022-06-27 20:46 ` Dave Hansen
2022-06-27 22:34 ` Kai Huang
2022-06-27 22:56 ` Dave Hansen
2022-06-27 23:59 ` Kai Huang
2022-06-28 0:03 ` Dave Hansen
2022-06-28 0:11 ` Kai Huang
2022-06-22 11:16 ` [PATCH v5 09/22] x86/virt/tdx: Detect TDX module by doing module global initialization Kai Huang
2022-06-22 11:16 ` [PATCH v5 10/22] x86/virt/tdx: Do logical-cpu scope TDX module initialization Kai Huang
2022-06-22 11:17 ` [PATCH v5 11/22] x86/virt/tdx: Get information about TDX module and TDX-capable memory Kai Huang
2022-06-22 11:17 ` [PATCH v5 12/22] x86/virt/tdx: Convert all memory regions in memblock to TDX memory Kai Huang
2022-06-24 19:40 ` Dave Hansen
2022-06-27 6:16 ` Kai Huang
2022-07-07 2:37 ` Kai Huang
2022-07-07 14:26 ` Dave Hansen
2022-07-07 14:36 ` Juergen Gross
2022-07-07 23:42 ` Kai Huang
2022-07-07 23:34 ` Kai Huang
2022-08-03 1:30 ` Kai Huang
2022-08-03 14:22 ` Dave Hansen
2022-08-03 22:14 ` Kai Huang
2022-06-22 11:17 ` [PATCH v5 13/22] x86/virt/tdx: Add placeholder to construct TDMRs based on memblock Kai Huang
2022-06-22 11:17 ` [PATCH v5 14/22] x86/virt/tdx: Create TDMRs to cover all memblock memory regions Kai Huang
2022-06-22 11:17 ` [PATCH v5 15/22] x86/virt/tdx: Allocate and set up PAMTs for TDMRs Kai Huang
2022-06-24 20:13 ` Dave Hansen
2022-06-27 10:31 ` Kai Huang
2022-06-27 20:41 ` Dave Hansen
2022-06-27 22:50 ` Kai Huang
2022-06-27 22:57 ` Dave Hansen
2022-06-27 23:05 ` Kai Huang
2022-06-28 0:48 ` Xiaoyao Li
2022-06-28 17:03 ` Dave Hansen
2022-08-17 22:46 ` Sagi Shahar
2022-08-17 23:43 ` Huang, Kai
2022-06-22 11:17 ` [PATCH v5 16/22] x86/virt/tdx: Set up reserved areas for all TDMRs Kai Huang
2022-06-22 11:17 ` [PATCH v5 17/22] x86/virt/tdx: Reserve TDX module global KeyID Kai Huang
2022-06-22 11:17 ` [PATCH v5 18/22] x86/virt/tdx: Configure TDX module with TDMRs and " Kai Huang
2022-06-22 11:17 ` [PATCH v5 19/22] x86/virt/tdx: Configure global KeyID on all packages Kai Huang
2022-06-22 11:17 ` [PATCH v5 20/22] x86/virt/tdx: Initialize all TDMRs Kai Huang
2022-06-22 11:17 ` [PATCH v5 21/22] x86/virt/tdx: Support kexec() Kai Huang
2022-06-22 11:17 ` [PATCH v5 22/22] Documentation/x86: Add documentation for TDX host support Kai Huang
2022-08-18 4:07 ` Bagas Sanjaya
2022-08-18 9:33 ` Huang, Kai
2022-06-24 19:47 ` [PATCH v5 00/22] TDX host kernel support Dave Hansen
2022-06-27 4:09 ` Kai Huang
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=062075b36150b119bf2d0a1262de973b0a2b11a7.1655894131.git.kai.huang@intel.com \
--to=kai.huang@intel.com \
--cc=ak@linux.intel.com \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@intel.com \
--cc=isaku.yamahata@intel.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=kvm@vger.kernel.org \
--cc=len.brown@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=rafael.j.wysocki@intel.com \
--cc=reinette.chatre@intel.com \
--cc=sathyanarayanan.kuppuswamy@linux.intel.com \
--cc=seanjc@google.com \
--cc=tony.luck@intel.com \
/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®