From patchwork Fri Sep 13 13:55:58 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 274778 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9A3CD2C00D9 for ; Fri, 13 Sep 2013 23:56:51 +1000 (EST) Received: from localhost ([::1]:47149 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VKTrd-0005BM-Jc for incoming@patchwork.ozlabs.org; Fri, 13 Sep 2013 09:56:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41947) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VKTr8-0004rD-Md for qemu-devel@nongnu.org; Fri, 13 Sep 2013 09:56:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VKTr0-00062B-2L for qemu-devel@nongnu.org; Fri, 13 Sep 2013 09:56:18 -0400 Received: from mail-ea0-x22b.google.com ([2a00:1450:4013:c01::22b]:37589) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VKTqz-00060e-SB for qemu-devel@nongnu.org; Fri, 13 Sep 2013 09:56:10 -0400 Received: by mail-ea0-f171.google.com with SMTP id n15so602579ead.16 for ; Fri, 13 Sep 2013 06:56:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=MlLTL60W3khdROt4Vl+7IvuXf0z6osCuRHLyaG5cDIc=; b=QtgY1uHEDooosvuA6QDolCduHVyG0141Ckm6Qa+9jCdL/vbit5vKCLiY4s5BY5XpNi 1LFzfVMb9uY299OmOiw9CNj6FZTi1J8ilu0K1+QLPiXeRQtcIuOdJnZcsZ73FsXEd5pC Z6bG4hE2VAdjRVG8jheuZTVlJfOIfeoGAQXGdazKCw+qJK6+Le0hX0DJkdVXguxWBwL2 8O0wgfexQBYGOf8Hoqm1HEXeu5eZ2TNXY4sNw3nX3LzTZXvVKssc9PhLO6WBD0+FagCB Xy80fCNbxq3PjFZgumsFoW0OI5/cRwTfHZtBtyYZr/XrEueIgzWLZxje3/oOz06/XEPj c4ig== X-Received: by 10.14.109.66 with SMTP id r42mr18492320eeg.43.1379080560648; Fri, 13 Sep 2013 06:56:00 -0700 (PDT) Received: from yakj.usersys.redhat.com (nat-pool-mxp-t.redhat.com. [209.132.186.18]) by mx.google.com with ESMTPSA id p5sm15160115eeg.5.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 13 Sep 2013 06:55:59 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 13 Sep 2013 15:55:58 +0200 Message-Id: <1379080558-16499-3-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1379080558-16499-1-git-send-email-pbonzini@redhat.com> References: <1379080558-16499-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4013:c01::22b Cc: kvm@vger.kernel.org Subject: [Qemu-devel] [PATCH v2 uq/master 2/2] x86: cpuid: reconstruct leaf 0Dh data X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The data in leaf 0Dh depends on information from other feature bits. Instead of passing it blindly from the host, compute it based on whether these feature bits are enabled. Signed-off-by: Paolo Bonzini --- target-i386/cpu.c | 63 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index ac83106..e6179f4 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -328,6 +328,15 @@ X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = { }; #undef REGISTER +typedef struct ExtSaveArea { + uint32_t feature, bits; + uint32_t offset, size; +} ExtSaveArea; + +static const ExtSaveArea ext_save_areas[] = { + [2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX, + .offset = 0x100, .size = 0x240 }, +}; const char *get_register_name_32(unsigned int reg) { @@ -2169,29 +2178,51 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *edx = 0; } break; - case 0xD: + case 0xD: { + KVMState *s = cs->kvm_state; + uint64_t kvm_mask; + int i; + /* Processor Extended State */ - if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) { - *eax = 0; - *ebx = 0; - *ecx = 0; - *edx = 0; + *eax = 0; + *ebx = 0; + *ecx = 0; + *edx = 0; + if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) || !kvm_enabled()) { break; } - if (kvm_enabled()) { - KVMState *s = cs->kvm_state; + kvm_mask = + kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX) | + ((uint64_t)kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX) << 32); - *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX); - *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX); - *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX); - *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX); - } else { - *eax = 0; - *ebx = 0; - *ecx = 0; - *edx = 0; + if (count == 0) { + *ecx = 0x240; + for (i = 2; i < ARRAY_SIZE(ext_save_areas); i++) { + const ExtSaveArea *esa = &ext_save_areas[i]; + if ((env->features[esa->feature] & esa->bits) == esa->bits && + (kvm_mask & (1 << i)) != 0) { + if (i < 32) { + *eax |= 1 << i; + } else { + *edx |= 1 << (i - 32); + } + *ecx = MAX(*ecx, esa->offset + esa->size); + } + } + *eax |= kvm_mask & 3; + *ebx = *ecx; + } else if (count == 1) { + *eax = kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX); + } else if (count < ARRAY_SIZE(ext_save_areas)) { + const ExtSaveArea *esa = &ext_save_areas[count]; + if ((env->features[esa->feature] & esa->bits) == esa->bits && + (kvm_mask & (1 << count)) != 0) { + *eax = esa->offset; + *ebx = esa->size; + } } break; + } case 0x80000000: *eax = env->cpuid_xlevel; *ebx = env->cpuid_vendor1;