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 7B0C3C433EF for ; Tue, 5 Oct 2021 02:52:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5CC346140A for ; Tue, 5 Oct 2021 02:52:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231948AbhJECyp (ORCPT ); Mon, 4 Oct 2021 22:54:45 -0400 Received: from mga01.intel.com ([192.55.52.88]:43315 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231559AbhJECyY (ORCPT ); Mon, 4 Oct 2021 22:54:24 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10127"; a="248894669" X-IronPort-AV: E=Sophos;i="5.85,347,1624345200"; d="scan'208";a="248894669" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Oct 2021 19:52:34 -0700 X-IronPort-AV: E=Sophos;i="5.85,347,1624345200"; d="scan'208";a="483409143" Received: from asaini1-mobl1.amr.corp.intel.com (HELO skuppusw-desk1.amr.corp.intel.com) ([10.251.138.96]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Oct 2021 19:52:33 -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 v8 11/11] x86/tdx: Handle CPUID via #VE Date: Mon, 4 Oct 2021 19:52:05 -0700 Message-Id: <20211005025205.1784480-12-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211005025205.1784480-1-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20211005025205.1784480-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 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 062ac4720434..11e367228e96 100644 --- a/arch/x86/kernel/tdx.c +++ b/arch/x86/kernel/tdx.c @@ -145,6 +145,31 @@ static int tdx_write_msr_safe(unsigned int msr, unsigned int low, return ret ? -EIO : 0; } +static u64 tdx_handle_cpuid(struct pt_regs *regs) +{ + struct tdx_hypercall_output out = {0}; + u64 ret; + + /* + * Emulate CPUID instruction via hypercall. More info about + * ABI can be found in TDX Guest-Host-Communication Interface + * (GHCI), section titled "VP.VMCALL". + */ + ret = _tdx_hypercall(EXIT_REASON_CPUID, regs->ax, regs->cx, 0, 0, &out); + + /* + * 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 ret; +} + unsigned long tdx_get_ve_info(struct ve_info *ve) { struct tdx_module_output out = {0}; @@ -188,6 +213,9 @@ int 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 -EFAULT; -- 2.25.1