All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Fix kvm cpuid reporting
@ 2009-05-03 14:04 ` Avi Kivity
  0 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-03 14:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

kvm supports an interface for reporting which cpuid features are supported.
Use it for trimming the cpu feature set reported to the guest.  This prevents,
for example, reporting NX to a guest when in fact we do not support it.

Avi Kivity (4):
  kvm: Add support for querying supported cpu features
  Make x86 cpuid feature names available in file scope
  Fix x86 feature modifications for features that set multiple bits
  kvm: Trim cpu features not supported by kvm

 kvm.h                |    3 ++
 target-i386/helper.c |   98 +++++++++++++++++++++++++++++++++----------------
 target-i386/kvm.c    |   80 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+), 32 deletions(-)


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 0/4] Fix kvm cpuid reporting
@ 2009-05-03 14:04 ` Avi Kivity
  0 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-03 14:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

kvm supports an interface for reporting which cpuid features are supported.
Use it for trimming the cpu feature set reported to the guest.  This prevents,
for example, reporting NX to a guest when in fact we do not support it.

Avi Kivity (4):
  kvm: Add support for querying supported cpu features
  Make x86 cpuid feature names available in file scope
  Fix x86 feature modifications for features that set multiple bits
  kvm: Trim cpu features not supported by kvm

 kvm.h                |    3 ++
 target-i386/helper.c |   98 +++++++++++++++++++++++++++++++++----------------
 target-i386/kvm.c    |   80 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+), 32 deletions(-)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/4] kvm: Add support for querying supported cpu features
  2009-05-03 14:04 ` [Qemu-devel] " Avi Kivity
@ 2009-05-03 14:04   ` Avi Kivity
  -1 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-03 14:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

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


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 1/4] kvm: Add support for querying supported cpu features
@ 2009-05-03 14:04   ` Avi Kivity
  0 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-03 14:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

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

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/4] Make x86 cpuid feature names available in file scope
  2009-05-03 14:04 ` [Qemu-devel] " Avi Kivity
@ 2009-05-03 14:04   ` Avi Kivity
  -1 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-03 14:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

To be used later.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 target-i386/helper.c |   55 +++++++++++++++++++++++++------------------------
 1 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index a070e08..88585b8 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -32,39 +32,40 @@
 
 //#define DEBUG_MMU
 
+/* feature flags taken from "Intel Processor Identification and the CPUID
+ * Instruction" and AMD's "CPUID Specification". In cases of disagreement
+ * about feature names, the Linux name is used. */
+static const char *feature_name[] = {
+    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+    "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
+    "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
+};
+static const char *ext_feature_name[] = {
+    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
+    "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
+    NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+static const char *ext2_feature_name[] = {
+    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
+    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
+};
+static const char *ext3_feature_name[] = {
+    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
+    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
 static void add_flagname_to_bitmaps(char *flagname, uint32_t *features, 
                                     uint32_t *ext_features, 
                                     uint32_t *ext2_features, 
                                     uint32_t *ext3_features)
 {
     int i;
-    /* feature flags taken from "Intel Processor Identification and the CPUID
-     * Instruction" and AMD's "CPUID Specification". In cases of disagreement 
-     * about feature names, the Linux name is used. */
-    static const char *feature_name[] = {
-        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-        "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
-        "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
-    };
-    static const char *ext_feature_name[] = {
-       "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
-       "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
-       NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    };
-    static const char *ext2_feature_name[] = {
-       "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-       "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
-       "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
-       "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
-    };
-    static const char *ext3_feature_name[] = {
-       "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
-       "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    };
 
     for ( i = 0 ; i < 32 ; i++ ) 
         if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
-- 
1.6.1.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 2/4] Make x86 cpuid feature names available in file scope
@ 2009-05-03 14:04   ` Avi Kivity
  0 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-03 14:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

To be used later.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 target-i386/helper.c |   55 +++++++++++++++++++++++++------------------------
 1 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index a070e08..88585b8 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -32,39 +32,40 @@
 
 //#define DEBUG_MMU
 
+/* feature flags taken from "Intel Processor Identification and the CPUID
+ * Instruction" and AMD's "CPUID Specification". In cases of disagreement
+ * about feature names, the Linux name is used. */
+static const char *feature_name[] = {
+    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+    "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
+    "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
+};
+static const char *ext_feature_name[] = {
+    "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
+    "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
+    NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+static const char *ext2_feature_name[] = {
+    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
+    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
+};
+static const char *ext3_feature_name[] = {
+    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
+    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
 static void add_flagname_to_bitmaps(char *flagname, uint32_t *features, 
                                     uint32_t *ext_features, 
                                     uint32_t *ext2_features, 
                                     uint32_t *ext3_features)
 {
     int i;
-    /* feature flags taken from "Intel Processor Identification and the CPUID
-     * Instruction" and AMD's "CPUID Specification". In cases of disagreement 
-     * about feature names, the Linux name is used. */
-    static const char *feature_name[] = {
-        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-        "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
-        "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
-    };
-    static const char *ext_feature_name[] = {
-       "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
-       "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
-       NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    };
-    static const char *ext2_feature_name[] = {
-       "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-       "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
-       "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
-       "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
-    };
-    static const char *ext3_feature_name[] = {
-       "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
-       "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    };
 
     for ( i = 0 ; i < 32 ; i++ ) 
         if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
-- 
1.6.1.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/4] Fix x86 feature modifications for features that set multiple bits
  2009-05-03 14:04 ` [Qemu-devel] " Avi Kivity
@ 2009-05-03 14:04   ` Avi Kivity
  -1 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-03 14:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

QEMU allows adding or removing cpu features by using the syntax '-cpu +feature'
or '-cpu -feature'.  Some cpuid features cause more than one bit to be set or
cleared; but QEMU stops after just one bit has been modified, causing the
feature bits to be inconsistent.

Fix by allowing all feature bits corresponding to a given name to be set.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 target-i386/helper.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index 88585b8..0c91133 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -66,28 +66,31 @@ static void add_flagname_to_bitmaps(char *flagname, uint32_t *features,
                                     uint32_t *ext3_features)
 {
     int i;
+    int found = 0;
 
     for ( i = 0 ; i < 32 ; i++ ) 
         if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
             *features |= 1 << i;
-            return;
+            found = 1;
         }
     for ( i = 0 ; i < 32 ; i++ ) 
         if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
             *ext_features |= 1 << i;
-            return;
+            found = 1;
         }
     for ( i = 0 ; i < 32 ; i++ ) 
         if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
             *ext2_features |= 1 << i;
-            return;
+            found = 1;
         }
     for ( i = 0 ; i < 32 ; i++ ) 
         if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
             *ext3_features |= 1 << i;
-            return;
+            found = 1;
         }
-    fprintf(stderr, "CPU feature %s not found\n", flagname);
+    if (!found) {
+        fprintf(stderr, "CPU feature %s not found\n", flagname);
+    }
 }
 
 typedef struct x86_def_t {
-- 
1.6.1.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 3/4] Fix x86 feature modifications for features that set multiple bits
@ 2009-05-03 14:04   ` Avi Kivity
  0 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-03 14:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

QEMU allows adding or removing cpu features by using the syntax '-cpu +feature'
or '-cpu -feature'.  Some cpuid features cause more than one bit to be set or
cleared; but QEMU stops after just one bit has been modified, causing the
feature bits to be inconsistent.

Fix by allowing all feature bits corresponding to a given name to be set.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 target-i386/helper.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index 88585b8..0c91133 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -66,28 +66,31 @@ static void add_flagname_to_bitmaps(char *flagname, uint32_t *features,
                                     uint32_t *ext3_features)
 {
     int i;
+    int found = 0;
 
     for ( i = 0 ; i < 32 ; i++ ) 
         if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
             *features |= 1 << i;
-            return;
+            found = 1;
         }
     for ( i = 0 ; i < 32 ; i++ ) 
         if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
             *ext_features |= 1 << i;
-            return;
+            found = 1;
         }
     for ( i = 0 ; i < 32 ; i++ ) 
         if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
             *ext2_features |= 1 << i;
-            return;
+            found = 1;
         }
     for ( i = 0 ; i < 32 ; i++ ) 
         if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
             *ext3_features |= 1 << i;
-            return;
+            found = 1;
         }
-    fprintf(stderr, "CPU feature %s not found\n", flagname);
+    if (!found) {
+        fprintf(stderr, "CPU feature %s not found\n", flagname);
+    }
 }
 
 typedef struct x86_def_t {
-- 
1.6.1.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/4] kvm: Trim cpu features not supported by kvm
  2009-05-03 14:04 ` [Qemu-devel] " Avi Kivity
@ 2009-05-03 14:04   ` Avi Kivity
  -1 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-03 14:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

Remove cpu features that are not supported by kvm from the cpuid features
reported to the guest.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 target-i386/helper.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index 0c91133..bdf242b 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -93,6 +93,21 @@ static void add_flagname_to_bitmaps(char *flagname, uint32_t *features,
     }
 }
 
+static void kvm_trim_features(uint32_t *features, uint32_t supported,
+                              const char *names[])
+{
+    int i;
+    uint32_t mask;
+
+    for (i = 0; i < 32; ++i) {
+        mask = 1U << i;
+        if ((*features & mask) && !(supported & mask)) {
+            printf("Processor feature %s not supported by kvm\n", names[i]);
+            *features &= ~mask;
+        }
+    }
+}
+
 typedef struct x86_def_t {
     const char *name;
     uint32_t level;
@@ -1699,5 +1714,20 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
 
     qemu_init_vcpu(env);
 
+    if (kvm_enabled()) {
+        kvm_trim_features(&env->cpuid_features,
+                          kvm_arch_get_supported_cpuid(env, 1, R_EDX),
+                          feature_name);
+        kvm_trim_features(&env->cpuid_ext_features,
+                          kvm_arch_get_supported_cpuid(env, 1, R_ECX),
+                          ext_feature_name);
+        kvm_trim_features(&env->cpuid_ext2_features,
+                          kvm_arch_get_supported_cpuid(env, 0x80000001, R_EDX),
+                          ext2_feature_name);
+        kvm_trim_features(&env->cpuid_ext3_features,
+                          kvm_arch_get_supported_cpuid(env, 0x80000001, R_ECX),
+                          ext3_feature_name);
+    }
+
     return env;
 }
-- 
1.6.1.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 4/4] kvm: Trim cpu features not supported by kvm
@ 2009-05-03 14:04   ` Avi Kivity
  0 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-03 14:04 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

Remove cpu features that are not supported by kvm from the cpuid features
reported to the guest.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 target-i386/helper.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index 0c91133..bdf242b 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -93,6 +93,21 @@ static void add_flagname_to_bitmaps(char *flagname, uint32_t *features,
     }
 }
 
+static void kvm_trim_features(uint32_t *features, uint32_t supported,
+                              const char *names[])
+{
+    int i;
+    uint32_t mask;
+
+    for (i = 0; i < 32; ++i) {
+        mask = 1U << i;
+        if ((*features & mask) && !(supported & mask)) {
+            printf("Processor feature %s not supported by kvm\n", names[i]);
+            *features &= ~mask;
+        }
+    }
+}
+
 typedef struct x86_def_t {
     const char *name;
     uint32_t level;
@@ -1699,5 +1714,20 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
 
     qemu_init_vcpu(env);
 
+    if (kvm_enabled()) {
+        kvm_trim_features(&env->cpuid_features,
+                          kvm_arch_get_supported_cpuid(env, 1, R_EDX),
+                          feature_name);
+        kvm_trim_features(&env->cpuid_ext_features,
+                          kvm_arch_get_supported_cpuid(env, 1, R_ECX),
+                          ext_feature_name);
+        kvm_trim_features(&env->cpuid_ext2_features,
+                          kvm_arch_get_supported_cpuid(env, 0x80000001, R_EDX),
+                          ext2_feature_name);
+        kvm_trim_features(&env->cpuid_ext3_features,
+                          kvm_arch_get_supported_cpuid(env, 0x80000001, R_ECX),
+                          ext3_feature_name);
+    }
+
     return env;
 }
-- 
1.6.1.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/4] kvm: Add support for querying supported cpu features
  2009-05-03 14:04   ` [Qemu-devel] " Avi Kivity
@ 2009-05-08 20:50     ` Anthony Liguori
  -1 siblings, 0 replies; 18+ messages in thread
From: Anthony Liguori @ 2009-05-08 20:50 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Anthony Liguori, qemu-devel, kvm

Avi Kivity wrote:
> 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;
> +    

kvm_check_extension doesn't exist in upstream QEMU.  It's a good idea 
though so I added it in a previous commit.  However, I changed the 
signature to it to take a KVMState * as the first argument (which is 
available in env->kvm_state).  I updated this patch to pass the extra 
's' parameter.

Regards,

Anthony Liguori


-- 
Regards,

Anthony Liguori


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Qemu-devel] Re: [PATCH 1/4] kvm: Add support for querying supported cpu features
@ 2009-05-08 20:50     ` Anthony Liguori
  0 siblings, 0 replies; 18+ messages in thread
From: Anthony Liguori @ 2009-05-08 20:50 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel, kvm

Avi Kivity wrote:
> 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;
> +    

kvm_check_extension doesn't exist in upstream QEMU.  It's a good idea 
though so I added it in a previous commit.  However, I changed the 
signature to it to take a KVMState * as the first argument (which is 
available in env->kvm_state).  I updated this patch to pass the extra 
's' parameter.

Regards,

Anthony Liguori


-- 
Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/4] kvm: Add support for querying supported cpu features
  2009-05-08 20:50     ` [Qemu-devel] " Anthony Liguori
@ 2009-05-08 21:09       ` Anthony Liguori
  -1 siblings, 0 replies; 18+ messages in thread
From: Anthony Liguori @ 2009-05-08 21:09 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Anthony Liguori, qemu-devel, kvm

Anthony Liguori wrote:
>
> kvm_check_extension doesn't exist in upstream QEMU.  It's a good idea 
> though so I added it in a previous commit.  However, I changed the 
> signature to it to take a KVMState * as the first argument (which is 
> available in env->kvm_state).  I updated this patch to pass the extra 
> 's' parameter.

Ah, you had a patch, I just didn't notice in my queue.

Still wanted to make the KVMState change though.

-- 
Regards,

Anthony Liguori


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Qemu-devel] Re: [PATCH 1/4] kvm: Add support for querying supported cpu features
@ 2009-05-08 21:09       ` Anthony Liguori
  0 siblings, 0 replies; 18+ messages in thread
From: Anthony Liguori @ 2009-05-08 21:09 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel, kvm

Anthony Liguori wrote:
>
> kvm_check_extension doesn't exist in upstream QEMU.  It's a good idea 
> though so I added it in a previous commit.  However, I changed the 
> signature to it to take a KVMState * as the first argument (which is 
> available in env->kvm_state).  I updated this patch to pass the extra 
> 's' parameter.

Ah, you had a patch, I just didn't notice in my queue.

Still wanted to make the KVMState change though.

-- 
Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/4] kvm: Add support for querying supported cpu features
  2009-05-08 21:09       ` [Qemu-devel] " Anthony Liguori
@ 2009-05-09  8:41         ` Avi Kivity
  -1 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-09  8:41 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Anthony Liguori, qemu-devel, kvm

Anthony Liguori wrote:
> Anthony Liguori wrote:
>>
>> kvm_check_extension doesn't exist in upstream QEMU.  It's a good idea 
>> though so I added it in a previous commit.  However, I changed the 
>> signature to it to take a KVMState * as the first argument (which is 
>> available in env->kvm_state).  I updated this patch to pass the extra 
>> 's' parameter.
>
> Ah, you had a patch, I just didn't notice in my queue.
>

Yeah, I should have made the dependency explicit.

> Still wanted to make the KVMState change though.
>

I think the KVM_REQUIRE_EXTENSION bit didn't like it.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Qemu-devel] Re: [PATCH 1/4] kvm: Add support for querying supported cpu features
@ 2009-05-09  8:41         ` Avi Kivity
  0 siblings, 0 replies; 18+ messages in thread
From: Avi Kivity @ 2009-05-09  8:41 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, kvm

Anthony Liguori wrote:
> Anthony Liguori wrote:
>>
>> kvm_check_extension doesn't exist in upstream QEMU.  It's a good idea 
>> though so I added it in a previous commit.  However, I changed the 
>> signature to it to take a KVMState * as the first argument (which is 
>> available in env->kvm_state).  I updated this patch to pass the extra 
>> 's' parameter.
>
> Ah, you had a patch, I just didn't notice in my queue.
>

Yeah, I should have made the dependency explicit.

> Still wanted to make the KVMState change though.
>

I think the KVM_REQUIRE_EXTENSION bit didn't like it.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 4/4] kvm: Trim cpu features not supported by kvm
  2009-05-03 14:04   ` [Qemu-devel] " Avi Kivity
@ 2009-05-12 11:52     ` Mark McLoughlin
  -1 siblings, 0 replies; 18+ messages in thread
From: Mark McLoughlin @ 2009-05-12 11:52 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Anthony Liguori, qemu-devel, kvm

On Sun, 2009-05-03 at 17:04 +0300, Avi Kivity wrote:
> Remove cpu features that are not supported by kvm from the cpuid features
> reported to the guest.
> 
> Signed-off-by: Avi Kivity <avi@redhat.com>
....
> @@ -1699,5 +1714,20 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
>  
>      qemu_init_vcpu(env);
>  
> +    if (kvm_enabled()) {
> +        kvm_trim_features(&env->cpuid_features,
> +                          kvm_arch_get_supported_cpuid(env, 1, R_EDX),
> +                          feature_name);

This isn't work in qemu.git because the features are only queried from
qemu_init_vcpu() (see kvm_arch_init_vcpu())

The obvious fix is to move qemu_init_vcpu() after the feature trimming,
but that requires us to split env->kvm_state initialization out of
kvm_init_vcpu()

Also, it works in qemu-kvm.git, but only because actually call
kvm_qemu_init_env() twice - once before feature trimming and once after.

Cheers,
Mark.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 4/4] kvm: Trim cpu features not supported by kvm
@ 2009-05-12 11:52     ` Mark McLoughlin
  0 siblings, 0 replies; 18+ messages in thread
From: Mark McLoughlin @ 2009-05-12 11:52 UTC (permalink / raw)
  To: Avi Kivity; +Cc: qemu-devel, kvm

On Sun, 2009-05-03 at 17:04 +0300, Avi Kivity wrote:
> Remove cpu features that are not supported by kvm from the cpuid features
> reported to the guest.
> 
> Signed-off-by: Avi Kivity <avi@redhat.com>
....
> @@ -1699,5 +1714,20 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
>  
>      qemu_init_vcpu(env);
>  
> +    if (kvm_enabled()) {
> +        kvm_trim_features(&env->cpuid_features,
> +                          kvm_arch_get_supported_cpuid(env, 1, R_EDX),
> +                          feature_name);

This isn't work in qemu.git because the features are only queried from
qemu_init_vcpu() (see kvm_arch_init_vcpu())

The obvious fix is to move qemu_init_vcpu() after the feature trimming,
but that requires us to split env->kvm_state initialization out of
kvm_init_vcpu()

Also, it works in qemu-kvm.git, but only because actually call
kvm_qemu_init_env() twice - once before feature trimming and once after.

Cheers,
Mark.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2009-05-12 11:52 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 1/4] kvm: Add support for querying supported cpu features Avi Kivity
2009-05-03 14:04   ` [Qemu-devel] " 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

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.