kvm.vger.kernel.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).