From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LSFfv-0006Cn-Fy for qemu-devel@nongnu.org; Wed, 28 Jan 2009 14:02:11 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LSFft-0006AM-Qj for qemu-devel@nongnu.org; Wed, 28 Jan 2009 14:02:10 -0500 Received: from [199.232.76.173] (port=40910 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LSFft-00069x-2i for qemu-devel@nongnu.org; Wed, 28 Jan 2009 14:02:09 -0500 Received: from mx2.redhat.com ([66.187.237.31]:51333) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LSFfs-0006eq-6C for qemu-devel@nongnu.org; Wed, 28 Jan 2009 14:02:08 -0500 From: Glauber Costa Date: Wed, 28 Jan 2009 14:02:03 -0500 Message-Id: <1233169325-5487-2-git-send-email-glommer@redhat.com> In-Reply-To: <1233169325-5487-1-git-send-email-glommer@redhat.com> References: <1233169325-5487-1-git-send-email-glommer@redhat.com> Subject: [Qemu-devel] [PATCH 1/3] expose paravirt feature list to cpuid Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@us.ibm.com Expose the paravirt features provided by the host to the guest. The features exposed uses qemu just as a medium, since they only depend on a negotiation between the host and guest directly. As a direct result, we're now able to run the kvm pvclock in qemu based kvm guests. Signed-off-by: Glauber Costa --- kvm.h | 1 + target-i386/kvm.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/kvm.h b/kvm.h index efce145..db58baa 100644 --- a/kvm.h +++ b/kvm.h @@ -17,6 +17,7 @@ #include "config.h" #ifdef CONFIG_KVM +#include extern int kvm_allowed; #define kvm_enabled() (kvm_allowed) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 2412ae4..7f4e5aa 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -33,16 +33,61 @@ do { } while (0) #endif +struct kvm_para_features { + int cap; + int feature; +} para_features[] = { +#ifdef KVM_CAP_CLOCKSOURCE + { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE }, +#endif +#ifdef KVM_CAP_NOP_IO_DELAY + { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY }, +#endif +#ifdef KVM_CAP_PV_MMU + { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP }, +#endif +#ifdef KVM_CAP_CR3_CACHE + { KVM_CAP_CR3_CACHE, KVM_FEATURE_CR3_CACHE }, +#endif +}; + +static uint32_t get_para_features(CPUState *env) +{ + uint32_t i, features = 0; + + for (i = 0; i < ARRAY_SIZE(para_features); i++) { + if (kvm_ioctl(env->kvm_state, KVM_CHECK_EXTENSION, para_features[i].cap)) + features |= (1 << para_features[i].feature); + } + + return features; +} int kvm_arch_init_vcpu(CPUState *env) { struct { struct kvm_cpuid cpuid; struct kvm_cpuid_entry entries[100]; } __attribute__((packed)) cpuid_data; - uint32_t limit, i, cpuid_i; + uint32_t limit, i, cpuid_i = 0; uint32_t eax, ebx, ecx, edx; +#ifdef KVM_CPUID_SIGNATURE + struct kvm_cpuid_entry *pv_ent; + + /* Paravirtualization CPUIDs */ + pv_ent = &cpuid_data.entries[cpuid_i++]; + memset(pv_ent, 0, sizeof(*pv_ent)); + pv_ent->function = KVM_CPUID_SIGNATURE; + pv_ent->eax = 0; + pv_ent->ebx = 0x4b4d564b; /* KVMKVMK */ + pv_ent->ecx = 0x564b4d56; /* VMKV */ + pv_ent->edx = 0x0000004d; /* M */ + + pv_ent = &cpuid_data.entries[cpuid_i++]; + memset(pv_ent, 0, sizeof(*pv_ent)); + pv_ent->function = KVM_CPUID_FEATURES; + pv_ent->eax = get_para_features(env); +#endif - cpuid_i = 0; cpu_x86_cpuid(env, 0, &eax, &ebx, &ecx, &edx); limit = eax; -- 1.5.6.5