* [PATCH v1 10/11] x86/tdx: Add MSR support for TDX guest
@ 2021-06-02 2:19 Kuppuswamy Sathyanarayanan
2021-06-02 2:19 ` [PATCH v1 11/11] x86/tdx: Handle CPUID via #VE Kuppuswamy Sathyanarayanan
0 siblings, 1 reply; 3+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2021-06-02 2:19 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Peter Zijlstra,
Andy Lutomirski
Cc: Peter H Anvin, Dave Hansen, Tony Luck, Dan Williams, Andi Kleen,
Kirill Shutemov, Kuppuswamy Sathyanarayanan, Sean Christopherson,
Kuppuswamy Sathyanarayanan, linux-kernel, x86
From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Operations on context-switched MSRs can be run natively. The rest of
MSRs should be handled through TDVMCALLs.
TDVMCALL[Instruction.RDMSR] and TDVMCALL[Instruction.WRMSR] provide
MSR oprations.
You can find RDMSR and WRMSR details in Guest-Host-Communication
Interface (GHCI) for Intel Trust Domain Extensions (Intel TDX)
specification, sec 3.10, 3.11.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
arch/x86/kernel/tdx.c | 67 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 65 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/tdx.c b/arch/x86/kernel/tdx.c
index 76b71bf56b81..af7acea500ab 100644
--- a/arch/x86/kernel/tdx.c
+++ b/arch/x86/kernel/tdx.c
@@ -115,6 +115,55 @@ static __cpuidle void tdg_safe_halt(void)
BUG_ON(ret);
}
+static bool tdg_is_context_switched_msr(unsigned int msr)
+{
+ switch (msr) {
+ case MSR_EFER:
+ case MSR_IA32_CR_PAT:
+ case MSR_FS_BASE:
+ case MSR_GS_BASE:
+ case MSR_KERNEL_GS_BASE:
+ case MSR_IA32_SYSENTER_CS:
+ case MSR_IA32_SYSENTER_EIP:
+ case MSR_IA32_SYSENTER_ESP:
+ case MSR_STAR:
+ case MSR_LSTAR:
+ case MSR_SYSCALL_MASK:
+ case MSR_IA32_XSS:
+ case MSR_TSC_AUX:
+ case MSR_IA32_BNDCFGS:
+ return true;
+ }
+ return false;
+}
+
+static u64 tdg_read_msr_safe(unsigned int msr, int *err)
+{
+ u64 ret;
+ struct tdx_hypercall_output out = {0};
+
+ WARN_ON_ONCE(tdg_is_context_switched_msr(msr));
+
+ ret = __tdx_hypercall(EXIT_REASON_MSR_READ, msr, 0, 0, 0, &out);
+
+ *err = ret ? -EIO : 0;
+
+ return out.r11;
+}
+
+static int tdg_write_msr_safe(unsigned int msr, unsigned int low,
+ unsigned int high)
+{
+ u64 ret;
+
+ WARN_ON_ONCE(tdg_is_context_switched_msr(msr));
+
+ ret = __tdx_hypercall(EXIT_REASON_MSR_WRITE, msr, (u64)high << 32 | low,
+ 0, 0, NULL);
+
+ return ret ? -EIO : 0;
+}
+
unsigned long tdg_get_ve_info(struct ve_info *ve)
{
u64 ret;
@@ -141,19 +190,33 @@ unsigned long tdg_get_ve_info(struct ve_info *ve)
int tdg_handle_virtualization_exception(struct pt_regs *regs,
struct ve_info *ve)
{
+ unsigned long val;
+ int ret = 0;
+
switch (ve->exit_reason) {
case EXIT_REASON_HLT:
tdg_halt();
break;
+ case EXIT_REASON_MSR_READ:
+ val = tdg_read_msr_safe(regs->cx, (unsigned int *)&ret);
+ if (!ret) {
+ regs->ax = val & UINT_MAX;
+ regs->dx = val >> 32;
+ }
+ break;
+ case EXIT_REASON_MSR_WRITE:
+ ret = tdg_write_msr_safe(regs->cx, regs->ax, regs->dx);
+ break;
default:
pr_warn("Unexpected #VE: %lld\n", ve->exit_reason);
return -EFAULT;
}
/* After successful #VE handling, move the IP */
- regs->ip += ve->instr_len;
+ if (!ret)
+ regs->ip += ve->instr_len;
- return 0;
+ return ret;
}
void __init tdx_early_init(void)
--
2.25.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v1 11/11] x86/tdx: Handle CPUID via #VE
2021-06-02 2:19 [PATCH v1 10/11] x86/tdx: Add MSR support for TDX guest Kuppuswamy Sathyanarayanan
@ 2021-06-02 2:19 ` Kuppuswamy Sathyanarayanan
0 siblings, 0 replies; 3+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2021-06-02 2:19 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Peter Zijlstra,
Andy Lutomirski
Cc: Peter H Anvin, Dave Hansen, Tony Luck, Dan Williams, Andi Kleen,
Kirill Shutemov, Kuppuswamy Sathyanarayanan, Sean Christopherson,
Kuppuswamy Sathyanarayanan, linux-kernel, x86
From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
TDX has three classes of CPUID leaves: some CPUID leaves
are always handled by the CPU, others are handled by the TDX module,
and some others are handled by the VMM. Since the VMM cannot directly
intercept the instruction these are reflected with a #VE exception
to the guest, which then converts it into a hypercall to the VMM,
or handled directly.
The TDX module EAS has a full list of CPUID leaves which are handled
natively or by the TDX module in 16.2. Only unknown CPUIDs are handled by
the #VE method. In practice this typically only applies to the
hypervisor specific CPUIDs unknown to the native CPU.
Therefore there is no risk of causing this in early CPUID code which
runs before the #VE handler is set up because it will never access
those exotic CPUID leaves.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
arch/x86/kernel/tdx.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/x86/kernel/tdx.c b/arch/x86/kernel/tdx.c
index af7acea500ab..17725646eb30 100644
--- a/arch/x86/kernel/tdx.c
+++ b/arch/x86/kernel/tdx.c
@@ -164,6 +164,22 @@ static int tdg_write_msr_safe(unsigned int msr, unsigned int low,
return ret ? -EIO : 0;
}
+static void tdg_handle_cpuid(struct pt_regs *regs)
+{
+ u64 ret;
+ struct tdx_hypercall_output out = {0};
+
+ ret = __tdx_hypercall(EXIT_REASON_CPUID, regs->ax,
+ regs->cx, 0, 0, &out);
+
+ WARN_ON(ret);
+
+ regs->ax = out.r12;
+ regs->bx = out.r13;
+ regs->cx = out.r14;
+ regs->dx = out.r15;
+}
+
unsigned long tdg_get_ve_info(struct ve_info *ve)
{
u64 ret;
@@ -207,6 +223,9 @@ int tdg_handle_virtualization_exception(struct pt_regs *regs,
case EXIT_REASON_MSR_WRITE:
ret = tdg_write_msr_safe(regs->cx, regs->ax, regs->dx);
break;
+ case EXIT_REASON_CPUID:
+ tdg_handle_cpuid(regs);
+ break;
default:
pr_warn("Unexpected #VE: %lld\n", ve->exit_reason);
return -EFAULT;
--
2.25.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v1 00/11] Add TDX Guest Support (Initial support)
@ 2021-06-02 2:21 Kuppuswamy Sathyanarayanan
2021-06-02 2:21 ` [PATCH v1 11/11] x86/tdx: Handle CPUID via #VE Kuppuswamy Sathyanarayanan
0 siblings, 1 reply; 3+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2021-06-02 2:21 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Peter Zijlstra,
Andy Lutomirski
Cc: Peter H Anvin, Dave Hansen, Tony Luck, Dan Williams, Andi Kleen,
Kirill Shutemov, Kuppuswamy Sathyanarayanan, Sean Christopherson,
Kuppuswamy Sathyanarayanan, linux-kernel, x86
Hi All,
Intel's Trust Domain Extensions (TDX) protect guest VMs from malicious
hosts and some physical attacks. This series adds the basic TDX guest
infrastructure support (including #VE handler support, and #VE support
for halt and CPUID). This is just a subset of patches in the bare minimum
TDX support patch list which is required for supporting minimal
functional TDX guest. Other basic feature features like #VE support for
IO, MMIO, boot optimization fixes and shared-mm support will be submitted
in a separate patch set. To make reviewing easier we split it into smaller
series. This series alone is not necessarily fully functional.
Also, the host-side support patches, and support for advanced TD guest
features like attestation or debug-mode will be submitted at a later time.
Also, at this point it is not secure with some known holes in drivers, and
also hasn’t been fully audited and fuzzed yet.
TDX has a lot of similarities to SEV. It enhances confidentiality and
of guest memory and state (like registers) and includes a new exception
(#VE) for the same basic reasons as SEV-ES. Like SEV-SNP (not merged
yet), TDX limits the host's ability to effect changes in the guest
physical address space. With TDX the host cannot access the guest memory,
so various functionality that would normally be done in KVM has moved
into a (paravirtualized) guest. Partially this is done using the
Virtualization Exception (#VE) and partially with direct paravirtual hooks.
The TDX architecture also includes a new CPU mode called
Secure-Arbitration Mode (SEAM). The software (TDX module) running in this
mode arbitrates interactions between host and guest and implements many of
the guarantees of the TDX architecture.
Some of the key differences between TD and regular VM is,
1. Multi CPU bring-up is done using the ACPI MADT wake-up table.
2. A new #VE exception handler is added. The TDX module injects #VE exception
to the guest TD in cases of instructions that need to be emulated, disallowed
MSR accesses, etc.
3. By default memory is marked as private, and TD will selectively share it with
VMM based on need.
Note that the kernel will also need to be hardened against low level inputs from
the now untrusted hosts. This will be done in follow on patches.
You can find TDX related documents in the following link.
https://software.intel.com/content/www/br/pt/develop/articles/intel-trust-domain-extensions.html
Kirill A. Shutemov (7):
x86/paravirt: Move halt paravirt calls under CONFIG_PARAVIRT
x86/tdx: Get TD execution environment information via TDINFO
x86/traps: Add #VE support for TDX guest
x86/tdx: Add HLT support for TDX guest
x86/tdx: Wire up KVM hypercalls
x86/tdx: Add MSR support for TDX guest
x86/tdx: Handle CPUID via #VE
Kuppuswamy Sathyanarayanan (4):
x86/tdx: Introduce INTEL_TDX_GUEST config option
x86/cpufeatures: Add TDX Guest CPU feature
x86/x86: Add is_tdx_guest() interface
x86/tdx: Add __tdx_module_call() and __tdx_hypercall() helper
functions
arch/x86/Kconfig | 20 ++
arch/x86/boot/compressed/Makefile | 1 +
arch/x86/boot/compressed/tdx.c | 32 ++++
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/include/asm/idtentry.h | 4 +
arch/x86/include/asm/irqflags.h | 40 ++--
arch/x86/include/asm/kvm_para.h | 21 +++
arch/x86/include/asm/paravirt.h | 20 +-
arch/x86/include/asm/paravirt_types.h | 3 +-
arch/x86/include/asm/tdx.h | 153 ++++++++++++++++
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/asm-offsets.c | 22 +++
arch/x86/kernel/head64.c | 3 +
arch/x86/kernel/idt.c | 6 +
arch/x86/kernel/paravirt.c | 4 +-
arch/x86/kernel/tdcall.S | 254 ++++++++++++++++++++++++++
arch/x86/kernel/tdx.c | 254 ++++++++++++++++++++++++++
arch/x86/kernel/traps.c | 69 +++++++
18 files changed, 877 insertions(+), 31 deletions(-)
create mode 100644 arch/x86/boot/compressed/tdx.c
create mode 100644 arch/x86/include/asm/tdx.h
create mode 100644 arch/x86/kernel/tdcall.S
create mode 100644 arch/x86/kernel/tdx.c
--
2.25.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v1 11/11] x86/tdx: Handle CPUID via #VE
2021-06-02 2:21 [PATCH v1 00/11] Add TDX Guest Support (Initial support) Kuppuswamy Sathyanarayanan
@ 2021-06-02 2:21 ` Kuppuswamy Sathyanarayanan
0 siblings, 0 replies; 3+ messages in thread
From: Kuppuswamy Sathyanarayanan @ 2021-06-02 2:21 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Peter Zijlstra,
Andy Lutomirski
Cc: Peter H Anvin, Dave Hansen, Tony Luck, Dan Williams, Andi Kleen,
Kirill Shutemov, Kuppuswamy Sathyanarayanan, Sean Christopherson,
Kuppuswamy Sathyanarayanan, linux-kernel, x86
From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
TDX has three classes of CPUID leaves: some CPUID leaves
are always handled by the CPU, others are handled by the TDX module,
and some others are handled by the VMM. Since the VMM cannot directly
intercept the instruction these are reflected with a #VE exception
to the guest, which then converts it into a hypercall to the VMM,
or handled directly.
The TDX module EAS has a full list of CPUID leaves which are handled
natively or by the TDX module in 16.2. Only unknown CPUIDs are handled by
the #VE method. In practice this typically only applies to the
hypervisor specific CPUIDs unknown to the native CPU.
Therefore there is no risk of causing this in early CPUID code which
runs before the #VE handler is set up because it will never access
those exotic CPUID leaves.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
arch/x86/kernel/tdx.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/x86/kernel/tdx.c b/arch/x86/kernel/tdx.c
index af7acea500ab..17725646eb30 100644
--- a/arch/x86/kernel/tdx.c
+++ b/arch/x86/kernel/tdx.c
@@ -164,6 +164,22 @@ static int tdg_write_msr_safe(unsigned int msr, unsigned int low,
return ret ? -EIO : 0;
}
+static void tdg_handle_cpuid(struct pt_regs *regs)
+{
+ u64 ret;
+ struct tdx_hypercall_output out = {0};
+
+ ret = __tdx_hypercall(EXIT_REASON_CPUID, regs->ax,
+ regs->cx, 0, 0, &out);
+
+ WARN_ON(ret);
+
+ regs->ax = out.r12;
+ regs->bx = out.r13;
+ regs->cx = out.r14;
+ regs->dx = out.r15;
+}
+
unsigned long tdg_get_ve_info(struct ve_info *ve)
{
u64 ret;
@@ -207,6 +223,9 @@ int tdg_handle_virtualization_exception(struct pt_regs *regs,
case EXIT_REASON_MSR_WRITE:
ret = tdg_write_msr_safe(regs->cx, regs->ax, regs->dx);
break;
+ case EXIT_REASON_CPUID:
+ tdg_handle_cpuid(regs);
+ break;
default:
pr_warn("Unexpected #VE: %lld\n", ve->exit_reason);
return -EFAULT;
--
2.25.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-06-02 2:22 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-02 2:19 [PATCH v1 10/11] x86/tdx: Add MSR support for TDX guest Kuppuswamy Sathyanarayanan
2021-06-02 2:19 ` [PATCH v1 11/11] x86/tdx: Handle CPUID via #VE Kuppuswamy Sathyanarayanan
2021-06-02 2:21 [PATCH v1 00/11] Add TDX Guest Support (Initial support) Kuppuswamy Sathyanarayanan
2021-06-02 2:21 ` [PATCH v1 11/11] x86/tdx: Handle CPUID via #VE Kuppuswamy Sathyanarayanan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.