Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp868739ybl; Wed, 28 Aug 2019 06:32:42 -0700 (PDT) X-Google-Smtp-Source: APXvYqxZfNg5BqjVzupX8oUabjpT1f5bJUeNt91lDMaylslvm1IgcmsHbFBdnqQ+hlM+/4WYVzCu X-Received: by 2002:a17:902:248:: with SMTP id 66mr4426354plc.19.1566999162308; Wed, 28 Aug 2019 06:32:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566999162; cv=none; d=google.com; s=arc-20160816; b=GzsbNAedrtOVhmarGNSx6uzXXA2iNSsKxGWprYtQ6oTSnPrtaCnZy7Av+m2sNTieJk 6JWnxYUkPPil5P2EVE3EJ9Q1DWyoIZEithnixcFtTqc8W58JkIbq9aTqj2gE8NGNcABk FJ8fPPlKvYHMFz3yV8uM/F/YJ7nC0NHd1/v4o/8BeDbkC7sBoWN5qVYx4YaBJL8+bjcA 49RY1yfsfugEnefaqkMA9NxLAqCoLapPjGetRhLFofs+g+pkk90TdzMx39EKu7dPtbW5 /6StTX9oylaG0jfpS+I/feOQ1KwZQSdm3E8KG7XTi8ZiOPK64VcP98/8ppxx8w7V+Yr+ TZ8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :robot-unsubscribe:robot-id:message-id:mime-version:references :in-reply-to:cc:subject:to:reply-to:from:date; bh=aSM2C980AgZfEBjFM/KAB2On9rFtfJXVh2PNXUehtlY=; b=SqWjz+ZkA9OIhOkHqs7ZbprW0ur+qnAbNhwnBxerqu0e4BjzCeglVT7tDOJ9tTTk0v vvVElcWglZXJjq9ZKEU5cr9X1YLtW2RnWIDbz+B42qL32nLda+fWKSJnJJG9LPfMGwfl RYkbYvhofnZGNQ9393PIDfBx8gHZek3Jz9CmUOBfY8cW8V867ZwpLskA3EK61g1IUKx0 Cp9W1+NHsaA1tICmuoSkAA5ouJXTGaIhlLIKnnLMf0HNyFth4aDZBP6a+fzU899lfVVM f8pD9nV9XFlactwo7qpdJkhMaJIUk3mN9BJ8u7wnxx8Qcg2gG4k7yBekZWwNRkZ5fsuC 2HnA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i4si2186711pgj.558.2019.08.28.06.32.26; Wed, 28 Aug 2019 06:32:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726775AbfH1NbG (ORCPT + 99 others); Wed, 28 Aug 2019 09:31:06 -0400 Received: from Galois.linutronix.de ([193.142.43.55]:47264 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726439AbfH1NbE (ORCPT ); Wed, 28 Aug 2019 09:31:04 -0400 Received: from [5.158.153.53] (helo=tip-bot2.lab.linutronix.de) by Galois.linutronix.de with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1i2y2J-0004MS-5C; Wed, 28 Aug 2019 15:30:55 +0200 Received: from [127.0.1.1] (localhost [IPv6:::1]) by tip-bot2.lab.linutronix.de (Postfix) with ESMTP id C55241C07D2; Wed, 28 Aug 2019 15:30:54 +0200 (CEST) Date: Wed, 28 Aug 2019 13:30:54 -0000 From: "tip-bot2 for Thomas Hellstrom" Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/vmware] x86/vmware: Update platform detection code for VMCALL/VMMCALL hypercalls Cc: Doug Covelli , Thomas Hellstrom , Borislav Petkov , "H. Peter Anvin" , Ingo Molnar , linux-graphics-maintainer@vmware.com, Thomas Gleixner , virtualization@lists.linux-foundation.org, , "x86-ml" , Ingo Molnar , Borislav Petkov , linux-kernel@vger.kernel.org In-Reply-To: <20190828080353.12658-2-thomas_os@shipmail.org> References: <20190828080353.12658-2-thomas_os@shipmail.org> MIME-Version: 1.0 Message-ID: <156699905467.5310.17325936546223421628.tip-bot2@tip-bot2> X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the x86/vmware branch of tip: Commit-ID: bac7b4e843232a3a49a042410cf743341eb0887e Gitweb: https://git.kernel.org/tip/bac7b4e843232a3a49a042410cf743341eb0887e Author: Thomas Hellstrom AuthorDate: Wed, 28 Aug 2019 10:03:50 +02:00 Committer: Borislav Petkov CommitterDate: Wed, 28 Aug 2019 10:48:30 +02:00 x86/vmware: Update platform detection code for VMCALL/VMMCALL hypercalls Vmware has historically used an INL instruction for this, but recent hardware versions support using VMCALL/VMMCALL instead, so use this method if supported at platform detection time. Explicitly code separate macro versions since the alternatives self-patching has not been performed at platform detection time. Also put tighter constraints on the assembly input parameters. Co-developed-by: Doug Covelli Signed-off-by: Doug Covelli Signed-off-by: Thomas Hellstrom Signed-off-by: Borislav Petkov Reviewed-by: Doug Covelli Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: linux-graphics-maintainer@vmware.com Cc: Thomas Gleixner Cc: virtualization@lists.linux-foundation.org Cc: Cc: x86-ml Link: https://lkml.kernel.org/r/20190828080353.12658-2-thomas_os@shipmail.org --- arch/x86/kernel/cpu/vmware.c | 88 ++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 3c64847..757dded 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -34,30 +34,65 @@ #undef pr_fmt #define pr_fmt(fmt) "vmware: " fmt -#define CPUID_VMWARE_INFO_LEAF 0x40000000 +#define CPUID_VMWARE_INFO_LEAF 0x40000000 +#define CPUID_VMWARE_FEATURES_LEAF 0x40000010 +#define CPUID_VMWARE_FEATURES_ECX_VMMCALL BIT(0) +#define CPUID_VMWARE_FEATURES_ECX_VMCALL BIT(1) + #define VMWARE_HYPERVISOR_MAGIC 0x564D5868 #define VMWARE_HYPERVISOR_PORT 0x5658 -#define VMWARE_PORT_CMD_GETVERSION 10 -#define VMWARE_PORT_CMD_GETHZ 45 -#define VMWARE_PORT_CMD_GETVCPU_INFO 68 -#define VMWARE_PORT_CMD_LEGACY_X2APIC 3 -#define VMWARE_PORT_CMD_VCPU_RESERVED 31 +#define VMWARE_CMD_GETVERSION 10 +#define VMWARE_CMD_GETHZ 45 +#define VMWARE_CMD_GETVCPU_INFO 68 +#define VMWARE_CMD_LEGACY_X2APIC 3 +#define VMWARE_CMD_VCPU_RESERVED 31 #define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \ __asm__("inl (%%dx)" : \ - "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \ - "0"(VMWARE_HYPERVISOR_MAGIC), \ - "1"(VMWARE_PORT_CMD_##cmd), \ - "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) : \ - "memory"); + "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \ + "a"(VMWARE_HYPERVISOR_MAGIC), \ + "c"(VMWARE_CMD_##cmd), \ + "d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) : \ + "memory") + +#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx) \ + __asm__("vmcall" : \ + "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \ + "a"(VMWARE_HYPERVISOR_MAGIC), \ + "c"(VMWARE_CMD_##cmd), \ + "d"(0), "b"(UINT_MAX) : \ + "memory") + +#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx) \ + __asm__("vmmcall" : \ + "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \ + "a"(VMWARE_HYPERVISOR_MAGIC), \ + "c"(VMWARE_CMD_##cmd), \ + "d"(0), "b"(UINT_MAX) : \ + "memory") + +#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do { \ + switch (vmware_hypercall_mode) { \ + case CPUID_VMWARE_FEATURES_ECX_VMCALL: \ + VMWARE_VMCALL(cmd, eax, ebx, ecx, edx); \ + break; \ + case CPUID_VMWARE_FEATURES_ECX_VMMCALL: \ + VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx); \ + break; \ + default: \ + VMWARE_PORT(cmd, eax, ebx, ecx, edx); \ + break; \ + } \ + } while (0) static unsigned long vmware_tsc_khz __ro_after_init; +static u8 vmware_hypercall_mode __ro_after_init; static inline int __vmware_platform(void) { uint32_t eax, ebx, ecx, edx; - VMWARE_PORT(GETVERSION, eax, ebx, ecx, edx); + VMWARE_CMD(GETVERSION, eax, ebx, ecx, edx); return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC; } @@ -136,7 +171,7 @@ static void __init vmware_platform_setup(void) uint32_t eax, ebx, ecx, edx; uint64_t lpj, tsc_khz; - VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); + VMWARE_CMD(GETHZ, eax, ebx, ecx, edx); if (ebx != UINT_MAX) { lpj = tsc_khz = eax | (((uint64_t)ebx) << 32); @@ -174,10 +209,21 @@ static void __init vmware_platform_setup(void) vmware_set_capabilities(); } +static u8 vmware_select_hypercall(void) +{ + int eax, ebx, ecx, edx; + + cpuid(CPUID_VMWARE_FEATURES_LEAF, &eax, &ebx, &ecx, &edx); + return (ecx & (CPUID_VMWARE_FEATURES_ECX_VMMCALL | + CPUID_VMWARE_FEATURES_ECX_VMCALL)); +} + /* * While checking the dmi string information, just checking the product * serial key should be enough, as this will always have a VMware * specific string when running under VMware hypervisor. + * If !boot_cpu_has(X86_FEATURE_HYPERVISOR), vmware_hypercall_mode + * intentionally defaults to 0. */ static uint32_t __init vmware_platform(void) { @@ -187,8 +233,16 @@ static uint32_t __init vmware_platform(void) cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &hyper_vendor_id[0], &hyper_vendor_id[1], &hyper_vendor_id[2]); - if (!memcmp(hyper_vendor_id, "VMwareVMware", 12)) + if (!memcmp(hyper_vendor_id, "VMwareVMware", 12)) { + if (eax >= CPUID_VMWARE_FEATURES_LEAF) + vmware_hypercall_mode = + vmware_select_hypercall(); + + pr_info("hypercall mode: 0x%02x\n", + (unsigned int) vmware_hypercall_mode); + return CPUID_VMWARE_INFO_LEAF; + } } else if (dmi_available && dmi_name_in_serial("VMware") && __vmware_platform()) return 1; @@ -200,9 +254,9 @@ static uint32_t __init vmware_platform(void) static bool __init vmware_legacy_x2apic_available(void) { uint32_t eax, ebx, ecx, edx; - VMWARE_PORT(GETVCPU_INFO, eax, ebx, ecx, edx); - return (eax & (1 << VMWARE_PORT_CMD_VCPU_RESERVED)) == 0 && - (eax & (1 << VMWARE_PORT_CMD_LEGACY_X2APIC)) != 0; + VMWARE_CMD(GETVCPU_INFO, eax, ebx, ecx, edx); + return (eax & (1 << VMWARE_CMD_VCPU_RESERVED)) == 0 && + (eax & (1 << VMWARE_CMD_LEGACY_X2APIC)) != 0; } const __initconst struct hypervisor_x86 x86_hyper_vmware = {