[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] kvm: Add helpers for checking and requiring kvm ext
From: |
Avi Kivity |
Subject: |
[Qemu-devel] [PATCH] kvm: Add helpers for checking and requiring kvm extensions |
Date: |
Sun, 3 May 2009 14:34:08 +0300 |
Instead of open-coding the check extension sequence, provide helpers
for checking whether an extension exists, and for aborting if an
extension is missing.
Signed-off-by: Avi Kivity <address@hidden>
---
kvm-all.c | 63 +++++++++++++++++++++++++++--------------------------
kvm.h | 6 +++++
target-i386/kvm.c | 8 +------
3 files changed, 39 insertions(+), 38 deletions(-)
diff --git a/kvm-all.c b/kvm-all.c
index 36659a9..1642a2a 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -64,6 +64,30 @@ struct KVMState
static KVMState *kvm_state;
+int kvm_check_extension(int extension)
+{
+ int ret;
+
+ ret = kvm_ioctl(kvm_state, KVM_CHECK_EXTENSION, extension);
+ if (ret < 0) {
+ fprintf(stderr, "KVM_CHECK_EXTENSION failed: %s\n", strerror(errno));
+ exit(1);
+ }
+ return ret;
+}
+
+int kvm_require_extension(int extension, const char *estr)
+{
+ int ret;
+
+ ret = kvm_check_extension(extension);
+ if (!ret) {
+ fprintf(stderr, "Required KVM extension %s not present\n", estr);
+ exit(1);
+ }
+ return ret;
+}
+
static KVMSlot *kvm_alloc_slot(KVMState *s)
{
int i;
@@ -331,6 +355,8 @@ int kvm_init(int smp_cpus)
s = qemu_mallocz(sizeof(KVMState));
+ kvm_state = s;
+
#ifdef KVM_CAP_SET_GUEST_DEBUG
TAILQ_INIT(&s->kvm_sw_breakpoints);
#endif
@@ -368,42 +394,22 @@ int kvm_init(int smp_cpus)
* just use a user allocated buffer so we can use regular pages
* unmodified. Make sure we have a sufficiently modern version of KVM.
*/
- ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_USER_MEMORY);
- if (ret <= 0) {
- if (ret == 0)
- ret = -EINVAL;
- fprintf(stderr, "kvm does not support KVM_CAP_USER_MEMORY\n");
- goto err;
- }
+ KVM_REQUIRE_EXTENSION(KVM_CAP_USER_MEMORY);
/* 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. */
- ret = kvm_ioctl(s, KVM_CHECK_EXTENSION,
- KVM_CAP_DESTROY_MEMORY_REGION_WORKS);
- if (ret <= 0) {
- if (ret == 0)
- ret = -EINVAL;
-
- fprintf(stderr,
- "KVM kernel module broken (DESTROY_MEMORY_REGION)\n"
- "Please upgrade to at least kvm-81.\n");
- goto err;
- }
+ KVM_REQUIRE_EXTENSION(KVM_CAP_DESTROY_MEMORY_REGION_WORKS);
s->coalesced_mmio = 0;
#ifdef KVM_CAP_COALESCED_MMIO
- ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_COALESCED_MMIO);
- if (ret > 0)
- s->coalesced_mmio = ret;
+ s->coalesced_mmio = kvm_check_extension(KVM_CAP_COALESCED_MMIO);
#endif
ret = kvm_arch_init(s, smp_cpus);
if (ret < 0)
goto err;
- kvm_state = s;
-
return 0;
err:
@@ -415,6 +421,8 @@ err:
}
qemu_free(s);
+ kvm_state = NULL;
+
return ret;
}
@@ -763,14 +771,7 @@ int kvm_vcpu_ioctl(CPUState *env, int type, ...)
int kvm_has_sync_mmu(void)
{
-#ifdef KVM_CAP_SYNC_MMU
- KVMState *s = kvm_state;
-
- if (kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_SYNC_MMU) > 0)
- return 1;
-#endif
-
- return 0;
+ return kvm_check_extension(KVM_CAP_SYNC_MMU);
}
void kvm_setup_guest_memory(void *start, size_t size)
diff --git a/kvm.h b/kvm.h
index 0ea2426..bd4e8d4 100644
--- a/kvm.h
+++ b/kvm.h
@@ -29,6 +29,12 @@ struct kvm_run;
/* external API */
+#define KVM_REQUIRE_EXTENSION(extension) \
+ kvm_require_extension(extension, #extension)
+
+int kvm_check_extension(int extension);
+int kvm_require_extension(int extension, const char *estr);
+
int kvm_init(int smp_cpus);
int kvm_init_vcpu(CPUState *env);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 2de8b81..b534b2d 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -154,19 +154,13 @@ static int kvm_has_msr_star(CPUState *env)
int kvm_arch_init(KVMState *s, int smp_cpus)
{
- int ret;
-
/* 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_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_SET_TSS_ADDR);
- if (ret <= 0) {
- fprintf(stderr, "kvm does not support KVM_CAP_SET_TSS_ADDR\n");
- return ret;
- }
+ KVM_REQUIRE_EXTENSION(KVM_CAP_SET_TSS_ADDR);
/* 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
--
1.6.1.1
- [Qemu-devel] [PATCH] kvm: Add helpers for checking and requiring kvm extensions,
Avi Kivity <=