qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [5627] Add KVM support to QEMU
@ 2008-11-05 16:04 Anthony Liguori
  2008-11-05 16:19 ` andrzej zaborowski
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Anthony Liguori @ 2008-11-05 16:04 UTC (permalink / raw)
  To: qemu-devel

Revision: 5627
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5627
Author:   aliguori
Date:     2008-11-05 16:04:33 +0000 (Wed, 05 Nov 2008)

Log Message:
-----------
Add KVM support to QEMU

This patch adds very basic KVM support.  KVM is a kernel module for Linux that
allows userspace programs to make use of hardware virtualization support.  It
current supports x86 hardware virtualization using Intel VT-x or AMD-V.  It
also supports IA64 VT-i, PPC 440, and S390.

This patch only implements the bare minimum support to get a guest booting.  It
has very little impact the rest of QEMU and attempts to integrate nicely with
the rest of QEMU.

Even though this implementation is basic, it is significantly faster than TCG.
Booting and shutting down a Linux guest:

w/TCG:  1:32.36 elapsed  84% CPU

w/KVM:  0:31.14 elapsed  59% CPU

Right now, KVM is disabled by default and must be explicitly enabled with
 -enable-kvm.  We can enable it by default later when we have had better
testing.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Modified Paths:
--------------
    trunk/Makefile.target
    trunk/configure
    trunk/cpu-defs.h
    trunk/cpu-exec.c
    trunk/exec.c
    trunk/hw/acpi.c
    trunk/monitor.c
    trunk/target-i386/cpu.h
    trunk/target-i386/helper.c
    trunk/vl.c

Modified: trunk/Makefile.target
===================================================================
--- trunk/Makefile.target	2008-11-05 15:34:06 UTC (rev 5626)
+++ trunk/Makefile.target	2008-11-05 16:04:33 UTC (rev 5627)
@@ -183,6 +183,9 @@
 endif
 endif
 
+kvm.o: CFLAGS+=$(KVM_CFLAGS)
+kvm-all.o: CFLAGS+=$(KVM_CFLAGS)
+
 all: $(PROGS)
 
 #########################################################
@@ -581,6 +584,9 @@
 OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o net-checksum.o
 OBJS+=fw_cfg.o aio.o buffered_file.o migration.o migration-tcp.o qemu-char.o
 OBJS+=net.o
+ifdef CONFIG_KVM
+OBJS+=kvm.o kvm-all.o
+endif
 ifdef CONFIG_WIN32
 OBJS+=block-raw-win32.o
 else

Modified: trunk/configure
===================================================================
--- trunk/configure	2008-11-05 15:34:06 UTC (rev 5626)
+++ trunk/configure	2008-11-05 16:04:33 UTC (rev 5627)
@@ -115,6 +115,7 @@
 nptl="yes"
 mixemu="no"
 bluez="yes"
+kvm="yes"
 
 # OS specific
 targetos=`uname -s`
@@ -303,6 +304,8 @@
   ;;
   --disable-bluez) bluez="no"
   ;;
+  --disable-kvm) kvm="no"
+  ;;
   --enable-profiler) profiler="yes"
   ;;
   --enable-cocoa)
@@ -448,6 +451,7 @@
 echo "  --disable-vnc-tls        disable TLS encryption for VNC server"
 echo "  --disable-curses         disable curses output"
 echo "  --disable-bluez          disable bluez stack connectivity"
+echo "  --disable-kvm            disable KVM acceleration support"
 echo "  --disable-nptl           disable usermode NPTL support"
 echo "  --enable-system          enable all system emulation targets"
 echo "  --disable-system         disable all system emulation targets"
@@ -951,6 +955,30 @@
 fi
 
 ##########################################
+# kvm probe
+if test "$kvm" = "yes" ; then
+    cat > $TMPC <<EOF
+#include <linux/kvm.h>
+#if !defined(KVM_API_VERSION) || \
+    KVM_API_VERSION < 12 || \
+    KVM_API_VERSION > 12 || \
+    !defined(KVM_CAP_USER_MEMORY) || \
+    !defined(KVM_CAP_SET_TSS_ADDR)
+#error Invalid KVM version
+#endif
+int main(void) { return 0; }
+EOF
+  # FIXME make this configurable
+  kvm_cflags=-I/lib/modules/`uname -r`/build/include
+  if $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $kvm_cflags $TMPC \
+      2>/dev/null ; then
+    :
+  else
+    kvm="no"
+  fi
+fi
+
+##########################################
 # AIO probe
 if test "$aio" = "yes" ; then
   aio=no
@@ -1036,6 +1064,7 @@
 echo "NPTL support      $nptl"
 echo "vde support       $vde"
 echo "AIO support       $aio"
+echo "KVM support       $kvm"
 
 if test $sdl_too_old = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -1411,6 +1440,15 @@
 echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
 gdb_xml_files=""
 
+# FIXME allow i386 to build on x86_64 and vice versa
+if test "$kvm" = "yes" -a "$target_cpu" != "$cpu" ; then
+  kvm="no"
+fi
+# Disable KVM for linux-user
+if test "$kvm" = "yes" -a "$target_softmmu" = "no" ; then
+  kvm="no"
+fi
+
 case "$target_cpu" in
   i386)
     echo "TARGET_ARCH=i386" >> $config_mak
@@ -1420,6 +1458,11 @@
     then
       echo "#define USE_KQEMU 1" >> $config_h
     fi
+    if test "$kvm" = "yes" ; then
+      echo "CONFIG_KVM=yes" >> $config_mak
+      echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
+      echo "#define CONFIG_KVM" >> $config_h
+    fi
     gcc3minver=`$cc --version 2> /dev/null| fgrep "(GCC) 3." | awk '{ print $3 }' | cut -f2 -d.`
     if test -n "$gcc3minver" && test $gcc3minver -gt 3
     then
@@ -1437,6 +1480,11 @@
     then
       echo "#define USE_KQEMU 1" >> $config_h
     fi
+    if test "$kvm" = "yes" ; then
+      echo "CONFIG_KVM=yes" >> $config_mak
+      echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
+      echo "#define CONFIG_KVM 1" >> $config_h
+    fi
   ;;
   alpha)
     echo "TARGET_ARCH=alpha" >> $config_mak

Modified: trunk/cpu-defs.h
===================================================================
--- trunk/cpu-defs.h	2008-11-05 15:34:06 UTC (rev 5626)
+++ trunk/cpu-defs.h	2008-11-05 16:04:33 UTC (rev 5627)
@@ -142,6 +142,9 @@
 } icount_decr_u16;
 #endif
 
+struct kvm_run;
+struct KVMState;
+
 #define CPU_TEMP_BUF_NLONGS 128
 #define CPU_COMMON                                                      \
     struct TranslationBlock *current_tb; /* currently executing TB  */  \
@@ -199,6 +202,9 @@
     /* user data */                                                     \
     void *opaque;                                                       \
                                                                         \
-    const char *cpu_model_str;
+    const char *cpu_model_str;                                          \
+    struct KVMState *kvm_state;                                         \
+    struct kvm_run *kvm_run;                                            \
+    int kvm_fd;
 
 #endif

Modified: trunk/cpu-exec.c
===================================================================
--- trunk/cpu-exec.c	2008-11-05 15:34:06 UTC (rev 5626)
+++ trunk/cpu-exec.c	2008-11-05 16:04:33 UTC (rev 5627)
@@ -22,6 +22,7 @@
 #include "exec.h"
 #include "disas.h"
 #include "tcg.h"
+#include "kvm.h"
 
 #if !defined(CONFIG_SOFTMMU)
 #undef EAX
@@ -371,6 +372,19 @@
             }
 #endif
 
+            if (kvm_enabled()) {
+                int ret;
+                ret = kvm_cpu_exec(env);
+                if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) {
+                    env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
+                    env->exception_index = EXCP_INTERRUPT;
+                    cpu_loop_exit();
+                } else if (env->halted) {
+                    cpu_loop_exit();
+                } else
+                    longjmp(env->jmp_env, 1);
+            }
+
             next_tb = 0; /* force lookup of first TB */
             for(;;) {
                 interrupt_request = env->interrupt_request;

Modified: trunk/exec.c
===================================================================
--- trunk/exec.c	2008-11-05 15:34:06 UTC (rev 5626)
+++ trunk/exec.c	2008-11-05 16:04:33 UTC (rev 5627)
@@ -39,6 +39,7 @@
 #include "tcg.h"
 #include "hw/hw.h"
 #include "osdep.h"
+#include "kvm.h"
 #if defined(CONFIG_USER_ONLY)
 #include <qemu.h>
 #endif
@@ -2212,6 +2213,9 @@
         kqemu_set_phys_mem(start_addr, size, phys_offset);
     }
 #endif
+    if (kvm_enabled())
+        kvm_set_phys_mem(start_addr, size, phys_offset);
+
     size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
     end_addr = start_addr + (target_phys_addr_t)size;
     for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {

Modified: trunk/hw/acpi.c
===================================================================
--- trunk/hw/acpi.c	2008-11-05 15:34:06 UTC (rev 5626)
+++ trunk/hw/acpi.c	2008-11-05 16:04:33 UTC (rev 5627)
@@ -23,6 +23,7 @@
 #include "sysemu.h"
 #include "i2c.h"
 #include "smbus.h"
+#include "kvm.h"
 
 //#define DEBUG
 
@@ -501,6 +502,12 @@
 
     register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
 
+    if (kvm_enabled()) {
+        /* Mark SMM as already inited to prevent SMM from running.  KVM does not
+         * support SMM mode. */
+        pci_conf[0x5B] = 0x02;
+    }
+
     /* XXX: which specification is used ? The i82731AB has different
        mappings */
     pci_conf[0x5f] = (parallel_hds[0] != NULL ? 0x80 : 0) | 0x10;

Modified: trunk/monitor.c
===================================================================
--- trunk/monitor.c	2008-11-05 15:34:06 UTC (rev 5626)
+++ trunk/monitor.c	2008-11-05 16:04:33 UTC (rev 5627)
@@ -37,6 +37,7 @@
 #include <dirent.h>
 #include "qemu-timer.h"
 #include "migration.h"
+#include "kvm.h"
 
 //#define DEBUG
 //#define DEBUG_COMPLETION
@@ -1263,6 +1264,19 @@
 #endif
 }
 
+static void do_info_kvm(void)
+{
+#ifdef CONFIG_KVM
+    term_printf("kvm support: ");
+    if (kvm_enabled())
+	term_printf("enabled\n");
+    else
+	term_printf("disabled\n");
+#else
+    term_printf("kvm support: not compiled\n");
+#endif
+}
+
 #ifdef CONFIG_PROFILER
 
 int64_t kqemu_time;
@@ -1497,6 +1511,8 @@
       "", "show dynamic compiler info", },
     { "kqemu", "", do_info_kqemu,
       "", "show kqemu information", },
+    { "kvm", "", do_info_kvm,
+      "", "show kvm information", },
     { "usb", "", usb_info,
       "", "show guest USB devices", },
     { "usbhost", "", usb_host_info,

Modified: trunk/target-i386/cpu.h
===================================================================
--- trunk/target-i386/cpu.h	2008-11-05 15:34:06 UTC (rev 5626)
+++ trunk/target-i386/cpu.h	2008-11-05 16:04:33 UTC (rev 5627)
@@ -587,6 +587,8 @@
     target_ulong kernelgsbase;
 #endif
 
+    uint64_t tsc;
+
     uint64_t pat;
 
     /* exception/interrupt handling */
@@ -617,6 +619,10 @@
     int kqemu_enabled;
     int last_io_time;
 #endif
+
+    /* For KVM */
+    uint64_t interrupt_bitmap[256 / 64];
+
     /* in order to simplify APIC support, we leave this pointer to the
        user */
     struct APICState *apic_state;

Modified: trunk/target-i386/helper.c
===================================================================
--- trunk/target-i386/helper.c	2008-11-05 15:34:06 UTC (rev 5626)
+++ trunk/target-i386/helper.c	2008-11-05 16:04:33 UTC (rev 5627)
@@ -29,6 +29,7 @@
 #include "exec-all.h"
 #include "svm.h"
 #include "qemu-common.h"
+#include "kvm.h"
 
 //#define DEBUG_MMU
 
@@ -115,6 +116,8 @@
 #ifdef USE_KQEMU
     kqemu_init(env);
 #endif
+    if (kvm_enabled())
+        kvm_init_vcpu(env);
     return env;
 }
 
@@ -1288,6 +1291,40 @@
 }
 #endif /* !CONFIG_USER_ONLY */
 
+#if defined(CONFIG_KVM)
+static void host_cpuid(uint32_t function, uint32_t *eax, uint32_t *ebx,
+                       uint32_t *ecx, uint32_t *edx)
+{
+    uint32_t vec[4];
+
+#ifdef __x86_64__
+    asm volatile("cpuid"
+		 : "=a"(vec[0]), "=b"(vec[1]),
+		   "=c"(vec[2]), "=d"(vec[3])
+		 : "0"(function) : "cc");
+#else
+    asm volatile("pusha \n\t"
+		 "cpuid \n\t"
+		 "mov %%eax, 0(%1) \n\t"
+		 "mov %%ebx, 4(%1) \n\t"
+		 "mov %%ecx, 8(%1) \n\t"
+		 "mov %%edx, 12(%1) \n\t"
+		 "popa"
+		 : : "a"(function), "S"(vec)
+		 : "memory", "cc");
+#endif
+
+    if (eax)
+	*eax = vec[0];
+    if (ebx)
+	*ebx = vec[1];
+    if (ecx)
+	*ecx = vec[2];
+    if (edx)
+	*edx = vec[3];
+}
+#endif
+
 void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
                    uint32_t *eax, uint32_t *ebx,
                    uint32_t *ecx, uint32_t *edx)
@@ -1307,12 +1344,23 @@
         *ebx = env->cpuid_vendor1;
         *edx = env->cpuid_vendor2;
         *ecx = env->cpuid_vendor3;
+
+        /* sysenter isn't supported on compatibility mode on AMD.  and syscall
+         * isn't supported in compatibility mode on Intel.  so advertise the
+         * actuall cpu, and say goodbye to migration between different vendors
+         * is you use compatibility mode. */
+        if (kvm_enabled())
+            host_cpuid(0, NULL, ebx, ecx, edx);
         break;
     case 1:
         *eax = env->cpuid_version;
         *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
         *ecx = env->cpuid_ext_features;
         *edx = env->cpuid_features;
+
+        /* "Hypervisor present" bit required for Microsoft SVVP */
+        if (kvm_enabled())
+            *ecx |= (1 << 31);
         break;
     case 2:
         /* cache info: needed for Pentium Pro compatibility */
@@ -1390,6 +1438,31 @@
         *ebx = 0;
         *ecx = env->cpuid_ext3_features;
         *edx = env->cpuid_ext2_features;
+
+        if (kvm_enabled()) {
+            uint32_t h_eax, h_edx;
+
+            host_cpuid(0x80000001, &h_eax, NULL, NULL, &h_edx);
+
+            /* disable CPU features that the host does not support */
+
+            /* long mode */
+            if ((h_edx & 0x20000000) == 0 /* || !lm_capable_kernel */)
+                *edx &= ~0x20000000;
+            /* syscall */
+            if ((h_edx & 0x00000800) == 0)
+                *edx &= ~0x00000800;
+            /* nx */
+            if ((h_edx & 0x00100000) == 0)
+                *edx &= ~0x00100000;
+
+            /* disable CPU features that KVM cannot support */
+
+            /* svm */
+            *ecx &= ~4UL;
+            /* 3dnow */
+            *edx = ~0xc0000000;
+        }
         break;
     case 0x80000002:
     case 0x80000003:

Modified: trunk/vl.c
===================================================================
--- trunk/vl.c	2008-11-05 15:34:06 UTC (rev 5626)
+++ trunk/vl.c	2008-11-05 16:04:33 UTC (rev 5627)
@@ -39,6 +39,7 @@
 #include "block.h"
 #include "audio/audio.h"
 #include "migration.h"
+#include "kvm.h"
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -4782,6 +4783,9 @@
            "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
            "-no-kqemu       disable KQEMU kernel module usage\n"
 #endif
+#ifdef CONFIG_KVM
+           "-enable-kvm     enable KVM full virtualization support\n"
+#endif
 #ifdef TARGET_I386
            "-no-acpi        disable ACPI\n"
 #endif
@@ -4887,6 +4891,7 @@
     QEMU_OPTION_pidfile,
     QEMU_OPTION_no_kqemu,
     QEMU_OPTION_kernel_kqemu,
+    QEMU_OPTION_enable_kvm,
     QEMU_OPTION_win2k_hack,
     QEMU_OPTION_usb,
     QEMU_OPTION_usbdevice,
@@ -4973,6 +4978,9 @@
     { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
     { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
 #endif
+#ifdef CONFIG_KVM
+    { "enable-kvm", 0, QEMU_OPTION_enable_kvm },
+#endif
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
     { "g", 1, QEMU_OPTION_g },
 #endif
@@ -5794,6 +5802,14 @@
                 kqemu_allowed = 2;
                 break;
 #endif
+#ifdef CONFIG_KVM
+            case QEMU_OPTION_enable_kvm:
+                kvm_allowed = 1;
+#ifdef USE_KQEMU
+                kqemu_allowed = 0;
+#endif
+                break;
+#endif
             case QEMU_OPTION_usb:
                 usb_enabled = 1;
                 break;
@@ -5928,6 +5944,14 @@
         }
     }
 
+#if defined(CONFIG_KVM) && defined(USE_KQEMU)
+    if (kvm_allowed && kqemu_allowed) {
+        fprintf(stderr,
+                "You can not enable both KVM and kqemu at the same time\n");
+        exit(1);
+    }
+#endif
+
     machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
     if (smp_cpus > machine->max_cpus) {
         fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
@@ -6229,6 +6253,16 @@
         }
     }
 
+    if (kvm_enabled()) {
+        int ret;
+
+        ret = kvm_init(smp_cpus);
+        if (ret < 0) {
+            fprintf(stderr, "failed to initialize KVM\n");
+            exit(1);
+        }
+    }
+
     machine->init(ram_size, vga_ram_size, boot_devices, ds,
                   kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
 

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

* Re: [Qemu-devel] [5627] Add KVM support to QEMU
  2008-11-05 16:04 [Qemu-devel] [5627] Add KVM support to QEMU Anthony Liguori
@ 2008-11-05 16:19 ` andrzej zaborowski
  2008-11-05 16:30   ` Anthony Liguori
  2008-11-05 18:34 ` [Qemu-devel] " Jan Kiszka
  2008-11-12 10:42 ` [Qemu-devel] " Christoph Hellwig
  2 siblings, 1 reply; 6+ messages in thread
From: andrzej zaborowski @ 2008-11-05 16:19 UTC (permalink / raw)
  To: qemu-devel

2008/11/5 Anthony Liguori <anthony@codemonkey.ws>:
> Revision: 5627
>          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5627
> Author:   aliguori
> Date:     2008-11-05 16:04:33 +0000 (Wed, 05 Nov 2008)
>
> Log Message:
> -----------
> Add KVM support to QEMU
>
> This patch adds very basic KVM support.  KVM is a kernel module for Linux that
> allows userspace programs to make use of hardware virtualization support.  It
> current supports x86 hardware virtualization using Intel VT-x or AMD-V.  It
> also supports IA64 VT-i, PPC 440, and S390.
>
> This patch only implements the bare minimum support to get a guest booting.  It
> has very little impact the rest of QEMU and attempts to integrate nicely with
> the rest of QEMU.
>
> Even though this implementation is basic, it is significantly faster than TCG.
> Booting and shutting down a Linux guest:
>
> w/TCG:  1:32.36 elapsed  84% CPU
>
> w/KVM:  0:31.14 elapsed  59% CPU
>
> Right now, KVM is disabled by default and must be explicitly enabled with
>  -enable-kvm.  We can enable it by default later when we have had better
> testing.
>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>
> Modified Paths:
> --------------
>    trunk/Makefile.target
>    trunk/configure
>    trunk/cpu-defs.h
>    trunk/cpu-exec.c
>    trunk/exec.c
>    trunk/hw/acpi.c
>    trunk/monitor.c
>    trunk/target-i386/cpu.h
>    trunk/target-i386/helper.c
>    trunk/vl.c
>
> Modified: trunk/Makefile.target
> ===================================================================
> --- trunk/Makefile.target       2008-11-05 15:34:06 UTC (rev 5626)
> +++ trunk/Makefile.target       2008-11-05 16:04:33 UTC (rev 5627)
> @@ -183,6 +183,9 @@
>  endif
>  endif
>
> +kvm.o: CFLAGS+=$(KVM_CFLAGS)
> +kvm-all.o: CFLAGS+=$(KVM_CFLAGS)

The source seems to be missing, probably forgotten?

Cheers

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

* Re: [Qemu-devel] [5627] Add KVM support to QEMU
  2008-11-05 16:19 ` andrzej zaborowski
@ 2008-11-05 16:30   ` Anthony Liguori
  0 siblings, 0 replies; 6+ messages in thread
From: Anthony Liguori @ 2008-11-05 16:30 UTC (permalink / raw)
  To: qemu-devel

andrzej zaborowski wrote:
> 2008/11/5 Anthony Liguori <anthony@codemonkey.ws>:
>   
>>     
> The source seems to be missing, probably forgotten?
>   

Yeah, sorry about that.  I just fixed it.

Regards,

Anthony Liguori

> Cheers
>
>
>   

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

* [Qemu-devel] Re: [5627] Add KVM support to QEMU
  2008-11-05 16:04 [Qemu-devel] [5627] Add KVM support to QEMU Anthony Liguori
  2008-11-05 16:19 ` andrzej zaborowski
@ 2008-11-05 18:34 ` Jan Kiszka
  2008-11-12 10:42 ` [Qemu-devel] " Christoph Hellwig
  2 siblings, 0 replies; 6+ messages in thread
From: Jan Kiszka @ 2008-11-05 18:34 UTC (permalink / raw)
  To: qemu-devel

Anthony Liguori wrote:
> Revision: 5627
>           http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5627
> Author:   aliguori
> Date:     2008-11-05 16:04:33 +0000 (Wed, 05 Nov 2008)
> 
> Log Message:
> -----------
> Add KVM support to QEMU
> 

...

> Modified: trunk/target-i386/helper.c
> ===================================================================
> --- trunk/target-i386/helper.c	2008-11-05 15:34:06 UTC (rev 5626)
> +++ trunk/target-i386/helper.c	2008-11-05 16:04:33 UTC (rev 5627)
> @@ -29,6 +29,7 @@
>  #include "exec-all.h"
>  #include "svm.h"
>  #include "qemu-common.h"
> +#include "kvm.h"
>  
>  //#define DEBUG_MMU
>  
> @@ -115,6 +116,8 @@
>  #ifdef USE_KQEMU
>      kqemu_init(env);
>  #endif
> +    if (kvm_enabled())
> +        kvm_init_vcpu(env);
>      return env;
>  }
>  
> @@ -1288,6 +1291,40 @@
>  }
>  #endif /* !CONFIG_USER_ONLY */
>  
> +#if defined(CONFIG_KVM)
> +static void host_cpuid(uint32_t function, uint32_t *eax, uint32_t *ebx,
> +                       uint32_t *ecx, uint32_t *edx)
> +{
> +    uint32_t vec[4];
> +
> +#ifdef __x86_64__
> +    asm volatile("cpuid"
> +		 : "=a"(vec[0]), "=b"(vec[1]),
> +		   "=c"(vec[2]), "=d"(vec[3])
> +		 : "0"(function) : "cc");
> +#else
> +    asm volatile("pusha \n\t"
> +		 "cpuid \n\t"
> +		 "mov %%eax, 0(%1) \n\t"
> +		 "mov %%ebx, 4(%1) \n\t"
> +		 "mov %%ecx, 8(%1) \n\t"
> +		 "mov %%edx, 12(%1) \n\t"
> +		 "popa"
> +		 : : "a"(function), "S"(vec)
> +		 : "memory", "cc");
> +#endif
> +
> +    if (eax)
> +	*eax = vec[0];
> +    if (ebx)
> +	*ebx = vec[1];
> +    if (ecx)
> +	*ecx = vec[2];
> +    if (edx)
> +	*edx = vec[3];
> +}
> +#endif
> +

...and if KVM is disabled, let's keep the compiler happy:

------------>

Fix compiler warning for KVM-disabled case.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 target-i386/helper.c |    3 +++
 1 file changed, 3 insertions(+)

Index: b/target-i386/helper.c
===================================================================
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1323,6 +1323,9 @@ static void host_cpuid(uint32_t function
     if (edx)
 	*edx = vec[3];
 }
+#else
+static inline void host_cpuid(uint32_t function, uint32_t *eax, uint32_t *ebx,
+                              uint32_t *ecx, uint32_t *edx) { }
 #endif
 
 void cpu_x86_cpuid(CPUX86State *env, uint32_t index,

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

* Re: [Qemu-devel] [5627] Add KVM support to QEMU
  2008-11-05 16:04 [Qemu-devel] [5627] Add KVM support to QEMU Anthony Liguori
  2008-11-05 16:19 ` andrzej zaborowski
  2008-11-05 18:34 ` [Qemu-devel] " Jan Kiszka
@ 2008-11-12 10:42 ` Christoph Hellwig
  2008-11-13 19:56   ` Anthony Liguori
  2 siblings, 1 reply; 6+ messages in thread
From: Christoph Hellwig @ 2008-11-12 10:42 UTC (permalink / raw)
  To: qemu-devel

On Wed, Nov 05, 2008 at 04:04:33PM +0000, Anthony Liguori wrote:
> +# kvm probe
> +if test "$kvm" = "yes" ; then
> +    cat > $TMPC <<EOF
> +#include <linux/kvm.h>
> +#if !defined(KVM_API_VERSION) || \
> +    KVM_API_VERSION < 12 || \
> +    KVM_API_VERSION > 12 || \
> +    !defined(KVM_CAP_USER_MEMORY) || \
> +    !defined(KVM_CAP_SET_TSS_ADDR)
> +#error Invalid KVM version
> +#endif

The installed linux/kvm.h has no relatation at all to the currently
running kernel.   Please ship a current max API version kvm.h with qemu
and always build against that one, and handle lower API versions at
runtime.  Please don't turn mainline qemu kvm support into the same
bloody mess as the kvm userspace repository.

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

* Re: [Qemu-devel] [5627] Add KVM support to QEMU
  2008-11-12 10:42 ` [Qemu-devel] " Christoph Hellwig
@ 2008-11-13 19:56   ` Anthony Liguori
  0 siblings, 0 replies; 6+ messages in thread
From: Anthony Liguori @ 2008-11-13 19:56 UTC (permalink / raw)
  To: qemu-devel, Christoph Hellwig

Christoph Hellwig wrote:
> On Wed, Nov 05, 2008 at 04:04:33PM +0000, Anthony Liguori wrote:
>   
>> +# kvm probe
>> +if test "$kvm" = "yes" ; then
>> +    cat > $TMPC <<EOF
>> +#include <linux/kvm.h>
>> +#if !defined(KVM_API_VERSION) || \
>> +    KVM_API_VERSION < 12 || \
>> +    KVM_API_VERSION > 12 || \
>> +    !defined(KVM_CAP_USER_MEMORY) || \
>> +    !defined(KVM_CAP_SET_TSS_ADDR)
>> +#error Invalid KVM version
>> +#endif
>>     
>
> The installed linux/kvm.h has no relatation at all to the currently
> running kernel.   Please ship a current max API version kvm.h with qemu
> and always build against that one, and handle lower API versions at
> runtime.  Please don't turn mainline qemu kvm support into the same
> bloody mess as the kvm userspace repository.
>   

There are multiple places in QEMU that depend on kernel headers.  I 
don't want to stick kvm headers in QEMU while depending on external 
headers for USB pass through.  If someone wants to put together a patch 
to make QEMU no longer depend on external headers, I'd happily 
review/apply it.  I expect it to be tested on various kernel versions 
though.  Some less than wonderful kernel subsystems have not always been 
good about making interface changes backwards compatible.  linux-aio is 
a good example of an interface that makes it exceedingly difficult to 
detect whether a new feature is supported on any given kernel version 
without doing a compile test.

Regards,

Anthony Liguori

>
>   

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

end of thread, other threads:[~2008-11-13 19:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-05 16:04 [Qemu-devel] [5627] Add KVM support to QEMU Anthony Liguori
2008-11-05 16:19 ` andrzej zaborowski
2008-11-05 16:30   ` Anthony Liguori
2008-11-05 18:34 ` [Qemu-devel] " Jan Kiszka
2008-11-12 10:42 ` [Qemu-devel] " Christoph Hellwig
2008-11-13 19:56   ` Anthony Liguori

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).