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 X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 04365C433EF for ; Fri, 3 Sep 2021 17:29:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DD30261101 for ; Fri, 3 Sep 2021 17:29:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350372AbhICRaA (ORCPT ); Fri, 3 Sep 2021 13:30:00 -0400 Received: from mga01.intel.com ([192.55.52.88]:33544 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350271AbhICR3d (ORCPT ); Fri, 3 Sep 2021 13:29:33 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10096"; a="241760109" X-IronPort-AV: E=Sophos;i="5.85,265,1624345200"; d="scan'208";a="241760109" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Sep 2021 10:28:33 -0700 X-IronPort-AV: E=Sophos;i="5.85,265,1624345200"; d="scan'208";a="534222289" Received: from dlinsen-mobl.amr.corp.intel.com (HELO skuppusw-desk1.amr.corp.intel.com) ([10.254.56.172]) by fmsmga003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Sep 2021 10:28:32 -0700 From: Kuppuswamy Sathyanarayanan To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , x86@kernel.org, Paolo Bonzini , 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 v6 11/11] x86/tdx: Handle CPUID via #VE Date: Fri, 3 Sep 2021 10:28:12 -0700 Message-Id: <20210903172812.1097643-12-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210903172812.1097643-1-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20210903172812.1097643-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" 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 hypercall to the VMM, or handled directly. The TDX module specification [1], sec 16.2 has a full list of CPUID leaves which are handled natively or by the TDX module. 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. [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 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 | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/x86/kernel/tdx.c b/arch/x86/kernel/tdx.c index 5c52dde4a5fd..c65c117aff5f 100644 --- a/arch/x86/kernel/tdx.c +++ b/arch/x86/kernel/tdx.c @@ -150,6 +150,21 @@ 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; + + ret = _tdx_hypercall(EXIT_REASON_CPUID, regs->ax, regs->cx, 0, 0, &out); + + 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}; @@ -193,6 +208,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