From patchwork Mon Dec 7 10:58:02 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 40451 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3D423B6F0C for ; Mon, 7 Dec 2009 22:02:54 +1100 (EST) Received: from localhost ([127.0.0.1]:35304 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NHbMh-0005Y2-88 for incoming@patchwork.ozlabs.org; Mon, 07 Dec 2009 06:02:51 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NHbIU-0002xy-ES for qemu-devel@nongnu.org; Mon, 07 Dec 2009 05:58:30 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NHbIP-0002uR-K0 for qemu-devel@nongnu.org; Mon, 07 Dec 2009 05:58:30 -0500 Received: from [199.232.76.173] (port=54121 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NHbIP-0002uL-C1 for qemu-devel@nongnu.org; Mon, 07 Dec 2009 05:58:25 -0500 Received: from tx2ehsobe003.messaging.microsoft.com ([65.55.88.13]:41794 helo=TX2EHSOBE006.bigfish.com) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_ARCFOUR_MD5:16) (Exim 4.60) (envelope-from ) id 1NHbIO-0007mk-UG for qemu-devel@nongnu.org; Mon, 07 Dec 2009 05:58:25 -0500 Received: from mail131-tx2-R.bigfish.com (10.9.14.244) by TX2EHSOBE006.bigfish.com (10.9.40.26) with Microsoft SMTP Server id 8.1.340.0; Mon, 7 Dec 2009 10:58:23 +0000 Received: from mail131-tx2 (localhost.localdomain [127.0.0.1]) by mail131-tx2-R.bigfish.com (Postfix) with ESMTP id AC4E41390167; Mon, 7 Dec 2009 10:58:22 +0000 (UTC) X-SpamScore: -2 X-BigFish: VPS-2(zz936eMab9bhzz1202hzzz32i6bh43j61h) X-Spam-TCS-SCL: 0:0 Received: from mail131-tx2 (localhost.localdomain [127.0.0.1]) by mail131-tx2 (MessageSwitch) id 1260183500389530_27742; Mon, 7 Dec 2009 10:58:20 +0000 (UTC) Received: from TX2EHSMHS025.bigfish.com (unknown [10.9.14.236]) by mail131-tx2.bigfish.com (Postfix) with ESMTP id 5C21F51005A; Mon, 7 Dec 2009 10:58:20 +0000 (UTC) Received: from ausb3extmailp01.amd.com (163.181.251.8) by TX2EHSMHS025.bigfish.com (10.9.99.125) with Microsoft SMTP Server (TLS) id 14.0.482.32; Mon, 7 Dec 2009 10:58:19 +0000 Received: from ausb3twp01.amd.com ([163.181.250.37]) by ausb3extmailp01.amd.com (Switch-3.2.7/Switch-3.2.7) with ESMTP id nB7AwBFI014966; Mon, 7 Dec 2009 04:58:14 -0600 X-WSS-ID: 0KUA3SZ-01-41D-02 X-M-MSG: Received: from sausexbh2.amd.com (SAUSEXBH2.amd.com [163.181.22.102]) by ausb3twp01.amd.com (Tumbleweed MailGate 3.7.2) with ESMTP id 22B76102994D; Mon, 7 Dec 2009 04:58:11 -0600 (CST) Received: from sausexmb5.amd.com ([163.181.49.129]) by sausexbh2.amd.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 7 Dec 2009 04:58:14 -0600 Received: from seurexmb1.amd.com ([165.204.9.130]) by sausexmb5.amd.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 7 Dec 2009 04:58:13 -0600 Received: from gwo.osrc.amd.com ([165.204.16.204]) by seurexmb1.amd.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 7 Dec 2009 11:58:11 +0100 Received: from localhost.localdomain (tronje.osrc.amd.com [165.204.15.48]) by gwo.osrc.amd.com (Postfix) with ESMTP id 5E02649C150; Mon, 7 Dec 2009 10:58:11 +0000 (GMT) From: Andre Przywara To: aliguori@linux.vnet.ibm.com Date: Mon, 7 Dec 2009 11:58:02 +0100 Message-ID: <1260183482-22331-1-git-send-email-andre.przywara@amd.com> X-Mailer: git-send-email 1.6.4 X-OriginalArrivalTime: 07 Dec 2009 10:58:11.0626 (UTC) FILETIME=[2AF228A0:01CA772C] MIME-Version: 1.0 X-Reverse-DNS: unknown X-detected-operating-system: by monty-python.gnu.org: Windows 2000 SP4, XP SP1+ Cc: Andre Przywara , qemu-devel@nongnu.org Subject: [Qemu-devel] [FOR 0.12][PATCH] cpuid: Fix multicore setup on Intel X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The multicore CPUID code detects whether the guest is an Intel or an AMD CPU, because the Linux kernel is picky about the CmpLegacy bit. KVM by default passes through the host's vendor, which was not catched by the code. So fork out the vendor determining bits into a separate function to be used from both places and always get the real vendor. This fixes KVM's multicore setup on Intel CPUs. Signed-off-by: Andre Przywara Reported-by: Dietmar Maurer --- target-i386/helper.c | 46 +++++++++++++++++++++++++++++++--------------- 1 files changed, 31 insertions(+), 15 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index 957b3fc..08e6d6c 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1638,6 +1638,24 @@ static void host_cpuid(uint32_t function, uint32_t count, #endif } +static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx, + uint32_t *ecx, uint32_t *edx) +{ + *ebx = env->cpuid_vendor1; + *edx = env->cpuid_vendor2; + *ecx = env->cpuid_vendor3; + + /* sysenter isn't supported on compatibility mode on AMD, syscall + * isn't supported in compatibility mode on Intel. + * Normally we advertise the actual cpu vendor, but you can override + * this if you want to use KVM's sysenter/syscall emulation + * in compatibility mode and when doing cross vendor migration + */ + if (kvm_enabled() && env->cpuid_vendor_override) { + host_cpuid(0, 0, NULL, ebx, ecx, edx); + } +} + void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) @@ -1654,16 +1672,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, switch(index) { case 0: *eax = env->cpuid_level; - *ebx = env->cpuid_vendor1; - *edx = env->cpuid_vendor2; - *ecx = env->cpuid_vendor3; - - /* sysenter isn't supported on compatibility mode on AMD. and syscall - * isn't supported in compatibility mode on Intel. so advertise the - * actuall cpu, and say goodbye to migration between different vendors - * is you use compatibility mode. */ - if (kvm_enabled() && !env->cpuid_vendor_override) - host_cpuid(0, 0, NULL, ebx, ecx, edx); + get_cpuid_vendor(env, ebx, ecx, edx); break; case 1: *eax = env->cpuid_version; @@ -1759,11 +1768,18 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = env->cpuid_ext3_features; *edx = env->cpuid_ext2_features; - if (env->nr_cores * env->nr_threads > 1 && - env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && - env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && - env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) { - *ecx |= 1 << 1; /* CmpLegacy bit */ + /* The Linux kernel checks for the CMPLegacy bit and + * discards multiple thread information if it is set. + * So dont set it here for Intel to make Linux guests happy. + */ + if (env->nr_cores * env->nr_threads > 1) { + uint32_t tebx, tecx, tedx; + get_cpuid_vendor(env, &tebx, &tecx, &tedx); + if (tebx != CPUID_VENDOR_INTEL_1 || + tedx != CPUID_VENDOR_INTEL_2 || + tecx != CPUID_VENDOR_INTEL_3) { + *ecx |= 1 << 1; /* CmpLegacy bit */ + } } if (kvm_enabled()) {