Skip to contentSkip to conversation

Porting KVM to QEMU CVS

RFC In review Anthony Liguori 2 participants 5 messages Dec 18, 2006 – Dec 21, 2006 4 messages not in the archive

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

RFC 1/1 Porting KVM to QEMU CVS

I spent some time this weekend trying to port the KVM changes to the latest QEMU CVS. I got snagged on a certain changeset though. Specifically, the changeset on Sep 24th that added SMM support (and moved ACPI init to the BIOS) is where my patch stops working.

KVM dies with a bus error after real early in boot. The BIOS appears to be accessing a memory address at 0xa8000. With the latest CVS, this bus error doesn't occur but the guest never makes any progress (not even in the BIOS).

So far, my best guess is that the VGA area is no longer in 0xa0000-0xc0000 so the special handling of this is no longer valid. Although, I don't really know all that much about the legacy RAM space but I thought that the VGA area was pretty much fixed?

Any thoughts? Is anyone else working on this?

I've attached my patch for reference (it's minimal--it has none of the migration/vmdk stuff).

Regards,

Anthony Liguori

Makefile.target +9 -2
diff -r 8cf7c25fcede 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
@@ -322,6 +322,10 @@ endif
 endif
 ifdef CONFIG_ADLIB
 SOUND_HW += fmopl.o adlib.o
+endif
+ifdef CONFIG_KVM_KERNEL_INC
+DEFINES += -I $(CONFIG_KVM_KERNEL_INC)
+LIBS += -lkvm
 endif
 AUDIODRV+= wavcapture.o
 
@@ -485,6 +489,9 @@ endif
 endif
 
 cpu-exec.o: cpu-exec.c
+	$(CC) $(HELPER_CFLAGS) $(DEFINES) -c -o $@ $<
+
+qemu-kvm.o: qemu-kvm.c
 	$(CC) $(HELPER_CFLAGS) $(DEFINES) -c -o $@ $<
 
 ifeq ($(TARGET_BASE_ARCH), i386)
configure +14 -0
diff -r 8cf7c25fcede 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 8cf7c25fcede 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 +11 -0
diff -r 8cf7c25fcede cpu-exec.c
@@ -33,6 +33,11 @@
 #undef EIP
 #include <signal.h>
 #include <sys/ucontext.h>
+#endif
+
+#ifdef USE_KVM
+#include "qemu-kvm.h"
+extern int kvm_allowed;
 #endif
 
 int tb_invalidated_flag;
@@ -449,6 +454,12 @@ int cpu_exec(CPUState *env1)
             }
 #endif
 
+#ifdef USE_KVM
+            if (kvm_allowed) {
+                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 +19 -0
diff -r 8cf7c25fcede exec.c
@@ -68,6 +68,10 @@
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
 #endif
 
+#ifdef USE_KVM
+extern int kvm_allowed;
+#endif
+
 TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
 TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
 int nb_tbs;
@@ -81,6 +85,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 +1047,11 @@ int cpu_breakpoint_insert(CPUState *env,
     if (env->nb_breakpoints >= MAX_BREAKPOINTS)
         return -1;
     env->breakpoints[env->nb_breakpoints++] = pc;
+
+#ifdef USE_KVM
+    if (kvm_allowed)
+	kvm_update_debugger(env);
+#endif
     
     breakpoint_invalidate(env, pc);
     return 0;
@@ -1065,6 +1075,11 @@ int cpu_breakpoint_remove(CPUState *env,
     if (i < env->nb_breakpoints)
       env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
 
+#ifdef USE_KVM
+    if (kvm_allowed)
+	kvm_update_debugger(env);
+#endif
+    
     breakpoint_invalidate(env, pc);
     return 0;
 #else
@@ -1083,6 +1098,10 @@ void cpu_single_step(CPUState *env, int 
         /* XXX: only flush what is necessary */
         tb_flush(env);
     }
+#ifdef USE_KVM
+    if (kvm_allowed)
+	kvm_update_debugger(env);
+#endif
 #endif
 }
 
hw/cirrus_vga.c +121 -0

174 lines not on this page · raw message

hw/pc.c +33 -0
diff -r 8cf7c25fcede hw/pc.c
@@ -22,6 +22,10 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
+#ifdef USE_KVM
+#include "qemu-kvm.h"
+extern int kvm_allowed;
+#endif
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -605,6 +609,11 @@ static void pc_init_ne2k_isa(NICInfo *nd
     nb_ne2k++;
 }
 
+#ifdef USE_KVM
+extern kvm_context_t kvm_context;
+extern int kvm_allowed;
+#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 +683,11 @@ 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
+    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 */
     isa_bios_size = bios_size;
@@ -684,9 +698,28 @@ 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
+    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
+    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
     
     bochs_bios_init();
 
hw/usb-hid.c +3 -1
diff -r 8cf7c25fcede hw/usb-hid.c
@@ -169,7 +169,9 @@ static const uint8_t qemu_tablet_config_
 	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
  	0x03,       /*  u8  ep_bmAttributes; Interrupt */
  	0x08, 0x00, /*  u16 ep_wMaxPacketSize; */
-	0x03,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
+	/* Temporarily increase usb polling interval to prevent cpu
+	 * saturation (3 ms is way too often for kvm) */
+	0x33,       /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
 };
 
 static const uint8_t qemu_mouse_hid_report_descriptor[] = {
hw/vga.c +73 -0

114 lines not on this page · raw message

hw/vga_int.h +1 -0
diff -r 8cf7c25fcede hw/vga_int.h
@@ -174,5 +174,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 +18 -3
diff -r 8cf7c25fcede 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
@@ -487,6 +492,9 @@ typedef struct CPUX86State {
     target_ulong kernelgsbase;
 #endif
 
+#ifdef USE_KVM
+    uint64_t tsc; /* time stamp counter */
+#endif
     uint64_t pat;
 
     /* temporary data for USE_CODE_COPY mode */
@@ -524,6 +532,13 @@ typedef struct CPUX86State {
     int kqemu_enabled;
     int last_io_time;
 #endif
+
+#ifdef USE_KVM
+#define BITS_PER_LONG (8 * sizeof (long))
+#define NR_IRQ_WORDS (256/ BITS_PER_LONG)
+    unsigned long kvm_interrupt_bitmap[NR_IRQ_WORDS];
+#endif
+
     /* in order to simplify APIC support, we leave this pointer to the
        user */
     struct APICState *apic_state;
target-i386/helper.c +41 -1

86 lines not on this page · raw message

usb-linux.c +0 -1
diff -r 8cf7c25fcede usb-linux.c
@@ -26,7 +26,6 @@
 #if defined(__linux__)
 #include <dirent.h>
 #include <sys/ioctl.h>
-#include <linux/compiler.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/version.h>
 
vl.c +49 -1

109 lines not on this page · raw message

vl.h +5 -0
diff -r 8cf7c25fcede vl.h
@@ -149,6 +149,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;
@@ -160,6 +161,10 @@ extern int smp_cpus;
 #define BIOS_SIZE (128 * 1024)
 #else
 #define BIOS_SIZE ((256 + 64) * 1024)
+#endif
+
+#if USE_KVM
+#define KVM_EXTRA_PAGES 3
 #endif
 
 /* keyboard/mouse support */
qemu-kvm.c new file +648 -0

648 lines not on this page · raw message

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

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

_______________________________________________
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]

#2 lore raw
Quoted 10 lines · Anthony Liguori

I spent some time this weekend trying to port the KVM changes to the latest QEMU CVS. I got snagged on a certain changeset though. Specifically, the changeset on Sep 24th that added SMM support (and moved ACPI init to the BIOS) is where my patch stops working.

KVM dies with a bus error after real early in boot. The BIOS appears to be accessing a memory address at 0xa8000. With the latest CVS, this bus error doesn't occur but the guest never makes any progress (not even in the BIOS).

Quoted 6 lines

So far, my best guess is that the VGA area is no longer in 0xa0000-0xc0000 so the special handling of this is no longer valid. Although, I don't really know all that much about the legacy RAM space but I thought that the VGA area was pretty much fixed?

Any thoughts?

SMM continues the tradition of making each x86 generation hackier than before.

What happens (probably) is that the virtual hardware unmaps the vga memory when SMM is entered, and uses the physical memory at these addresses (which is not normally accessible) to store the SMI handler code.

The way to fix this (again, probably) is to:

1. Revert the 0-640K/1MB-end-of-memory slot thing and create just one memory slot for all physical RAM.
2. Add hacks in the memory slot code to not return a memory slot if the physical address is in the forbidden range.
3. Add another hack to disable the first hack when SMM is entered and re-enabled it when SMM is exited (e.g. some ioctl).

Quoted 1 line

Is anyone else working on this?

I intended to merge qemu once a release is made. However, if you get this working and it is stable, it may make sense to merge sooner as I very much like qemu cvs.

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


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

#4 lore raw
Quoted 6 lines · Avi Kivity
Quoted 1 line · Anthony Liguori

Any thoughts?

SMM continues the tradition of making each x86 generation hackier than before.

What happens (probably) is that the virtual hardware unmaps the vga memory when SMM is entered, and uses the physical memory at these addresses (which is not normally accessible) to store the SMI handler code.

Doh! SMM uses the VGA memory doesn't it. Now it all makes sense :-)

If I disable SMM in the Bochs BIOS, the patch works quite happily with the latest CVS. I've attached the patch for reference.

Quoted 3 lines

The way to fix this (again, probably) is to:

1. Revert the 0-640K/1MB-end-of-memory slot thing and create just one memory slot for all physical RAM.

We lose the VGA optimization here right?

Quoted 1 line

2. Add hacks in the memory slot code to not return a memory slot if the physical address is in the forbidden range.

I'm not sure I understand what you mean by this. I guess I have to spend some time and understand how the whole memory slot thing works.

Quoted 1 line

3. Add another hack to disable the first hack when SMM is entered and re-enabled it when SMM is exited (e.g. some ioctl).

I'll have to read a little more into SMM. It can be entered at any moment right? I seem to recall that either the VT or SVM spec has special handling for SMIs?

Another option to consider would simply be to have the BIOS detect whether or not the emulated hardware supports SMM dynamically (right now, it's a compile time switch). This would let us turn it off in QEMU when KVM is enabled.

Quoted 4 lines
Quoted 2 lines

Is anyone else working on this?

I intended to merge qemu once a release is made. However, if you get this working and it is stable, it may make sense to merge sooner as I very much like qemu cvs.

I would rather just submit this patch (with the BIOS hack) to QEMU and try and get it picked up in CVS. There are some regressions at the moment in CVS so it may be nice for users to have an 0.8.2 based version available. What do you think?

Would be nice to have KVM support in QEMU CVS by the time 2.6.20 rolls out.

Regards,

Anthony Liguori

? _rombios_.c
? _rombiosl_.c
? biossums
? rombios.s
? rombios.sym
? rombios.txt
? rombios16.bin
? rombios32.bin
? rombios32.out
? rombiosl.s
? rombiosl.sym
? rombiosl.txt
Index: BIOS-bochs-latest
===================================================================
RCS file: /cvsroot/bochs/bochs/bios/BIOS-bochs-latest,v retrieving revision 1.141
diff -u -r1.141 BIOS-bochs-latest
Binary files /tmp/cvsCh2IkN and BIOS-bochs-latest differ
Index: BIOS-bochs-legacy
===================================================================
RCS file: /cvsroot/bochs/bochs/bios/BIOS-bochs-legacy,v retrieving revision 1.5
diff -u -r1.5 BIOS-bochs-legacy
Binary files /tmp/cvsQC2QUQ and BIOS-bochs-legacy differ
Index: rombios.h
===================================================================
RCS file: /cvsroot/bochs/bochs/bios/rombios.h,v retrieving revision 1.3

rombios.h +1 -1
diff -u -r1.3 rombios.h
@@ -19,7 +19,7 @@
 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 
 /* define it to include QEMU specific code */
-//#define BX_QEMU
+#define BX_QEMU
 
 #ifndef LEGACY
 #  define BX_ROMBIOS32     1

Index: rombios32.c
===================================================================
RCS file: /cvsroot/bochs/bochs/bios/rombios32.c,v
retrieving revision 1.8

rombios32.c +6 -1
diff -u -r1.8 rombios32.c
@@ -38,7 +38,7 @@
 //#define BX_USE_EBDA_TABLES
 
 /* define it if the (emulated) hardware supports SMM mode */
-#define BX_USE_SMM
+//#define BX_USE_SMM
 
 #define cpuid(index, eax, ebx, ecx, edx) \
   asm volatile ("cpuid" \
@@ -852,6 +852,11 @@
     int ioapic_id, i, len;
     int mp_config_table_size;
 
+#ifdef BX_QEMU
+    if (smp_cpus <= 1)
+	return 1;
+#endif
+
 #ifdef BX_USE_EBDA_TABLES
     mp_config_table = (uint8_t *)(ram_size - ACPI_DATA_SIZE - MPTABLE_MAX_SIZE);
 #else

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

_______________________________________________
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]

#6 lore raw
Quoted 7 lines · Anthony Liguori
Quoted 6 lines · Avi Kivity
Quoted 1 line · Anthony Liguori

Any thoughts?

SMM continues the tradition of making each x86 generation hackier than before.

Quoted 6 lines
Quoted 4 lines

What happens (probably) is that the virtual hardware unmaps the vga memory when SMM is entered, and uses the physical memory at these addresses (which is not normally accessible) to store the SMI handler code.

Doh! SMM uses the VGA memory doesn't it. Now it all makes sense :-)

That last sentence is rarely heard in the context of PC architecture.

Quoted 10 lines

If I disable SMM in the Bochs BIOS, the patch works quite happily with the latest CVS. I've attached the patch for reference.

Quoted 4 lines

The way to fix this (again, probably) is to:

1. Revert the 0-640K/1MB-end-of-memory slot thing and create just one memory slot for all physical RAM.

We lose the VGA optimization here right?

No. The vga optimization is that access to the pci framebuffer (which is at a runtime-determined address, but not the vga hole) is through direct access rather than mmio. The code in cirrus.c that creates the framebuffer as a kvm memory slot is thy key to that optimization.

Quoted 6 lines
Quoted 3 lines

2. Add hacks in the memory slot code to not return a memory slot if the physical address is in the forbidden range.

I'm not sure I understand what you mean by this. I guess I have to spend some time and understand how the whole memory slot thing works.

Memory slots are just like the DIMM (or, since the qemu model is rather old, SIMM) slots in a PC.

A PC memory controller has circuitry to route memory access to a DIMM or to the PCI bus. The logic is something like this (first match wins):

- if the access is to the VGA hole, and we're not in SMM, route the access to PCI (the vga controller will route it further to somewhere in the framebuffer)
- if the access is to the VGA hole, and we are in SMM mode, route to the DIMM that contains the address
- if the access is to the ROM areas (0xf0000-0xfffff), route to the ROM
- if the access is to an area mapped by a DIMM, do that
- otherwise it's an mmio access

My proposal is to implement the special runtime routing table. This way we can have a DIMM that covers all of memory including the forbidden hole.

Entry into SMM will issue an ioctl() to remove the vga routing; exit from SMM will reinstall it.

Quoted 6 lines
Quoted 3 lines

3. Add another hack to disable the first hack when SMM is entered and re-enabled it when SMM is exited (e.g. some ioctl).

I'll have to read a little more into SMM. It can be entered at any moment right?

yes.

Quoted 2 lines

I seem to recall that either the VT or SVM spec has special handling for SMIs?

At least VT. It's horribly complex. It's meant more for the host rather than the guest.

Quoted 6 lines

Another option to consider would simply be to have the BIOS detect whether or not the emulated hardware supports SMM dynamically (right now, it's a compile time switch). This would let us turn it off in QEMU when KVM is enabled.

That may be best. What does SMM buy us anyway?

Quoted 7 lines
Quoted 6 lines
Quoted 2 lines

Is anyone else working on this?

I intended to merge qemu once a release is made. However, if you get this working and it is stable, it may make sense to merge sooner as I very much like qemu cvs.

Quoted 7 lines

I would rather just submit this patch (with the BIOS hack) to QEMU and try and get it picked up in CVS. There are some regressions at the moment in CVS so it may be nice for users to have an 0.8.2 based version available. What do you think?

Would be nice to have KVM support in QEMU CVS by the time 2.6.20 rolls out.

I'll reply to this in the next email, this one's too long already.

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


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

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

#8 lore raw
Quoted 22 lines · Avi Kivity
Quoted 6 lines
Quoted 3 lines

2. Add hacks in the memory slot code to not return a memory slot if the physical address is in the forbidden range.

I'm not sure I understand what you mean by this. I guess I have to spend some time and understand how the whole memory slot thing works.

Memory slots are just like the DIMM (or, since the qemu model is rather old, SIMM) slots in a PC.

A PC memory controller has circuitry to route memory access to a DIMM or to the PCI bus. The logic is something like this (first match wins):

- if the access is to the VGA hole, and we're not in SMM, route the access to PCI (the vga controller will route it further to somewhere in the framebuffer)
- if the access is to the VGA hole, and we are in SMM mode, route to the DIMM that contains the address
- if the access is to the ROM areas (0xf0000-0xfffff), route to the ROM
- if the access is to an area mapped by a DIMM, do that
- otherwise it's an mmio access

Quoted 3 lines

My proposal is to implement the special runtime routing table. This way we can have a DIMM that covers all of memory including the forbidden hole.

Okay, that makes sense.

Quoted 2 lines

Entry into SMM will issue an ioctl() to remove the vga routing; exit from SMM will reinstall it.

Right.

Quoted 7 lines
Quoted 5 lines

Another option to consider would simply be to have the BIOS detect whether or not the emulated hardware supports SMM dynamically (right now, it's a compile time switch). This would let us turn it off in QEMU when KVM is enabled.

That may be best. What does SMM buy us anyway?

I was hoping to be able to do this with something like CPUID but there isn't a bit. Right now I'm using PIO but I'd have to ask on the bochs mailing list whether or not this is a reasonable thing to do.

The current bochs bios doesn't really do anything with SMM. It merely enables or disables ACPI.

Regards,

Anthony Liguori

Quoted 13 lines
Quoted 13 lines
Quoted 7 lines
Quoted 3 lines

Is anyone else working on this?

I intended to merge qemu once a release is made. However, if you get this working and it is stable, it may make sense to merge sooner as I very much like qemu cvs.

I would rather just submit this patch (with the BIOS hack) to QEMU and try and get it picked up in CVS. There are some regressions at the moment in CVS so it may be nice for users to have an 0.8.2 based version available. What do you think?

Quoted 5 lines
Quoted 2 lines

Would be nice to have KVM support in QEMU CVS by the time 2.6.20 rolls out.

I'll reply to this in the next email, this one's too long already.

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV