All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/9] Move closer to upstream
@ 2009-07-10 20:17 Glauber Costa
  2009-07-10 20:17 ` [PATCH v2 1/9] replace USE_KVM with CONFIG_KVM Glauber Costa
  2009-07-12  9:01 ` [PATCH v2 0/9] Move closer to upstream Avi Kivity
  0 siblings, 2 replies; 12+ messages in thread
From: Glauber Costa @ 2009-07-10 20:17 UTC (permalink / raw)
  To: kvm; +Cc: avi

Hi,

This is another step at getting us closer to qemu upstream. I'm getting rid
of USE_KVM, replacing it with the combination of KVM_UPSTREAM and CONFIG_KVM

The goal is to slowly reduce that isolation. To demonstrate what I aim
for, the last patches of the series shares code for breakpoint handling.
next in my radar are ioctl functions and cpuid trimming.

Have fun

Changes from v1:
* Include qemu-kvm.c and qemu-kvm-x86.c instead of folding it, as by gleb
  suggestion.
* duplicate structures that we need, to avoid messing with upstream, per
  avi suggestion
* drop KVM_UPSTREAM instead of moving code, per Jan suggestion
* kvm_qemu_init() -> kvm_init(smp_cpus), to get closer to upstream, per
  glommer evil twin suggestion


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

* [PATCH v2 1/9] replace USE_KVM with CONFIG_KVM
  2009-07-10 20:17 [PATCH v2 0/9] Move closer to upstream Glauber Costa
@ 2009-07-10 20:17 ` Glauber Costa
  2009-07-10 20:17   ` [PATCH v2 2/9] Do not compile qemu-kvm.c and qemu-kvm-x86.c Glauber Costa
  2009-07-12  9:01 ` [PATCH v2 0/9] Move closer to upstream Avi Kivity
  1 sibling, 1 reply; 12+ messages in thread
From: Glauber Costa @ 2009-07-10 20:17 UTC (permalink / raw)
  To: kvm; +Cc: avi

Make things less confuse, and we have KVM_UPSTREAM to differentiate
between the two versions anyway. kvm-all.c and kvm.c gets compiled now,
but protected with KVM_UPSTREAM too, so no function in there gets visible
in the final binary

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 Makefile.target   |   20 ++++++--------------
 configure         |   14 +++++++-------
 kvm-all.c         |    2 ++
 libkvm-all.h      |    6 +++---
 qemu-kvm.h        |    2 +-
 target-i386/kvm.c |    2 ++
 vl.c              |    6 +++---
 7 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 660a855..11a6da8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -160,9 +160,7 @@ ifeq ($(ARCH),sparc64)
 CPPFLAGS+=-I$(SRC_PATH)/tcg/sparc
 endif
 
-ifeq ($(USE_KVM), 1)
-libobj-y += qemu-kvm.o
-endif
+libobj-$(CONFIG_KVM) += qemu-kvm.o
 ifdef CONFIG_SOFTFLOAT
 libobj-y += fpu/softfloat.o
 else
@@ -173,18 +171,14 @@ libobj-y += op_helper.o helper.o
 
 ifeq ($(TARGET_ARCH), i386)
 libobj-y += helper.o
-ifeq ($(USE_KVM), 1)
-libobj-y += qemu-kvm-x86.o kvm-tpr-opt.o
-libobj-y += qemu-kvm-helper.o
-endif
+libobj-$(CONFIG_KVM) += qemu-kvm-x86.o kvm-tpr-opt.o
+libobj-$(CONFIG_KVM) += qemu-kvm-helper.o
 endif
 
 ifeq ($(TARGET_ARCH), x86_64)
 libobj-y += helper.o
-ifeq ($(USE_KVM), 1)
-libobj-y += qemu-kvm-x86.o kvm-tpr-opt.o
-libobj-y += qemu-kvm-helper.o
-endif
+libobj-$(CONFIG_KVM) += qemu-kvm-x86.o kvm-tpr-opt.o
+libobj-$(CONFIG_KVM) += qemu-kvm-helper.o
 endif
 
 libobj-y += op_helper.o
@@ -203,9 +197,7 @@ endif
 
 ifeq ($(TARGET_BASE_ARCH), ia64)
 libobj-y += op_helper.o firmware.o
-ifeq ($(USE_KVM), 1)
-libobj-y += qemu-kvm-ia64.o
-endif
+libobj-$(CONFIG_KVM) += qemu-kvm-ia64.o
 endif
 
 ifeq ($(TARGET_BASE_ARCH), cris)
diff --git a/configure b/configure
index 3a224d1..fd76259 100755
--- a/configure
+++ b/configure
@@ -2125,8 +2125,8 @@ disable_cpu_emulation() {
 configure_kvm() {
   if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
           \( "$cpu" = "i386" -o "$cpu" = "x86_64" -o "$cpu" = "ia64" -o "$cpu" = "powerpc" \); then
-    echo "#define USE_KVM 1" >> $config_h
-    echo "USE_KVM=1" >> $config_mak
+    echo "#define CONFIG_KVM 1" >> $config_h
+    echo "CONFIG_KVM=y" >> $config_mak
     echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
     if test $kvm_cap_pit = "yes" ; then
 	echo "USE_KVM_PIT=1" >> $config_mak
@@ -2163,9 +2163,9 @@ case "$target_arch2" in
       echo "#define CONFIG_KQEMU 1" >> $config_h
     fi
     if test "$target_kvm" = "yes" ; then
-      echo "USE_KVM=yes" >> $config_mak
+      echo "CONFIG_KVM=y" >> $config_mak
       echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
-      echo "#define USE_KVM 1" >> $config_h
+      echo "#define CONFIG_KVM 1" >> $config_h
     fi
     if test "$xen" = "yes" -a "$target_softmmu" = "yes";
     then
@@ -2187,9 +2187,9 @@ case "$target_arch2" in
     fi
     if [ use_upstream_kvm = yes ]; then
     if test "$target_kvm" = "yes" ; then
-      echo "USE_KVM=yes" >> $config_mak
+      echo "CONFIG_KVM=y" >> $config_mak
       echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
-      echo "#define USE_KVM 1" >> $config_h
+      echo "#define CONFIG_KVM 1" >> $config_h
     fi
     fi
     if test "$xen" = "yes" -a "$target_softmmu" = "yes"
@@ -2284,7 +2284,7 @@ case "$target_arch2" in
     if test "$target_kvm" = "yes" ; then
       echo "CONFIG_KVM=y" >> $config_mak
       echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
-      echo "#define USE_KVM 1" >> $config_h
+      echo "#define CONFIG_KVM 1" >> $config_h
     fi
     fi
     gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
diff --git a/kvm-all.c b/kvm-all.c
index 8567ac9..4c2fdf5 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -26,6 +26,7 @@
 #include "gdbstub.h"
 #include "kvm.h"
 
+#ifdef KVM_UPSTREAM
 /* KVM uses PAGE_SIZE in it's definition of COALESCED_MMIO_MAX */
 #define PAGE_SIZE TARGET_PAGE_SIZE
 
@@ -1027,3 +1028,4 @@ void kvm_remove_all_breakpoints(CPUState *current_env)
 {
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
+#endif
diff --git a/libkvm-all.h b/libkvm-all.h
index e16646c..3e3e1b4 100644
--- a/libkvm-all.h
+++ b/libkvm-all.h
@@ -5,7 +5,7 @@
 #ifndef LIBKVM_H
 #define LIBKVM_H
 
-#ifdef USE_KVM
+#ifdef CONFIG_KVM
 
 #if defined(__s390__)
 #include <asm/ptrace.h>
@@ -952,10 +952,10 @@ int kvm_assign_set_msix_entry(kvm_context_t kvm,
 
 uint32_t kvm_get_supported_cpuid(kvm_context_t kvm, uint32_t function, int reg);
 
-#else /* !USE_KVM */
+#else /* !CONFIG_KVM */
 
 struct kvm_pit_state { };
 
-#endif /* !USE_KVM */
+#endif /* !CONFIG_KVM */
 
 #endif
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 4c185fd..96dc85f 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -136,7 +136,7 @@ void kvm_arch_do_ioperm(void *_data);
 #define ALIGN(x, y)  (((x)+(y)-1) & ~((y)-1))
 #define BITMAP_SIZE(m) (ALIGN(((m)>>TARGET_PAGE_BITS), HOST_LONG_BITS) / 8)
 
-#ifdef USE_KVM
+#ifdef CONFIG_KVM
 #include "sys-queue.h"
 
 extern int kvm_allowed;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 0af2f55..d26161a 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -24,6 +24,7 @@
 #include "cpu.h"
 #include "gdbstub.h"
 
+#ifdef KVM_UPSTREAM
 //#define DEBUG_KVM
 
 #ifdef DEBUG_KVM
@@ -959,3 +960,4 @@ void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
     }
 }
 #endif /* KVM_CAP_SET_GUEST_DEBUG */
+#endif
diff --git a/vl.c b/vl.c
index 5d86e69..ae02ef7 100644
--- a/vl.c
+++ b/vl.c
@@ -5644,14 +5644,14 @@ int main(int argc, char **argv, char **envp)
                 break;
 #endif
 #ifdef CONFIG_KVM
+#ifdef KVM_UPSTREAM
             case QEMU_OPTION_enable_kvm:
                 kvm_allowed = 1;
 #ifdef CONFIG_KQEMU
                 kqemu_allowed = 0;
 #endif
-                break;
 #endif
-#ifdef USE_KVM
+                break;
 	    case QEMU_OPTION_no_kvm:
 		kvm_allowed = 0;
 		break;
@@ -5948,7 +5948,7 @@ int main(int argc, char **argv, char **envp)
         signal(SIGTTIN, SIG_IGN);
     }
 
-#ifdef USE_KVM
+#ifdef CONFIG_KVM
     if (kvm_enabled()) {
 	if (kvm_qemu_init() < 0) {
 	    fprintf(stderr, "Could not initialize KVM, will disable KVM support\n");
-- 
1.6.2.2


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

* [PATCH v2 2/9] Do not compile qemu-kvm.c and qemu-kvm-x86.c
  2009-07-10 20:17 ` [PATCH v2 1/9] replace USE_KVM with CONFIG_KVM Glauber Costa
@ 2009-07-10 20:17   ` Glauber Costa
  2009-07-10 20:17     ` [PATCH v2 3/9] replace malloc with qemu_malloc Glauber Costa
  0 siblings, 1 reply; 12+ messages in thread
From: Glauber Costa @ 2009-07-10 20:17 UTC (permalink / raw)
  To: kvm; +Cc: avi

Instead, include them from upstream files

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 Makefile.target   |    5 ++---
 kvm-all.c         |    2 ++
 target-i386/kvm.c |    2 ++
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 11a6da8..1c0f4ea 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -160,7 +160,6 @@ ifeq ($(ARCH),sparc64)
 CPPFLAGS+=-I$(SRC_PATH)/tcg/sparc
 endif
 
-libobj-$(CONFIG_KVM) += qemu-kvm.o
 ifdef CONFIG_SOFTFLOAT
 libobj-y += fpu/softfloat.o
 else
@@ -171,13 +170,13 @@ libobj-y += op_helper.o helper.o
 
 ifeq ($(TARGET_ARCH), i386)
 libobj-y += helper.o
-libobj-$(CONFIG_KVM) += qemu-kvm-x86.o kvm-tpr-opt.o
+libobj-$(CONFIG_KVM) += kvm-tpr-opt.o
 libobj-$(CONFIG_KVM) += qemu-kvm-helper.o
 endif
 
 ifeq ($(TARGET_ARCH), x86_64)
 libobj-y += helper.o
-libobj-$(CONFIG_KVM) += qemu-kvm-x86.o kvm-tpr-opt.o
+libobj-$(CONFIG_KVM) += kvm-tpr-opt.o
 libobj-$(CONFIG_KVM) += qemu-kvm-helper.o
 endif
 
diff --git a/kvm-all.c b/kvm-all.c
index 4c2fdf5..e42b1f6 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1029,3 +1029,5 @@ void kvm_remove_all_breakpoints(CPUState *current_env)
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
 #endif
+
+#include "qemu-kvm.c"
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index d26161a..6e9d938 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -961,3 +961,5 @@ void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
 }
 #endif /* KVM_CAP_SET_GUEST_DEBUG */
 #endif
+
+#include "qemu-kvm-x86.c"
-- 
1.6.2.2


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

* [PATCH v2 3/9] replace malloc with qemu_malloc
  2009-07-10 20:17   ` [PATCH v2 2/9] Do not compile qemu-kvm.c and qemu-kvm-x86.c Glauber Costa
@ 2009-07-10 20:17     ` Glauber Costa
  2009-07-10 20:17       ` [PATCH v2 4/9] remove leftover: Glauber Costa
  0 siblings, 1 reply; 12+ messages in thread
From: Glauber Costa @ 2009-07-10 20:17 UTC (permalink / raw)
  To: kvm; +Cc: avi

This patch replaces both malloc and malloc+memset sequences
with qemu_malloc and qemu_mallocz. Target is upstream integration

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 qemu-kvm-x86.c |   31 ++++++++-----------------------
 qemu-kvm.c     |   26 +++++---------------------
 2 files changed, 13 insertions(+), 44 deletions(-)

diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 8ba3b6e..d3fb2e3 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -352,12 +352,9 @@ struct kvm_msr_list *kvm_get_msr_list(kvm_context_t kvm)
 		return NULL;
 	/* Old kernel modules had a bug and could write beyond the provided
 	   memory. Allocate at least a safe amount of 1K. */
-	msrs = malloc(MAX(1024, sizeof(*msrs) +
-				sizer.nmsrs * sizeof(*msrs->indices)));
-	if (!msrs) {
-		errno = ENOMEM;
-		return NULL;
-	}
+	msrs = qemu_malloc(MAX(1024, sizeof(*msrs) +
+				       sizer.nmsrs * sizeof(*msrs->indices)));
+
 	msrs->nmsrs = sizer.nmsrs;
 	r = ioctl(kvm->fd, KVM_GET_MSR_INDEX_LIST, msrs);
 	if (r == -1) {
@@ -371,13 +368,9 @@ struct kvm_msr_list *kvm_get_msr_list(kvm_context_t kvm)
 
 int kvm_get_msrs(kvm_vcpu_context_t vcpu, struct kvm_msr_entry *msrs, int n)
 {
-    struct kvm_msrs *kmsrs = malloc(sizeof *kmsrs + n * sizeof *msrs);
+    struct kvm_msrs *kmsrs = qemu_malloc(sizeof *kmsrs + n * sizeof *msrs);
     int r, e;
 
-    if (!kmsrs) {
-	errno = ENOMEM;
-	return -1;
-    }
     kmsrs->nmsrs = n;
     memcpy(kmsrs->entries, msrs, n * sizeof *msrs);
     r = ioctl(vcpu->fd, KVM_GET_MSRS, kmsrs);
@@ -390,13 +383,9 @@ int kvm_get_msrs(kvm_vcpu_context_t vcpu, struct kvm_msr_entry *msrs, int n)
 
 int kvm_set_msrs(kvm_vcpu_context_t vcpu, struct kvm_msr_entry *msrs, int n)
 {
-    struct kvm_msrs *kmsrs = malloc(sizeof *kmsrs + n * sizeof *msrs);
+    struct kvm_msrs *kmsrs = qemu_malloc(sizeof *kmsrs + n * sizeof *msrs);
     int r, e;
 
-    if (!kmsrs) {
-	errno = ENOMEM;
-	return -1;
-    }
     kmsrs->nmsrs = n;
     memcpy(kmsrs->entries, msrs, n * sizeof *msrs);
     r = ioctl(vcpu->fd, KVM_SET_MSRS, kmsrs);
@@ -486,9 +475,7 @@ int kvm_setup_cpuid(kvm_vcpu_context_t vcpu, int nent,
 	struct kvm_cpuid *cpuid;
 	int r;
 
-	cpuid = malloc(sizeof(*cpuid) + nent * sizeof(*entries));
-	if (!cpuid)
-		return -ENOMEM;
+	cpuid = qemu_malloc(sizeof(*cpuid) + nent * sizeof(*entries));
 
 	cpuid->nent = nent;
 	memcpy(cpuid->entries, entries, nent * sizeof(*entries));
@@ -504,9 +491,7 @@ int kvm_setup_cpuid2(kvm_vcpu_context_t vcpu, int nent,
 	struct kvm_cpuid2 *cpuid;
 	int r;
 
-	cpuid = malloc(sizeof(*cpuid) + nent * sizeof(*entries));
-	if (!cpuid)
-		return -ENOMEM;
+	cpuid = qemu_malloc(sizeof(*cpuid) + nent * sizeof(*entries));
 
 	cpuid->nent = nent;
 	memcpy(cpuid->entries, entries, nent * sizeof(*entries));
@@ -594,7 +579,7 @@ static struct kvm_cpuid2 *try_get_cpuid(kvm_context_t kvm, int max)
 	int r, size;
 
 	size = sizeof(*cpuid) + max * sizeof(*cpuid->entries);
-	cpuid = (struct kvm_cpuid2 *)malloc(size);
+	cpuid = qemu_malloc(size);
 	cpuid->nent = max;
 	r = ioctl(kvm->fd, KVM_GET_SUPPORTED_CPUID, cpuid);
 	if (r == -1)
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 982ad33..1d1c919 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -447,10 +447,7 @@ kvm_context_t kvm_init(void *opaque)
 	}
 	kvm_abi = r;
 	kvm_page_size = getpagesize();
-	kvm = malloc(sizeof(*kvm));
-	if (kvm == NULL)
-		goto out_close;
-	memset(kvm, 0, sizeof(*kvm));
+	kvm = qemu_mallocz(sizeof(*kvm));
 	kvm->fd = fd;
 	kvm->vm_fd = -1;
 	kvm->opaque = opaque;
@@ -464,10 +461,7 @@ kvm_context_t kvm_init(void *opaque)
 
 		/* Round up so we can search ints using ffs */
 		gsi_bits = ALIGN(gsi_count, 32);
-		kvm->used_gsi_bitmap = malloc(gsi_bits / 8);
-		if (!kvm->used_gsi_bitmap)
-			goto out_close;
-		memset(kvm->used_gsi_bitmap, 0, gsi_bits / 8);
+		kvm->used_gsi_bitmap = qemu_mallocz(gsi_bits / 8);
 		kvm->max_gsi = gsi_bits;
 
 		/* Mark any over-allocated bits as already in use */
@@ -507,12 +501,7 @@ kvm_vcpu_context_t kvm_create_vcpu(kvm_context_t kvm, int id)
 {
 	long mmap_size;
 	int r;
-	kvm_vcpu_context_t vcpu_ctx = malloc(sizeof(struct kvm_vcpu_context));
-
-	if (!vcpu_ctx) {
-		errno = ENOMEM;
-		return NULL;
-	}
+	kvm_vcpu_context_t vcpu_ctx = qemu_malloc(sizeof(struct kvm_vcpu_context));
 
 	vcpu_ctx->kvm = kvm;
 	vcpu_ctx->id = id;
@@ -559,10 +548,7 @@ int kvm_create_vm(kvm_context_t kvm)
 	int fd = kvm->fd;
 
 #ifdef KVM_CAP_IRQ_ROUTING
-	kvm->irq_routes = malloc(sizeof(*kvm->irq_routes));
-	if (!kvm->irq_routes)
-		return -ENOMEM;
-	memset(kvm->irq_routes, 0, sizeof(*kvm->irq_routes));
+	kvm->irq_routes = qemu_mallocz(sizeof(*kvm->irq_routes));
 	kvm->nr_allocated_irq_routes = 0;
 #endif
 
@@ -1167,9 +1153,7 @@ int kvm_set_signal_mask(kvm_vcpu_context_t vcpu, const sigset_t *sigset)
 			r = -errno;
 		return r;
 	}
-	sigmask = malloc(sizeof(*sigmask) + sizeof(*sigset));
-	if (!sigmask)
-		return -ENOMEM;
+	sigmask = qemu_malloc(sizeof(*sigmask) + sizeof(*sigset));
 
 	sigmask->len = 8;
 	memcpy(sigmask->sigset, sigset, sizeof(*sigset));
-- 
1.6.2.2


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

* [PATCH v2 4/9] remove leftover:
  2009-07-10 20:17     ` [PATCH v2 3/9] replace malloc with qemu_malloc Glauber Costa
@ 2009-07-10 20:17       ` Glauber Costa
  2009-07-10 20:17         ` [PATCH v2 5/9] fold libkvm-all into standard qemu header Glauber Costa
  0 siblings, 1 reply; 12+ messages in thread
From: Glauber Costa @ 2009-07-10 20:17 UTC (permalink / raw)
  To: kvm; +Cc: avi

get rid of kvm_callbacks structure definition

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 libkvm-all.h |   57 ---------------------------------------------------------
 1 files changed, 0 insertions(+), 57 deletions(-)

diff --git a/libkvm-all.h b/libkvm-all.h
index 3e3e1b4..01c0486 100644
--- a/libkvm-all.h
+++ b/libkvm-all.h
@@ -105,7 +105,6 @@ int handle_io_window(kvm_context_t kvm);
 int handle_debug(kvm_vcpu_context_t vcpu, void *env);
 int try_push_interrupts(kvm_context_t kvm);
 
-
 #if defined(__x86_64__) || defined(__i386__)
 struct kvm_msr_list *kvm_get_msr_list(kvm_context_t);
 int kvm_get_msrs(kvm_vcpu_context_t, struct kvm_msr_entry *msrs, int n);
@@ -113,62 +112,6 @@ int kvm_set_msrs(kvm_vcpu_context_t, struct kvm_msr_entry *msrs, int n);
 #endif
 
 /*!
- * \brief KVM callbacks structure
- *
- * This structure holds pointers to various functions that KVM will call
- * when it encounters something that cannot be virtualized, such as
- * accessing hardware devices via MMIO or regular IO.
- */
-struct kvm_callbacks {
-	/// For 8bit IO reads from the guest (Usually when executing 'inb')
-    int (*inb)(void *opaque, uint16_t addr, uint8_t *data);
-	/// For 16bit IO reads from the guest (Usually when executing 'inw')
-    int (*inw)(void *opaque, uint16_t addr, uint16_t *data);
-	/// For 32bit IO reads from the guest (Usually when executing 'inl')
-    int (*inl)(void *opaque, uint16_t addr, uint32_t *data);
-	/// For 8bit IO writes from the guest (Usually when executing 'outb')
-    int (*outb)(void *opaque, uint16_t addr, uint8_t data);
-	/// For 16bit IO writes from the guest (Usually when executing 'outw')
-    int (*outw)(void *opaque, uint16_t addr, uint16_t data);
-	/// For 32bit IO writes from the guest (Usually when executing 'outl')
-    int (*outl)(void *opaque, uint16_t addr, uint32_t data);
-	/// generic memory reads to unmapped memory (For MMIO devices)
-    int (*mmio_read)(void *opaque, uint64_t addr, uint8_t *data,
-					int len);
-	/// generic memory writes to unmapped memory (For MMIO devices)
-    int (*mmio_write)(void *opaque, uint64_t addr, uint8_t *data,
-					int len);
-#ifdef KVM_CAP_SET_GUEST_DEBUG
-    int (*debug)(void *opaque, void *env,
-		 struct kvm_debug_exit_arch *arch_info);
-#endif
-	/*!
-	 * \brief Called when the VCPU issues an 'hlt' instruction.
-	 *
-	 * Typically, you should yeild here to prevent 100% CPU utilization
-	 * on the host CPU.
-	 */
-    int (*halt)(void *opaque, kvm_vcpu_context_t vcpu);
-    int (*shutdown)(void *opaque, void *env);
-    int (*io_window)(void *opaque);
-    int (*try_push_interrupts)(void *opaque);
-#ifdef KVM_CAP_USER_NMI
-    void (*push_nmi)(void *opaque);
-#endif
-    void (*post_kvm_run)(void *opaque, void *env);
-    int (*pre_kvm_run)(void *opaque, void *env);
-    int (*tpr_access)(void *opaque, kvm_vcpu_context_t vcpu, uint64_t rip, int is_write);
-#if defined(__s390__)
-    int (*s390_handle_intercept)(kvm_context_t context, kvm_vcpu_context_t vcpu,
-	struct kvm_run *run);
-    int (*s390_handle_reset)(kvm_context_t context, kvm_vcpu_context_t vcpu,
-	 struct kvm_run *run);
-#endif
-    int (*unhandled)(kvm_context_t context, kvm_vcpu_context_t vcpu,
-                     uint64_t hw_reason);
-};
-
-/*!
  * \brief Create new KVM context
  *
  * This creates a new kvm_context. A KVM context is a small area of data that
-- 
1.6.2.2


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

* [PATCH v2 5/9] fold libkvm-all into standard qemu header
  2009-07-10 20:17       ` [PATCH v2 4/9] remove leftover: Glauber Costa
@ 2009-07-10 20:17         ` Glauber Costa
  2009-07-10 20:17           ` [PATCH v2 6/9] duplicate KVMState Glauber Costa
  0 siblings, 1 reply; 12+ messages in thread
From: Glauber Costa @ 2009-07-10 20:17 UTC (permalink / raw)
  To: kvm; +Cc: avi

Sharing of structures containing each other between libkvm-all.h and
qemu-kmv.h gets a bit messy in this series. So fold them together. libkvm-all.h
has no place in the final schema of things anyway.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 kvm.h                |    1 -
 libkvm-all.h         |  904 --------------------------------------------------
 qemu-kvm-ia64.c      |    1 -
 qemu-kvm-x86.c       |    1 -
 qemu-kvm.c           |    1 -
 qemu-kvm.h           |  896 +++++++++++++++++++++++++++++++++++++++++++++++++-
 target-i386/libkvm.h |    2 -
 7 files changed, 895 insertions(+), 911 deletions(-)
 delete mode 100644 libkvm-all.h

diff --git a/kvm.h b/kvm.h
index d9723d7..e9a43e2 100644
--- a/kvm.h
+++ b/kvm.h
@@ -16,7 +16,6 @@
 
 #include "config.h"
 #include "sys-queue.h"
-#include "libkvm-all.h"
 
 #ifdef KVM_UPSTREAM
 
diff --git a/libkvm-all.h b/libkvm-all.h
deleted file mode 100644
index 01c0486..0000000
--- a/libkvm-all.h
+++ /dev/null
@@ -1,904 +0,0 @@
-/** \file libkvm.h
- * libkvm API
- */
-
-#ifndef LIBKVM_H
-#define LIBKVM_H
-
-#ifdef CONFIG_KVM
-
-#if defined(__s390__)
-#include <asm/ptrace.h>
-#endif
-
-#include <stdint.h>
-
-#ifndef __user
-#define __user /* temporary, until installed via make headers_install */
-#endif
-
-#include <linux/kvm.h>
-
-#include <signal.h>
-
-/* FIXME: share this number with kvm */
-/* FIXME: or dynamically alloc/realloc regions */
-#ifdef __s390__
-#define KVM_MAX_NUM_MEM_REGIONS 1u
-#define MAX_VCPUS 64
-#define LIBKVM_S390_ORIGIN (0UL)
-#elif defined(__ia64__)
-#define KVM_MAX_NUM_MEM_REGIONS 32u
-#define MAX_VCPUS 256
-#else
-#define KVM_MAX_NUM_MEM_REGIONS 32u
-#define MAX_VCPUS 16
-#endif
-
-/* kvm abi verison variable */
-extern int kvm_abi;
-
-/**
- * \brief The KVM context
- *
- * The verbose KVM context
- */
-
-struct kvm_context {
-	/// Filedescriptor to /dev/kvm
-	int fd;
-	int vm_fd;
-	/// Callbacks that KVM uses to emulate various unvirtualizable functionality
-	struct kvm_callbacks *callbacks;
-	void *opaque;
-	/// is dirty pages logging enabled for all regions or not
-	int dirty_pages_log_all;
-	/// do not create in-kernel irqchip if set
-	int no_irqchip_creation;
-	/// in-kernel irqchip status
-	int irqchip_in_kernel;
-	/// ioctl to use to inject interrupts
-	int irqchip_inject_ioctl;
-	/// do not create in-kernel pit if set
-	int no_pit_creation;
-	/// in-kernel pit status
-	int pit_in_kernel;
-	/// in-kernel coalesced mmio
-	int coalesced_mmio;
-#ifdef KVM_CAP_IRQ_ROUTING
-	struct kvm_irq_routing *irq_routes;
-	int nr_allocated_irq_routes;
-#endif
-	void *used_gsi_bitmap;
-	int max_gsi;
-};
-
-struct kvm_vcpu_context
-{
-	int fd;
-	struct kvm_run *run;
-	struct kvm_context *kvm;
-	uint32_t id;
-};
-
-typedef struct kvm_context *kvm_context_t;
-typedef struct kvm_vcpu_context *kvm_vcpu_context_t;
-
-#include "kvm.h"
-int kvm_alloc_kernel_memory(kvm_context_t kvm, unsigned long memory,
-								void **vm_mem);
-int kvm_alloc_userspace_memory(kvm_context_t kvm, unsigned long memory,
-								void **vm_mem);
-
-int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
-                        void **vm_mem);
-int kvm_arch_run(kvm_vcpu_context_t vcpu);
-
-
-void kvm_show_code(kvm_vcpu_context_t vcpu);
-
-int handle_halt(kvm_vcpu_context_t vcpu);
-int handle_shutdown(kvm_context_t kvm, CPUState *env);
-void post_kvm_run(kvm_context_t kvm, CPUState *env);
-int pre_kvm_run(kvm_context_t kvm, CPUState *env);
-int handle_io_window(kvm_context_t kvm);
-int handle_debug(kvm_vcpu_context_t vcpu, void *env);
-int try_push_interrupts(kvm_context_t kvm);
-
-#if defined(__x86_64__) || defined(__i386__)
-struct kvm_msr_list *kvm_get_msr_list(kvm_context_t);
-int kvm_get_msrs(kvm_vcpu_context_t, struct kvm_msr_entry *msrs, int n);
-int kvm_set_msrs(kvm_vcpu_context_t, struct kvm_msr_entry *msrs, int n);
-#endif
-
-/*!
- * \brief Create new KVM context
- *
- * This creates a new kvm_context. A KVM context is a small area of data that
- * holds information about the KVM instance that gets created by this call.\n
- * This should always be your first call to KVM.
- *
- * \param opaque Not used
- * \return NULL on failure
- */
-kvm_context_t kvm_init(void *opaque);
-
-/*!
- * \brief Cleanup the KVM context
- *
- * Should always be called when closing down KVM.\n
- * Exception: If kvm_init() fails, this function should not be called, as the
- * context would be invalid
- *
- * \param kvm Pointer to the kvm_context that is to be freed
- */
-void kvm_finalize(kvm_context_t kvm);
-
-/*!
- * \brief Disable the in-kernel IRQCHIP creation
- *
- * In-kernel irqchip is enabled by default. If userspace irqchip is to be used,
- * this should be called prior to kvm_create().
- *
- * \param kvm Pointer to the kvm_context
- */
-void kvm_disable_irqchip_creation(kvm_context_t kvm);
-
-/*!
- * \brief Disable the in-kernel PIT creation
- *
- * In-kernel pit is enabled by default. If userspace pit is to be used,
- * this should be called prior to kvm_create().
- *
- *  \param kvm Pointer to the kvm_context
- */
-void kvm_disable_pit_creation(kvm_context_t kvm);
-
-/*!
- * \brief Create new virtual machine
- *
- * This creates a new virtual machine, maps physical RAM to it, and creates a
- * virtual CPU for it.\n
- * \n
- * Memory gets mapped for addresses 0->0xA0000, 0xC0000->phys_mem_bytes
- *
- * \param kvm Pointer to the current kvm_context
- * \param phys_mem_bytes The amount of physical ram you want the VM to have
- * \param phys_mem This pointer will be set to point to the memory that
- * kvm_create allocates for physical RAM
- * \return 0 on success
- */
-int kvm_create(kvm_context_t kvm,
-	       unsigned long phys_mem_bytes,
-	       void **phys_mem);
-int kvm_create_vm(kvm_context_t kvm);
-int kvm_check_extension(kvm_context_t kvm, int ext);
-void kvm_create_irqchip(kvm_context_t kvm);
-
-/*!
- * \brief Create a new virtual cpu
- *
- * This creates a new virtual cpu (the first vcpu is created by kvm_create()).
- * Should be called from a thread dedicated to the vcpu.
- *
- * \param kvm kvm context
- * \param slot vcpu number (> 0)
- * \return 0 on success, -errno on failure
- */
-kvm_vcpu_context_t kvm_create_vcpu(kvm_context_t kvm, int id);
-
-/*!
- * \brief Start the VCPU
- *
- * This starts the VCPU and virtualization is started.\n
- * \n
- * This function will not return until any of these conditions are met:
- * - An IO/MMIO handler does not return "0"
- * - An exception that neither the guest OS, nor KVM can handle occurs
- *
- * \note This function will call the callbacks registered in kvm_init()
- * to emulate those functions
- * \note If you at any point want to interrupt the VCPU, kvm_run() will
- * listen to the EINTR signal. This allows you to simulate external interrupts
- * and asyncronous IO.
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should be started
- * \return 0 on success, but you really shouldn't expect this function to
- * return except for when an error has occured, or when you have sent it
- * an EINTR signal.
- */
-int kvm_run(kvm_vcpu_context_t vcpu, void *env);
-
-/*!
- * \brief Get interrupt flag from on last exit to userspace
- *
- * This gets the CPU interrupt flag as it was on the last exit to userspace.
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \return interrupt flag value (0 or 1)
- */
-int kvm_get_interrupt_flag(kvm_vcpu_context_t vcpu);
-
-/*!
- * \brief Get the value of the APIC_BASE msr as of last exit to userspace
- *
- * This gets the APIC_BASE msr as it was on the last exit to userspace.
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \return APIC_BASE msr contents
- */
-uint64_t kvm_get_apic_base(kvm_vcpu_context_t vcpu);
-
-/*!
- * \brief Check if a vcpu is ready for interrupt injection
- *
- * This checks if vcpu interrupts are not masked by mov ss or sti.
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \return boolean indicating interrupt injection readiness
- */
-int kvm_is_ready_for_interrupt_injection(kvm_vcpu_context_t vcpu);
-
-/*!
- * \brief Read VCPU registers
- *
- * This gets the GP registers from the VCPU and outputs them
- * into a kvm_regs structure
- *
- * \note This function returns a \b copy of the VCPUs registers.\n
- * If you wish to modify the VCPUs GP registers, you should call kvm_set_regs()
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \param regs Pointer to a kvm_regs which will be populated with the VCPUs
- * registers values
- * \return 0 on success
- */
-int kvm_get_regs(kvm_vcpu_context_t vcpu, struct kvm_regs *regs);
-
-/*!
- * \brief Write VCPU registers
- *
- * This sets the GP registers on the VCPU from a kvm_regs structure
- *
- * \note When this function returns, the regs pointer and the data it points to
- * can be discarded
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \param regs Pointer to a kvm_regs which will be populated with the VCPUs
- * registers values
- * \return 0 on success
- */
-int kvm_set_regs(kvm_vcpu_context_t vcpu, struct kvm_regs *regs);
-/*!
- * \brief Read VCPU fpu registers
- *
- * This gets the FPU registers from the VCPU and outputs them
- * into a kvm_fpu structure
- *
- * \note This function returns a \b copy of the VCPUs registers.\n
- * If you wish to modify the VCPU FPU registers, you should call kvm_set_fpu()
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \param fpu Pointer to a kvm_fpu which will be populated with the VCPUs
- * fpu registers values
- * \return 0 on success
- */
-int kvm_get_fpu(kvm_vcpu_context_t vcpu, struct kvm_fpu *fpu);
-
-/*!
- * \brief Write VCPU fpu registers
- *
- * This sets the FPU registers on the VCPU from a kvm_fpu structure
- *
- * \note When this function returns, the fpu pointer and the data it points to
- * can be discarded
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \param fpu Pointer to a kvm_fpu which holds the new vcpu fpu state
- * \return 0 on success
- */
-int kvm_set_fpu(kvm_vcpu_context_t vcpu, struct kvm_fpu *fpu);
-
-/*!
- * \brief Read VCPU system registers
- *
- * This gets the non-GP registers from the VCPU and outputs them
- * into a kvm_sregs structure
- *
- * \note This function returns a \b copy of the VCPUs registers.\n
- * If you wish to modify the VCPUs non-GP registers, you should call
- * kvm_set_sregs()
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \param regs Pointer to a kvm_sregs which will be populated with the VCPUs
- * registers values
- * \return 0 on success
- */
-int kvm_get_sregs(kvm_vcpu_context_t vcpu, struct kvm_sregs *regs);
-
-/*!
- * \brief Write VCPU system registers
- *
- * This sets the non-GP registers on the VCPU from a kvm_sregs structure
- *
- * \note When this function returns, the regs pointer and the data it points to
- * can be discarded
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \param regs Pointer to a kvm_sregs which will be populated with the VCPUs
- * registers values
- * \return 0 on success
- */
-int kvm_set_sregs(kvm_vcpu_context_t vcpu, struct kvm_sregs *regs);
-
-#ifdef KVM_CAP_MP_STATE
-/*!
- *  * \brief Read VCPU MP state
- *
- */
-int kvm_get_mpstate(kvm_vcpu_context_t vcpu, struct kvm_mp_state *mp_state);
-
-/*!
- *  * \brief Write VCPU MP state
- *
- */
-int kvm_set_mpstate(kvm_vcpu_context_t vcpu, struct kvm_mp_state *mp_state);
-/*!
- *  * \brief Reset VCPU MP state
- *
- */
-static inline int kvm_reset_mpstate(kvm_vcpu_context_t vcpu)
-{
-    struct kvm_mp_state mp_state = {.mp_state = KVM_MP_STATE_UNINITIALIZED};
-    return kvm_set_mpstate(vcpu, &mp_state);
-}
-#endif
-
-/*!
- * \brief Simulate an external vectored interrupt
- *
- * This allows you to simulate an external vectored interrupt.
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \param irq Vector number
- * \return 0 on success
- */
-int kvm_inject_irq(kvm_vcpu_context_t vcpu, unsigned irq);
-
-#ifdef KVM_CAP_SET_GUEST_DEBUG
-int kvm_set_guest_debug(kvm_vcpu_context_t, struct kvm_guest_debug *dbg);
-#endif
-
-#if defined(__i386__) || defined(__x86_64__)
-/*!
- * \brief Setup a vcpu's cpuid instruction emulation
- *
- * Set up a table of cpuid function to cpuid outputs.\n
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should be initialized
- * \param nent number of entries to be installed
- * \param entries cpuid function entries table
- * \return 0 on success, or -errno on error
- */
-int kvm_setup_cpuid(kvm_vcpu_context_t vcpu, int nent,
-		    struct kvm_cpuid_entry *entries);
-
-/*!
- * \brief Setup a vcpu's cpuid instruction emulation
- *
- * Set up a table of cpuid function to cpuid outputs.
- * This call replaces the older kvm_setup_cpuid interface by adding a few
- * parameters to support cpuid functions that have sub-leaf values.
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should be initialized
- * \param nent number of entries to be installed
- * \param entries cpuid function entries table
- * \return 0 on success, or -errno on error
- */
-int kvm_setup_cpuid2(kvm_vcpu_context_t vcpu, int nent,
-		     struct kvm_cpuid_entry2 *entries);
-
-/*!
- * \brief Setting the number of shadow pages to be allocated to the vm
- *
- * \param kvm pointer to kvm_context
- * \param nrshadow_pages number of pages to be allocated
- */
-int kvm_set_shadow_pages(kvm_context_t kvm, unsigned int nrshadow_pages);
-
-/*!
- * \brief Getting the number of shadow pages that are allocated to the vm
- *
- * \param kvm pointer to kvm_context
- * \param nrshadow_pages number of pages to be allocated
- */
-int kvm_get_shadow_pages(kvm_context_t kvm , unsigned int *nrshadow_pages);
-
-/*!
- * \brief Set up cr8 for next time the vcpu is executed
- *
- * This is a fast setter for cr8, which will be applied when the
- * vcpu next enters guest mode.
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \param cr8 next cr8 value
- */
-void kvm_set_cr8(kvm_vcpu_context_t vcpu, uint64_t cr8);
-
-/*!
- * \brief Get cr8 for sync tpr in qemu apic emulation
- *
- * This is a getter for cr8, which used to sync with the tpr in qemu
- * apic emualtion.
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- */
-__u64 kvm_get_cr8(kvm_vcpu_context_t vcpu);
-#endif
-
-/*!
- * \brief Set a vcpu's signal mask for guest mode
- *
- * A vcpu can have different signals blocked in guest mode and user mode.
- * This allows guest execution to be interrupted on a signal, without requiring
- * that the signal be delivered to a signal handler (the signal can be
- * dequeued using sigwait(2).
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should be initialized
- * \param sigset signal mask for guest mode
- * \return 0 on success, or -errno on error
- */
-int kvm_set_signal_mask(kvm_vcpu_context_t vcpu, const sigset_t *sigset);
-
-/*!
- * \brief Dump VCPU registers
- *
- * This dumps some of the information that KVM has about a virtual CPU, namely:
- * - GP Registers
- *
- * A much more verbose version of this is available as kvm_dump_vcpu()
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \return 0 on success
- */
-void kvm_show_regs(kvm_vcpu_context_t vcpu);
-
-
-void *kvm_create_phys_mem(kvm_context_t, unsigned long phys_start, 
-			  unsigned long len, int log, int writable);
-void kvm_destroy_phys_mem(kvm_context_t, unsigned long phys_start, 
-			  unsigned long len);
-void kvm_unregister_memory_area(kvm_context_t, uint64_t phys_start,
-                                unsigned long len);
-
-int kvm_is_containing_region(kvm_context_t kvm, unsigned long phys_start, unsigned long size);
-int kvm_register_phys_mem(kvm_context_t kvm,
-			unsigned long phys_start, void *userspace_addr,
-			unsigned long len, int log);
-int kvm_get_dirty_pages(kvm_context_t, unsigned long phys_addr, void *buf);
-int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
-			      unsigned long end_addr, void*opaque,
-			      int (*cb)(unsigned long start, unsigned long len,
-					void*bitmap, void *opaque));
-int kvm_register_coalesced_mmio(kvm_context_t kvm,
-				uint64_t addr, uint32_t size);
-int kvm_unregister_coalesced_mmio(kvm_context_t kvm,
-				  uint64_t addr, uint32_t size);
-
-/*!
- * \brief Create a memory alias
- *
- * Aliases a portion of physical memory to another portion.  If the guest
- * accesses the alias region, it will behave exactly as if it accessed
- * the target memory.
- */
-int kvm_create_memory_alias(kvm_context_t,
-			    uint64_t phys_start, uint64_t len,
-			    uint64_t target_phys);
-
-/*!
- * \brief Destroy a memory alias
- *
- * Removes an alias created with kvm_create_memory_alias().
- */
-int kvm_destroy_memory_alias(kvm_context_t, uint64_t phys_start);
-
-/*!
- * \brief Get a bitmap of guest ram pages which are allocated to the guest.
- *
- * \param kvm Pointer to the current kvm_context
- * \param phys_addr Memory slot phys addr
- * \param bitmap Long aligned address of a big enough bitmap (one bit per page)
- */
-int kvm_get_mem_map(kvm_context_t kvm, unsigned long phys_addr, void *bitmap);
-int kvm_get_mem_map_range(kvm_context_t kvm, unsigned long phys_addr,
-			   unsigned long len, void *buf, void *opaque,
-			   int (*cb)(unsigned long start,unsigned long len,
-				     void* bitmap, void* opaque));
-int kvm_set_irq_level(kvm_context_t kvm, int irq, int level, int *status);
-
-int kvm_dirty_pages_log_enable_slot(kvm_context_t kvm,
-				    uint64_t phys_start,
-				    uint64_t len);
-int kvm_dirty_pages_log_disable_slot(kvm_context_t kvm,
-				     uint64_t phys_start,
-				     uint64_t len);
-/*!
- * \brief Enable dirty-pages-logging for all memory regions
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_dirty_pages_log_enable_all(kvm_context_t kvm);
-
-/*!
- * \brief Disable dirty-page-logging for some memory regions
- *
- * Disable dirty-pages-logging for those memory regions that were
- * created with dirty-page-logging disabled.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_dirty_pages_log_reset(kvm_context_t kvm);
-
-/*!
- * \brief Query whether in kernel irqchip is used
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_irqchip_in_kernel(kvm_context_t kvm);
-
-#ifdef KVM_CAP_IRQCHIP
-/*!
- * \brief Dump in kernel IRQCHIP contents
- *
- * Dump one of the in kernel irq chip devices, including PIC (master/slave)
- * and IOAPIC into a kvm_irqchip structure
- *
- * \param kvm Pointer to the current kvm_context
- * \param chip The irq chip device to be dumped
- */
-int kvm_get_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip);
-
-/*!
- * \brief Set in kernel IRQCHIP contents
- *
- * Write one of the in kernel irq chip devices, including PIC (master/slave)
- * and IOAPIC
- *
- *
- * \param kvm Pointer to the current kvm_context
- * \param chip THe irq chip device to be written
- */
-int kvm_set_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip);
-
-#if defined(__i386__) || defined(__x86_64__)
-/*!
- * \brief Get in kernel local APIC for vcpu
- *
- * Save the local apic state including the timer of a virtual CPU
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should be accessed
- * \param s Local apic state of the specific virtual CPU
- */
-int kvm_get_lapic(kvm_vcpu_context_t vcpu, struct kvm_lapic_state *s);
-
-/*!
- * \brief Set in kernel local APIC for vcpu
- *
- * Restore the local apic state including the timer of a virtual CPU
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should be accessed
- * \param s Local apic state of the specific virtual CPU
- */
-int kvm_set_lapic(kvm_vcpu_context_t vcpu, struct kvm_lapic_state *s);
-
-#endif
-
-/*!
- * \brief Simulate an NMI
- *
- * This allows you to simulate a non-maskable interrupt.
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu Which virtual CPU should get dumped
- * \return 0 on success
- */
-int kvm_inject_nmi(kvm_vcpu_context_t vcpu);
-
-#endif
-
-/*!
- * \brief Query wheather in kernel pit is used
- *
- *  \param kvm Pointer to the current kvm_context
- */
-int kvm_pit_in_kernel(kvm_context_t kvm);
-
-/*!
- * \brief Initialize coalesced MMIO
- *
- * Check for coalesced MMIO capability and store in context
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_init_coalesced_mmio(kvm_context_t kvm);
-
-#ifdef KVM_CAP_PIT
-
-#if defined(__i386__) || defined(__x86_64__)
-/*!
- * \brief Get in kernel PIT of the virtual domain
- *
- * Save the PIT state.
- *
- * \param kvm Pointer to the current kvm_context
- * \param s PIT state of the virtual domain
- */
-int kvm_get_pit(kvm_context_t kvm, struct kvm_pit_state *s);
-
-/*!
- * \brief Set in kernel PIT of the virtual domain
- *
- * Restore the PIT state.
- * Timer would be retriggerred after restored.
- *
- * \param kvm Pointer to the current kvm_context
- * \param s PIT state of the virtual domain
- */
-int kvm_set_pit(kvm_context_t kvm, struct kvm_pit_state *s);
-#endif
-
-int kvm_reinject_control(kvm_context_t kvm, int pit_reinject);
-
-#endif
-
-#ifdef KVM_CAP_VAPIC
-
-/*!
- * \brief Enable kernel tpr access reporting
- *
- * When tpr access reporting is enabled, the kernel will call the
- * ->tpr_access() callback every time the guest vcpu accesses the tpr.
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu vcpu to enable tpr access reporting on
- */
-int kvm_enable_tpr_access_reporting(kvm_vcpu_context_t vcpu);
-
-/*!
- * \brief Disable kernel tpr access reporting
- *
- * Undoes the effect of kvm_enable_tpr_access_reporting().
- *
- * \param kvm Pointer to the current kvm_context
- * \param vcpu vcpu to disable tpr access reporting on
- */
-int kvm_disable_tpr_access_reporting(kvm_vcpu_context_t vcpu);
-
-int kvm_enable_vapic(kvm_vcpu_context_t vcpu, uint64_t vapic);
-
-#endif
-
-#if defined(__s390__)
-int kvm_s390_initial_reset(kvm_context_t kvm, int slot);
-int kvm_s390_interrupt(kvm_context_t kvm, int slot,
-	struct kvm_s390_interrupt *kvmint);
-int kvm_s390_set_initial_psw(kvm_context_t kvm, int slot, psw_t psw);
-int kvm_s390_store_status(kvm_context_t kvm, int slot, unsigned long addr);
-#endif
-
-#ifdef KVM_CAP_DEVICE_ASSIGNMENT
-/*!
- * \brief Notifies host kernel about a PCI device to be assigned to a guest
- *
- * Used for PCI device assignment, this function notifies the host
- * kernel about the assigning of the physical PCI device to a guest.
- *
- * \param kvm Pointer to the current kvm_context
- * \param assigned_dev Parameters, like bus, devfn number, etc
- */
-int kvm_assign_pci_device(kvm_context_t kvm,
-			  struct kvm_assigned_pci_dev *assigned_dev);
-
-/*!
- * \brief Assign IRQ for an assigned device
- *
- * Used for PCI device assignment, this function assigns IRQ numbers for
- * an physical device and guest IRQ handling.
- *
- * \param kvm Pointer to the current kvm_context
- * \param assigned_irq Parameters, like dev id, host irq, guest irq, etc
- */
-int kvm_assign_irq(kvm_context_t kvm,
-		   struct kvm_assigned_irq *assigned_irq);
-
-#ifdef KVM_CAP_ASSIGN_DEV_IRQ
-/*!
- * \brief Deassign IRQ for an assigned device
- *
- * Used for PCI device assignment, this function deassigns IRQ numbers
- * for an assigned device.
- *
- * \param kvm Pointer to the current kvm_context
- * \param assigned_irq Parameters, like dev id, host irq, guest irq, etc
- */
-int kvm_deassign_irq(kvm_context_t kvm,
-                   struct kvm_assigned_irq *assigned_irq);
-#endif
-#endif
-
-/*!
- * \brief Determines whether destroying memory regions is allowed
- *
- * KVM before 2.6.29 had a bug when destroying memory regions.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_destroy_memory_region_works(kvm_context_t kvm);
-
-#ifdef KVM_CAP_DEVICE_DEASSIGNMENT
-/*!
- * \brief Notifies host kernel about a PCI device to be deassigned from a guest
- *
- * Used for hot remove PCI device, this function notifies the host
- * kernel about the deassigning of the physical PCI device from a guest.
- *
- * \param kvm Pointer to the current kvm_context
- * \param assigned_dev Parameters, like bus, devfn number, etc
- */
-int kvm_deassign_pci_device(kvm_context_t kvm,
-			    struct kvm_assigned_pci_dev *assigned_dev);
-#endif
-
-/*!
- * \brief Checks whether the generic irq routing capability is present
- *
- * Checks whether kvm can reroute interrupts among the various interrupt
- * controllers.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_has_gsi_routing(kvm_context_t kvm);
-
-/*!
- * \brief Determines the number of gsis that can be routed
- *
- * Returns the number of distinct gsis that can be routed by kvm.  This is
- * also the number of distinct routes (if a gsi has two routes, than another
- * gsi cannot be used...)
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_get_gsi_count(kvm_context_t kvm);
-
-/*!
- * \brief Clears the temporary irq routing table
- *
- * Clears the temporary irq routing table.  Nothing is committed to the
- * running VM.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_clear_gsi_routes(kvm_context_t kvm);
-
-/*!
- * \brief Adds an irq route to the temporary irq routing table
- *
- * Adds an irq route to the temporary irq routing table.  Nothing is
- * committed to the running VM.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_add_irq_route(kvm_context_t kvm, int gsi, int irqchip, int pin);
-
-/*!
- * \brief Removes an irq route from the temporary irq routing table
- *
- * Adds an irq route to the temporary irq routing table.  Nothing is
- * committed to the running VM.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_del_irq_route(kvm_context_t kvm, int gsi, int irqchip, int pin);
-
-struct kvm_irq_routing_entry;
-/*!
- * \brief Adds a routing entry to the temporary irq routing table
- *
- * Adds a filled routing entry to the temporary irq routing table. Nothing is
- * committed to the running VM.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_add_routing_entry(kvm_context_t kvm,
-                          struct kvm_irq_routing_entry* entry);
-
-/*!
- * \brief Removes a routing from the temporary irq routing table
- *
- * Remove a routing to the temporary irq routing table.  Nothing is
- * committed to the running VM.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_del_routing_entry(kvm_context_t kvm,
-		          struct kvm_irq_routing_entry* entry);
-
-/*!
- * \brief Updates a routing in the temporary irq routing table
- *
- * Update a routing in the temporary irq routing table
- * with a new value. entry type and GSI can not be changed.
- * Nothing is committed to the running VM.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_update_routing_entry(kvm_context_t kvm,
-                             struct kvm_irq_routing_entry* entry,
-                             struct kvm_irq_routing_entry* newentry
-);
-
-/*!
- * \brief Commit the temporary irq routing table
- *
- * Commit the temporary irq routing table to the running VM.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_commit_irq_routes(kvm_context_t kvm);
-
-/*!
- * \brief Get unused GSI number for irq routing table
- *
- * Get unused GSI number for irq routing table
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_get_irq_route_gsi(kvm_context_t kvm);
-
-/*!
- * \brief Create a file descriptor for injecting interrupts
- *
- * Creates an eventfd based file-descriptor that maps to a specific GSI
- * in the guest.  eventfd compliant signaling (write() from userspace, or
- * eventfd_signal() from kernelspace) will cause the GSI to inject
- * itself into the guest at the next available window.
- *
- * \param kvm Pointer to the current kvm_context
- * \param gsi GSI to assign to this fd
- * \param flags reserved, must be zero
- */
-int kvm_irqfd(kvm_context_t kvm, int gsi, int flags);
-
-#ifdef KVM_CAP_DEVICE_MSIX
-int kvm_assign_set_msix_nr(kvm_context_t kvm,
-			   struct kvm_assigned_msix_nr *msix_nr);
-int kvm_assign_set_msix_entry(kvm_context_t kvm,
-                              struct kvm_assigned_msix_entry *entry);
-#endif
-
-uint32_t kvm_get_supported_cpuid(kvm_context_t kvm, uint32_t function, int reg);
-
-#else /* !CONFIG_KVM */
-
-struct kvm_pit_state { };
-
-#endif /* !CONFIG_KVM */
-
-#endif
diff --git a/qemu-kvm-ia64.c b/qemu-kvm-ia64.c
index 582113f..b8a2587 100644
--- a/qemu-kvm-ia64.c
+++ b/qemu-kvm-ia64.c
@@ -5,7 +5,6 @@
 
 #include "hw/hw.h"
 #include "qemu-kvm.h"
-#include "libkvm-all.h"
 #include <pthread.h>
 #include <sys/utsname.h>
 #include <sys/io.h>
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index d3fb2e3..48b2e2f 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -15,7 +15,6 @@
 #include <sys/io.h>
 
 #include "qemu-kvm.h"
-#include "libkvm-all.h"
 #include "libkvm.h"
 #include <pthread.h>
 #include <sys/utsname.h>
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 1d1c919..32e903a 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -19,7 +19,6 @@
 #include "gdbstub.h"
 
 #include "qemu-kvm.h"
-#include "libkvm-all.h"
 #include "libkvm.h"
 
 #include <pthread.h>
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 96dc85f..43102a1 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -10,9 +10,903 @@
 
 #include "cpu.h"
 
+#ifdef CONFIG_KVM
+
+#include <signal.h>
+
+#if defined(__s390__)
+#include <asm/ptrace.h>
+#endif
+
+#include <stdint.h>
+
+#ifndef __user
+#define __user /* temporary, until installed via make headers_install */
+#endif
+
+#include <linux/kvm.h>
+
 #include <signal.h>
 
-#include "libkvm-all.h"
+/* FIXME: share this number with kvm */
+/* FIXME: or dynamically alloc/realloc regions */
+#ifdef __s390__
+#define KVM_MAX_NUM_MEM_REGIONS 1u
+#define MAX_VCPUS 64
+#define LIBKVM_S390_ORIGIN (0UL)
+#elif defined(__ia64__)
+#define KVM_MAX_NUM_MEM_REGIONS 32u
+#define MAX_VCPUS 256
+#else
+#define KVM_MAX_NUM_MEM_REGIONS 32u
+#define MAX_VCPUS 16
+#endif
+
+/* kvm abi verison variable */
+extern int kvm_abi;
+
+/**
+ * \brief The KVM context
+ *
+ * The verbose KVM context
+ */
+
+struct kvm_context {
+	/// Filedescriptor to /dev/kvm
+	int fd;
+	int vm_fd;
+	/// Callbacks that KVM uses to emulate various unvirtualizable functionality
+	struct kvm_callbacks *callbacks;
+	void *opaque;
+	/// is dirty pages logging enabled for all regions or not
+	int dirty_pages_log_all;
+	/// do not create in-kernel irqchip if set
+	int no_irqchip_creation;
+	/// in-kernel irqchip status
+	int irqchip_in_kernel;
+	/// ioctl to use to inject interrupts
+	int irqchip_inject_ioctl;
+	/// do not create in-kernel pit if set
+	int no_pit_creation;
+	/// in-kernel pit status
+	int pit_in_kernel;
+	/// in-kernel coalesced mmio
+	int coalesced_mmio;
+#ifdef KVM_CAP_IRQ_ROUTING
+	struct kvm_irq_routing *irq_routes;
+	int nr_allocated_irq_routes;
+#endif
+	void *used_gsi_bitmap;
+	int max_gsi;
+};
+
+struct kvm_vcpu_context
+{
+	int fd;
+	struct kvm_run *run;
+	struct kvm_context *kvm;
+	uint32_t id;
+};
+
+typedef struct kvm_context *kvm_context_t;
+typedef struct kvm_vcpu_context *kvm_vcpu_context_t;
+
+#include "kvm.h"
+int kvm_alloc_kernel_memory(kvm_context_t kvm, unsigned long memory,
+								void **vm_mem);
+int kvm_alloc_userspace_memory(kvm_context_t kvm, unsigned long memory,
+								void **vm_mem);
+
+int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
+                        void **vm_mem);
+int kvm_arch_run(kvm_vcpu_context_t vcpu);
+
+
+void kvm_show_code(kvm_vcpu_context_t vcpu);
+
+int handle_halt(kvm_vcpu_context_t vcpu);
+int handle_shutdown(kvm_context_t kvm, CPUState *env);
+void post_kvm_run(kvm_context_t kvm, CPUState *env);
+int pre_kvm_run(kvm_context_t kvm, CPUState *env);
+int handle_io_window(kvm_context_t kvm);
+int handle_debug(kvm_vcpu_context_t vcpu, void *env);
+int try_push_interrupts(kvm_context_t kvm);
+
+#if defined(__x86_64__) || defined(__i386__)
+struct kvm_msr_list *kvm_get_msr_list(kvm_context_t);
+int kvm_get_msrs(kvm_vcpu_context_t, struct kvm_msr_entry *msrs, int n);
+int kvm_set_msrs(kvm_vcpu_context_t, struct kvm_msr_entry *msrs, int n);
+#endif
+
+/*!
+ * \brief Create new KVM context
+ *
+ * This creates a new kvm_context. A KVM context is a small area of data that
+ * holds information about the KVM instance that gets created by this call.\n
+ * This should always be your first call to KVM.
+ *
+ * \param opaque Not used
+ * \return NULL on failure
+ */
+kvm_context_t kvm_init(void *opaque);
+
+/*!
+ * \brief Cleanup the KVM context
+ *
+ * Should always be called when closing down KVM.\n
+ * Exception: If kvm_init() fails, this function should not be called, as the
+ * context would be invalid
+ *
+ * \param kvm Pointer to the kvm_context that is to be freed
+ */
+void kvm_finalize(kvm_context_t kvm);
+
+/*!
+ * \brief Disable the in-kernel IRQCHIP creation
+ *
+ * In-kernel irqchip is enabled by default. If userspace irqchip is to be used,
+ * this should be called prior to kvm_create().
+ *
+ * \param kvm Pointer to the kvm_context
+ */
+void kvm_disable_irqchip_creation(kvm_context_t kvm);
+
+/*!
+ * \brief Disable the in-kernel PIT creation
+ *
+ * In-kernel pit is enabled by default. If userspace pit is to be used,
+ * this should be called prior to kvm_create().
+ *
+ *  \param kvm Pointer to the kvm_context
+ */
+void kvm_disable_pit_creation(kvm_context_t kvm);
+
+/*!
+ * \brief Create new virtual machine
+ *
+ * This creates a new virtual machine, maps physical RAM to it, and creates a
+ * virtual CPU for it.\n
+ * \n
+ * Memory gets mapped for addresses 0->0xA0000, 0xC0000->phys_mem_bytes
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param phys_mem_bytes The amount of physical ram you want the VM to have
+ * \param phys_mem This pointer will be set to point to the memory that
+ * kvm_create allocates for physical RAM
+ * \return 0 on success
+ */
+int kvm_create(kvm_context_t kvm,
+	       unsigned long phys_mem_bytes,
+	       void **phys_mem);
+int kvm_create_vm(kvm_context_t kvm);
+int kvm_check_extension(kvm_context_t kvm, int ext);
+void kvm_create_irqchip(kvm_context_t kvm);
+
+/*!
+ * \brief Create a new virtual cpu
+ *
+ * This creates a new virtual cpu (the first vcpu is created by kvm_create()).
+ * Should be called from a thread dedicated to the vcpu.
+ *
+ * \param kvm kvm context
+ * \param slot vcpu number (> 0)
+ * \return 0 on success, -errno on failure
+ */
+kvm_vcpu_context_t kvm_create_vcpu(kvm_context_t kvm, int id);
+
+/*!
+ * \brief Start the VCPU
+ *
+ * This starts the VCPU and virtualization is started.\n
+ * \n
+ * This function will not return until any of these conditions are met:
+ * - An IO/MMIO handler does not return "0"
+ * - An exception that neither the guest OS, nor KVM can handle occurs
+ *
+ * \note This function will call the callbacks registered in kvm_init()
+ * to emulate those functions
+ * \note If you at any point want to interrupt the VCPU, kvm_run() will
+ * listen to the EINTR signal. This allows you to simulate external interrupts
+ * and asyncronous IO.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should be started
+ * \return 0 on success, but you really shouldn't expect this function to
+ * return except for when an error has occured, or when you have sent it
+ * an EINTR signal.
+ */
+int kvm_run(kvm_vcpu_context_t vcpu, void *env);
+
+/*!
+ * \brief Get interrupt flag from on last exit to userspace
+ *
+ * This gets the CPU interrupt flag as it was on the last exit to userspace.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \return interrupt flag value (0 or 1)
+ */
+int kvm_get_interrupt_flag(kvm_vcpu_context_t vcpu);
+
+/*!
+ * \brief Get the value of the APIC_BASE msr as of last exit to userspace
+ *
+ * This gets the APIC_BASE msr as it was on the last exit to userspace.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \return APIC_BASE msr contents
+ */
+uint64_t kvm_get_apic_base(kvm_vcpu_context_t vcpu);
+
+/*!
+ * \brief Check if a vcpu is ready for interrupt injection
+ *
+ * This checks if vcpu interrupts are not masked by mov ss or sti.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \return boolean indicating interrupt injection readiness
+ */
+int kvm_is_ready_for_interrupt_injection(kvm_vcpu_context_t vcpu);
+
+/*!
+ * \brief Read VCPU registers
+ *
+ * This gets the GP registers from the VCPU and outputs them
+ * into a kvm_regs structure
+ *
+ * \note This function returns a \b copy of the VCPUs registers.\n
+ * If you wish to modify the VCPUs GP registers, you should call kvm_set_regs()
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \param regs Pointer to a kvm_regs which will be populated with the VCPUs
+ * registers values
+ * \return 0 on success
+ */
+int kvm_get_regs(kvm_vcpu_context_t vcpu, struct kvm_regs *regs);
+
+/*!
+ * \brief Write VCPU registers
+ *
+ * This sets the GP registers on the VCPU from a kvm_regs structure
+ *
+ * \note When this function returns, the regs pointer and the data it points to
+ * can be discarded
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \param regs Pointer to a kvm_regs which will be populated with the VCPUs
+ * registers values
+ * \return 0 on success
+ */
+int kvm_set_regs(kvm_vcpu_context_t vcpu, struct kvm_regs *regs);
+/*!
+ * \brief Read VCPU fpu registers
+ *
+ * This gets the FPU registers from the VCPU and outputs them
+ * into a kvm_fpu structure
+ *
+ * \note This function returns a \b copy of the VCPUs registers.\n
+ * If you wish to modify the VCPU FPU registers, you should call kvm_set_fpu()
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \param fpu Pointer to a kvm_fpu which will be populated with the VCPUs
+ * fpu registers values
+ * \return 0 on success
+ */
+int kvm_get_fpu(kvm_vcpu_context_t vcpu, struct kvm_fpu *fpu);
+
+/*!
+ * \brief Write VCPU fpu registers
+ *
+ * This sets the FPU registers on the VCPU from a kvm_fpu structure
+ *
+ * \note When this function returns, the fpu pointer and the data it points to
+ * can be discarded
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \param fpu Pointer to a kvm_fpu which holds the new vcpu fpu state
+ * \return 0 on success
+ */
+int kvm_set_fpu(kvm_vcpu_context_t vcpu, struct kvm_fpu *fpu);
+
+/*!
+ * \brief Read VCPU system registers
+ *
+ * This gets the non-GP registers from the VCPU and outputs them
+ * into a kvm_sregs structure
+ *
+ * \note This function returns a \b copy of the VCPUs registers.\n
+ * If you wish to modify the VCPUs non-GP registers, you should call
+ * kvm_set_sregs()
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \param regs Pointer to a kvm_sregs which will be populated with the VCPUs
+ * registers values
+ * \return 0 on success
+ */
+int kvm_get_sregs(kvm_vcpu_context_t vcpu, struct kvm_sregs *regs);
+
+/*!
+ * \brief Write VCPU system registers
+ *
+ * This sets the non-GP registers on the VCPU from a kvm_sregs structure
+ *
+ * \note When this function returns, the regs pointer and the data it points to
+ * can be discarded
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \param regs Pointer to a kvm_sregs which will be populated with the VCPUs
+ * registers values
+ * \return 0 on success
+ */
+int kvm_set_sregs(kvm_vcpu_context_t vcpu, struct kvm_sregs *regs);
+
+#ifdef KVM_CAP_MP_STATE
+/*!
+ *  * \brief Read VCPU MP state
+ *
+ */
+int kvm_get_mpstate(kvm_vcpu_context_t vcpu, struct kvm_mp_state *mp_state);
+
+/*!
+ *  * \brief Write VCPU MP state
+ *
+ */
+int kvm_set_mpstate(kvm_vcpu_context_t vcpu, struct kvm_mp_state *mp_state);
+/*!
+ *  * \brief Reset VCPU MP state
+ *
+ */
+static inline int kvm_reset_mpstate(kvm_vcpu_context_t vcpu)
+{
+    struct kvm_mp_state mp_state = {.mp_state = KVM_MP_STATE_UNINITIALIZED};
+    return kvm_set_mpstate(vcpu, &mp_state);
+}
+#endif
+
+/*!
+ * \brief Simulate an external vectored interrupt
+ *
+ * This allows you to simulate an external vectored interrupt.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \param irq Vector number
+ * \return 0 on success
+ */
+int kvm_inject_irq(kvm_vcpu_context_t vcpu, unsigned irq);
+
+#ifdef KVM_CAP_SET_GUEST_DEBUG
+int kvm_set_guest_debug(kvm_vcpu_context_t, struct kvm_guest_debug *dbg);
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+/*!
+ * \brief Setup a vcpu's cpuid instruction emulation
+ *
+ * Set up a table of cpuid function to cpuid outputs.\n
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should be initialized
+ * \param nent number of entries to be installed
+ * \param entries cpuid function entries table
+ * \return 0 on success, or -errno on error
+ */
+int kvm_setup_cpuid(kvm_vcpu_context_t vcpu, int nent,
+		    struct kvm_cpuid_entry *entries);
+
+/*!
+ * \brief Setup a vcpu's cpuid instruction emulation
+ *
+ * Set up a table of cpuid function to cpuid outputs.
+ * This call replaces the older kvm_setup_cpuid interface by adding a few
+ * parameters to support cpuid functions that have sub-leaf values.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should be initialized
+ * \param nent number of entries to be installed
+ * \param entries cpuid function entries table
+ * \return 0 on success, or -errno on error
+ */
+int kvm_setup_cpuid2(kvm_vcpu_context_t vcpu, int nent,
+		     struct kvm_cpuid_entry2 *entries);
+
+/*!
+ * \brief Setting the number of shadow pages to be allocated to the vm
+ *
+ * \param kvm pointer to kvm_context
+ * \param nrshadow_pages number of pages to be allocated
+ */
+int kvm_set_shadow_pages(kvm_context_t kvm, unsigned int nrshadow_pages);
+
+/*!
+ * \brief Getting the number of shadow pages that are allocated to the vm
+ *
+ * \param kvm pointer to kvm_context
+ * \param nrshadow_pages number of pages to be allocated
+ */
+int kvm_get_shadow_pages(kvm_context_t kvm , unsigned int *nrshadow_pages);
+
+/*!
+ * \brief Set up cr8 for next time the vcpu is executed
+ *
+ * This is a fast setter for cr8, which will be applied when the
+ * vcpu next enters guest mode.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \param cr8 next cr8 value
+ */
+void kvm_set_cr8(kvm_vcpu_context_t vcpu, uint64_t cr8);
+
+/*!
+ * \brief Get cr8 for sync tpr in qemu apic emulation
+ *
+ * This is a getter for cr8, which used to sync with the tpr in qemu
+ * apic emualtion.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ */
+__u64 kvm_get_cr8(kvm_vcpu_context_t vcpu);
+#endif
+
+/*!
+ * \brief Set a vcpu's signal mask for guest mode
+ *
+ * A vcpu can have different signals blocked in guest mode and user mode.
+ * This allows guest execution to be interrupted on a signal, without requiring
+ * that the signal be delivered to a signal handler (the signal can be
+ * dequeued using sigwait(2).
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should be initialized
+ * \param sigset signal mask for guest mode
+ * \return 0 on success, or -errno on error
+ */
+int kvm_set_signal_mask(kvm_vcpu_context_t vcpu, const sigset_t *sigset);
+
+/*!
+ * \brief Dump VCPU registers
+ *
+ * This dumps some of the information that KVM has about a virtual CPU, namely:
+ * - GP Registers
+ *
+ * A much more verbose version of this is available as kvm_dump_vcpu()
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \return 0 on success
+ */
+void kvm_show_regs(kvm_vcpu_context_t vcpu);
+
+
+void *kvm_create_phys_mem(kvm_context_t, unsigned long phys_start,
+			  unsigned long len, int log, int writable);
+void kvm_destroy_phys_mem(kvm_context_t, unsigned long phys_start,
+			  unsigned long len);
+void kvm_unregister_memory_area(kvm_context_t, uint64_t phys_start,
+                                unsigned long len);
+
+int kvm_is_containing_region(kvm_context_t kvm, unsigned long phys_start, unsigned long size);
+int kvm_register_phys_mem(kvm_context_t kvm,
+			unsigned long phys_start, void *userspace_addr,
+			unsigned long len, int log);
+int kvm_get_dirty_pages(kvm_context_t, unsigned long phys_addr, void *buf);
+int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
+			      unsigned long end_addr, void*opaque,
+			      int (*cb)(unsigned long start, unsigned long len,
+					void*bitmap, void *opaque));
+int kvm_register_coalesced_mmio(kvm_context_t kvm,
+				uint64_t addr, uint32_t size);
+int kvm_unregister_coalesced_mmio(kvm_context_t kvm,
+				  uint64_t addr, uint32_t size);
+
+/*!
+ * \brief Create a memory alias
+ *
+ * Aliases a portion of physical memory to another portion.  If the guest
+ * accesses the alias region, it will behave exactly as if it accessed
+ * the target memory.
+ */
+int kvm_create_memory_alias(kvm_context_t,
+			    uint64_t phys_start, uint64_t len,
+			    uint64_t target_phys);
+
+/*!
+ * \brief Destroy a memory alias
+ *
+ * Removes an alias created with kvm_create_memory_alias().
+ */
+int kvm_destroy_memory_alias(kvm_context_t, uint64_t phys_start);
+
+/*!
+ * \brief Get a bitmap of guest ram pages which are allocated to the guest.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param phys_addr Memory slot phys addr
+ * \param bitmap Long aligned address of a big enough bitmap (one bit per page)
+ */
+int kvm_get_mem_map(kvm_context_t kvm, unsigned long phys_addr, void *bitmap);
+int kvm_get_mem_map_range(kvm_context_t kvm, unsigned long phys_addr,
+			   unsigned long len, void *buf, void *opaque,
+			   int (*cb)(unsigned long start,unsigned long len,
+				     void* bitmap, void* opaque));
+int kvm_set_irq_level(kvm_context_t kvm, int irq, int level, int *status);
+
+int kvm_dirty_pages_log_enable_slot(kvm_context_t kvm,
+				    uint64_t phys_start,
+				    uint64_t len);
+int kvm_dirty_pages_log_disable_slot(kvm_context_t kvm,
+				     uint64_t phys_start,
+				     uint64_t len);
+/*!
+ * \brief Enable dirty-pages-logging for all memory regions
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_dirty_pages_log_enable_all(kvm_context_t kvm);
+
+/*!
+ * \brief Disable dirty-page-logging for some memory regions
+ *
+ * Disable dirty-pages-logging for those memory regions that were
+ * created with dirty-page-logging disabled.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_dirty_pages_log_reset(kvm_context_t kvm);
+
+/*!
+ * \brief Query whether in kernel irqchip is used
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_irqchip_in_kernel(kvm_context_t kvm);
+
+#ifdef KVM_CAP_IRQCHIP
+/*!
+ * \brief Dump in kernel IRQCHIP contents
+ *
+ * Dump one of the in kernel irq chip devices, including PIC (master/slave)
+ * and IOAPIC into a kvm_irqchip structure
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param chip The irq chip device to be dumped
+ */
+int kvm_get_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip);
+
+/*!
+ * \brief Set in kernel IRQCHIP contents
+ *
+ * Write one of the in kernel irq chip devices, including PIC (master/slave)
+ * and IOAPIC
+ *
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param chip THe irq chip device to be written
+ */
+int kvm_set_irqchip(kvm_context_t kvm, struct kvm_irqchip *chip);
+
+#if defined(__i386__) || defined(__x86_64__)
+/*!
+ * \brief Get in kernel local APIC for vcpu
+ *
+ * Save the local apic state including the timer of a virtual CPU
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should be accessed
+ * \param s Local apic state of the specific virtual CPU
+ */
+int kvm_get_lapic(kvm_vcpu_context_t vcpu, struct kvm_lapic_state *s);
+
+/*!
+ * \brief Set in kernel local APIC for vcpu
+ *
+ * Restore the local apic state including the timer of a virtual CPU
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should be accessed
+ * \param s Local apic state of the specific virtual CPU
+ */
+int kvm_set_lapic(kvm_vcpu_context_t vcpu, struct kvm_lapic_state *s);
+
+#endif
+
+/*!
+ * \brief Simulate an NMI
+ *
+ * This allows you to simulate a non-maskable interrupt.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu Which virtual CPU should get dumped
+ * \return 0 on success
+ */
+int kvm_inject_nmi(kvm_vcpu_context_t vcpu);
+
+#endif
+
+/*!
+ * \brief Query wheather in kernel pit is used
+ *
+ *  \param kvm Pointer to the current kvm_context
+ */
+int kvm_pit_in_kernel(kvm_context_t kvm);
+
+/*!
+ * \brief Initialize coalesced MMIO
+ *
+ * Check for coalesced MMIO capability and store in context
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_init_coalesced_mmio(kvm_context_t kvm);
+
+#ifdef KVM_CAP_PIT
+
+#if defined(__i386__) || defined(__x86_64__)
+/*!
+ * \brief Get in kernel PIT of the virtual domain
+ *
+ * Save the PIT state.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param s PIT state of the virtual domain
+ */
+int kvm_get_pit(kvm_context_t kvm, struct kvm_pit_state *s);
+
+/*!
+ * \brief Set in kernel PIT of the virtual domain
+ *
+ * Restore the PIT state.
+ * Timer would be retriggerred after restored.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param s PIT state of the virtual domain
+ */
+int kvm_set_pit(kvm_context_t kvm, struct kvm_pit_state *s);
+#endif
+
+int kvm_reinject_control(kvm_context_t kvm, int pit_reinject);
+
+#endif
+
+#ifdef KVM_CAP_VAPIC
+
+/*!
+ * \brief Enable kernel tpr access reporting
+ *
+ * When tpr access reporting is enabled, the kernel will call the
+ * ->tpr_access() callback every time the guest vcpu accesses the tpr.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu vcpu to enable tpr access reporting on
+ */
+int kvm_enable_tpr_access_reporting(kvm_vcpu_context_t vcpu);
+
+/*!
+ * \brief Disable kernel tpr access reporting
+ *
+ * Undoes the effect of kvm_enable_tpr_access_reporting().
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param vcpu vcpu to disable tpr access reporting on
+ */
+int kvm_disable_tpr_access_reporting(kvm_vcpu_context_t vcpu);
+
+int kvm_enable_vapic(kvm_vcpu_context_t vcpu, uint64_t vapic);
+
+#endif
+
+#if defined(__s390__)
+int kvm_s390_initial_reset(kvm_context_t kvm, int slot);
+int kvm_s390_interrupt(kvm_context_t kvm, int slot,
+	struct kvm_s390_interrupt *kvmint);
+int kvm_s390_set_initial_psw(kvm_context_t kvm, int slot, psw_t psw);
+int kvm_s390_store_status(kvm_context_t kvm, int slot, unsigned long addr);
+#endif
+
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+/*!
+ * \brief Notifies host kernel about a PCI device to be assigned to a guest
+ *
+ * Used for PCI device assignment, this function notifies the host
+ * kernel about the assigning of the physical PCI device to a guest.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param assigned_dev Parameters, like bus, devfn number, etc
+ */
+int kvm_assign_pci_device(kvm_context_t kvm,
+			  struct kvm_assigned_pci_dev *assigned_dev);
+
+/*!
+ * \brief Assign IRQ for an assigned device
+ *
+ * Used for PCI device assignment, this function assigns IRQ numbers for
+ * an physical device and guest IRQ handling.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param assigned_irq Parameters, like dev id, host irq, guest irq, etc
+ */
+int kvm_assign_irq(kvm_context_t kvm,
+		   struct kvm_assigned_irq *assigned_irq);
+
+#ifdef KVM_CAP_ASSIGN_DEV_IRQ
+/*!
+ * \brief Deassign IRQ for an assigned device
+ *
+ * Used for PCI device assignment, this function deassigns IRQ numbers
+ * for an assigned device.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param assigned_irq Parameters, like dev id, host irq, guest irq, etc
+ */
+int kvm_deassign_irq(kvm_context_t kvm,
+                   struct kvm_assigned_irq *assigned_irq);
+#endif
+#endif
+
+/*!
+ * \brief Determines whether destroying memory regions is allowed
+ *
+ * KVM before 2.6.29 had a bug when destroying memory regions.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_destroy_memory_region_works(kvm_context_t kvm);
+
+#ifdef KVM_CAP_DEVICE_DEASSIGNMENT
+/*!
+ * \brief Notifies host kernel about a PCI device to be deassigned from a guest
+ *
+ * Used for hot remove PCI device, this function notifies the host
+ * kernel about the deassigning of the physical PCI device from a guest.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param assigned_dev Parameters, like bus, devfn number, etc
+ */
+int kvm_deassign_pci_device(kvm_context_t kvm,
+			    struct kvm_assigned_pci_dev *assigned_dev);
+#endif
+
+/*!
+ * \brief Checks whether the generic irq routing capability is present
+ *
+ * Checks whether kvm can reroute interrupts among the various interrupt
+ * controllers.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_has_gsi_routing(kvm_context_t kvm);
+
+/*!
+ * \brief Determines the number of gsis that can be routed
+ *
+ * Returns the number of distinct gsis that can be routed by kvm.  This is
+ * also the number of distinct routes (if a gsi has two routes, than another
+ * gsi cannot be used...)
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_get_gsi_count(kvm_context_t kvm);
+
+/*!
+ * \brief Clears the temporary irq routing table
+ *
+ * Clears the temporary irq routing table.  Nothing is committed to the
+ * running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_clear_gsi_routes(kvm_context_t kvm);
+
+/*!
+ * \brief Adds an irq route to the temporary irq routing table
+ *
+ * Adds an irq route to the temporary irq routing table.  Nothing is
+ * committed to the running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_add_irq_route(kvm_context_t kvm, int gsi, int irqchip, int pin);
+
+/*!
+ * \brief Removes an irq route from the temporary irq routing table
+ *
+ * Adds an irq route to the temporary irq routing table.  Nothing is
+ * committed to the running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_del_irq_route(kvm_context_t kvm, int gsi, int irqchip, int pin);
+
+struct kvm_irq_routing_entry;
+/*!
+ * \brief Adds a routing entry to the temporary irq routing table
+ *
+ * Adds a filled routing entry to the temporary irq routing table. Nothing is
+ * committed to the running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_add_routing_entry(kvm_context_t kvm,
+                          struct kvm_irq_routing_entry* entry);
+
+/*!
+ * \brief Removes a routing from the temporary irq routing table
+ *
+ * Remove a routing to the temporary irq routing table.  Nothing is
+ * committed to the running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_del_routing_entry(kvm_context_t kvm,
+		          struct kvm_irq_routing_entry* entry);
+
+/*!
+ * \brief Updates a routing in the temporary irq routing table
+ *
+ * Update a routing in the temporary irq routing table
+ * with a new value. entry type and GSI can not be changed.
+ * Nothing is committed to the running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_update_routing_entry(kvm_context_t kvm,
+                             struct kvm_irq_routing_entry* entry,
+                             struct kvm_irq_routing_entry* newentry
+);
+
+/*!
+ * \brief Commit the temporary irq routing table
+ *
+ * Commit the temporary irq routing table to the running VM.
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_commit_irq_routes(kvm_context_t kvm);
+
+/*!
+ * \brief Get unused GSI number for irq routing table
+ *
+ * Get unused GSI number for irq routing table
+ *
+ * \param kvm Pointer to the current kvm_context
+ */
+int kvm_get_irq_route_gsi(kvm_context_t kvm);
+
+/*!
+ * \brief Create a file descriptor for injecting interrupts
+ *
+ * Creates an eventfd based file-descriptor that maps to a specific GSI
+ * in the guest.  eventfd compliant signaling (write() from userspace, or
+ * eventfd_signal() from kernelspace) will cause the GSI to inject
+ * itself into the guest at the next available window.
+ *
+ * \param kvm Pointer to the current kvm_context
+ * \param gsi GSI to assign to this fd
+ * \param flags reserved, must be zero
+ */
+int kvm_irqfd(kvm_context_t kvm, int gsi, int flags);
+
+#ifdef KVM_CAP_DEVICE_MSIX
+int kvm_assign_set_msix_nr(kvm_context_t kvm,
+			   struct kvm_assigned_msix_nr *msix_nr);
+int kvm_assign_set_msix_entry(kvm_context_t kvm,
+                              struct kvm_assigned_msix_entry *entry);
+#endif
+
+uint32_t kvm_get_supported_cpuid(kvm_context_t kvm, uint32_t function, int reg);
+
+#else /* !CONFIG_KVM */
+
+struct kvm_pit_state { };
+
+#endif /* CONFIG_KVM */
 
 int kvm_main_loop(void);
 int kvm_qemu_init(void);
diff --git a/target-i386/libkvm.h b/target-i386/libkvm.h
index f3fc6dc..d85b6a1 100644
--- a/target-i386/libkvm.h
+++ b/target-i386/libkvm.h
@@ -18,8 +18,6 @@
 #ifndef KVM_X86_H
 #define KVM_X86_H
 
-#include "libkvm-all.h"
-
 #define PAGE_SIZE 4096ul
 #define PAGE_MASK (~(PAGE_SIZE - 1))
 
-- 
1.6.2.2


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

* [PATCH v2 6/9] duplicate KVMState
  2009-07-10 20:17         ` [PATCH v2 5/9] fold libkvm-all into standard qemu header Glauber Costa
@ 2009-07-10 20:17           ` Glauber Costa
  2009-07-10 20:17             ` [PATCH v2 7/9] provide env->kvm_fd Glauber Costa
  0 siblings, 1 reply; 12+ messages in thread
From: Glauber Costa @ 2009-07-10 20:17 UTC (permalink / raw)
  To: kvm; +Cc: avi

In this patch, we duplicate most of KVMState in our files. This should be
removed later, when they are 100 % equal. Meanwhile, we fold our kvm_context_t
structure inside it.

To make transition smooth, we still keep a global variable kvm_context
pointing to its position inside the global KVMState. This way we don't
need to hurry about changing all callers.

kvm_init() and kvm_finalize are changed, though, since they have now to
deal with the creation/destruction of a global KVMState

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 qemu-kvm.c |   61 +++++++++++++++++++++++++++--------------------------------
 qemu-kvm.h |   36 +++++++++++++++++++++++-----------
 vl.c       |    2 +-
 3 files changed, 53 insertions(+), 46 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index 32e903a..e15956a 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -42,6 +42,9 @@ int kvm_irqchip = 1;
 int kvm_pit = 1;
 int kvm_pit_reinject = 1;
 int kvm_nested = 0;
+
+
+static KVMState *kvm_state;
 kvm_context_t kvm_context;
 
 pthread_mutex_t qemu_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -416,16 +419,16 @@ int kvm_dirty_pages_log_reset(kvm_context_t kvm)
 }
 
 
-kvm_context_t kvm_init(void *opaque)
+int kvm_init(int smp_cpus)
 {
 	int fd;
-	kvm_context_t kvm;
 	int r, gsi_count;
 
+
 	fd = open("/dev/kvm", O_RDWR);
 	if (fd == -1) {
 		perror("open /dev/kvm");
-		return NULL;
+		return -1;
 	}
 	r = ioctl(fd, KVM_GET_API_VERSION, 0);
 	if (r == -1) {
@@ -446,35 +449,39 @@ kvm_context_t kvm_init(void *opaque)
 	}
 	kvm_abi = r;
 	kvm_page_size = getpagesize();
-	kvm = qemu_mallocz(sizeof(*kvm));
-	kvm->fd = fd;
-	kvm->vm_fd = -1;
-	kvm->opaque = opaque;
-	kvm->dirty_pages_log_all = 0;
-	kvm->no_irqchip_creation = 0;
-	kvm->no_pit_creation = 0;
+	kvm_state = qemu_mallocz(sizeof(*kvm_state));
+    kvm_context = &kvm_state->kvm_context;
 
-	gsi_count = kvm_get_gsi_count(kvm);
+	kvm_context->fd = fd;
+	kvm_context->vm_fd = -1;
+	kvm_context->opaque = cpu_single_env;
+	kvm_context->dirty_pages_log_all = 0;
+	kvm_context->no_irqchip_creation = 0;
+	kvm_context->no_pit_creation = 0;
+
+	gsi_count = kvm_get_gsi_count(kvm_context);
 	if (gsi_count > 0) {
 		int gsi_bits, i;
 
 		/* Round up so we can search ints using ffs */
 		gsi_bits = ALIGN(gsi_count, 32);
-		kvm->used_gsi_bitmap = qemu_mallocz(gsi_bits / 8);
-		kvm->max_gsi = gsi_bits;
+		kvm_context->used_gsi_bitmap = qemu_mallocz(gsi_bits / 8);
+		kvm_context->max_gsi = gsi_bits;
 
 		/* Mark any over-allocated bits as already in use */
 		for (i = gsi_count; i < gsi_bits; i++)
-			set_gsi(kvm, i);
+			set_gsi(kvm_context, i);
 	}
 
-	return kvm;
+    pthread_mutex_lock(&qemu_mutex);
+	return 0;
+
  out_close:
 	close(fd);
-	return NULL;
+	return -1;
 }
 
-void kvm_finalize(kvm_context_t kvm)
+static void kvm_finalize(KVMState *s)
 {
 	/* FIXME
 	if (kvm->vcpu_fd[0] != -1)
@@ -482,8 +489,8 @@ void kvm_finalize(kvm_context_t kvm)
 	if (kvm->vm_fd != -1)
 		close(kvm->vm_fd);
 	*/
-	close(kvm->fd);
-	free(kvm);
+	close(s->kvm_context.fd);
+	free(s);
 }
 
 void kvm_disable_irqchip_creation(kvm_context_t kvm)
@@ -2197,18 +2204,6 @@ int kvm_main_loop(void)
     return 0;
 }
 
-int kvm_qemu_init()
-{
-    /* Try to initialize kvm */
-    kvm_context = kvm_init(cpu_single_env);
-    if (!kvm_context) {
-      	return -1;
-    }
-    pthread_mutex_lock(&qemu_mutex);
-
-    return 0;
-}
-
 #ifdef TARGET_I386
 static int destroy_region_works = 0;
 #endif
@@ -2232,12 +2227,12 @@ int kvm_qemu_create_context(void)
         kvm_disable_pit_creation(kvm_context);
     }
     if (kvm_create(kvm_context, 0, NULL) < 0) {
-       kvm_finalize(kvm_context);
+       kvm_finalize(kvm_state);
        return -1;
     }
     r = kvm_arch_qemu_create_context();
     if(r <0)
-       kvm_finalize(kvm_context);
+       kvm_finalize(kvm_state);
     if (kvm_pit && !kvm_pit_reinject) {
         if (kvm_reinject_control(kvm_context, 0)) {
             fprintf(stderr, "failure to disable in-kernel PIT reinjection\n");
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 43102a1..417622d 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -128,18 +128,7 @@ int kvm_set_msrs(kvm_vcpu_context_t, struct kvm_msr_entry *msrs, int n);
  * \param opaque Not used
  * \return NULL on failure
  */
-kvm_context_t kvm_init(void *opaque);
-
-/*!
- * \brief Cleanup the KVM context
- *
- * Should always be called when closing down KVM.\n
- * Exception: If kvm_init() fails, this function should not be called, as the
- * context would be invalid
- *
- * \param kvm Pointer to the kvm_context that is to be freed
- */
-void kvm_finalize(kvm_context_t kvm);
+int kvm_init(int smp_cpus);
 
 /*!
  * \brief Disable the in-kernel IRQCHIP creation
@@ -1125,4 +1114,27 @@ static inline int kvm_set_migration_log(int enable)
     return kvm_physical_memory_set_dirty_tracking(enable);
 }
 
+typedef struct KVMSlot
+{
+    target_phys_addr_t start_addr;
+    ram_addr_t memory_size;
+    ram_addr_t phys_offset;
+    int slot;
+    int flags;
+} KVMSlot;
+
+typedef struct kvm_dirty_log KVMDirtyLog;
+
+typedef struct KVMState
+{
+    KVMSlot slots[32];
+    int fd;
+    int vmfd;
+    int coalesced_mmio;
+    int broken_set_mem_region;
+    int migration_log;
+    struct kvm_context kvm_context;
+} KVMState;
+
+
 #endif
diff --git a/vl.c b/vl.c
index ae02ef7..b235538 100644
--- a/vl.c
+++ b/vl.c
@@ -5950,7 +5950,7 @@ int main(int argc, char **argv, char **envp)
 
 #ifdef CONFIG_KVM
     if (kvm_enabled()) {
-	if (kvm_qemu_init() < 0) {
+	if (kvm_init(smp_cpus) < 0) {
 	    fprintf(stderr, "Could not initialize KVM, will disable KVM support\n");
 #ifdef NO_CPU_EMULATION
 	    fprintf(stderr, "Compiled with --disable-cpu-emulation, exiting.\n");
-- 
1.6.2.2


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

* [PATCH v2 7/9] provide env->kvm_fd
  2009-07-10 20:17           ` [PATCH v2 6/9] duplicate KVMState Glauber Costa
@ 2009-07-10 20:17             ` Glauber Costa
  2009-07-10 20:17               ` [PATCH v2 8/9] use kvm_upstream sw_breakpoints structure Glauber Costa
  0 siblings, 1 reply; 12+ messages in thread
From: Glauber Costa @ 2009-07-10 20:17 UTC (permalink / raw)
  To: kvm; +Cc: avi

qemu upstream puts kvm information on env. Do that too, since it will
allow us to use CPUState in cpu-specific functions, instead of kvm-specific
types.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 qemu-kvm.c |    9 +++++++--
 qemu-kvm.h |    2 +-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index e15956a..beee038 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -503,11 +503,12 @@ void kvm_disable_pit_creation(kvm_context_t kvm)
 	kvm->no_pit_creation = 1;
 }
 
-kvm_vcpu_context_t kvm_create_vcpu(kvm_context_t kvm, int id)
+kvm_vcpu_context_t kvm_create_vcpu(CPUState *env, int id)
 {
 	long mmap_size;
 	int r;
 	kvm_vcpu_context_t vcpu_ctx = qemu_malloc(sizeof(struct kvm_vcpu_context));
+    kvm_context_t kvm = kvm_context;
 
 	vcpu_ctx->kvm = kvm;
 	vcpu_ctx->id = id;
@@ -518,6 +519,10 @@ kvm_vcpu_context_t kvm_create_vcpu(kvm_context_t kvm, int id)
 		goto err;
 	}
 	vcpu_ctx->fd = r;
+
+    env->kvm_fd = r;
+    env->kvm_state = kvm_state;
+
 	mmap_size = ioctl(kvm->fd, KVM_GET_VCPU_MMAP_SIZE, 0);
 	if (mmap_size == -1) {
 		fprintf(stderr, "get vcpu mmap size: %m\n");
@@ -2013,7 +2018,7 @@ static void *ap_main_loop(void *_env)
     env->thread_id = kvm_get_thread_id();
     sigfillset(&signals);
     sigprocmask(SIG_BLOCK, &signals, NULL);
-    env->kvm_cpu_state.vcpu_ctx = kvm_create_vcpu(kvm_context, env->cpu_index);
+    env->kvm_cpu_state.vcpu_ctx = kvm_create_vcpu(env, env->cpu_index);
 
 #ifdef USE_KVM_DEVICE_ASSIGNMENT
     /* do ioperm for io ports of assigned devices */
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 417622d..9d10cf6 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -181,7 +181,7 @@ void kvm_create_irqchip(kvm_context_t kvm);
  * \param slot vcpu number (> 0)
  * \return 0 on success, -errno on failure
  */
-kvm_vcpu_context_t kvm_create_vcpu(kvm_context_t kvm, int id);
+kvm_vcpu_context_t kvm_create_vcpu(CPUState *env, int id);
 
 /*!
  * \brief Start the VCPU
-- 
1.6.2.2


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

* [PATCH v2 8/9] use kvm_upstream sw_breakpoints structure
  2009-07-10 20:17             ` [PATCH v2 7/9] provide env->kvm_fd Glauber Costa
@ 2009-07-10 20:17               ` Glauber Costa
  2009-07-10 20:18                 ` [PATCH v2 9/9] reuse upstream breakpoint code Glauber Costa
  0 siblings, 1 reply; 12+ messages in thread
From: Glauber Costa @ 2009-07-10 20:17 UTC (permalink / raw)
  To: kvm; +Cc: avi

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 qemu-kvm-x86.c |    4 ++--
 qemu-kvm.c     |   27 ++++++++++++++++++---------
 qemu-kvm.h     |    9 ++++++---
 3 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 48b2e2f..f3890fe 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -1481,7 +1481,7 @@ int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
 			break;
 		    }
 	}
-    } else if (kvm_find_sw_breakpoint(arch_info->pc))
+    } else if (kvm_find_sw_breakpoint(cpu_single_env, arch_info->pc))
 	handle = 1;
 
     if (!handle)
@@ -1504,7 +1504,7 @@ void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
     };
     int n;
 
-    if (!TAILQ_EMPTY(&kvm_sw_breakpoints))
+    if (kvm_sw_breakpoints_active(env))
 	dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
 
     if (nb_hw_breakpoint > 0) {
diff --git a/qemu-kvm.c b/qemu-kvm.c
index beee038..490024e 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -459,6 +459,10 @@ int kvm_init(int smp_cpus)
 	kvm_context->no_irqchip_creation = 0;
 	kvm_context->no_pit_creation = 0;
 
+#ifdef KVM_CAP_SET_GUEST_DEBUG
+    TAILQ_INIT(&kvm_state->kvm_sw_breakpoints);
+#endif
+
 	gsi_count = kvm_get_gsi_count(kvm_context);
 	if (gsi_count > 0) {
 		int gsi_bits, i;
@@ -2419,14 +2423,13 @@ int kvm_qemu_init_env(CPUState *cenv)
 }
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
-struct kvm_sw_breakpoint_head kvm_sw_breakpoints =
-    TAILQ_HEAD_INITIALIZER(kvm_sw_breakpoints);
 
-struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(target_ulong pc)
+struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
+                                                 target_ulong pc)
 {
     struct kvm_sw_breakpoint *bp;
 
-    TAILQ_FOREACH(bp, &kvm_sw_breakpoints, entry) {
+    TAILQ_FOREACH(bp, &env->kvm_state->kvm_sw_breakpoints, entry) {
 	if (bp->pc == pc)
 	    return bp;
     }
@@ -2461,6 +2464,11 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
     return data.err;
 }
 
+int kvm_sw_breakpoints_active(CPUState *env)
+{
+    return !TAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints);
+}
+
 int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
                           target_ulong len, int type)
 {
@@ -2469,7 +2477,7 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
-	bp = kvm_find_sw_breakpoint(addr);
+	bp = kvm_find_sw_breakpoint(current_env, addr);
 	if (bp) {
 	    bp->use_count++;
 	    return 0;
@@ -2487,7 +2495,8 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
 	    return err;
 	}
 
-	TAILQ_INSERT_HEAD(&kvm_sw_breakpoints, bp, entry);
+    TAILQ_INSERT_HEAD(&current_env->kvm_state->kvm_sw_breakpoints,
+                      bp, entry);
     } else {
 	err = kvm_arch_insert_hw_breakpoint(addr, len, type);
 	if (err)
@@ -2510,7 +2519,7 @@ int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
-	bp = kvm_find_sw_breakpoint(addr);
+	bp = kvm_find_sw_breakpoint(current_env, addr);
 	if (!bp)
 	    return -ENOENT;
 
@@ -2523,7 +2532,7 @@ int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
 	if (err)
 	    return err;
 
-	TAILQ_REMOVE(&kvm_sw_breakpoints, bp, entry);
+	TAILQ_REMOVE(&current_env->kvm_state->kvm_sw_breakpoints, bp, entry);
 	qemu_free(bp);
     } else {
 	err = kvm_arch_remove_hw_breakpoint(addr, len, type);
@@ -2544,7 +2553,7 @@ void kvm_remove_all_breakpoints(CPUState *current_env)
     struct kvm_sw_breakpoint *bp, *next;
     CPUState *env;
 
-    TAILQ_FOREACH_SAFE(bp, &kvm_sw_breakpoints, entry, next) {
+    TAILQ_FOREACH_SAFE(bp, &current_env->kvm_state->kvm_sw_breakpoints, entry, next) {
         if (kvm_arch_remove_sw_breakpoint(current_env, bp) != 0) {
             /* Try harder to find a CPU that currently sees the breakpoint. */
             for (env = first_cpu; env != NULL; env = env->next_cpu) {
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 9d10cf6..b2c5c54 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -971,12 +971,12 @@ struct kvm_sw_breakpoint {
     int use_count;
     TAILQ_ENTRY(kvm_sw_breakpoint) entry;
 };
-TAILQ_HEAD(kvm_sw_breakpoint_head, kvm_sw_breakpoint);
 
-extern struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
+TAILQ_HEAD(kvm_sw_breakpoint_head, kvm_sw_breakpoint);
 
 int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info);
-struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(target_ulong pc);
+int kvm_sw_breakpoints_active(CPUState *env);
+struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env, target_ulong pc);
 int kvm_arch_insert_sw_breakpoint(CPUState *current_env,
                                   struct kvm_sw_breakpoint *bp);
 int kvm_arch_remove_sw_breakpoint(CPUState *current_env,
@@ -1133,6 +1133,9 @@ typedef struct KVMState
     int coalesced_mmio;
     int broken_set_mem_region;
     int migration_log;
+#ifdef KVM_CAP_SET_GUEST_DEBUG
+    struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
+#endif
     struct kvm_context kvm_context;
 } KVMState;
 
-- 
1.6.2.2


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

* [PATCH v2 9/9] reuse upstream breakpoint code
  2009-07-10 20:17               ` [PATCH v2 8/9] use kvm_upstream sw_breakpoints structure Glauber Costa
@ 2009-07-10 20:18                 ` Glauber Costa
  2009-07-12  9:30                   ` Gleb Natapov
  0 siblings, 1 reply; 12+ messages in thread
From: Glauber Costa @ 2009-07-10 20:18 UTC (permalink / raw)
  To: kvm; +Cc: avi, Jan Kiszka

Drop KVM_UPSTREAM around functions we intend to reuse.
This allow us to share code in kvm-all.c, that is equal in qemu-kvm.c

Signed-off-by: Glauber Costa <glommer@redhat.com>
CC: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c  |    5 ++-
 kvm.h      |    1 +
 qemu-kvm.c |  140 +-----------------------------------------------------------
 3 files changed, 6 insertions(+), 140 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index e42b1f6..67908a7 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -873,6 +873,8 @@ void kvm_setup_guest_memory(void *start, size_t size)
     }
 }
 
+#endif /* KVM_UPSTREAM */
+
 #ifdef KVM_CAP_SET_GUEST_DEBUG
 struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
                                                  target_ulong pc)
@@ -891,6 +893,7 @@ int kvm_sw_breakpoints_active(CPUState *env)
     return !TAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints);
 }
 
+#ifdef KVM_UPSTREAM
 int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
 {
     struct kvm_guest_debug dbg;
@@ -904,6 +907,7 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
 
     return kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg);
 }
+#endif
 
 int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
                           target_ulong len, int type)
@@ -1028,6 +1032,5 @@ void kvm_remove_all_breakpoints(CPUState *current_env)
 {
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
-#endif
 
 #include "qemu-kvm.c"
diff --git a/kvm.h b/kvm.h
index e9a43e2..0191752 100644
--- a/kvm.h
+++ b/kvm.h
@@ -16,6 +16,7 @@
 
 #include "config.h"
 #include "sys-queue.h"
+#include "qemu-kvm.h"
 
 #ifdef KVM_UPSTREAM
 
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 490024e..8778e6d 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -2424,18 +2424,6 @@ int kvm_qemu_init_env(CPUState *cenv)
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
 
-struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
-                                                 target_ulong pc)
-{
-    struct kvm_sw_breakpoint *bp;
-
-    TAILQ_FOREACH(bp, &env->kvm_state->kvm_sw_breakpoints, entry) {
-	if (bp->pc == pc)
-	    return bp;
-    }
-    return NULL;
-}
-
 struct kvm_set_guest_debug_data {
     struct kvm_guest_debug dbg;
     int err;
@@ -2464,133 +2452,7 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
     return data.err;
 }
 
-int kvm_sw_breakpoints_active(CPUState *env)
-{
-    return !TAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints);
-}
-
-int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
-                          target_ulong len, int type)
-{
-    struct kvm_sw_breakpoint *bp;
-    CPUState *env;
-    int err;
-
-    if (type == GDB_BREAKPOINT_SW) {
-	bp = kvm_find_sw_breakpoint(current_env, addr);
-	if (bp) {
-	    bp->use_count++;
-	    return 0;
-	}
-
-	bp = qemu_malloc(sizeof(struct kvm_sw_breakpoint));
-	if (!bp)
-	    return -ENOMEM;
-
-	bp->pc = addr;
-	bp->use_count = 1;
-	err = kvm_arch_insert_sw_breakpoint(current_env, bp);
-	if (err) {
-	    free(bp);
-	    return err;
-	}
-
-    TAILQ_INSERT_HEAD(&current_env->kvm_state->kvm_sw_breakpoints,
-                      bp, entry);
-    } else {
-	err = kvm_arch_insert_hw_breakpoint(addr, len, type);
-	if (err)
-	    return err;
-    }
-
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-	err = kvm_update_guest_debug(env, 0);
-	if (err)
-	    return err;
-    }
-    return 0;
-}
-
-int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
-                          target_ulong len, int type)
-{
-    struct kvm_sw_breakpoint *bp;
-    CPUState *env;
-    int err;
-
-    if (type == GDB_BREAKPOINT_SW) {
-	bp = kvm_find_sw_breakpoint(current_env, addr);
-	if (!bp)
-	    return -ENOENT;
-
-	if (bp->use_count > 1) {
-	    bp->use_count--;
-	    return 0;
-	}
-
-	err = kvm_arch_remove_sw_breakpoint(current_env, bp);
-	if (err)
-	    return err;
-
-	TAILQ_REMOVE(&current_env->kvm_state->kvm_sw_breakpoints, bp, entry);
-	qemu_free(bp);
-    } else {
-	err = kvm_arch_remove_hw_breakpoint(addr, len, type);
-	if (err)
-	    return err;
-    }
-
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-	err = kvm_update_guest_debug(env, 0);
-	if (err)
-	    return err;
-    }
-    return 0;
-}
-
-void kvm_remove_all_breakpoints(CPUState *current_env)
-{
-    struct kvm_sw_breakpoint *bp, *next;
-    CPUState *env;
-
-    TAILQ_FOREACH_SAFE(bp, &current_env->kvm_state->kvm_sw_breakpoints, entry, next) {
-        if (kvm_arch_remove_sw_breakpoint(current_env, bp) != 0) {
-            /* Try harder to find a CPU that currently sees the breakpoint. */
-            for (env = first_cpu; env != NULL; env = env->next_cpu) {
-                if (kvm_arch_remove_sw_breakpoint(env, bp) == 0)
-                    break;
-            }
-        }
-    }
-    kvm_arch_remove_all_hw_breakpoints();
-
-    for (env = first_cpu; env != NULL; env = env->next_cpu)
-	kvm_update_guest_debug(env, 0);
-}
-
-#else /* !KVM_CAP_SET_GUEST_DEBUG */
-
-int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
-{
-    return -EINVAL;
-}
-
-int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
-                          target_ulong len, int type)
-{
-    return -EINVAL;
-}
-
-int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
-                          target_ulong len, int type)
-{
-    return -EINVAL;
-}
-
-void kvm_remove_all_breakpoints(CPUState *current_env)
-{
-}
-#endif /* !KVM_CAP_SET_GUEST_DEBUG */
+#endif
 
 /*
  * dirty pages logging
-- 
1.6.2.2


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

* Re: [PATCH v2 0/9] Move closer to upstream
  2009-07-10 20:17 [PATCH v2 0/9] Move closer to upstream Glauber Costa
  2009-07-10 20:17 ` [PATCH v2 1/9] replace USE_KVM with CONFIG_KVM Glauber Costa
@ 2009-07-12  9:01 ` Avi Kivity
  1 sibling, 0 replies; 12+ messages in thread
From: Avi Kivity @ 2009-07-12  9:01 UTC (permalink / raw)
  To: Glauber Costa; +Cc: kvm

On 07/10/2009 11:17 PM, Glauber Costa wrote:
> Hi,
>
> This is another step at getting us closer to qemu upstream. I'm getting rid
> of USE_KVM, replacing it with the combination of KVM_UPSTREAM and CONFIG_KVM
>
> The goal is to slowly reduce that isolation. To demonstrate what I aim
> for, the last patches of the series shares code for breakpoint handling.
> next in my radar are ioctl functions and cpuid trimming.
>
> Have fun
>
> Changes from v1:
> * Include qemu-kvm.c and qemu-kvm-x86.c instead of folding it, as by gleb
>    suggestion.
> * duplicate structures that we need, to avoid messing with upstream, per
>    avi suggestion
> * drop KVM_UPSTREAM instead of moving code, per Jan suggestion
> * kvm_qemu_init() ->  kvm_init(smp_cpus), to get closer to upstream, per
>    glommer evil twin suggestion
>    

Doesn't apply, again due to the code movement patch.  Just use #includes 
again and leave me instructions for the actual folding.

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH v2 9/9] reuse upstream breakpoint code
  2009-07-10 20:18                 ` [PATCH v2 9/9] reuse upstream breakpoint code Glauber Costa
@ 2009-07-12  9:30                   ` Gleb Natapov
  0 siblings, 0 replies; 12+ messages in thread
From: Gleb Natapov @ 2009-07-12  9:30 UTC (permalink / raw)
  To: Glauber Costa; +Cc: kvm, avi, Jan Kiszka

On Fri, Jul 10, 2009 at 04:18:00PM -0400, Glauber Costa wrote:
> Drop KVM_UPSTREAM around functions we intend to reuse.
> This allow us to share code in kvm-all.c, that is equal in qemu-kvm.c
> 
Can we push on_vcpu() to upstream? Then we will be able to reuse
kvm_update_guest_debug() from upstream too.

> Signed-off-by: Glauber Costa <glommer@redhat.com>
> CC: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  kvm-all.c  |    5 ++-
>  kvm.h      |    1 +
>  qemu-kvm.c |  140 +-----------------------------------------------------------
>  3 files changed, 6 insertions(+), 140 deletions(-)
> 
> diff --git a/kvm-all.c b/kvm-all.c
> index e42b1f6..67908a7 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -873,6 +873,8 @@ void kvm_setup_guest_memory(void *start, size_t size)
>      }
>  }
>  
> +#endif /* KVM_UPSTREAM */
> +
>  #ifdef KVM_CAP_SET_GUEST_DEBUG
>  struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
>                                                   target_ulong pc)
> @@ -891,6 +893,7 @@ int kvm_sw_breakpoints_active(CPUState *env)
>      return !TAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints);
>  }
>  
> +#ifdef KVM_UPSTREAM
>  int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
>  {
>      struct kvm_guest_debug dbg;
> @@ -904,6 +907,7 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
>  
>      return kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg);
>  }
> +#endif
>  
>  int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
>                            target_ulong len, int type)
> @@ -1028,6 +1032,5 @@ void kvm_remove_all_breakpoints(CPUState *current_env)
>  {
>  }
>  #endif /* !KVM_CAP_SET_GUEST_DEBUG */
> -#endif
>  
>  #include "qemu-kvm.c"
> diff --git a/kvm.h b/kvm.h
> index e9a43e2..0191752 100644
> --- a/kvm.h
> +++ b/kvm.h
> @@ -16,6 +16,7 @@
>  
>  #include "config.h"
>  #include "sys-queue.h"
> +#include "qemu-kvm.h"
>  
>  #ifdef KVM_UPSTREAM
>  
> diff --git a/qemu-kvm.c b/qemu-kvm.c
> index 490024e..8778e6d 100644
> --- a/qemu-kvm.c
> +++ b/qemu-kvm.c
> @@ -2424,18 +2424,6 @@ int kvm_qemu_init_env(CPUState *cenv)
>  
>  #ifdef KVM_CAP_SET_GUEST_DEBUG
>  
> -struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
> -                                                 target_ulong pc)
> -{
> -    struct kvm_sw_breakpoint *bp;
> -
> -    TAILQ_FOREACH(bp, &env->kvm_state->kvm_sw_breakpoints, entry) {
> -	if (bp->pc == pc)
> -	    return bp;
> -    }
> -    return NULL;
> -}
> -
>  struct kvm_set_guest_debug_data {
>      struct kvm_guest_debug dbg;
>      int err;
> @@ -2464,133 +2452,7 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
>      return data.err;
>  }
>  
> -int kvm_sw_breakpoints_active(CPUState *env)
> -{
> -    return !TAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints);
> -}
> -
> -int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
> -                          target_ulong len, int type)
> -{
> -    struct kvm_sw_breakpoint *bp;
> -    CPUState *env;
> -    int err;
> -
> -    if (type == GDB_BREAKPOINT_SW) {
> -	bp = kvm_find_sw_breakpoint(current_env, addr);
> -	if (bp) {
> -	    bp->use_count++;
> -	    return 0;
> -	}
> -
> -	bp = qemu_malloc(sizeof(struct kvm_sw_breakpoint));
> -	if (!bp)
> -	    return -ENOMEM;
> -
> -	bp->pc = addr;
> -	bp->use_count = 1;
> -	err = kvm_arch_insert_sw_breakpoint(current_env, bp);
> -	if (err) {
> -	    free(bp);
> -	    return err;
> -	}
> -
> -    TAILQ_INSERT_HEAD(&current_env->kvm_state->kvm_sw_breakpoints,
> -                      bp, entry);
> -    } else {
> -	err = kvm_arch_insert_hw_breakpoint(addr, len, type);
> -	if (err)
> -	    return err;
> -    }
> -
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -	err = kvm_update_guest_debug(env, 0);
> -	if (err)
> -	    return err;
> -    }
> -    return 0;
> -}
> -
> -int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
> -                          target_ulong len, int type)
> -{
> -    struct kvm_sw_breakpoint *bp;
> -    CPUState *env;
> -    int err;
> -
> -    if (type == GDB_BREAKPOINT_SW) {
> -	bp = kvm_find_sw_breakpoint(current_env, addr);
> -	if (!bp)
> -	    return -ENOENT;
> -
> -	if (bp->use_count > 1) {
> -	    bp->use_count--;
> -	    return 0;
> -	}
> -
> -	err = kvm_arch_remove_sw_breakpoint(current_env, bp);
> -	if (err)
> -	    return err;
> -
> -	TAILQ_REMOVE(&current_env->kvm_state->kvm_sw_breakpoints, bp, entry);
> -	qemu_free(bp);
> -    } else {
> -	err = kvm_arch_remove_hw_breakpoint(addr, len, type);
> -	if (err)
> -	    return err;
> -    }
> -
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -	err = kvm_update_guest_debug(env, 0);
> -	if (err)
> -	    return err;
> -    }
> -    return 0;
> -}
> -
> -void kvm_remove_all_breakpoints(CPUState *current_env)
> -{
> -    struct kvm_sw_breakpoint *bp, *next;
> -    CPUState *env;
> -
> -    TAILQ_FOREACH_SAFE(bp, &current_env->kvm_state->kvm_sw_breakpoints, entry, next) {
> -        if (kvm_arch_remove_sw_breakpoint(current_env, bp) != 0) {
> -            /* Try harder to find a CPU that currently sees the breakpoint. */
> -            for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -                if (kvm_arch_remove_sw_breakpoint(env, bp) == 0)
> -                    break;
> -            }
> -        }
> -    }
> -    kvm_arch_remove_all_hw_breakpoints();
> -
> -    for (env = first_cpu; env != NULL; env = env->next_cpu)
> -	kvm_update_guest_debug(env, 0);
> -}
> -
> -#else /* !KVM_CAP_SET_GUEST_DEBUG */
> -
> -int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
> -{
> -    return -EINVAL;
> -}
> -
> -int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
> -                          target_ulong len, int type)
> -{
> -    return -EINVAL;
> -}
> -
> -int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
> -                          target_ulong len, int type)
> -{
> -    return -EINVAL;
> -}
> -
> -void kvm_remove_all_breakpoints(CPUState *current_env)
> -{
> -}
> -#endif /* !KVM_CAP_SET_GUEST_DEBUG */
> +#endif
>  
>  /*
>   * dirty pages logging
> -- 
> 1.6.2.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
			Gleb.

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

end of thread, other threads:[~2009-07-12  9:31 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-10 20:17 [PATCH v2 0/9] Move closer to upstream Glauber Costa
2009-07-10 20:17 ` [PATCH v2 1/9] replace USE_KVM with CONFIG_KVM Glauber Costa
2009-07-10 20:17   ` [PATCH v2 2/9] Do not compile qemu-kvm.c and qemu-kvm-x86.c Glauber Costa
2009-07-10 20:17     ` [PATCH v2 3/9] replace malloc with qemu_malloc Glauber Costa
2009-07-10 20:17       ` [PATCH v2 4/9] remove leftover: Glauber Costa
2009-07-10 20:17         ` [PATCH v2 5/9] fold libkvm-all into standard qemu header Glauber Costa
2009-07-10 20:17           ` [PATCH v2 6/9] duplicate KVMState Glauber Costa
2009-07-10 20:17             ` [PATCH v2 7/9] provide env->kvm_fd Glauber Costa
2009-07-10 20:17               ` [PATCH v2 8/9] use kvm_upstream sw_breakpoints structure Glauber Costa
2009-07-10 20:18                 ` [PATCH v2 9/9] reuse upstream breakpoint code Glauber Costa
2009-07-12  9:30                   ` Gleb Natapov
2009-07-12  9:01 ` [PATCH v2 0/9] Move closer to upstream Avi Kivity

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.