Skip to contentSkip to conversation

kvm tools: Split x86 arch-specific bits into x86/

PATCH Applied Matt Evans 11 participants 105 messages Dec 6, 2011 – Dec 23, 2011 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore

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

Matt Evans

author
#1 lore raw

PATCH 1/28 kvm tools: Split x86 arch-specific bits into x86/

Create a new arch-specific subdirectory to contain architecture-specific code and includes.

The Makefile now adds various arch-specific objects based on detected architecture. That aside, this patch should only contain code moves. These include:

- x86-specific kvm_cpu setup, kernel loading, memory setup etc. now in x86/kvm{-cpu}.c
- BIOS now lives in x86/bios/
- ioport setup
- KVM extensions are asserted in arch-specific kvm.c now, so each architecture can manage its own dependencies.
- Various architecture-specific #defines are moved into $(ARCH)/include/kvm{-cpu}.h such as struct kvm_cpu, KVM_NR_CPUS, KVM_32BIT_GAP_SIZE.

---
 tools/kvm/Makefile                              |   96 ++++---
 tools/kvm/builtin-run.c                         |    6 +-
 tools/kvm/include/kvm/ioport.h                  |    2 +-
 tools/kvm/include/kvm/kvm-cpu.h                 |   27 +--
 tools/kvm/include/kvm/kvm.h                     |   58 +---
 tools/kvm/ioport.c                              |   54 ----
 tools/kvm/kvm-cpu.c                             |  372 ----------------------
 tools/kvm/kvm.c                                 |  323 +-------------------
 tools/kvm/{ => x86}/bios.c                      |    0
 tools/kvm/{ => x86}/bios/.gitignore             |    0
 tools/kvm/{ => x86}/bios/bios-rom.S             |    2 +-
 tools/kvm/{ => x86}/bios/e820.c                 |    0
 tools/kvm/{ => x86}/bios/entry.S                |    0
 tools/kvm/{ => x86}/bios/gen-offsets.sh         |    0
 tools/kvm/{ => x86}/bios/int10.c                |    0
 tools/kvm/{ => x86}/bios/int15.c                |    0
 tools/kvm/{ => x86}/bios/local.S                |    0
 tools/kvm/{ => x86}/bios/macro.S                |    0
 tools/kvm/{ => x86}/bios/memcpy.c               |    0
 tools/kvm/{ => x86}/bios/rom.ld.S               |    0
 tools/kvm/{ => x86}/cpuid.c                     |    0
 tools/kvm/{ => x86}/include/kvm/assembly.h      |    0
 tools/kvm/{ => x86}/include/kvm/barrier.h       |    0
 tools/kvm/{ => x86}/include/kvm/bios-export.h   |    0
 tools/kvm/{ => x86}/include/kvm/bios.h          |    0
 tools/kvm/{ => x86}/include/kvm/boot-protocol.h |    0
 tools/kvm/{ => x86}/include/kvm/cpufeature.h    |    0
 tools/kvm/{ => x86}/include/kvm/interrupt.h     |    0
 tools/kvm/x86/include/kvm/kvm-arch.h            |   59 ++++
 tools/kvm/x86/include/kvm/kvm-cpu-arch.h        |   33 ++
 tools/kvm/{ => x86}/include/kvm/mptable.h       |    0
 tools/kvm/{ => x86}/interrupt.c                 |    0
 tools/kvm/x86/ioport.c                          |   59 ++++
 tools/kvm/{ => x86}/irq.c                       |    0
 tools/kvm/x86/kvm-cpu.c                         |  383 +++++++++++++++++++++++
 tools/kvm/x86/kvm.c                             |  330 +++++++++++++++++++
 tools/kvm/{ => x86}/mptable.c                   |    0
 37 files changed, 951 insertions(+), 853 deletions(-)
 rename tools/kvm/{ => x86}/bios.c (100%)
 rename tools/kvm/{ => x86}/bios/.gitignore (100%)
 rename tools/kvm/{ => x86}/bios/bios-rom.S (80%)
 rename tools/kvm/{ => x86}/bios/e820.c (100%)
 rename tools/kvm/{ => x86}/bios/entry.S (100%)
 rename tools/kvm/{ => x86}/bios/gen-offsets.sh (100%)
 rename tools/kvm/{ => x86}/bios/int10.c (100%)
 rename tools/kvm/{ => x86}/bios/int15.c (100%)
 rename tools/kvm/{ => x86}/bios/local.S (100%)
 rename tools/kvm/{ => x86}/bios/macro.S (100%)
 rename tools/kvm/{ => x86}/bios/memcpy.c (100%)
 rename tools/kvm/{ => x86}/bios/rom.ld.S (100%)
 rename tools/kvm/{ => x86}/cpuid.c (100%)
 rename tools/kvm/{ => x86}/include/kvm/assembly.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/barrier.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/bios-export.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/bios.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/boot-protocol.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/cpufeature.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/interrupt.h (100%)
 create mode 100644 tools/kvm/x86/include/kvm/kvm-arch.h
 create mode 100644 tools/kvm/x86/include/kvm/kvm-cpu-arch.h
 rename tools/kvm/{ => x86}/include/kvm/mptable.h (100%)
 rename tools/kvm/{ => x86}/interrupt.c (100%)
 create mode 100644 tools/kvm/x86/ioport.c
 rename tools/kvm/{ => x86}/irq.c (100%)
 create mode 100644 tools/kvm/x86/kvm-cpu.c
 create mode 100644 tools/kvm/x86/kvm.c
 rename tools/kvm/{ => x86}/mptable.c (100%)
tools/kvm/Makefile +60 -36
index bb5f6b0..243886e 100644
@@ -33,13 +33,11 @@ OBJS	+= builtin-run.o
 OBJS	+= builtin-setup.o
 OBJS	+= builtin-stop.o
 OBJS	+= builtin-version.o
-OBJS	+= cpuid.o
 OBJS	+= disk/core.o
 OBJS	+= framebuffer.o
 OBJS	+= guest_compat.o
 OBJS	+= hw/rtc.o
 OBJS	+= hw/serial.o
-OBJS	+= interrupt.o
 OBJS	+= ioport.o
 OBJS	+= kvm-cpu.o
 OBJS	+= kvm.o
@@ -61,7 +59,6 @@ OBJS	+= disk/blk.o
 OBJS	+= disk/qcow.o
 OBJS	+= disk/raw.o
 OBJS	+= ioeventfd.o
-OBJS	+= irq.o
 OBJS	+= net/uip/core.o
 OBJS	+= net/uip/arp.o
 OBJS	+= net/uip/icmp.o
@@ -72,7 +69,6 @@ OBJS	+= net/uip/buf.o
 OBJS	+= net/uip/csum.o
 OBJS	+= net/uip/dhcp.o
 OBJS	+= kvm-cmd.o
-OBJS	+= mptable.o
 OBJS	+= rbtree.o
 OBJS	+= threadpool.o
 OBJS	+= util/parse-options.o
@@ -123,12 +119,6 @@ ifeq ($(has_AIO),y)
 	LIBS	+= -laio
 endif
 
-DEPS	:= $(patsubst %.o,%.d,$(OBJS))
-
-# Exclude BIOS object files from header dependencies.
-OBJS	+= bios.o
-OBJS	+= bios/bios-rom.o
-
 LIBS	+= -lrt
 LIBS	+= -lpthread
 LIBS	+= -lutil
@@ -150,12 +140,43 @@ ifeq ($(uname_M),x86_64)
 	DEFINES      += -DCONFIG_X86_64
 endif
 
+
+### Arch-specific stuff
+
+#x86
+ifeq ($(ARCH),x86)
+	DEFINES += -DCONFIG_X86
+	OBJS	+= x86/cpuid.o
+	OBJS	+= x86/interrupt.o
+	OBJS	+= x86/ioport.o
+	OBJS	+= x86/irq.o
+	OBJS	+= x86/kvm.o
+	OBJS	+= x86/kvm-cpu.o
+	OBJS	+= x86/mptable.o
+# Exclude BIOS object files from header dependencies.
+	OTHEROBJS	+= x86/bios.o
+	OTHEROBJS	+= x86/bios/bios-rom.o
+	ARCH_INCLUDE := x86/include
+endif
+
+###
+
+ifeq (,$(ARCH_INCLUDE))
+	UNSUPP_ERR = @echo "This architecture is not supported in kvmtool." && exit 1
+else
+	UNSUPP_ERR =
+endif
+
+DEPS	:= $(patsubst %.o,%.d,$(OBJS))
+OBJS	+= $(OTHEROBJS)
+
 DEFINES	+= -D_FILE_OFFSET_BITS=64
 DEFINES	+= -D_GNU_SOURCE
 DEFINES	+= -DKVMTOOLS_VERSION='"$(KVMTOOLS_VERSION)"'
+DEFINES	+= -DBUILD_ARCH='"$(ARCH)"'
 
 KVM_INCLUDE := include
-CFLAGS	+= $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -Os -g
+CFLAGS	+= $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I$(ARCH_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -Os -g
 
 ifneq ($(WERROR),0)
 	WARNINGS += -Werror
@@ -179,7 +200,10 @@ WARNINGS += -Wwrite-strings
 
 CFLAGS	+= $(WARNINGS)
 
-all: $(PROGRAM) $(GUEST_INIT)
+all: arch_support_check $(PROGRAM) $(GUEST_INIT)
+
+arch_support_check:
+	$(UNSUPP_ERR)
 
 KVMTOOLS-VERSION-FILE:
 	@$(SHELL_PATH) util/KVMTOOLS-VERSION-GEN $(OUTPUT)
@@ -227,33 +251,33 @@ BIOS_CFLAGS += -mregparm=3
 BIOS_CFLAGS += -fno-stack-protector
 BIOS_CFLAGS += -I../../arch/$(ARCH)
 
-bios.o: bios/bios.bin bios/bios-rom.h
-
-bios/bios.bin.elf: bios/entry.S bios/e820.c bios/int10.c bios/int15.c bios/rom.ld.S
-	$(E) "  CC       bios/memcpy.o"
-	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/memcpy.c -o bios/memcpy.o
-	$(E) "  CC       bios/e820.o"
-	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/e820.c -o bios/e820.o
-	$(E) "  CC       bios/int10.o"
-	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/int10.c -o bios/int10.o
-	$(E) "  CC       bios/int15.o"
-	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/int15.c -o bios/int15.o
-	$(E) "  CC       bios/entry.o"
-	$(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/entry.S -o bios/entry.o
+x86/bios.o: x86/bios/bios.bin x86/bios/bios-rom.h
+
+x86/bios/bios.bin.elf: x86/bios/entry.S x86/bios/e820.c x86/bios/int10.c x86/bios/int15.c x86/bios/rom.ld.S
+	$(E) "  CC       x86/bios/memcpy.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/memcpy.c -o x86/bios/memcpy.o
+	$(E) "  CC       x86/bios/e820.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/e820.c -o x86/bios/e820.o
+	$(E) "  CC       x86/bios/int10.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int10.c -o x86/bios/int10.o
+	$(E) "  CC       x86/bios/int15.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int15.c -o x86/bios/int15.o
+	$(E) "  CC       x86/bios/entry.o"
+	$(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/entry.S -o x86/bios/entry.o
 	$(E) "  LD      " $@
-	$(Q) ld -T bios/rom.ld.S -o bios/bios.bin.elf bios/memcpy.o bios/entry.o bios/e820.o bios/int10.o bios/int15.o
+	$(Q) ld -T x86/bios/rom.ld.S -o x86/bios/bios.bin.elf x86/bios/memcpy.o x86/bios/entry.o x86/bios/e820.o x86/bios/int10.o x86/bios/int15.o
 
-bios/bios.bin: bios/bios.bin.elf
+x86/bios/bios.bin: x86/bios/bios.bin.elf
 	$(E) "  OBJCOPY " $@
-	$(Q) objcopy -O binary -j .text bios/bios.bin.elf bios/bios.bin
+	$(Q) objcopy -O binary -j .text x86/bios/bios.bin.elf x86/bios/bios.bin
 
-bios/bios-rom.o: bios/bios-rom.S bios/bios.bin bios/bios-rom.h
+x86/bios/bios-rom.o: x86/bios/bios-rom.S x86/bios/bios.bin x86/bios/bios-rom.h
 	$(E) "  CC      " $@
-	$(Q) $(CC) -c $(CFLAGS) bios/bios-rom.S -o bios/bios-rom.o
+	$(Q) $(CC) -c $(CFLAGS) x86/bios/bios-rom.S -o x86/bios/bios-rom.o
 
-bios/bios-rom.h: bios/bios.bin.elf
+x86/bios/bios-rom.h: x86/bios/bios.bin.elf
 	$(E) "  NM      " $@
-	$(Q) cd bios && sh gen-offsets.sh > bios-rom.h && cd ..
+	$(Q) cd x86/bios && sh gen-offsets.sh > bios-rom.h && cd ..
 
 check: $(PROGRAM)
 	$(MAKE) -C tests
@@ -263,10 +287,10 @@ check: $(PROGRAM)
 
 clean:
 	$(E) "  CLEAN"
-	$(Q) rm -f bios/*.bin
-	$(Q) rm -f bios/*.elf
-	$(Q) rm -f bios/*.o
-	$(Q) rm -f bios/bios-rom.h
+	$(Q) rm -f x86/bios/*.bin
+	$(Q) rm -f x86/bios/*.elf
+	$(Q) rm -f x86/bios/*.o
+	$(Q) rm -f x86/bios/bios-rom.h
 	$(Q) rm -f tests/boot/boot_test.iso
 	$(Q) rm -rf tests/boot/rootfs/
 	$(Q) rm -f $(DEPS) $(OBJS) $(PROGRAM) $(GUEST_INIT)
tools/kvm/builtin-run.c +3 -3
index 33de4f6..9148d83 100644
@@ -568,7 +568,7 @@ static const char *host_kernels[] = {
 
 static const char *default_kernels[] = {
 	"./bzImage",
-	"../../arch/x86/boot/bzImage",
+	"../../arch/" BUILD_ARCH "/boot/bzImage",
 	NULL
 };
 
@@ -886,7 +886,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm->vmlinux		= vmlinux_filename;
 
-	ioport__setup_legacy();
+	ioport__setup_arch();
 
 	rtc__init();
 
@@ -931,7 +931,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm__start_timer(kvm);
 
-	kvm__setup_bios(kvm);
+	kvm__arch_setup_firmware(kvm);
 
 	for (i = 0; i < nrcpus; i++) {
 		kvm_cpus[i] = kvm_cpu__init(kvm, i);
tools/kvm/include/kvm/ioport.h +1 -1
index 5b857dd..61a70ec 100644
@@ -28,7 +28,7 @@ struct ioport_operations {
 	bool (*io_out)(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size);
 };
 
-void ioport__setup_legacy(void);
+void ioport__setup_arch(void);
 
 u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *param);
 
tools/kvm/include/kvm/kvm-cpu.h +1 -26
index 01540ac..719e286 100644
@@ -1,32 +1,7 @@
 #ifndef KVM__KVM_CPU_H
 #define KVM__KVM_CPU_H
 
-#include <linux/kvm.h>	/* for struct kvm_regs */
-
-#include <pthread.h>
-
-struct kvm;
-
-struct kvm_cpu {
-	pthread_t		thread;		/* VCPU thread */
-
-	unsigned long		cpu_id;
-
-	struct kvm		*kvm;		/* parent KVM */
-	int			vcpu_fd;	/* For VCPU ioctls() */
-	struct kvm_run		*kvm_run;
-
-	struct kvm_regs		regs;
-	struct kvm_sregs	sregs;
-	struct kvm_fpu		fpu;
-
-	struct kvm_msrs		*msrs;		/* dynamically allocated */
-
-	u8			is_running;
-	u8			paused;
-
-	struct kvm_coalesced_mmio_ring	*ring;
-};
+#include "kvm/kvm-cpu-arch.h"
 
 struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id);
 void kvm_cpu__delete(struct kvm_cpu *vcpu);
tools/kvm/include/kvm/kvm.h +15 -43

94 lines not on this page · raw message

tools/kvm/ioport.c +0 -54

63 lines not on this page · raw message

tools/kvm/kvm-cpu.c +0 -372

399 lines not on this page · raw message

tools/kvm/kvm.c +6 -317

400 lines not on this page · raw message

tools/kvm/x86/bios.c renamed from tools/kvm/bios.c +0 -0
similarity index 100%
rename from tools/kvm/bios.c
rename to tools/kvm/x86/bios.c
tools/kvm/x86/bios/.gitignore renamed from tools/kvm/bios/.gitignore +0 -0
similarity index 100%
rename from tools/kvm/bios/.gitignore
rename to tools/kvm/x86/bios/.gitignore
tools/kvm/x86/bios/bios-rom.S renamed from tools/kvm/bios/bios-rom.S +1 -1
similarity index 80%
rename from tools/kvm/bios/bios-rom.S
rename to tools/kvm/x86/bios/bios-rom.S
index dc52b1e..3269ce9 100644
@@ -8,5 +8,5 @@
 #endif
 
 GLOBAL(bios_rom)
-	.incbin "bios/bios.bin"
+	.incbin "x86/bios/bios.bin"
 END(bios_rom)
tools/kvm/x86/bios/e820.c renamed from tools/kvm/bios/e820.c +0 -0
similarity index 100%
rename from tools/kvm/bios/e820.c
rename to tools/kvm/x86/bios/e820.c
tools/kvm/x86/bios/entry.S renamed from tools/kvm/bios/entry.S +0 -0
similarity index 100%
rename from tools/kvm/bios/entry.S
rename to tools/kvm/x86/bios/entry.S
tools/kvm/x86/bios/gen-offsets.sh renamed from tools/kvm/bios/gen-offsets.sh +0 -0
similarity index 100%
rename from tools/kvm/bios/gen-offsets.sh
rename to tools/kvm/x86/bios/gen-offsets.sh
tools/kvm/x86/bios/int10.c renamed from tools/kvm/bios/int10.c +0 -0
similarity index 100%
rename from tools/kvm/bios/int10.c
rename to tools/kvm/x86/bios/int10.c
tools/kvm/x86/bios/int15.c renamed from tools/kvm/bios/int15.c +0 -0
similarity index 100%
rename from tools/kvm/bios/int15.c
rename to tools/kvm/x86/bios/int15.c
tools/kvm/x86/bios/local.S renamed from tools/kvm/bios/local.S +0 -0
similarity index 100%
rename from tools/kvm/bios/local.S
rename to tools/kvm/x86/bios/local.S
tools/kvm/x86/bios/macro.S renamed from tools/kvm/bios/macro.S +0 -0
similarity index 100%
rename from tools/kvm/bios/macro.S
rename to tools/kvm/x86/bios/macro.S
tools/kvm/x86/bios/memcpy.c renamed from tools/kvm/bios/memcpy.c +0 -0
similarity index 100%
rename from tools/kvm/bios/memcpy.c
rename to tools/kvm/x86/bios/memcpy.c
tools/kvm/x86/bios/rom.ld.S renamed from tools/kvm/bios/rom.ld.S +0 -0
similarity index 100%
rename from tools/kvm/bios/rom.ld.S
rename to tools/kvm/x86/bios/rom.ld.S
tools/kvm/x86/cpuid.c renamed from tools/kvm/cpuid.c +0 -0
similarity index 100%
rename from tools/kvm/cpuid.c
rename to tools/kvm/x86/cpuid.c
tools/kvm/x86/include/kvm/assembly.h renamed from tools/kvm/include/kvm/assembly.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/assembly.h
rename to tools/kvm/x86/include/kvm/assembly.h
tools/kvm/x86/include/kvm/barrier.h renamed from tools/kvm/include/kvm/barrier.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/barrier.h
rename to tools/kvm/x86/include/kvm/barrier.h
tools/kvm/x86/include/kvm/bios-export.h renamed from tools/kvm/include/kvm/bios-export.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/bios-export.h
rename to tools/kvm/x86/include/kvm/bios-export.h
tools/kvm/x86/include/kvm/bios.h renamed from tools/kvm/include/kvm/bios.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/bios.h
rename to tools/kvm/x86/include/kvm/bios.h
tools/kvm/x86/include/kvm/boot-protocol.h renamed from tools/kvm/include/kvm/boot-protocol.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/boot-protocol.h
rename to tools/kvm/x86/include/kvm/boot-protocol.h
tools/kvm/x86/include/kvm/cpufeature.h renamed from tools/kvm/include/kvm/cpufeature.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/cpufeature.h
rename to tools/kvm/x86/include/kvm/cpufeature.h
tools/kvm/x86/include/kvm/interrupt.h renamed from tools/kvm/include/kvm/interrupt.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/interrupt.h
rename to tools/kvm/x86/include/kvm/interrupt.h
tools/kvm/x86/include/kvm/kvm-arch.h new file +59 -0

59 lines not on this page · raw message

tools/kvm/x86/include/kvm/kvm-cpu-arch.h new file +33 -0
new file mode 100644
index 0000000..ed1c727
@@ -0,0 +1,33 @@
+#ifndef KVM__KVM_CPU_ARCH_H
+#define KVM__KVM_CPU_ARCH_H
+
+/* Architecture-specific kvm_cpu definitions. */
+
+#include <linux/kvm.h>	/* for struct kvm_regs */
+
+#include <pthread.h>
+
+struct kvm;
+
+struct kvm_cpu {
+	pthread_t		thread;		/* VCPU thread */
+
+	unsigned long		cpu_id;
+
+	struct kvm		*kvm;		/* parent KVM */
+	int			vcpu_fd;	/* For VCPU ioctls() */
+	struct kvm_run		*kvm_run;
+
+	struct kvm_regs		regs;
+	struct kvm_sregs	sregs;
+	struct kvm_fpu		fpu;
+
+	struct kvm_msrs		*msrs;		/* dynamically allocated */
+
+	u8			is_running;
+	u8			paused;
+
+	struct kvm_coalesced_mmio_ring	*ring;
+};
+
+#endif /* KVM__KVM_CPU_ARCH_H */
tools/kvm/x86/include/kvm/mptable.h renamed from tools/kvm/include/kvm/mptable.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/mptable.h
rename to tools/kvm/x86/include/kvm/mptable.h
tools/kvm/x86/interrupt.c renamed from tools/kvm/interrupt.c +0 -0
similarity index 100%
rename from tools/kvm/interrupt.c
rename to tools/kvm/x86/interrupt.c
tools/kvm/x86/ioport.c new file +59 -0

59 lines not on this page · raw message

tools/kvm/x86/irq.c renamed from tools/kvm/irq.c +0 -0
similarity index 100%
rename from tools/kvm/irq.c
rename to tools/kvm/x86/irq.c
tools/kvm/x86/kvm-cpu.c new file +383 -0

383 lines not on this page · raw message

tools/kvm/x86/kvm.c new file +330 -0

330 lines not on this page · raw message

tools/kvm/x86/mptable.c renamed from tools/kvm/mptable.c +0 -0
similarity index 100%
rename from tools/kvm/mptable.c
rename to tools/kvm/x86/mptable.c
#2 lore raw

The code doesn't build after this patch due to missing header issues which you fixed in patches #10 & #11. Could you please move those two to the beginning of the series for the sake of bisectablilty?

Quoted 2,339 lines · Matt Evans

Create a new arch-specific subdirectory to contain architecture-specific code and includes.

The Makefile now adds various arch-specific objects based on detected architecture. That aside, this patch should only contain code moves. These include:

- x86-specific kvm_cpu setup, kernel loading, memory setup etc. now in x86/kvm{-cpu}.c
- BIOS now lives in x86/bios/
- ioport setup
- KVM extensions are asserted in arch-specific kvm.c now, so each architecture can manage its own dependencies.
- Various architecture-specific #defines are moved into $(ARCH)/include/kvm{-cpu}.h such as struct kvm_cpu, KVM_NR_CPUS, KVM_32BIT_GAP_SIZE.

---
 tools/kvm/Makefile                              |   96 ++++---
 tools/kvm/builtin-run.c                         |    6 +-
 tools/kvm/include/kvm/ioport.h                  |    2 +-
 tools/kvm/include/kvm/kvm-cpu.h                 |   27 +--
 tools/kvm/include/kvm/kvm.h                     |   58 +---
 tools/kvm/ioport.c                              |   54 ----
 tools/kvm/kvm-cpu.c                             |  372 ----------------------
 tools/kvm/kvm.c                                 |  323 +-------------------
 tools/kvm/{ => x86}/bios.c                      |    0
 tools/kvm/{ => x86}/bios/.gitignore             |    0
 tools/kvm/{ => x86}/bios/bios-rom.S             |    2 +-
 tools/kvm/{ => x86}/bios/e820.c                 |    0
 tools/kvm/{ => x86}/bios/entry.S                |    0
 tools/kvm/{ => x86}/bios/gen-offsets.sh         |    0
 tools/kvm/{ => x86}/bios/int10.c                |    0
 tools/kvm/{ => x86}/bios/int15.c                |    0
 tools/kvm/{ => x86}/bios/local.S                |    0
 tools/kvm/{ => x86}/bios/macro.S                |    0
 tools/kvm/{ => x86}/bios/memcpy.c               |    0
 tools/kvm/{ => x86}/bios/rom.ld.S               |    0
 tools/kvm/{ => x86}/cpuid.c                     |    0
 tools/kvm/{ => x86}/include/kvm/assembly.h      |    0
 tools/kvm/{ => x86}/include/kvm/barrier.h       |    0
 tools/kvm/{ => x86}/include/kvm/bios-export.h   |    0
 tools/kvm/{ => x86}/include/kvm/bios.h          |    0
 tools/kvm/{ => x86}/include/kvm/boot-protocol.h |    0
 tools/kvm/{ => x86}/include/kvm/cpufeature.h    |    0
 tools/kvm/{ => x86}/include/kvm/interrupt.h     |    0
 tools/kvm/x86/include/kvm/kvm-arch.h            |   59 ++++
 tools/kvm/x86/include/kvm/kvm-cpu-arch.h        |   33 ++
 tools/kvm/{ => x86}/include/kvm/mptable.h       |    0
 tools/kvm/{ => x86}/interrupt.c                 |    0
 tools/kvm/x86/ioport.c                          |   59 ++++
 tools/kvm/{ => x86}/irq.c                       |    0
 tools/kvm/x86/kvm-cpu.c                         |  383 +++++++++++++++++++++++
 tools/kvm/x86/kvm.c                             |  330 +++++++++++++++++++
 tools/kvm/{ => x86}/mptable.c                   |    0
 37 files changed, 951 insertions(+), 853 deletions(-)
 rename tools/kvm/{ => x86}/bios.c (100%)
 rename tools/kvm/{ => x86}/bios/.gitignore (100%)
 rename tools/kvm/{ => x86}/bios/bios-rom.S (80%)
 rename tools/kvm/{ => x86}/bios/e820.c (100%)
 rename tools/kvm/{ => x86}/bios/entry.S (100%)
 rename tools/kvm/{ => x86}/bios/gen-offsets.sh (100%)
 rename tools/kvm/{ => x86}/bios/int10.c (100%)
 rename tools/kvm/{ => x86}/bios/int15.c (100%)
 rename tools/kvm/{ => x86}/bios/local.S (100%)
 rename tools/kvm/{ => x86}/bios/macro.S (100%)
 rename tools/kvm/{ => x86}/bios/memcpy.c (100%)
 rename tools/kvm/{ => x86}/bios/rom.ld.S (100%)
 rename tools/kvm/{ => x86}/cpuid.c (100%)
 rename tools/kvm/{ => x86}/include/kvm/assembly.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/barrier.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/bios-export.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/bios.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/boot-protocol.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/cpufeature.h (100%)
 rename tools/kvm/{ => x86}/include/kvm/interrupt.h (100%)
 create mode 100644 tools/kvm/x86/include/kvm/kvm-arch.h
 create mode 100644 tools/kvm/x86/include/kvm/kvm-cpu-arch.h
 rename tools/kvm/{ => x86}/include/kvm/mptable.h (100%)
 rename tools/kvm/{ => x86}/interrupt.c (100%)
 create mode 100644 tools/kvm/x86/ioport.c
 rename tools/kvm/{ => x86}/irq.c (100%)
 create mode 100644 tools/kvm/x86/kvm-cpu.c
 create mode 100644 tools/kvm/x86/kvm.c
 rename tools/kvm/{ => x86}/mptable.c (100%)
tools/kvm/Makefile +60 -36
index bb5f6b0..243886e 100644
@@ -33,13 +33,11 @@ OBJS	+= builtin-run.o
 OBJS	+= builtin-setup.o
 OBJS	+= builtin-stop.o
 OBJS	+= builtin-version.o
-OBJS	+= cpuid.o
 OBJS	+= disk/core.o
 OBJS	+= framebuffer.o
 OBJS	+= guest_compat.o
 OBJS	+= hw/rtc.o
 OBJS	+= hw/serial.o
-OBJS	+= interrupt.o
 OBJS	+= ioport.o
 OBJS	+= kvm-cpu.o
 OBJS	+= kvm.o
@@ -61,7 +59,6 @@ OBJS	+= disk/blk.o
 OBJS	+= disk/qcow.o
 OBJS	+= disk/raw.o
 OBJS	+= ioeventfd.o
-OBJS	+= irq.o
 OBJS	+= net/uip/core.o
 OBJS	+= net/uip/arp.o
 OBJS	+= net/uip/icmp.o
@@ -72,7 +69,6 @@ OBJS	+= net/uip/buf.o
 OBJS	+= net/uip/csum.o
 OBJS	+= net/uip/dhcp.o
 OBJS	+= kvm-cmd.o
-OBJS	+= mptable.o
 OBJS	+= rbtree.o
 OBJS	+= threadpool.o
 OBJS	+= util/parse-options.o
@@ -123,12 +119,6 @@ ifeq ($(has_AIO),y)
 	LIBS	+= -laio
 endif
 
-DEPS	:= $(patsubst %.o,%.d,$(OBJS))
-
-# Exclude BIOS object files from header dependencies.
-OBJS	+= bios.o
-OBJS	+= bios/bios-rom.o
-
 LIBS	+= -lrt
 LIBS	+= -lpthread
 LIBS	+= -lutil
@@ -150,12 +140,43 @@ ifeq ($(uname_M),x86_64)
 	DEFINES      += -DCONFIG_X86_64
 endif
 
+
+### Arch-specific stuff
+
+#x86
+ifeq ($(ARCH),x86)
+	DEFINES += -DCONFIG_X86
+	OBJS	+= x86/cpuid.o
+	OBJS	+= x86/interrupt.o
+	OBJS	+= x86/ioport.o
+	OBJS	+= x86/irq.o
+	OBJS	+= x86/kvm.o
+	OBJS	+= x86/kvm-cpu.o
+	OBJS	+= x86/mptable.o
+# Exclude BIOS object files from header dependencies.
+	OTHEROBJS	+= x86/bios.o
+	OTHEROBJS	+= x86/bios/bios-rom.o
+	ARCH_INCLUDE := x86/include
+endif
+
+###
+
+ifeq (,$(ARCH_INCLUDE))
+	UNSUPP_ERR = @echo "This architecture is not supported in kvmtool." && exit 1
+else
+	UNSUPP_ERR =
+endif
+
+DEPS	:= $(patsubst %.o,%.d,$(OBJS))
+OBJS	+= $(OTHEROBJS)
+
 DEFINES	+= -D_FILE_OFFSET_BITS=64
 DEFINES	+= -D_GNU_SOURCE
 DEFINES	+= -DKVMTOOLS_VERSION='"$(KVMTOOLS_VERSION)"'
+DEFINES	+= -DBUILD_ARCH='"$(ARCH)"'
 
 KVM_INCLUDE := include
-CFLAGS	+= $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -Os -g
+CFLAGS	+= $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I$(ARCH_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -Os -g
 
 ifneq ($(WERROR),0)
 	WARNINGS += -Werror
@@ -179,7 +200,10 @@ WARNINGS += -Wwrite-strings
 
 CFLAGS	+= $(WARNINGS)
 
-all: $(PROGRAM) $(GUEST_INIT)
+all: arch_support_check $(PROGRAM) $(GUEST_INIT)
+
+arch_support_check:
+	$(UNSUPP_ERR)
 
 KVMTOOLS-VERSION-FILE:
 	@$(SHELL_PATH) util/KVMTOOLS-VERSION-GEN $(OUTPUT)
@@ -227,33 +251,33 @@ BIOS_CFLAGS += -mregparm=3
 BIOS_CFLAGS += -fno-stack-protector
 BIOS_CFLAGS += -I../../arch/$(ARCH)
 
-bios.o: bios/bios.bin bios/bios-rom.h
-
-bios/bios.bin.elf: bios/entry.S bios/e820.c bios/int10.c bios/int15.c bios/rom.ld.S
-	$(E) "  CC       bios/memcpy.o"
-	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/memcpy.c -o bios/memcpy.o
-	$(E) "  CC       bios/e820.o"
-	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/e820.c -o bios/e820.o
-	$(E) "  CC       bios/int10.o"
-	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/int10.c -o bios/int10.o
-	$(E) "  CC       bios/int15.o"
-	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/int15.c -o bios/int15.o
-	$(E) "  CC       bios/entry.o"
-	$(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/entry.S -o bios/entry.o
+x86/bios.o: x86/bios/bios.bin x86/bios/bios-rom.h
+
+x86/bios/bios.bin.elf: x86/bios/entry.S x86/bios/e820.c x86/bios/int10.c x86/bios/int15.c x86/bios/rom.ld.S
+	$(E) "  CC       x86/bios/memcpy.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/memcpy.c -o x86/bios/memcpy.o
+	$(E) "  CC       x86/bios/e820.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/e820.c -o x86/bios/e820.o
+	$(E) "  CC       x86/bios/int10.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int10.c -o x86/bios/int10.o
+	$(E) "  CC       x86/bios/int15.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int15.c -o x86/bios/int15.o
+	$(E) "  CC       x86/bios/entry.o"
+	$(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/entry.S -o x86/bios/entry.o
 	$(E) "  LD      " $@
-	$(Q) ld -T bios/rom.ld.S -o bios/bios.bin.elf bios/memcpy.o bios/entry.o bios/e820.o bios/int10.o bios/int15.o
+	$(Q) ld -T x86/bios/rom.ld.S -o x86/bios/bios.bin.elf x86/bios/memcpy.o x86/bios/entry.o x86/bios/e820.o x86/bios/int10.o x86/bios/int15.o
 
-bios/bios.bin: bios/bios.bin.elf
+x86/bios/bios.bin: x86/bios/bios.bin.elf
 	$(E) "  OBJCOPY " $@
-	$(Q) objcopy -O binary -j .text bios/bios.bin.elf bios/bios.bin
+	$(Q) objcopy -O binary -j .text x86/bios/bios.bin.elf x86/bios/bios.bin
 
-bios/bios-rom.o: bios/bios-rom.S bios/bios.bin bios/bios-rom.h
+x86/bios/bios-rom.o: x86/bios/bios-rom.S x86/bios/bios.bin x86/bios/bios-rom.h
 	$(E) "  CC      " $@
-	$(Q) $(CC) -c $(CFLAGS) bios/bios-rom.S -o bios/bios-rom.o
+	$(Q) $(CC) -c $(CFLAGS) x86/bios/bios-rom.S -o x86/bios/bios-rom.o
 
-bios/bios-rom.h: bios/bios.bin.elf
+x86/bios/bios-rom.h: x86/bios/bios.bin.elf
 	$(E) "  NM      " $@
-	$(Q) cd bios && sh gen-offsets.sh > bios-rom.h && cd ..
+	$(Q) cd x86/bios && sh gen-offsets.sh > bios-rom.h && cd ..
 
 check: $(PROGRAM)
 	$(MAKE) -C tests
@@ -263,10 +287,10 @@ check: $(PROGRAM)
 
 clean:
 	$(E) "  CLEAN"
-	$(Q) rm -f bios/*.bin
-	$(Q) rm -f bios/*.elf
-	$(Q) rm -f bios/*.o
-	$(Q) rm -f bios/bios-rom.h
+	$(Q) rm -f x86/bios/*.bin
+	$(Q) rm -f x86/bios/*.elf
+	$(Q) rm -f x86/bios/*.o
+	$(Q) rm -f x86/bios/bios-rom.h
 	$(Q) rm -f tests/boot/boot_test.iso
 	$(Q) rm -rf tests/boot/rootfs/
 	$(Q) rm -f $(DEPS) $(OBJS) $(PROGRAM) $(GUEST_INIT)
tools/kvm/builtin-run.c +3 -3
index 33de4f6..9148d83 100644
@@ -568,7 +568,7 @@ static const char *host_kernels[] = {
 
 static const char *default_kernels[] = {
 	"./bzImage",
-	"../../arch/x86/boot/bzImage",
+	"../../arch/" BUILD_ARCH "/boot/bzImage",
 	NULL
 };
 
@@ -886,7 +886,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm->vmlinux		= vmlinux_filename;
 
-	ioport__setup_legacy();
+	ioport__setup_arch();
 
 	rtc__init();
 
@@ -931,7 +931,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm__start_timer(kvm);
 
-	kvm__setup_bios(kvm);
+	kvm__arch_setup_firmware(kvm);
 
 	for (i = 0; i < nrcpus; i++) {
 		kvm_cpus[i] = kvm_cpu__init(kvm, i);
tools/kvm/include/kvm/ioport.h +1 -1
index 5b857dd..61a70ec 100644
@@ -28,7 +28,7 @@ struct ioport_operations {
 	bool (*io_out)(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size);
 };
 
-void ioport__setup_legacy(void);
+void ioport__setup_arch(void);
 
 u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *param);
 
tools/kvm/include/kvm/kvm-cpu.h +1 -26
index 01540ac..719e286 100644
@@ -1,32 +1,7 @@
 #ifndef KVM__KVM_CPU_H
 #define KVM__KVM_CPU_H
 
-#include <linux/kvm.h>	/* for struct kvm_regs */
-
-#include <pthread.h>
-
-struct kvm;
-
-struct kvm_cpu {
-	pthread_t		thread;		/* VCPU thread */
-
-	unsigned long		cpu_id;
-
-	struct kvm		*kvm;		/* parent KVM */
-	int			vcpu_fd;	/* For VCPU ioctls() */
-	struct kvm_run		*kvm_run;
-
-	struct kvm_regs		regs;
-	struct kvm_sregs	sregs;
-	struct kvm_fpu		fpu;
-
-	struct kvm_msrs		*msrs;		/* dynamically allocated */
-
-	u8			is_running;
-	u8			paused;
-
-	struct kvm_coalesced_mmio_ring	*ring;
-};
+#include "kvm/kvm-cpu-arch.h"
 
 struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id);
 void kvm_cpu__delete(struct kvm_cpu *vcpu);
tools/kvm/include/kvm/kvm.h +15 -43
index 2b3024a..ca1acc0 100644
@@ -1,22 +1,13 @@
 #ifndef KVM__KVM_H
 #define KVM__KVM_H
 
-#include "kvm/interrupt.h"
-#include "kvm/segment.h"
+#include "kvm/kvm-arch.h"
 
 #include <stdbool.h>
 #include <linux/types.h>
 #include <time.h>
 #include <signal.h>
 
-#define KVM_NR_CPUS		(255)
-
-/*
- * The hole includes VESA framebuffer and PCI memory.
- */
-#define KVM_32BIT_GAP_SIZE	(768 << 20)
-#define KVM_32BIT_GAP_START	((1ULL << 32) - KVM_32BIT_GAP_SIZE)
-
 #define SIGKVMEXIT		(SIGRTMIN + 0)
 #define SIGKVMPAUSE		(SIGRTMIN + 1)
 #define SIGKVMSTOP		(SIGRTMIN + 4)
@@ -25,33 +16,15 @@
 #define KVM_PID_FILE_PATH	"/.kvm-tools/"
 #define HOME_DIR		getenv("HOME")
 
-struct kvm {
-	int			sys_fd;		/* For system ioctls(), i.e. /dev/kvm */
-	int			vm_fd;		/* For VM ioctls() */
-	timer_t			timerid;	/* Posix timer for interrupts */
-
-	int			nrcpus;		/* Number of cpus to run */
-
-	u32			mem_slots;	/* for KVM_SET_USER_MEMORY_REGION */
-
-	u64			ram_size;
-	void			*ram_start;
-
-	bool			nmi_disabled;
-
-	bool			single_step;
+#define PAGE_SIZE (sysconf(_SC_PAGE_SIZE))
 
-	u16			boot_selector;
-	u16			boot_ip;
-	u16			boot_sp;
+#define DEFINE_KVM_EXT(ext)		\
+	.name = #ext,			\
+	.code = ext
 
-	struct interrupt_table	interrupt_table;
-
-	const char		*vmlinux;
-	struct disk_image       **disks;
-	int                     nr_disks;
-
-	const char		*name;
+struct kvm_ext {
+	const char *name;
+	int code;
 };
 
 void kvm__set_dir(const char *fmt, ...);
@@ -64,7 +37,6 @@ void kvm__init_ram(struct kvm *kvm);
 void kvm__delete(struct kvm *kvm);
 bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
 			const char *initrd_filename, const char *kernel_cmdline, u16 vidmode);
-void kvm__setup_bios(struct kvm *kvm);
 void kvm__start_timer(struct kvm *kvm);
 void kvm__stop_timer(struct kvm *kvm);
 void kvm__irq_line(struct kvm *kvm, int irq, int level);
@@ -81,6 +53,13 @@ int kvm__get_sock_by_instance(const char *name);
 int kvm__enumerate_instances(int (*callback)(const char *name, int pid));
 void kvm__remove_socket(const char *name);
 
+void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name);
+void kvm__arch_setup_firmware(struct kvm *kvm);
+bool kvm__arch_cpu_supports_vm(void);
+
+int load_flat_binary(struct kvm *kvm, int fd);
+bool load_bzimage(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline, u16 vidmode);
+
 /*
  * Debugging
  */
@@ -98,11 +77,4 @@ static inline void *guest_flat_to_host(struct kvm *kvm, unsigned long offset)
 	return kvm->ram_start + offset;
 }
 
-static inline void *guest_real_to_host(struct kvm *kvm, u16 selector, u16 offset)
-{
-	unsigned long flat = segment_to_flat(selector, offset);
-
-	return guest_flat_to_host(kvm, flat);
-}
-
 #endif /* KVM__KVM_H */
tools/kvm/ioport.c +0 -54
index 7cbc44e..965cfc2 100644
@@ -52,34 +52,6 @@ static int ioport_insert(struct rb_root *root, struct ioport *data)
 	return rb_int_insert(root, &data->node);
 }
 
-static bool debug_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
-{
-	exit(EXIT_SUCCESS);
-}
-
-static struct ioport_operations debug_ops = {
-	.io_out		= debug_io_out,
-};
-
-static bool dummy_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
-{
-	return true;
-}
-
-static bool dummy_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
-{
-	return true;
-}
-
-static struct ioport_operations dummy_read_write_ioport_ops = {
-	.io_in		= dummy_io_in,
-	.io_out		= dummy_io_out,
-};
-
-static struct ioport_operations dummy_write_only_ioport_ops = {
-	.io_out		= dummy_io_out,
-};
-
 u16 ioport__register(u16 port, struct ioport_operations *ops, int count, void *param)
 {
 	struct ioport *entry;
@@ -164,29 +136,3 @@ error:
 
 	return !ioport_debug;
 }
-
-void ioport__setup_legacy(void)
-{
-	/* 0x0020 - 0x003F - 8259A PIC 1 */
-	ioport__register(0x0020, &dummy_read_write_ioport_ops, 2, NULL);
-
-	/* PORT 0040-005F - PIT - PROGRAMMABLE INTERVAL TIMER (8253, 8254) */
-	ioport__register(0x0040, &dummy_read_write_ioport_ops, 4, NULL);
-
-	/* 0x00A0 - 0x00AF - 8259A PIC 2 */
-	ioport__register(0x00A0, &dummy_read_write_ioport_ops, 2, NULL);
-
-	/* PORT 00E0-00EF are 'motherboard specific' so we use them for our
-	   internal debugging purposes.  */
-	ioport__register(IOPORT_DBG, &debug_ops, 1, NULL);
-
-	/* PORT 00ED - DUMMY PORT FOR DELAY??? */
-	ioport__register(0x00ED, &dummy_write_only_ioport_ops, 1, NULL);
-
-	/* 0x00F0 - 0x00FF - Math co-processor */
-	ioport__register(0x00F0, &dummy_write_only_ioport_ops, 2, NULL);
-
-	/* PORT 03D4-03D5 - COLOR VIDEO - CRT CONTROL REGISTERS */
-	ioport__register(0x03D4, &dummy_read_write_ioport_ops, 1, NULL);
-	ioport__register(0x03D5, &dummy_write_only_ioport_ops, 1, NULL);
-}
tools/kvm/kvm-cpu.c +0 -372
index 0ad6f3b..5aba3bb 100644
@@ -4,8 +4,6 @@
 #include "kvm/util.h"
 #include "kvm/kvm.h"
 
-#include <asm/msr-index.h>
-
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <signal.h>
@@ -14,106 +12,9 @@
 #include <errno.h>
 #include <stdio.h>
 
-#define PAGE_SIZE (sysconf(_SC_PAGE_SIZE))
-
 extern struct kvm_cpu *kvm_cpus[KVM_NR_CPUS];
 extern __thread struct kvm_cpu *current_kvm_cpu;
 
-static int debug_fd;
-
-void kvm_cpu__set_debug_fd(int fd)
-{
-	debug_fd = fd;
-}
-
-int kvm_cpu__get_debug_fd(void)
-{
-	return debug_fd;
-}
-
-static inline bool is_in_protected_mode(struct kvm_cpu *vcpu)
-{
-	return vcpu->sregs.cr0 & 0x01;
-}
-
-static inline u64 ip_to_flat(struct kvm_cpu *vcpu, u64 ip)
-{
-	u64 cs;
-
-	/*
-	 * NOTE! We should take code segment base address into account here.
-	 * Luckily it's usually zero because Linux uses flat memory model.
-	 */
-	if (is_in_protected_mode(vcpu))
-		return ip;
-
-	cs = vcpu->sregs.cs.selector;
-
-	return ip + (cs << 4);
-}
-
-static inline u32 selector_to_base(u16 selector)
-{
-	/*
-	 * KVM on Intel requires 'base' to be 'selector * 16' in real mode.
-	 */
-	return (u32)selector * 16;
-}
-
-static struct kvm_cpu *kvm_cpu__new(struct kvm *kvm)
-{
-	struct kvm_cpu *vcpu;
-
-	vcpu		= calloc(1, sizeof *vcpu);
-	if (!vcpu)
-		return NULL;
-
-	vcpu->kvm	= kvm;
-
-	return vcpu;
-}
-
-void kvm_cpu__delete(struct kvm_cpu *vcpu)
-{
-	if (vcpu->msrs)
-		free(vcpu->msrs);
-
-	free(vcpu);
-}
-
-struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id)
-{
-	struct kvm_cpu *vcpu;
-	int mmap_size;
-	int coalesced_offset;
-
-	vcpu		= kvm_cpu__new(kvm);
-	if (!vcpu)
-		return NULL;
-
-	vcpu->cpu_id	= cpu_id;
-
-	vcpu->vcpu_fd = ioctl(vcpu->kvm->vm_fd, KVM_CREATE_VCPU, cpu_id);
-	if (vcpu->vcpu_fd < 0)
-		die_perror("KVM_CREATE_VCPU ioctl");
-
-	mmap_size = ioctl(vcpu->kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
-	if (mmap_size < 0)
-		die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl");
-
-	vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, vcpu->vcpu_fd, 0);
-	if (vcpu->kvm_run == MAP_FAILED)
-		die("unable to mmap vcpu fd");
-
-	coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_COALESCED_MMIO);
-	if (coalesced_offset)
-		vcpu->ring = (void *)vcpu->kvm_run + (coalesced_offset * PAGE_SIZE);
-
-	vcpu->is_running = true;
-
-	return vcpu;
-}
-
 void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu)
 {
 	struct kvm_guest_debug debug = {
@@ -124,278 +25,6 @@ void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu)
 		pr_warning("KVM_SET_GUEST_DEBUG failed");
 }
 
-static struct kvm_msrs *kvm_msrs__new(size_t nmsrs)
-{
-	struct kvm_msrs *vcpu = calloc(1, sizeof(*vcpu) + (sizeof(struct kvm_msr_entry) * nmsrs));
-
-	if (!vcpu)
-		die("out of memory");
-
-	return vcpu;
-}
-
-#define KVM_MSR_ENTRY(_index, _data)	\
-	(struct kvm_msr_entry) { .index = _index, .data = _data }
-
-static void kvm_cpu__setup_msrs(struct kvm_cpu *vcpu)
-{
-	unsigned long ndx = 0;
-
-	vcpu->msrs = kvm_msrs__new(100);
-
-	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_CS,	0x0);
-	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_ESP,	0x0);
-	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_EIP,	0x0);
-#ifdef CONFIG_X86_64
-	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_STAR,			0x0);
-	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_CSTAR,			0x0);
-	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_KERNEL_GS_BASE,		0x0);
-	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_SYSCALL_MASK,		0x0);
-	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_LSTAR,			0x0);
-#endif
-	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_TSC,		0x0);
-	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_MISC_ENABLE,
-						MSR_IA32_MISC_ENABLE_FAST_STRING);
-
-	vcpu->msrs->nmsrs	= ndx;
-
-	if (ioctl(vcpu->vcpu_fd, KVM_SET_MSRS, vcpu->msrs) < 0)
-		die_perror("KVM_SET_MSRS failed");
-}
-
-static void kvm_cpu__setup_fpu(struct kvm_cpu *vcpu)
-{
-	vcpu->fpu = (struct kvm_fpu) {
-		.fcw		= 0x37f,
-		.mxcsr		= 0x1f80,
-	};
-
-	if (ioctl(vcpu->vcpu_fd, KVM_SET_FPU, &vcpu->fpu) < 0)
-		die_perror("KVM_SET_FPU failed");
-}
-
-static void kvm_cpu__setup_regs(struct kvm_cpu *vcpu)
-{
-	vcpu->regs = (struct kvm_regs) {
-		/* We start the guest in 16-bit real mode  */
-		.rflags		= 0x0000000000000002ULL,
-
-		.rip		= vcpu->kvm->boot_ip,
-		.rsp		= vcpu->kvm->boot_sp,
-		.rbp		= vcpu->kvm->boot_sp,
-	};
-
-	if (vcpu->regs.rip > USHRT_MAX)
-		die("ip 0x%llx is too high for real mode", (u64) vcpu->regs.rip);
-
-	if (ioctl(vcpu->vcpu_fd, KVM_SET_REGS, &vcpu->regs) < 0)
-		die_perror("KVM_SET_REGS failed");
-}
-
-static void kvm_cpu__setup_sregs(struct kvm_cpu *vcpu)
-{
-
-	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &vcpu->sregs) < 0)
-		die_perror("KVM_GET_SREGS failed");
-
-	vcpu->sregs.cs.selector	= vcpu->kvm->boot_selector;
-	vcpu->sregs.cs.base	= selector_to_base(vcpu->kvm->boot_selector);
-	vcpu->sregs.ss.selector	= vcpu->kvm->boot_selector;
-	vcpu->sregs.ss.base	= selector_to_base(vcpu->kvm->boot_selector);
-	vcpu->sregs.ds.selector	= vcpu->kvm->boot_selector;
-	vcpu->sregs.ds.base	= selector_to_base(vcpu->kvm->boot_selector);
-	vcpu->sregs.es.selector	= vcpu->kvm->boot_selector;
-	vcpu->sregs.es.base	= selector_to_base(vcpu->kvm->boot_selector);
-	vcpu->sregs.fs.selector	= vcpu->kvm->boot_selector;
-	vcpu->sregs.fs.base	= selector_to_base(vcpu->kvm->boot_selector);
-	vcpu->sregs.gs.selector	= vcpu->kvm->boot_selector;
-	vcpu->sregs.gs.base	= selector_to_base(vcpu->kvm->boot_selector);
-
-	if (ioctl(vcpu->vcpu_fd, KVM_SET_SREGS, &vcpu->sregs) < 0)
-		die_perror("KVM_SET_SREGS failed");
-}
-
-/**
- * kvm_cpu__reset_vcpu - reset virtual CPU to a known state
- */
-void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
-{
-	kvm_cpu__setup_sregs(vcpu);
-	kvm_cpu__setup_regs(vcpu);
-	kvm_cpu__setup_fpu(vcpu);
-	kvm_cpu__setup_msrs(vcpu);
-}
-
-static void print_dtable(const char *name, struct kvm_dtable *dtable)
-{
-	dprintf(debug_fd, " %s                 %016llx  %08hx\n",
-		name, (u64) dtable->base, (u16) dtable->limit);
-}
-
-static void print_segment(const char *name, struct kvm_segment *seg)
-{
-	dprintf(debug_fd, " %s       %04hx      %016llx  %08x  %02hhx    %x %x   %x  %x %x %x %x\n",
-		name, (u16) seg->selector, (u64) seg->base, (u32) seg->limit,
-		(u8) seg->type, seg->present, seg->dpl, seg->db, seg->s, seg->l, seg->g, seg->avl);
-}
-
-void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
-{
-	unsigned long cr0, cr2, cr3;
-	unsigned long cr4, cr8;
-	unsigned long rax, rbx, rcx;
-	unsigned long rdx, rsi, rdi;
-	unsigned long rbp,  r8,  r9;
-	unsigned long r10, r11, r12;
-	unsigned long r13, r14, r15;
-	unsigned long rip, rsp;
-	struct kvm_sregs sregs;
-	unsigned long rflags;
-	struct kvm_regs regs;
-	int i;
-
-	if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &regs) < 0)
-		die("KVM_GET_REGS failed");
-
-	rflags = regs.rflags;
-
-	rip = regs.rip; rsp = regs.rsp;
-	rax = regs.rax; rbx = regs.rbx; rcx = regs.rcx;
-	rdx = regs.rdx; rsi = regs.rsi; rdi = regs.rdi;
-	rbp = regs.rbp; r8  = regs.r8;  r9  = regs.r9;
-	r10 = regs.r10; r11 = regs.r11; r12 = regs.r12;
-	r13 = regs.r13; r14 = regs.r14; r15 = regs.r15;
-
-	dprintf(debug_fd, "\n Registers:\n");
-	dprintf(debug_fd,   " ----------\n");
-	dprintf(debug_fd, " rip: %016lx   rsp: %016lx flags: %016lx\n", rip, rsp, rflags);
-	dprintf(debug_fd, " rax: %016lx   rbx: %016lx   rcx: %016lx\n", rax, rbx, rcx);
-	dprintf(debug_fd, " rdx: %016lx   rsi: %016lx   rdi: %016lx\n", rdx, rsi, rdi);
-	dprintf(debug_fd, " rbp: %016lx    r8: %016lx    r9: %016lx\n", rbp, r8,  r9);
-	dprintf(debug_fd, " r10: %016lx   r11: %016lx   r12: %016lx\n", r10, r11, r12);
-	dprintf(debug_fd, " r13: %016lx   r14: %016lx   r15: %016lx\n", r13, r14, r15);
-
-	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0)
-		die("KVM_GET_REGS failed");
-
-	cr0 = sregs.cr0; cr2 = sregs.cr2; cr3 = sregs.cr3;
-	cr4 = sregs.cr4; cr8 = sregs.cr8;
-
-	dprintf(debug_fd, " cr0: %016lx   cr2: %016lx   cr3: %016lx\n", cr0, cr2, cr3);
-	dprintf(debug_fd, " cr4: %016lx   cr8: %016lx\n", cr4, cr8);
-	dprintf(debug_fd, "\n Segment registers:\n");
-	dprintf(debug_fd,   " ------------------\n");
-	dprintf(debug_fd, " register  selector  base              limit     type  p dpl db s l g avl\n");
-	print_segment("cs ", &sregs.cs);
-	print_segment("ss ", &sregs.ss);
-	print_segment("ds ", &sregs.ds);
-	print_segment("es ", &sregs.es);
-	print_segment("fs ", &sregs.fs);
-	print_segment("gs ", &sregs.gs);
-	print_segment("tr ", &sregs.tr);
-	print_segment("ldt", &sregs.ldt);
-	print_dtable("gdt", &sregs.gdt);
-	print_dtable("idt", &sregs.idt);
-
-	dprintf(debug_fd, "\n APIC:\n");
-	dprintf(debug_fd,   " -----\n");
-	dprintf(debug_fd, " efer: %016llx  apic base: %016llx  nmi: %s\n",
-		(u64) sregs.efer, (u64) sregs.apic_base,
-		(vcpu->kvm->nmi_disabled ? "disabled" : "enabled"));
-
-	dprintf(debug_fd, "\n Interrupt bitmap:\n");
-	dprintf(debug_fd,   " -----------------\n");
-	for (i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; i++)
-		dprintf(debug_fd, " %016llx", (u64) sregs.interrupt_bitmap[i]);
-	dprintf(debug_fd, "\n");
-}
-
-#define MAX_SYM_LEN		128
-
-void kvm_cpu__show_code(struct kvm_cpu *vcpu)
-{
-	unsigned int code_bytes = 64;
-	unsigned int code_prologue = code_bytes * 43 / 64;
-	unsigned int code_len = code_bytes;
-	char sym[MAX_SYM_LEN];
-	unsigned char c;
-	unsigned int i;
-	u8 *ip;
-
-	if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &vcpu->regs) < 0)
-		die("KVM_GET_REGS failed");
-
-	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &vcpu->sregs) < 0)
-		die("KVM_GET_SREGS failed");
-
-	ip = guest_flat_to_host(vcpu->kvm, ip_to_flat(vcpu, vcpu->regs.rip) - code_prologue);
-
-	dprintf(debug_fd, "\n Code:\n");
-	dprintf(debug_fd,   " -----\n");
-
-	symbol__lookup(vcpu->kvm, vcpu->regs.rip, sym, MAX_SYM_LEN);
-
-	dprintf(debug_fd, " rip: [<%016lx>] %s\n\n", (unsigned long) vcpu->regs.rip, sym);
-
-	for (i = 0; i < code_len; i++, ip++) {
-		if (!host_ptr_in_ram(vcpu->kvm, ip))
-			break;
-
-		c = *ip;
-
-		if (ip == guest_flat_to_host(vcpu->kvm, ip_to_flat(vcpu, vcpu->regs.rip)))
-			dprintf(debug_fd, " <%02x>", c);
-		else
-			dprintf(debug_fd, " %02x", c);
-	}
-
-	dprintf(debug_fd, "\n");
-
-	dprintf(debug_fd, "\n Stack:\n");
-	dprintf(debug_fd,   " ------\n");
-	kvm__dump_mem(vcpu->kvm, vcpu->regs.rsp, 32);
-}
-
-void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
-{
-	u64 *pte1;
-	u64 *pte2;
-	u64 *pte3;
-	u64 *pte4;
-
-	if (!is_in_protected_mode(vcpu))
-		return;
-
-	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &vcpu->sregs) < 0)
-		die("KVM_GET_SREGS failed");
-
-	pte4	= guest_flat_to_host(vcpu->kvm, vcpu->sregs.cr3);
-	if (!host_ptr_in_ram(vcpu->kvm, pte4))
-		return;
-
-	pte3	= guest_flat_to_host(vcpu->kvm, (*pte4 & ~0xfff));
-	if (!host_ptr_in_ram(vcpu->kvm, pte3))
-		return;
-
-	pte2	= guest_flat_to_host(vcpu->kvm, (*pte3 & ~0xfff));
-	if (!host_ptr_in_ram(vcpu->kvm, pte2))
-		return;
-
-	pte1	= guest_flat_to_host(vcpu->kvm, (*pte2 & ~0xfff));
-	if (!host_ptr_in_ram(vcpu->kvm, pte1))
-		return;
-
-	dprintf(debug_fd, "Page Tables:\n");
-	if (*pte2 & (1 << 7))
-		dprintf(debug_fd, " pte4: %016llx   pte3: %016llx"
-			"   pte2: %016llx\n",
-			*pte4, *pte3, *pte2);
-	else
-		dprintf(debug_fd, " pte4: %016llx  pte3: %016llx   pte2: %016"
-			"llx   pte1: %016llx\n",
-			*pte4, *pte3, *pte2, *pte1);
-}
-
 void kvm_cpu__run(struct kvm_cpu *vcpu)
 {
 	int err;
@@ -454,7 +83,6 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
 	signal(SIGKVMEXIT, kvm_cpu_signal_handler);
 	signal(SIGKVMPAUSE, kvm_cpu_signal_handler);
 
-	kvm_cpu__setup_cpuid(cpu);
 	kvm_cpu__reset_vcpu(cpu);
 
 	if (cpu->kvm->single_step)
tools/kvm/kvm.c +6 -317
index 252bd18..7ce1640 100644
@@ -1,10 +1,5 @@
 #include "kvm/kvm.h"
-
-#include "kvm/boot-protocol.h"
-#include "kvm/cpufeature.h"
 #include "kvm/read-write.h"
-#include "kvm/interrupt.h"
-#include "kvm/mptable.h"
 #include "kvm/util.h"
 #include "kvm/mutex.h"
 #include "kvm/kvm-cpu.h"
@@ -12,14 +7,11 @@
 
 #include <linux/kvm.h>
 
-#include <asm/bootparam.h>
-
 #include <sys/un.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
-#include <sys/stat.h>
 #include <stdbool.h>
 #include <assert.h>
 #include <limits.h>
@@ -58,29 +50,11 @@ const char *kvm_exit_reasons[] = {
 	DEFINE_KVM_EXIT_REASON(KVM_EXIT_INTERNAL_ERROR),
 };
 
-#define DEFINE_KVM_EXT(ext)		\
-	.name = #ext,			\
-	.code = ext
-
-struct {
-	const char *name;
-	int code;
-} kvm_req_ext[] = {
-	{ DEFINE_KVM_EXT(KVM_CAP_COALESCED_MMIO) },
-	{ DEFINE_KVM_EXT(KVM_CAP_SET_TSS_ADDR) },
-	{ DEFINE_KVM_EXT(KVM_CAP_PIT2) },
-	{ DEFINE_KVM_EXT(KVM_CAP_USER_MEMORY) },
-	{ DEFINE_KVM_EXT(KVM_CAP_IRQ_ROUTING) },
-	{ DEFINE_KVM_EXT(KVM_CAP_IRQCHIP) },
-	{ DEFINE_KVM_EXT(KVM_CAP_HLT) },
-	{ DEFINE_KVM_EXT(KVM_CAP_IRQ_INJECT_STATUS) },
-	{ DEFINE_KVM_EXT(KVM_CAP_EXT_CPUID) },
-};
-
 extern struct kvm *kvm;
 extern struct kvm_cpu *kvm_cpus[KVM_NR_CPUS];
 static int pause_event;
 static DEFINE_MUTEX(pause_lock);
+extern struct kvm_ext kvm_req_ext[];
 
 static char kvm_dir[PATH_MAX];
 
@@ -127,7 +101,9 @@ static int kvm__check_extensions(struct kvm *kvm)
 {
 	unsigned int i;
 
-	for (i = 0; i < ARRAY_SIZE(kvm_req_ext); i++) {
+	for (i = 0; ; i++) {
+		if (!kvm_req_ext[i].name)
+			break;
 		if (!kvm__supports_extension(kvm, kvm_req_ext[i].code)) {
 			pr_error("Unsuppored KVM extension detected: %s",
 				kvm_req_ext[i].name);
@@ -261,48 +237,6 @@ void kvm__delete(struct kvm *kvm)
 	free(kvm);
 }
 
-static bool kvm__cpu_supports_vm(void)
-{
-	struct cpuid_regs regs;
-	u32 eax_base;
-	int feature;
-
-	regs	= (struct cpuid_regs) {
-		.eax		= 0x00,
-	};
-	host_cpuid(&regs);
-
-	switch (regs.ebx) {
-	case CPUID_VENDOR_INTEL_1:
-		eax_base	= 0x00;
-		feature		= KVM__X86_FEATURE_VMX;
-		break;
-
-	case CPUID_VENDOR_AMD_1:
-		eax_base	= 0x80000000;
-		feature		= KVM__X86_FEATURE_SVM;
-		break;
-
-	default:
-		return false;
-	}
-
-	regs	= (struct cpuid_regs) {
-		.eax		= eax_base,
-	};
-	host_cpuid(&regs);
-
-	if (regs.eax < eax_base + 0x01)
-		return false;
-
-	regs	= (struct cpuid_regs) {
-		.eax		= eax_base + 0x01
-	};
-	host_cpuid(&regs);
-
-	return regs.ecx & (1 << feature);
-}
-
 /*
  * Note: KVM_SET_USER_MEMORY_REGION assumes that we don't pass overlapping
  * memory regions to it. Therefore, be careful if you use this function for
@@ -325,47 +259,6 @@ void kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspac
 		die_perror("KVM_SET_USER_MEMORY_REGION ioctl");
 }
 
-/*
- * Allocating RAM size bigger than 4GB requires us to leave a gap
- * in the RAM which is used for PCI MMIO, hotplug, and unconfigured
- * devices (see documentation of e820_setup_gap() for details).
- *
- * If we're required to initialize RAM bigger than 4GB, we will create
- * a gap between 0xe0000000 and 0x100000000 in the guest virtual mem space.
- */
-
-void kvm__init_ram(struct kvm *kvm)
-{
-	u64	phys_start, phys_size;
-	void	*host_mem;
-
-	if (kvm->ram_size < KVM_32BIT_GAP_START) {
-		/* Use a single block of RAM for 32bit RAM */
-
-		phys_start = 0;
-		phys_size  = kvm->ram_size;
-		host_mem   = kvm->ram_start;
-
-		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
-	} else {
-		/* First RAM range from zero to the PCI gap: */
-
-		phys_start = 0;
-		phys_size  = KVM_32BIT_GAP_START;
-		host_mem   = kvm->ram_start;
-
-		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
-
-		/* Second RAM range from 4GB to the end of RAM: */
-
-		phys_start = 0x100000000ULL;
-		phys_size  = kvm->ram_size - phys_size;
-		host_mem   = kvm->ram_start + phys_start;
-
-		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
-	}
-}
-
 int kvm__recommended_cpus(struct kvm *kvm)
 {
 	int ret;
@@ -410,11 +303,10 @@ int kvm__max_cpus(struct kvm *kvm)
 
 struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
 {
-	struct kvm_pit_config pit_config = { .flags = 0, };
 	struct kvm *kvm;
 	int ret;
 
-	if (!kvm__cpu_supports_vm())
+	if (!kvm__arch_cpu_supports_vm())
 		die("Your CPU does not support hardware virtualization");
 
 	kvm = kvm__new();
@@ -442,36 +334,7 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
 	if (kvm__check_extensions(kvm))
 		die("A required KVM extention is not supported by OS");
 
-	ret = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000);
-	if (ret < 0)
-		die_perror("KVM_SET_TSS_ADDR ioctl");
-
-	ret = ioctl(kvm->vm_fd, KVM_CREATE_PIT2, &pit_config);
-	if (ret < 0)
-		die_perror("KVM_CREATE_PIT2 ioctl");
-
-	kvm->ram_size		= ram_size;
-
-	if (kvm->ram_size < KVM_32BIT_GAP_START) {
-		kvm->ram_start = mmap(NULL, ram_size, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
-	} else {
-		kvm->ram_start = mmap(NULL, ram_size + KVM_32BIT_GAP_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
-		if (kvm->ram_start != MAP_FAILED) {
-			/*
-			 * We mprotect the gap (see kvm__init_ram() for details) PROT_NONE so that
-			 * if we accidently write to it, we will know.
-			 */
-			mprotect(kvm->ram_start + KVM_32BIT_GAP_START, KVM_32BIT_GAP_SIZE, PROT_NONE);
-		}
-	}
-	if (kvm->ram_start == MAP_FAILED)
-		die("out of memory");
-
-	madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
-
-	ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
-	if (ret < 0)
-		die_perror("KVM_CREATE_IRQCHIP ioctl");
+	kvm__arch_init(kvm, kvm_dev, ram_size, name);
 
 	kvm->name = name;
 
@@ -480,141 +343,6 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
 	return kvm;
 }
 
-#define BOOT_LOADER_SELECTOR	0x1000
-#define BOOT_LOADER_IP		0x0000
-#define BOOT_LOADER_SP		0x8000
-#define BOOT_CMDLINE_OFFSET	0x20000
-
-#define BOOT_PROTOCOL_REQUIRED	0x206
-#define LOAD_HIGH		0x01
-
-static int load_flat_binary(struct kvm *kvm, int fd)
-{
-	void *p;
-	int nr;
-
-	if (lseek(fd, 0, SEEK_SET) < 0)
-		die_perror("lseek");
-
-	p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
-
-	while ((nr = read(fd, p, 65536)) > 0)
-		p += nr;
-
-	kvm->boot_selector	= BOOT_LOADER_SELECTOR;
-	kvm->boot_ip		= BOOT_LOADER_IP;
-	kvm->boot_sp		= BOOT_LOADER_SP;
-
-	return true;
-}
-
-static const char *BZIMAGE_MAGIC	= "HdrS";
-
-static bool load_bzimage(struct kvm *kvm, int fd_kernel,
-			int fd_initrd, const char *kernel_cmdline, u16 vidmode)
-{
-	struct boot_params *kern_boot;
-	unsigned long setup_sects;
-	struct boot_params boot;
-	size_t cmdline_size;
-	ssize_t setup_size;
-	void *p;
-	int nr;
-
-	/*
-	 * See Documentation/x86/boot.txt for details no bzImage on-disk and
-	 * memory layout.
-	 */
-
-	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
-		die_perror("lseek");
-
-	if (read(fd_kernel, &boot, sizeof(boot)) != sizeof(boot))
-		return false;
-
-	if (memcmp(&boot.hdr.header, BZIMAGE_MAGIC, strlen(BZIMAGE_MAGIC)))
-		return false;
-
-	if (boot.hdr.version < BOOT_PROTOCOL_REQUIRED)
-		die("Too old kernel");
-
-	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
-		die_perror("lseek");
-
-	if (!boot.hdr.setup_sects)
-		boot.hdr.setup_sects = BZ_DEFAULT_SETUP_SECTS;
-	setup_sects = boot.hdr.setup_sects + 1;
-
-	setup_size = setup_sects << 9;
-	p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
-
-	/* copy setup.bin to mem*/
-	if (read(fd_kernel, p, setup_size) != setup_size)
-		die_perror("read");
-
-	/* copy vmlinux.bin to BZ_KERNEL_START*/
-	p = guest_flat_to_host(kvm, BZ_KERNEL_START);
-
-	while ((nr = read(fd_kernel, p, 65536)) > 0)
-		p += nr;
-
-	p = guest_flat_to_host(kvm, BOOT_CMDLINE_OFFSET);
-	if (kernel_cmdline) {
-		cmdline_size = strlen(kernel_cmdline) + 1;
-		if (cmdline_size > boot.hdr.cmdline_size)
-			cmdline_size = boot.hdr.cmdline_size;
-
-		memset(p, 0, boot.hdr.cmdline_size);
-		memcpy(p, kernel_cmdline, cmdline_size - 1);
-	}
-
-	kern_boot	= guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, 0x00);
-
-	kern_boot->hdr.cmd_line_ptr	= BOOT_CMDLINE_OFFSET;
-	kern_boot->hdr.type_of_loader	= 0xff;
-	kern_boot->hdr.heap_end_ptr	= 0xfe00;
-	kern_boot->hdr.loadflags	|= CAN_USE_HEAP;
-	kern_boot->hdr.vid_mode		= vidmode;
-
-	/*
-	 * Read initrd image into guest memory
-	 */
-	if (fd_initrd >= 0) {
-		struct stat initrd_stat;
-		unsigned long addr;
-
-		if (fstat(fd_initrd, &initrd_stat))
-			die_perror("fstat");
-
-		addr = boot.hdr.initrd_addr_max & ~0xfffff;
-		for (;;) {
-			if (addr < BZ_KERNEL_START)
-				die("Not enough memory for initrd");
-			else if (addr < (kvm->ram_size - initrd_stat.st_size))
-				break;
-			addr -= 0x100000;
-		}
-
-		p = guest_flat_to_host(kvm, addr);
-		nr = read(fd_initrd, p, initrd_stat.st_size);
-		if (nr != initrd_stat.st_size)
-			die("Failed to read initrd");
-
-		kern_boot->hdr.ramdisk_image	= addr;
-		kern_boot->hdr.ramdisk_size	= initrd_stat.st_size;
-	}
-
-	kvm->boot_selector	= BOOT_LOADER_SELECTOR;
-	/*
-	 * The real-mode setup code starts at offset 0x200 of a bzImage. See
-	 * Documentation/x86/boot.txt for details.
-	 */
-	kvm->boot_ip		= BOOT_LOADER_IP + 0x200;
-	kvm->boot_sp		= BOOT_LOADER_SP;
-
-	return true;
-}
-
 /* RFC 1952 */
 #define GZIP_ID1		0x1f
 #define GZIP_ID2		0x8b
@@ -675,24 +403,6 @@ found_kernel:
 	return ret;
 }
 
-/**
- * kvm__setup_bios - inject BIOS into guest system memory
- * @kvm - guest system descriptor
- *
- * This function is a main routine where we poke guest memory
- * and install BIOS there.
- */
-void kvm__setup_bios(struct kvm *kvm)
-{
-	/* standart minimal configuration */
-	setup_bios(kvm);
-
-	/* FIXME: SMP, ACPI and friends here */
-
-	/* MP table */
-	mptable_setup(kvm, kvm->nrcpus);
-}
-
 #define TIMER_INTERVAL_NS 1000000	/* 1 msec */
 
 /*
@@ -732,27 +442,6 @@ void kvm__stop_timer(struct kvm *kvm)
 	kvm->timerid = 0;
 }
 
-void kvm__irq_line(struct kvm *kvm, int irq, int level)
-{
-	struct kvm_irq_level irq_level;
-
-	irq_level	= (struct kvm_irq_level) {
-		{
-			.irq		= irq,
-		},
-		.level		= level,
-	};
-
-	if (ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level) < 0)
-		die_perror("KVM_IRQ_LINE failed");
-}
-
-void kvm__irq_trigger(struct kvm *kvm, int irq)
-{
-	kvm__irq_line(kvm, irq, 1);
-	kvm__irq_line(kvm, irq, 0);
-}
-
 void kvm__dump_mem(struct kvm *kvm, unsigned long addr, unsigned long size)
 {
 	unsigned char *p;
tools/kvm/x86/bios.c renamed from tools/kvm/bios.c +0 -0
similarity index 100%
rename from tools/kvm/bios.c
rename to tools/kvm/x86/bios.c
tools/kvm/x86/bios/.gitignore renamed from tools/kvm/bios/.gitignore +0 -0
similarity index 100%
rename from tools/kvm/bios/.gitignore
rename to tools/kvm/x86/bios/.gitignore
tools/kvm/x86/bios/bios-rom.S renamed from tools/kvm/bios/bios-rom.S +1 -1
similarity index 80%
rename from tools/kvm/bios/bios-rom.S
rename to tools/kvm/x86/bios/bios-rom.S
index dc52b1e..3269ce9 100644
@@ -8,5 +8,5 @@
 #endif
 
 GLOBAL(bios_rom)
-	.incbin "bios/bios.bin"
+	.incbin "x86/bios/bios.bin"
 END(bios_rom)
tools/kvm/x86/bios/e820.c renamed from tools/kvm/bios/e820.c +0 -0
similarity index 100%
rename from tools/kvm/bios/e820.c
rename to tools/kvm/x86/bios/e820.c
tools/kvm/x86/bios/entry.S renamed from tools/kvm/bios/entry.S +0 -0
similarity index 100%
rename from tools/kvm/bios/entry.S
rename to tools/kvm/x86/bios/entry.S
tools/kvm/x86/bios/gen-offsets.sh renamed from tools/kvm/bios/gen-offsets.sh +0 -0
similarity index 100%
rename from tools/kvm/bios/gen-offsets.sh
rename to tools/kvm/x86/bios/gen-offsets.sh
tools/kvm/x86/bios/int10.c renamed from tools/kvm/bios/int10.c +0 -0
similarity index 100%
rename from tools/kvm/bios/int10.c
rename to tools/kvm/x86/bios/int10.c
tools/kvm/x86/bios/int15.c renamed from tools/kvm/bios/int15.c +0 -0
similarity index 100%
rename from tools/kvm/bios/int15.c
rename to tools/kvm/x86/bios/int15.c
tools/kvm/x86/bios/local.S renamed from tools/kvm/bios/local.S +0 -0
similarity index 100%
rename from tools/kvm/bios/local.S
rename to tools/kvm/x86/bios/local.S
tools/kvm/x86/bios/macro.S renamed from tools/kvm/bios/macro.S +0 -0
similarity index 100%
rename from tools/kvm/bios/macro.S
rename to tools/kvm/x86/bios/macro.S
tools/kvm/x86/bios/memcpy.c renamed from tools/kvm/bios/memcpy.c +0 -0
similarity index 100%
rename from tools/kvm/bios/memcpy.c
rename to tools/kvm/x86/bios/memcpy.c
tools/kvm/x86/bios/rom.ld.S renamed from tools/kvm/bios/rom.ld.S +0 -0
similarity index 100%
rename from tools/kvm/bios/rom.ld.S
rename to tools/kvm/x86/bios/rom.ld.S
tools/kvm/x86/cpuid.c renamed from tools/kvm/cpuid.c +0 -0
similarity index 100%
rename from tools/kvm/cpuid.c
rename to tools/kvm/x86/cpuid.c
tools/kvm/x86/include/kvm/assembly.h renamed from tools/kvm/include/kvm/assembly.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/assembly.h
rename to tools/kvm/x86/include/kvm/assembly.h
tools/kvm/x86/include/kvm/barrier.h renamed from tools/kvm/include/kvm/barrier.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/barrier.h
rename to tools/kvm/x86/include/kvm/barrier.h
tools/kvm/x86/include/kvm/bios-export.h renamed from tools/kvm/include/kvm/bios-export.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/bios-export.h
rename to tools/kvm/x86/include/kvm/bios-export.h
tools/kvm/x86/include/kvm/bios.h renamed from tools/kvm/include/kvm/bios.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/bios.h
rename to tools/kvm/x86/include/kvm/bios.h
tools/kvm/x86/include/kvm/boot-protocol.h renamed from tools/kvm/include/kvm/boot-protocol.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/boot-protocol.h
rename to tools/kvm/x86/include/kvm/boot-protocol.h
tools/kvm/x86/include/kvm/cpufeature.h renamed from tools/kvm/include/kvm/cpufeature.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/cpufeature.h
rename to tools/kvm/x86/include/kvm/cpufeature.h
tools/kvm/x86/include/kvm/interrupt.h renamed from tools/kvm/include/kvm/interrupt.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/interrupt.h
rename to tools/kvm/x86/include/kvm/interrupt.h
tools/kvm/x86/include/kvm/kvm-arch.h new file +59 -0
new file mode 100644
index 0000000..02aa8b9
@@ -0,0 +1,59 @@
+#ifndef KVM__KVM_ARCH_H
+#define KVM__KVM_ARCH_H
+
+#include "kvm/interrupt.h"
+#include "kvm/segment.h"
+
+#include <stdbool.h>
+#include <linux/types.h>
+#include <time.h>
+
+#define KVM_NR_CPUS		(255)
+
+/*
+ * The hole includes VESA framebuffer and PCI memory.
+ */
+#define KVM_32BIT_GAP_SIZE	(768 << 20)
+#define KVM_32BIT_GAP_START	((1ULL << 32) - KVM_32BIT_GAP_SIZE)
+
+#define KVM_MMIO_START		KVM_32BIT_GAP_START
+
+struct kvm {
+	int			sys_fd;		/* For system ioctls(), i.e. /dev/kvm */
+	int			vm_fd;		/* For VM ioctls() */
+	timer_t			timerid;	/* Posix timer for interrupts */
+
+	int			nrcpus;		/* Number of cpus to run */
+
+	u32			mem_slots;	/* for KVM_SET_USER_MEMORY_REGION */
+
+	u64			ram_size;
+	void			*ram_start;
+
+	bool			nmi_disabled;
+
+	bool			single_step;
+
+	u16			boot_selector;
+	u16			boot_ip;
+	u16			boot_sp;
+
+	struct interrupt_table	interrupt_table;
+
+	const char		*vmlinux;
+	struct disk_image       **disks;
+	int                     nr_disks;
+
+	const char		*name;
+};
+
+static inline void *guest_flat_to_host(struct kvm *kvm, unsigned long offset); /* In kvm.h */
+
+static inline void *guest_real_to_host(struct kvm *kvm, u16 selector, u16 offset)
+{
+	unsigned long flat = segment_to_flat(selector, offset);
+
+	return guest_flat_to_host(kvm, flat);
+}
+
+#endif /* KVM__KVM_ARCH_H */
tools/kvm/x86/include/kvm/kvm-cpu-arch.h new file +33 -0
new file mode 100644
index 0000000..ed1c727
@@ -0,0 +1,33 @@
+#ifndef KVM__KVM_CPU_ARCH_H
+#define KVM__KVM_CPU_ARCH_H
+
+/* Architecture-specific kvm_cpu definitions. */
+
+#include <linux/kvm.h>	/* for struct kvm_regs */
+
+#include <pthread.h>
+
+struct kvm;
+
+struct kvm_cpu {
+	pthread_t		thread;		/* VCPU thread */
+
+	unsigned long		cpu_id;
+
+	struct kvm		*kvm;		/* parent KVM */
+	int			vcpu_fd;	/* For VCPU ioctls() */
+	struct kvm_run		*kvm_run;
+
+	struct kvm_regs		regs;
+	struct kvm_sregs	sregs;
+	struct kvm_fpu		fpu;
+
+	struct kvm_msrs		*msrs;		/* dynamically allocated */
+
+	u8			is_running;
+	u8			paused;
+
+	struct kvm_coalesced_mmio_ring	*ring;
+};
+
+#endif /* KVM__KVM_CPU_ARCH_H */
tools/kvm/x86/include/kvm/mptable.h renamed from tools/kvm/include/kvm/mptable.h +0 -0
similarity index 100%
rename from tools/kvm/include/kvm/mptable.h
rename to tools/kvm/x86/include/kvm/mptable.h
tools/kvm/x86/interrupt.c renamed from tools/kvm/interrupt.c +0 -0
similarity index 100%
rename from tools/kvm/interrupt.c
rename to tools/kvm/x86/interrupt.c
tools/kvm/x86/ioport.c new file +59 -0
new file mode 100644
index 0000000..8a91bf2
@@ -0,0 +1,59 @@
+#include "kvm/ioport.h"
+
+#include <stdlib.h>
+
+static bool debug_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	exit(EXIT_SUCCESS);
+}
+
+static struct ioport_operations debug_ops = {
+	.io_out		= debug_io_out,
+};
+
+static bool dummy_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	return true;
+}
+
+static bool dummy_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	return true;
+}
+
+static struct ioport_operations dummy_read_write_ioport_ops = {
+	.io_in		= dummy_io_in,
+	.io_out		= dummy_io_out,
+};
+
+static struct ioport_operations dummy_write_only_ioport_ops = {
+	.io_out		= dummy_io_out,
+};
+
+void ioport__setup_arch(void)
+{
+	/* Legacy ioport setup */
+
+	/* 0x0020 - 0x003F - 8259A PIC 1 */
+	ioport__register(0x0020, &dummy_read_write_ioport_ops, 2, NULL);
+
+	/* PORT 0040-005F - PIT - PROGRAMMABLE INTERVAL TIMER (8253, 8254) */
+	ioport__register(0x0040, &dummy_read_write_ioport_ops, 4, NULL);
+
+	/* 0x00A0 - 0x00AF - 8259A PIC 2 */
+	ioport__register(0x00A0, &dummy_read_write_ioport_ops, 2, NULL);
+
+	/* PORT 00E0-00EF are 'motherboard specific' so we use them for our
+	   internal debugging purposes.  */
+	ioport__register(IOPORT_DBG, &debug_ops, 1, NULL);
+
+	/* PORT 00ED - DUMMY PORT FOR DELAY??? */
+	ioport__register(0x00ED, &dummy_write_only_ioport_ops, 1, NULL);
+
+	/* 0x00F0 - 0x00FF - Math co-processor */
+	ioport__register(0x00F0, &dummy_write_only_ioport_ops, 2, NULL);
+
+	/* PORT 03D4-03D5 - COLOR VIDEO - CRT CONTROL REGISTERS */
+	ioport__register(0x03D4, &dummy_read_write_ioport_ops, 1, NULL);
+	ioport__register(0x03D5, &dummy_write_only_ioport_ops, 1, NULL);
+}
tools/kvm/x86/irq.c renamed from tools/kvm/irq.c +0 -0
similarity index 100%
rename from tools/kvm/irq.c
rename to tools/kvm/x86/irq.c
tools/kvm/x86/kvm-cpu.c new file +383 -0
new file mode 100644
index 0000000..b26b208
@@ -0,0 +1,383 @@
+#include "kvm/kvm-cpu.h"
+
+#include "kvm/symbol.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+
+#include <asm/msr-index.h>
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+static int debug_fd;
+
+void kvm_cpu__set_debug_fd(int fd)
+{
+	debug_fd = fd;
+}
+
+int kvm_cpu__get_debug_fd(void)
+{
+	return debug_fd;
+}
+
+static inline bool is_in_protected_mode(struct kvm_cpu *vcpu)
+{
+	return vcpu->sregs.cr0 & 0x01;
+}
+
+static inline u64 ip_to_flat(struct kvm_cpu *vcpu, u64 ip)
+{
+	u64 cs;
+
+	/*
+	 * NOTE! We should take code segment base address into account here.
+	 * Luckily it's usually zero because Linux uses flat memory model.
+	 */
+	if (is_in_protected_mode(vcpu))
+		return ip;
+
+	cs = vcpu->sregs.cs.selector;
+
+	return ip + (cs << 4);
+}
+
+static inline u32 selector_to_base(u16 selector)
+{
+	/*
+	 * KVM on Intel requires 'base' to be 'selector * 16' in real mode.
+	 */
+	return (u32)selector * 16;
+}
+
+static struct kvm_cpu *kvm_cpu__new(struct kvm *kvm)
+{
+	struct kvm_cpu *vcpu;
+
+	vcpu		= calloc(1, sizeof *vcpu);
+	if (!vcpu)
+		return NULL;
+
+	vcpu->kvm	= kvm;
+
+	return vcpu;
+}
+
+void kvm_cpu__delete(struct kvm_cpu *vcpu)
+{
+	if (vcpu->msrs)
+		free(vcpu->msrs);
+
+	free(vcpu);
+}
+
+struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id)
+{
+	struct kvm_cpu *vcpu;
+	int mmap_size;
+	int coalesced_offset;
+
+	vcpu		= kvm_cpu__new(kvm);
+	if (!vcpu)
+		return NULL;
+
+	vcpu->cpu_id	= cpu_id;
+
+	vcpu->vcpu_fd = ioctl(vcpu->kvm->vm_fd, KVM_CREATE_VCPU, cpu_id);
+	if (vcpu->vcpu_fd < 0)
+		die_perror("KVM_CREATE_VCPU ioctl");
+
+	mmap_size = ioctl(vcpu->kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
+	if (mmap_size < 0)
+		die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl");
+
+	vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, vcpu->vcpu_fd, 0);
+	if (vcpu->kvm_run == MAP_FAILED)
+		die("unable to mmap vcpu fd");
+
+	coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_COALESCED_MMIO);
+	if (coalesced_offset)
+		vcpu->ring = (void *)vcpu->kvm_run + (coalesced_offset * PAGE_SIZE);
+
+	vcpu->is_running = true;
+
+	return vcpu;
+}
+
+static struct kvm_msrs *kvm_msrs__new(size_t nmsrs)
+{
+	struct kvm_msrs *vcpu = calloc(1, sizeof(*vcpu) + (sizeof(struct kvm_msr_entry) * nmsrs));
+
+	if (!vcpu)
+		die("out of memory");
+
+	return vcpu;
+}
+
+#define KVM_MSR_ENTRY(_index, _data)	\
+	(struct kvm_msr_entry) { .index = _index, .data = _data }
+
+static void kvm_cpu__setup_msrs(struct kvm_cpu *vcpu)
+{
+	unsigned long ndx = 0;
+
+	vcpu->msrs = kvm_msrs__new(100);
+
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_CS,	0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_ESP,	0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_EIP,	0x0);
+#ifdef CONFIG_X86_64
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_STAR,			0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_CSTAR,			0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_KERNEL_GS_BASE,		0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_SYSCALL_MASK,		0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_LSTAR,			0x0);
+#endif
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_TSC,		0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_MISC_ENABLE,
+						MSR_IA32_MISC_ENABLE_FAST_STRING);
+
+	vcpu->msrs->nmsrs	= ndx;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_MSRS, vcpu->msrs) < 0)
+		die_perror("KVM_SET_MSRS failed");
+}
+
+static void kvm_cpu__setup_fpu(struct kvm_cpu *vcpu)
+{
+	vcpu->fpu = (struct kvm_fpu) {
+		.fcw		= 0x37f,
+		.mxcsr		= 0x1f80,
+	};
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_FPU, &vcpu->fpu) < 0)
+		die_perror("KVM_SET_FPU failed");
+}
+
+static void kvm_cpu__setup_regs(struct kvm_cpu *vcpu)
+{
+	vcpu->regs = (struct kvm_regs) {
+		/* We start the guest in 16-bit real mode  */
+		.rflags		= 0x0000000000000002ULL,
+
+		.rip		= vcpu->kvm->boot_ip,
+		.rsp		= vcpu->kvm->boot_sp,
+		.rbp		= vcpu->kvm->boot_sp,
+	};
+
+	if (vcpu->regs.rip > USHRT_MAX)
+		die("ip 0x%llx is too high for real mode", (u64) vcpu->regs.rip);
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_REGS, &vcpu->regs) < 0)
+		die_perror("KVM_SET_REGS failed");
+}
+
+static void kvm_cpu__setup_sregs(struct kvm_cpu *vcpu)
+{
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &vcpu->sregs) < 0)
+		die_perror("KVM_GET_SREGS failed");
+
+	vcpu->sregs.cs.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.cs.base	= selector_to_base(vcpu->kvm->boot_selector);
+	vcpu->sregs.ss.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.ss.base	= selector_to_base(vcpu->kvm->boot_selector);
+	vcpu->sregs.ds.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.ds.base	= selector_to_base(vcpu->kvm->boot_selector);
+	vcpu->sregs.es.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.es.base	= selector_to_base(vcpu->kvm->boot_selector);
+	vcpu->sregs.fs.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.fs.base	= selector_to_base(vcpu->kvm->boot_selector);
+	vcpu->sregs.gs.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.gs.base	= selector_to_base(vcpu->kvm->boot_selector);
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_SREGS, &vcpu->sregs) < 0)
+		die_perror("KVM_SET_SREGS failed");
+}
+
+/**
+ * kvm_cpu__reset_vcpu - reset virtual CPU to a known state
+ */
+void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
+{
+	kvm_cpu__setup_cpuid(vcpu);
+	kvm_cpu__setup_sregs(vcpu);
+	kvm_cpu__setup_regs(vcpu);
+	kvm_cpu__setup_fpu(vcpu);
+	kvm_cpu__setup_msrs(vcpu);
+}
+
+static void print_dtable(const char *name, struct kvm_dtable *dtable)
+{
+	dprintf(debug_fd, " %s                 %016llx  %08hx\n",
+		name, (u64) dtable->base, (u16) dtable->limit);
+}
+
+static void print_segment(const char *name, struct kvm_segment *seg)
+{
+	dprintf(debug_fd, " %s       %04hx      %016llx  %08x  %02hhx    %x %x   %x  %x %x %x %x\n",
+		name, (u16) seg->selector, (u64) seg->base, (u32) seg->limit,
+		(u8) seg->type, seg->present, seg->dpl, seg->db, seg->s, seg->l, seg->g, seg->avl);
+}
+
+void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
+{
+	unsigned long cr0, cr2, cr3;
+	unsigned long cr4, cr8;
+	unsigned long rax, rbx, rcx;
+	unsigned long rdx, rsi, rdi;
+	unsigned long rbp,  r8,  r9;
+	unsigned long r10, r11, r12;
+	unsigned long r13, r14, r15;
+	unsigned long rip, rsp;
+	struct kvm_sregs sregs;
+	unsigned long rflags;
+	struct kvm_regs regs;
+	int i;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &regs) < 0)
+		die("KVM_GET_REGS failed");
+
+	rflags = regs.rflags;
+
+	rip = regs.rip; rsp = regs.rsp;
+	rax = regs.rax; rbx = regs.rbx; rcx = regs.rcx;
+	rdx = regs.rdx; rsi = regs.rsi; rdi = regs.rdi;
+	rbp = regs.rbp; r8  = regs.r8;  r9  = regs.r9;
+	r10 = regs.r10; r11 = regs.r11; r12 = regs.r12;
+	r13 = regs.r13; r14 = regs.r14; r15 = regs.r15;
+
+	dprintf(debug_fd, "\n Registers:\n");
+	dprintf(debug_fd,   " ----------\n");
+	dprintf(debug_fd, " rip: %016lx   rsp: %016lx flags: %016lx\n", rip, rsp, rflags);
+	dprintf(debug_fd, " rax: %016lx   rbx: %016lx   rcx: %016lx\n", rax, rbx, rcx);
+	dprintf(debug_fd, " rdx: %016lx   rsi: %016lx   rdi: %016lx\n", rdx, rsi, rdi);
+	dprintf(debug_fd, " rbp: %016lx    r8: %016lx    r9: %016lx\n", rbp, r8,  r9);
+	dprintf(debug_fd, " r10: %016lx   r11: %016lx   r12: %016lx\n", r10, r11, r12);
+	dprintf(debug_fd, " r13: %016lx   r14: %016lx   r15: %016lx\n", r13, r14, r15);
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0)
+		die("KVM_GET_REGS failed");
+
+	cr0 = sregs.cr0; cr2 = sregs.cr2; cr3 = sregs.cr3;
+	cr4 = sregs.cr4; cr8 = sregs.cr8;
+
+	dprintf(debug_fd, " cr0: %016lx   cr2: %016lx   cr3: %016lx\n", cr0, cr2, cr3);
+	dprintf(debug_fd, " cr4: %016lx   cr8: %016lx\n", cr4, cr8);
+	dprintf(debug_fd, "\n Segment registers:\n");
+	dprintf(debug_fd,   " ------------------\n");
+	dprintf(debug_fd, " register  selector  base              limit     type  p dpl db s l g avl\n");
+	print_segment("cs ", &sregs.cs);
+	print_segment("ss ", &sregs.ss);
+	print_segment("ds ", &sregs.ds);
+	print_segment("es ", &sregs.es);
+	print_segment("fs ", &sregs.fs);
+	print_segment("gs ", &sregs.gs);
+	print_segment("tr ", &sregs.tr);
+	print_segment("ldt", &sregs.ldt);
+	print_dtable("gdt", &sregs.gdt);
+	print_dtable("idt", &sregs.idt);
+
+	dprintf(debug_fd, "\n APIC:\n");
+	dprintf(debug_fd,   " -----\n");
+	dprintf(debug_fd, " efer: %016llx  apic base: %016llx  nmi: %s\n",
+		(u64) sregs.efer, (u64) sregs.apic_base,
+		(vcpu->kvm->nmi_disabled ? "disabled" : "enabled"));
+
+	dprintf(debug_fd, "\n Interrupt bitmap:\n");
+	dprintf(debug_fd,   " -----------------\n");
+	for (i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; i++)
+		dprintf(debug_fd, " %016llx", (u64) sregs.interrupt_bitmap[i]);
+	dprintf(debug_fd, "\n");
+}
+
+#define MAX_SYM_LEN		128
+
+void kvm_cpu__show_code(struct kvm_cpu *vcpu)
+{
+	unsigned int code_bytes = 64;
+	unsigned int code_prologue = code_bytes * 43 / 64;
+	unsigned int code_len = code_bytes;
+	char sym[MAX_SYM_LEN];
+	unsigned char c;
+	unsigned int i;
+	u8 *ip;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &vcpu->regs) < 0)
+		die("KVM_GET_REGS failed");
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &vcpu->sregs) < 0)
+		die("KVM_GET_SREGS failed");
+
+	ip = guest_flat_to_host(vcpu->kvm, ip_to_flat(vcpu, vcpu->regs.rip) - code_prologue);
+
+	dprintf(debug_fd, "\n Code:\n");
+	dprintf(debug_fd,   " -----\n");
+
+	symbol__lookup(vcpu->kvm, vcpu->regs.rip, sym, MAX_SYM_LEN);
+
+	dprintf(debug_fd, " rip: [<%016lx>] %s\n\n", (unsigned long) vcpu->regs.rip, sym);
+
+	for (i = 0; i < code_len; i++, ip++) {
+		if (!host_ptr_in_ram(vcpu->kvm, ip))
+			break;
+
+		c = *ip;
+
+		if (ip == guest_flat_to_host(vcpu->kvm, ip_to_flat(vcpu, vcpu->regs.rip)))
+			dprintf(debug_fd, " <%02x>", c);
+		else
+			dprintf(debug_fd, " %02x", c);
+	}
+
+	dprintf(debug_fd, "\n");
+
+	dprintf(debug_fd, "\n Stack:\n");
+	dprintf(debug_fd,   " ------\n");
+	kvm__dump_mem(vcpu->kvm, vcpu->regs.rsp, 32);
+}
+
+void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
+{
+	u64 *pte1;
+	u64 *pte2;
+	u64 *pte3;
+	u64 *pte4;
+
+	if (!is_in_protected_mode(vcpu))
+		return;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &vcpu->sregs) < 0)
+		die("KVM_GET_SREGS failed");
+
+	pte4	= guest_flat_to_host(vcpu->kvm, vcpu->sregs.cr3);
+	if (!host_ptr_in_ram(vcpu->kvm, pte4))
+		return;
+
+	pte3	= guest_flat_to_host(vcpu->kvm, (*pte4 & ~0xfff));
+	if (!host_ptr_in_ram(vcpu->kvm, pte3))
+		return;
+
+	pte2	= guest_flat_to_host(vcpu->kvm, (*pte3 & ~0xfff));
+	if (!host_ptr_in_ram(vcpu->kvm, pte2))
+		return;
+
+	pte1	= guest_flat_to_host(vcpu->kvm, (*pte2 & ~0xfff));
+	if (!host_ptr_in_ram(vcpu->kvm, pte1))
+		return;
+
+	dprintf(debug_fd, "Page Tables:\n");
+	if (*pte2 & (1 << 7))
+		dprintf(debug_fd, " pte4: %016llx   pte3: %016llx"
+			"   pte2: %016llx\n",
+			*pte4, *pte3, *pte2);
+	else
+		dprintf(debug_fd, " pte4: %016llx  pte3: %016llx   pte2: %016"
+			"llx   pte1: %016llx\n",
+			*pte4, *pte3, *pte2, *pte1);
+}
tools/kvm/x86/kvm.c new file +330 -0
new file mode 100644
index 0000000..ac6c91e
@@ -0,0 +1,330 @@
+#include "kvm/kvm.h"
+#include "kvm/boot-protocol.h"
+#include "kvm/cpufeature.h"
+#include "kvm/interrupt.h"
+#include "kvm/mptable.h"
+#include "kvm/util.h"
+
+#include <asm/bootparam.h>
+#include <linux/kvm.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <asm/unistd.h>
+
+struct kvm_ext kvm_req_ext[] = {
+	{ DEFINE_KVM_EXT(KVM_CAP_COALESCED_MMIO) },
+	{ DEFINE_KVM_EXT(KVM_CAP_SET_TSS_ADDR) },
+	{ DEFINE_KVM_EXT(KVM_CAP_PIT2) },
+	{ DEFINE_KVM_EXT(KVM_CAP_USER_MEMORY) },
+	{ DEFINE_KVM_EXT(KVM_CAP_IRQ_ROUTING) },
+	{ DEFINE_KVM_EXT(KVM_CAP_IRQCHIP) },
+	{ DEFINE_KVM_EXT(KVM_CAP_HLT) },
+	{ DEFINE_KVM_EXT(KVM_CAP_IRQ_INJECT_STATUS) },
+	{ DEFINE_KVM_EXT(KVM_CAP_EXT_CPUID) },
+	{ 0, 0 }
+};
+
+bool kvm__arch_cpu_supports_vm(void)
+{
+	struct cpuid_regs regs;
+	u32 eax_base;
+	int feature;
+
+	regs	= (struct cpuid_regs) {
+		.eax		= 0x00,
+	};
+	host_cpuid(&regs);
+
+	switch (regs.ebx) {
+	case CPUID_VENDOR_INTEL_1:
+		eax_base	= 0x00;
+		feature		= KVM__X86_FEATURE_VMX;
+		break;
+
+	case CPUID_VENDOR_AMD_1:
+		eax_base	= 0x80000000;
+		feature		= KVM__X86_FEATURE_SVM;
+		break;
+
+	default:
+		return false;
+	}
+
+	regs	= (struct cpuid_regs) {
+		.eax		= eax_base,
+	};
+	host_cpuid(&regs);
+
+	if (regs.eax < eax_base + 0x01)
+		return false;
+
+	regs	= (struct cpuid_regs) {
+		.eax		= eax_base + 0x01
+	};
+	host_cpuid(&regs);
+
+	return regs.ecx & (1 << feature);
+}
+
+/*
+ * Allocating RAM size bigger than 4GB requires us to leave a gap
+ * in the RAM which is used for PCI MMIO, hotplug, and unconfigured
+ * devices (see documentation of e820_setup_gap() for details).
+ *
+ * If we're required to initialize RAM bigger than 4GB, we will create
+ * a gap between 0xe0000000 and 0x100000000 in the guest virtual mem space.
+ */
+
+void kvm__init_ram(struct kvm *kvm)
+{
+	u64	phys_start, phys_size;
+	void	*host_mem;
+
+	if (kvm->ram_size < KVM_32BIT_GAP_START) {
+		/* Use a single block of RAM for 32bit RAM */
+
+		phys_start = 0;
+		phys_size  = kvm->ram_size;
+		host_mem   = kvm->ram_start;
+
+		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
+	} else {
+		/* First RAM range from zero to the PCI gap: */
+
+		phys_start = 0;
+		phys_size  = KVM_32BIT_GAP_START;
+		host_mem   = kvm->ram_start;
+
+		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
+
+		/* Second RAM range from 4GB to the end of RAM: */
+
+		phys_start = 0x100000000ULL;
+		phys_size  = kvm->ram_size - phys_size;
+		host_mem   = kvm->ram_start + phys_start;
+
+		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
+	}
+}
+
+/* Architecture-specific KVM init */
+void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name)
+{
+	struct kvm_pit_config pit_config = { .flags = 0, };
+	int ret;
+
+	ret = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000);
+	if (ret < 0)
+		die_perror("KVM_SET_TSS_ADDR ioctl");
+
+	ret = ioctl(kvm->vm_fd, KVM_CREATE_PIT2, &pit_config);
+	if (ret < 0)
+		die_perror("KVM_CREATE_PIT2 ioctl");
+
+	kvm->ram_size		= ram_size;
+
+	if (kvm->ram_size < KVM_32BIT_GAP_START) {
+		kvm->ram_start = mmap(NULL, ram_size, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
+	} else {
+		kvm->ram_start = mmap(NULL, ram_size + KVM_32BIT_GAP_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
+		if (kvm->ram_start != MAP_FAILED) {
+			/*
+			 * We mprotect the gap (see kvm__init_ram() for details) PROT_NONE so that
+			 * if we accidently write to it, we will know.
+			 */
+			mprotect(kvm->ram_start + KVM_32BIT_GAP_START, KVM_32BIT_GAP_SIZE, PROT_NONE);
+		}
+	}
+	if (kvm->ram_start == MAP_FAILED)
+		die("out of memory");
+
+	madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
+
+	ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
+	if (ret < 0)
+		die_perror("KVM_CREATE_IRQCHIP ioctl");
+}
+
+void kvm__irq_line(struct kvm *kvm, int irq, int level)
+{
+	struct kvm_irq_level irq_level;
+
+	irq_level	= (struct kvm_irq_level) {
+		{
+			.irq		= irq,
+		},
+		.level		= level,
+	};
+
+	if (ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level) < 0)
+		die_perror("KVM_IRQ_LINE failed");
+}
+
+void kvm__irq_trigger(struct kvm *kvm, int irq)
+{
+	kvm__irq_line(kvm, irq, 1);
+	kvm__irq_line(kvm, irq, 0);
+}
+
+#define BOOT_LOADER_SELECTOR	0x1000
+#define BOOT_LOADER_IP		0x0000
+#define BOOT_LOADER_SP		0x8000
+#define BOOT_CMDLINE_OFFSET	0x20000
+
+#define BOOT_PROTOCOL_REQUIRED	0x206
+#define LOAD_HIGH		0x01
+
+int load_flat_binary(struct kvm *kvm, int fd)
+{
+	void *p;
+	int nr;
+
+	if (lseek(fd, 0, SEEK_SET) < 0)
+		die_perror("lseek");
+
+	p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
+
+	while ((nr = read(fd, p, 65536)) > 0)
+		p += nr;
+
+	kvm->boot_selector	= BOOT_LOADER_SELECTOR;
+	kvm->boot_ip		= BOOT_LOADER_IP;
+	kvm->boot_sp		= BOOT_LOADER_SP;
+
+	return true;
+}
+
+static const char *BZIMAGE_MAGIC	= "HdrS";
+
+bool load_bzimage(struct kvm *kvm, int fd_kernel,
+		  int fd_initrd, const char *kernel_cmdline, u16 vidmode)
+{
+	struct boot_params *kern_boot;
+	unsigned long setup_sects;
+	struct boot_params boot;
+	size_t cmdline_size;
+	ssize_t setup_size;
+	void *p;
+	int nr;
+
+	/*
+	 * See Documentation/x86/boot.txt for details no bzImage on-disk and
+	 * memory layout.
+	 */
+
+	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
+		die_perror("lseek");
+
+	if (read(fd_kernel, &boot, sizeof(boot)) != sizeof(boot))
+		return false;
+
+	if (memcmp(&boot.hdr.header, BZIMAGE_MAGIC, strlen(BZIMAGE_MAGIC)))
+		return false;
+
+	if (boot.hdr.version < BOOT_PROTOCOL_REQUIRED)
+		die("Too old kernel");
+
+	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
+		die_perror("lseek");
+
+	if (!boot.hdr.setup_sects)
+		boot.hdr.setup_sects = BZ_DEFAULT_SETUP_SECTS;
+	setup_sects = boot.hdr.setup_sects + 1;
+
+	setup_size = setup_sects << 9;
+	p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
+
+	/* copy setup.bin to mem*/
+	if (read(fd_kernel, p, setup_size) != setup_size)
+		die_perror("read");
+
+	/* copy vmlinux.bin to BZ_KERNEL_START*/
+	p = guest_flat_to_host(kvm, BZ_KERNEL_START);
+
+	while ((nr = read(fd_kernel, p, 65536)) > 0)
+		p += nr;
+
+	p = guest_flat_to_host(kvm, BOOT_CMDLINE_OFFSET);
+	if (kernel_cmdline) {
+		cmdline_size = strlen(kernel_cmdline) + 1;
+		if (cmdline_size > boot.hdr.cmdline_size)
+			cmdline_size = boot.hdr.cmdline_size;
+
+		memset(p, 0, boot.hdr.cmdline_size);
+		memcpy(p, kernel_cmdline, cmdline_size - 1);
+	}
+
+	kern_boot	= guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, 0x00);
+
+	kern_boot->hdr.cmd_line_ptr	= BOOT_CMDLINE_OFFSET;
+	kern_boot->hdr.type_of_loader	= 0xff;
+	kern_boot->hdr.heap_end_ptr	= 0xfe00;
+	kern_boot->hdr.loadflags	|= CAN_USE_HEAP;
+	kern_boot->hdr.vid_mode		= vidmode;
+
+	/*
+	 * Read initrd image into guest memory
+	 */
+	if (fd_initrd >= 0) {
+		struct stat initrd_stat;
+		unsigned long addr;
+
+		if (fstat(fd_initrd, &initrd_stat))
+			die_perror("fstat");
+
+		addr = boot.hdr.initrd_addr_max & ~0xfffff;
+		for (;;) {
+			if (addr < BZ_KERNEL_START)
+				die("Not enough memory for initrd");
+			else if (addr < (kvm->ram_size - initrd_stat.st_size))
+				break;
+			addr -= 0x100000;
+		}
+
+		p = guest_flat_to_host(kvm, addr);
+		nr = read(fd_initrd, p, initrd_stat.st_size);
+		if (nr != initrd_stat.st_size)
+			die("Failed to read initrd");
+
+		kern_boot->hdr.ramdisk_image	= addr;
+		kern_boot->hdr.ramdisk_size	= initrd_stat.st_size;
+	}
+
+	kvm->boot_selector	= BOOT_LOADER_SELECTOR;
+	/*
+	 * The real-mode setup code starts at offset 0x200 of a bzImage. See
+	 * Documentation/x86/boot.txt for details.
+	 */
+	kvm->boot_ip		= BOOT_LOADER_IP + 0x200;
+	kvm->boot_sp		= BOOT_LOADER_SP;
+
+	return true;
+}
+
+/**
+ * kvm__arch_setup_firmware - inject BIOS into guest system memory
+ * @kvm - guest system descriptor
+ *
+ * This function is a main routine where we poke guest memory
+ * and install BIOS there.
+ */
+void kvm__arch_setup_firmware(struct kvm *kvm)
+{
+	/* standart minimal configuration */
+	setup_bios(kvm);
+
+	/* FIXME: SMP, ACPI and friends here */
+
+	/* MP table */
+	mptable_setup(kvm, kvm->nrcpus);
+}
tools/kvm/x86/mptable.c renamed from tools/kvm/mptable.c +0 -1
similarity index 100%
rename from tools/kvm/mptable.c
rename to tools/kvm/x86/mptable.c
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Sasha.
#3 lore raw
Quoted 3 lines · Sasha Levin

The code doesn't build after this patch due to missing header issues which you fixed in patches #10 & #11. Could you please move those two to the beginning of the series for the sake of bisectablilty?

I did that myself. Patches 10, 11, and 1 applied, thanks!

author
#4 lore raw

PATCH 2/28 kvm tools: Only build/init i8042 on x86

In reply to a message not in the archive

Not every architecture has an i8042 kbd controller, so only use this when building for x86.

---
 tools/kvm/Makefile      |    2 +-
 tools/kvm/builtin-run.c |    2 ++
 2 files changed, 3 insertions(+), 1 deletions(-)
tools/kvm/Makefile +1 -1
index 243886e..f58a1d8 100644
@@ -77,7 +77,6 @@ OBJS	+= util/strbuf.o
 OBJS	+= virtio/9p.o
 OBJS	+= virtio/9p-pdu.o
 OBJS	+= hw/vesa.o
-OBJS	+= hw/i8042.o
 OBJS	+= hw/pci-shmem.o
 OBJS	+= kvm-ipc.o
 
@@ -153,6 +152,7 @@ ifeq ($(ARCH),x86)
 	OBJS	+= x86/kvm.o
 	OBJS	+= x86/kvm-cpu.o
 	OBJS	+= x86/mptable.o
+	OBJS	+= hw/i8042.o
 # Exclude BIOS object files from header dependencies.
 	OTHEROBJS	+= x86/bios.o
 	OTHEROBJS	+= x86/bios/bios-rom.o
tools/kvm/builtin-run.c +2 -0
index 9148d83..e4aa87e 100644
@@ -941,7 +941,9 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm__init_ram(kvm);
 
+#ifdef CONFIG_X86
 	kbd__init(kvm);
+#endif
 
 	pci_shmem__init(kvm);
 
#5 lore raw

Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86

For some reason I can't explain, I'm getting this error after applying this patch:

Applying: kvm tools: Only build/init i8042 on x86
fatal: mode change for tools/kvm/bios.c, which is not in current HEAD Repository lacks necessary blobs to fall back on 3-way merge. Cannot fall back to three-way merge.
Patch failed at 0002 kvm tools: Only build/init i8042 on x86

Any idea why it would happen?

Quoted 47 lines · Matt Evans

Not every architecture has an i8042 kbd controller, so only use this when building for x86.

---
 tools/kvm/Makefile      |    2 +-
 tools/kvm/builtin-run.c |    2 ++
 2 files changed, 3 insertions(+), 1 deletions(-)
tools/kvm/Makefile +1 -1
index 243886e..f58a1d8 100644
@@ -77,7 +77,6 @@ OBJS	+= util/strbuf.o
 OBJS	+= virtio/9p.o
 OBJS	+= virtio/9p-pdu.o
 OBJS	+= hw/vesa.o
-OBJS	+= hw/i8042.o
 OBJS	+= hw/pci-shmem.o
 OBJS	+= kvm-ipc.o
 
@@ -153,6 +152,7 @@ ifeq ($(ARCH),x86)
 	OBJS	+= x86/kvm.o
 	OBJS	+= x86/kvm-cpu.o
 	OBJS	+= x86/mptable.o
+	OBJS	+= hw/i8042.o
 # Exclude BIOS object files from header dependencies.
 	OTHEROBJS	+= x86/bios.o
 	OTHEROBJS	+= x86/bios/bios-rom.o
tools/kvm/builtin-run.c +2 -1
index 9148d83..e4aa87e 100644
@@ -941,7 +941,9 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm__init_ram(kvm);
 
+#ifdef CONFIG_X86
 	kbd__init(kvm);
+#endif
 
 	pci_shmem__init(kvm);
 
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Sasha.
#6 lore raw

Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86

In reply to Matt Evans
Quoted 2 lines · Matt Evans

Not every architecture has an i8042 kbd controller, so only use this when building for x86.

There are non-x86 machines that have one, though -- does KVM tool have any sort of target configuration mechanism?

-Scott

author
#7 lore raw

Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86

Quoted 6 lines · Scott Wood
Quoted 2 lines · Matt Evans

Not every architecture has an i8042 kbd controller, so only use this when building for x86.

There are non-x86 machines that have one, though -- does KVM tool have any sort of target configuration mechanism?

See my other mail (of 1m ago), there isn't a configuration mechanism nor a way to select devices at run-time (nor buses to attach them to, etc.). This patch is a bit of a hack, though there's no other way without the extra infrastructure. This patch will get a 2nd platform going, and can be revisited when another rears its head.

Cheers,

Matt

author
#8 lore raw

PATCH 3/28 kvm tools: Add Makefile parameter for kernel include path

In reply to a message not in the archive

This patch adds an 'I' parameter to override the default kernel include path of '../../include'.

---
 tools/kvm/Makefile |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)
tools/kvm/Makefile +7 -2
index f58a1d8..f85a154 100644
@@ -9,7 +9,12 @@ else
 	E = @\#
 	Q =
 endif
-export E Q
+ifneq ($(I), )
+	KINCL_PATH=$(I)
+else
+	KINCL_PATH=../..
+endif
+export E Q KINCL_PATH
 
 include config/utilities.mak
 include config/feature-tests.mak
@@ -176,7 +181,7 @@ DEFINES	+= -DKVMTOOLS_VERSION='"$(KVMTOOLS_VERSION)"'
 DEFINES	+= -DBUILD_ARCH='"$(ARCH)"'
 
 KVM_INCLUDE := include
-CFLAGS	+= $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I$(ARCH_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -Os -g
+CFLAGS	+= $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I$(ARCH_INCLUDE) -I$(KINCL_PATH)/include -I$(KINCL_PATH)/arch/$(ARCH)/include/ -Os -g
 
 ifneq ($(WERROR),0)
 	WARNINGS += -Werror
author
#9 lore raw

PATCH 4/28 kvm tools: Re-arrange Makefile to heed CFLAGS before checking for optional libs

In reply to a message not in the archive

The checks for optional libraries build code to perform the tests, so should respect certain CFLAGS -- in particular, -m64 so we check for 64bit libraries if they're required.

---
 tools/kvm/Makefile |   86 ++++++++++++++++++++++++++-------------------------
 1 files changed, 44 insertions(+), 42 deletions(-)
tools/kvm/Makefile +44 -42
index f85a154..009a6ba 100644
@@ -85,48 +85,6 @@ OBJS	+= hw/vesa.o
 OBJS	+= hw/pci-shmem.o
 OBJS	+= kvm-ipc.o
 
-FLAGS_BFD := $(CFLAGS) -lbfd
-has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD))
-ifeq ($(has_bfd),y)
-	CFLAGS	+= -DCONFIG_HAS_BFD
-	OBJS	+= symbol.o
-	LIBS	+= -lbfd
-endif
-
-FLAGS_VNCSERVER := $(CFLAGS) -lvncserver
-has_vncserver := $(call try-cc,$(SOURCE_VNCSERVER),$(FLAGS_VNCSERVER))
-ifeq ($(has_vncserver),y)
-	OBJS	+= ui/vnc.o
-	CFLAGS	+= -DCONFIG_HAS_VNCSERVER
-	LIBS	+= -lvncserver
-endif
-
-FLAGS_SDL := $(CFLAGS) -lSDL
-has_SDL := $(call try-cc,$(SOURCE_SDL),$(FLAGS_SDL))
-ifeq ($(has_SDL),y)
-	OBJS	+= ui/sdl.o
-	CFLAGS	+= -DCONFIG_HAS_SDL
-	LIBS	+= -lSDL
-endif
-
-FLAGS_ZLIB := $(CFLAGS) -lz
-has_ZLIB := $(call try-cc,$(SOURCE_ZLIB),$(FLAGS_ZLIB))
-ifeq ($(has_ZLIB),y)
-	CFLAGS	+= -DCONFIG_HAS_ZLIB
-	LIBS	+= -lz
-endif
-
-FLAGS_AIO := $(CFLAGS) -laio
-has_AIO := $(call try-cc,$(SOURCE_AIO),$(FLAGS_AIO))
-ifeq ($(has_AIO),y)
-	CFLAGS	+= -DCONFIG_HAS_AIO
-	LIBS	+= -laio
-endif
-
-LIBS	+= -lrt
-LIBS	+= -lpthread
-LIBS	+= -lutil
-
 # Additional ARCH settings for x86
 ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
                   -e s/arm.*/arm/ -e s/sa110/arm/ \
@@ -172,6 +130,50 @@ else
 	UNSUPP_ERR =
 endif
 
+
+FLAGS_BFD := $(CFLAGS) -lbfd
+has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD))
+ifeq ($(has_bfd),y)
+	CFLAGS	+= -DCONFIG_HAS_BFD
+	OBJS	+= symbol.o
+	LIBS	+= -lbfd
+endif
+
+FLAGS_VNCSERVER := $(CFLAGS) -lvncserver
+has_vncserver := $(call try-cc,$(SOURCE_VNCSERVER),$(FLAGS_VNCSERVER))
+ifeq ($(has_vncserver),y)
+	OBJS	+= ui/vnc.o
+	CFLAGS	+= -DCONFIG_HAS_VNCSERVER
+	LIBS	+= -lvncserver
+endif
+
+FLAGS_SDL := $(CFLAGS) -lSDL
+has_SDL := $(call try-cc,$(SOURCE_SDL),$(FLAGS_SDL))
+ifeq ($(has_SDL),y)
+	OBJS	+= ui/sdl.o
+	CFLAGS	+= -DCONFIG_HAS_SDL
+	LIBS	+= -lSDL
+endif
+
+FLAGS_ZLIB := $(CFLAGS) -lz
+has_ZLIB := $(call try-cc,$(SOURCE_ZLIB),$(FLAGS_ZLIB))
+ifeq ($(has_ZLIB),y)
+	CFLAGS	+= -DCONFIG_HAS_ZLIB
+	LIBS	+= -lz
+endif
+
+FLAGS_AIO := $(CFLAGS) -laio
+has_AIO := $(call try-cc,$(SOURCE_AIO),$(FLAGS_AIO))
+ifeq ($(has_AIO),y)
+	CFLAGS	+= -DCONFIG_HAS_AIO
+	LIBS	+= -laio
+endif
+
+LIBS	+= -lrt
+LIBS	+= -lpthread
+LIBS	+= -lutil
+
+
 DEPS	:= $(patsubst %.o,%.d,$(OBJS))
 OBJS	+= $(OTHEROBJS)
 
author
#10 lore raw

PATCH 5/28 kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

In reply to a message not in the archive

On LP64 systems our u64s are just longs; remove the %llx'es in favour of PRIx64 etc.

This patch also adds CFLAGS to the final link, so that any -m64 is obeyed when linking, too.

---
 tools/kvm/Makefile       |    2 +-
 tools/kvm/builtin-run.c  |   14 ++++++++------
 tools/kvm/builtin-stat.c |    4 +++-
 tools/kvm/disk/core.c    |    4 +++-
 tools/kvm/mmio.c         |    4 +++-
 5 files changed, 18 insertions(+), 10 deletions(-)
tools/kvm/Makefile +1 -1
index 009a6ba..57dc521 100644
@@ -218,7 +218,7 @@ KVMTOOLS-VERSION-FILE:
 
 $(PROGRAM): $(DEPS) $(OBJS)
 	$(E) "  LINK    " $@
-	$(Q) $(CC) $(OBJS) $(LIBS) -o $@
+	$(Q) $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $@
 
 $(GUEST_INIT): guest/init.c
 	$(E) "  LINK    " $@
tools/kvm/builtin-run.c +8 -6
index e4aa87e..7cf208d 100644
@@ -42,6 +42,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
 #include <ctype.h>
 #include <stdio.h>
 
@@ -383,8 +385,8 @@ static int shmem_parser(const struct option *opt, const char *arg, int unset)
 		strcpy(handle, default_handle);
 	}
 	if (verbose) {
-		pr_info("shmem: phys_addr = %llx", phys_addr);
-		pr_info("shmem: size      = %llx", size);
+		pr_info("shmem: phys_addr = %"PRIx64, phys_addr);
+		pr_info("shmem: size      = %"PRIx64, size);
 		pr_info("shmem: handle    = %s", handle);
 		pr_info("shmem: create    = %d", create);
 	}
@@ -545,7 +547,7 @@ panic_kvm:
 		current_kvm_cpu->kvm_run->exit_reason,
 		kvm_exit_reasons[current_kvm_cpu->kvm_run->exit_reason]);
 	if (current_kvm_cpu->kvm_run->exit_reason == KVM_EXIT_UNKNOWN)
-		fprintf(stderr, "KVM exit code: 0x%Lu\n",
+		fprintf(stderr, "KVM exit code: 0x%"PRIx64"\n",
 			current_kvm_cpu->kvm_run->hw.hardware_exit_reason);
 
 	kvm_cpu__set_debug_fd(STDOUT_FILENO);
@@ -760,10 +762,10 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		ram_size	= get_ram_size(nrcpus);
 
 	if (ram_size < MIN_RAM_SIZE_MB)
-		die("Not enough memory specified: %lluMB (min %lluMB)", ram_size, MIN_RAM_SIZE_MB);
+		die("Not enough memory specified: %"PRIu64"MB (min %lluMB)", ram_size, MIN_RAM_SIZE_MB);
 
 	if (ram_size > host_ram_size())
-		pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB", ram_size, host_ram_size());
+		pr_warning("Guest memory size %"PRIu64"MB exceeds host physical RAM size %"PRIu64"MB", ram_size, host_ram_size());
 
 	ram_size <<= MB_SHIFT;
 
@@ -878,7 +880,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		virtio_blk__init_all(kvm);
 	}
 
-	printf("  # kvm run -k %s -m %Lu -c %d --name %s\n", kernel_filename, ram_size / 1024 / 1024, nrcpus, guest_name);
+	printf("  # kvm run -k %s -m %"PRId64" -c %d --name %s\n", kernel_filename, ram_size / 1024 / 1024, nrcpus, guest_name);
 
 	if (!kvm__load_kernel(kvm, kernel_filename, initrd_filename,
 				real_cmdline, vidmode))
tools/kvm/builtin-stat.c +3 -1
index e28eb5b..c1f2605 100644
@@ -9,6 +9,8 @@
 #include <stdio.h>
 #include <string.h>
 #include <signal.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
 
 #include <linux/virtio_balloon.h>
 
@@ -97,7 +99,7 @@ static int do_memstat(const char *name, int sock)
 			printf("The total amount of memory available (in bytes):");
 			break;
 		}
-		printf("%llu\n", stats[i].val);
+		printf("%"PRId64"\n", stats[i].val);
 	}
 	printf("\n");
 
tools/kvm/disk/core.c +3 -1
index 4915efd..a135851 100644
@@ -4,6 +4,8 @@
 
 #include <sys/eventfd.h>
 #include <sys/poll.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
 
 #define AIO_MAX 32
 
@@ -232,7 +234,7 @@ ssize_t disk_image__get_serial(struct disk_image *disk, void *buffer, ssize_t *l
 	if (fstat(disk->fd, &st) != 0)
 		return 0;
 
-	*len = snprintf(buffer, *len, "%llu%llu%llu", (u64)st.st_dev, (u64)st.st_rdev, (u64)st.st_ino);
+	*len = snprintf(buffer, *len, "%"PRId64"%"PRId64"%"PRId64, (u64)st.st_dev, (u64)st.st_rdev, (u64)st.st_ino);
 	return *len;
 }
 
tools/kvm/mmio.c +3 -1
index de7320f..1158bff 100644
@@ -9,6 +9,8 @@
 #include <linux/kvm.h>
 #include <linux/types.h>
 #include <linux/rbtree.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
 
 #define mmio_node(n) rb_entry(n, struct mmio_mapping, node)
 
@@ -124,7 +126,7 @@ bool kvm__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_
 	if (mmio)
 		mmio->mmio_fn(phys_addr, data, len, is_write, mmio->ptr);
 	else
-		fprintf(stderr, "Warning: Ignoring MMIO %s at %016llx (length %u)\n",
+		fprintf(stderr, "Warning: Ignoring MMIO %s at %016"PRIx64" (length %u)\n",
 			to_direction(is_write), phys_addr, len);
 	br_read_unlock();
 
#11 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Ingo actually got us to remove all the PRI* specifiers, but that was back when we only did x86 :)

Ingo, does it make sense to use them now when we support different architectures?

Quoted 153 lines · Matt Evans

On LP64 systems our u64s are just longs; remove the %llx'es in favour of PRIx64 etc.

This patch also adds CFLAGS to the final link, so that any -m64 is obeyed when linking, too.

---
 tools/kvm/Makefile       |    2 +-
 tools/kvm/builtin-run.c  |   14 ++++++++------
 tools/kvm/builtin-stat.c |    4 +++-
 tools/kvm/disk/core.c    |    4 +++-
 tools/kvm/mmio.c         |    4 +++-
 5 files changed, 18 insertions(+), 10 deletions(-)
tools/kvm/Makefile +1 -1
index 009a6ba..57dc521 100644
@@ -218,7 +218,7 @@ KVMTOOLS-VERSION-FILE:
 
 $(PROGRAM): $(DEPS) $(OBJS)
 	$(E) "  LINK    " $@
-	$(Q) $(CC) $(OBJS) $(LIBS) -o $@
+	$(Q) $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $@
 
 $(GUEST_INIT): guest/init.c
 	$(E) "  LINK    " $@
tools/kvm/builtin-run.c +8 -6
index e4aa87e..7cf208d 100644
@@ -42,6 +42,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
 #include <ctype.h>
 #include <stdio.h>
 
@@ -383,8 +385,8 @@ static int shmem_parser(const struct option *opt, const char *arg, int unset)
 		strcpy(handle, default_handle);
 	}
 	if (verbose) {
-		pr_info("shmem: phys_addr = %llx", phys_addr);
-		pr_info("shmem: size      = %llx", size);
+		pr_info("shmem: phys_addr = %"PRIx64, phys_addr);
+		pr_info("shmem: size      = %"PRIx64, size);
 		pr_info("shmem: handle    = %s", handle);
 		pr_info("shmem: create    = %d", create);
 	}
@@ -545,7 +547,7 @@ panic_kvm:
 		current_kvm_cpu->kvm_run->exit_reason,
 		kvm_exit_reasons[current_kvm_cpu->kvm_run->exit_reason]);
 	if (current_kvm_cpu->kvm_run->exit_reason = KVM_EXIT_UNKNOWN)
-		fprintf(stderr, "KVM exit code: 0x%Lu\n",
+		fprintf(stderr, "KVM exit code: 0x%"PRIx64"\n",
 			current_kvm_cpu->kvm_run->hw.hardware_exit_reason);
 
 	kvm_cpu__set_debug_fd(STDOUT_FILENO);
@@ -760,10 +762,10 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		ram_size	= get_ram_size(nrcpus);
 
 	if (ram_size < MIN_RAM_SIZE_MB)
-		die("Not enough memory specified: %lluMB (min %lluMB)", ram_size, MIN_RAM_SIZE_MB);
+		die("Not enough memory specified: %"PRIu64"MB (min %lluMB)", ram_size, MIN_RAM_SIZE_MB);
 
 	if (ram_size > host_ram_size())
-		pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB", ram_size, host_ram_size());
+		pr_warning("Guest memory size %"PRIu64"MB exceeds host physical RAM size %"PRIu64"MB", ram_size, host_ram_size());
 
 	ram_size <<= MB_SHIFT;
 
@@ -878,7 +880,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		virtio_blk__init_all(kvm);
 	}
 
-	printf("  # kvm run -k %s -m %Lu -c %d --name %s\n", kernel_filename, ram_size / 1024 / 1024, nrcpus, guest_name);
+	printf("  # kvm run -k %s -m %"PRId64" -c %d --name %s\n", kernel_filename, ram_size / 1024 / 1024, nrcpus, guest_name);
 
 	if (!kvm__load_kernel(kvm, kernel_filename, initrd_filename,
 				real_cmdline, vidmode))
tools/kvm/builtin-stat.c +3 -1
index e28eb5b..c1f2605 100644
@@ -9,6 +9,8 @@
 #include <stdio.h>
 #include <string.h>
 #include <signal.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
 
 #include <linux/virtio_balloon.h>
 
@@ -97,7 +99,7 @@ static int do_memstat(const char *name, int sock)
 			printf("The total amount of memory available (in bytes):");
 			break;
 		}
-		printf("%llu\n", stats[i].val);
+		printf("%"PRId64"\n", stats[i].val);
 	}
 	printf("\n");
 
tools/kvm/disk/core.c +3 -1
index 4915efd..a135851 100644
@@ -4,6 +4,8 @@
 
 #include <sys/eventfd.h>
 #include <sys/poll.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
 
 #define AIO_MAX 32
 
@@ -232,7 +234,7 @@ ssize_t disk_image__get_serial(struct disk_image *disk, void *buffer, ssize_t *l
 	if (fstat(disk->fd, &st) != 0)
 		return 0;
 
-	*len = snprintf(buffer, *len, "%llu%llu%llu", (u64)st.st_dev, (u64)st.st_rdev, (u64)st.st_ino);
+	*len = snprintf(buffer, *len, "%"PRId64"%"PRId64"%"PRId64, (u64)st.st_dev, (u64)st.st_rdev, (u64)st.st_ino);
 	return *len;
 }
 
tools/kvm/mmio.c +3 -2
index de7320f..1158bff 100644
@@ -9,6 +9,8 @@
 #include <linux/kvm.h>
 #include <linux/types.h>
 #include <linux/rbtree.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
 
 #define mmio_node(n) rb_entry(n, struct mmio_mapping, node)
 
@@ -124,7 +126,7 @@ bool kvm__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_
 	if (mmio)
 		mmio->mmio_fn(phys_addr, data, len, is_write, mmio->ptr);
 	else
-		fprintf(stderr, "Warning: Ignoring MMIO %s at %016llx (length %u)\n",
+		fprintf(stderr, "Warning: Ignoring MMIO %s at %016"PRIx64" (length %u)\n",
 			to_direction(is_write), phys_addr, len);
 	br_read_unlock();
 
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Sasha.
#12 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 5 lines · Sasha Levin

Ingo actually got us to remove all the PRI* specifiers, but that was back when we only did x86 :)

Ingo, does it make sense to use them now when we support different architectures?

Not at all - ppc should use a sane u64/s64 definition, i.e. int-ll64.h instead of the int-l64.h crap.

The powerpc maintainers indicated that they'd fix that, a couple of years ago, but nothing appears to have come out of that.

Thanks,

Ingo

#13 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 6 lines · Ingo Molnar
Quoted 3 lines · Sasha Levin

Ingo actually got us to remove all the PRI* specifiers, but that was back when we only did x86 :)

Quoted 8 lines
Quoted 2 lines

Ingo, does it make sense to use them now when we support different architectures?

Not at all - ppc should use a sane u64/s64 definition, i.e. int-ll64.h instead of the int-l64.h crap.

The powerpc maintainers indicated that they'd fix that, a couple of years ago, but nothing appears to have come out of that.

We changed it for the kernel, but not for userspace (i.e. glibc) because of concerns about possibly breaking existing userspace programs. I haven't looked closely at Matt's patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.

Paul.

#14 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 13 lines · Paul Mackerras
Quoted 12 lines · Ingo Molnar
Quoted 5 lines · Sasha Levin

Ingo actually got us to remove all the PRI* specifiers, but that was back when we only did x86 :)

Ingo, does it make sense to use them now when we support different architectures?

Not at all - ppc should use a sane u64/s64 definition, i.e. int-ll64.h instead of the int-l64.h crap.

Quoted 6 lines
Quoted 2 lines

The powerpc maintainers indicated that they'd fix that, a couple of years ago, but nothing appears to have come out of that.

We changed it for the kernel, but not for userspace (i.e. glibc) because of concerns about possibly breaking existing userspace programs. [...]

Indeed, you do:

#if defined(__powerpc64__) && !defined(__KERNEL__)

 # include <asm-generic/int-l64.h>
 #else
 # include <asm-generic/int-ll64.h>
 #endif

which correctly uses int-ll64.h everywhere except 64-bit userspace inclusions. So i take back my 'nothing appears to have come out of that' comment - it's all nicely fixed!

Quoted 3 lines

[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.

In tools/kvm/ we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick up int-l64.h accidentally via the arch/powerpc/include/asm/types.h exception for user-space.

Stray uses of int64 should be converted to u64 (i see some in tools/kvm/virtio/9p-pdu.c) but otherwise we should be ok - unless i'm missing some complication.

Thanks,

Ingo

author
#15 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Hi Ingo,

Quoted 35 lines · Ingo Molnar
Quoted 13 lines · Paul Mackerras
Quoted 12 lines · Ingo Molnar
Quoted 5 lines · Sasha Levin

Ingo actually got us to remove all the PRI* specifiers, but that was back when we only did x86 :)

Ingo, does it make sense to use them now when we support different architectures?

Not at all - ppc should use a sane u64/s64 definition, i.e. int-ll64.h instead of the int-l64.h crap.

Quoted 6 lines
Quoted 2 lines

The powerpc maintainers indicated that they'd fix that, a couple of years ago, but nothing appears to have come out of that.

We changed it for the kernel, but not for userspace (i.e. glibc) because of concerns about possibly breaking existing userspace programs. [...]

Indeed, you do:

#if defined(__powerpc64__) && !defined(__KERNEL__)

 # include <asm-generic/int-l64.h>
 #else
 # include <asm-generic/int-ll64.h>
 #endif

which correctly uses int-ll64.h everywhere except 64-bit userspace inclusions. So i take back my 'nothing appears to have come out of that' comment - it's all nicely fixed!

Quoted 8 lines
Quoted 3 lines

[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.

In tools/kvm/ we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick up int-l64.h accidentally via the arch/powerpc/include/asm/types.h exception for user-space.

That's what's happening here; we're __powerpc64__ and !__KERNEL__, tools/kvm/include/linux/types.h includes asm/types.h so gets the int-l64.h definition of __u64, as above. :/

builtin-run.c:389: error: format %llx' expects type long long unsigned int', but argument 2 has type `u64'

etc. etc.

Cheers,

Matt

#16 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines

[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.

In tools/kvm/ we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick up int-l64.h accidentally via the arch/powerpc/include/asm/types.h exception for user-space.

Quoted 7 lines

That's what's happening here; we're __powerpc64__ and !__KERNEL__, tools/kvm/include/linux/types.h includes asm/types.h so gets the int-l64.h definition of __u64, as above. :/

builtin-run.c:389: error: format %llx' expects type long long unsigned int', but argument 2 has type `u64'

So either define __KERNEL__ or patch a __NEW_USERSPACE__ define into power/asm/types.h and use it - if the PowerPC folks agree with that approach.

Sane userspace should not be prevented from using the same sane types the kernel is already using :-)

Thanks,

Ingo

maintainer
#17 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 5 lines · Ingo Molnar
Quoted 5 lines
Quoted 5 lines

That's what's happening here; we're __powerpc64__ and !__KERNEL__, tools/kvm/include/linux/types.h includes asm/types.h so gets the int-l64.h definition of __u64, as above. :/

Quoted 8 lines
Quoted 2 lines
Quoted 2 lines

builtin-run.c:389: error: format %llx' expects type long long unsigned int', but argument 2 has type `u64'

So either define __KERNEL__ or patch a __NEW_USERSPACE__ define into power/asm/types.h and use it - if the PowerPC folks agree with that approach.

Sane userspace should not be prevented from using the same sane types the kernel is already using:-)

I should dig up that patent of mine for "apparatus for conversion of circular motion to rectilinear ('wheel')".

Paolo

#18 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 13 lines · Ingo Molnar
Quoted 13 lines
Quoted 7 lines
Quoted 7 lines

That's what's happening here; we're __powerpc64__ and !__KERNEL__, tools/kvm/include/linux/types.h includes asm/types.h so gets the int-l64.h definition of __u64, as above. :/

builtin-run.c:389: error: format %llx' expects type long long unsigned int', but argument 2 has type `u64'

So either define __KERNEL__ or patch a __NEW_USERSPACE__ define into power/asm/types.h and use it - if the PowerPC folks agree with that approach.

Sane userspace should not be prevented from using the same sane types the kernel is already using:-)

Quoted 1 line · Paolo Bonzini

I should dig up that patent of mine for "apparatus for conversion of circular motion to rectilinear ('wheel')".

What's your point?

We use kernel types for obvious reasons and it trying to use <stdint.h> for the PPC port is just begging for trouble.

Pekka

#19 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

In reply to Ingo Molnar
Quoted 20 lines · Ingo Molnar
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines

[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.

In tools/kvm/ we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick up int-l64.h accidentally via the arch/powerpc/include/asm/types.h exception for user-space.

Quoted 7 lines

That's what's happening here; we're __powerpc64__ and !__KERNEL__, tools/kvm/include/linux/types.h includes asm/types.h so gets the int-l64.h definition of __u64, as above. :/

builtin-run.c:389: error: format %llx' expects type long long unsigned int', but argument 2 has type `u64'

Quoted 6 lines

So either define __KERNEL__ or patch a __NEW_USERSPACE__ define into power/asm/types.h and use it - if the PowerPC folks agree with that approach.

Sane userspace should not be prevented from using the same sane types the kernel is already using :-)

How does perf handle this? I'm sure it has the exact same issue, doesn't it?

Pekka

author
#20 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 26 lines · Pekka Enberg
Quoted 24 lines · Ingo Molnar
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines

[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.

In tools/kvm/ we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick up int-l64.h accidentally via the arch/powerpc/include/asm/types.h exception for user-space.

Quoted 7 lines

That's what's happening here; we're __powerpc64__ and !__KERNEL__, tools/kvm/include/linux/types.h includes asm/types.h so gets the int-l64.h definition of __u64, as above. :/

builtin-run.c:389: error: format %llx' expects type long long unsigned int', but argument 2 has type `u64'

So either define __KERNEL__ or patch a __NEW_USERSPACE__ define into power/asm/types.h and use it - if the PowerPC folks agree with that approach.

Quoted 5 lines
Quoted 2 lines

Sane userspace should not be prevented from using the same sane types the kernel is already using :-)

How does perf handle this? I'm sure it has the exact same issue, doesn't it?

It does; ironically it uses PRIblah, so I had followed its example.

Cheers,

Matt

#21 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 27 lines · Matt Evans
Quoted 26 lines · Pekka Enberg
Quoted 24 lines · Ingo Molnar
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines

[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.

In tools/kvm/ we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick up int-l64.h accidentally via the arch/powerpc/include/asm/types.h exception for user-space.

Quoted 7 lines

That's what's happening here; we're __powerpc64__ and !__KERNEL__, tools/kvm/include/linux/types.h includes asm/types.h so gets the int-l64.h definition of __u64, as above. :/

builtin-run.c:389: error: format %llx' expects type long long unsigned int', but argument 2 has type `u64'

So either define __KERNEL__ or patch a __NEW_USERSPACE__ define into power/asm/types.h and use it - if the PowerPC folks agree with that approach.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Sane userspace should not be prevented from using the same sane types the kernel is already using :-)

How does perf handle this? I'm sure it has the exact same issue, doesn't it?

It does; ironically it uses PRIblah, so I had followed its example.

Sadly it regressed lately in that area - it was certainly PRIblah-less in the early stages :-)

Pekka, how do the headers react if we define __KERNEL__? Alternatively, allowing an override in powerpc/types.h beyond __KERNEL__ looks sensible as well.

Thanks,

Ingo

author
#22 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 33 lines · Ingo Molnar
Quoted 30 lines · Matt Evans
Quoted 29 lines · Pekka Enberg
Quoted 26 lines · Ingo Molnar
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines

[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.

In tools/kvm/ we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick up int-l64.h accidentally via the arch/powerpc/include/asm/types.h exception for user-space.

Quoted 7 lines

That's what's happening here; we're __powerpc64__ and !__KERNEL__, tools/kvm/include/linux/types.h includes asm/types.h so gets the int-l64.h definition of __u64, as above. :/

builtin-run.c:389: error: format %llx' expects type long long unsigned int', but argument 2 has type `u64'

So either define __KERNEL__ or patch a __NEW_USERSPACE__ define into power/asm/types.h and use it - if the PowerPC folks agree with that approach.

Sane userspace should not be prevented from using the same sane types the kernel is already using :-)

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

How does perf handle this? I'm sure it has the exact same issue, doesn't it?

It does; ironically it uses PRIblah, so I had followed its example.

Sadly it regressed lately in that area - it was certainly PRIblah-less in the early stages :-)

Oh dear :-)

Quoted 3 lines

Pekka, how do the headers react if we define __KERNEL__? Alternatively, allowing an override in powerpc/types.h beyond __KERNEL__ looks sensible as well.

Well, I just tried it and it ended in tears; various things bring in tons more (ppc) stuff from asm/, quite a few conflicts.

I've resorted to defining __KERNEL__ in linux/types.h *only* around #include <asm/types.h> (i.e. undefining it afterwards). This picks up the correct int-ll64.h on PPC64 and doesn't break everything else.

Cheers,

Matt

author
#23 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 49 lines · Matt Evans
Quoted 33 lines · Ingo Molnar
Quoted 30 lines · Matt Evans
Quoted 29 lines · Pekka Enberg
Quoted 26 lines · Ingo Molnar
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines

[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.

In tools/kvm/ we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick up int-l64.h accidentally via the arch/powerpc/include/asm/types.h exception for user-space.

Quoted 7 lines

That's what's happening here; we're __powerpc64__ and !__KERNEL__, tools/kvm/include/linux/types.h includes asm/types.h so gets the int-l64.h definition of __u64, as above. :/

builtin-run.c:389: error: format %llx' expects type long long unsigned int', but argument 2 has type `u64'

So either define __KERNEL__ or patch a __NEW_USERSPACE__ define into power/asm/types.h and use it - if the PowerPC folks agree with that approach.

Sane userspace should not be prevented from using the same sane types the kernel is already using :-)

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

How does perf handle this? I'm sure it has the exact same issue, doesn't it?

It does; ironically it uses PRIblah, so I had followed its example.

Sadly it regressed lately in that area - it was certainly PRIblah-less in the early stages :-)

Oh dear :-)

Quoted 3 lines

Pekka, how do the headers react if we define __KERNEL__? Alternatively, allowing an override in powerpc/types.h beyond __KERNEL__ looks sensible as well.

Quoted 6 lines

Well, I just tried it and it ended in tears; various things bring in tons more (ppc) stuff from asm/, quite a few conflicts.

I've resorted to defining __KERNEL__ in linux/types.h *only* around #include <asm/types.h> (i.e. undefining it afterwards). This picks up the correct int-ll64.h on PPC64 and doesn't break everything else.

I spoke too soon; this screws x86 (who?), in that BITS_PER_LONG's redefined as ../../include/asm-generic/bitsperlong.h now kicks in if __KERNEL__'s defined. Defining __KERNEL__ feels a bit nasty, esp. considering these knock-on effects.

Since tools/kvm/include/linux/types.h only requires __u32, __u64 et al from <asm/types.h>, wouldn't it be most straightforward to just #include <asm-generic/int-ll64.h>? This avoids #define __KERNEL__ breaking other includes brought into userland, avoids changing system headers/distros, and includes the file we're really interested in on both x86 & PPC.

Cheers,

Matt

#24 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 7 lines · Matt Evans

Since tools/kvm/include/linux/types.h only requires __u32, __u64 et al from <asm/types.h>, wouldn't it be most straightforward to just #include <asm-generic/int-ll64.h>? This avoids #define __KERNEL__ breaking other includes brought into userland, avoids changing system headers/distros, and includes the file we're really interested in on both x86 & PPC.

No system headers need to be changed: you can just patch powerpc/types.h with the extra __SANE_USERSPACE__ define (or any suitable name) and the KVM tool should work as-is.

The beauty of tools/kvm/ being integrated into the kernel tree.

Really, if that works and if the PowerPC folks agree then we have an immediate, fully adequate, instantly applicable solution.

Thanks,

Ingo

author
#25 lore raw

Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately

Quoted 15 lines · Ingo Molnar
Quoted 7 lines · Matt Evans

Since tools/kvm/include/linux/types.h only requires __u32, __u64 et al from <asm/types.h>, wouldn't it be most straightforward to just #include <asm-generic/int-ll64.h>? This avoids #define __KERNEL__ breaking other includes brought into userland, avoids changing system headers/distros, and includes the file we're really interested in on both x86 & PPC.

No system headers need to be changed: you can just patch powerpc/types.h with the extra __SANE_USERSPACE__ define (or any suitable name) and the KVM tool should work as-is.

Quoted 5 lines

The beauty of tools/kvm/ being integrated into the kernel tree.

Really, if that works and if the PowerPC folks agree then we have an immediate, fully adequate, instantly applicable solution.

Ahh, I finally understand you-- I'd earlier thought you were referring to the system headers' asm/types.h, etc. Thanks for your patience on this very trivial point :-) I'll add __SANE_USERSPACE_TYPES__ and we'll see how the others like it. >:) (Paul, that sound OK?)

Thanks,

Matt

author
#26 lore raw

PATCH 6/28 kvm tools: Add arch-specific KVM_RUN exit handling via kvm_cpu__handle_exit()

In reply to a message not in the archive

This patch creates a new function in x86/kvm-cpu.c, kvm_cpu__handle_exit(), in which arch-specific exit reasons can be handled outside of the common runloop.

---
 tools/kvm/include/kvm/kvm-cpu.h |    2 ++
 tools/kvm/kvm-cpu.c             |   10 ++++++++--
 tools/kvm/x86/kvm-cpu.c         |    5 +++++
 3 files changed, 15 insertions(+), 2 deletions(-)
tools/kvm/include/kvm/kvm-cpu.h +2 -0
index 719e286..15618f1 100644
@@ -2,6 +2,7 @@
 #define KVM__KVM_CPU_H
 
 #include "kvm/kvm-cpu-arch.h"
+#include <stdbool.h>
 
 struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id);
 void kvm_cpu__delete(struct kvm_cpu *vcpu);
@@ -11,6 +12,7 @@ void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu);
 void kvm_cpu__run(struct kvm_cpu *vcpu);
 void kvm_cpu__reboot(void);
 int kvm_cpu__start(struct kvm_cpu *cpu);
+bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu);
 
 int kvm_cpu__get_debug_fd(void);
 void kvm_cpu__set_debug_fd(int fd);
tools/kvm/kvm-cpu.c +8 -2
index 5aba3bb..9bc0796 100644
@@ -137,8 +137,14 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
 			goto exit_kvm;
 		case KVM_EXIT_SHUTDOWN:
 			goto exit_kvm;
-		default:
-			goto panic_kvm;
+		default: {
+			bool ret;
+
+			ret = kvm_cpu__handle_exit(cpu);
+			if (!ret)
+				goto panic_kvm;
+			break;
+		}
 		}
 		kvm_cpu__handle_coalesced_mmio(cpu);
 	}
tools/kvm/x86/kvm-cpu.c +5 -0
index b26b208..a0d10cc 100644
@@ -212,6 +212,11 @@ void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
 	kvm_cpu__setup_msrs(vcpu);
 }
 
+bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
+{
+	return false;
+}
+
 static void print_dtable(const char *name, struct kvm_dtable *dtable)
 {
 	dprintf(debug_fd, " %s                 %016llx  %08hx\n",
author
#27 lore raw

PATCH 7/28 kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

In reply to a message not in the archive

Architectures can recommend/count/determine number of CPUs differently, so move this out of generic code.

---
 tools/kvm/kvm.c     |   30 ------------------------------
 tools/kvm/x86/kvm.c |   30 ++++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 30 deletions(-)
tools/kvm/kvm.c +0 -30
index 7ce1640..e526483 100644
@@ -259,17 +259,6 @@ void kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspac
 		die_perror("KVM_SET_USER_MEMORY_REGION ioctl");
 }
 
-int kvm__recommended_cpus(struct kvm *kvm)
-{
-	int ret;
-
-	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS);
-	if (ret <= 0)
-		die_perror("KVM_CAP_NR_VCPUS");
-
-	return ret;
-}
-
 static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
 {
 	pid_t pid = getpid();
@@ -282,25 +271,6 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
 		pr_warning("Failed sending PID");
 }
 
-/*
- * The following hack should be removed once 'x86: Raise the hard
- * VCPU count limit' makes it's way into the mainline.
- */
-#ifndef KVM_CAP_MAX_VCPUS
-#define KVM_CAP_MAX_VCPUS 66
-#endif
-
-int kvm__max_cpus(struct kvm *kvm)
-{
-	int ret;
-
-	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS);
-	if (ret <= 0)
-		ret = kvm__recommended_cpus(kvm);
-
-	return ret;
-}
-
 struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
 {
 	struct kvm *kvm;
tools/kvm/x86/kvm.c +30 -0
index ac6c91e..75e4a52 100644
@@ -76,6 +76,36 @@ bool kvm__arch_cpu_supports_vm(void)
 	return regs.ecx & (1 << feature);
 }
 
+int kvm__recommended_cpus(struct kvm *kvm)
+{
+	int ret;
+
+	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS);
+	if (ret <= 0)
+		die_perror("KVM_CAP_NR_VCPUS");
+
+	return ret;
+}
+
+/*
+ * The following hack should be removed once 'x86: Raise the hard
+ * VCPU count limit' makes it's way into the mainline.
+ */
+#ifndef KVM_CAP_MAX_VCPUS
+#define KVM_CAP_MAX_VCPUS 66
+#endif
+
+int kvm__max_cpus(struct kvm *kvm)
+{
+	int ret;
+
+	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS);
+	if (ret <= 0)
+		ret = kvm__recommended_cpus(kvm);
+
+	return ret;
+}
+
 /*
  * Allocating RAM size bigger than 4GB requires us to leave a gap
  * in the RAM which is used for PCI MMIO, hotplug, and unconfigured
#28 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Why is it getting moved out of generic code?

This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS are not arch specific.

Quoted 102 lines · Matt Evans

Architectures can recommend/count/determine number of CPUs differently, so move this out of generic code.

---
 tools/kvm/kvm.c     |   30 ------------------------------
 tools/kvm/x86/kvm.c |   30 ++++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 30 deletions(-)
tools/kvm/kvm.c +0 -30
index 7ce1640..e526483 100644
@@ -259,17 +259,6 @@ void kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspac
 		die_perror("KVM_SET_USER_MEMORY_REGION ioctl");
 }
 
-int kvm__recommended_cpus(struct kvm *kvm)
-{
-	int ret;
-
-	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS);
-	if (ret <= 0)
-		die_perror("KVM_CAP_NR_VCPUS");
-
-	return ret;
-}
-
 static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
 {
 	pid_t pid = getpid();
@@ -282,25 +271,6 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
 		pr_warning("Failed sending PID");
 }
 
-/*
- * The following hack should be removed once 'x86: Raise the hard
- * VCPU count limit' makes it's way into the mainline.
- */
-#ifndef KVM_CAP_MAX_VCPUS
-#define KVM_CAP_MAX_VCPUS 66
-#endif
-
-int kvm__max_cpus(struct kvm *kvm)
-{
-	int ret;
-
-	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS);
-	if (ret <= 0)
-		ret = kvm__recommended_cpus(kvm);
-
-	return ret;
-}
-
 struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
 {
 	struct kvm *kvm;
tools/kvm/x86/kvm.c +30 -1
index ac6c91e..75e4a52 100644
@@ -76,6 +76,36 @@ bool kvm__arch_cpu_supports_vm(void)
 	return regs.ecx & (1 << feature);
 }
 
+int kvm__recommended_cpus(struct kvm *kvm)
+{
+	int ret;
+
+	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS);
+	if (ret <= 0)
+		die_perror("KVM_CAP_NR_VCPUS");
+
+	return ret;
+}
+
+/*
+ * The following hack should be removed once 'x86: Raise the hard
+ * VCPU count limit' makes it's way into the mainline.
+ */
+#ifndef KVM_CAP_MAX_VCPUS
+#define KVM_CAP_MAX_VCPUS 66
+#endif
+
+int kvm__max_cpus(struct kvm *kvm)
+{
+	int ret;
+
+	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS);
+	if (ret <= 0)
+		ret = kvm__recommended_cpus(kvm);
+
+	return ret;
+}
+
 /*
  * Allocating RAM size bigger than 4GB requires us to leave a gap
  * in the RAM which is used for PCI MMIO, hotplug, and unconfigured
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Sasha.
author
#29 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 5 lines · Sasha Levin

Why is it getting moved out of generic code?

This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS are not arch specific.

I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if KVM_CAP_NR_VCPUS fails, use 4" instead of die(); you'll see that when I repost.

This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)

Thanks,

Matt

Quoted 105 lines · Matt Evans
Quoted 102 lines

Architectures can recommend/count/determine number of CPUs differently, so move this out of generic code.

---
 tools/kvm/kvm.c     |   30 ------------------------------
 tools/kvm/x86/kvm.c |   30 ++++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 30 deletions(-)
tools/kvm/kvm.c +0 -30
index 7ce1640..e526483 100644
@@ -259,17 +259,6 @@ void kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspac
 		die_perror("KVM_SET_USER_MEMORY_REGION ioctl");
 }
 
-int kvm__recommended_cpus(struct kvm *kvm)
-{
-	int ret;
-
-	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS);
-	if (ret <= 0)
-		die_perror("KVM_CAP_NR_VCPUS");
-
-	return ret;
-}
-
 static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
 {
 	pid_t pid = getpid();
@@ -282,25 +271,6 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
 		pr_warning("Failed sending PID");
 }
 
-/*
- * The following hack should be removed once 'x86: Raise the hard
- * VCPU count limit' makes it's way into the mainline.
- */
-#ifndef KVM_CAP_MAX_VCPUS
-#define KVM_CAP_MAX_VCPUS 66
-#endif
-
-int kvm__max_cpus(struct kvm *kvm)
-{
-	int ret;
-
-	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS);
-	if (ret <= 0)
-		ret = kvm__recommended_cpus(kvm);
-
-	return ret;
-}
-
 struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
 {
 	struct kvm *kvm;
tools/kvm/x86/kvm.c +30 -1
index ac6c91e..75e4a52 100644
@@ -76,6 +76,36 @@ bool kvm__arch_cpu_supports_vm(void)
 	return regs.ecx & (1 << feature);
 }
 
+int kvm__recommended_cpus(struct kvm *kvm)
+{
+	int ret;
+
+	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS);
+	if (ret <= 0)
+		die_perror("KVM_CAP_NR_VCPUS");
+
+	return ret;
+}
+
+/*
+ * The following hack should be removed once 'x86: Raise the hard
+ * VCPU count limit' makes it's way into the mainline.
+ */
+#ifndef KVM_CAP_MAX_VCPUS
+#define KVM_CAP_MAX_VCPUS 66
+#endif
+
+int kvm__max_cpus(struct kvm *kvm)
+{
+	int ret;
+
+	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS);
+	if (ret <= 0)
+		ret = kvm__recommended_cpus(kvm);
+
+	return ret;
+}
+
 /*
  * Allocating RAM size bigger than 4GB requires us to leave a gap
  * in the RAM which is used for PCI MMIO, hotplug, and unconfigured
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#30 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin

Why is it getting moved out of generic code?

This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS are not arch specific.

Quoted 7 lines

I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if KVM_CAP_NR_VCPUS fails, use 4" instead of die(); you'll see that when I repost.

This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)

I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in kvmppc_core_vcpu_create() in the book3s code:

	vcpu = kvmppc_core_vcpu_create(kvm, id);
	vcpu->arch.wqp = &vcpu->wq;
	if (!IS_ERR(vcpu))
		kvmppc_create_vcpu_debugfs(vcpu, id);

This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.

Signature · 1 line
Sasha.
author
#31 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 19 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin

Why is it getting moved out of generic code?

This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS are not arch specific.

Quoted 7 lines

I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if KVM_CAP_NR_VCPUS fails, use 4" instead of die(); you'll see that when I repost.

This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)

I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in kvmppc_core_vcpu_create() in the book3s code:

Quoted 7 lines
	vcpu = kvmppc_core_vcpu_create(kvm, id);
	vcpu->arch.wqp = &vcpu->wq;
	if (!IS_ERR(vcpu))
		kvmppc_create_vcpu_debugfs(vcpu, id);

This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.

Yeah, that's b0rk. Alex, a patch below. :)

Cheers,

Matt

---
Subject: [PATCH] KVM: PPC: Fix vcpu_create dereference before validity check.

---
 arch/powerpc/kvm/powerpc.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
arch/powerpc/kvm/powerpc.c +3 -2
index 084d1c5..7c7220c 100644
@@ -285,9 +285,10 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvm_vcpu *vcpu;
 	vcpu = kvmppc_core_vcpu_create(kvm, id);
-	vcpu->arch.wqp = &vcpu->wq;
-	if (!IS_ERR(vcpu))
+	if (!IS_ERR(vcpu)) {
+		vcpu->arch.wqp = &vcpu->wq;
 		kvmppc_create_vcpu_debugfs(vcpu, id);
+	}
 	return vcpu;
 }
 
Signature · 1 line
1.7.0.4
#32 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 25 lines · Matt Evans
Quoted 24 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin

Why is it getting moved out of generic code?

This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS are not arch specific.

Quoted 7 lines

I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if KVM_CAP_NR_VCPUS fails, use 4" instead of die(); you'll see that when I repost.

This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)

I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in kvmppc_core_vcpu_create() in the book3s code:

   vcpu = kvmppc_core_vcpu_create(kvm, id);
   vcpu->arch.wqp = &vcpu->wq;
   if (!IS_ERR(vcpu))
       kvmppc_create_vcpu_debugfs(vcpu, id);
Quoted 4 lines
Quoted 2 lines

This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.

Yeah, that's b0rk. Alex, a patch below. :)

Thanks :). Will apply asap but don't have a real keyboard today :).

I suppose this is stable material?

Alex

Quoted 1 line
author
#33 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 28 lines · Alexander Graf
Quoted 25 lines · Matt Evans
Quoted 24 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin

Why is it getting moved out of generic code?

This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS are not arch specific.

Quoted 7 lines

I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if KVM_CAP_NR_VCPUS fails, use 4" instead of die(); you'll see that when I repost.

This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)

I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in kvmppc_core_vcpu_create() in the book3s code:

   vcpu = kvmppc_core_vcpu_create(kvm, id);
   vcpu->arch.wqp = &vcpu->wq;
   if (!IS_ERR(vcpu))
       kvmppc_create_vcpu_debugfs(vcpu, id);
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.

Yeah, that's b0rk. Alex, a patch below. :)

Thanks :). Will apply asap but don't have a real keyboard today :).

Ha! Voice control on your phone, what could go wrong?

Quoted 1 line

I suppose this is stable material?

Good idea, (and if we're formal,

). I suppose no one's seen a vcpu fail to be created, yet.

Thanks,

Matt

#34 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 36 lines · Matt Evans
Quoted 28 lines · Alexander Graf
Quoted 25 lines · Matt Evans
Quoted 24 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin

Why is it getting moved out of generic code?

This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS are not arch specific.

Quoted 7 lines

I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if KVM_CAP_NR_VCPUS fails, use 4" instead of die(); you'll see that when I repost.

This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)

I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in kvmppc_core_vcpu_create() in the book3s code:

   vcpu = kvmppc_core_vcpu_create(kvm, id);
   vcpu->arch.wqp = &vcpu->wq;
   if (!IS_ERR(vcpu))
       kvmppc_create_vcpu_debugfs(vcpu, id);
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.

Yeah, that's b0rk. Alex, a patch below. :)

Thanks :). Will apply asap but don't have a real keyboard today :).

Quoted 7 lines

Ha! Voice control on your phone, what could go wrong?

Quoted 1 line

I suppose this is stable material?

Good idea, (and if we're formal,

). I suppose no one's seen a vcpu fail to be created, yet.

I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?

---

From: Sasha Levin <[email protected]>
Date: Wed, 7 Dec 2011 10:24:56 +0200
Subject: [PATCH] KVM: PPC: Use the vcpu kmem_cache when allocating new VCPUs

Currently the code kzalloc()s new VCPUs instead of using the kmem_cache which is created when KVM is initialized.

Modify it to allocate VCPUs from that kmem_cache.

---
 arch/powerpc/kvm/book3s_hv.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
arch/powerpc/kvm/book3s_hv.c +3 -3
index 0cb137a..e309099 100644
@@ -411,7 +411,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 		goto out;
 
 	err = -ENOMEM;
-	vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
+	vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
 	if (!vcpu)
 		goto out;
 
@@ -463,7 +463,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 	return vcpu;
 
 free_vcpu:
-	kfree(vcpu);
+	kmem_cache_free(kvm_vcpu_cache, vcpu);
 out:
 	return ERR_PTR(err);
 }
@@ -471,7 +471,7 @@ out:
 void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
 {
 	kvm_vcpu_uninit(vcpu);
-	kfree(vcpu);
+	kmem_cache_free(kvm_vcpu_cache, vcpu);
 }
 
 static void kvmppc_set_timer(struct kvm_vcpu *vcpu)
Signature · 1 line
Sasha.
#35 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 4 lines · Sasha Levin

I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?

qemu offers free ppc shells

Signature · 1 line
error compiling committee.c: too many arguments to function
#36 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 7 lines · Avi Kivity
Quoted 4 lines · Sasha Levin

I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?

qemu offers free ppc shells

qemu would let me nest a guest inside a ppc guest on my x86?

Signature · 1 line
Sasha.
#37 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 10 lines · Sasha Levin
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Sasha Levin

I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?

qemu offers free ppc shells

qemu would let me nest a guest inside a ppc guest on my x86?

On supervisor mode only (trap-and-emulate virtualization); I don't think qemu emulates ppc hypervisor mode.

Signature · 1 line
error compiling committee.c: too many arguments to function
#38 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 8 lines · Avi Kivity
Quoted 7 lines · Sasha Levin
Quoted 6 lines · Avi Kivity
Quoted 4 lines · Sasha Levin

I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

qemu offers free ppc shells

qemu would let me nest a guest inside a ppc guest on my x86?

On supervisor mode only (trap-and-emulate virtualization); I don't think qemu emulates ppc hypervisor mode.

Yup, that should work for PR KVM. I'm not sure Matt's patches work in that mode though.

So you should be able to run qemu-system-ppc64 -M pseries -nographic to emulate a ppc box and then do the same in the guest with -enable-kvm.

If that works, you can try with kvm tool in the first guest :).

Alex

Quoted 1 line
#39 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 14 lines · Alexander Graf
Quoted 12 lines · Avi Kivity
Quoted 10 lines · Sasha Levin
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Sasha Levin

I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?

qemu offers free ppc shells

qemu would let me nest a guest inside a ppc guest on my x86?

Quoted 8 lines
Quoted 2 lines

On supervisor mode only (trap-and-emulate virtualization); I don't think qemu emulates ppc hypervisor mode.

Yup, that should work for PR KVM. I'm not sure Matt's patches work in that mode though.

So you should be able to run qemu-system-ppc64 -M pseries -nographic to emulate a ppc box and then do the same in the guest with -enable-kvm.

If that works, you can try with kvm tool in the first guest :).

Tried that, got the following (qemu-kvm-1.0 on qemu-kvm.git):

LINK ppc64-softmmu/qemu-system-ppc64
../libhw64/i8259.o: In function `kvm_i8259_set_irq':
/root/work/src/qemu-kvm/hw/i8259.c:707: undefined reference to apic_set_irq_delivered' ../libhw64/i8259.o: In function pic_read_irq':
/root/work/src/qemu-kvm/hw/i8259.c:240: undefined reference to timer_acks' /root/work/src/qemu-kvm/hw/i8259.c:241: undefined reference to timer_ints_to_push'
collect2: ld returned 1 exit status
make[1]: *** [qemu-system-ppc64] Error 1
make: *** [subdir-ppc64-softmmu] Error 2

What am I doing wrong?

Signature · 1 line
Sasha.
#40 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 36 lines · Sasha Levin
Quoted 14 lines · Alexander Graf
Quoted 12 lines · Avi Kivity
Quoted 10 lines · Sasha Levin
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Sasha Levin

I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?

qemu offers free ppc shells

qemu would let me nest a guest inside a ppc guest on my x86?

Quoted 8 lines
Quoted 2 lines

On supervisor mode only (trap-and-emulate virtualization); I don't think qemu emulates ppc hypervisor mode.

Yup, that should work for PR KVM. I'm not sure Matt's patches work in that mode though.

So you should be able to run qemu-system-ppc64 -M pseries -nographic to emulate a ppc box and then do the same in the guest with -enable-kvm.

If that works, you can try with kvm tool in the first guest :).

Tried that, got the following (qemu-kvm-1.0 on qemu-kvm.git):

LINK ppc64-softmmu/qemu-system-ppc64
../libhw64/i8259.o: In function `kvm_i8259_set_irq':
/root/work/src/qemu-kvm/hw/i8259.c:707: undefined reference to apic_set_irq_delivered' ../libhw64/i8259.o: In function pic_read_irq':
/root/work/src/qemu-kvm/hw/i8259.c:240: undefined reference to timer_acks' /root/work/src/qemu-kvm/hw/i8259.c:241: undefined reference to timer_ints_to_push'
collect2: ld returned 1 exit status
make[1]: *** [qemu-system-ppc64] Error 1
make: *** [subdir-ppc64-softmmu] Error 2

Quoted 1 line

What am I doing wrong?

You're probably using the wrong tree :). The qemu-kvm fork used to work a while back, but I don't autotest it. Try again with

git://git.qemu.org/qemu.git

and make sure to have libfdt installed :)

Alex

Quoted 1 line
#41 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

In reply to Sasha Levin
Quoted 41 lines · Sasha Levin
Quoted 40 lines · Matt Evans
Quoted 28 lines · Alexander Graf
Quoted 25 lines · Matt Evans
Quoted 24 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin

Why is it getting moved out of generic code?

This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS are not arch specific.

Quoted 7 lines

I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if KVM_CAP_NR_VCPUS fails, use 4" instead of die(); you'll see that when I repost.

This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)

I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in kvmppc_core_vcpu_create() in the book3s code:

  vcpu = kvmppc_core_vcpu_create(kvm, id);
  vcpu->arch.wqp = &vcpu->wq;
  if (!IS_ERR(vcpu))
      kvmppc_create_vcpu_debugfs(vcpu, id);
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.

Yeah, that's b0rk. Alex, a patch below. :)

Thanks :). Will apply asap but don't have a real keyboard today :).

Ha! Voice control on your phone, what could go wrong?

Quoted 1 line

I suppose this is stable material?

Quoted 7 lines
Quoted 3 lines

Good idea, (and if we're formal,

). I suppose no one's seen a vcpu fail to be created, yet.

I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?

The problem with giving you a shell on a PPC box is really that the hardware Matt's work is focusing on is not available to the public yet. I could maybe try and get you access on a G5 box, but I'm not sure how useful that is to you really, as you'll only be able to run PR KVM, not HV KVM.

Quoted 22 lines

---

From: Sasha Levin <[email protected]>
Date: Wed, 7 Dec 2011 10:24:56 +0200
Subject: [PATCH] KVM: PPC: Use the vcpu kmem_cache when allocating new VCPUs

Currently the code kzalloc()s new VCPUs instead of using the kmem_cache which is created when KVM is initialized.

Modify it to allocate VCPUs from that kmem_cache.

---
arch/powerpc/kvm/book3s_hv.c | 6 +++---

1 files changed, 3 insertions(+), 3 deletions(-)
arch/powerpc/kvm/book3s_hv.c +0 -0
index 0cb137a..e309099 100644

arch/powerpc/kvm/book3s_hv.c struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) · line 414

Quoted 5 lines
arch/powerpc/kvm/book3s_hv.c +1 -1
@@ -411,7 +411,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 		goto out;
 
 	err = -ENOMEM;
-	vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
+	vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);

Paul, is there any rationale on why not to use the kmem cache? Are we bound by real mode magic again?

Alex

Quoted 30 lines
arch/powerpc/kvm/book3s_hv.c +0 -0
 	if (!vcpu)
 		goto out;
 
@@ -463,7 +463,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 	return vcpu;
 

free_vcpu:

arch/powerpc/kvm/book3s_hv.c +1 -1
-	kfree(vcpu);
+	kmem_cache_free(kvm_vcpu_cache, vcpu);

out:

	return ERR_PTR(err);
}
arch/powerpc/kvm/book3s_hv.c +1 -1
@@ -471,7 +471,7 @@ out:
 void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
 {
 	kvm_vcpu_uninit(vcpu);
-	kfree(vcpu);
+	kmem_cache_free(kvm_vcpu_cache, vcpu);
 }
 
 static void kvmppc_set_timer(struct kvm_vcpu *vcpu)
Signature · 8 lines
-- 

Sasha.

--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#42 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 5 lines · Alexander Graf

arch/powerpc/kvm/book3s_hv.c struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) · line 414

Quoted 2 lines
arch/powerpc/kvm/book3s_hv.c +1 -1
-	vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
+	vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);

Paul, is there any rationale on why not to use the kmem cache? Are we bound by real mode magic again?

No, I just hadn't realized it existed. This looks fine to me.

Paul.

#43 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

Quoted 11 lines · Paul Mackerras
Quoted 5 lines · Alexander Graf

arch/powerpc/kvm/book3s_hv.c struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) · line 414

Quoted 2 lines
arch/powerpc/kvm/book3s_hv.c +1 -1
-	vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
+	vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);

Paul, is there any rationale on why not to use the kmem cache? Are we bound by real mode magic again?

No, I just hadn't realized it existed. This looks fine to me.

Thanks, applied to kvm-ppc-next.

Alex

#44 lore raw

Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code

In reply to Matt Evans
Quoted 34 lines · Matt Evans
Quoted 19 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin

Why is it getting moved out of generic code?

This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS are not arch specific.

Quoted 7 lines

I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if KVM_CAP_NR_VCPUS fails, use 4" instead of die(); you'll see that when I repost.

This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)

I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in kvmppc_core_vcpu_create() in the book3s code:

Quoted 7 lines
	vcpu = kvmppc_core_vcpu_create(kvm, id);
	vcpu->arch.wqp = &vcpu->wq;
	if (!IS_ERR(vcpu))
		kvmppc_create_vcpu_debugfs(vcpu, id);

This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.

Yeah, that's b0rk. Alex, a patch below. :)

Cheers,

Quoted 7 lines

Matt

---
Subject: [PATCH] KVM: PPC: Fix vcpu_create dereference before validity check.

Thanks, applied to kvm-ppc-next with an actual patch description added.

Alex

Quoted 24 lines

---
arch/powerpc/kvm/powerpc.c | 5 +++--

1 files changed, 3 insertions(+), 2 deletions(-)
arch/powerpc/kvm/powerpc.c +3 -2
index 084d1c5..7c7220c 100644
@@ -285,9 +285,10 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvm_vcpu *vcpu;
 	vcpu = kvmppc_core_vcpu_create(kvm, id);
-	vcpu->arch.wqp = &vcpu->wq;
-	if (!IS_ERR(vcpu))
+	if (!IS_ERR(vcpu)) {
+		vcpu->arch.wqp = &vcpu->wq;
 		kvmppc_create_vcpu_debugfs(vcpu, id);
+	}
 	return vcpu;
 }
 
Signature · 1 line
1.7.0.4
author
#45 lore raw

PATCH 8/28 kvm tools: Fix KVM_RUN exit code check

In reply to a message not in the archive

kvm_cpu__run() currently die()s if KVM_RUN returns non-zero. Some architectures may return positive values in non-error cases, whereas real errors are always negative return values. Check for those instead.

---
 tools/kvm/kvm-cpu.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
tools/kvm/kvm-cpu.c +1 -1
index 9bc0796..884a89f 100644
@@ -30,7 +30,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu)
 	int err;
 
 	err = ioctl(vcpu->vcpu_fd, KVM_RUN, 0);
-	if (err && (errno != EINTR && errno != EAGAIN))
+	if (err < 0 && (errno != EINTR && errno != EAGAIN))
 		die_perror("KVM_RUN failed");
 }
 
#46 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

If KVM_RUN can actually return anything besides 0 or -1 it may be also worthwhile to update Documentation/virtual/kvm/api.txt .

What are the cases where it happens?

Quoted 26 lines · Matt Evans

kvm_cpu__run() currently die()s if KVM_RUN returns non-zero. Some architectures may return positive values in non-error cases, whereas real errors are always negative return values. Check for those instead.

---
 tools/kvm/kvm-cpu.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
tools/kvm/kvm-cpu.c +1 -2
index 9bc0796..884a89f 100644
@@ -30,7 +30,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu)
 	int err;
 
 	err = ioctl(vcpu->vcpu_fd, KVM_RUN, 0);
-	if (err && (errno != EINTR && errno != EAGAIN))
+	if (err < 0 && (errno != EINTR && errno != EAGAIN))
 		die_perror("KVM_RUN failed");
 }
 
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Sasha.
author
#47 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

Quoted 4 lines · Sasha Levin

If KVM_RUN can actually return anything besides 0 or -1 it may be also worthwhile to update Documentation/virtual/kvm/api.txt .

What are the cases where it happens?

Well, on PPC the internal kvmppc_run_vcpu() returns either RESUME_GUEST (which stays in-kernel and drops back to the guest) or RESUME_HOST, which is propagated back out to userland as the return value of ioctl(KVM_RUN). So, anything kvmtool sees is either <0 for error or RESUME_HOST, i.e. 2.

Alex, do you think the PPC KVM code should be forced to 0 on success, or is there any value to the expanded the return codes (and updating api.txt) for varying kinds of positive success?

Cheers,

Matt

Quoted 29 lines · Matt Evans
Quoted 26 lines

kvm_cpu__run() currently die()s if KVM_RUN returns non-zero. Some architectures may return positive values in non-error cases, whereas real errors are always negative return values. Check for those instead.

---
 tools/kvm/kvm-cpu.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
tools/kvm/kvm-cpu.c +1 -2
index 9bc0796..884a89f 100644
@@ -30,7 +30,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu)
 	int err;
 
 	err = ioctl(vcpu->vcpu_fd, KVM_RUN, 0);
-	if (err && (errno != EINTR && errno != EAGAIN))
+	if (err < 0 && (errno != EINTR && errno != EAGAIN))
 		die_perror("KVM_RUN failed");
 }
 
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#48 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

Quoted 6 lines · Matt Evans
Quoted 4 lines · Sasha Levin

If KVM_RUN can actually return anything besides 0 or -1 it may be also worthwhile to update Documentation/virtual/kvm/api.txt .

What are the cases where it happens?

Quoted 8 lines

Well, on PPC the internal kvmppc_run_vcpu() returns either RESUME_GUEST (which stays in-kernel and drops back to the guest) or RESUME_HOST, which is propagated back out to userland as the return value of ioctl(KVM_RUN). So, anything kvmtool sees is either <0 for error or RESUME_HOST, i.e. 2.

Alex, do you think the PPC KVM code should be forced to 0 on success, or is there any value to the expanded the return codes (and updating api.txt) for varying kinds of positive success?

I don't think it's worth the potential ABI breakage to change the current behavior :). Even if we did change it, you would still have to touch kvm tool to work with older kernels.

Alex

Quoted 1 line
#49 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

Quoted 13 lines · Alexander Graf
Quoted 11 lines · Matt Evans
Quoted 4 lines · Sasha Levin

If KVM_RUN can actually return anything besides 0 or -1 it may be also worthwhile to update Documentation/virtual/kvm/api.txt .

What are the cases where it happens?

Well, on PPC the internal kvmppc_run_vcpu() returns either RESUME_GUEST (which stays in-kernel and drops back to the guest) or RESUME_HOST, which is propagated back out to userland as the return value of ioctl(KVM_RUN). So, anything kvmtool sees is either <0 for error or RESUME_HOST, i.e. 2.

Quoted 5 lines
Quoted 3 lines

Alex, do you think the PPC KVM code should be forced to 0 on success, or is there any value to the expanded the return codes (and updating api.txt) for varying kinds of positive success?

I don't think it's worth the potential ABI breakage to change the current behavior :). Even if we did change it, you would still have to touch kvm tool to work with older kernels.

Well it deviates from api.txt, so please fix one or the other.

Signature · 1 line
error compiling committee.c: too many arguments to function
#50 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

Quoted 14 lines · Avi Kivity
Quoted 13 lines · Alexander Graf
Quoted 11 lines · Matt Evans
Quoted 4 lines · Sasha Levin

If KVM_RUN can actually return anything besides 0 or -1 it may be also worthwhile to update Documentation/virtual/kvm/api.txt .

What are the cases where it happens?

Well, on PPC the internal kvmppc_run_vcpu() returns either RESUME_GUEST (which stays in-kernel and drops back to the guest) or RESUME_HOST, which is propagated back out to userland as the return value of ioctl(KVM_RUN). So, anything kvmtool sees is either <0 for error or RESUME_HOST, i.e. 2.

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

Alex, do you think the PPC KVM code should be forced to 0 on success, or is there any value to the expanded the return codes (and updating api.txt) for varying kinds of positive success?

I don't think it's worth the potential ABI breakage to change the current behavior :). Even if we did change it, you would still have to touch kvm tool to work with older kernels.

Well it deviates from api.txt, so please fix one or the other.

Hrm - let me check all users. Maybe we can change the return argument. Will do when I'm back on a keyboard ;).

Alex

Quoted 1 line
#51 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

Quoted 1 line · Alexander Graf

Will do when I'm back on a keyboard ;).

Siri, write a patch for bugzilla #123456 and post it upstream.

Signature · 1 line
error compiling committee.c: too many arguments to function
author
#52 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

In reply to Sasha Levin

Hi Sasha,

Quoted 4 lines · Sasha Levin

If KVM_RUN can actually return anything besides 0 or -1 it may be also worthwhile to update Documentation/virtual/kvm/api.txt .

What are the cases where it happens?

It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's KVM_RUN return val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )

Cheers,

Matt

Quoted 29 lines · Matt Evans
Quoted 26 lines

kvm_cpu__run() currently die()s if KVM_RUN returns non-zero. Some architectures may return positive values in non-error cases, whereas real errors are always negative return values. Check for those instead.

---
 tools/kvm/kvm-cpu.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
tools/kvm/kvm-cpu.c +1 -2
index 9bc0796..884a89f 100644
@@ -30,7 +30,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu)
 	int err;
 
 	err = ioctl(vcpu->vcpu_fd, KVM_RUN, 0);
-	if (err && (errno != EINTR && errno != EAGAIN))
+	if (err < 0 && (errno != EINTR && errno != EAGAIN))
 		die_perror("KVM_RUN failed");
 }
 
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#53 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

Quoted 6 lines · Matt Evans

Hi Sasha,

Quoted 3 lines · Sasha Levin

If KVM_RUN can actually return anything besides 0 or -1 it may be also worthwhile to update Documentation/virtual/kvm/api.txt .

Quoted 7 lines
Quoted 1 line

What are the cases where it happens?

It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's KVM_RUN return val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )

'<0' is fine as it's what api.txt says :)

Signature · 1 line
Sasha.
#54 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

Quoted 8 lines · Sasha Levin
Quoted 6 lines

It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's KVM_RUN return val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )

'<0' is fine as it's what api.txt says :)

What? ioctls return -1 on error, not <0.

The syscalls do return <0, but libc converts that to -1/errno.

Signature · 1 line
error compiling committee.c: too many arguments to function
#55 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

Quoted 11 lines · Avi Kivity
Quoted 8 lines · Sasha Levin
Quoted 6 lines

It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's KVM_RUN return val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )

'<0' is fine as it's what api.txt says :)

What? ioctls return -1 on error, not <0.

<0 as opposed to the !=0 check we had there before.

Theres no harm in checking for <0 even if the only possible negative result is -1.

Quoted 3 lines

The syscalls do return <0, but libc converts that to -1/errno.

Signature · 1 line
Sasha.
#56 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

Quoted 9 lines · Sasha Levin
Quoted 8 lines · Avi Kivity
Quoted 7 lines · Sasha Levin
Quoted 6 lines

It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's KVM_RUN return val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )

Quoted 10 lines
Quoted 3 lines
Quoted 1 line

'<0' is fine as it's what api.txt says :)

What? ioctls return -1 on error, not <0.

<0 as opposed to the !=0 check we had there before.

Theres no harm in checking for <0 even if the only possible negative result is -1.

Yes, but the documentation should say -1. Which ioctl is this?

Signature · 1 line
error compiling committee.c: too many arguments to function
#57 lore raw

Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check

Quoted 14 lines · Avi Kivity
Quoted 13 lines · Sasha Levin
Quoted 11 lines · Avi Kivity
Quoted 8 lines · Sasha Levin
Quoted 6 lines

It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's KVM_RUN return val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )

'<0' is fine as it's what api.txt says :)

What? ioctls return -1 on error, not <0.

Quoted 8 lines
Quoted 6 lines

<0 as opposed to the !=0 check we had there before.

Theres no harm in checking for <0 even if the only possible negative result is -1.

Yes, but the documentation should say -1. Which ioctl is this?

That was KVM_RUN, but the documentation on that is correct (-1), so I'm not sure what I was thinking.

On the other hand, there are several ioctls that do need fixing:

- KVM_IOEVENTFD
- KVM_PPC_GET_PVINFO
- KVM_CAP_GET_TSC_KHZ

Signature · 1 line
Sasha.
author
#58 lore raw

PATCH 9/28 kvm tools: Add kvm__arch_periodic_poll()

In reply to a message not in the archive

Currently, the SIGALRM handler calls device poll functions (for serial, virtio console) directly. Which devices are present and which require polling is a system-specific decision, so create a new function called from common code & move the x86-specific poll calls into it.

---
 tools/kvm/builtin-run.c     |    3 +--
 tools/kvm/include/kvm/kvm.h |    1 +
 tools/kvm/x86/kvm.c         |    8 ++++++++
 3 files changed, 10 insertions(+), 2 deletions(-)
tools/kvm/builtin-run.c +1 -2
index 7cf208d..9ef331e 100644
@@ -522,8 +522,7 @@ static void handle_debug(int fd, u32 type, u32 len, u8 *msg)
 
 static void handle_sigalrm(int sig)
 {
-	serial8250__inject_interrupt(kvm);
-	virtio_console__inject_interrupt(kvm);
+	kvm__arch_periodic_poll(kvm);
 }
 
 static void handle_stop(int fd, u32 type, u32 len, u8 *msg)
tools/kvm/include/kvm/kvm.h +1 -0
index ca1acc0..60842d5 100644
@@ -56,6 +56,7 @@ void kvm__remove_socket(const char *name);
 void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name);
 void kvm__arch_setup_firmware(struct kvm *kvm);
 bool kvm__arch_cpu_supports_vm(void);
+void kvm__arch_periodic_poll(struct kvm *kvm);
 
 int load_flat_binary(struct kvm *kvm, int fd);
 bool load_bzimage(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline, u16 vidmode);
tools/kvm/x86/kvm.c +8 -0
index 75e4a52..45dcb77 100644
@@ -4,6 +4,8 @@
 #include "kvm/interrupt.h"
 #include "kvm/mptable.h"
 #include "kvm/util.h"
+#include "kvm/8250-serial.h"
+#include "kvm/virtio-console.h"
 
 #include <asm/bootparam.h>
 #include <linux/kvm.h>
@@ -358,3 +360,9 @@ void kvm__arch_setup_firmware(struct kvm *kvm)
 	/* MP table */
 	mptable_setup(kvm, kvm->nrcpus);
 }
+
+void kvm__arch_periodic_poll(struct kvm *kvm)
+{
+	serial8250__inject_interrupt(kvm);
+	virtio_console__inject_interrupt(kvm);
+}
author
#59 lore raw

PATCH 10/28 kvm tools: term.h needs to include stdbool.h

In reply to a message not in the archive

Fix a missing include.

---
 tools/kvm/include/kvm/term.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
tools/kvm/include/kvm/term.h +1 -0
index 37ec731..938c26f 100644
@@ -2,6 +2,7 @@
 #define KVM__TERM_H
 
 #include <sys/uio.h>
+#include <stdbool.h>
 
 #define CONSOLE_8250	1
 #define CONSOLE_VIRTIO	2
author
#60 lore raw

PATCH 11/28 kvm tools: kvm.c needs to include sys/stat.h for mkdir

In reply to a message not in the archive

Fix a missing include.

---
 tools/kvm/kvm.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
tools/kvm/kvm.c +1 -0
index e526483..33243f1 100644
@@ -8,6 +8,7 @@
 #include <linux/kvm.h>
 
 #include <sys/un.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
author
#61 lore raw

PATCH 12/28 kvm tools: Move arch-specific cmdline init into kvm__arch_set_cmdline()

In reply to a message not in the archive

Different systems will want different base kernel commandlines, e.g. non-x86 systems probably don't need noapic, i8042.* etc., so set the commandline up in arch-specific code. Then, if the resulting commandline is empty, don't strcat a space onto the front.

---
 tools/kvm/builtin-run.c     |   12 +++++-------
 tools/kvm/include/kvm/kvm.h |    1 +
 tools/kvm/x86/kvm.c         |   11 +++++++++++
 3 files changed, 17 insertions(+), 7 deletions(-)
tools/kvm/builtin-run.c +5 -7
index 9ef331e..a67bd8c 100644
@@ -835,13 +835,11 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		vidmode = 0;
 
 	memset(real_cmdline, 0, sizeof(real_cmdline));
-	strcpy(real_cmdline, "noapic noacpi pci=conf1 reboot=k panic=1 i8042.direct=1 "
-				"i8042.dumbkbd=1 i8042.nopnp=1");
-	if (vnc || sdl) {
-		strcat(real_cmdline, " video=vesafb console=tty0");
-	} else
-		strcat(real_cmdline, " console=ttyS0 earlyprintk=serial i8042.noaux=1");
-	strcat(real_cmdline, " ");
+	kvm__arch_set_cmdline(real_cmdline, vnc || sdl);
+
+	if (strlen(real_cmdline) > 0)
+		strcat(real_cmdline, " ");
+
 	if (kernel_cmdline)
 		strlcat(real_cmdline, kernel_cmdline, sizeof(real_cmdline));
 
tools/kvm/include/kvm/kvm.h +1 -0
index 60842d5..fae2ba9 100644
@@ -53,6 +53,7 @@ int kvm__get_sock_by_instance(const char *name);
 int kvm__enumerate_instances(int (*callback)(const char *name, int pid));
 void kvm__remove_socket(const char *name);
 
+void kvm__arch_set_cmdline(char *cmdline, bool video);
 void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name);
 void kvm__arch_setup_firmware(struct kvm *kvm);
 bool kvm__arch_cpu_supports_vm(void);
tools/kvm/x86/kvm.c +11 -0
index 45dcb77..7071dc6 100644
@@ -149,6 +149,17 @@ void kvm__init_ram(struct kvm *kvm)
 	}
 }
 
+/* Arch-specific commandline setup */
+void kvm__arch_set_cmdline(char *cmdline, bool video)
+{
+	strcpy(cmdline, "noapic noacpi pci=conf1 reboot=k panic=1 i8042.direct=1 "
+				"i8042.dumbkbd=1 i8042.nopnp=1");
+	if (video) {
+		strcat(cmdline, " video=vesafb console=tty0");
+	} else
+		strcat(cmdline, " console=ttyS0 earlyprintk=serial i8042.noaux=1");
+}
+
 /* Architecture-specific KVM init */
 void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name)
 {
author
#62 lore raw

PATCH 13/28 kvm tools: Add CONSOLE_HV term type and allow it to be selected

In reply to a message not in the archive

This patch paves the way for adding a hypervisor console, useful on systems that support one out of the box yet don't have either serial port or virtio console support (e.g. kernels expecting POWER SPAPR).

---
 tools/kvm/builtin-run.c      |    8 ++++++--
 tools/kvm/include/kvm/term.h |    1 +
 2 files changed, 7 insertions(+), 2 deletions(-)
tools/kvm/builtin-run.c +6 -2
index a67bd8c..1257c90 100644
@@ -416,7 +416,7 @@ static const struct option options[] = {
 	OPT_BOOLEAN('\0', "rng", &virtio_rng, "Enable virtio Random Number Generator"),
 	OPT_CALLBACK('\0', "9p", NULL, "dir_to_share,tag_name",
 		     "Enable virtio 9p to share files between host and guest", virtio_9p_rootdir_parser),
-	OPT_STRING('\0', "console", &console, "serial or virtio",
+	OPT_STRING('\0', "console", &console, "serial, virtio or hv",
 			"Console to use"),
 	OPT_STRING('\0', "dev", &dev, "device_file", "KVM device file"),
 	OPT_CALLBACK('\0', "tty", NULL, "tty id",
@@ -776,8 +776,12 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	if (!strncmp(console, "virtio", 6))
 		active_console  = CONSOLE_VIRTIO;
-	else
+	else if (!strncmp(console, "serial", 6))
 		active_console  = CONSOLE_8250;
+	else if (!strncmp(console, "hv", 2))
+		active_console = CONSOLE_HV;
+	else
+		pr_warning("No console!");
 
 	if (!host_ip)
 		host_ip = DEFAULT_HOST_ADDR;
tools/kvm/include/kvm/term.h +1 -0
index 938c26f..a6a9822 100644
@@ -6,6 +6,7 @@
 
 #define CONSOLE_8250	1
 #define CONSOLE_VIRTIO	2
+#define CONSOLE_HV	3
 
 int term_putc_iov(int who, struct iovec *iov, int iovcnt, int term);
 int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term);
author
#63 lore raw

PATCH 14/28 kvm tools: Fix term_getc(), term_getc_iov() endian bugs

In reply to a message not in the archive

term_getc()'s int c has one byte written into it (at its lowest address) by read_in_full(). This is expected to be the least significant byte, but that isn't the case on BE! Use correct type, unsigned char. A similar issue exists in term_getc_iov(), which needs to write a char to the iov rather than an int.

---
 tools/kvm/term.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)
tools/kvm/term.c +2 -3
index fb5d71c..440884e 100644
@@ -30,11 +30,10 @@ int term_fds[4][2];
 
 int term_getc(int who, int term)
 {
-	int c;
+	unsigned char c;
 
 	if (who != active_console)
 		return -1;
-
 	if (read_in_full(term_fds[term][TERM_FD_IN], &c, 1) < 0)
 		return -1;
 
@@ -84,7 +83,7 @@ int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term)
 	if (c < 0)
 		return 0;
 
-	*((int *)iov[TERM_FD_IN].iov_base)	= c;
+	*((char *)iov[TERM_FD_IN].iov_base)	= (char)c;
 
 	return sizeof(char);
 }
#64 lore raw

Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs

Quoted 28 lines · Matt Evans

term_getc()'s int c has one byte written into it (at its lowest address) by read_in_full().  This is expected to be the least significant byte, but that isn't the case on BE!  Use correct type, unsigned char.  A similar issue exists in term_getc_iov(), which needs to write a char to the iov rather than an int.

---
 tools/kvm/term.c |    5 ++---

 1 files changed, 2 insertions(+), 3 deletions(-)
tools/kvm/term.c +1 -2
index fb5d71c..440884e 100644
@@ -30,11 +30,10 @@ int term_fds[4][2];
 
  int term_getc(int who, int term)
  {
-       int c;
+       unsigned char c;
 
        if (who != active_console)
                return -1;
-
        if (read_in_full(term_fds[term][TERM_FD_IN], &c, 1) < 0)
                return -1;
 

tools/kvm/term.c int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term) · line 89

Quoted 8 lines
tools/kvm/term.c +1 -1
@@ -84,7 +83,7 @@ int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term)
        if (c < 0)
                return 0;
 
-       *((int *)iov[TERM_FD_IN].iov_base)      = c;
+       *((char *)iov[TERM_FD_IN].iov_base)     = (char)c;
 
        return sizeof(char);
  }

Looks OK to me. Asias?

#65 lore raw

Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs

Quoted 17 lines · Pekka Enberg
Quoted 16 lines · Matt Evans

term_getc()'s int c has one byte written into it (at its lowest address) by read_in_full(). This is expected to be the least significant byte, but that isn't the case on BE! Use correct type, unsigned char. A similar issue exists in term_getc_iov(), which needs to write a char to the iov rather than an int.

---
 tools/kvm/term.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)
tools/kvm/term.c +0 -0
index fb5d71c..440884e 100644
@@ -30,11 +30,10 @@ int term_fds[4][2];
 
Quoted 8 lines

tools/kvm/term.c int term_fds[4][2]; · line 37

Quoted 8 lines
tools/kvm/term.c +1 -2
 int term_getc(int who, int term)
 {
-       int c;
+       unsigned char c;
 
       if (who != active_console)
               return -1;
-

We can drop this line too.

	c &= 0xff;
Quoted 7 lines
Quoted 7 lines
tools/kvm/term.c +0 -0
       if (read_in_full(term_fds[term][TERM_FD_IN], &c, 1) < 0)
               return -1;
 
@@ -84,7 +83,7 @@ int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term)
       if (c < 0)
               return 0;
 
Quoted 8 lines

tools/kvm/term.c int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term) · line 89

Quoted 5 lines
tools/kvm/term.c +1 -1
-       *((int *)iov[TERM_FD_IN].iov_base)      = c;
+       *((char *)iov[TERM_FD_IN].iov_base)     = (char)c;
 
       return sizeof(char);
 }

Looks OK to me. Asias?

Otherwise, looks fine to me.

Signature · 1 line
Asias He
author
#66 lore raw

Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs

Hi Asias,

Quoted 23 lines · Asias He
Quoted 22 lines · Pekka Enberg
Quoted 21 lines · Matt Evans

term_getc()'s int c has one byte written into it (at its lowest address) by read_in_full(). This is expected to be the least significant byte, but that isn't the case on BE! Use correct type, unsigned char. A similar issue exists in term_getc_iov(), which needs to write a char to the iov rather than an int.

---
 tools/kvm/term.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)
tools/kvm/term.c +1 -1
index fb5d71c..440884e 100644
@@ -30,11 +30,10 @@ int term_fds[4][2];
 
 int term_getc(int who, int term)
 {
-       int c;
+       unsigned char c;
 
Quoted 7 lines
Quoted 3 lines

tools/kvm/term.c int term_fds[4][2]; · line 37

Quoted 3 lines
tools/kvm/term.c +0 -1
       if (who != active_console)
               return -1;
-

We can drop this line too.

	c &= 0xff;

D'oh! Of course it can -- I'll remove it & repost.

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
tools/kvm/term.c +1 -1
       if (read_in_full(term_fds[term][TERM_FD_IN], &c, 1) < 0)
               return -1;
 
@@ -84,7 +83,7 @@ int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term)
       if (c < 0)
               return 0;
 
-       *((int *)iov[TERM_FD_IN].iov_base)      = c;
+       *((char *)iov[TERM_FD_IN].iov_base)     = (char)c;
 
Quoted 7 lines
Quoted 5 lines

tools/kvm/term.c int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term) · line 89

Quoted 2 lines
tools/kvm/term.c +0 -0
       return sizeof(char);
 }

Looks OK to me. Asias?

Otherwise, looks fine to me.

Thanks for reviewing!

Matt

author
#67 lore raw

PATCH 15/28 kvm tools: Allow initrd_check() to match a cpio

In reply to a message not in the archive

cpios are valid as initrds too, so allow them through the check.

---
 tools/kvm/kvm.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)
tools/kvm/kvm.c +5 -3
index 33243f1..457de1a 100644
@@ -317,10 +317,11 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
 /* RFC 1952 */
 #define GZIP_ID1		0x1f
 #define GZIP_ID2		0x8b
-
+#define CPIO_MAGIC		"0707"
+/* initrd may be gzipped, or a plain cpio */
 static bool initrd_check(int fd)
 {
-	unsigned char id[2];
+	unsigned char id[4];
 
 	if (read_in_full(fd, id, ARRAY_SIZE(id)) < 0)
 		return false;
@@ -328,7 +329,8 @@ static bool initrd_check(int fd)
 	if (lseek(fd, 0, SEEK_SET) < 0)
 		die_perror("lseek");
 
-	return id[0] == GZIP_ID1 && id[1] == GZIP_ID2;
+	return (id[0] == GZIP_ID1 && id[1] == GZIP_ID2) ||
+		!memcmp(id, CPIO_MAGIC, 4);
 }
 
 bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
#68 lore raw

Re: [PATCH 15/28] kvm tools: Allow initrd_check() to match a cpio

Quoted 26 lines · Matt Evans

cpios are valid as initrds too, so allow them through the check.

---
 tools/kvm/kvm.c |    8 +++++---

 1 files changed, 5 insertions(+), 3 deletions(-)
tools/kvm/kvm.c +3 -2
index 33243f1..457de1a 100644
@@ -317,10 +317,11 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
  /* RFC 1952 */
  #define GZIP_ID1               0x1f
  #define GZIP_ID2               0x8b
-
+#define CPIO_MAGIC             "0707"
+/* initrd may be gzipped, or a plain cpio */
  static bool initrd_check(int fd)
  {
-       unsigned char id[2];
+       unsigned char id[4];
 
        if (read_in_full(fd, id, ARRAY_SIZE(id)) < 0)
                return false;

tools/kvm/kvm.c static bool initrd_check(int fd) · line 336

Quoted 9 lines
tools/kvm/kvm.c +2 -1
@@ -328,7 +329,8 @@ static bool initrd_check(int fd)
        if (lseek(fd, 0, SEEK_SET) < 0)
                die_perror("lseek");
 
-       return id[0] == GZIP_ID1 && id[1] == GZIP_ID2;
+       return (id[0] == GZIP_ID1 && id[1] == GZIP_ID2) ||
+               !memcmp(id, CPIO_MAGIC, 4);
  }
 
  bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,

Looks good to me.

author
#69 lore raw

PATCH 16/28 kvm tools: Allow load_flat_binary() to load an initrd alongside

In reply to a message not in the archive

This patch passes the initrd fd and commandline to load_flat_binary(), which may be used to load both the kernel & an initrd (stashing or inserting the commandline as appropriate) in the same way that load_bzimage() does. This is especially useful when load_bzimage() is unused for a particular architecture. :-)

---
 tools/kvm/include/kvm/kvm.h |    2 +-
 tools/kvm/kvm.c             |   10 ++++++----
 tools/kvm/x86/kvm.c         |   12 +++++++++---
 3 files changed, 16 insertions(+), 8 deletions(-)
tools/kvm/include/kvm/kvm.h +1 -1
index fae2ba9..5fe6e75 100644
@@ -59,7 +59,7 @@ void kvm__arch_setup_firmware(struct kvm *kvm);
 bool kvm__arch_cpu_supports_vm(void);
 void kvm__arch_periodic_poll(struct kvm *kvm);
 
-int load_flat_binary(struct kvm *kvm, int fd);
+int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline);
 bool load_bzimage(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline, u16 vidmode);
 
 /*
tools/kvm/kvm.c +6 -4
index 457de1a..6f33e1a 100644
@@ -354,23 +354,25 @@ bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
 
 	ret = load_bzimage(kvm, fd_kernel, fd_initrd, kernel_cmdline, vidmode);
 
-	if (initrd_filename)
-		close(fd_initrd);
-
 	if (ret)
 		goto found_kernel;
 
 	pr_warning("%s is not a bzImage. Trying to load it as a flat binary...", kernel_filename);
 
-	ret = load_flat_binary(kvm, fd_kernel);
+	ret = load_flat_binary(kvm, fd_kernel, fd_initrd, kernel_cmdline);
+
 	if (ret)
 		goto found_kernel;
 
+	if (initrd_filename)
+		close(fd_initrd);
 	close(fd_kernel);
 
 	die("%s is not a valid bzImage or flat binary", kernel_filename);
 
 found_kernel:
+	if (initrd_filename)
+		close(fd_initrd);
 	close(fd_kernel);
 
 	return ret;
tools/kvm/x86/kvm.c +9 -3
index 7071dc6..4ac21c0 100644
@@ -227,17 +227,23 @@ void kvm__irq_trigger(struct kvm *kvm, int irq)
 #define BOOT_PROTOCOL_REQUIRED	0x206
 #define LOAD_HIGH		0x01
 
-int load_flat_binary(struct kvm *kvm, int fd)
+int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline)
 {
 	void *p;
 	int nr;
 
-	if (lseek(fd, 0, SEEK_SET) < 0)
+	/* Some architectures may support loading an initrd alongside the flat kernel,
+	 * but we do not.
+	 */
+	if (fd_initrd != -1)
+		pr_warning("Loading initrd with flat binary not supported.");
+
+	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
 		die_perror("lseek");
 
 	p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
 
-	while ((nr = read(fd, p, 65536)) > 0)
+	while ((nr = read(fd_kernel, p, 65536)) > 0)
 		p += nr;
 
 	kvm->boot_selector	= BOOT_LOADER_SELECTOR;
#70 lore raw

Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside

Quoted 68 lines · Matt Evans

This patch passes the initrd fd and commandline to load_flat_binary(), which may be used to load both the kernel & an initrd (stashing or inserting the commandline as appropriate) in the same way that load_bzimage() does.  This is especially useful when load_bzimage() is unused for a particular architecture. :-)

---
 tools/kvm/include/kvm/kvm.h |    2 +-
 tools/kvm/kvm.c             |   10 ++++++----
 tools/kvm/x86/kvm.c         |   12 +++++++++---

 3 files changed, 16 insertions(+), 8 deletions(-)
tools/kvm/include/kvm/kvm.h +1 -1
index fae2ba9..5fe6e75 100644
@@ -59,7 +59,7 @@ void kvm__arch_setup_firmware(struct kvm *kvm);
  bool kvm__arch_cpu_supports_vm(void);
  void kvm__arch_periodic_poll(struct kvm *kvm);
 
-int load_flat_binary(struct kvm *kvm, int fd);
+int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline);
  bool load_bzimage(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline, u16 vidmode);
 
  /*
tools/kvm/kvm.c +4 -4
index 457de1a..6f33e1a 100644
@@ -354,23 +354,25 @@ bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
 
        ret = load_bzimage(kvm, fd_kernel, fd_initrd, kernel_cmdline, vidmode);
 
-       if (initrd_filename)
-               close(fd_initrd);
-
        if (ret)
                goto found_kernel;
 
        pr_warning("%s is not a bzImage. Trying to load it as a flat binary...", kernel_filename);
 
-       ret = load_flat_binary(kvm, fd_kernel);
+       ret = load_flat_binary(kvm, fd_kernel, fd_initrd, kernel_cmdline);
+
        if (ret)
                goto found_kernel;
 
+       if (initrd_filename)
+               close(fd_initrd);
        close(fd_kernel);
 
        die("%s is not a valid bzImage or flat binary", kernel_filename);
 

 found_kernel:
+       if (initrd_filename)
+               close(fd_initrd);
       close(fd_kernel);

       return ret;

tools/kvm/x86/kvm.c +0 -0
index 7071dc6..4ac21c0 100644
@@ -227,17 +227,23 @@ void kvm__irq_trigger(struct kvm *kvm, int irq)
  #define BOOT_PROTOCOL_REQUIRED 0x206
  #define LOAD_HIGH              0x01
 

tools/kvm/x86/kvm.c void kvm__irq_trigger(struct kvm *kvm, int irq) · line 237

Quoted 10 lines
tools/kvm/x86/kvm.c +4 -2
-int load_flat_binary(struct kvm *kvm, int fd)
+int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline)
  {
        void *p;
        int nr;
 
-       if (lseek(fd, 0, SEEK_SET) < 0)
+       /* Some architectures may support loading an initrd alongside the flat kernel,
+        * but we do not.
+        */

Minor nit - we use comment format where the first line is left empty from text:

      /*
       * Some architectures may support loading an initrd alongside
the flat kernel,
       * but we do not.
       */

Quoted 14 lines
tools/kvm/x86/kvm.c +5 -2
+       if (fd_initrd != -1)
+               pr_warning("Loading initrd with flat binary not supported.");
+
+       if (lseek(fd_kernel, 0, SEEK_SET) < 0)
                die_perror("lseek");
 
        p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
 
-       while ((nr = read(fd, p, 65536)) > 0)
+       while ((nr = read(fd_kernel, p, 65536)) > 0)
                p += nr;
 
        kvm->boot_selector      = BOOT_LOADER_SELECTOR;
--
Quoted 3 lines

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Otherwise looks OK to me. Cyrill?

#71 lore raw

Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside

On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
...

Quoted 3 lines

Otherwise looks OK to me. Cyrill?

It might be not seen from patch (or my local kvm repo is not yet updated well) but I somehow miss who will be reading initrd in case of loading flat image? If noone, then what's the point to pass fd there at all?

Cyrill

author
#72 lore raw

Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside

Hi Cyrill,

Quoted 10 lines · Cyrill Gorcunov

On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
...

Quoted 3 lines

Otherwise looks OK to me. Cyrill?

It might be not seen from patch (or my local kvm repo is not yet updated well) but I somehow miss who will be reading initrd in case of loading flat image? If noone, then what's the point to pass fd there at all?

I pass in the initrd fd in generic code in preparation for the PPC support in "[PATCH 1/8] kvm tools: Add initial SPAPR PPC64 architecture support" which uses it. As you saw, I haven't made x86 load the initrd in the case of a flat kernel binary being loaded; I didn't think a flat kernel can have a non-embedded initrd on x86? (My x86 is rusty, this may not be true ;) bootparams are [b]zImage only?)

Thanks for reviewing,

Matt

#73 lore raw

Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside

Quoted 14 lines · Matt Evans

Hi Cyrill,

Quoted 10 lines · Cyrill Gorcunov

On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
...

Quoted 3 lines

Otherwise looks OK to me. Cyrill?

It might be not seen from patch (or my local kvm repo is not yet updated well) but I somehow miss who will be reading initrd in case of loading flat image? If noone, then what's the point to pass fd there at all?

Quoted 7 lines

I pass in the initrd fd in generic code in preparation for the PPC support in "[PATCH 1/8] kvm tools: Add initial SPAPR PPC64 architecture support" which uses it. As you saw, I haven't made x86 load the initrd in the case of a flat kernel binary being loaded; I didn't think a flat kernel can have a non-embedded initrd on x86? (My x86 is rusty, this may not be true ;) bootparams are [b]zImage only?)

Ah, I see. Sorry for confusion. Thanks.

Cyrill

author
#74 lore raw

PATCH 17/28 kvm tools: Only call symbol__init() if we have BFD

In reply to a message not in the archive

CONFIG_HAS_BFD is optional, symbol.c inclusion is optional -- so make its init call dependent on CONFIG_HAS_BFD.

---
 tools/kvm/builtin-run.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
tools/kvm/builtin-run.c +2 -1
index 1257c90..aaa5132 100644
@@ -798,8 +798,9 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 	if (!script)
 		script = DEFAULT_SCRIPT;
 
+#ifdef CONFIG_HAS_BFD
 	symbol__init(vmlinux_filename);
-
+#endif
 	term_init();
 
 	if (!guest_name) {
#75 lore raw

Re: [PATCH 17/28] kvm tools: Only call symbol__init() if we have BFD

It's optional, but when CONFIG_HAS_BFD is not defined symbol__init() is defined as an empty static function.

Why was there a need to wrap it in a #ifdef here?

Quoted 27 lines · Matt Evans

CONFIG_HAS_BFD is optional, symbol.c inclusion is optional -- so make its init call dependent on CONFIG_HAS_BFD.

---
 tools/kvm/builtin-run.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
tools/kvm/builtin-run.c +2 -2
index 1257c90..aaa5132 100644
@@ -798,8 +798,9 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 	if (!script)
 		script = DEFAULT_SCRIPT;
 
+#ifdef CONFIG_HAS_BFD
 	symbol__init(vmlinux_filename);
-
+#endif
 	term_init();
 
 	if (!guest_name) {
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Sasha.
author
#76 lore raw

Re: [PATCH 17/28] kvm tools: Only call symbol__init() if we have BFD

Quoted 4 lines · Sasha Levin

It's optional, but when CONFIG_HAS_BFD is not defined symbol__init() is defined as an empty static function.

Why was there a need to wrap it in a #ifdef here?

That's an excellent question and I think the true answer is just embarrassing so I'll just drop this patch from the series. ;-)

Thanks,

Matt

Quoted 30 lines · Matt Evans
Quoted 27 lines

CONFIG_HAS_BFD is optional, symbol.c inclusion is optional -- so make its init call dependent on CONFIG_HAS_BFD.

---
 tools/kvm/builtin-run.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
tools/kvm/builtin-run.c +2 -2
index 1257c90..aaa5132 100644
@@ -798,8 +798,9 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 	if (!script)
 		script = DEFAULT_SCRIPT;
 
+#ifdef CONFIG_HAS_BFD
 	symbol__init(vmlinux_filename);
-
+#endif
 	term_init();
 
 	if (!guest_name) {
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#77 lore raw

PATCH 18/28 kvm tools: Initialise PCI before devices start getting registered with PCI

In reply to a message not in the archive

Re-arrange pci__init() in builtin-run such that it comes before devices are initialised.

---
 tools/kvm/builtin-run.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
tools/kvm/builtin-run.c +2 -2
index aaa5132..32e19e7 100644
@@ -829,6 +829,8 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm->nrcpus = nrcpus;
 
+	pci__init();
+
 	/*
 	 * vidmode should be either specified
 	 * either set by default
@@ -896,8 +898,6 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	serial8250__init(kvm);
 
-	pci__init();
-
 	if (active_console == CONSOLE_VIRTIO)
 		virtio_console__init(kvm);
 
author
#78 lore raw

PATCH 19/28 kvm tools: Perform CPU and firmware setup after devices are added

In reply to a message not in the archive

Currently some devices (in this case kbd, fb, vesa) are initialised after CPU/firmware setup. On some platforms (e.g. PPC) kvm__arch_setup_firmware() may be making a device tree. Any devices added after this point will be missed!

Tiny refactor of builtin-run.c, moving timer start, firmware setup, cpu init to occur last.

---
 tools/kvm/builtin-run.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)
tools/kvm/builtin-run.c +14 -10
index 32e19e7..576dcfa 100644
@@ -933,16 +933,6 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		virtio_net__init(&net_params);
 	}
 
-	kvm__start_timer(kvm);
-
-	kvm__arch_setup_firmware(kvm);
-
-	for (i = 0; i < nrcpus; i++) {
-		kvm_cpus[i] = kvm_cpu__init(kvm, i);
-		if (!kvm_cpus[i])
-			die("unable to initialize KVM VCPU");
-	}
-
 	kvm__init_ram(kvm);
 
 #ifdef CONFIG_X86
@@ -966,6 +956,20 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	fb__start();
 
+	/* Device init all done; firmware init must
+	 * come after this (it may set up device trees etc.)
+	 */
+
+	kvm__start_timer(kvm);
+
+	kvm__arch_setup_firmware(kvm);
+
+	for (i = 0; i < nrcpus; i++) {
+		kvm_cpus[i] = kvm_cpu__init(kvm, i);
+		if (!kvm_cpus[i])
+			die("unable to initialize KVM VCPU");
+	}
+
 	thread_pool__init(nr_online_cpus);
 	ioeventfd__start();
 
author
#79 lore raw

PATCH 20/28 kvm tools: Init IRQs after determining nrcpus

In reply to a message not in the archive

IRQ init may involve per-CPU setup/allocation of resources, so make sure kvm->nrcpus is initialised before calling irq__init().

---
 tools/kvm/builtin-run.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
tools/kvm/builtin-run.c +2 -2
index 576dcfa..84aa931 100644
@@ -810,8 +810,6 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm = kvm__init(dev, ram_size, guest_name);
 
-	irq__init(kvm);
-
 	kvm->single_step = single_step;
 
 	ioeventfd__init();
@@ -829,6 +827,8 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm->nrcpus = nrcpus;
 
+	irq__init(kvm);
+
 	pci__init();
 
 	/*
author
#80 lore raw

PATCH 21/28 kvm tools: Add --hugetlbfs option to specify memory path

In reply to a message not in the archive

Some architectures may want to use hugetlbfs to mmap() their guest memory, so allow a path to be specified on the commandline and pass it to kvm__arch_init().

---
 tools/kvm/builtin-run.c     |    4 +++-
 tools/kvm/include/kvm/kvm.h |    4 ++--
 tools/kvm/kvm.c             |    4 ++--
 tools/kvm/x86/kvm.c         |    2 +-
 4 files changed, 8 insertions(+), 6 deletions(-)
tools/kvm/builtin-run.c +3 -1
index 84aa931..4c88169 100644
@@ -84,6 +84,7 @@ static const char *guest_mac;
 static const char *host_mac;
 static const char *script;
 static const char *guest_name;
+static const char *hugetlbfs_path;
 static struct virtio_net_params *net_params;
 static bool single_step;
 static bool readonly_image[MAX_DISK_IMAGES];
@@ -422,6 +423,7 @@ static const struct option options[] = {
 	OPT_CALLBACK('\0', "tty", NULL, "tty id",
 		     "Remap guest TTY into a pty on the host",
 		     tty_parser),
+	OPT_STRING('\0', "hugetlbfs", &hugetlbfs_path, "path", "Hugetlbfs path"),
 
 	OPT_GROUP("Kernel options:"),
 	OPT_STRING('k', "kernel", &kernel_filename, "kernel",
@@ -808,7 +810,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		guest_name = default_name;
 	}
 
-	kvm = kvm__init(dev, ram_size, guest_name);
+	kvm = kvm__init(dev, hugetlbfs_path, ram_size, guest_name);
 
 	kvm->single_step = single_step;
 
tools/kvm/include/kvm/kvm.h +2 -2
index 5fe6e75..7159952 100644
@@ -30,7 +30,7 @@ struct kvm_ext {
 void kvm__set_dir(const char *fmt, ...);
 const char *kvm__get_dir(void);
 
-struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name);
+struct kvm *kvm__init(const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name);
 int kvm__recommended_cpus(struct kvm *kvm);
 int kvm__max_cpus(struct kvm *kvm);
 void kvm__init_ram(struct kvm *kvm);
@@ -54,7 +54,7 @@ int kvm__enumerate_instances(int (*callback)(const char *name, int pid));
 void kvm__remove_socket(const char *name);
 
 void kvm__arch_set_cmdline(char *cmdline, bool video);
-void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name);
+void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name);
 void kvm__arch_setup_firmware(struct kvm *kvm);
 bool kvm__arch_cpu_supports_vm(void);
 void kvm__arch_periodic_poll(struct kvm *kvm);
tools/kvm/kvm.c +2 -2
index 6f33e1a..503ceae 100644
@@ -272,7 +272,7 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
 		pr_warning("Failed sending PID");
 }
 
-struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
+struct kvm *kvm__init(const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name)
 {
 	struct kvm *kvm;
 	int ret;
@@ -305,7 +305,7 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
 	if (kvm__check_extensions(kvm))
 		die("A required KVM extention is not supported by OS");
 
-	kvm__arch_init(kvm, kvm_dev, ram_size, name);
+	kvm__arch_init(kvm, kvm_dev, hugetlbfs_path, ram_size, name);
 
 	kvm->name = name;
 
tools/kvm/x86/kvm.c +1 -1
index 4ac21c0..76f805f 100644
@@ -161,7 +161,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name)
+void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name)
 {
 	struct kvm_pit_config pit_config = { .flags = 0, };
 	int ret;
#81 lore raw

Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path

I'm seeing hugetlbfs_path being passed around, but I don't see anything that actually does something with it.

Did it get into a different patch? or maybe it wasn't 'git add'ed?

Quoted 101 lines · Matt Evans

Some architectures may want to use hugetlbfs to mmap() their guest memory, so allow a path to be specified on the commandline and pass it to kvm__arch_init().

---
 tools/kvm/builtin-run.c     |    4 +++-
 tools/kvm/include/kvm/kvm.h |    4 ++--
 tools/kvm/kvm.c             |    4 ++--
 tools/kvm/x86/kvm.c         |    2 +-
 4 files changed, 8 insertions(+), 6 deletions(-)
tools/kvm/builtin-run.c +3 -1
index 84aa931..4c88169 100644
@@ -84,6 +84,7 @@ static const char *guest_mac;
 static const char *host_mac;
 static const char *script;
 static const char *guest_name;
+static const char *hugetlbfs_path;
 static struct virtio_net_params *net_params;
 static bool single_step;
 static bool readonly_image[MAX_DISK_IMAGES];
@@ -422,6 +423,7 @@ static const struct option options[] = {
 	OPT_CALLBACK('\0', "tty", NULL, "tty id",
 		     "Remap guest TTY into a pty on the host",
 		     tty_parser),
+	OPT_STRING('\0', "hugetlbfs", &hugetlbfs_path, "path", "Hugetlbfs path"),
 
 	OPT_GROUP("Kernel options:"),
 	OPT_STRING('k', "kernel", &kernel_filename, "kernel",
@@ -808,7 +810,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		guest_name = default_name;
 	}
 
-	kvm = kvm__init(dev, ram_size, guest_name);
+	kvm = kvm__init(dev, hugetlbfs_path, ram_size, guest_name);
 
 	kvm->single_step = single_step;
 
tools/kvm/include/kvm/kvm.h +2 -2
index 5fe6e75..7159952 100644
@@ -30,7 +30,7 @@ struct kvm_ext {
 void kvm__set_dir(const char *fmt, ...);
 const char *kvm__get_dir(void);
 
-struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name);
+struct kvm *kvm__init(const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name);
 int kvm__recommended_cpus(struct kvm *kvm);
 int kvm__max_cpus(struct kvm *kvm);
 void kvm__init_ram(struct kvm *kvm);
@@ -54,7 +54,7 @@ int kvm__enumerate_instances(int (*callback)(const char *name, int pid));
 void kvm__remove_socket(const char *name);
 
 void kvm__arch_set_cmdline(char *cmdline, bool video);
-void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name);
+void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name);
 void kvm__arch_setup_firmware(struct kvm *kvm);
 bool kvm__arch_cpu_supports_vm(void);
 void kvm__arch_periodic_poll(struct kvm *kvm);
tools/kvm/kvm.c +2 -2
index 6f33e1a..503ceae 100644
@@ -272,7 +272,7 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
 		pr_warning("Failed sending PID");
 }
 
-struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
+struct kvm *kvm__init(const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name)
 {
 	struct kvm *kvm;
 	int ret;
@@ -305,7 +305,7 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
 	if (kvm__check_extensions(kvm))
 		die("A required KVM extention is not supported by OS");
 
-	kvm__arch_init(kvm, kvm_dev, ram_size, name);
+	kvm__arch_init(kvm, kvm_dev, hugetlbfs_path, ram_size, name);
 
 	kvm->name = name;
 
tools/kvm/x86/kvm.c +1 -2
index 4ac21c0..76f805f 100644
@@ -161,7 +161,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name)
+void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name)
 {
 	struct kvm_pit_config pit_config = { .flags = 0, };
 	int ret;
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Sasha.
author
#82 lore raw

Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path

Quoted 4 lines · Sasha Levin

I'm seeing hugetlbfs_path being passed around, but I don't see anything that actually does something with it.

Did it get into a different patch? or maybe it wasn't 'git add'ed?

It's actually moved in preparation for the later "[PATCH 1/8] kvm tools: Add initial SPAPR PPC64 architecture support" patch, which uses it. I could've mushed that into the later PPC series but I thought it'd be clearer to do the generic/x86 stuff separately.

Matt

Quoted 104 lines · Matt Evans
Quoted 101 lines

Some architectures may want to use hugetlbfs to mmap() their guest memory, so allow a path to be specified on the commandline and pass it to kvm__arch_init().

---
 tools/kvm/builtin-run.c     |    4 +++-
 tools/kvm/include/kvm/kvm.h |    4 ++--
 tools/kvm/kvm.c             |    4 ++--
 tools/kvm/x86/kvm.c         |    2 +-
 4 files changed, 8 insertions(+), 6 deletions(-)
tools/kvm/builtin-run.c +3 -1
index 84aa931..4c88169 100644
@@ -84,6 +84,7 @@ static const char *guest_mac;
 static const char *host_mac;
 static const char *script;
 static const char *guest_name;
+static const char *hugetlbfs_path;
 static struct virtio_net_params *net_params;
 static bool single_step;
 static bool readonly_image[MAX_DISK_IMAGES];
@@ -422,6 +423,7 @@ static const struct option options[] = {
 	OPT_CALLBACK('\0', "tty", NULL, "tty id",
 		     "Remap guest TTY into a pty on the host",
 		     tty_parser),
+	OPT_STRING('\0', "hugetlbfs", &hugetlbfs_path, "path", "Hugetlbfs path"),
 
 	OPT_GROUP("Kernel options:"),
 	OPT_STRING('k', "kernel", &kernel_filename, "kernel",
@@ -808,7 +810,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 		guest_name = default_name;
 	}
 
-	kvm = kvm__init(dev, ram_size, guest_name);
+	kvm = kvm__init(dev, hugetlbfs_path, ram_size, guest_name);
 
 	kvm->single_step = single_step;
 
tools/kvm/include/kvm/kvm.h +2 -2
index 5fe6e75..7159952 100644
@@ -30,7 +30,7 @@ struct kvm_ext {
 void kvm__set_dir(const char *fmt, ...);
 const char *kvm__get_dir(void);
 
-struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name);
+struct kvm *kvm__init(const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name);
 int kvm__recommended_cpus(struct kvm *kvm);
 int kvm__max_cpus(struct kvm *kvm);
 void kvm__init_ram(struct kvm *kvm);
@@ -54,7 +54,7 @@ int kvm__enumerate_instances(int (*callback)(const char *name, int pid));
 void kvm__remove_socket(const char *name);
 
 void kvm__arch_set_cmdline(char *cmdline, bool video);
-void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name);
+void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name);
 void kvm__arch_setup_firmware(struct kvm *kvm);
 bool kvm__arch_cpu_supports_vm(void);
 void kvm__arch_periodic_poll(struct kvm *kvm);
tools/kvm/kvm.c +2 -2
index 6f33e1a..503ceae 100644
@@ -272,7 +272,7 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
 		pr_warning("Failed sending PID");
 }
 
-struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
+struct kvm *kvm__init(const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name)
 {
 	struct kvm *kvm;
 	int ret;
@@ -305,7 +305,7 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)
 	if (kvm__check_extensions(kvm))
 		die("A required KVM extention is not supported by OS");
 
-	kvm__arch_init(kvm, kvm_dev, ram_size, name);
+	kvm__arch_init(kvm, kvm_dev, hugetlbfs_path, ram_size, name);
 
 	kvm->name = name;
 
tools/kvm/x86/kvm.c +1 -2
index 4ac21c0..76f805f 100644
@@ -161,7 +161,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const char *name)
+void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name)
 {
 	struct kvm_pit_config pit_config = { .flags = 0, };
 	int ret;
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#83 lore raw

Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path

Quoted 10 lines · Matt Evans
Quoted 4 lines · Sasha Levin

I'm seeing hugetlbfs_path being passed around, but I don't see anything that actually does something with it.

Did it get into a different patch? or maybe it wasn't 'git add'ed?

It's actually moved in preparation for the later "[PATCH 1/8] kvm tools: Add initial SPAPR PPC64 architecture support" patch, which uses it. I could've mushed that into the later PPC series but I thought it'd be clearer to do the generic/x86 stuff separately.

I actually would like to see everything moved into the generic code out of the PPC series :)

hugetlb allocation should probably be done in the generic code as it would work on x86 as well.

Signature · 1 line
Sasha.
author
#84 lore raw

PATCH 22/28 kvm tools: Move PCI_MAX_DEVICES to pci.h

In reply to a message not in the archive

Other pieces of kvmtool may be interested in PCI_MAX_DEVICES.

---
 tools/kvm/include/kvm/pci.h |    1 +
 tools/kvm/pci.c             |    1 -
 2 files changed, 1 insertions(+), 1 deletions(-)
tools/kvm/include/kvm/pci.h +1 -0
index f71af0b..b578ad7 100644
@@ -6,6 +6,7 @@
 #include <linux/pci_regs.h>
 #include <linux/msi.h>
 
+#define PCI_MAX_DEVICES			256
 /*
  * PCI Configuration Mechanism #1 I/O ports. See Section 3.7.4.1.
  * ("Configuration Mechanism #1") of the PCI Local Bus Specification 2.1 for
tools/kvm/pci.c +0 -1
index d1afc05..920e13e 100644
@@ -5,7 +5,6 @@
 
 #include <assert.h>
 
-#define PCI_MAX_DEVICES			256
 #define PCI_BAR_OFFSET(b)		(offsetof(struct pci_device_header, bar[b]))
 
 static struct pci_device_header		*pci_devices[PCI_MAX_DEVICES];
author
#85 lore raw

PATCH 23/28 kvm tools: Endian-sanitise pci.h and PCI device setup

In reply to a message not in the archive

vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The pci_config_address bitfield also needs to be reversed when building on BE systems.

---
 tools/kvm/hw/pci-shmem.c       |   23 +++++++++++----------
 tools/kvm/hw/vesa.c            |   15 +++++++------
 tools/kvm/include/kvm/ioport.h |   11 +++++----
 tools/kvm/include/kvm/pci.h    |   24 +++++++++++++++++-----
 tools/kvm/pci.c                |    4 +-
 tools/kvm/virtio/pci.c         |   41 +++++++++++++++++++++------------------
 6 files changed, 68 insertions(+), 50 deletions(-)
tools/kvm/hw/pci-shmem.c +12 -11
index 780a377..fd954c5 100644
@@ -8,21 +8,22 @@
 #include "kvm/ioeventfd.h"
 
 #include <linux/kvm.h>
+#include <linux/byteorder.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <sys/mman.h>
 
 static struct pci_device_header pci_shmem_pci_device = {
-	.vendor_id	= PCI_VENDOR_ID_REDHAT_QUMRANET,
-	.device_id	= 0x1110,
+	.vendor_id	= cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+	.device_id	= cpu_to_le16(0x1110),
 	.header_type	= PCI_HEADER_TYPE_NORMAL,
-	.class		= 0xFF0000,	/* misc pci device */
-	.status		= PCI_STATUS_CAP_LIST,
+	.class[2]	= 0xFF,	/* misc pci device */
+	.status		= cpu_to_le16(PCI_STATUS_CAP_LIST),
 	.capabilities	= (void *)&pci_shmem_pci_device.msix - (void *)&pci_shmem_pci_device,
 	.msix.cap	= PCI_CAP_ID_MSIX,
-	.msix.ctrl	= 1,
-	.msix.table_offset = 1,		/* Use BAR 1 */
-	.msix.pba_offset = 0x1001,	/* Use BAR 1 */
+	.msix.ctrl	= cpu_to_le16(1),
+	.msix.table_offset = cpu_to_le32(1),		/* Use BAR 1 */
+	.msix.pba_offset = cpu_to_le32(0x1001),		/* Use BAR 1 */
 };
 
 /* registers for the Inter-VM shared memory device */
@@ -123,7 +124,7 @@ int pci_shmem__get_local_irqfd(struct kvm *kvm)
 		if (fd < 0)
 			return fd;
 
-		if (pci_shmem_pci_device.msix.ctrl & PCI_MSIX_FLAGS_ENABLE) {
+		if (pci_shmem_pci_device.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE)) {
 			gsi = irq__add_msix_route(kvm, &msix_table[0].msg);
 		} else {
 			gsi = pci_shmem_pci_device.irq_line;
@@ -241,11 +242,11 @@ int pci_shmem__init(struct kvm *kvm)
 	 * 1 - MSI-X MMIO space
 	 * 2 - Shared memory block
 	 */
-	pci_shmem_pci_device.bar[0] = ivshmem_registers | PCI_BASE_ADDRESS_SPACE_IO;
+	pci_shmem_pci_device.bar[0] = cpu_to_le32(ivshmem_registers | PCI_BASE_ADDRESS_SPACE_IO);
 	pci_shmem_pci_device.bar_size[0] = shmem_region->size;
-	pci_shmem_pci_device.bar[1] = msix_block | PCI_BASE_ADDRESS_SPACE_MEMORY;
+	pci_shmem_pci_device.bar[1] = cpu_to_le32(msix_block | PCI_BASE_ADDRESS_SPACE_MEMORY);
 	pci_shmem_pci_device.bar_size[1] = 0x1010;
-	pci_shmem_pci_device.bar[2] = shmem_region->phys_addr | PCI_BASE_ADDRESS_SPACE_MEMORY;
+	pci_shmem_pci_device.bar[2] = cpu_to_le32(shmem_region->phys_addr | PCI_BASE_ADDRESS_SPACE_MEMORY);
 	pci_shmem_pci_device.bar_size[2] = shmem_region->size;
 
 	pci__register(&pci_shmem_pci_device, dev);
tools/kvm/hw/vesa.c +8 -7
index 22b1652..63f1082 100644
@@ -8,6 +8,7 @@
 #include "kvm/irq.h"
 #include "kvm/kvm.h"
 #include "kvm/pci.h"
+#include <linux/byteorder.h>
 #include <sys/mman.h>
 
 #include <sys/types.h>
@@ -31,14 +32,14 @@ static struct ioport_operations vesa_io_ops = {
 };
 
 static struct pci_device_header vesa_pci_device = {
-	.vendor_id		= PCI_VENDOR_ID_REDHAT_QUMRANET,
-	.device_id		= PCI_DEVICE_ID_VESA,
+	.vendor_id		= cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+	.device_id		= cpu_to_le16(PCI_DEVICE_ID_VESA),
 	.header_type		= PCI_HEADER_TYPE_NORMAL,
 	.revision_id		= 0,
-	.class			= 0x030000,
-	.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
-	.subsys_id		= PCI_SUBSYSTEM_ID_VESA,
-	.bar[1]			= VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY,
+	.class[2]		= 0x03,
+	.subsys_vendor_id	= cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
+	.subsys_id		= cpu_to_le16(PCI_SUBSYSTEM_ID_VESA),
+	.bar[1]			= cpu_to_le32(VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY),
 	.bar_size[1]		= VESA_MEM_SIZE,
 };
 
@@ -56,7 +57,7 @@ struct framebuffer *vesa__init(struct kvm *kvm)
 	vesa_pci_device.irq_pin		= pin;
 	vesa_pci_device.irq_line	= line;
 	vesa_base_addr			= ioport__register(IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL);
-	vesa_pci_device.bar[0]		= vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO;
+	vesa_pci_device.bar[0]		= cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO);
 	pci__register(&vesa_pci_device, dev);
 
 	mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
tools/kvm/include/kvm/ioport.h +6 -5
index 61a70ec..09bf876 100644
@@ -7,6 +7,7 @@
 #include <limits.h>
 #include <asm/types.h>
 #include <linux/types.h>
+#include <linux/byteorder.h>
 
 /* some ports we reserve for own use */
 #define IOPORT_DBG			0xe0
@@ -36,15 +37,15 @@ static inline u8 ioport__read8(u8 *data)
 {
 	return *data;
 }
-
+/* On BE platforms, PCI I/O is byteswapped, i.e. LE, so swap back. */
 static inline u16 ioport__read16(u16 *data)
 {
-	return *data;
+	return le16_to_cpu(*data);
 }
 
 static inline u32 ioport__read32(u32 *data)
 {
-	return *data;
+	return le32_to_cpu(*data);
 }
 
 static inline void ioport__write8(u8 *data, u8 value)
@@ -54,12 +55,12 @@ static inline void ioport__write8(u8 *data, u8 value)
 
 static inline void ioport__write16(u16 *data, u16 value)
 {
-	*data		 = value;
+	*data		 = cpu_to_le16(value);
 }
 
 static inline void ioport__write32(u32 *data, u32 value)
 {
-	*data		 = value;
+	*data		 = cpu_to_le32(value);
 }
 
 #endif /* KVM__IOPORT_H */
tools/kvm/include/kvm/pci.h +18 -6
index b578ad7..88e92dc 100644
@@ -5,6 +5,7 @@
 #include <linux/kvm.h>
 #include <linux/pci_regs.h>
 #include <linux/msi.h>
+#include <endian.h>
 
 #define PCI_MAX_DEVICES			256
 /*
@@ -17,7 +18,8 @@
 #define PCI_CONFIG_BUS_FORWARD	0xcfa
 #define PCI_IO_SIZE		0x100
 
-struct pci_config_address {
+union pci_config_address {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
 	unsigned	zeros		: 2;		/* 1  .. 0  */
 	unsigned	register_number	: 6;		/* 7  .. 2  */
 	unsigned	function_number	: 3;		/* 10 .. 8  */
@@ -25,6 +27,16 @@ struct pci_config_address {
 	unsigned	bus_number	: 8;		/* 23 .. 16 */
 	unsigned	reserved	: 7;		/* 30 .. 24 */
 	unsigned	enable_bit	: 1;		/* 31       */
+#else
+	unsigned	enable_bit	: 1;		/* 31       */
+	unsigned	reserved	: 7;		/* 30 .. 24 */
+	unsigned	bus_number	: 8;		/* 23 .. 16 */
+	unsigned	device_number	: 5;		/* 15 .. 11 */
+	unsigned	function_number	: 3;		/* 10 .. 8  */
+	unsigned	register_number	: 6;		/* 7  .. 2  */
+	unsigned	zeros		: 2;		/* 1  .. 0  */
+#endif
+	u32 w;
 };
 
 struct msix_table {
@@ -45,8 +57,8 @@ struct pci_device_header {
 	u16		device_id;
 	u16		command;
 	u16		status;
-	u16		revision_id		:  8;
-	u32		class			: 24;
+	u8		revision_id;
+	u8		class[3];
 	u8		cacheline_size;
 	u8		latency_timer;
 	u8		header_type;
@@ -56,8 +68,8 @@ struct pci_device_header {
 	u16		subsys_vendor_id;
 	u16		subsys_id;
 	u32		exp_rom_bar;
-	u32		capabilities		:  8;
-	u32		reserved1		: 24;
+	u8		capabilities;
+	u8		reserved1[3];
 	u32		reserved2;
 	u8		irq_line;
 	u8		irq_pin;
@@ -66,7 +78,7 @@ struct pci_device_header {
 	struct msix_cap msix;
 	u8		empty[136]; /* Rest of PCI config space */
 	u32		bar_size[6];
-};
+} __attribute__((packed));
 
 void pci__init(void);
 void pci__register(struct pci_device_header *dev, u8 dev_num);
tools/kvm/pci.c +2 -2
index 920e13e..5bbcbc7 100644
@@ -9,7 +9,7 @@
 
 static struct pci_device_header		*pci_devices[PCI_MAX_DEVICES];
 
-static struct pci_config_address	pci_config_address;
+static union pci_config_address		pci_config_address;
 
 /* This is within our PCI gap - in an unused area */
 static u32 io_space_blocks		= KVM_32BIT_GAP_START + 0x1000000;
@@ -105,7 +105,7 @@ static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port
 			 * When the kernel got the size it would write the address
 			 * back.
 			 */
-			if (ioport__read32(p + offset)) {
+			if (*(u32 *)(p + offset)) {
 				/* See if kernel tries to mask one of the BARs */
 				if ((offset >= PCI_BAR_OFFSET(0)) &&
 				    (offset <= PCI_BAR_OFFSET(6)) &&
tools/kvm/virtio/pci.c +22 -19

84 lines not on this page · raw message

#86 lore raw

Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup

Quoted 5 lines · Matt Evans

vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE).  The pci_config_address bitfield also needs to be reversed when building on BE systems.

Looks OK to me. Sasha, Cyrill?

#87 lore raw

Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup

Quoted 9 lines · Pekka Enberg
Quoted 5 lines · Matt Evans

vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE).  The pci_config_address bitfield also needs to be reversed when building on BE systems.

Looks OK to me. Sasha, Cyrill?

BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!

Cyrill

#88 lore raw

Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup

Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines · Pekka Enberg
Quoted 4 lines · Matt Evans

vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE).  The pci_config_address bitfield also needs to be reversed when building on BE systems.

Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Looks OK to me. Sasha, Cyrill?

BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!

Hmm. This seems to break "make check" for me:

./kvm run -d tests/boot/boot_test.iso -p "init=init"

  # kvm run -k ../../arch/x86/boot/bzImage -m 448 -c 4 --name guest-2845
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.0-rc3 (penberg@tux) (gcc version
4.6.0 20110603 (Red Hat 4.6.0-10) (GCC) ) #67 SMP Thu Nov 24 11:05:24
EET 2011
[    0.000000] Command line: noapic noacpi pci=conf1 reboot=k panic=1
i8042.direct=1 i8042.dumbkbd=1 i8042.nopnp=1 console=ttyS0
earlyprintk=serial i8042.noaux=1 init=init root=/dev/vda rw
[    0.000000] BIOS-provided physical RAM map:
[    0.000000]  BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
[    0.000000]  BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
[    0.000000]  BIOS-e820: 00000000000f0000 - 00000000000fffff (reserved)
[    0.000000]  BIOS-e820: 0000000000100000 - 000000001c000000 (usable)
[    0.000000] bootconsole [earlyser0] enabled
[    0.000000] NX (Execute Disable) protection: active
[    0.000000] DMI not present or invalid.
[    0.000000] No AGP bridge found
[    0.000000] last_pfn = 0x1c000 max_arch_pfn = 0x400000000
[    0.000000] x86 PAT enabled: cpu 0, old 0x70106, new 0x7010600070106
[    0.000000] CPU MTRRs all blank - virtualized system.
[    0.000000] found SMP MP-table at [ffff8800000f0390] f0390
[    0.000000] init_memory_mapping: 0000000000000000-000000001c000000
[    0.000000] ACPI Error: A valid RSDP was not found (20110623/tbxfroot-219)
[    0.000000] No NUMA configuration found
[    0.000000] Faking a node at 0000000000000000-000000001c000000
[    0.000000] Initmem setup node 0 0000000000000000-000000001c000000
[    0.000000]   NODE_DATA [000000001bfec000 - 000000001bffffff]
[    0.000000] kvm-clock: Using msrs 4b564d01 and 4b564d00
[    0.000000] kvm-clock: cpu 0, msr 0:1b71301, boot clock
[    0.000000] Zone PFN ranges:
[    0.000000]   DMA      0x00000010 -> 0x00001000
[    0.000000]   DMA32    0x00001000 -> 0x00100000
[    0.000000]   Normal   empty
[    0.000000] Movable zone start PFN for each node
[    0.000000] early_node_map[2] active PFN ranges
[    0.000000]     0: 0x00000010 -> 0x0000009f
[    0.000000]     0: 0x00000100 -> 0x0001c000
[    0.000000] SFI: Simple Firmware Interface v0.81 http://simplefirmware.org
[    0.000000] Intel MultiProcessor Specification v1.4
[    0.000000] MPTABLE: OEM ID: KVMCPU00
[    0.000000] MPTABLE: Product ID: 0.1
[    0.000000] MPTABLE: APIC at: 0xFEE00000
[    0.000000] Processor #0 (Bootup-CPU)
[    0.000000] Processor #1
[    0.000000] Processor #2
[    0.000000] Processor #3
[    0.000000] IOAPIC[0]: apic_id 5, version 17, address 0xfec00000, GSI 0-23
[    0.000000] Processors: 4
[    0.000000] SMP: Allowing 4 CPUs, 0 hotplug CPUs
[    0.000000] PM: Registered nosave memory: 000000000009f000 - 00000000000a0000
[    0.000000] PM: Registered nosave memory: 00000000000a0000 - 00000000000f0000
[    0.000000] PM: Registered nosave memory: 00000000000f0000 - 00000000000ff000
[    0.000000] PM: Registered nosave memory: 00000000000ff000 - 0000000000100000
[    0.000000] Allocating PCI resources starting at 1c000000 (gap:
1c000000:e4000000)
[    0.000000] Booting paravirtualized kernel on KVM
[    0.000000] setup_percpu: NR_CPUS:256 nr_cpumask_bits:256
nr_cpu_ids:4 nr_node_ids:1
[    0.000000] PERCPU: Embedded 27 pages/cpu @ffff88001bc00000 s77888
r8192 d24512 u524288
[    0.000000] kvm-clock: cpu 0, msr 0:1bc12301, primary cpu clock
[    0.000000] KVM setup async PF for cpu 0
[    0.000000] kvm-stealtime: cpu 0, msr 1bc0d000
[    0.000000] Built 1 zonelists in Node order, mobility grouping on.
Total pages: 112778
[    0.000000] Policy zone: DMA32
[    0.000000] Kernel command line: noapic noacpi pci=conf1 reboot=k
panic=1 i8042.direct=1 i8042.dumbkbd=1 i8042.nopnp=1 console=ttyS0
earlyprintk=serial i8042.noaux=1 init=init root=/dev/vda rw
[    0.000000] PID hash table entries: 2048 (order: 2, 16384 bytes)
[    0.000000] xsave/xrstor: enabled xstate_bv 0x7, cntxt size 0x340
[    0.000000] Checking aperture...
[    0.000000] No AGP bridge found
[    0.000000] Memory: 435408k/458752k available (4752k kernel code,
452k absent, 22892k reserved, 6886k data, 908k init)
[    0.000000] SLUB: Genslabs=15, HWalign=64, Order=0-3, MinObjects=0,
CPUs=4, Nodes=1
[    0.000000] Hierarchical RCU implementation.
[    0.000000] 	RCU dyntick-idle grace-period acceleration is enabled.
[    0.000000] NR_IRQS:16640 nr_irqs:712 16
[    0.000000] Console: colour *CGA 80x25
[    0.000000] console [ttyS0] enabled, bootconsole disabled
[    0.000000] console [ttyS0] enabled, bootconsole disabled
[    0.000000] allocated 4194304 bytes of page_cgroup
[    0.000000] please try 'cgroup_disable=memory' option if you don't
want memory cgroups
[    0.000000] Detected 2691.682 MHz processor.
[    0.000999] Calibrating delay loop (skipped) preset value.. 5383.36
BogoMIPS (lpj=2691682)
[    0.002009] pid_max: default: 32768 minimum: 301
[    0.002722] Security Framework initialized
[    0.003146] Dentry cache hash table entries: 65536 (order: 7, 524288 bytes)
[    0.005202] Inode-cache hash table entries: 32768 (order: 6, 262144 bytes)
[    0.006221] Mount-cache hash table entries: 256
[    0.007267] Initializing cgroup subsys cpuacct
[    0.007810] Initializing cgroup subsys memory
[    0.008042] Initializing cgroup subsys devices
[    0.008591] Initializing cgroup subsys freezer
[    0.009003] Initializing cgroup subsys net_cls
[    0.009452] Initializing cgroup subsys blkio
[    0.010015] Initializing cgroup subsys perf_event
[    0.010554] CPU: Physical Processor ID: 0
[    0.011002] CPU: Processor Core ID: 0
[    0.011390] mce: CPU supports 32 MCE banks
[    0.013371] ftrace: allocating 24096 entries in 95 pages
[    0.016161] CPU0: Intel 06/2a stepping 07
[    0.118022] Performance Events: unsupported p6 CPU model 42 no PMU
driver, software events only.
[    0.119085] NMI watchdog disabled (cpu0): hardware events not enabled
[    0.119886] Booting Node   0, Processors  #1
[    0.132990] kvm-clock: cpu 1, msr 0:1bc92301, secondary cpu clock
[    0.133013] NMI watchdog disabled (cpu1): hardware events not enabled
[    0.133155]  #2
[    0.133035] KVM setup async PF for cpu 1
[    0.133035] kvm-stealtime: cpu 1, msr 1bc8d000
[    0.146998] kvm-clock: cpu 2, msr 0:1bd12301, secondary cpu clock
[    0.147018] NMI watchdog disabled (cpu2): hardware events not enabled
[    0.147158]  #3 Ok.
[    0.147042] KVM setup async PF for cpu 2
[    0.147042] kvm-stealtime: cpu 2, msr 1bd0d000
[    0.159987] kvm-clock: cpu 3, msr 0:1bd92301, secondary cpu clock
[    0.160018] NMI watchdog disabled (cpu3): hardware events not enabled
[    0.160052] Brought up 4 CPUs
[    0.160054] Total of 4 processors activated (21533.45 BogoMIPS).
[    0.160050] KVM setup async PF for cpu 3
[    0.160050] kvm-stealtime: cpu 3, msr 1bd8d000
[    0.166066] devtmpfs: initialized
[    0.169332] atomic64 test passed for x86-64 platform with CX8 and with SSE
[    0.170095] RTC time: 11:40:38, date: 12/06/11
[    0.170631] NET: Registered protocol family 16
[    0.173092] PCI: Using configuration type 1 for base access
[    0.175422] bio: create slab <bio-0> at 0
[    0.176087] ACPI: Interpreter disabled.
[    0.177069] vgaarb: loaded
[    0.177585] SCSI subsystem initialized
[    0.178077] usbcore: registered new interface driver usbfs
[    0.179013] usbcore: registered new interface driver hub
[    0.180077] usbcore: registered new device driver usb
[    0.181129] PCI: Probing PCI hardware
[    0.182273] NetLabel: Initializing
[    0.182984] NetLabel:  domain hash size = 128
[    0.183675] NetLabel:  protocols = UNLABELED CIPSOv4
[    0.183994] NetLabel:  unlabeled traffic allowed by default
[    0.184986] Switching to clocksource kvm-clock
[    0.193502] pnp: PnP ACPI: disabled
[    0.201702] NET: Registered protocol family 2
[    0.202465] IP route cache hash table entries: 4096 (order: 3, 32768 bytes)
[    0.203701] TCP established hash table entries: 16384 (order: 6,
262144 bytes)
[    0.204975] TCP bind hash table entries: 16384 (order: 6, 262144 bytes)
[    0.206334] TCP: Hash tables configured (established 16384 bind 16384)
[    0.207420] TCP reno registered
[    0.207919] UDP hash table entries: 256 (order: 1, 8192 bytes)
[    0.208865] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
[    0.209934] NET: Registered protocol family 1
[    0.210904] kvm: no hardware support
[    0.211689] platform rtc_cmos: registered platform RTC device (no
PNP device found)
[    0.217236] alg: No test for __gcm-aes-aesni (__driver-gcm-aes-aesni)
[    0.218979] audit: initializing netlink socket (disabled)
[    0.220207] type=2000 audit(1323171638.219:1): initialized
[    0.237755] HugeTLB registered 2 MB page size, pre-allocated 0 pages
[    0.240695] VFS: Disk quotas dquot_6.5.2
[    0.241409] Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    0.242980] Installing v9fs 9p2000 file system support
[    0.243865] msgmni has been set to 850
[    0.245846] alg: No test for stdrng (krng)
[    0.246747] NET: Registered protocol family 38
[    0.247489] Block layer SCSI generic (bsg) driver version 0.4
loaded (major 253)
[    0.248841] io scheduler noop registered
[    0.249551] io scheduler deadline registered
[    0.250295] io scheduler cfq registered (default)
[    0.251156] pci_hotplug: PCI Hot Plug PCI Core version: 0.5
[    0.252108] pciehp: PCI Express Hot Plug Controller Driver version: 0.4
[    0.253206] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
[    0.254505] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    0.276481] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    0.306891] serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
[    0.333156] serial8250: ttyS2 at I/O 0x3e8 (irq = 4) is a 16550A
[    0.334767] Non-volatile memory driver v1.3
[    0.335276] Linux agpgart interface v0.103
[    0.338190] brd: module loaded
[    0.339946] loop: module loaded
[    0.340440] Fixed MDIO Bus: probed
[    0.340946] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    0.341698] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    0.342413] uhci_hcd: USB Universal Host Controller Interface driver
[    0.343194] usbcore: registered new interface driver usbserial
[    0.343840] USB Serial support registered for generic
[    0.344436] usbcore: registered new interface driver usbserial_generic
[    0.345170] usbserial: USB Serial Driver core
[    0.345649] i8042: PNP detection disabled
[    0.346277] serio: i8042 KBD port at 0x60,0x64 irq 1
[    0.347061] mousedev: PS/2 mouse device common for all mice
[    0.348078] input: AT Raw Set 2 keyboard as
/devices/platform/i8042/serio0/input/input0
[    0.349770] rtc_cmos rtc_cmos: rtc core: registered rtc_cmos as rtc0
[    0.350818] rtc_cmos rtc_cmos: only 24-hr supported
[    0.351831] device-mapper: uevent: version 1.0.3
[    0.352788] device-mapper: ioctl: 4.22.0-ioctl (2011-10-19)
initialised: [email protected]
[    0.354096] cpuidle: using governor ladder
[    0.354554] cpuidle: using governor menu
[    0.354982] EFI Variables Facility v0.08 2004-May-17
[    0.355676] usbcore: registered new interface driver usbhid
[    0.356297] usbhid: USB HID core driver
[    0.356748] ip_tables: (C) 2000-2006 Netfilter Core Team
[    0.357344] TCP cubic registered
[    0.357705] NET: Registered protocol family 17
[    0.358214] Installing 9P2000 support
[    0.358627] Registering the dns_resolver key type
[    0.359358] registered taskstats version 1
[    0.359824] IMA: No TPM chip found, activating TPM-bypass!
[    0.360677]   Magic number: 7:784:680
[    0.361129] drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
[    0.361841] Initializing network drop monitor service
[    0.362933] md: Waiting for all devices to be available before autodetect
[    0.363691] md: If you don't use raid, use raid=noautodetect
[    0.364537] md: Autodetecting RAID arrays.
[    0.364997] md: Scanned 0 and added 0 devices.
[    0.365502] md: autorun ...
[    0.365809] md: ... autorun DONE.
[    0.366234] VFS: Cannot open root device "vda" or unknown-block(0,0)
[    0.367056] Please append a correct "root=" boot option; here are
the available partitions:
[    0.368484] Kernel panic - not syncing: VFS: Unable to mount root
fs on unknown-block(0,0)
[    0.369907] Pid: 1, comm: swapper Not tainted 3.2.0-rc3 #67
[    0.370644] Call Trace:
[    0.370922]  [<ffffffff8148f63b>] panic+0x91/0x1a5
[    0.371450]  [<ffffffff81b73fc9>] mount_block_root+0x250/0x27b
[    0.372107]  [<ffffffff81b7417a>] mount_root+0x53/0x57
[    0.372662]  [<ffffffff81b742eb>] prepare_namespace+0x16d/0x1a6
[    0.373312]  [<ffffffff8109b4a3>] ? release_tgcred+0x2f/0x2f
[    0.373923]  [<ffffffff81b73cb5>] kernel_init+0x153/0x158
[    0.374527]  [<ffffffff81076758>] ? schedule_tail+0x27/0x6c
[    0.375147]  [<ffffffff814a0474>] kernel_thread_helper+0x4/0x10
[    0.375785]  [<ffffffff81b73b62>] ? start_kernel+0x3bd/0x3bd
[    0.376408]  [<ffffffff814a0470>] ? gs_change+0x13/0x13
[    0.377064] Rebooting in 1 seconds..

*** Compatibility Warning ***

virtio-blk device was not detected

While you have requested a virtio-blk device, the guest kernel did not initialize it.
Please make sure that the guest kernel was compiled with CONFIG_VIRTIO_BLK=y enabled in its .config

# KVM session ended normally.

#89 lore raw

Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup

Quoted 7 lines · Pekka Enberg
Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines · Pekka Enberg
Quoted 4 lines · Matt Evans

vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE).  The pci_config_address bitfield also needs to be reversed when building on BE systems.

Quoted 9 lines
Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Looks OK to me. Sasha, Cyrill?

BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!

Hmm. This seems to break "make check" for me:

If you change back to

 static struct pci_device_header pci_shmem_pci_device = {
	...
	.class          = 0xFF0000,     /* misc pci device */
	...

};

does it help?

Cyrill

#90 lore raw

Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup

Quoted 20 lines · Cyrill Gorcunov
Quoted 7 lines · Pekka Enberg
Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines · Pekka Enberg
Quoted 4 lines · Matt Evans

vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The pci_config_address bitfield also needs to be reversed when building on BE systems.

Quoted 9 lines
Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Looks OK to me. Sasha, Cyrill?

BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!

Hmm. This seems to break "make check" for me:

If you change back to

Quoted 7 lines
 static struct pci_device_header pci_shmem_pci_device = {
	...
	.class          = 0xFF0000,     /* misc pci device */
	...

};

does it help?

No but dropping these hunks fixes it for me:

@@ -17,7 +18,8 @@
#define PCI_CONFIG_BUS_FORWARD 0xcfa
#define PCI_IO_SIZE 0x100

-struct pci_config_address {
+union pci_config_address {
+#if __BYTE_ORDER == __LITTLE_ENDIAN

       unsigned        zeros           : 2;            /* 1  .. 0  */
       unsigned        register_number : 6;            /* 7  .. 2  */
       unsigned        function_number : 3;            /* 10 .. 8  */
@@ -25,6 +27,16 @@ struct pci_config_address {
       unsigned        bus_number      : 8;            /* 23 .. 16 */
       unsigned        reserved        : 7;            /* 30 .. 24 */
       unsigned        enable_bit      : 1;            /* 31       */
+#else
+       unsigned        enable_bit      : 1;            /* 31       */
+       unsigned        reserved        : 7;            /* 30 .. 24 */
+       unsigned        bus_number      : 8;            /* 23 .. 16 */
+       unsigned        device_number   : 5;            /* 15 .. 11 */
+       unsigned        function_number : 3;            /* 10 .. 8  */
+       unsigned        register_number : 6;            /* 7  .. 2  */
+       unsigned        zeros           : 2;            /* 1  .. 0  */

+#endif
+ u32 w;
};

Pekka

#91 lore raw

Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup

Quoted 49 lines · Pekka Enberg
Quoted 20 lines · Cyrill Gorcunov
Quoted 7 lines · Pekka Enberg
Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines · Pekka Enberg
Quoted 4 lines · Matt Evans

vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The pci_config_address bitfield also needs to be reversed when building on BE systems.

Quoted 9 lines
Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Looks OK to me. Sasha, Cyrill?

BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!

Hmm. This seems to break "make check" for me:

If you change back to

Quoted 7 lines
 static struct pci_device_header pci_shmem_pci_device = {
	...
	.class          = 0xFF0000,     /* misc pci device */
	...

};

does it help?

No but dropping these hunks fixes it for me:

tools/kvm/include/kvm/pci.h +5 -1
@@ -17,7 +18,8 @@
 #define PCI_CONFIG_BUS_FORWARD 0xcfa
 #define PCI_IO_SIZE            0x100
 
-struct pci_config_address {
+union pci_config_address {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
       unsigned        zeros           : 2;            /* 1  .. 0  */
       unsigned        register_number : 6;            /* 7  .. 2  */
       unsigned        function_number : 3;            /* 10 .. 8  */
@@ -25,6 +27,16 @@ struct pci_config_address {
       unsigned        bus_number      : 8;            /* 23 .. 16 */
       unsigned        reserved        : 7;            /* 30 .. 24 */
       unsigned        enable_bit      : 1;            /* 31       */
+#else
+       unsigned        enable_bit      : 1;            /* 31       */
+       unsigned        reserved        : 7;            /* 30 .. 24 */

tools/kvm/include/kvm/pci.h struct pci_config_address { · line 42

Quoted 10 lines
tools/kvm/include/kvm/pci.h +7 -0
+       unsigned        bus_number      : 8;            /* 23 .. 16 */
+       unsigned        device_number   : 5;            /* 15 .. 11 */
+       unsigned        function_number : 3;            /* 10 .. 8  */
+       unsigned        register_number : 6;            /* 7  .. 2  */
+       unsigned        zeros           : 2;            /* 1  .. 0  */
+#endif
+       u32 w;
 };
 
 			Pekka

Hehe, this is because it should be rtaher defined as

union pci_config_address {
struct {

  #if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned        zeros           : 2;
    unsigned        register_number : 6;
  #else
    ...

#endif
}
u32 w;
};

Cyrill

#92 lore raw

Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup

Quoted 70 lines · Cyrill Gorcunov
Quoted 49 lines · Pekka Enberg
Quoted 20 lines · Cyrill Gorcunov
Quoted 7 lines · Pekka Enberg
Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines · Pekka Enberg
Quoted 4 lines · Matt Evans

vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The pci_config_address bitfield also needs to be reversed when building on BE systems.

Quoted 9 lines
Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Looks OK to me. Sasha, Cyrill?

BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!

Hmm. This seems to break "make check" for me:

If you change back to

Quoted 7 lines
 static struct pci_device_header pci_shmem_pci_device = {
	...
	.class          = 0xFF0000,     /* misc pci device */
	...

};

does it help?

No but dropping these hunks fixes it for me:

(quoted diff) +5 -1
@@ -17,7 +18,8 @@
 #define PCI_CONFIG_BUS_FORWARD 0xcfa
 #define PCI_IO_SIZE            0x100
 
-struct pci_config_address {
+union pci_config_address {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
       unsigned        zeros           : 2;            /* 1  .. 0  */
       unsigned        register_number : 6;            /* 7  .. 2  */
       unsigned        function_number : 3;            /* 10 .. 8  */
@@ -25,6 +27,16 @@ struct pci_config_address {
       unsigned        bus_number      : 8;            /* 23 .. 16 */
       unsigned        reserved        : 7;            /* 30 .. 24 */
       unsigned        enable_bit      : 1;            /* 31       */
+#else
+       unsigned        enable_bit      : 1;            /* 31       */
+       unsigned        reserved        : 7;            /* 30 .. 24 */

Review struct pci_config_address { · line 42

Quoted 10 lines
(quoted diff) +7 -0
+       unsigned        bus_number      : 8;            /* 23 .. 16 */
+       unsigned        device_number   : 5;            /* 15 .. 11 */
+       unsigned        function_number : 3;            /* 10 .. 8  */
+       unsigned        register_number : 6;            /* 7  .. 2  */
+       unsigned        zeros           : 2;            /* 1  .. 0  */
+#endif
+       u32 w;
 };
 
 			Pekka

Hehe, this is because it should be rtaher defined as

union pci_config_address {
struct {

 #if __BYTE_ORDER == __LITTLE_ENDIAN
   unsigned        zeros           : 2;
   unsigned        register_number : 6;
 #else
   ...
Quoted 4 lines

#endif
}
u32 w;
};

Yup, that fixes it for me.

Pekka

#93 lore raw

Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup

Quoted 15 lines · Pekka Enberg
Quoted 14 lines

Hehe, this is because it should be rtaher defined as

union pci_config_address {
struct {
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned zeros : 2;
unsigned register_number : 6;
#else
...
#endif
}
u32 w;
};

Quoted 2 lines

Yup, that fixes it for me.

Good. Matt, mind to update?

Cyrill

author
#94 lore raw

Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup

Quoted 16 lines · Cyrill Gorcunov
Quoted 15 lines · Pekka Enberg
Quoted 14 lines

Hehe, this is because it should be rtaher defined as

union pci_config_address {
struct {
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned zeros : 2;
unsigned register_number : 6;
#else
...
#endif
}
u32 w;
};

Quoted 4 lines
Quoted 2 lines

Yup, that fixes it for me.

Good. Matt, mind to update?

Absolutely -- thank you for digging in and debugging that! I'll repost a V2.

Cheers,

Matt

author
#95 lore raw

PATCH 24/28 kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM

In reply to a message not in the archive

The field size is currently wrong, read into a 32bit word instead of 16. This casues trouble when BE.

---
 tools/kvm/virtio/pci.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
tools/kvm/virtio/pci.c +1 -2
index 0ae93fb..6b27ff8 100644
@@ -116,8 +116,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port,
 		break;
 	case VIRTIO_PCI_QUEUE_NUM:
 		val = vtrans->virtio_ops->get_size_vq(kvm, vpci->dev, vpci->queue_selector);
-		ioport__write32(data, val);
-		break;
+		ioport__write16(data, val);
 		break;
 	case VIRTIO_PCI_STATUS:
 		ioport__write8(data, vpci->status);
#96 lore raw

Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM

Quoted 14 lines · Matt Evans

The field size is currently wrong, read into a 32bit word instead of 16.  This casues trouble when BE.

---
 tools/kvm/virtio/pci.c |    3 +--

 1 files changed, 1 insertions(+), 2 deletions(-)
tools/kvm/virtio/pci.c +0 -0
index 0ae93fb..6b27ff8 100644
@@ -116,8 +116,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port,
                break;
Quoted 8 lines

       case VIRTIO_PCI_QUEUE_NUM:
               val = vtrans->virtio_ops->get_size_vq(kvm, vpci->dev, vpci->queue_selector);
-               ioport__write32(data, val);
-               break;
+               ioport__write16(data, val);
               break;
       case VIRTIO_PCI_STATUS:
               ioport__write8(data, vpci->status);

Looks good to me. Asias, Sasha?

#97 lore raw

Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM

Quoted 9 lines · Pekka Enberg
Quoted 8 lines · Matt Evans

The field size is currently wrong, read into a 32bit word instead of 16. This casues trouble when BE.

---
 tools/kvm/virtio/pci.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
Quoted 16 lines
Quoted 5 lines
tools/kvm/virtio/pci.c +0 -0
index 0ae93fb..6b27ff8 100644

tools/kvm/virtio/pci.c static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, · line 122

Quoted 9 lines
tools/kvm/virtio/pci.c +1 -2
@@ -116,8 +116,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port,
               break;
       case VIRTIO_PCI_QUEUE_NUM:
               val = vtrans->virtio_ops->get_size_vq(kvm, vpci->dev, vpci->queue_selector);
-               ioport__write32(data, val);
-               break;
+               ioport__write16(data, val);
               break;
       case VIRTIO_PCI_STATUS:
               ioport__write8(data, vpci->status);

Looks good to me. Asias, Sasha?

Looks good to me.

Signature · 1 line
Asias He
Applied
#98 lore raw

Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM

Quoted 13 lines · Asias He
Quoted 4 lines
Quoted 4 lines
(quoted diff) +0 -0
@@ -116,8 +116,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port,
                break;

       case VIRTIO_PCI_QUEUE_NUM:
               val = vtrans->virtio_ops->get_size_vq(kvm, vpci->dev, vpci->queue_selector);

Quoted 8 lines
Quoted 6 lines

-               ioport__write32(data, val);
-               break;
+               ioport__write16(data, val); break;
       case VIRTIO_PCI_STATUS:
               ioport__write8(data, vpci->status);

Looks good to me. Asias, Sasha?

Quoted 1 line

Looks good to me.

Applied, thanks!

#99 lore raw

Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM

In reply to Pekka Enberg
Quoted 9 lines · Pekka Enberg
Quoted 8 lines · Matt Evans

The field size is currently wrong, read into a 32bit word instead of 16. This casues trouble when BE.

---
 tools/kvm/virtio/pci.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
Quoted 16 lines
Quoted 5 lines
tools/kvm/virtio/pci.c +0 -0
index 0ae93fb..6b27ff8 100644

tools/kvm/virtio/pci.c static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, · line 122

Quoted 9 lines
tools/kvm/virtio/pci.c +1 -2
@@ -116,8 +116,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port,
               break;
       case VIRTIO_PCI_QUEUE_NUM:
               val = vtrans->virtio_ops->get_size_vq(kvm, vpci->dev, vpci->queue_selector);
-               ioport__write32(data, val);
-               break;
+               ioport__write16(data, val);
               break;
       case VIRTIO_PCI_STATUS:
               ioport__write8(data, vpci->status);

Looks good to me. Asias, Sasha?

Looks good.

Signature · 1 line
Sasha.
author
#100 lore raw

PATCH 25/28 kvm tools: Correctly set virtio-pci bar_size and remove hardwired address

In reply to a message not in the archive

The BAR addresses are set up fine, but missed the bar_size[] array which is now updated correspondingly.

Use PCI_IO_SIZE instead of '0x100'.

---
 tools/kvm/virtio/pci.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)
tools/kvm/virtio/pci.c +5 -2
index 6b27ff8..ffa3768 100644
@@ -293,8 +293,8 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
 	vpci->msix_pba_block = pci_get_io_space_block(PCI_IO_SIZE);
 
 	vpci->base_addr = ioport__register(IOPORT_EMPTY, &virtio_pci__io_ops, IOPORT_SIZE, vtrans);
-	kvm__register_mmio(kvm, vpci->msix_io_block, 0x100, callback_mmio_table, vpci);
-	kvm__register_mmio(kvm, vpci->msix_pba_block, 0x100, callback_mmio_pba, vpci);
+	kvm__register_mmio(kvm, vpci->msix_io_block, PCI_IO_SIZE, callback_mmio_table, vpci);
+	kvm__register_mmio(kvm, vpci->msix_pba_block, PCI_IO_SIZE, callback_mmio_pba, vpci);
 
 	vpci->pci_hdr = (struct pci_device_header) {
 		.vendor_id		= cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
@@ -313,6 +313,9 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
 						      | PCI_BASE_ADDRESS_MEM_TYPE_64),
 		.status			= cpu_to_le16(PCI_STATUS_CAP_LIST),
 		.capabilities		= (void *)&vpci->pci_hdr.msix - (void *)&vpci->pci_hdr,
+		.bar_size[0]		= IOPORT_SIZE,
+		.bar_size[1]		= PCI_IO_SIZE,
+		.bar_size[3]		= PCI_IO_SIZE,
 	};
 
 	vpci->pci_hdr.msix.cap = PCI_CAP_ID_MSIX;
author
#101 lore raw

PATCH 26/28 kvm tools: Add pci__config_{rd,wr}(), pci__find_dev() and fix PCI config register addressing

In reply to a message not in the archive

This allows config space access in a more natural manner than clunky x86 IO ports, and is useful for other architectures.

Furthermore, the actual registers were only accessed in 32bit chunks; other systems (e.g. PPC) allow smaller accesses so that, for example, the 16-bit config field can be read directly. This patch allows this sort of addressing.

---
 tools/kvm/include/kvm/pci.h |    5 +++
 tools/kvm/pci.c             |   63 +++++++++++++++++++++++++++---------------
 2 files changed, 45 insertions(+), 23 deletions(-)
tools/kvm/include/kvm/pci.h +5 -0
index 88e92dc..be2b0bc 100644
@@ -7,6 +7,8 @@
 #include <linux/msi.h>
 #include <endian.h>
 
+#include "kvm/kvm.h"
+
 #define PCI_MAX_DEVICES			256
 /*
  * PCI Configuration Mechanism #1 I/O ports. See Section 3.7.4.1.
@@ -82,6 +84,9 @@ struct pci_device_header {
 
 void pci__init(void);
 void pci__register(struct pci_device_header *dev, u8 dev_num);
+struct pci_device_header *pci__find_dev(u8 dev_num);
 u32 pci_get_io_space_block(u32 size);
+void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size);
+void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size);
 
 #endif /* KVM__PCI_H */
tools/kvm/pci.c +40 -23

108 lines not on this page · raw message

author
#102 lore raw

PATCH 27/28 kvm tools: Arch-specific define for PCI MMIO allocation area

In reply to a message not in the archive

pci_get_io_space_block() used to grab addresses from KVM_32BIT_GAP_START + 0x1000000, which is x86-specific. Create a new define, KVM_PCI_MMIO_AREA, to specify a bus address these allocations can come from.

---
 tools/kvm/pci.c                      |    8 ++++++--
 tools/kvm/x86/include/kvm/kvm-arch.h |    5 +++++
 2 files changed, 11 insertions(+), 2 deletions(-)
tools/kvm/pci.c +6 -2
index 8282e23..045c1c5 100644
@@ -11,8 +11,12 @@ static struct pci_device_header		*pci_devices[PCI_MAX_DEVICES];
 
 static union pci_config_address		pci_config_address;
 
-/* This is within our PCI gap - in an unused area */
-static u32 io_space_blocks		= KVM_32BIT_GAP_START + 0x1000000;
+/* This is within our PCI gap - in an unused area.
+ * Note this is a PCI *bus address*, is used to assign BARs etc.!
+ * (That's why it can still 32bit even with 64bit guests-- 64bit
+ * PCI isn't currently supported.)
+ */
+static u32 io_space_blocks		= KVM_PCI_MMIO_AREA;
 
 u32 pci_get_io_space_block(u32 size)
 {
tools/kvm/x86/include/kvm/kvm-arch.h +5 -0
index 02aa8b9..686b1b8 100644
@@ -18,6 +18,11 @@
 
 #define KVM_MMIO_START		KVM_32BIT_GAP_START
 
+/* This is the address that pci_get_io_space_block() starts allocating
+ * from.  Note that this is a PCI bus address (though same on x86).
+ */
+#define KVM_PCI_MMIO_AREA	(KVM_MMIO_START + 0x1000000)
+
 struct kvm {
 	int			sys_fd;		/* For system ioctls(), i.e. /dev/kvm */
 	int			vm_fd;		/* For VM ioctls() */
author
#103 lore raw

PATCH 28/28 kvm tools: Create arch-specific kvm_cpu__emulate_io()

In reply to a message not in the archive

Different architectures will deal with MMIO exits differently. For example, KVM_EXIT_IO is x86-specific, and I/O cycles are often synthesisted by steering into windows in PCI bridges on other architectures.

This patch moves the IO/MMIO exit code from the main runloop into x86/kvm-cpu.c

---
 tools/kvm/include/kvm/kvm-cpu.h |    1 +
 tools/kvm/kvm-cpu.c             |   37 +++++--------------------------------
 tools/kvm/x86/kvm-cpu.c         |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 32 deletions(-)
tools/kvm/include/kvm/kvm-cpu.h +1 -0
index 15618f1..6f38c0c 100644
@@ -13,6 +13,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu);
 void kvm_cpu__reboot(void);
 int kvm_cpu__start(struct kvm_cpu *cpu);
 bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu);
+bool kvm_cpu__emulate_io(struct kvm_cpu *cpu, struct kvm_run *kvm_run);
 
 int kvm_cpu__get_debug_fd(void);
 void kvm_cpu__set_debug_fd(int fd);
tools/kvm/kvm-cpu.c +5 -32
index 884a89f..c9fbc81 100644
@@ -103,49 +103,22 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
 			kvm_cpu__show_registers(cpu);
 			kvm_cpu__show_code(cpu);
 			break;
-		case KVM_EXIT_IO: {
-			bool ret;
-
-			ret = kvm__emulate_io(cpu->kvm,
-					cpu->kvm_run->io.port,
-					(u8 *)cpu->kvm_run +
-					cpu->kvm_run->io.data_offset,
-					cpu->kvm_run->io.direction,
-					cpu->kvm_run->io.size,
-					cpu->kvm_run->io.count);
-
-			if (!ret)
+		case KVM_EXIT_IO:
+		case KVM_EXIT_MMIO:
+			if (!kvm_cpu__emulate_io(cpu, cpu->kvm_run))
 				goto panic_kvm;
 			break;
-		}
-		case KVM_EXIT_MMIO: {
-			bool ret;
-
-			ret = kvm__emulate_mmio(cpu->kvm,
-					cpu->kvm_run->mmio.phys_addr,
-					cpu->kvm_run->mmio.data,
-					cpu->kvm_run->mmio.len,
-					cpu->kvm_run->mmio.is_write);
-
-			if (!ret)
-				goto panic_kvm;
-			break;
-		}
 		case KVM_EXIT_INTR:
 			if (cpu->is_running)
 				break;
 			goto exit_kvm;
 		case KVM_EXIT_SHUTDOWN:
 			goto exit_kvm;
-		default: {
-			bool ret;
-
-			ret = kvm_cpu__handle_exit(cpu);
-			if (!ret)
+		default:
+			if (!kvm_cpu__handle_exit(cpu))
 				goto panic_kvm;
 			break;
 		}
-		}
 		kvm_cpu__handle_coalesced_mmio(cpu);
 	}
 
tools/kvm/x86/kvm-cpu.c +37 -0
index a0d10cc..665d742 100644
@@ -217,6 +217,43 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
 	return false;
 }
 
+bool kvm_cpu__emulate_io(struct kvm_cpu *cpu, struct kvm_run *kvm_run)
+{
+	bool ret;
+	switch (kvm_run->exit_reason) {
+	case KVM_EXIT_IO: {
+		ret = kvm__emulate_io(cpu->kvm,
+				      cpu->kvm_run->io.port,
+				      (u8 *)cpu->kvm_run +
+				      cpu->kvm_run->io.data_offset,
+				      cpu->kvm_run->io.direction,
+				      cpu->kvm_run->io.size,
+				      cpu->kvm_run->io.count);
+
+		if (!ret)
+			goto panic_kvm;
+		break;
+	}
+	case KVM_EXIT_MMIO: {
+		ret = kvm__emulate_mmio(cpu->kvm,
+					cpu->kvm_run->mmio.phys_addr,
+					cpu->kvm_run->mmio.data,
+					cpu->kvm_run->mmio.len,
+					cpu->kvm_run->mmio.is_write);
+
+		if (!ret)
+			goto panic_kvm;
+		break;
+	}
+	default:
+		pr_warning("Unknown exit reason %d in %s\n", kvm_run->exit_reason, __FUNCTION__);
+		return false;
+	}
+	return true;
+panic_kvm:
+	return false;
+}
+
 static void print_dtable(const char *name, struct kvm_dtable *dtable)
 {
 	dprintf(debug_fd, " %s                 %016llx  %08hx\n",
#104 lore raw

Re: [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io()

Can we possibly do it by getting the generic code to call both 'kvm_cpu__arch_emulate_io' and 'kvm_cpu__arch_emulate_mmio', and have the ppc code have an empty static for 'kvm_cpu__arch_emulate_io'?

Quoted 136 lines · Matt Evans

Different architectures will deal with MMIO exits differently. For example, KVM_EXIT_IO is x86-specific, and I/O cycles are often synthesisted by steering into windows in PCI bridges on other architectures.

This patch moves the IO/MMIO exit code from the main runloop into x86/kvm-cpu.c

---
 tools/kvm/include/kvm/kvm-cpu.h |    1 +
 tools/kvm/kvm-cpu.c             |   37 +++++--------------------------------
 tools/kvm/x86/kvm-cpu.c         |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 32 deletions(-)
tools/kvm/include/kvm/kvm-cpu.h +1 -0
index 15618f1..6f38c0c 100644
@@ -13,6 +13,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu);
 void kvm_cpu__reboot(void);
 int kvm_cpu__start(struct kvm_cpu *cpu);
 bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu);
+bool kvm_cpu__emulate_io(struct kvm_cpu *cpu, struct kvm_run *kvm_run);
 
 int kvm_cpu__get_debug_fd(void);
 void kvm_cpu__set_debug_fd(int fd);
tools/kvm/kvm-cpu.c +5 -32
index 884a89f..c9fbc81 100644
@@ -103,49 +103,22 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
 			kvm_cpu__show_registers(cpu);
 			kvm_cpu__show_code(cpu);
 			break;
-		case KVM_EXIT_IO: {
-			bool ret;
-
-			ret = kvm__emulate_io(cpu->kvm,
-					cpu->kvm_run->io.port,
-					(u8 *)cpu->kvm_run +
-					cpu->kvm_run->io.data_offset,
-					cpu->kvm_run->io.direction,
-					cpu->kvm_run->io.size,
-					cpu->kvm_run->io.count);
-
-			if (!ret)
+		case KVM_EXIT_IO:
+		case KVM_EXIT_MMIO:
+			if (!kvm_cpu__emulate_io(cpu, cpu->kvm_run))
 				goto panic_kvm;
 			break;
-		}
-		case KVM_EXIT_MMIO: {
-			bool ret;
-
-			ret = kvm__emulate_mmio(cpu->kvm,
-					cpu->kvm_run->mmio.phys_addr,
-					cpu->kvm_run->mmio.data,
-					cpu->kvm_run->mmio.len,
-					cpu->kvm_run->mmio.is_write);
-
-			if (!ret)
-				goto panic_kvm;
-			break;
-		}
 		case KVM_EXIT_INTR:
 			if (cpu->is_running)
 				break;
 			goto exit_kvm;
 		case KVM_EXIT_SHUTDOWN:
 			goto exit_kvm;
-		default: {
-			bool ret;
-
-			ret = kvm_cpu__handle_exit(cpu);
-			if (!ret)
+		default:
+			if (!kvm_cpu__handle_exit(cpu))
 				goto panic_kvm;
 			break;
 		}
-		}
 		kvm_cpu__handle_coalesced_mmio(cpu);
 	}
 
tools/kvm/x86/kvm-cpu.c +37 -1
index a0d10cc..665d742 100644
@@ -217,6 +217,43 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
 	return false;
 }
 
+bool kvm_cpu__emulate_io(struct kvm_cpu *cpu, struct kvm_run *kvm_run)
+{
+	bool ret;
+	switch (kvm_run->exit_reason) {
+	case KVM_EXIT_IO: {
+		ret = kvm__emulate_io(cpu->kvm,
+				      cpu->kvm_run->io.port,
+				      (u8 *)cpu->kvm_run +
+				      cpu->kvm_run->io.data_offset,
+				      cpu->kvm_run->io.direction,
+				      cpu->kvm_run->io.size,
+				      cpu->kvm_run->io.count);
+
+		if (!ret)
+			goto panic_kvm;
+		break;
+	}
+	case KVM_EXIT_MMIO: {
+		ret = kvm__emulate_mmio(cpu->kvm,
+					cpu->kvm_run->mmio.phys_addr,
+					cpu->kvm_run->mmio.data,
+					cpu->kvm_run->mmio.len,
+					cpu->kvm_run->mmio.is_write);
+
+		if (!ret)
+			goto panic_kvm;
+		break;
+	}
+	default:
+		pr_warning("Unknown exit reason %d in %s\n", kvm_run->exit_reason, __FUNCTION__);
+		return false;
+	}
+	return true;
+panic_kvm:
+	return false;
+}
+
 static void print_dtable(const char *name, struct kvm_dtable *dtable)
 {
 	dprintf(debug_fd, " %s                 %016llx  %08hx\n",
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Sasha.
author
#105 lore raw

Re: [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io()

Quoted 3 lines · Sasha Levin

Can we possibly do it by getting the generic code to call both 'kvm_cpu__arch_emulate_io' and 'kvm_cpu__arch_emulate_mmio', and have the ppc code have an empty static for 'kvm_cpu__arch_emulate_io'?

Yeah that's nicer, I'll make that change... less invasive.

Cheers,

Matt

Quoted 139 lines · Matt Evans
Quoted 136 lines

Different architectures will deal with MMIO exits differently. For example, KVM_EXIT_IO is x86-specific, and I/O cycles are often synthesisted by steering into windows in PCI bridges on other architectures.

This patch moves the IO/MMIO exit code from the main runloop into x86/kvm-cpu.c

---
 tools/kvm/include/kvm/kvm-cpu.h |    1 +
 tools/kvm/kvm-cpu.c             |   37 +++++--------------------------------
 tools/kvm/x86/kvm-cpu.c         |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 32 deletions(-)
tools/kvm/include/kvm/kvm-cpu.h +1 -0
index 15618f1..6f38c0c 100644
@@ -13,6 +13,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu);
 void kvm_cpu__reboot(void);
 int kvm_cpu__start(struct kvm_cpu *cpu);
 bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu);
+bool kvm_cpu__emulate_io(struct kvm_cpu *cpu, struct kvm_run *kvm_run);
 
 int kvm_cpu__get_debug_fd(void);
 void kvm_cpu__set_debug_fd(int fd);
tools/kvm/kvm-cpu.c +5 -32
index 884a89f..c9fbc81 100644
@@ -103,49 +103,22 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
 			kvm_cpu__show_registers(cpu);
 			kvm_cpu__show_code(cpu);
 			break;
-		case KVM_EXIT_IO: {
-			bool ret;
-
-			ret = kvm__emulate_io(cpu->kvm,
-					cpu->kvm_run->io.port,
-					(u8 *)cpu->kvm_run +
-					cpu->kvm_run->io.data_offset,
-					cpu->kvm_run->io.direction,
-					cpu->kvm_run->io.size,
-					cpu->kvm_run->io.count);
-
-			if (!ret)
+		case KVM_EXIT_IO:
+		case KVM_EXIT_MMIO:
+			if (!kvm_cpu__emulate_io(cpu, cpu->kvm_run))
 				goto panic_kvm;
 			break;
-		}
-		case KVM_EXIT_MMIO: {
-			bool ret;
-
-			ret = kvm__emulate_mmio(cpu->kvm,
-					cpu->kvm_run->mmio.phys_addr,
-					cpu->kvm_run->mmio.data,
-					cpu->kvm_run->mmio.len,
-					cpu->kvm_run->mmio.is_write);
-
-			if (!ret)
-				goto panic_kvm;
-			break;
-		}
 		case KVM_EXIT_INTR:
 			if (cpu->is_running)
 				break;
 			goto exit_kvm;
 		case KVM_EXIT_SHUTDOWN:
 			goto exit_kvm;
-		default: {
-			bool ret;
-
-			ret = kvm_cpu__handle_exit(cpu);
-			if (!ret)
+		default:
+			if (!kvm_cpu__handle_exit(cpu))
 				goto panic_kvm;
 			break;
 		}
-		}
 		kvm_cpu__handle_coalesced_mmio(cpu);
 	}
 
tools/kvm/x86/kvm-cpu.c +37 -1
index a0d10cc..665d742 100644
@@ -217,6 +217,43 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
 	return false;
 }
 
+bool kvm_cpu__emulate_io(struct kvm_cpu *cpu, struct kvm_run *kvm_run)
+{
+	bool ret;
+	switch (kvm_run->exit_reason) {
+	case KVM_EXIT_IO: {
+		ret = kvm__emulate_io(cpu->kvm,
+				      cpu->kvm_run->io.port,
+				      (u8 *)cpu->kvm_run +
+				      cpu->kvm_run->io.data_offset,
+				      cpu->kvm_run->io.direction,
+				      cpu->kvm_run->io.size,
+				      cpu->kvm_run->io.count);
+
+		if (!ret)
+			goto panic_kvm;
+		break;
+	}
+	case KVM_EXIT_MMIO: {
+		ret = kvm__emulate_mmio(cpu->kvm,
+					cpu->kvm_run->mmio.phys_addr,
+					cpu->kvm_run->mmio.data,
+					cpu->kvm_run->mmio.len,
+					cpu->kvm_run->mmio.is_write);
+
+		if (!ret)
+			goto panic_kvm;
+		break;
+	}
+	default:
+		pr_warning("Unknown exit reason %d in %s\n", kvm_run->exit_reason, __FUNCTION__);
+		return false;
+	}
+	return true;
+panic_kvm:
+	return false;
+}
+
 static void print_dtable(const char *name, struct kvm_dtable *dtable)
 {
 	dprintf(debug_fd, " %s                 %016llx  %08hx\n",
--

To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html