From: Avi Kivity <avi@redhat.com> To: Anthony Liguori <anthony@codemonkey.ws> Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org Subject: [PATCH 1/4] kvm: Add support for querying supported cpu features Date: Sun, 3 May 2009 17:04:01 +0300 [thread overview] Message-ID: <1241359444-8538-2-git-send-email-avi@redhat.com> (raw) In-Reply-To: <1241359444-8538-1-git-send-email-avi@redhat.com> kvm does not support all cpu features; add support for dunamically querying the supported feature set. Signed-off-by: Avi Kivity <avi@redhat.com> --- kvm.h | 3 ++ target-i386/kvm.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 0 deletions(-) diff --git a/kvm.h b/kvm.h index bd4e8d4..c134c45 100644 --- a/kvm.h +++ b/kvm.h @@ -124,6 +124,9 @@ void kvm_arch_remove_all_hw_breakpoints(void); void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg); +uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, + int reg); + /* generic hooks - to be moved/refactored once there are more users */ static inline void cpu_synchronize_state(CPUState *env, int modified) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index b534b2d..5f54ff5 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -34,6 +34,86 @@ do { } while (0) #endif +#ifdef KVM_CAP_EXT_CPUID + +static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) +{ + struct kvm_cpuid2 *cpuid; + int r, size; + + size = sizeof(*cpuid) + max * sizeof(*cpuid->entries); + cpuid = (struct kvm_cpuid2 *)qemu_mallocz(size); + cpuid->nent = max; + r = kvm_ioctl(s, KVM_GET_SUPPORTED_CPUID, cpuid); + if (r < 0) { + if (r == -E2BIG) { + qemu_free(cpuid); + return NULL; + } else { + fprintf(stderr, "KVM_GET_SUPPORTED_CPUID failed: %s\n", + strerror(-r)); + exit(1); + } + } + return cpuid; +} + +uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg) +{ + struct kvm_cpuid2 *cpuid; + int i, max; + uint32_t ret = 0; + uint32_t cpuid_1_edx; + + if (!kvm_check_extension(KVM_CAP_EXT_CPUID)) { + return -1U; + } + + max = 1; + while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) { + max *= 2; + } + + for (i = 0; i < cpuid->nent; ++i) { + if (cpuid->entries[i].function == function) { + switch (reg) { + case R_EAX: + ret = cpuid->entries[i].eax; + break; + case R_EBX: + ret = cpuid->entries[i].ebx; + break; + case R_ECX: + ret = cpuid->entries[i].ecx; + break; + case R_EDX: + ret = cpuid->entries[i].edx; + if (function == 0x80000001) { + /* On Intel, kvm returns cpuid according to the Intel spec, + * so add missing bits according to the AMD spec: + */ + cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, R_EDX); + ret |= cpuid_1_edx & 0xdfeff7ff; + } + break; + } + } + } + + qemu_free(cpuid); + + return ret; +} + +#else + +uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg) +{ + return -1U; +} + +#endif + int kvm_arch_init_vcpu(CPUState *env) { struct { -- 1.6.1.1
WARNING: multiple messages have this Message-ID (diff)
From: Avi Kivity <avi@redhat.com> To: Anthony Liguori <anthony@codemonkey.ws> Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org Subject: [Qemu-devel] [PATCH 1/4] kvm: Add support for querying supported cpu features Date: Sun, 3 May 2009 17:04:01 +0300 [thread overview] Message-ID: <1241359444-8538-2-git-send-email-avi@redhat.com> (raw) In-Reply-To: <1241359444-8538-1-git-send-email-avi@redhat.com> kvm does not support all cpu features; add support for dunamically querying the supported feature set. Signed-off-by: Avi Kivity <avi@redhat.com> --- kvm.h | 3 ++ target-i386/kvm.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 0 deletions(-) diff --git a/kvm.h b/kvm.h index bd4e8d4..c134c45 100644 --- a/kvm.h +++ b/kvm.h @@ -124,6 +124,9 @@ void kvm_arch_remove_all_hw_breakpoints(void); void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg); +uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, + int reg); + /* generic hooks - to be moved/refactored once there are more users */ static inline void cpu_synchronize_state(CPUState *env, int modified) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index b534b2d..5f54ff5 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -34,6 +34,86 @@ do { } while (0) #endif +#ifdef KVM_CAP_EXT_CPUID + +static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) +{ + struct kvm_cpuid2 *cpuid; + int r, size; + + size = sizeof(*cpuid) + max * sizeof(*cpuid->entries); + cpuid = (struct kvm_cpuid2 *)qemu_mallocz(size); + cpuid->nent = max; + r = kvm_ioctl(s, KVM_GET_SUPPORTED_CPUID, cpuid); + if (r < 0) { + if (r == -E2BIG) { + qemu_free(cpuid); + return NULL; + } else { + fprintf(stderr, "KVM_GET_SUPPORTED_CPUID failed: %s\n", + strerror(-r)); + exit(1); + } + } + return cpuid; +} + +uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg) +{ + struct kvm_cpuid2 *cpuid; + int i, max; + uint32_t ret = 0; + uint32_t cpuid_1_edx; + + if (!kvm_check_extension(KVM_CAP_EXT_CPUID)) { + return -1U; + } + + max = 1; + while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) { + max *= 2; + } + + for (i = 0; i < cpuid->nent; ++i) { + if (cpuid->entries[i].function == function) { + switch (reg) { + case R_EAX: + ret = cpuid->entries[i].eax; + break; + case R_EBX: + ret = cpuid->entries[i].ebx; + break; + case R_ECX: + ret = cpuid->entries[i].ecx; + break; + case R_EDX: + ret = cpuid->entries[i].edx; + if (function == 0x80000001) { + /* On Intel, kvm returns cpuid according to the Intel spec, + * so add missing bits according to the AMD spec: + */ + cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, R_EDX); + ret |= cpuid_1_edx & 0xdfeff7ff; + } + break; + } + } + } + + qemu_free(cpuid); + + return ret; +} + +#else + +uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg) +{ + return -1U; +} + +#endif + int kvm_arch_init_vcpu(CPUState *env) { struct { -- 1.6.1.1
next prev parent reply other threads:[~2009-05-03 14:04 UTC|newest] Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top 2009-05-03 14:04 [PATCH 0/4] Fix kvm cpuid reporting Avi Kivity 2009-05-03 14:04 ` [Qemu-devel] " Avi Kivity 2009-05-03 14:04 ` Avi Kivity [this message] 2009-05-03 14:04 ` [Qemu-devel] [PATCH 1/4] kvm: Add support for querying supported cpu features Avi Kivity 2009-05-08 20:50 ` Anthony Liguori 2009-05-08 20:50 ` [Qemu-devel] " Anthony Liguori 2009-05-08 21:09 ` Anthony Liguori 2009-05-08 21:09 ` [Qemu-devel] " Anthony Liguori 2009-05-09 8:41 ` Avi Kivity 2009-05-09 8:41 ` [Qemu-devel] " Avi Kivity 2009-05-03 14:04 ` [PATCH 2/4] Make x86 cpuid feature names available in file scope Avi Kivity 2009-05-03 14:04 ` [Qemu-devel] " Avi Kivity 2009-05-03 14:04 ` [PATCH 3/4] Fix x86 feature modifications for features that set multiple bits Avi Kivity 2009-05-03 14:04 ` [Qemu-devel] " Avi Kivity 2009-05-03 14:04 ` [PATCH 4/4] kvm: Trim cpu features not supported by kvm Avi Kivity 2009-05-03 14:04 ` [Qemu-devel] " Avi Kivity 2009-05-12 11:52 ` Mark McLoughlin 2009-05-12 11:52 ` Mark McLoughlin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1241359444-8538-2-git-send-email-avi@redhat.com \ --to=avi@redhat.com \ --cc=anthony@codemonkey.ws \ --cc=kvm@vger.kernel.org \ --cc=qemu-devel@nongnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.