All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marcelo Tosatti <mtosatti@redhat.com>
To: Anthony Liguori <aliguori@us.ibm.com>
Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org,
	Jan Kiszka <jan.kiszka@siemens.com>,
	Marcelo Tosatti <mtosatti@redhat.com>
Subject: [PATCH 26/31] kvm: Consolidate must-have capability checks
Date: Mon, 24 Jan 2011 07:02:35 -0200	[thread overview]
Message-ID: <94a8d39afd8ccfdbf578af04c3385fdb5f545af1.1295859760.git.mtosatti@redhat.com> (raw)
In-Reply-To: <cover.1295859760.git.mtosatti@redhat.com>

From: Jan Kiszka <jan.kiszka@siemens.com>

Instead of splattering the code with #ifdefs and runtime checks for
capabilities we cannot work without anyway, provide central test
infrastructure for verifying their availability both at build and
runtime.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
 configure          |   39 ++++++++++++++++++++----------
 kvm-all.c          |   67 +++++++++++++++++++++-------------------------------
 kvm.h              |   10 +++++++
 target-i386/kvm.c  |   39 ++++++------------------------
 target-ppc/kvm.c   |    4 +++
 target-s390x/kvm.c |    4 +++
 6 files changed, 79 insertions(+), 84 deletions(-)

diff --git a/configure b/configure
index 9a02d1f..4673bf0 100755
--- a/configure
+++ b/configure
@@ -1662,18 +1662,31 @@ if test "$kvm" != "no" ; then
 #if !defined(KVM_API_VERSION) || KVM_API_VERSION < 12 || KVM_API_VERSION > 12
 #error Invalid KVM version
 #endif
-#if !defined(KVM_CAP_USER_MEMORY)
-#error Missing KVM capability KVM_CAP_USER_MEMORY
-#endif
-#if !defined(KVM_CAP_SET_TSS_ADDR)
-#error Missing KVM capability KVM_CAP_SET_TSS_ADDR
-#endif
-#if !defined(KVM_CAP_DESTROY_MEMORY_REGION_WORKS)
-#error Missing KVM capability KVM_CAP_DESTROY_MEMORY_REGION_WORKS
-#endif
-#if !defined(KVM_CAP_USER_NMI)
-#error Missing KVM capability KVM_CAP_USER_NMI
+EOF
+    must_have_caps="KVM_CAP_USER_MEMORY \
+                    KVM_CAP_DESTROY_MEMORY_REGION_WORKS \
+                    KVM_CAP_COALESCED_MMIO \
+                    KVM_CAP_SYNC_MMU \
+                   "
+    if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) ; then
+      must_have_caps="$caps \
+                      KVM_CAP_SET_TSS_ADDR \
+                      KVM_CAP_EXT_CPUID \
+                      KVM_CAP_CLOCKSOURCE \
+                      KVM_CAP_NOP_IO_DELAY \
+                      KVM_CAP_PV_MMU \
+                      KVM_CAP_MP_STATE \
+                      KVM_CAP_USER_NMI \
+                     "
+    fi
+    for c in $must_have_caps ; do
+      cat >> $TMPC <<EOF
+#if !defined($c)
+#error Missing KVM capability $c
 #endif
+EOF
+    done
+    cat >> $TMPC <<EOF
 int main(void) { return 0; }
 EOF
   if test "$kerneldir" != "" ; then
@@ -1708,8 +1721,8 @@ EOF
 	| awk -F "error: " '{if (NR>1) printf(", "); printf("%s",$2);}'`
         if test "$kvmerr" != "" ; then
           echo -e "${kvmerr}\n\
-      NOTE: To enable KVM support, update your kernel to 2.6.29+ or install \
-  recent kvm-kmod from http://sourceforge.net/projects/kvm."
+NOTE: To enable KVM support, update your kernel to 2.6.29+ or install \
+recent kvm-kmod from http://sourceforge.net/projects/kvm."
         fi
       fi
       feature_not_found "kvm"
diff --git a/kvm-all.c b/kvm-all.c
index 8053f92..3a1f63b 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -63,9 +63,7 @@ struct KVMState
     int fd;
     int vmfd;
     int coalesced_mmio;
-#ifdef KVM_CAP_COALESCED_MMIO
     struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
-#endif
     int broken_set_mem_region;
     int migration_log;
     int vcpu_events;
@@ -82,6 +80,12 @@ struct KVMState
 
 static KVMState *kvm_state;
 
+static const KVMCapabilityInfo kvm_required_capabilites[] = {
+    KVM_CAP_INFO(USER_MEMORY),
+    KVM_CAP_INFO(DESTROY_MEMORY_REGION_WORKS),
+    KVM_CAP_LAST_INFO
+};
+
 static KVMSlot *kvm_alloc_slot(KVMState *s)
 {
     int i;
@@ -227,12 +231,10 @@ int kvm_init_vcpu(CPUState *env)
         goto err;
     }
 
-#ifdef KVM_CAP_COALESCED_MMIO
     if (s->coalesced_mmio && !s->coalesced_mmio_ring) {
         s->coalesced_mmio_ring =
             (void *)env->kvm_run + s->coalesced_mmio * PAGE_SIZE;
     }
-#endif
 
     ret = kvm_arch_init_vcpu(env);
     if (ret == 0) {
@@ -401,7 +403,6 @@ static int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
 int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
 {
     int ret = -ENOSYS;
-#ifdef KVM_CAP_COALESCED_MMIO
     KVMState *s = kvm_state;
 
     if (s->coalesced_mmio) {
@@ -412,7 +413,6 @@ int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
 
         ret = kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone);
     }
-#endif
 
     return ret;
 }
@@ -420,7 +420,6 @@ int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
 int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
 {
     int ret = -ENOSYS;
-#ifdef KVM_CAP_COALESCED_MMIO
     KVMState *s = kvm_state;
 
     if (s->coalesced_mmio) {
@@ -431,7 +430,6 @@ int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
 
         ret = kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone);
     }
-#endif
 
     return ret;
 }
@@ -481,6 +479,18 @@ static int kvm_check_many_ioeventfds(void)
 #endif
 }
 
+static const KVMCapabilityInfo *
+kvm_check_extension_list(KVMState *s, const KVMCapabilityInfo *list)
+{
+    while (list->name) {
+        if (!kvm_check_extension(s, list->value)) {
+            return list;
+        }
+        list++;
+    }
+    return NULL;
+}
+
 static void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size,
                              ram_addr_t phys_offset)
 {
@@ -642,6 +652,7 @@ int kvm_init(void)
         "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
         "(see http://sourceforge.net/projects/kvm).\n";
     KVMState *s;
+    const KVMCapabilityInfo *missing_cap;
     int ret;
     int i;
 
@@ -685,35 +696,19 @@ int kvm_init(void)
         goto err;
     }
 
-    /* initially, KVM allocated its own memory and we had to jump through
-     * hooks to make phys_ram_base point to this.  Modern versions of KVM
-     * just use a user allocated buffer so we can use regular pages
-     * unmodified.  Make sure we have a sufficiently modern version of KVM.
-     */
-    if (!kvm_check_extension(s, KVM_CAP_USER_MEMORY)) {
-        ret = -EINVAL;
-        fprintf(stderr, "kvm does not support KVM_CAP_USER_MEMORY\n%s",
-                upgrade_note);
-        goto err;
+    missing_cap = kvm_check_extension_list(s, kvm_required_capabilites);
+    if (!missing_cap) {
+        missing_cap =
+            kvm_check_extension_list(s, kvm_arch_required_capabilities);
     }
-
-    /* There was a nasty bug in < kvm-80 that prevents memory slots from being
-     * destroyed properly.  Since we rely on this capability, refuse to work
-     * with any kernel without this capability. */
-    if (!kvm_check_extension(s, KVM_CAP_DESTROY_MEMORY_REGION_WORKS)) {
+    if (missing_cap) {
         ret = -EINVAL;
-
-        fprintf(stderr,
-                "KVM kernel module broken (DESTROY_MEMORY_REGION).\n%s",
-                upgrade_note);
+        fprintf(stderr, "kvm does not support %s\n%s",
+                missing_cap->name, upgrade_note);
         goto err;
     }
 
-    s->coalesced_mmio = 0;
-#ifdef KVM_CAP_COALESCED_MMIO
     s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
-    s->coalesced_mmio_ring = NULL;
-#endif
 
     s->broken_set_mem_region = 1;
 #ifdef KVM_CAP_JOIN_MEMORY_REGIONS_WORKS
@@ -845,7 +840,6 @@ static int kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
 
 void kvm_flush_coalesced_mmio_buffer(void)
 {
-#ifdef KVM_CAP_COALESCED_MMIO
     KVMState *s = kvm_state;
     if (s->coalesced_mmio_ring) {
         struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring;
@@ -859,7 +853,6 @@ void kvm_flush_coalesced_mmio_buffer(void)
             ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX;
         }
     }
-#endif
 }
 
 static void do_kvm_cpu_synchronize_state(void *_env)
@@ -1059,13 +1052,7 @@ int kvm_vcpu_ioctl(CPUState *env, int type, ...)
 
 int kvm_has_sync_mmu(void)
 {
-#ifdef KVM_CAP_SYNC_MMU
-    KVMState *s = kvm_state;
-
-    return kvm_check_extension(s, KVM_CAP_SYNC_MMU);
-#else
-    return 0;
-#endif
+    return kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU);
 }
 
 int kvm_has_vcpu_events(void)
diff --git a/kvm.h b/kvm.h
index a971752..ca57517 100644
--- a/kvm.h
+++ b/kvm.h
@@ -32,6 +32,14 @@ extern int kvm_allowed;
 
 struct kvm_run;
 
+typedef struct KVMCapabilityInfo {
+    const char *name;
+    int value;
+} KVMCapabilityInfo;
+
+#define KVM_CAP_INFO(CAP) { "KVM_CAP_" stringify(CAP), KVM_CAP_##CAP }
+#define KVM_CAP_LAST_INFO { NULL, 0 }
+
 /* external API */
 
 int kvm_init(void);
@@ -86,6 +94,8 @@ int kvm_vcpu_ioctl(CPUState *env, int type, ...);
 
 /* Arch specific hooks */
 
+extern const KVMCapabilityInfo kvm_arch_required_capabilities[];
+
 int kvm_arch_post_run(CPUState *env, struct kvm_run *run);
 
 int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 016b67d..1db8227 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -54,12 +54,17 @@
 #define BUS_MCEERR_AO 5
 #endif
 
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+    KVM_CAP_INFO(SET_TSS_ADDR),
+    KVM_CAP_INFO(EXT_CPUID),
+    KVM_CAP_INFO(MP_STATE),
+    KVM_CAP_LAST_INFO
+};
+
 static bool has_msr_star;
 static bool has_msr_hsave_pa;
 static int lm_capable_kernel;
 
-#ifdef KVM_CAP_EXT_CPUID
-
 static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
 {
     struct kvm_cpuid2 *cpuid;
@@ -93,10 +98,6 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
     uint32_t ret = 0;
     uint32_t cpuid_1_edx;
 
-    if (!kvm_check_extension(env->kvm_state, KVM_CAP_EXT_CPUID)) {
-        return -1U;
-    }
-
     max = 1;
     while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) {
         max *= 2;
@@ -140,30 +141,14 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
     return ret;
 }
 
-#else
-
-uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
-                                      uint32_t index, int reg)
-{
-    return -1U;
-}
-
-#endif
-
 #ifdef CONFIG_KVM_PARA
 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_ASYNC_PF
     { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
 #endif
@@ -542,15 +527,7 @@ int kvm_arch_init(KVMState *s)
 
     /* create vm86 tss.  KVM uses vm86 mode to emulate 16-bit code
      * directly.  In order to use vm86 mode, a TSS is needed.  Since this
-     * must be part of guest physical memory, we need to allocate it.  Older
-     * versions of KVM just assumed that it would be at the end of physical
-     * memory but that doesn't work with more than 4GB of memory.  We simply
-     * refuse to work with those older versions of KVM. */
-    ret = kvm_check_extension(s, KVM_CAP_SET_TSS_ADDR);
-    if (ret <= 0) {
-        fprintf(stderr, "kvm does not support KVM_CAP_SET_TSS_ADDR\n");
-        return ret;
-    }
+     * must be part of guest physical memory, we need to allocate it. */
 
     /* this address is 3 pages before the bios, and the bios should present
      * as unavaible memory.  FIXME, need to ensure the e820 map deals with
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 3c05630..710eca1 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -37,6 +37,10 @@
     do { } while (0)
 #endif
 
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+    KVM_CAP_LAST_INFO
+};
+
 static int cap_interrupt_unset = false;
 static int cap_interrupt_level = false;
 
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index b177e10..38823f5 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -70,6 +70,10 @@
 #define SCLP_CMDW_READ_SCP_INFO         0x00020001
 #define SCLP_CMDW_READ_SCP_INFO_FORCED  0x00120001
 
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+    KVM_CAP_LAST_INFO
+};
+
 int kvm_arch_init(KVMState *s)
 {
     return 0;
-- 
1.7.2.3


WARNING: multiple messages have this Message-ID (diff)
From: Marcelo Tosatti <mtosatti@redhat.com>
To: Anthony Liguori <aliguori@us.ibm.com>
Cc: Jan Kiszka <jan.kiszka@siemens.com>,
	Marcelo Tosatti <mtosatti@redhat.com>,
	qemu-devel@nongnu.org, kvm@vger.kernel.org
Subject: [Qemu-devel] [PATCH 26/31] kvm: Consolidate must-have capability checks
Date: Mon, 24 Jan 2011 07:02:35 -0200	[thread overview]
Message-ID: <94a8d39afd8ccfdbf578af04c3385fdb5f545af1.1295859760.git.mtosatti@redhat.com> (raw)
In-Reply-To: <cover.1295859760.git.mtosatti@redhat.com>

From: Jan Kiszka <jan.kiszka@siemens.com>

Instead of splattering the code with #ifdefs and runtime checks for
capabilities we cannot work without anyway, provide central test
infrastructure for verifying their availability both at build and
runtime.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
---
 configure          |   39 ++++++++++++++++++++----------
 kvm-all.c          |   67 +++++++++++++++++++++-------------------------------
 kvm.h              |   10 +++++++
 target-i386/kvm.c  |   39 ++++++------------------------
 target-ppc/kvm.c   |    4 +++
 target-s390x/kvm.c |    4 +++
 6 files changed, 79 insertions(+), 84 deletions(-)

diff --git a/configure b/configure
index 9a02d1f..4673bf0 100755
--- a/configure
+++ b/configure
@@ -1662,18 +1662,31 @@ if test "$kvm" != "no" ; then
 #if !defined(KVM_API_VERSION) || KVM_API_VERSION < 12 || KVM_API_VERSION > 12
 #error Invalid KVM version
 #endif
-#if !defined(KVM_CAP_USER_MEMORY)
-#error Missing KVM capability KVM_CAP_USER_MEMORY
-#endif
-#if !defined(KVM_CAP_SET_TSS_ADDR)
-#error Missing KVM capability KVM_CAP_SET_TSS_ADDR
-#endif
-#if !defined(KVM_CAP_DESTROY_MEMORY_REGION_WORKS)
-#error Missing KVM capability KVM_CAP_DESTROY_MEMORY_REGION_WORKS
-#endif
-#if !defined(KVM_CAP_USER_NMI)
-#error Missing KVM capability KVM_CAP_USER_NMI
+EOF
+    must_have_caps="KVM_CAP_USER_MEMORY \
+                    KVM_CAP_DESTROY_MEMORY_REGION_WORKS \
+                    KVM_CAP_COALESCED_MMIO \
+                    KVM_CAP_SYNC_MMU \
+                   "
+    if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) ; then
+      must_have_caps="$caps \
+                      KVM_CAP_SET_TSS_ADDR \
+                      KVM_CAP_EXT_CPUID \
+                      KVM_CAP_CLOCKSOURCE \
+                      KVM_CAP_NOP_IO_DELAY \
+                      KVM_CAP_PV_MMU \
+                      KVM_CAP_MP_STATE \
+                      KVM_CAP_USER_NMI \
+                     "
+    fi
+    for c in $must_have_caps ; do
+      cat >> $TMPC <<EOF
+#if !defined($c)
+#error Missing KVM capability $c
 #endif
+EOF
+    done
+    cat >> $TMPC <<EOF
 int main(void) { return 0; }
 EOF
   if test "$kerneldir" != "" ; then
@@ -1708,8 +1721,8 @@ EOF
 	| awk -F "error: " '{if (NR>1) printf(", "); printf("%s",$2);}'`
         if test "$kvmerr" != "" ; then
           echo -e "${kvmerr}\n\
-      NOTE: To enable KVM support, update your kernel to 2.6.29+ or install \
-  recent kvm-kmod from http://sourceforge.net/projects/kvm."
+NOTE: To enable KVM support, update your kernel to 2.6.29+ or install \
+recent kvm-kmod from http://sourceforge.net/projects/kvm."
         fi
       fi
       feature_not_found "kvm"
diff --git a/kvm-all.c b/kvm-all.c
index 8053f92..3a1f63b 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -63,9 +63,7 @@ struct KVMState
     int fd;
     int vmfd;
     int coalesced_mmio;
-#ifdef KVM_CAP_COALESCED_MMIO
     struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
-#endif
     int broken_set_mem_region;
     int migration_log;
     int vcpu_events;
@@ -82,6 +80,12 @@ struct KVMState
 
 static KVMState *kvm_state;
 
+static const KVMCapabilityInfo kvm_required_capabilites[] = {
+    KVM_CAP_INFO(USER_MEMORY),
+    KVM_CAP_INFO(DESTROY_MEMORY_REGION_WORKS),
+    KVM_CAP_LAST_INFO
+};
+
 static KVMSlot *kvm_alloc_slot(KVMState *s)
 {
     int i;
@@ -227,12 +231,10 @@ int kvm_init_vcpu(CPUState *env)
         goto err;
     }
 
-#ifdef KVM_CAP_COALESCED_MMIO
     if (s->coalesced_mmio && !s->coalesced_mmio_ring) {
         s->coalesced_mmio_ring =
             (void *)env->kvm_run + s->coalesced_mmio * PAGE_SIZE;
     }
-#endif
 
     ret = kvm_arch_init_vcpu(env);
     if (ret == 0) {
@@ -401,7 +403,6 @@ static int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
 int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
 {
     int ret = -ENOSYS;
-#ifdef KVM_CAP_COALESCED_MMIO
     KVMState *s = kvm_state;
 
     if (s->coalesced_mmio) {
@@ -412,7 +413,6 @@ int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
 
         ret = kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone);
     }
-#endif
 
     return ret;
 }
@@ -420,7 +420,6 @@ int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
 int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
 {
     int ret = -ENOSYS;
-#ifdef KVM_CAP_COALESCED_MMIO
     KVMState *s = kvm_state;
 
     if (s->coalesced_mmio) {
@@ -431,7 +430,6 @@ int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
 
         ret = kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone);
     }
-#endif
 
     return ret;
 }
@@ -481,6 +479,18 @@ static int kvm_check_many_ioeventfds(void)
 #endif
 }
 
+static const KVMCapabilityInfo *
+kvm_check_extension_list(KVMState *s, const KVMCapabilityInfo *list)
+{
+    while (list->name) {
+        if (!kvm_check_extension(s, list->value)) {
+            return list;
+        }
+        list++;
+    }
+    return NULL;
+}
+
 static void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size,
                              ram_addr_t phys_offset)
 {
@@ -642,6 +652,7 @@ int kvm_init(void)
         "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
         "(see http://sourceforge.net/projects/kvm).\n";
     KVMState *s;
+    const KVMCapabilityInfo *missing_cap;
     int ret;
     int i;
 
@@ -685,35 +696,19 @@ int kvm_init(void)
         goto err;
     }
 
-    /* initially, KVM allocated its own memory and we had to jump through
-     * hooks to make phys_ram_base point to this.  Modern versions of KVM
-     * just use a user allocated buffer so we can use regular pages
-     * unmodified.  Make sure we have a sufficiently modern version of KVM.
-     */
-    if (!kvm_check_extension(s, KVM_CAP_USER_MEMORY)) {
-        ret = -EINVAL;
-        fprintf(stderr, "kvm does not support KVM_CAP_USER_MEMORY\n%s",
-                upgrade_note);
-        goto err;
+    missing_cap = kvm_check_extension_list(s, kvm_required_capabilites);
+    if (!missing_cap) {
+        missing_cap =
+            kvm_check_extension_list(s, kvm_arch_required_capabilities);
     }
-
-    /* There was a nasty bug in < kvm-80 that prevents memory slots from being
-     * destroyed properly.  Since we rely on this capability, refuse to work
-     * with any kernel without this capability. */
-    if (!kvm_check_extension(s, KVM_CAP_DESTROY_MEMORY_REGION_WORKS)) {
+    if (missing_cap) {
         ret = -EINVAL;
-
-        fprintf(stderr,
-                "KVM kernel module broken (DESTROY_MEMORY_REGION).\n%s",
-                upgrade_note);
+        fprintf(stderr, "kvm does not support %s\n%s",
+                missing_cap->name, upgrade_note);
         goto err;
     }
 
-    s->coalesced_mmio = 0;
-#ifdef KVM_CAP_COALESCED_MMIO
     s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
-    s->coalesced_mmio_ring = NULL;
-#endif
 
     s->broken_set_mem_region = 1;
 #ifdef KVM_CAP_JOIN_MEMORY_REGIONS_WORKS
@@ -845,7 +840,6 @@ static int kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
 
 void kvm_flush_coalesced_mmio_buffer(void)
 {
-#ifdef KVM_CAP_COALESCED_MMIO
     KVMState *s = kvm_state;
     if (s->coalesced_mmio_ring) {
         struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring;
@@ -859,7 +853,6 @@ void kvm_flush_coalesced_mmio_buffer(void)
             ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX;
         }
     }
-#endif
 }
 
 static void do_kvm_cpu_synchronize_state(void *_env)
@@ -1059,13 +1052,7 @@ int kvm_vcpu_ioctl(CPUState *env, int type, ...)
 
 int kvm_has_sync_mmu(void)
 {
-#ifdef KVM_CAP_SYNC_MMU
-    KVMState *s = kvm_state;
-
-    return kvm_check_extension(s, KVM_CAP_SYNC_MMU);
-#else
-    return 0;
-#endif
+    return kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU);
 }
 
 int kvm_has_vcpu_events(void)
diff --git a/kvm.h b/kvm.h
index a971752..ca57517 100644
--- a/kvm.h
+++ b/kvm.h
@@ -32,6 +32,14 @@ extern int kvm_allowed;
 
 struct kvm_run;
 
+typedef struct KVMCapabilityInfo {
+    const char *name;
+    int value;
+} KVMCapabilityInfo;
+
+#define KVM_CAP_INFO(CAP) { "KVM_CAP_" stringify(CAP), KVM_CAP_##CAP }
+#define KVM_CAP_LAST_INFO { NULL, 0 }
+
 /* external API */
 
 int kvm_init(void);
@@ -86,6 +94,8 @@ int kvm_vcpu_ioctl(CPUState *env, int type, ...);
 
 /* Arch specific hooks */
 
+extern const KVMCapabilityInfo kvm_arch_required_capabilities[];
+
 int kvm_arch_post_run(CPUState *env, struct kvm_run *run);
 
 int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 016b67d..1db8227 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -54,12 +54,17 @@
 #define BUS_MCEERR_AO 5
 #endif
 
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+    KVM_CAP_INFO(SET_TSS_ADDR),
+    KVM_CAP_INFO(EXT_CPUID),
+    KVM_CAP_INFO(MP_STATE),
+    KVM_CAP_LAST_INFO
+};
+
 static bool has_msr_star;
 static bool has_msr_hsave_pa;
 static int lm_capable_kernel;
 
-#ifdef KVM_CAP_EXT_CPUID
-
 static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
 {
     struct kvm_cpuid2 *cpuid;
@@ -93,10 +98,6 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
     uint32_t ret = 0;
     uint32_t cpuid_1_edx;
 
-    if (!kvm_check_extension(env->kvm_state, KVM_CAP_EXT_CPUID)) {
-        return -1U;
-    }
-
     max = 1;
     while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) {
         max *= 2;
@@ -140,30 +141,14 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
     return ret;
 }
 
-#else
-
-uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
-                                      uint32_t index, int reg)
-{
-    return -1U;
-}
-
-#endif
-
 #ifdef CONFIG_KVM_PARA
 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_ASYNC_PF
     { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
 #endif
@@ -542,15 +527,7 @@ int kvm_arch_init(KVMState *s)
 
     /* create vm86 tss.  KVM uses vm86 mode to emulate 16-bit code
      * directly.  In order to use vm86 mode, a TSS is needed.  Since this
-     * must be part of guest physical memory, we need to allocate it.  Older
-     * versions of KVM just assumed that it would be at the end of physical
-     * memory but that doesn't work with more than 4GB of memory.  We simply
-     * refuse to work with those older versions of KVM. */
-    ret = kvm_check_extension(s, KVM_CAP_SET_TSS_ADDR);
-    if (ret <= 0) {
-        fprintf(stderr, "kvm does not support KVM_CAP_SET_TSS_ADDR\n");
-        return ret;
-    }
+     * must be part of guest physical memory, we need to allocate it. */
 
     /* this address is 3 pages before the bios, and the bios should present
      * as unavaible memory.  FIXME, need to ensure the e820 map deals with
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 3c05630..710eca1 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -37,6 +37,10 @@
     do { } while (0)
 #endif
 
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+    KVM_CAP_LAST_INFO
+};
+
 static int cap_interrupt_unset = false;
 static int cap_interrupt_level = false;
 
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index b177e10..38823f5 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -70,6 +70,10 @@
 #define SCLP_CMDW_READ_SCP_INFO         0x00020001
 #define SCLP_CMDW_READ_SCP_INFO_FORCED  0x00120001
 
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+    KVM_CAP_LAST_INFO
+};
+
 int kvm_arch_init(KVMState *s)
 {
     return 0;
-- 
1.7.2.3

  parent reply	other threads:[~2011-01-24  9:05 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-24  9:02 [PATCH 00/31] [PULL] qemu-kvm.git uq/master queue Marcelo Tosatti
2011-01-24  9:02 ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 01/31] kvm: Enable user space NMI injection for kvm guest Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 02/31] kvm: convert kvm_ioctl(KVM_CHECK_EXTENSION) to kvm_check_extension() Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 03/31] Clean up cpu_inject_x86_mce() Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 04/31] Add "broadcast" option for mce command Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 05/31] Add function for checking mca broadcast of CPU Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 06/31] kvm: introduce kvm_mce_in_progress Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 07/31] kvm: kvm_mce_inj_* subroutines for templated error injections Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 08/31] kvm: introduce kvm_inject_x86_mce_on Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 09/31] kvm: x86: Fix DPL write back of segment registers Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 10/31] kvm: x86: Remove obsolete SS.RPL/DPL aligment Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 11/31] kvm: x86: Prevent sign extension of DR7 in guest debugging mode Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 12/31] kvm: x86: Fix a few coding style violations Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 13/31] kvm: Fix " Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 14/31] kvm: x86: Swallow KVM_EXIT_SET_TPR Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 15/31] kvm: Stop on all fatal exit reasons Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 16/31] kvm: Improve reporting of fatal errors Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 17/31] x86: Optionally dump code bytes on cpu_dump_state Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 18/31] kvm: x86: Align kvm_arch_put_registers code with comment Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 19/31] kvm: x86: Prepare kvm_get_mp_state for in-kernel irqchip Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 20/31] kvm: x86: Remove redundant mp_state initialization Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 21/31] kvm: x86: Fix xcr0 reset mismerge Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 22/31] kvm: x86: Refactor msr_star/hsave_pa setup and checks Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 23/31] kvm: x86: Reset paravirtual MSRs Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 24/31] kvm: x86: Fix !CONFIG_KVM_PARA build Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 25/31] kvm: Drop smp_cpus argument from init functions Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` Marcelo Tosatti [this message]
2011-01-24  9:02   ` [Qemu-devel] [PATCH 26/31] kvm: Consolidate must-have capability checks Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 27/31] kvm: x86: Rework identity map and TSS setup for larger BIOS sizes Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 28/31] kvm: Flush coalesced mmio buffer on IO window exits Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 29/31] kvm: Do not use qemu_fair_mutex Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 30/31] kvm: x86: Implicitly clear nmi_injected/pending on reset Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-01-24  9:02 ` [PATCH 31/31] kvm: x86: Only read/write MSR_KVM_ASYNC_PF_EN if supported Marcelo Tosatti
2011-01-24  9:02   ` [Qemu-devel] " Marcelo Tosatti
2011-02-01 21:32 ` [Qemu-devel] [PATCH 00/31] [PULL] qemu-kvm.git uq/master queue Anthony Liguori
2011-02-17 20:00   ` Anthony Liguori

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=94a8d39afd8ccfdbf578af04c3385fdb5f545af1.1295859760.git.mtosatti@redhat.com \
    --to=mtosatti@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=jan.kiszka@siemens.com \
    --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: link
Be 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.