Skip to contentSkip to conversation

Split up QEMU patches

PATCH Applied Anthony Liguori 2 participants 14 messages Nov 3, 2006 – Nov 5, 2006 7 messages not in the archive

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover Split up QEMU patches

This patch series splits up the qemu-kvm-1.patch into a series of patches. The goal is to isolate the KVM changes from general cleanup in order to simplify upstream submission. The final patch in the series also adds the ability to use KVM within a normal QEMU binary.

Regards,

Anthony Liguori

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw

PATCH 1/7 Compile fix for usb-linux.c

Simple patch adopted from Xen.

Regards,

Anthony Liguori

usb-linux.c +3 -1
diff -r 66fbe7668f97 usb-linux.c
@@ -26,7 +26,9 @@
 #if defined(__linux__)
 #include <dirent.h>
 #include <sys/ioctl.h>
-#include <linux/compiler.h>
+#ifndef __user
+#define __user
+#endif
 #include <linux/usbdevice_fs.h>
 #include <linux/version.h>
 

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#3 lore raw

PATCH 2/7 APIC save/restore fix

In reply to a message not in the archive

This apparently is already in QEMU CVS.

Regards,

Anthony Liguori

hw/apic.c +4 -0
diff -r 7b36a6ae02f3 hw/apic.c
@@ -745,6 +745,8 @@ static void apic_save(QEMUFile *f, void 
     qemu_put_be32s(f, &s->initial_count);
     qemu_put_be64s(f, &s->initial_count_load_time);
     qemu_put_be64s(f, &s->next_time);
+
+    qemu_put_timer(f, s->timer);
 }
 
 static int apic_load(QEMUFile *f, void *opaque, int version_id)
@@ -779,6 +781,8 @@ static int apic_load(QEMUFile *f, void *
     qemu_get_be32s(f, &s->initial_count);
     qemu_get_be64s(f, &s->initial_count_load_time);
     qemu_get_be64s(f, &s->next_time);
+
+    qemu_get_timer(f, s->timer);
     return 0;
 }
 

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#4 lore raw

PATCH 3/7 Timer save/restore fix

In reply to a message not in the archive

This is also in QEMU CVS.

Regards,

Anthony Liguori

vl.c +2 -0
diff -r dd0c57d03fb3 vl.c
@@ -822,6 +822,7 @@ static void timer_save(QEMUFile *f, void
     }
     qemu_put_be64s(f, &cpu_ticks_offset);
     qemu_put_be64s(f, &ticks_per_sec);
+    qemu_put_be64s(f, &cpu_clock_offset);
 }
 
 static int timer_load(QEMUFile *f, void *opaque, int version_id)
@@ -833,6 +834,7 @@ static int timer_load(QEMUFile *f, void 
     }
     qemu_get_be64s(f, &cpu_ticks_offset);
     qemu_get_be64s(f, &ticks_per_sec);
+    qemu_get_be64s(f, &cpu_clock_offset);
     return 0;
 }
 

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#5 lore raw

PATCH 4/7 gdbstub for x86-64

In reply to a message not in the archive

This is from Avi's original patch. Enables gdbstub for x86-64.

Regards,

Anthony Liguori

gdbstub.c +135 -1
diff -r 439455affc9a gdbstub.c
@@ -185,7 +185,141 @@ static int put_packet(GDBState *s, char 
     return 0;
 }
 
-#if defined(TARGET_I386)
+#if defined(TARGET_X86_64)
+
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+    uint8_t *p = mem_buf;
+    int i, fpus;
+
+#define PUTREG(x) do { \
+	target_ulong reg = tswapl(x); \
+	memcpy(p, &reg, sizeof reg); \
+	p += sizeof reg; \
+    } while (0)
+#define PUTREG32(x) do { \
+	uint32_t reg = tswap32(x);		\
+	memcpy(p, &reg, sizeof reg); \
+	p += sizeof reg; \
+    } while (0)
+#define PUTREGF(x) do { \
+	memcpy(p, &(x), 10);			\
+	p += sizeof (x);			\
+    } while (0)
+
+    PUTREG(env->regs[R_EAX]);
+    PUTREG(env->regs[R_EBX]);
+    PUTREG(env->regs[R_ECX]);
+    PUTREG(env->regs[R_EDX]);
+    PUTREG(env->regs[R_ESI]);
+    PUTREG(env->regs[R_EDI]);
+    PUTREG(env->regs[R_EBP]);
+    PUTREG(env->regs[R_ESP]);
+    PUTREG(env->regs[8]);
+    PUTREG(env->regs[9]);
+    PUTREG(env->regs[10]);
+    PUTREG(env->regs[11]);
+    PUTREG(env->regs[12]);
+    PUTREG(env->regs[13]);
+    PUTREG(env->regs[14]);
+    PUTREG(env->regs[15]);
+
+    PUTREG(env->eip);
+    PUTREG32(env->eflags);
+    PUTREG32(env->segs[R_CS].selector);
+    PUTREG32(env->segs[R_SS].selector);
+    PUTREG32(env->segs[R_DS].selector);
+    PUTREG32(env->segs[R_ES].selector);
+    PUTREG32(env->segs[R_FS].selector);
+    PUTREG32(env->segs[R_GS].selector);
+    /* XXX: convert floats */
+    for(i = 0; i < 8; i++) {
+        PUTREGF(env->fpregs[i]);
+    }
+    PUTREG32(env->fpuc);
+    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
+    PUTREG32(fpus);
+    PUTREG32(0); /* XXX: convert tags */
+    PUTREG32(0); /* fiseg */
+    PUTREG32(0); /* fioff */
+    PUTREG32(0); /* foseg */
+    PUTREG32(0); /* fooff */
+    PUTREG32(0); /* fop */
+
+#undef PUTREG
+#undef PUTREG32
+#undef PUTREGF
+
+    return p - mem_buf;
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+    uint8_t *p = mem_buf;
+    uint32_t junk;
+    int i, fpus;
+
+#define GETREG(x) do { \
+	target_ulong reg; \
+    	memcpy(&reg, p, sizeof reg);     \
+	x = tswapl(reg);		 \
+	p += sizeof reg;                 \
+    } while (0)
+#define GETREG32(x) do { \
+	uint32_t reg; \
+    	memcpy(&reg, p, sizeof reg);     \
+	x = tswap32(reg);		 \
+	p += sizeof reg;                 \
+    } while (0)
+#define GETREGF(x) do { \
+    	memcpy(&(x), p, 10);		 \
+	p += 10;                         \
+    } while (0)
+
+    GETREG(env->regs[R_EAX]);
+    GETREG(env->regs[R_EBX]);
+    GETREG(env->regs[R_ECX]);
+    GETREG(env->regs[R_EDX]);
+    GETREG(env->regs[R_ESI]);
+    GETREG(env->regs[R_EDI]);
+    GETREG(env->regs[R_EBP]);
+    GETREG(env->regs[R_ESP]);
+    GETREG(env->regs[8]);
+    GETREG(env->regs[9]);
+    GETREG(env->regs[10]);
+    GETREG(env->regs[11]);
+    GETREG(env->regs[12]);
+    GETREG(env->regs[13]);
+    GETREG(env->regs[14]);
+    GETREG(env->regs[15]);
+
+    GETREG(env->eip);
+    GETREG32(env->eflags);
+    GETREG32(env->segs[R_CS].selector);
+    GETREG32(env->segs[R_SS].selector);
+    GETREG32(env->segs[R_DS].selector);
+    GETREG32(env->segs[R_ES].selector);
+    GETREG32(env->segs[R_FS].selector);
+    GETREG32(env->segs[R_GS].selector);
+    /* XXX: convert floats */
+    for(i = 0; i < 8; i++) {
+        GETREGF(env->fpregs[i]);
+    }
+    GETREG32(env->fpuc);
+    GETREG32(fpus); /* XXX: convert fpus */
+    GETREG32(junk); /* XXX: convert tags */
+    GETREG32(junk); /* fiseg */
+    GETREG32(junk); /* fioff */
+    GETREG32(junk); /* foseg */
+    GETREG32(junk); /* fooff */
+    GETREG32(junk); /* fop */
+
+#undef GETREG
+#undef GETREG32
+#undef GETREGF
+}
+
+#elif defined(TARGET_I386)
 
 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
 {

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#6 lore raw

PATCH 5/7 VMDK Snapshot Support

In reply to a message not in the archive

This is from Avi's original patch. It implements snapshot support for VMDK disk images. It's not directly related to KVM but it's included here for completeness.

Regards,

Anthony Liguori

Makefile +1 -1
diff -r 1e79f1fb1c91 Makefile
@@ -13,7 +13,7 @@ CFLAGS+=-mcpu=ultrasparc
 CFLAGS+=-mcpu=ultrasparc
 endif
 LDFLAGS=-g
-LIBS=
+LIBS=-luuid
 DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
 TOOLS=qemu-img$(EXESUF)
 ifdef CONFIG_STATIC
Makefile.target +1 -1
diff -r 1e79f1fb1c91 Makefile.target
@@ -407,7 +407,7 @@ ifndef CONFIG_DARWIN
 ifndef CONFIG_DARWIN
 ifndef CONFIG_WIN32
 ifndef CONFIG_SOLARIS
-VL_LIBS=-lutil -lrt
+VL_LIBS=-lutil -lrt -luuid
 endif
 endif
 endif
block-vmdk.c +200 -2

238 lines not on this page · raw message

block_int.h +6 -1
diff -r 1e79f1fb1c91 block_int.h
@@ -67,12 +67,17 @@ struct BlockDriverState {
     int is_temporary;
     
     BlockDriverState *backing_hd;
+
+    BlockDriverState *bs_par_table;
+    char *parent_img_name;
+    uint32_t parent_cid;
+    uint32_t cid;
     
     /* NOTE: the following infos are only hints for real hardware
        drivers. They are not used by the block driver */
     int cyls, heads, secs, translation;
     int type;
-    char device_name[32];
+    char device_name[256];
     BlockDriverState *next;
 };
 

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#7 lore raw

PATCH 6/7 KVM changes for QEMU

In reply to a message not in the archive

This is the meat. This patch is adapted from Avi's original patch. The only changes are some minor whitespace cleanups to reduce the patch size.

Regards,

Anthony Liguori

Makefile.target +6 -2
diff -r 0890f554d752 Makefile.target
@@ -201,8 +201,8 @@ OBJS+= libqemu.a
 OBJS+= libqemu.a
 
 # cpu emulator library
-LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\
-        translate.o op.o 
+LIBOBJS=exec.o kqemu.o qemu-kvm.o translate-op.o translate-all.o cpu-exec.o\
+        translate.o op.o
 ifdef CONFIG_SOFTFLOAT
 LIBOBJS+=fpu/softfloat.o
 else
@@ -323,6 +323,10 @@ SOUND_HW += fmopl.o adlib.o
 SOUND_HW += fmopl.o adlib.o
 endif
 AUDIODRV+= wavcapture.o
+ifdef CONFIG_KVM_KERNEL_INC
+DEFINES += -I $(CONFIG_KVM_KERNEL_INC)
+LIBS += -lkvm
+endif
 
 # SCSI layer
 VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a.o
configure +14 -0
diff -r 0890f554d752 configure
@@ -87,6 +87,7 @@ bsd="no"
 bsd="no"
 linux="no"
 kqemu="no"
+kvm="no"
 profiler="no"
 kernel_path=""
 cocoa="no"
@@ -221,6 +222,8 @@ for opt do
   ;;
   --disable-kqemu) kqemu="no"
   ;;
+  --enable-kvm) kvm="yes"
+  ;;
   --enable-profiler) profiler="yes"
   ;;
   --kernel-path=*) kernel_path="$optarg"
@@ -268,6 +271,7 @@ echo "kqemu kernel acceleration support:
 echo "kqemu kernel acceleration support:"
 echo "  --disable-kqemu          disable kqemu support"
 echo "  --kernel-path=PATH       set the kernel path (configure probes it)"
+echo "  --enable-kvm             enable kernel virtual machine support"
 echo ""
 echo "Advanced options (experts only):"
 echo "  --source-path=PATH       path of source code [$source_path]"
@@ -559,6 +563,7 @@ fi
 fi
 echo "FMOD support      $fmod $fmod_support"
 echo "kqemu support     $kqemu"
+echo "kvm support       $kvm"
 echo "Documentation     $build_docs"
 [ ! -z "$uname_release" ] && \
 echo "uname -r          $uname_release"
@@ -784,6 +789,13 @@ interp_prefix1=`echo "$interp_prefix" | 
 interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
 echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
 
+configure_kvm() {
+  if test $kvm = "yes" -a "$target_softmmu" = "yes" -a $cpu = "$target_cpu" ; then
+    echo "#define USE_KVM 1" >> $config_h
+    echo "CONFIG_KVM_KERNEL_INC=$kernel_path/include" >> $config_mak
+  fi
+}
+
 if test "$target_cpu" = "i386" ; then
   echo "TARGET_ARCH=i386" >> $config_mak
   echo "#define TARGET_ARCH \"i386\"" >> $config_h
@@ -791,6 +803,7 @@ if test "$target_cpu" = "i386" ; then
   if test $kqemu = "yes" -a "$target_softmmu" = "yes" -a $cpu = "i386" ; then
     echo "#define USE_KQEMU 1" >> $config_h
   fi
+  configure_kvm
 elif test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" ; then
   echo "TARGET_ARCH=arm" >> $config_mak
   echo "#define TARGET_ARCH \"arm\"" >> $config_h
@@ -822,6 +835,7 @@ elif test "$target_cpu" = "x86_64" ; the
   if test $kqemu = "yes" -a "$target_softmmu" = "yes" -a $cpu = "x86_64"  ; then
     echo "#define USE_KQEMU 1" >> $config_h
   fi
+  configure_kvm
 elif test "$target_cpu" = "mips" -o "$target_cpu" = "mipsel" ; then
   echo "TARGET_ARCH=mips" >> $config_mak
   echo "#define TARGET_ARCH \"mips\"" >> $config_h
cpu-all.h +1 -0
diff -r 0890f554d752 cpu-all.h
@@ -818,6 +818,7 @@ extern int phys_ram_fd;
 extern int phys_ram_fd;
 extern uint8_t *phys_ram_base;
 extern uint8_t *phys_ram_dirty;
+extern uint8_t *bios_mem;
 
 /* physical memory access */
 #define TLB_INVALID_MASK   (1 << 3)
cpu-exec.c +8 -0
diff -r 0890f554d752 cpu-exec.c
@@ -33,6 +33,10 @@
 #undef EIP
 #include <signal.h>
 #include <sys/ucontext.h>
+#endif
+
+#ifdef USE_KVM
+#include "qemu-kvm.h"
 #endif
 
 int tb_invalidated_flag;
@@ -449,6 +453,10 @@ int cpu_exec(CPUState *env1)
             }
 #endif
 
+#ifdef USE_KVM
+            kvm_cpu_exec(env);
+            longjmp(env->jmp_env, 1);
+#endif
             T0 = 0; /* force lookup of first TB */
             for(;;) {
 #if defined(__sparc__) && !defined(HOST_SOLARIS)
exec.c +12 -0
diff -r 0890f554d752 exec.c
@@ -81,6 +81,7 @@ int phys_ram_fd;
 int phys_ram_fd;
 uint8_t *phys_ram_base;
 uint8_t *phys_ram_dirty;
+uint8_t *bios_mem;
 
 CPUState *first_cpu;
 /* current CPU in the current thread. It is only valid inside
@@ -1042,6 +1043,10 @@ int cpu_breakpoint_insert(CPUState *env,
     if (env->nb_breakpoints >= MAX_BREAKPOINTS)
         return -1;
     env->breakpoints[env->nb_breakpoints++] = pc;
+
+#ifdef USE_KVM
+    kvm_update_debugger(env);
+#endif
     
     breakpoint_invalidate(env, pc);
     return 0;
@@ -1065,6 +1070,10 @@ int cpu_breakpoint_remove(CPUState *env,
     if (i < env->nb_breakpoints)
       env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
 
+#ifdef USE_KVM
+    kvm_update_debugger(env);
+#endif
+    
     breakpoint_invalidate(env, pc);
     return 0;
 #else
@@ -1083,6 +1092,9 @@ void cpu_single_step(CPUState *env, int 
         /* XXX: only flush what is necessary */
         tb_flush(env);
     }
+#ifdef USE_KVM
+    kvm_update_debugger(env);
+#endif
 #endif
 }
 
hw/cirrus_vga.c +119 -0

172 lines not on this page · raw message

hw/pc.c +25 -0
diff -r 0890f554d752 hw/pc.c
@@ -22,6 +22,9 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
+#ifdef USE_KVM
+#include "qemu-kvm.h"
+#endif
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -605,6 +608,10 @@ static void pc_init_ne2k_isa(NICInfo *nd
     nb_ne2k++;
 }
 
+#ifdef USE_KVM
+extern kvm_context_t kvm_context;
+#endif
+
 /* PC hardware initialisation */
 static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
                      DisplayState *ds, const char **fd_filename, int snapshot,
@@ -674,6 +681,9 @@ static void pc_init1(int ram_size, int v
     /* setup basic memory access */
     cpu_register_physical_memory(0xc0000, 0x10000, 
                                  vga_bios_offset | IO_MEM_ROM);
+#ifdef USE_KVM
+    memcpy(phys_ram_base + 0xc0000, phys_ram_base + vga_bios_offset, 0x10000);
+#endif
 
     /* map the last 128KB of the BIOS in ISA space */
     isa_bios_size = bios_size;
@@ -684,9 +694,24 @@ static void pc_init1(int ram_size, int v
     cpu_register_physical_memory(0x100000 - isa_bios_size, 
                                  isa_bios_size, 
                                  (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
+#ifdef USE_KVM
+    memcpy(phys_ram_base + 0x100000 - isa_bios_size, phys_ram_base + (bios_offset + bios_size - isa_bios_size), isa_bios_size);
+#endif
     /* map all the bios at the top of memory */
     cpu_register_physical_memory((uint32_t)(-bios_size), 
                                  bios_size, bios_offset | IO_MEM_ROM);
+#ifdef USE_KVM
+    bios_mem = kvm_create_phys_mem(kvm_context, (uint32_t)(-bios_size),
+				       bios_size, 2, 0, 1);
+    if (!bios_mem) {
+	    exit(1);
+    }
+    memcpy(bios_mem, phys_ram_base + bios_offset, bios_size);
+
+    cpu_register_physical_memory(phys_ram_size - KVM_EXTRA_PAGES * 4096, KVM_EXTRA_PAGES * 4096,
+				 (phys_ram_size - KVM_EXTRA_PAGES * 4096) | IO_MEM_ROM);
+    
+#endif
     
     bochs_bios_init();
 
hw/vga.c +62 -0

99 lines not on this page · raw message

hw/vga_int.h +1 -0
diff -r 0890f554d752 hw/vga_int.h
@@ -169,5 +169,6 @@ void vga_draw_cursor_line_32(uint8_t *d1
                              unsigned int color0, unsigned int color1,
                              unsigned int color_xor);
 
+void *vga_update_vram(VGAState *s, void *vga_ram_base, int vga_ram_size);
 extern const uint8_t sr_mask[8];
 extern const uint8_t gr_mask[16];
target-i386/cpu.h +13 -3
diff -r 0890f554d752 target-i386/cpu.h
@@ -154,13 +154,17 @@
 #define HF_MP_MASK           (1 << HF_MP_SHIFT)
 #define HF_EM_MASK           (1 << HF_EM_SHIFT)
 #define HF_TS_MASK           (1 << HF_TS_SHIFT)
+#define HF_IOPL_MASK         (3 << HF_IOPL_SHIFT)
 #define HF_LMA_MASK          (1 << HF_LMA_SHIFT)
 #define HF_CS64_MASK         (1 << HF_CS64_SHIFT)
 #define HF_OSFXSR_MASK       (1 << HF_OSFXSR_SHIFT)
+#define HF_VM_MASK           (1 << HF_VM_SHIFT)
 #define HF_HALTED_MASK       (1 << HF_HALTED_SHIFT)
 
-#define CR0_PE_MASK  (1 << 0)
-#define CR0_MP_MASK  (1 << 1)
+#define CR0_PE_SHIFT 0
+#define CR0_PE_MASK  (1 << CR0_PE_SHIFT)
+#define CR0_MP_SHIFT 1
+#define CR0_MP_MASK  (1 << CR0_MP_SHIFT)
 #define CR0_EM_MASK  (1 << 2)
 #define CR0_TS_MASK  (1 << 3)
 #define CR0_ET_MASK  (1 << 4)
@@ -177,7 +181,8 @@
 #define CR4_PAE_MASK  (1 << 5)
 #define CR4_PGE_MASK  (1 << 7)
 #define CR4_PCE_MASK  (1 << 8)
-#define CR4_OSFXSR_MASK (1 << 9)
+#define CR4_OSFXSR_SHIFT 9
+#define CR4_OSFXSR_MASK (1 << CR4_OSFXSR_SHIFT)
 #define CR4_OSXMMEXCPT_MASK  (1 << 10)
 
 #define PG_PRESENT_BIT	0
@@ -524,6 +529,11 @@ typedef struct CPUX86State {
     int kqemu_enabled;
     int last_io_time;
 #endif
+
+#ifdef USE_KVM
+    int kvm_pending_int;
+#endif
+
     /* in order to simplify APIC support, we leave this pointer to the
        user */
     struct APICState *apic_state;
target-i386/helper.c +32 -0
diff -r 0890f554d752 target-i386/helper.c
@@ -184,7 +184,15 @@ static inline void get_ss_esp_from_tss(u
     if (!(env->tr.flags & DESC_P_MASK))
         cpu_abort(env, "invalid tss");
     type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
+#ifdef USE_KVM
+    /*
+     * Bit 1 is the Busy bit.  We believe it is legal to interrupt into a busy
+     * segment
+     */
+    if ((type & 5) != 1)
+#else
     if ((type & 7) != 1)
+#endif
         cpu_abort(env, "invalid tss type");
     shift = type >> 3;
     index = (dpl * 4 + 2) << shift;
@@ -497,7 +505,12 @@ static inline void check_io(int addr, in
     
     /* TSS must be a valid 32 bit one */
     if (!(env->tr.flags & DESC_P_MASK) ||
+#ifdef USE_KVM
+	/* Probable qemu bug: 11 is a valid segment type */
+        ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xd) != 9 ||
+#else
         ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
+#endif
         env->tr.limit < 103)
         goto fail;
     io_offset = lduw_kernel(env->tr.base + 0x66);
@@ -824,6 +837,11 @@ static void do_interrupt64(int intno, in
     uint32_t e1, e2, e3, ss;
     target_ulong old_eip, esp, offset;
 
+#ifdef USE_KVM
+    printf("%s: unexpect\n", __FUNCTION__);
+    exit(-1);
+#endif
+
     has_error_code = 0;
     if (!is_int && !is_hw) {
         switch(intno) {
@@ -1107,6 +1125,10 @@ void do_interrupt_user(int intno, int is
     int dpl, cpl;
     uint32_t e2;
 
+#ifdef USE_KVM
+    printf("%s: unexpect\n", __FUNCTION__);
+    exit(-1);
+#endif
     dt = &env->idt;
     ptr = dt->base + (intno * 8);
     e2 = ldl_kernel(ptr + 4);
@@ -1132,6 +1154,10 @@ void do_interrupt(int intno, int is_int,
 void do_interrupt(int intno, int is_int, int error_code, 
                   target_ulong next_eip, int is_hw)
 {
+#ifdef USE_KVM
+    printf("%s: unexpect\n", __FUNCTION__);
+    exit(-1);
+#endif
     if (loglevel & CPU_LOG_INT) {
         if ((env->cr[0] & CR0_PE_MASK)) {
             static int count;
@@ -1660,6 +1686,12 @@ void helper_ljmp_protected_T0_T1(int nex
         cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
                        get_seg_base(e1, e2), limit, e2);
         EIP = new_eip;
+#ifdef USE_KVM
+        if (e2 & DESC_L_MASK) {
+            env->exception_index = -1;
+            cpu_loop_exit();   
+        }       
+#endif
     } else {
         /* jump to call or task gate */
         dpl = (e2 >> DESC_DPL_SHIFT) & 3;
vl.c +20 -1
diff -r 0890f554d752 vl.c
@@ -86,6 +86,10 @@
 #include "disas.h"
 
 #include "exec-all.h"
+
+#if USE_KVM
+#include "qemu-kvm.h"
+#endif
 
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 
@@ -4589,6 +4593,9 @@ int cpu_load(QEMUFile *f, void *opaque, 
     /* XXX: compute hflags from scratch, except for CPL and IIF */
     env->hflags = hflags;
     tlb_flush(env, 1);
+#ifdef USE_KVM
+    kvm_load_registers(env);
+#endif
     return 0;
 }
 
@@ -4753,6 +4760,10 @@ static void ram_save(QEMUFile *f, void *
     int i;
     qemu_put_be32(f, phys_ram_size);
     for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
+#ifdef USE_KVM
+        if ((i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */
+            continue;
+#endif
         ram_put_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
     }
 }
@@ -4766,6 +4777,10 @@ static int ram_load(QEMUFile *f, void *o
     if (qemu_get_be32(f) != phys_ram_size)
         return -EINVAL;
     for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
+#ifdef USE_KVM
+        if ((i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */
+            continue;
+#endif
         ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
         if (ret)
             return ret;
@@ -6072,13 +6087,17 @@ int main(int argc, char **argv)
     }
 
     /* init the memory */
+#if USE_KVM
+    phys_ram_size = ram_size + vga_ram_size + bios_size + KVM_EXTRA_PAGES * 4096;
+    kvm_qemu_init();
+#else
     phys_ram_size = ram_size + vga_ram_size + bios_size;
-
     phys_ram_base = qemu_vmalloc(phys_ram_size);
     if (!phys_ram_base) {
         fprintf(stderr, "Could not allocate physical memory\n");
         exit(1);
     }
+#endif
 
     /* we always create the cdrom drive, even if no disk is there */
     bdrv_init();
vl.h +4 -0
diff -r 0890f554d752 vl.h
@@ -161,6 +161,10 @@ extern int smp_cpus;
 #define BIOS_SIZE ((256 + 64) * 1024)
 #endif
 
+#if USE_KVM
+#define KVM_EXTRA_PAGES 3
+#endif
+
 /* keyboard/mouse support */
 
 #define MOUSE_EVENT_LBUTTON 0x01
qemu-kvm.c new file +478 -0

478 lines not on this page · raw message

qemu-kvm.h new file +11 -0
diff -r 0890f554d752 qemu-kvm.h
@@ -0,0 +1,11 @@
+#ifndef QEMU_KVM_H
+#define QEMU_KVM_H
+
+#include "kvmctl.h"
+
+void kvm_qemu_init(void);
+void kvm_load_registers(CPUState *env);
+int kvm_cpu_exec(CPUState *env);
+int kvm_update_debugger(CPUState *env);
+
+#endif

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

#8 lore raw

PATCH 7/7 Allow KVM from a normal QEMU binary

In reply to a message not in the archive

This patch depends on patch 6 and modifies the KVM changes to be an "accelerator" for QEMU in much the same way kqemu is.

The basic idea was to introduce a use_kvm flag in CPUState and, where appropriate, check for use_kvm before doing KVM specific things. There are a number of places where a valid CPUState is not available or simply not created yet. In these cases, we use the global kvm_allowed variable.

This isn't a very pretty approach but it seems to work. Figuring out how to make this all work with SMP is going to largely depend on how SMP gets implemented in KVM.

Regards,

Anthony Liguori

cpu-exec.c +4 -2
diff -r 29c67b2ba36e cpu-exec.c
@@ -454,8 +454,10 @@ int cpu_exec(CPUState *env1)
 #endif
 
 #ifdef USE_KVM
-            kvm_cpu_exec(env);
-            longjmp(env->jmp_env, 1);
+	    if (env->use_kvm) {
+		kvm_cpu_exec(env);
+		longjmp(env->jmp_env, 1);
+	    }
 #endif
             T0 = 0; /* force lookup of first TB */
             for(;;) {
exec.c +6 -3
diff -r 29c67b2ba36e exec.c
@@ -1045,7 +1045,8 @@ int cpu_breakpoint_insert(CPUState *env,
     env->breakpoints[env->nb_breakpoints++] = pc;
 
 #ifdef USE_KVM
-    kvm_update_debugger(env);
+    if (env->use_kvm)
+	kvm_update_debugger(env);
 #endif
     
     breakpoint_invalidate(env, pc);
@@ -1071,7 +1072,8 @@ int cpu_breakpoint_remove(CPUState *env,
       env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
 
 #ifdef USE_KVM
-    kvm_update_debugger(env);
+    if (env->use_kvm)
+	kvm_update_debugger(env);
 #endif
     
     breakpoint_invalidate(env, pc);
@@ -1093,7 +1095,8 @@ void cpu_single_step(CPUState *env, int 
         tb_flush(env);
     }
 #ifdef USE_KVM
-    kvm_update_debugger(env);
+    if (env->use_kvm)
+	kvm_update_debugger(env);
 #endif
 #endif
 }
hw/cirrus_vga.c +28 -11
diff -r 29c67b2ba36e hw/cirrus_vga.c
@@ -2596,7 +2596,9 @@ static void cirrus_update_memory_access(
 	mode = s->gr[0x05] & 0x7;
 	if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
 #ifdef USE_KVM
-            if (s->cirrus_lfb_addr && s->cirrus_lfb_end && !s->map_addr) {
+	    CPUState *env = cpu_single_env; /* XXX: SMP support */
+            if (env->use_kvm && s->cirrus_lfb_addr && s->cirrus_lfb_end &&
+		!s->map_addr) {
                 void *vram_pointer, *old_vram;
 
                 vram_pointer = set_vram_mapping(s->cirrus_lfb_addr,
@@ -2616,9 +2618,14 @@ static void cirrus_update_memory_access(
             s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
             s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
         } else {
+#ifdef USE_KVM
+	    CPUState *env;
+#endif
         generic_io:
 #ifdef USE_KVM
-            if (s->cirrus_lfb_addr && s->cirrus_lfb_end && s->map_addr) {
+	    env = cpu_single_env;
+            if (env->use_kvm && s->cirrus_lfb_addr && s->cirrus_lfb_end &&
+		s->map_addr) {
 		int error;
                 void *old_vram = NULL;
 
@@ -2993,6 +3000,9 @@ static void cirrus_vga_save(QEMUFile *f,
 static void cirrus_vga_save(QEMUFile *f, void *opaque)
 {
     CirrusVGAState *s = opaque;
+#ifdef USE_KVM
+    CPUState *env = cpu_single_env;
+#endif
 
     qemu_put_be32s(f, &s->latch);
     qemu_put_8s(f, &s->sr_index);
@@ -3029,14 +3039,19 @@ static void cirrus_vga_save(QEMUFile *f,
        the state when the blitter is active */
 
 #ifdef USE_KVM
-    qemu_put_be32s(f, &s->real_vram_size);
-    qemu_put_buffer(f, s->vram_ptr, s->real_vram_size);
+    if (env->use_kvm) { /* XXX: KVM images ought to be loadable in QEMU */
+	qemu_put_be32s(f, &s->real_vram_size);
+	qemu_put_buffer(f, s->vram_ptr, s->real_vram_size);
+    }
 #endif
 }
 
 static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
 {
     CirrusVGAState *s = opaque;
+#ifdef USE_KVM
+    CPUState *env = cpu_single_env;
+#endif    
 
     if (version_id != 1)
         return -EINVAL;
@@ -3076,7 +3091,7 @@ static int cirrus_vga_load(QEMUFile *f, 
     qemu_get_be32s(f, &s->hw_cursor_y);
 
 #ifdef USE_KVM
-    {
+    if (env->use_kvm) {
         int real_vram_size;
         qemu_get_be32s(f, &real_vram_size);
         if (real_vram_size != s->real_vram_size) {
@@ -3247,12 +3262,14 @@ static void cirrus_pci_lfb_map(PCIDevice
     cpu_register_physical_memory(addr, s->vram_size,
 				 s->cirrus_linear_io_addr);
 #ifdef USE_KVM
-    s->cirrus_lfb_addr = addr;
-    s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
-
-    if (s->map_addr && (s->cirrus_lfb_addr != s->map_addr) &&
-        (s->cirrus_lfb_end != s->map_end))
-        printf("cirrus vga map change while on lfb mode\n");
+    if (kqemu_allowed) {
+	s->cirrus_lfb_addr = addr;
+	s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
+
+	if (s->map_addr && (s->cirrus_lfb_addr != s->map_addr) &&
+	    (s->cirrus_lfb_end != s->map_end))
+	    printf("cirrus vga map change while on lfb mode\n");
+    }
 #endif
 
     cpu_register_physical_memory(addr + 0x1000000, 0x400000,
hw/pc.c +18 -11
diff -r 29c67b2ba36e hw/pc.c
@@ -610,6 +610,7 @@ static void pc_init_ne2k_isa(NICInfo *nd
 
 #ifdef USE_KVM
 extern kvm_context_t kvm_context;
+extern int kvm_allowed;
 #endif
 
 /* PC hardware initialisation */
@@ -682,7 +683,9 @@ static void pc_init1(int ram_size, int v
     cpu_register_physical_memory(0xc0000, 0x10000, 
                                  vga_bios_offset | IO_MEM_ROM);
 #ifdef USE_KVM
-    memcpy(phys_ram_base + 0xc0000, phys_ram_base + vga_bios_offset, 0x10000);
+    if (kvm_allowed)
+	    memcpy(phys_ram_base + 0xc0000, phys_ram_base + vga_bios_offset,
+		   0x10000);
 #endif
 
     /* map the last 128KB of the BIOS in ISA space */
@@ -695,21 +698,25 @@ static void pc_init1(int ram_size, int v
                                  isa_bios_size, 
                                  (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
 #ifdef USE_KVM
-    memcpy(phys_ram_base + 0x100000 - isa_bios_size, phys_ram_base + (bios_offset + bios_size - isa_bios_size), isa_bios_size);
+    if (kvm_allowed)
+	    memcpy(phys_ram_base + 0x100000 - isa_bios_size,
+		   phys_ram_base + (bios_offset + bios_size - isa_bios_size),
+		   isa_bios_size);
 #endif
     /* map all the bios at the top of memory */
     cpu_register_physical_memory((uint32_t)(-bios_size), 
                                  bios_size, bios_offset | IO_MEM_ROM);
 #ifdef USE_KVM
-    bios_mem = kvm_create_phys_mem(kvm_context, (uint32_t)(-bios_size),
-				       bios_size, 2, 0, 1);
-    if (!bios_mem) {
-	    exit(1);
-    }
-    memcpy(bios_mem, phys_ram_base + bios_offset, bios_size);
-
-    cpu_register_physical_memory(phys_ram_size - KVM_EXTRA_PAGES * 4096, KVM_EXTRA_PAGES * 4096,
-				 (phys_ram_size - KVM_EXTRA_PAGES * 4096) | IO_MEM_ROM);
+    if (kvm_allowed) {
+	    bios_mem = kvm_create_phys_mem(kvm_context, (uint32_t)(-bios_size),
+					   bios_size, 2, 0, 1);
+	    if (!bios_mem)
+		    exit(1);
+	    memcpy(bios_mem, phys_ram_base + bios_offset, bios_size);
+
+	    cpu_register_physical_memory(phys_ram_size - KVM_EXTRA_PAGES * 4096, KVM_EXTRA_PAGES * 4096,
+					 (phys_ram_size - KVM_EXTRA_PAGES * 4096) | IO_MEM_ROM);
+    }
     
 #endif
     
hw/vga.c +20 -6
diff -r 29c67b2ba36e hw/vga.c
@@ -1375,6 +1375,10 @@ static int bitmap_get_dirty(unsigned lon
 
 #endif
 
+#ifdef USE_KVM
+extern int kvm_allowed;
+#endif
+
 /* 
  * graphic modes
  */
@@ -1393,11 +1397,8 @@ static void vga_draw_graphic(VGAState *s
 #define BITMAP_SIZE ((8*1024*1024) / 4096 / 8 / sizeof(long))
     unsigned long bitmap[BITMAP_SIZE];
 
-    kvm_get_dirty_pages(kvm_context, 1, &bitmap);
-
-#define cpu_physical_memory_get_dirty(addr, type) \
-    (bitmap_get_dirty(bitmap, (addr - s->vram_offset) >> TARGET_PAGE_BITS) \
-     | cpu_physical_memory_get_dirty(addr, type))
+    if (kvm_allowed)
+	    kvm_get_dirty_pages(kvm_context, 1, &bitmap);
 #endif
 
     full_update |= update_basic_params(s);
@@ -1506,10 +1507,16 @@ static void vga_draw_graphic(VGAState *s
         update = full_update | 
             cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
             cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
+	if (kvm_allowed) {
+		update |= bitmap_get_dirty(bitmap, (page0 - s->vram_offset) >> TARGET_PAGE_BITS);
+		update |= bitmap_get_dirty(bitmap, (page1 - s->vram_offset) >> TARGET_PAGE_BITS);
+	}
         if ((page1 - page0) > TARGET_PAGE_SIZE) {
             /* if wide line, can use another page */
             update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, 
                                                     VGA_DIRTY_FLAG);
+	    if (kvm_allowed)
+		    update |= bitmap_get_dirty(bitmap, (page0 - s->vram_offset) >> TARGET_PAGE_BITS);
         }
         /* explicit invalidation for the hardware cursor */
         update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
@@ -1751,6 +1758,10 @@ static void vga_map(PCIDevice *pci_dev, 
     }
 }
 
+#ifdef USE_KVM
+extern int kvm_allowed;
+#endif
+
 /* when used on xen/kvm environment, the vga_ram_base is not used */
 void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, 
                      unsigned long vga_ram_offset, int vga_ram_size)
@@ -1785,7 +1796,10 @@ void vga_common_init(VGAState *s, Displa
 #ifndef USE_KVM
     s->vram_ptr = vga_ram_base;
 #else
-    s->vram_ptr = qemu_malloc(vga_ram_size);
+    if (kvm_allowed)
+	    s->vram_ptr = qemu_malloc(vga_ram_size);
+    else
+	    s->vram_ptr = vga_ram_base;
 #endif
     s->vram_offset = vga_ram_offset;
     s->vram_size = vga_ram_size;
target-i386/cpu.h +1 -0
diff -r 29c67b2ba36e target-i386/cpu.h
@@ -532,6 +532,7 @@ typedef struct CPUX86State {
 
 #ifdef USE_KVM
     int kvm_pending_int;
+    int use_kvm;
 #endif
 
     /* in order to simplify APIC support, we leave this pointer to the
target-i386/helper.c +14 -8
diff -r 29c67b2ba36e target-i386/helper.c
@@ -189,7 +189,7 @@ static inline void get_ss_esp_from_tss(u
      * Bit 1 is the Busy bit.  We believe it is legal to interrupt into a busy
      * segment
      */
-    if ((type & 5) != 1)
+    if ((env->use_kvm && (type & 5) != 1) || (type & 7) != 1)
 #else
     if ((type & 7) != 1)
 #endif
@@ -838,8 +838,10 @@ static void do_interrupt64(int intno, in
     target_ulong old_eip, esp, offset;
 
 #ifdef USE_KVM
-    printf("%s: unexpect\n", __FUNCTION__);
-    exit(-1);
+    if (env->use_kvm) {
+	    printf("%s: unexpect\n", __FUNCTION__);
+	    exit(-1);
+    }
 #endif
 
     has_error_code = 0;
@@ -1126,8 +1128,10 @@ void do_interrupt_user(int intno, int is
     uint32_t e2;
 
 #ifdef USE_KVM
-    printf("%s: unexpect\n", __FUNCTION__);
-    exit(-1);
+    if (env->use_kvm) {
+	    printf("%s: unexpect\n", __FUNCTION__);
+	    exit(-1);
+    }
 #endif
     dt = &env->idt;
     ptr = dt->base + (intno * 8);
@@ -1155,8 +1159,10 @@ void do_interrupt(int intno, int is_int,
                   target_ulong next_eip, int is_hw)
 {
 #ifdef USE_KVM
-    printf("%s: unexpect\n", __FUNCTION__);
-    exit(-1);
+    if (env->use_kvm) {
+	printf("%s: unexpect\n", __FUNCTION__);
+	exit(-1);
+    }
 #endif
     if (loglevel & CPU_LOG_INT) {
         if ((env->cr[0] & CR0_PE_MASK)) {
@@ -1687,7 +1693,7 @@ void helper_ljmp_protected_T0_T1(int nex
                        get_seg_base(e1, e2), limit, e2);
         EIP = new_eip;
 #ifdef USE_KVM
-        if (e2 & DESC_L_MASK) {
+        if (env->use_kvm && (e2 & DESC_L_MASK)) {
             env->exception_index = -1;
             cpu_loop_exit();   
         }       
target-i386/helper2.c +6 -0
diff -r 29c67b2ba36e target-i386/helper2.c
@@ -140,6 +140,12 @@ CPUX86State *cpu_x86_init(void)
     cpu_reset(env);
 #ifdef USE_KQEMU
     kqemu_init(env);
+#endif
+#ifdef USE_KVM
+    {
+	extern int kvm_allowed;
+	env->use_kvm = kvm_allowed;
+    }
 #endif
     return env;
 }
vl.c +27 -6
diff -r 29c67b2ba36e vl.c
@@ -4594,7 +4594,8 @@ int cpu_load(QEMUFile *f, void *opaque, 
     env->hflags = hflags;
     tlb_flush(env, 1);
 #ifdef USE_KVM
-    kvm_load_registers(env);
+    if (env->use_kvm)
+	    kvm_load_registers(env);
 #endif
     return 0;
 }
@@ -4761,7 +4762,7 @@ static void ram_save(QEMUFile *f, void *
     qemu_put_be32(f, phys_ram_size);
     for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
 #ifdef USE_KVM
-        if ((i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */
+        if (kvm_allowed && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */
             continue;
 #endif
         ram_put_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
@@ -4771,14 +4772,13 @@ static int ram_load(QEMUFile *f, void *o
 static int ram_load(QEMUFile *f, void *opaque, int version_id)
 {
     int i, ret;
-
     if (version_id != 1)
         return -EINVAL;
     if (qemu_get_be32(f) != phys_ram_size)
         return -EINVAL;
     for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
 #ifdef USE_KVM
-        if ((i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */
+        if (kqemu_allowed && (i>=0xa0000) && (i<0xc0000)) /* do not access video-addresses */
             continue;
 #endif
         ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
@@ -5230,6 +5230,9 @@ void help(void)
 #ifdef USE_KQEMU
            "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
            "-no-kqemu       disable KQEMU kernel module usage\n"
+#endif
+#ifdef USE_KVM
+	   "-enable-kvm     enable KVM full virtualization\n"
 #endif
 #ifdef USE_CODE_COPY
            "-no-code-copy   disable code copy acceleration\n"
@@ -5319,6 +5322,7 @@ enum {
     QEMU_OPTION_smp,
     QEMU_OPTION_vnc,
     QEMU_OPTION_no_acpi,
+    QEMU_OPTION_enable_kvm,
 };
 
 typedef struct QEMUOption {
@@ -5374,6 +5378,9 @@ const QEMUOption qemu_options[] = {
 #ifdef USE_KQEMU
     { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
     { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
+#endif
+#ifdef USE_KVM
+    { "enable-kvm", 0, QEMU_OPTION_enable_kvm },
 #endif
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
     { "g", 1, QEMU_OPTION_g },
@@ -6007,6 +6014,11 @@ int main(int argc, char **argv)
                 kqemu_allowed = 2;
                 break;
 #endif
+#ifdef USE_KVM
+	    case QEMU_OPTION_enable_kvm:
+		kvm_allowed = 1;
+		break;
+#endif
             case QEMU_OPTION_usb:
                 usb_enabled = 1;
                 break;
@@ -6088,8 +6100,17 @@ int main(int argc, char **argv)
 
     /* init the memory */
 #if USE_KVM
-    phys_ram_size = ram_size + vga_ram_size + bios_size + KVM_EXTRA_PAGES * 4096;
-    kvm_qemu_init();
+    phys_ram_size = ram_size + vga_ram_size + bios_size;
+    if (kvm_allowed) {
+	    phys_ram_size += KVM_EXTRA_PAGES * 4096;
+	    kvm_qemu_init();
+    } else {
+	    phys_ram_base = qemu_vmalloc(phys_ram_size);
+	    if (!phys_ram_base) {
+		    fprintf(stderr, "Could not allocate physical memory\n");
+		    exit(1);
+	    }
+    }
 #else
     phys_ram_size = ram_size + vga_ram_size + bios_size;
     phys_ram_base = qemu_vmalloc(phys_ram_size);
vl.h +1 -0
diff -r 29c67b2ba36e vl.h
@@ -148,6 +148,7 @@ extern int graphic_depth;
 extern int graphic_depth;
 extern const char *keyboard_layout;
 extern int kqemu_allowed;
+extern int kvm_allowed;
 extern int win2k_install_hack;
 extern int usb_enabled;
 extern int smp_cpus;

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

_______________________________________________
kvm-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel

A message that is not in the archive (sent off-list or not yet received): [email protected]

Applied
#10 lore raw

Re: [PATCH 7/7] Allow KVM from a normal QEMU binary

Quoted 8 lines · Anthony Liguori

This patch depends on patch 6 and modifies the KVM changes to be an "accelerator" for QEMU in much the same way kqemu is.

The basic idea was to introduce a use_kvm flag in CPUState and, where appropriate, check for use_kvm before doing KVM specific things. There are a number of places where a valid CPUState is not available or simply not created yet. In these cases, we use the global kvm_allowed variable.

Applied, with the following changes:

- actually define kvm_allowed (gcc 3.4 insists)
- a couple of places had kqemu_allowed instead of kvm_allowed
- renamed the command line option to -no-kvm (similar to -no-kqemu)

Most of the places where USE_KVM is used are now never called - they are relics from the days when we had mixed qemu/kvm execution.

Now, the "big real" fiasco means that we need some sort of emulation, but I'm not sure the qemu cpu loop is the best choice. Qemu is very complex because it is geared to multi-host, multi-target, high-performance emulation. The cpu state is baroque, and SMP isn't going to be fun.

I think we're better off with taking the x86 emulator from the kernel and extending it to support the non-memory instructions. It can run in the kernel or userspace since there's no performance requirement.

Quoted 5 lines

This isn't a very pretty approach but it seems to work. Figuring out how to make this all work with SMP is going to largely depend on how SMP gets implemented in KVM.

If we proceed as outlined above all we need is to slap a lock on all accesses to the device model. Later we can fine-grain it so that each device has its own lock and accesses to multiple devices can occur in parallel.

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

A message that is not in the archive (sent off-list or not yet received): 454DAE74.4030306-atKUWr5tajBWk0Htik3J/[email protected]

#12 lore raw

Re: [PATCH 7/7] Allow KVM from a normal QEMU binary

Quoted 10 lines · Avi Kivity
Quoted 8 lines · Anthony Liguori

This patch depends on patch 6 and modifies the KVM changes to be an "accelerator" for QEMU in much the same way kqemu is.

The basic idea was to introduce a use_kvm flag in CPUState and, where appropriate, check for use_kvm before doing KVM specific things. There are a number of places where a valid CPUState is not available or simply not created yet. In these cases, we use the global kvm_allowed variable.

Quoted 3 lines

Applied, with the following changes:

- actually define kvm_allowed (gcc 3.4 insists)

Sorry, I had a small SNAFU with my patch queue with qemu-kvm.c not being in the original hg tree. I had defined kqemu_allowed in qemu-kvm.c but that wasn't in this patch.

Quoted 1 line

- a couple of places had kqemu_allowed instead of kvm_allowed

I guess I lucked out since kqemu_allowed=1 under normal circumstances. Thanks for catching that :-)

Quoted 1 line

- renamed the command line option to -no-kvm (similar to -no-kqemu)

When kqemu first went in, since it was considered "experimental" it had to be explicitly enabled with an -enable-kqemu option. Once it was considered to be stable, it was enabled by default (hence -no-kqemu).

It really doesn't matter to me all that much.

Quoted 3 lines

Most of the places where USE_KVM is used are now never called - they are relics from the days when we had mixed qemu/kvm execution.

One of the things I was thinking of doing was getting rid of USE_KVM completely. What I was thinking of doing is moving kvmctl.[ch] into the QEMU tree and refactoring things a bit so that it fails gracefully in the absence of a working KVM device.

The idea is to get rid of external dependencies. What are your thoughts on this? Do you think there will be significant users of libkvm.a outside of QEMU?

Quoted 5 lines

Now, the "big real" fiasco means that we need some sort of emulation, but I'm not sure the qemu cpu loop is the best choice. Qemu is very complex because it is geared to multi-host, multi-target, high-performance emulation. The cpu state is baroque, and SMP isn't going to be fun.

Right.

Quoted 3 lines

I think we're better off with taking the x86 emulator from the kernel and extending it to support the non-memory instructions. It can run in the kernel or userspace since there's no performance requirement.

This is the opposite strategy that Xen is taking FWIW. You not only need a full 16 bit emulator but a 32 bit emulator too (to deal with the transitions to/from userspace).

The tree we're working in is:

http://xenbits.xensource.com/ext/xen-unstable-hvm.hg

Linux kernel boots quite nicely and I'm in the process of debugging why Windows guests aren't booting (there appears to be a problem in the state transfer right now).

SMP guest support is still a hard problem that needs thinking through but if Xen solves it, KVM can use the solution (or vice versa).

Don't discount the importance of 16 bit emulation performance. I use QEMU a lot to play old DOS games :-)

Regards,

Anthony Liguori

Quoted 6 lines
Quoted 5 lines

This isn't a very pretty approach but it seems to work. Figuring out how to make this all work with SMP is going to largely depend on how SMP gets implemented in KVM.

Quoted 6 lines

If we proceed as outlined above all we need is to slap a lock on all accesses to the device model. Later we can fine-grain it so that each device has its own lock and accesses to multiple devices can occur in parallel.

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

A message that is not in the archive (sent off-list or not yet received): [email protected]

#14 lore raw

Re: [PATCH 7/7] Allow KVM from a normal QEMU binary

Quoted 8 lines · Anthony Liguori
Quoted 4 lines

Most of the places where USE_KVM is used are now never called - they are relics from the days when we had mixed qemu/kvm execution.

One of the things I was thinking of doing was getting rid of USE_KVM completely. What I was thinking of doing is moving kvmctl.[ch] into the QEMU tree

I'd like to keep kvmctl out, so that non-qemu based userspace can be built. True, I wouldn't like to be the one to do it, but I'd like to keep the possibility open.

Quoted 2 lines

and refactoring things a bit so that it fails gracefully in the absence of a working KVM device.

Sure, if it can't create a kvm vm it should fall back to kqemu or normal emulation.

Quoted 4 lines

The idea is to get rid of external dependencies. What are your thoughts on this? Do you think there will be significant users of libkvm.a outside of QEMU?

Right now there's just the (mostly broken) test suite.

Quoted 9 lines
Quoted 6 lines

Now, the "big real" fiasco means that we need some sort of emulation, but I'm not sure the qemu cpu loop is the best choice. Qemu is very complex because it is geared to multi-host, multi-target, high-performance emulation. The cpu state is baroque, and SMP isn't going to be fun.

Right.

Quoted 7 lines
Quoted 3 lines

I think we're better off with taking the x86 emulator from the kernel and extending it to support the non-memory instructions. It can run in the kernel or userspace since there's no performance requirement.

This is the opposite strategy that Xen is taking FWIW. You not only need a full 16 bit emulator but a 32 bit emulator too (to deal with the transitions to/from userspace).

We need a real-mode emulator. That includes 16 and 32 bits (via prefixes).

We already have some significant fraction of it in x86_emulator.c. Whether to extend it (in the kernel or in userspace) or to use some other emulator is a good question. Of course, we can use qemu, but that's fairly complex.

Quoted 8 lines

The tree we're working in is:

http://xenbits.xensource.com/ext/xen-unstable-hvm.hg

Linux kernel boots quite nicely and I'm in the process of debugging why Windows guests aren't booting (there appears to be a problem in the state transfer right now).

State transfer is what turned us of qemu. Reconstructing the state (esp. eflags and the segments) is quite difficult and there are some annoying qemu bugs (like the busy task flag checks).

BTW, dumping qemu cpu emulation will allow us to use gcc 4.x instead of gcc 3.x.

Quoted 3 lines

SMP guest support is still a hard problem that needs thinking through but if Xen solves it, KVM can use the solution (or vice versa).

I don't see a huge problem. We'll have to get the APIC right, and the mmu locking right in the kernel, but what else?

Quoted 3 lines

Don't discount the importance of 16 bit emulation performance. I use QEMU a lot to play old DOS games :-)

We'll add an option to udelay() in strategic places :)

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

A message that is not in the archive (sent off-list or not yet received): 454E23EE.7040505-atKUWr5tajBWk0Htik3J/[email protected]

#16 lore raw

Re: [PATCH 7/7] Allow KVM from a normal QEMU binary

Quoted 8 lines · Avi Kivity
Quoted 3 lines · Anthony Liguori

One of the things I was thinking of doing was getting rid of USE_KVM completely. What I was thinking of doing is moving kvmctl.[ch] into the QEMU tree

I'd like to keep kvmctl out, so that non-qemu based userspace can be built. True, I wouldn't like to be the one to do it, but I'd like to keep the possibility open.

Yeah, I'm on the fence myself. In the very least, we need a smarter configure check in QEMU to detect the presence of libkvm and enable the define appropriately.

I'll go as far as to say that once there's proper configure checks (and kvm fails gracefully), it would be appropriate to send it to qemu-devel. What are your thoughts?

Quoted 30 lines
Quoted 8 lines
Quoted 5 lines

Now, the "big real" fiasco means that we need some sort of emulation, but I'm not sure the qemu cpu loop is the best choice. Qemu is very complex because it is geared to multi-host, multi-target, high-performance emulation. The cpu state is baroque, and SMP isn't going to be fun.

Right.

Quoted 8 lines
Quoted 4 lines

I think we're better off with taking the x86 emulator from the kernel and extending it to support the non-memory instructions. It can run in the kernel or userspace since there's no performance requirement.

This is the opposite strategy that Xen is taking FWIW. You not only need a full 16 bit emulator but a 32 bit emulator too (to deal with the transitions to/from userspace).

We need a real-mode emulator. That includes 16 and 32 bits (via prefixes).

We already have some significant fraction of it in x86_emulator.c. Whether to extend it (in the kernel or in userspace) or to use some other emulator is a good question. Of course, we can use qemu, but that's fairly complex.

Quoted 5 lines

The tree we're working in is:

http://xenbits.xensource.com/ext/xen-unstable-hvm.hg

Quoted 7 lines
Quoted 3 lines

Linux kernel boots quite nicely and I'm in the process of debugging why Windows guests aren't booting (there appears to be a problem in the state transfer right now).

State transfer is what turned us of qemu. Reconstructing the state (esp. eflags and the segments) is quite difficult and there are some annoying qemu bugs (like the busy task flag checks).

The Xen tree already has the conversion code. It's annoying but it's not nearly as bad as say, shadow paging :-)

While not necessarily in your scope, in the long term, having the state transfer would be really useful.

I can imagine KVM eventually supporting VT, SVM, user mode virtualization, and paravirtualization. State transfer use is useful for VT at least but is absolutely required for user mode virtualization. All of these things exist in some form right now (user mode via qvm86 and para via lhype) and all are duplicating a lot of tough code (such as shadow paging).

Of course, state transfer won't be impossible to add down the road at some point so if you think big real mode will be easier with emulation, it wouldn't be that bad to give it a shot.

Quoted 9 lines

BTW, dumping qemu cpu emulation will allow us to use gcc 4.x instead of gcc 3.x.

Quoted 3 lines

SMP guest support is still a hard problem that needs thinking through but if Xen solves it, KVM can use the solution (or vice versa).

I don't see a huge problem. We'll have to get the APIC right, and the mmu locking right in the kernel, but what else?

It's not so bad provided you don't use QEMU for emulation. That's what I was referring to. There are some tricky cases where QEMU is accessing a piece of memory with an atomic instruction while another VCPU is running on bare metal and trying to touch the same memory. I suspect that as-is, QEMU would violate the atomic guarantees when it translates the instruction.

Regards,

Anthony Liguori

Quoted 6 lines
Quoted 3 lines

Don't discount the importance of 16 bit emulation performance. I use QEMU a lot to play old DOS games :-)

We'll add an option to udelay() in strategic places :)

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

A message that is not in the archive (sent off-list or not yet received): [email protected]

#18 lore raw

Re: [PATCH 7/7] Allow KVM from a normal QEMU binary

Quoted 10 lines · Anthony Liguori
Quoted 8 lines · Avi Kivity
Quoted 3 lines · Anthony Liguori

One of the things I was thinking of doing was getting rid of USE_KVM completely. What I was thinking of doing is moving kvmctl.[ch] into the QEMU tree

I'd like to keep kvmctl out, so that non-qemu based userspace can be built. True, I wouldn't like to be the one to do it, but I'd like to keep the possibility open.

Quoted 7 lines

Yeah, I'm on the fence myself. In the very least, we need a smarter configure check in QEMU to detect the presence of libkvm and enable the define appropriately.

I'll go as far as to say that once there's proper configure checks (and kvm fails gracefully), it would be appropriate to send it to qemu-devel. What are your thoughts?

Qemu-devel has been strangely nonresponsive to my patches (the x86-64 gdb patch was sent at least two months ago). Maybe as a known contributor they'll be more responsive to you.

The only other issue is how stable the interface is. I think that the kvmctl interface is almost there (I'd like to add a libkvm_open() and libkvm_close(), have kvm_create() use the context returned from libkvm_open(), and not create a vcpu and memory in kvm_create(), but these are fairly cosmetic).

The kernel interface is another matter. I want to apply Arnd's suggestions, but that's some time off. If we don't push libkvm/kvmctl to qemu then that's not an issue.

Quoted 7 lines
Quoted 4 lines

State transfer is what turned us of qemu. Reconstructing the state (esp. eflags and the segments) is quite difficult and there are some annoying qemu bugs (like the busy task flag checks).

The Xen tree already has the conversion code. It's annoying but it's not nearly as bad as say, shadow paging :-)

Well, a nice property of real mode is that it doesn't use shadow paging :)

Quoted 7 lines

While not necessarily in your scope, in the long term, having the state transfer would be really useful.

I can imagine KVM eventually supporting VT, SVM, user mode virtualization, and paravirtualization. State transfer use is useful for VT at least but is absolutely required for user mode virtualization.

What is user mode virtualization in this context?

Quoted 3 lines

All of these things exist in some form right now (user mode via qvm86 and para via lhype) and all are duplicating a lot of tough code (such as shadow paging).

Please elaborate.

Quoted 5 lines

Of course, state transfer won't be impossible to add down the road at some point so if you think big real mode will be easier with emulation, it wouldn't be that bad to give it a shot.

We already had real mode (and 16-bit protected, and 32-bit protected) during development. It should be very easy to add it back. I'm worried about maintenance and things like smp.

Quoted 10 lines
Quoted 9 lines

BTW, dumping qemu cpu emulation will allow us to use gcc 4.x instead of gcc 3.x.

Quoted 3 lines

SMP guest support is still a hard problem that needs thinking through but if Xen solves it, KVM can use the solution (or vice versa).

I don't see a huge problem. We'll have to get the APIC right, and the mmu locking right in the kernel, but what else?

Quoted 6 lines

It's not so bad provided you don't use QEMU for emulation. That's what I was referring to. There are some tricky cases where QEMU is accessing a piece of memory with an atomic instruction while another VCPU is running on bare metal and trying to touch the same memory. I suspect that as-is, QEMU would violate the atomic guarantees when it translates the instruction.

Ok. We're on the same cacheline then. An emulator definitely solves this.

(though I can't see real-mode locked instructions happening... maybe that's an issue with qemu emulating multiple instructions for Xen during mmio)

Signature · 8 lines
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

A message that is not in the archive (sent off-list or not yet received): 454E2DA4.8070405-atKUWr5tajBWk0Htik3J/[email protected]

#20 lore raw

Re: [PATCH 7/7] Allow KVM from a normal QEMU binary

Quoted 8 lines · Avi Kivity
Quoted 3 lines · Anthony Liguori

I'll go as far as to say that once there's proper configure checks (and kvm fails gracefully), it would be appropriate to send it to qemu-devel. What are your thoughts?

Qemu-devel has been strangely nonresponsive to my patches (the x86-64 gdb patch was sent at least two months ago). Maybe as a known contributor they'll be more responsive to you.

Fabrice can often miss patches for no other reason than I think he tends to deal with them in batches. Don't hesitate to resend patches and to CC him directly. He won't ignore patches because he doesn't like them.

Quoted 9 lines

The only other issue is how stable the interface is. I think that the kvmctl interface is almost there (I'd like to add a libkvm_open() and libkvm_close(), have kvm_create() use the context returned from libkvm_open(), and not create a vcpu and memory in kvm_create(), but these are fairly cosmetic).

The kernel interface is another matter. I want to apply Arnd's suggestions, but that's some time off. If we don't push libkvm/kvmctl to qemu then that's not an issue.

Right, I think that's the biggest argument for keeping libkvm so I'm happy with that for now.

Quoted 10 lines
Quoted 8 lines

While not necessarily in your scope, in the long term, having the state transfer would be really useful.

I can imagine KVM eventually supporting VT, SVM, user mode virtualization, and paravirtualization. State transfer use is useful for VT at least but is absolutely required for user mode virtualization.

What is user mode virtualization in this context?

Running ring 3 code on bare metal and then using QEMU to run ring 0/1/2 code. Surprisingly enough, it makes a pretty big impact. While not a total replacement for having VT/SVM, it's IMHO a pretty reasonable alternative for non VT/SVM chips.

Quoted 5 lines
Quoted 3 lines

All of these things exist in some form right now (user mode via qvm86 and para via lhype) and all are duplicating a lot of tough code (such as shadow paging).

Please elaborate.

Fundamentally, all these forms of virtualization follow the same idea--run some code directly on bare metal and run other code in an emulator. The only thing that separates the mechanisms is which code is run in the emulator and how the transition from bare metal to emulation is made.

For VT, the when is for 16 bit code and the how is via vmlaunch/vmexit combinations.

For SVM, then when is never (theoritically) and the how is via vmrun/vmexit.

For paravirtualization, the when is never (although I think using an emulator for 16 bit mode would still be useful here) and the how is hypercalls.

For user virtualization, the when is supervisor code and the how is privilege transitions.

All of these approaches require the same supporting code (IO emulation, shadow paging, etc.). While I think it's far too much to try and design for all of these things up front, I don't think it hurts to keep it in mind. Ideally, Linux could support all of these things and share the supporting code.

So, one of the reasons I think doing the transitioning with QEMU is a good idea is that I think it'll eventually be needed.

BTW, here are the respective links for qvm86 and lhype.

http://savannah.nongnu.org/projects/qvm86/ - qvm86

http://ozlabs.org/~rusty/paravirt - lhype.patch

Quoted 10 lines
Quoted 9 lines
Quoted 2 lines

I don't see a huge problem. We'll have to get the APIC right, and the mmu locking right in the kernel, but what else?

It's not so bad provided you don't use QEMU for emulation. That's what I was referring to. There are some tricky cases where QEMU is accessing a piece of memory with an atomic instruction while another VCPU is running on bare metal and trying to touch the same memory. I suspect that as-is, QEMU would violate the atomic guarantees when it translates the instruction.

Quoted 6 lines

Ok. We're on the same cacheline then. An emulator definitely solves this.

(though I can't see real-mode locked instructions happening... maybe that's an issue with qemu emulating multiple instructions for Xen during mmio)

Right, I presume that eventually you'll want to do emulation for MMIO so it would be necessary to deal with protected mode code.

I think enhancing the emulator to handle big real mode for now is a reasonable thing to do. Perhaps when we solve some of the SMP issues with V2E in Xen we can revisit this issue.

Regards,

Anthony Liguori

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642