From patchwork Fri Jan 30 01:12:56 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nitin A Kamble X-Patchwork-Id: 4688 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n0U1DScl028089 for ; Fri, 30 Jan 2009 01:13:28 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753580AbZA3BM6 (ORCPT ); Thu, 29 Jan 2009 20:12:58 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753096AbZA3BM6 (ORCPT ); Thu, 29 Jan 2009 20:12:58 -0500 Received: from mga01.intel.com ([192.55.52.88]:47723 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753330AbZA3BM5 (ORCPT ); Thu, 29 Jan 2009 20:12:57 -0500 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 29 Jan 2009 17:01:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.37,347,1231142400"; d="diff'?scan'208";a="426665852" Received: from mukti.sc.intel.com (HELO [143.183.140.220]) ([143.183.140.220]) by fmsmga002.fm.intel.com with ESMTP; 29 Jan 2009 17:07:32 -0800 Subject: [kernel patch] exposing host cpuids to guest From: Nitin A Kamble To: avi@redhat.com Cc: kvm@vger.kernel.org Date: Thu, 29 Jan 2009 17:12:56 -0800 Message-Id: <1233277976.28605.9.camel@mukti.sc.intel.com> Mime-Version: 1.0 X-Mailer: Evolution 2.24.2 (2.24.2-2.fc10) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Avi, I reworked the earlier patch for exposing the host cpuid bits to guests. Attached is the patch for your kvm.git tree. With this new code in the kernel both the old and new qemu binaries are working. There are also changes for the kvm-userspace.git tree. I will be sending out those changes too. Please apply or give feedback for this patch. Thanks & Regards, Nitin diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 55fd4c5..b450a69 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -87,7 +87,7 @@ #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT) #define KVM_MIN_FREE_MMU_PAGES 5 #define KVM_REFILL_PAGES 25 -#define KVM_MAX_CPUID_ENTRIES 40 +#define KVM_MAX_CPUID_ENTRIES 100 #define KVM_NR_FIXED_MTRR_REGION 88 #define KVM_NR_VAR_MTRR 8 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e96edda..4d5124b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1060,19 +1060,25 @@ long kvm_arch_dev_ioctl(struct file *filp, case KVM_GET_SUPPORTED_CPUID: { struct kvm_cpuid2 __user *cpuid_arg = argp; struct kvm_cpuid2 cpuid; + int retry = 0; r = -EFAULT; if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) goto out; r = kvm_dev_ioctl_get_supported_cpuid(&cpuid, cpuid_arg->entries); - if (r) + if (r == -EAGAIN) + retry = 1; + else if (r) goto out; r = -EFAULT; if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid)) goto out; - r = 0; + if (retry) + r = -EAGAIN; + else + r = 0; break; } default: @@ -1325,10 +1331,14 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, { struct kvm_cpuid_entry2 *cpuid_entries; int limit, nent = 0, r = -E2BIG; + int sizer = 0; u32 func; - if (cpuid->nent < 1) - goto out; + if (cpuid->nent == 0) { + sizer = 1; + cpuid->nent = KVM_MAX_CPUID_ENTRIES; + } + r = -ENOMEM; cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent); if (!cpuid_entries) @@ -1339,6 +1349,7 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, for (func = 1; func <= limit && nent < cpuid->nent; ++func) do_cpuid_ent(&cpuid_entries[nent], func, 0, &nent, cpuid->nent); + r = -E2BIG; if (nent >= cpuid->nent) goto out_free; @@ -1348,16 +1359,21 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func) do_cpuid_ent(&cpuid_entries[nent], func, 0, &nent, cpuid->nent); - r = -EFAULT; - if (copy_to_user(entries, cpuid_entries, - nent * sizeof(struct kvm_cpuid_entry2))) - goto out_free; - cpuid->nent = nent; - r = 0; + + if (sizer) + r = -EAGAIN; + else { + r = -EFAULT; + if (copy_to_user(entries, cpuid_entries, + nent * sizeof(struct kvm_cpuid_entry2))) + goto out_free; + r = 0; + } out_free: vfree(cpuid_entries); out: + cpuid->nent = nent; return r; }