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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D712CC433EF for ; Fri, 18 Feb 2022 16:19:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237825AbiBRQTZ (ORCPT ); Fri, 18 Feb 2022 11:19:25 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43144 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237540AbiBRQRk (ORCPT ); Fri, 18 Feb 2022 11:17:40 -0500 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 36951237E8 for ; Fri, 18 Feb 2022 08:17:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1645201040; x=1676737040; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=8v0I9pHgXAdnuKlkjsaVyyJSgZQ1dGCPAKIgxCKzdiU=; b=iVsmATutpDI0/TsVnEcGuomataMT78c6+aedujlhKb3n4pglrVgZCbbC 0Cv9ZLod7bLwV+I36/jVVcOwiDrD0z6M/4sIoDoYS2E+dUSxJfmodPDMu wY9AxT/p7+sRz/FnXIs4d7amcQQN/o+hCDbZzOmg4o7foiEPISeNvU1Mp vQ55jm6BNZK7R5E9XLJ/fnu3ueZpKkQgphKxE0pwNX69mNRorB4P+FsbS aLimihVICAPCCdL0f3gbZodxopi2NY5kboNMhEOushtTrWaOmyqGNfuLL hYf9oksM4CvuT1J29u4vUj3WeryPMSv3MiGiWH3gXA8xD2qUWlUr950j3 g==; X-IronPort-AV: E=McAfee;i="6200,9189,10261"; a="248752949" X-IronPort-AV: E=Sophos;i="5.88,379,1635231600"; d="scan'208";a="248752949" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Feb 2022 08:17:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,379,1635231600"; d="scan'208";a="637782164" Received: from black.fi.intel.com ([10.237.72.28]) by orsmga004.jf.intel.com with ESMTP; 18 Feb 2022 08:17:13 -0800 Received: by black.fi.intel.com (Postfix, from userid 1000) id 8FB22954; Fri, 18 Feb 2022 18:17:22 +0200 (EET) From: "Kirill A. Shutemov" To: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@intel.com, luto@kernel.org, peterz@infradead.org Cc: sathyanarayanan.kuppuswamy@linux.intel.com, aarcange@redhat.com, ak@linux.intel.com, dan.j.williams@intel.com, david@redhat.com, hpa@zytor.com, jgross@suse.com, jmattson@google.com, joro@8bytes.org, jpoimboe@redhat.com, knsathya@kernel.org, pbonzini@redhat.com, sdeep@vmware.com, seanjc@google.com, tony.luck@intel.com, vkuznets@redhat.com, wanpengli@tencent.com, x86@kernel.org, linux-kernel@vger.kernel.org, "Kirill A. Shutemov" Subject: [PATCHv3 11/32] x86/tdx: Handle CPUID via #VE Date: Fri, 18 Feb 2022 19:16:57 +0300 Message-Id: <20220218161718.67148-12-kirill.shutemov@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220218161718.67148-1-kirill.shutemov@linux.intel.com> References: <20220218161718.67148-1-kirill.shutemov@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In TDX guests, most CPUID leaf/sub-leaf combinations are virtualized by the TDX module while some trigger #VE. Implement the #VE handling for EXIT_REASON_CPUID by handing it through the hypercall, which in turn lets the TDX module handle it by invoking the host VMM. More details on CPUID Virtualization can be found in the TDX module specification, the section titled "CPUID Virtualization". Co-developed-by: Kuppuswamy Sathyanarayanan Signed-off-by: Kuppuswamy Sathyanarayanan Reviewed-by: Andi Kleen Reviewed-by: Tony Luck Signed-off-by: Kirill A. Shutemov --- arch/x86/coco/tdx.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/arch/x86/coco/tdx.c b/arch/x86/coco/tdx.c index c0549dce2588..83cbc94b30d0 100644 --- a/arch/x86/coco/tdx.c +++ b/arch/x86/coco/tdx.c @@ -154,6 +154,36 @@ static bool write_msr(struct pt_regs *regs) return !__tdx_hypercall(&args, 0); } +static bool handle_cpuid(struct pt_regs *regs) +{ + struct tdx_hypercall_args args = { + .r10 = TDX_HYPERCALL_STANDARD, + .r11 = EXIT_REASON_CPUID, + .r12 = regs->ax, + .r13 = regs->cx, + }; + + /* + * Emulate the CPUID instruction via a hypercall. More info about + * ABI can be found in TDX Guest-Host-Communication Interface + * (GHCI), section titled "VP.VMCALL". + */ + if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT)) + return false; + + /* + * As per TDX GHCI CPUID ABI, r12-r15 registers contain contents of + * EAX, EBX, ECX, EDX registers after the CPUID instruction execution. + * So copy the register contents back to pt_regs. + */ + regs->ax = args.r12; + regs->bx = args.r13; + regs->cx = args.r14; + regs->dx = args.r15; + + return true; +} + void tdx_get_ve_info(struct ve_info *ve) { struct tdx_module_output out; @@ -186,8 +216,13 @@ void tdx_get_ve_info(struct ve_info *ve) */ static bool virt_exception_user(struct pt_regs *regs, struct ve_info *ve) { - pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); - return false; + switch (ve->exit_reason) { + case EXIT_REASON_CPUID: + return handle_cpuid(regs); + default: + pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); + return false; + } } /* Handle the kernel #VE */ @@ -200,6 +235,8 @@ static bool virt_exception_kernel(struct pt_regs *regs, struct ve_info *ve) return read_msr(regs); case EXIT_REASON_MSR_WRITE: return write_msr(regs); + case EXIT_REASON_CPUID: + return handle_cpuid(regs); default: pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); return false; -- 2.34.1