From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C761DC433FE for ; Sat, 9 Oct 2021 05:38:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AFE0B60F9C for ; Sat, 9 Oct 2021 05:38:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244464AbhJIFk2 (ORCPT ); Sat, 9 Oct 2021 01:40:28 -0400 Received: from mga04.intel.com ([192.55.52.120]:29192 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244415AbhJIFkE (ORCPT ); Sat, 9 Oct 2021 01:40:04 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10131"; a="225410079" X-IronPort-AV: E=Sophos;i="5.85,360,1624345200"; d="scan'208";a="225410079" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Oct 2021 22:38:05 -0700 X-IronPort-AV: E=Sophos;i="5.85,360,1624345200"; d="scan'208";a="569280268" Received: from dmsojoza-mobl3.amr.corp.intel.com (HELO skuppusw-desk1.amr.corp.intel.com) ([10.251.135.62]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Oct 2021 22:38:04 -0700 From: Kuppuswamy Sathyanarayanan To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , x86@kernel.org, Paolo Bonzini , David Hildenbrand , Andrea Arcangeli , Josh Poimboeuf , Juergen Gross , Deep Shah , VMware Inc , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel Cc: Peter H Anvin , Dave Hansen , Tony Luck , Dan Williams , Andi Kleen , Kirill Shutemov , Sean Christopherson , Kuppuswamy Sathyanarayanan , linux-kernel@vger.kernel.org Subject: [PATCH v10 11/11] x86/tdx: Handle CPUID via #VE Date: Fri, 8 Oct 2021 22:37:47 -0700 Message-Id: <20211009053747.1694419-12-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211009053747.1694419-1-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20211009053747.1694419-1-sathyanarayanan.kuppuswamy@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Kirill A. Shutemov" When running virtualized, the CPUID instruction is handled differently based on the leaf being accessed. The behavior depends only on the leaf and applies equally to both kernel/ring-0 and userspace/ring-3 execution of CPUID. Historically, there are two basic classes: * Leaves handled transparently to the guest * Leaves handled by the VMM In a typical guest without TDX, "handled by the VMM" leaves cause a VMEXIT. TDX replaces these VMEXITs with a #VE exception in the guest. The guest typically handles the #VE by making a hypercall to the VMM. The TDX module specification [1], section titled "CPUID Virtualization" talks about a few more classes of CPUID handling. But, for the purposes of this patch, the "handled transparently" CPUID leaves are all lumped together because the guest handling is the same. [1] - https://software.intel.com/content/dam/develop/external/us/en/documents/tdx-module-1.0-public-spec-v0.931.pdf Signed-off-by: Kirill A. Shutemov Reviewed-by: Andi Kleen Reviewed-by: Tony Luck Signed-off-by: Kuppuswamy Sathyanarayanan --- Changes since v9: * None Changes since v8: * Removed zero initialization of struct tdx_hypercall_output in tdx_handle_cpuid(). * Changed return type of tdx_handle_cpuid() to bool. Changes since v7: * None Changes since v6: * Fixed commit log as per Dave Hansen comments. * Added extra comments for _tdx_hypercall() usage. Changes since v5: * Fixed commit log as per review comments. * Removed WARN_ON() in tdx_handle_cpuid(). * Renamed "tdg" prefix with "tdx". Changes since v4: * None Changes since v3: * None arch/x86/kernel/tdx.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/x86/kernel/tdx.c b/arch/x86/kernel/tdx.c index 7c6c84015302..f8f242215dbc 100644 --- a/arch/x86/kernel/tdx.c +++ b/arch/x86/kernel/tdx.c @@ -143,6 +143,31 @@ static bool tdx_write_msr_safe(unsigned int msr, unsigned int low, return ret ? false : true; } +static bool tdx_handle_cpuid(struct pt_regs *regs) +{ + struct tdx_hypercall_output out; + + /* + * Emulate CPUID instruction via hypercall. More info about + * ABI can be found in TDX Guest-Host-Communication Interface + * (GHCI), section titled "VP.VMCALL". + */ + if (_tdx_hypercall(EXIT_REASON_CPUID, regs->ax, regs->cx, 0, 0, &out)) + return false; + + /* + * As per TDX GHCI CPUID ABI, r12-r15 registers contains contents of + * EAX, EBX, ECX, EDX registers after CPUID instruction execution. + * So copy the register contents back to pt_regs. + */ + regs->ax = out.r12; + regs->bx = out.r13; + regs->cx = out.r14; + regs->dx = out.r15; + + return true; +} + bool tdx_get_ve_info(struct ve_info *ve) { struct tdx_module_output out; @@ -191,6 +216,9 @@ bool tdx_handle_virtualization_exception(struct pt_regs *regs, case EXIT_REASON_MSR_WRITE: ret = tdx_write_msr_safe(regs->cx, regs->ax, regs->dx); break; + case EXIT_REASON_CPUID: + ret = tdx_handle_cpuid(regs); + break; default: pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); return false; -- 2.25.1