Messages in this thread Patch in this message | | | From | Kuppuswamy Sathyanarayanan <> | Subject | [RFC v2 09/32] x86/tdx: Add HLT support for TDX guest | Date | Mon, 26 Apr 2021 11:01:36 -0700 |
| |
From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Per Guest-Host-Communication Interface (GHCI) for Intel Trust Domain Extensions (Intel TDX) specification, sec 3.8, TDVMCALL[Instruction.HLT] provides HLT operation. Use it to implement halt() and safe_halt() paravirtualization calls.
The same TDVMCALL is used to handle #VE exception due to EXIT_REASON_HLT.
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 | 44 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/tdx.c b/arch/x86/kernel/tdx.c index ccfcb07bfb2c..5169f72b6b3f 100644 --- a/arch/x86/kernel/tdx.c +++ b/arch/x86/kernel/tdx.c @@ -82,6 +82,27 @@ static void tdg_get_info(void) td_info.attributes = out.rdx; } +static __cpuidle void tdg_halt(void) +{ + u64 ret; + + ret = __tdvmcall(EXIT_REASON_HLT, 0, 0, 0, 0, NULL); + + /* It should never fail */ + BUG_ON(ret); +} + +static __cpuidle void tdg_safe_halt(void) +{ + /* + * Enable interrupts next to the TDVMCALL to avoid + * performance degradation. + */ + asm volatile("sti\n\t"); + + tdg_halt(); +} + unsigned long tdg_get_ve_info(struct ve_info *ve) { u64 ret; @@ -111,13 +132,19 @@ unsigned long tdg_get_ve_info(struct ve_info *ve) int tdg_handle_virtualization_exception(struct pt_regs *regs, struct ve_info *ve) { - /* - * TODO: Add handler support for various #VE exit - * reasons. It will be added by other patches in - * the series. - */ - pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); - return -EFAULT; + switch (ve->exit_reason) { + case EXIT_REASON_HLT: + tdg_halt(); + 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; + + return 0; } void __init tdx_early_init(void) @@ -129,5 +156,8 @@ void __init tdx_early_init(void) tdg_get_info(); + pv_ops.irq.safe_halt = tdg_safe_halt; + pv_ops.irq.halt = tdg_halt; + pr_info("TDX guest is initialized\n"); } -- 2.25.1
| |