Messages in this thread Patch in this message | | | From | Kuppuswamy Sathyanarayanan <> | Subject | [RFC v2 12/32] x86/tdx: Handle CPUID via #VE | Date | Mon, 26 Apr 2021 11:01:39 -0700 |
| |
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 TDCALL 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 | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/arch/x86/kernel/tdx.c b/arch/x86/kernel/tdx.c index 5b16707b3577..e42e260df245 100644 --- a/arch/x86/kernel/tdx.c +++ b/arch/x86/kernel/tdx.c @@ -174,6 +174,21 @@ 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 tdvmcall_output out = {0}; + + ret = __tdvmcall(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; @@ -220,6 +235,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
| |