All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/28] kvm tools: Split x86 arch-specific bits into x86/
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:37   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:37 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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%)

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index bb5f6b0..243886e 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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)
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 33de4f6..9148d83 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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);
diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 5b857dd..61a70ec 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -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);
 
diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
index 01540ac..719e286 100644
--- a/tools/kvm/include/kvm/kvm-cpu.h
+++ b/tools/kvm/include/kvm/kvm-cpu.h
@@ -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);
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index 2b3024a..ca1acc0 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -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 */
diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c
index 7cbc44e..965cfc2 100644
--- a/tools/kvm/ioport.c
+++ b/tools/kvm/ioport.c
@@ -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);
-}
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index 0ad6f3b..5aba3bb 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -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)
diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 252bd18..7ce1640 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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;
diff --git a/tools/kvm/bios.c b/tools/kvm/x86/bios.c
similarity index 100%
rename from tools/kvm/bios.c
rename to tools/kvm/x86/bios.c
diff --git a/tools/kvm/bios/.gitignore b/tools/kvm/x86/bios/.gitignore
similarity index 100%
rename from tools/kvm/bios/.gitignore
rename to tools/kvm/x86/bios/.gitignore
diff --git a/tools/kvm/bios/bios-rom.S b/tools/kvm/x86/bios/bios-rom.S
similarity index 80%
rename from tools/kvm/bios/bios-rom.S
rename to tools/kvm/x86/bios/bios-rom.S
index dc52b1e..3269ce9 100644
--- a/tools/kvm/bios/bios-rom.S
+++ b/tools/kvm/x86/bios/bios-rom.S
@@ -8,5 +8,5 @@
 #endif
 
 GLOBAL(bios_rom)
-	.incbin "bios/bios.bin"
+	.incbin "x86/bios/bios.bin"
 END(bios_rom)
diff --git a/tools/kvm/bios/e820.c b/tools/kvm/x86/bios/e820.c
similarity index 100%
rename from tools/kvm/bios/e820.c
rename to tools/kvm/x86/bios/e820.c
diff --git a/tools/kvm/bios/entry.S b/tools/kvm/x86/bios/entry.S
similarity index 100%
rename from tools/kvm/bios/entry.S
rename to tools/kvm/x86/bios/entry.S
diff --git a/tools/kvm/bios/gen-offsets.sh b/tools/kvm/x86/bios/gen-offsets.sh
similarity index 100%
rename from tools/kvm/bios/gen-offsets.sh
rename to tools/kvm/x86/bios/gen-offsets.sh
diff --git a/tools/kvm/bios/int10.c b/tools/kvm/x86/bios/int10.c
similarity index 100%
rename from tools/kvm/bios/int10.c
rename to tools/kvm/x86/bios/int10.c
diff --git a/tools/kvm/bios/int15.c b/tools/kvm/x86/bios/int15.c
similarity index 100%
rename from tools/kvm/bios/int15.c
rename to tools/kvm/x86/bios/int15.c
diff --git a/tools/kvm/bios/local.S b/tools/kvm/x86/bios/local.S
similarity index 100%
rename from tools/kvm/bios/local.S
rename to tools/kvm/x86/bios/local.S
diff --git a/tools/kvm/bios/macro.S b/tools/kvm/x86/bios/macro.S
similarity index 100%
rename from tools/kvm/bios/macro.S
rename to tools/kvm/x86/bios/macro.S
diff --git a/tools/kvm/bios/memcpy.c b/tools/kvm/x86/bios/memcpy.c
similarity index 100%
rename from tools/kvm/bios/memcpy.c
rename to tools/kvm/x86/bios/memcpy.c
diff --git a/tools/kvm/bios/rom.ld.S b/tools/kvm/x86/bios/rom.ld.S
similarity index 100%
rename from tools/kvm/bios/rom.ld.S
rename to tools/kvm/x86/bios/rom.ld.S
diff --git a/tools/kvm/cpuid.c b/tools/kvm/x86/cpuid.c
similarity index 100%
rename from tools/kvm/cpuid.c
rename to tools/kvm/x86/cpuid.c
diff --git a/tools/kvm/include/kvm/assembly.h b/tools/kvm/x86/include/kvm/assembly.h
similarity index 100%
rename from tools/kvm/include/kvm/assembly.h
rename to tools/kvm/x86/include/kvm/assembly.h
diff --git a/tools/kvm/include/kvm/barrier.h b/tools/kvm/x86/include/kvm/barrier.h
similarity index 100%
rename from tools/kvm/include/kvm/barrier.h
rename to tools/kvm/x86/include/kvm/barrier.h
diff --git a/tools/kvm/include/kvm/bios-export.h b/tools/kvm/x86/include/kvm/bios-export.h
similarity index 100%
rename from tools/kvm/include/kvm/bios-export.h
rename to tools/kvm/x86/include/kvm/bios-export.h
diff --git a/tools/kvm/include/kvm/bios.h b/tools/kvm/x86/include/kvm/bios.h
similarity index 100%
rename from tools/kvm/include/kvm/bios.h
rename to tools/kvm/x86/include/kvm/bios.h
diff --git a/tools/kvm/include/kvm/boot-protocol.h b/tools/kvm/x86/include/kvm/boot-protocol.h
similarity index 100%
rename from tools/kvm/include/kvm/boot-protocol.h
rename to tools/kvm/x86/include/kvm/boot-protocol.h
diff --git a/tools/kvm/include/kvm/cpufeature.h b/tools/kvm/x86/include/kvm/cpufeature.h
similarity index 100%
rename from tools/kvm/include/kvm/cpufeature.h
rename to tools/kvm/x86/include/kvm/cpufeature.h
diff --git a/tools/kvm/include/kvm/interrupt.h b/tools/kvm/x86/include/kvm/interrupt.h
similarity index 100%
rename from tools/kvm/include/kvm/interrupt.h
rename to tools/kvm/x86/include/kvm/interrupt.h
diff --git a/tools/kvm/x86/include/kvm/kvm-arch.h b/tools/kvm/x86/include/kvm/kvm-arch.h
new file mode 100644
index 0000000..02aa8b9
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/kvm-arch.h
@@ -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 */
diff --git a/tools/kvm/x86/include/kvm/kvm-cpu-arch.h b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
new file mode 100644
index 0000000..ed1c727
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
@@ -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 */
diff --git a/tools/kvm/include/kvm/mptable.h b/tools/kvm/x86/include/kvm/mptable.h
similarity index 100%
rename from tools/kvm/include/kvm/mptable.h
rename to tools/kvm/x86/include/kvm/mptable.h
diff --git a/tools/kvm/interrupt.c b/tools/kvm/x86/interrupt.c
similarity index 100%
rename from tools/kvm/interrupt.c
rename to tools/kvm/x86/interrupt.c
diff --git a/tools/kvm/x86/ioport.c b/tools/kvm/x86/ioport.c
new file mode 100644
index 0000000..8a91bf2
--- /dev/null
+++ b/tools/kvm/x86/ioport.c
@@ -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);
+}
diff --git a/tools/kvm/irq.c b/tools/kvm/x86/irq.c
similarity index 100%
rename from tools/kvm/irq.c
rename to tools/kvm/x86/irq.c
diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
new file mode 100644
index 0000000..b26b208
--- /dev/null
+++ b/tools/kvm/x86/kvm-cpu.c
@@ -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);
+}
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
new file mode 100644
index 0000000..ac6c91e
--- /dev/null
+++ b/tools/kvm/x86/kvm.c
@@ -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);
+}
diff --git a/tools/kvm/mptable.c b/tools/kvm/x86/mptable.c
similarity index 100%
rename from tools/kvm/mptable.c
rename to tools/kvm/x86/mptable.c

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

* [PATCH 01/28] kvm tools: Split x86 arch-specific bits into x86/
@ 2011-12-06  3:37   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:37 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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%)

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index bb5f6b0..243886e 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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_BITSd
 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)
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 33de4f6..9148d83 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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);
diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 5b857dd..61a70ec 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -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);
 
diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
index 01540ac..719e286 100644
--- a/tools/kvm/include/kvm/kvm-cpu.h
+++ b/tools/kvm/include/kvm/kvm-cpu.h
@@ -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);
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index 2b3024a..ca1acc0 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -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 */
diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c
index 7cbc44e..965cfc2 100644
--- a/tools/kvm/ioport.c
+++ b/tools/kvm/ioport.c
@@ -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);
-}
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index 0ad6f3b..5aba3bb 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -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)
diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 252bd18..7ce1640 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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;
diff --git a/tools/kvm/bios.c b/tools/kvm/x86/bios.c
similarity index 100%
rename from tools/kvm/bios.c
rename to tools/kvm/x86/bios.c
diff --git a/tools/kvm/bios/.gitignore b/tools/kvm/x86/bios/.gitignore
similarity index 100%
rename from tools/kvm/bios/.gitignore
rename to tools/kvm/x86/bios/.gitignore
diff --git a/tools/kvm/bios/bios-rom.S b/tools/kvm/x86/bios/bios-rom.S
similarity index 80%
rename from tools/kvm/bios/bios-rom.S
rename to tools/kvm/x86/bios/bios-rom.S
index dc52b1e..3269ce9 100644
--- a/tools/kvm/bios/bios-rom.S
+++ b/tools/kvm/x86/bios/bios-rom.S
@@ -8,5 +8,5 @@
 #endif
 
 GLOBAL(bios_rom)
-	.incbin "bios/bios.bin"
+	.incbin "x86/bios/bios.bin"
 END(bios_rom)
diff --git a/tools/kvm/bios/e820.c b/tools/kvm/x86/bios/e820.c
similarity index 100%
rename from tools/kvm/bios/e820.c
rename to tools/kvm/x86/bios/e820.c
diff --git a/tools/kvm/bios/entry.S b/tools/kvm/x86/bios/entry.S
similarity index 100%
rename from tools/kvm/bios/entry.S
rename to tools/kvm/x86/bios/entry.S
diff --git a/tools/kvm/bios/gen-offsets.sh b/tools/kvm/x86/bios/gen-offsets.sh
similarity index 100%
rename from tools/kvm/bios/gen-offsets.sh
rename to tools/kvm/x86/bios/gen-offsets.sh
diff --git a/tools/kvm/bios/int10.c b/tools/kvm/x86/bios/int10.c
similarity index 100%
rename from tools/kvm/bios/int10.c
rename to tools/kvm/x86/bios/int10.c
diff --git a/tools/kvm/bios/int15.c b/tools/kvm/x86/bios/int15.c
similarity index 100%
rename from tools/kvm/bios/int15.c
rename to tools/kvm/x86/bios/int15.c
diff --git a/tools/kvm/bios/local.S b/tools/kvm/x86/bios/local.S
similarity index 100%
rename from tools/kvm/bios/local.S
rename to tools/kvm/x86/bios/local.S
diff --git a/tools/kvm/bios/macro.S b/tools/kvm/x86/bios/macro.S
similarity index 100%
rename from tools/kvm/bios/macro.S
rename to tools/kvm/x86/bios/macro.S
diff --git a/tools/kvm/bios/memcpy.c b/tools/kvm/x86/bios/memcpy.c
similarity index 100%
rename from tools/kvm/bios/memcpy.c
rename to tools/kvm/x86/bios/memcpy.c
diff --git a/tools/kvm/bios/rom.ld.S b/tools/kvm/x86/bios/rom.ld.S
similarity index 100%
rename from tools/kvm/bios/rom.ld.S
rename to tools/kvm/x86/bios/rom.ld.S
diff --git a/tools/kvm/cpuid.c b/tools/kvm/x86/cpuid.c
similarity index 100%
rename from tools/kvm/cpuid.c
rename to tools/kvm/x86/cpuid.c
diff --git a/tools/kvm/include/kvm/assembly.h b/tools/kvm/x86/include/kvm/assembly.h
similarity index 100%
rename from tools/kvm/include/kvm/assembly.h
rename to tools/kvm/x86/include/kvm/assembly.h
diff --git a/tools/kvm/include/kvm/barrier.h b/tools/kvm/x86/include/kvm/barrier.h
similarity index 100%
rename from tools/kvm/include/kvm/barrier.h
rename to tools/kvm/x86/include/kvm/barrier.h
diff --git a/tools/kvm/include/kvm/bios-export.h b/tools/kvm/x86/include/kvm/bios-export.h
similarity index 100%
rename from tools/kvm/include/kvm/bios-export.h
rename to tools/kvm/x86/include/kvm/bios-export.h
diff --git a/tools/kvm/include/kvm/bios.h b/tools/kvm/x86/include/kvm/bios.h
similarity index 100%
rename from tools/kvm/include/kvm/bios.h
rename to tools/kvm/x86/include/kvm/bios.h
diff --git a/tools/kvm/include/kvm/boot-protocol.h b/tools/kvm/x86/include/kvm/boot-protocol.h
similarity index 100%
rename from tools/kvm/include/kvm/boot-protocol.h
rename to tools/kvm/x86/include/kvm/boot-protocol.h
diff --git a/tools/kvm/include/kvm/cpufeature.h b/tools/kvm/x86/include/kvm/cpufeature.h
similarity index 100%
rename from tools/kvm/include/kvm/cpufeature.h
rename to tools/kvm/x86/include/kvm/cpufeature.h
diff --git a/tools/kvm/include/kvm/interrupt.h b/tools/kvm/x86/include/kvm/interrupt.h
similarity index 100%
rename from tools/kvm/include/kvm/interrupt.h
rename to tools/kvm/x86/include/kvm/interrupt.h
diff --git a/tools/kvm/x86/include/kvm/kvm-arch.h b/tools/kvm/x86/include/kvm/kvm-arch.h
new file mode 100644
index 0000000..02aa8b9
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/kvm-arch.h
@@ -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 */
diff --git a/tools/kvm/x86/include/kvm/kvm-cpu-arch.h b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
new file mode 100644
index 0000000..ed1c727
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
@@ -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 */
diff --git a/tools/kvm/include/kvm/mptable.h b/tools/kvm/x86/include/kvm/mptable.h
similarity index 100%
rename from tools/kvm/include/kvm/mptable.h
rename to tools/kvm/x86/include/kvm/mptable.h
diff --git a/tools/kvm/interrupt.c b/tools/kvm/x86/interrupt.c
similarity index 100%
rename from tools/kvm/interrupt.c
rename to tools/kvm/x86/interrupt.c
diff --git a/tools/kvm/x86/ioport.c b/tools/kvm/x86/ioport.c
new file mode 100644
index 0000000..8a91bf2
--- /dev/null
+++ b/tools/kvm/x86/ioport.c
@@ -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);
+}
diff --git a/tools/kvm/irq.c b/tools/kvm/x86/irq.c
similarity index 100%
rename from tools/kvm/irq.c
rename to tools/kvm/x86/irq.c
diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
new file mode 100644
index 0000000..b26b208
--- /dev/null
+++ b/tools/kvm/x86/kvm-cpu.c
@@ -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);
+}
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
new file mode 100644
index 0000000..ac6c91e
--- /dev/null
+++ b/tools/kvm/x86/kvm.c
@@ -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);
+}
diff --git a/tools/kvm/mptable.c b/tools/kvm/x86/mptable.c
similarity index 100%
rename from tools/kvm/mptable.c
rename to tools/kvm/x86/mptable.c

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

* [PATCH 02/28] kvm tools: Only build/init i8042 on x86
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:37   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:37 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/Makefile      |    2 +-
 tools/kvm/builtin-run.c |    2 ++
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 243886e..f58a1d8 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 9148d83..e4aa87e 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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);
 

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

* [PATCH 02/28] kvm tools: Only build/init i8042 on x86
@ 2011-12-06  3:37   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:37 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/Makefile      |    2 +-
 tools/kvm/builtin-run.c |    2 ++
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 243886e..f58a1d8 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 9148d83..e4aa87e 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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);
 

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

* [PATCH 03/28] kvm tools: Add Makefile parameter for kernel include path
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:37   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:37 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/Makefile |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index f58a1d8..f85a154 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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

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

* [PATCH 03/28] kvm tools: Add Makefile parameter for kernel include
@ 2011-12-06  3:37   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:37 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/Makefile |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index f58a1d8..f85a154 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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

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

* [PATCH 04/28] kvm tools: Re-arrange Makefile to heed CFLAGS before checking for optional libs
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:38   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:38 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/Makefile |   86 ++++++++++++++++++++++++++-------------------------
 1 files changed, 44 insertions(+), 42 deletions(-)

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index f85a154..009a6ba 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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)
 

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

* [PATCH 04/28] kvm tools: Re-arrange Makefile to heed CFLAGS before
@ 2011-12-06  3:38   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:38 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/Makefile |   86 ++++++++++++++++++++++++++-------------------------
 1 files changed, 44 insertions(+), 42 deletions(-)

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index f85a154..009a6ba 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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)
 

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

* [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:38   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:38 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 009a6ba..57dc521 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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    " $@
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index e4aa87e..7cf208d 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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))
diff --git a/tools/kvm/builtin-stat.c b/tools/kvm/builtin-stat.c
index e28eb5b..c1f2605 100644
--- a/tools/kvm/builtin-stat.c
+++ b/tools/kvm/builtin-stat.c
@@ -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");
 
diff --git a/tools/kvm/disk/core.c b/tools/kvm/disk/core.c
index 4915efd..a135851 100644
--- a/tools/kvm/disk/core.c
+++ b/tools/kvm/disk/core.c
@@ -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;
 }
 
diff --git a/tools/kvm/mmio.c b/tools/kvm/mmio.c
index de7320f..1158bff 100644
--- a/tools/kvm/mmio.c
+++ b/tools/kvm/mmio.c
@@ -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();
 

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

* [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-06  3:38   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:38 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 009a6ba..57dc521 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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    " $@
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index e4aa87e..7cf208d 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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))
diff --git a/tools/kvm/builtin-stat.c b/tools/kvm/builtin-stat.c
index e28eb5b..c1f2605 100644
--- a/tools/kvm/builtin-stat.c
+++ b/tools/kvm/builtin-stat.c
@@ -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");
 
diff --git a/tools/kvm/disk/core.c b/tools/kvm/disk/core.c
index 4915efd..a135851 100644
--- a/tools/kvm/disk/core.c
+++ b/tools/kvm/disk/core.c
@@ -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;
 }
 
diff --git a/tools/kvm/mmio.c b/tools/kvm/mmio.c
index de7320f..1158bff 100644
--- a/tools/kvm/mmio.c
+++ b/tools/kvm/mmio.c
@@ -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();
 

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

* [PATCH 06/28] kvm tools: Add arch-specific KVM_RUN exit handling via kvm_cpu__handle_exit()
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:39   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:39 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
index 719e286..15618f1 100644
--- a/tools/kvm/include/kvm/kvm-cpu.h
+++ b/tools/kvm/include/kvm/kvm-cpu.h
@@ -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);
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index 5aba3bb..9bc0796 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -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);
 	}
diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
index b26b208..a0d10cc 100644
--- a/tools/kvm/x86/kvm-cpu.c
+++ b/tools/kvm/x86/kvm-cpu.c
@@ -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",

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

* [PATCH 06/28] kvm tools: Add arch-specific KVM_RUN exit handling
@ 2011-12-06  3:39   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:39 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
index 719e286..15618f1 100644
--- a/tools/kvm/include/kvm/kvm-cpu.h
+++ b/tools/kvm/include/kvm/kvm-cpu.h
@@ -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);
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index 5aba3bb..9bc0796 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -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);
 	}
diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
index b26b208..a0d10cc 100644
--- a/tools/kvm/x86/kvm-cpu.c
+++ b/tools/kvm/x86/kvm-cpu.c
@@ -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",

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

* [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:39   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:39 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/kvm.c     |   30 ------------------------------
 tools/kvm/x86/kvm.c |   30 ++++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 7ce1640..e526483 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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;
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
index ac6c91e..75e4a52 100644
--- a/tools/kvm/x86/kvm.c
+++ b/tools/kvm/x86/kvm.c
@@ -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

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

* [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific
@ 2011-12-06  3:39   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:39 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/kvm.c     |   30 ------------------------------
 tools/kvm/x86/kvm.c |   30 ++++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 7ce1640..e526483 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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;
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
index ac6c91e..75e4a52 100644
--- a/tools/kvm/x86/kvm.c
+++ b/tools/kvm/x86/kvm.c
@@ -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

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

* [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:39   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:39 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/kvm-cpu.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index 9bc0796..884a89f 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -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");
 }
 

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

* [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-06  3:39   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:39 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/kvm-cpu.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index 9bc0796..884a89f 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -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");
 }
 

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

* [PATCH 09/28] kvm tools: Add kvm__arch_periodic_poll()
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:39   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:39 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 7cf208d..9ef331e 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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)
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index ca1acc0..60842d5 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -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);
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
index 75e4a52..45dcb77 100644
--- a/tools/kvm/x86/kvm.c
+++ b/tools/kvm/x86/kvm.c
@@ -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);
+}

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

* [PATCH 09/28] kvm tools: Add kvm__arch_periodic_poll()
@ 2011-12-06  3:39   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:39 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 7cf208d..9ef331e 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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)
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index ca1acc0..60842d5 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -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);
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
index 75e4a52..45dcb77 100644
--- a/tools/kvm/x86/kvm.c
+++ b/tools/kvm/x86/kvm.c
@@ -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);
+}

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

* [PATCH 10/28] kvm tools: term.h needs to include stdbool.h
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:40   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

Fix a missing include.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/include/kvm/term.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/term.h b/tools/kvm/include/kvm/term.h
index 37ec731..938c26f 100644
--- a/tools/kvm/include/kvm/term.h
+++ b/tools/kvm/include/kvm/term.h
@@ -2,6 +2,7 @@
 #define KVM__TERM_H
 
 #include <sys/uio.h>
+#include <stdbool.h>
 
 #define CONSOLE_8250	1
 #define CONSOLE_VIRTIO	2

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

* [PATCH 10/28] kvm tools: term.h needs to include stdbool.h
@ 2011-12-06  3:40   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

Fix a missing include.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/include/kvm/term.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/include/kvm/term.h b/tools/kvm/include/kvm/term.h
index 37ec731..938c26f 100644
--- a/tools/kvm/include/kvm/term.h
+++ b/tools/kvm/include/kvm/term.h
@@ -2,6 +2,7 @@
 #define KVM__TERM_H
 
 #include <sys/uio.h>
+#include <stdbool.h>
 
 #define CONSOLE_8250	1
 #define CONSOLE_VIRTIO	2

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

* [PATCH 11/28] kvm tools: kvm.c needs to include sys/stat.h for mkdir
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:40   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

Fix a missing include.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/kvm.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index e526483..33243f1 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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>

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

* [PATCH 11/28] kvm tools: kvm.c needs to include sys/stat.h for mkdir
@ 2011-12-06  3:40   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

Fix a missing include.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/kvm.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index e526483..33243f1 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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>

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

* [PATCH 12/28] kvm tools: Move arch-specific cmdline init into kvm__arch_set_cmdline()
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:40   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 9ef331e..a67bd8c 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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));
 
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index 60842d5..fae2ba9 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -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);
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
index 45dcb77..7071dc6 100644
--- a/tools/kvm/x86/kvm.c
+++ b/tools/kvm/x86/kvm.c
@@ -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)
 {

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

* [PATCH 12/28] kvm tools: Move arch-specific cmdline init into kvm__arch_set_cmdline()
@ 2011-12-06  3:40   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 9ef331e..a67bd8c 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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));
 
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index 60842d5..fae2ba9 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -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);
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
index 45dcb77..7071dc6 100644
--- a/tools/kvm/x86/kvm.c
+++ b/tools/kvm/x86/kvm.c
@@ -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)
 {

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

* [PATCH 13/28] kvm tools: Add CONSOLE_HV term type and allow it to be selected
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:40   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/builtin-run.c      |    8 ++++++--
 tools/kvm/include/kvm/term.h |    1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index a67bd8c..1257c90 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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;
diff --git a/tools/kvm/include/kvm/term.h b/tools/kvm/include/kvm/term.h
index 938c26f..a6a9822 100644
--- a/tools/kvm/include/kvm/term.h
+++ b/tools/kvm/include/kvm/term.h
@@ -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);

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

* [PATCH 13/28] kvm tools: Add CONSOLE_HV term type and allow it to
@ 2011-12-06  3:40   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/builtin-run.c      |    8 ++++++--
 tools/kvm/include/kvm/term.h |    1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index a67bd8c..1257c90 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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;
diff --git a/tools/kvm/include/kvm/term.h b/tools/kvm/include/kvm/term.h
index 938c26f..a6a9822 100644
--- a/tools/kvm/include/kvm/term.h
+++ b/tools/kvm/include/kvm/term.h
@@ -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);

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

* [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:40   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/term.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/tools/kvm/term.c b/tools/kvm/term.c
index fb5d71c..440884e 100644
--- a/tools/kvm/term.c
+++ b/tools/kvm/term.c
@@ -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);
 }

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

* [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian
@ 2011-12-06  3:40   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/term.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/tools/kvm/term.c b/tools/kvm/term.c
index fb5d71c..440884e 100644
--- a/tools/kvm/term.c
+++ b/tools/kvm/term.c
@@ -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);
 }

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

* [PATCH 15/28] kvm tools: Allow initrd_check() to match a cpio
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:40   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/kvm.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 33243f1..457de1a 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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,

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

* [PATCH 15/28] kvm tools: Allow initrd_check() to match a cpio
@ 2011-12-06  3:40   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:40 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/kvm.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 33243f1..457de1a 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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,

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

* [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:41   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index fae2ba9..5fe6e75 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -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);
 
 /*
diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 457de1a..6f33e1a 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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;
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
index 7071dc6..4ac21c0 100644
--- a/tools/kvm/x86/kvm.c
+++ b/tools/kvm/x86/kvm.c
@@ -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;

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

* [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd
@ 2011-12-06  3:41   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index fae2ba9..5fe6e75 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -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);
 
 /*
diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 457de1a..6f33e1a 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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;
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
index 7071dc6..4ac21c0 100644
--- a/tools/kvm/x86/kvm.c
+++ b/tools/kvm/x86/kvm.c
@@ -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;

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

* [PATCH 17/28] kvm tools: Only call symbol__init() if we have BFD
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:41   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/builtin-run.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 1257c90..aaa5132 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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) {

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

* [PATCH 17/28] kvm tools: Only call symbol__init() if we have BFD
@ 2011-12-06  3:41   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/builtin-run.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 1257c90..aaa5132 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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) {

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

* [PATCH 18/28] kvm tools: Initialise PCI before devices start getting registered with PCI
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:41   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/builtin-run.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index aaa5132..32e19e7 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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);
 

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

* [PATCH 18/28] kvm tools: Initialise PCI before devices start getting
@ 2011-12-06  3:41   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/builtin-run.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index aaa5132..32e19e7 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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);
 

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

* [PATCH 19/28] kvm tools: Perform CPU and firmware setup after devices are added
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:41   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/builtin-run.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 32e19e7..576dcfa 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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();
 

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

* [PATCH 19/28] kvm tools: Perform CPU and firmware setup after devices
@ 2011-12-06  3:41   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/builtin-run.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 32e19e7..576dcfa 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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();
 

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

* [PATCH 20/28] kvm tools: Init IRQs after determining nrcpus
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:41   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/builtin-run.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 576dcfa..84aa931 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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();
 
 	/*

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

* [PATCH 20/28] kvm tools: Init IRQs after determining nrcpus
@ 2011-12-06  3:41   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/builtin-run.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 576dcfa..84aa931 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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();
 
 	/*

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

* [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:41   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 84aa931..4c88169 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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;
 
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index 5fe6e75..7159952 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -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);
diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 6f33e1a..503ceae 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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;
 
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
index 4ac21c0..76f805f 100644
--- a/tools/kvm/x86/kvm.c
+++ b/tools/kvm/x86/kvm.c
@@ -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;

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

* [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory
@ 2011-12-06  3:41   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:41 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 84aa931..4c88169 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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;
 
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index 5fe6e75..7159952 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -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);
diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
index 6f33e1a..503ceae 100644
--- a/tools/kvm/kvm.c
+++ b/tools/kvm/kvm.c
@@ -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;
 
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
index 4ac21c0..76f805f 100644
--- a/tools/kvm/x86/kvm.c
+++ b/tools/kvm/x86/kvm.c
@@ -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;

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

* [PATCH 22/28] kvm tools: Move PCI_MAX_DEVICES to pci.h
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:42   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:42 UTC (permalink / raw)
  To: kvm, kvm-ppc

Other pieces of kvmtool may be interested in PCI_MAX_DEVICES.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/include/kvm/pci.h |    1 +
 tools/kvm/pci.c             |    1 -
 2 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
index f71af0b..b578ad7 100644
--- a/tools/kvm/include/kvm/pci.h
+++ b/tools/kvm/include/kvm/pci.h
@@ -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
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index d1afc05..920e13e 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -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];

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

* [PATCH 22/28] kvm tools: Move PCI_MAX_DEVICES to pci.h
@ 2011-12-06  3:42   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:42 UTC (permalink / raw)
  To: kvm, kvm-ppc

Other pieces of kvmtool may be interested in PCI_MAX_DEVICES.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/include/kvm/pci.h |    1 +
 tools/kvm/pci.c             |    1 -
 2 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
index f71af0b..b578ad7 100644
--- a/tools/kvm/include/kvm/pci.h
+++ b/tools/kvm/include/kvm/pci.h
@@ -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
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index d1afc05..920e13e 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -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];

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

* [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:42   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:42 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c
index 780a377..fd954c5 100644
--- a/tools/kvm/hw/pci-shmem.c
+++ b/tools/kvm/hw/pci-shmem.c
@@ -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);
diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c
index 22b1652..63f1082 100644
--- a/tools/kvm/hw/vesa.c
+++ b/tools/kvm/hw/vesa.c
@@ -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);
diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 61a70ec..09bf876 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -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 */
diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
index b578ad7..88e92dc 100644
--- a/tools/kvm/include/kvm/pci.h
+++ b/tools/kvm/include/kvm/pci.h
@@ -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);
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index 920e13e..5bbcbc7 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -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)) &&
diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index 0737ae7..0ae93fb 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -9,6 +9,7 @@
 #include "kvm/virtio-trans.h"
 
 #include <linux/virtio_pci.h>
+#include <linux/byteorder.h>
 #include <string.h>
 
 struct virtio_trans_ops *virtio_pci__get_trans_ops(void)
@@ -59,7 +60,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_trans *vtra
 
 static inline bool virtio_pci__msix_enabled(struct virtio_pci *vpci)
 {
-	return vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_ENABLE;
+	return vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE);
 }
 
 static bool virtio_pci__specific_io_in(struct kvm *kvm, struct virtio_trans *vtrans, u16 port,
@@ -245,8 +246,8 @@ int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_trans *vtrans, u32 vq)
 	int tbl = vpci->vq_vector[vq];
 
 	if (virtio_pci__msix_enabled(vpci)) {
-		if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
-			vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
+		if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
+		    vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
 
 			vpci->msix_pba |= 1 << tbl;
 			return 0;
@@ -266,8 +267,8 @@ int virtio_pci__signal_config(struct kvm *kvm, struct virtio_trans *vtrans)
 	int tbl = vpci->config_vector;
 
 	if (virtio_pci__msix_enabled(vpci)) {
-		if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
-			vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
+		if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
+		    vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
 
 			vpci->msix_pba |= 1 << tbl;
 			return 0;
@@ -297,19 +298,21 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
 	kvm__register_mmio(kvm, vpci->msix_pba_block, 0x100, callback_mmio_pba, vpci);
 
 	vpci->pci_hdr = (struct pci_device_header) {
-		.vendor_id		= PCI_VENDOR_ID_REDHAT_QUMRANET,
-		.device_id		= device_id,
+		.vendor_id		= cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+		.device_id		= cpu_to_le16(device_id),
 		.header_type		= PCI_HEADER_TYPE_NORMAL,
 		.revision_id		= 0,
-		.class			= class,
-		.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
-		.subsys_id		= subsys_id,
-		.bar[0]			= vpci->base_addr | PCI_BASE_ADDRESS_SPACE_IO,
-		.bar[1]			= vpci->msix_io_block | PCI_BASE_ADDRESS_SPACE_MEMORY
-					| PCI_BASE_ADDRESS_MEM_TYPE_64,
-		.bar[3]			= vpci->msix_pba_block | PCI_BASE_ADDRESS_SPACE_MEMORY
-					| PCI_BASE_ADDRESS_MEM_TYPE_64,
-		.status			= PCI_STATUS_CAP_LIST,
+		.class[0]		= class & 0xff,
+		.class[1]		= (class >> 8) & 0xff,
+		.class[2]		= (class >> 16) & 0xff,
+		.subsys_vendor_id	= cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
+		.subsys_id		= cpu_to_le16(subsys_id),
+		.bar[0]			= cpu_to_le32(vpci->base_addr | PCI_BASE_ADDRESS_SPACE_IO),
+		.bar[1]			= cpu_to_le32(vpci->msix_io_block | PCI_BASE_ADDRESS_SPACE_MEMORY
+						      | PCI_BASE_ADDRESS_MEM_TYPE_64),
+		.bar[3]			= cpu_to_le32(vpci->msix_pba_block | PCI_BASE_ADDRESS_SPACE_MEMORY
+						      | PCI_BASE_ADDRESS_MEM_TYPE_64),
+		.status			= cpu_to_le16(PCI_STATUS_CAP_LIST),
 		.capabilities		= (void *)&vpci->pci_hdr.msix - (void *)&vpci->pci_hdr,
 	};
 
@@ -326,14 +329,14 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
 	 * For example, a returned value of "00000000011"
 	 * indicates a table size of 4.
 	 */
-	vpci->pci_hdr.msix.ctrl = (VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
+	vpci->pci_hdr.msix.ctrl = cpu_to_le16(VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
 
 	/*
 	 * Both table and PBA could be mapped on the same BAR, but for now
 	 * we're not in short of BARs
 	 */
-	vpci->pci_hdr.msix.table_offset = 1; /* Use BAR 1 */
-	vpci->pci_hdr.msix.pba_offset = 3; /* Use BAR 3 */
+	vpci->pci_hdr.msix.table_offset = cpu_to_le32(1); /* Use BAR 1 */
+	vpci->pci_hdr.msix.pba_offset = cpu_to_le32(3); /* Use BAR 3 */
 	vpci->config_vector = 0;
 
 	if (irq__register_device(subsys_id, &ndev, &pin, &line) < 0)

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

* [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
@ 2011-12-06  3:42   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:42 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c
index 780a377..fd954c5 100644
--- a/tools/kvm/hw/pci-shmem.c
+++ b/tools/kvm/hw/pci-shmem.c
@@ -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);
diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c
index 22b1652..63f1082 100644
--- a/tools/kvm/hw/vesa.c
+++ b/tools/kvm/hw/vesa.c
@@ -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);
diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
index 61a70ec..09bf876 100644
--- a/tools/kvm/include/kvm/ioport.h
+++ b/tools/kvm/include/kvm/ioport.h
@@ -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 */
diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
index b578ad7..88e92dc 100644
--- a/tools/kvm/include/kvm/pci.h
+++ b/tools/kvm/include/kvm/pci.h
@@ -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);
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index 920e13e..5bbcbc7 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -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)) &&
diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index 0737ae7..0ae93fb 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -9,6 +9,7 @@
 #include "kvm/virtio-trans.h"
 
 #include <linux/virtio_pci.h>
+#include <linux/byteorder.h>
 #include <string.h>
 
 struct virtio_trans_ops *virtio_pci__get_trans_ops(void)
@@ -59,7 +60,7 @@ static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_trans *vtra
 
 static inline bool virtio_pci__msix_enabled(struct virtio_pci *vpci)
 {
-	return vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_ENABLE;
+	return vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE);
 }
 
 static bool virtio_pci__specific_io_in(struct kvm *kvm, struct virtio_trans *vtrans, u16 port,
@@ -245,8 +246,8 @@ int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_trans *vtrans, u32 vq)
 	int tbl = vpci->vq_vector[vq];
 
 	if (virtio_pci__msix_enabled(vpci)) {
-		if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
-			vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
+		if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
+		    vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
 
 			vpci->msix_pba |= 1 << tbl;
 			return 0;
@@ -266,8 +267,8 @@ int virtio_pci__signal_config(struct kvm *kvm, struct virtio_trans *vtrans)
 	int tbl = vpci->config_vector;
 
 	if (virtio_pci__msix_enabled(vpci)) {
-		if (vpci->pci_hdr.msix.ctrl & PCI_MSIX_FLAGS_MASKALL ||
-			vpci->msix_table[tbl].ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
+		if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
+		    vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
 
 			vpci->msix_pba |= 1 << tbl;
 			return 0;
@@ -297,19 +298,21 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
 	kvm__register_mmio(kvm, vpci->msix_pba_block, 0x100, callback_mmio_pba, vpci);
 
 	vpci->pci_hdr = (struct pci_device_header) {
-		.vendor_id		= PCI_VENDOR_ID_REDHAT_QUMRANET,
-		.device_id		= device_id,
+		.vendor_id		= cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+		.device_id		= cpu_to_le16(device_id),
 		.header_type		= PCI_HEADER_TYPE_NORMAL,
 		.revision_id		= 0,
-		.class			= class,
-		.subsys_vendor_id	= PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET,
-		.subsys_id		= subsys_id,
-		.bar[0]			= vpci->base_addr | PCI_BASE_ADDRESS_SPACE_IO,
-		.bar[1]			= vpci->msix_io_block | PCI_BASE_ADDRESS_SPACE_MEMORY
-					| PCI_BASE_ADDRESS_MEM_TYPE_64,
-		.bar[3]			= vpci->msix_pba_block | PCI_BASE_ADDRESS_SPACE_MEMORY
-					| PCI_BASE_ADDRESS_MEM_TYPE_64,
-		.status			= PCI_STATUS_CAP_LIST,
+		.class[0]		= class & 0xff,
+		.class[1]		= (class >> 8) & 0xff,
+		.class[2]		= (class >> 16) & 0xff,
+		.subsys_vendor_id	= cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
+		.subsys_id		= cpu_to_le16(subsys_id),
+		.bar[0]			= cpu_to_le32(vpci->base_addr | PCI_BASE_ADDRESS_SPACE_IO),
+		.bar[1]			= cpu_to_le32(vpci->msix_io_block | PCI_BASE_ADDRESS_SPACE_MEMORY
+						      | PCI_BASE_ADDRESS_MEM_TYPE_64),
+		.bar[3]			= cpu_to_le32(vpci->msix_pba_block | PCI_BASE_ADDRESS_SPACE_MEMORY
+						      | PCI_BASE_ADDRESS_MEM_TYPE_64),
+		.status			= cpu_to_le16(PCI_STATUS_CAP_LIST),
 		.capabilities		= (void *)&vpci->pci_hdr.msix - (void *)&vpci->pci_hdr,
 	};
 
@@ -326,14 +329,14 @@ int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
 	 * For example, a returned value of "00000000011"
 	 * indicates a table size of 4.
 	 */
-	vpci->pci_hdr.msix.ctrl = (VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
+	vpci->pci_hdr.msix.ctrl = cpu_to_le16(VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
 
 	/*
 	 * Both table and PBA could be mapped on the same BAR, but for now
 	 * we're not in short of BARs
 	 */
-	vpci->pci_hdr.msix.table_offset = 1; /* Use BAR 1 */
-	vpci->pci_hdr.msix.pba_offset = 3; /* Use BAR 3 */
+	vpci->pci_hdr.msix.table_offset = cpu_to_le32(1); /* Use BAR 1 */
+	vpci->pci_hdr.msix.pba_offset = cpu_to_le32(3); /* Use BAR 3 */
 	vpci->config_vector = 0;
 
 	if (irq__register_device(subsys_id, &ndev, &pin, &line) < 0)

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

* [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:42   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:42 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/virtio/pci.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index 0ae93fb..6b27ff8 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -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);

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

* [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
@ 2011-12-06  3:42   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:42 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/virtio/pci.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index 0ae93fb..6b27ff8 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -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);

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

* [PATCH 25/28] kvm tools: Correctly set virtio-pci bar_size and remove hardwired address
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:42   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:42 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/virtio/pci.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index 6b27ff8..ffa3768 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -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;

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

* [PATCH 25/28] kvm tools: Correctly set virtio-pci bar_size and remove
@ 2011-12-06  3:42   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:42 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/virtio/pci.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
index 6b27ff8..ffa3768 100644
--- a/tools/kvm/virtio/pci.c
+++ b/tools/kvm/virtio/pci.c
@@ -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;

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

* [PATCH 26/28] kvm tools: Add pci__config_{rd,wr}(), pci__find_dev() and fix PCI config register addressing
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:42   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:42 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/include/kvm/pci.h |    5 +++
 tools/kvm/pci.c             |   63 +++++++++++++++++++++++++++---------------
 2 files changed, 45 insertions(+), 23 deletions(-)

diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
index 88e92dc..be2b0bc 100644
--- a/tools/kvm/include/kvm/pci.h
+++ b/tools/kvm/include/kvm/pci.h
@@ -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 */
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index 5bbcbc7..8282e23 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -77,7 +77,6 @@ static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_numbe
 static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
 {
 	unsigned long start;
-	u8 dev_num;
 
 	/*
 	 * If someone accesses PCI configuration space offsets that are not
@@ -85,12 +84,41 @@ static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port
 	 */
 	start = port - PCI_CONFIG_DATA;
 
-	dev_num		= pci_config_address.device_number;
+	pci__config_wr(kvm, pci_config_address, data, size);
+
+	return true;
+}
+
+static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	unsigned long start;
+
+	/*
+	 * If someone accesses PCI configuration space offsets that are not
+	 * aligned to 4 bytes, it uses ioports to signify that.
+	 */
+	start = port - PCI_CONFIG_DATA;
+
+	pci__config_rd(kvm, pci_config_address, data, size);
+
+	return true;
+}
+
+static struct ioport_operations pci_config_data_ops = {
+	.io_in		= pci_config_data_in,
+	.io_out		= pci_config_data_out,
+};
+
+void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size)
+{
+	u8 dev_num;
+
+	dev_num		= addr.device_number;
 
 	if (pci_device_exists(0, dev_num, 0)) {
 		unsigned long offset;
 
-		offset = start + (pci_config_address.register_number << 2);
+		offset = addr.w & 0xff;
 		if (offset < sizeof(struct pci_device_header)) {
 			void *p = pci_devices[dev_num];
 			u8 bar = (offset - PCI_BAR_OFFSET(0)) / (sizeof(u32));
@@ -116,27 +144,18 @@ static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port
 			}
 		}
 	}
-
-	return true;
 }
 
-static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size)
 {
-	unsigned long start;
 	u8 dev_num;
 
-	/*
-	 * If someone accesses PCI configuration space offsets that are not
-	 * aligned to 4 bytes, it uses ioports to signify that.
-	 */
-	start = port - PCI_CONFIG_DATA;
-
-	dev_num		= pci_config_address.device_number;
+	dev_num		= addr.device_number;
 
 	if (pci_device_exists(0, dev_num, 0)) {
 		unsigned long offset;
 
-		offset = start + (pci_config_address.register_number << 2);
+		offset = addr.w & 0xff;
 		if (offset < sizeof(struct pci_device_header)) {
 			void *p = pci_devices[dev_num];
 
@@ -145,22 +164,20 @@ static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port,
 			memset(data, 0x00, size);
 	} else
 		memset(data, 0xff, size);
-
-	return true;
 }
 
-static struct ioport_operations pci_config_data_ops = {
-	.io_in		= pci_config_data_in,
-	.io_out		= pci_config_data_out,
-};
-
 void pci__register(struct pci_device_header *dev, u8 dev_num)
 {
 	assert(dev_num < PCI_MAX_DEVICES);
-
 	pci_devices[dev_num]	= dev;
 }
 
+struct pci_device_header *pci__find_dev(u8 dev_num)
+{
+	assert(dev_num < PCI_MAX_DEVICES);
+	return pci_devices[dev_num];
+}
+
 void pci__init(void)
 {
 	ioport__register(PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL);

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

* [PATCH 26/28] kvm tools: Add pci__config_{rd,wr}(), pci__find_dev()
@ 2011-12-06  3:42   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:42 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/include/kvm/pci.h |    5 +++
 tools/kvm/pci.c             |   63 +++++++++++++++++++++++++++---------------
 2 files changed, 45 insertions(+), 23 deletions(-)

diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
index 88e92dc..be2b0bc 100644
--- a/tools/kvm/include/kvm/pci.h
+++ b/tools/kvm/include/kvm/pci.h
@@ -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 */
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index 5bbcbc7..8282e23 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -77,7 +77,6 @@ static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_numbe
 static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
 {
 	unsigned long start;
-	u8 dev_num;
 
 	/*
 	 * If someone accesses PCI configuration space offsets that are not
@@ -85,12 +84,41 @@ static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port
 	 */
 	start = port - PCI_CONFIG_DATA;
 
-	dev_num		= pci_config_address.device_number;
+	pci__config_wr(kvm, pci_config_address, data, size);
+
+	return true;
+}
+
+static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	unsigned long start;
+
+	/*
+	 * If someone accesses PCI configuration space offsets that are not
+	 * aligned to 4 bytes, it uses ioports to signify that.
+	 */
+	start = port - PCI_CONFIG_DATA;
+
+	pci__config_rd(kvm, pci_config_address, data, size);
+
+	return true;
+}
+
+static struct ioport_operations pci_config_data_ops = {
+	.io_in		= pci_config_data_in,
+	.io_out		= pci_config_data_out,
+};
+
+void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size)
+{
+	u8 dev_num;
+
+	dev_num		= addr.device_number;
 
 	if (pci_device_exists(0, dev_num, 0)) {
 		unsigned long offset;
 
-		offset = start + (pci_config_address.register_number << 2);
+		offset = addr.w & 0xff;
 		if (offset < sizeof(struct pci_device_header)) {
 			void *p = pci_devices[dev_num];
 			u8 bar = (offset - PCI_BAR_OFFSET(0)) / (sizeof(u32));
@@ -116,27 +144,18 @@ static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port
 			}
 		}
 	}
-
-	return true;
 }
 
-static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size)
 {
-	unsigned long start;
 	u8 dev_num;
 
-	/*
-	 * If someone accesses PCI configuration space offsets that are not
-	 * aligned to 4 bytes, it uses ioports to signify that.
-	 */
-	start = port - PCI_CONFIG_DATA;
-
-	dev_num		= pci_config_address.device_number;
+	dev_num		= addr.device_number;
 
 	if (pci_device_exists(0, dev_num, 0)) {
 		unsigned long offset;
 
-		offset = start + (pci_config_address.register_number << 2);
+		offset = addr.w & 0xff;
 		if (offset < sizeof(struct pci_device_header)) {
 			void *p = pci_devices[dev_num];
 
@@ -145,22 +164,20 @@ static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port,
 			memset(data, 0x00, size);
 	} else
 		memset(data, 0xff, size);
-
-	return true;
 }
 
-static struct ioport_operations pci_config_data_ops = {
-	.io_in		= pci_config_data_in,
-	.io_out		= pci_config_data_out,
-};
-
 void pci__register(struct pci_device_header *dev, u8 dev_num)
 {
 	assert(dev_num < PCI_MAX_DEVICES);
-
 	pci_devices[dev_num]	= dev;
 }
 
+struct pci_device_header *pci__find_dev(u8 dev_num)
+{
+	assert(dev_num < PCI_MAX_DEVICES);
+	return pci_devices[dev_num];
+}
+
 void pci__init(void)
 {
 	ioport__register(PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL);

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

* [PATCH 27/28] kvm tools: Arch-specific define for PCI MMIO allocation area
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:43   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:43 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/pci.c                      |    8 ++++++--
 tools/kvm/x86/include/kvm/kvm-arch.h |    5 +++++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index 8282e23..045c1c5 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -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)
 {
diff --git a/tools/kvm/x86/include/kvm/kvm-arch.h b/tools/kvm/x86/include/kvm/kvm-arch.h
index 02aa8b9..686b1b8 100644
--- a/tools/kvm/x86/include/kvm/kvm-arch.h
+++ b/tools/kvm/x86/include/kvm/kvm-arch.h
@@ -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() */

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

* [PATCH 27/28] kvm tools: Arch-specific define for PCI MMIO allocation
@ 2011-12-06  3:43   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:43 UTC (permalink / raw)
  To: kvm, kvm-ppc

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.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/pci.c                      |    8 ++++++--
 tools/kvm/x86/include/kvm/kvm-arch.h |    5 +++++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
index 8282e23..045c1c5 100644
--- a/tools/kvm/pci.c
+++ b/tools/kvm/pci.c
@@ -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)
 {
diff --git a/tools/kvm/x86/include/kvm/kvm-arch.h b/tools/kvm/x86/include/kvm/kvm-arch.h
index 02aa8b9..686b1b8 100644
--- a/tools/kvm/x86/include/kvm/kvm-arch.h
+++ b/tools/kvm/x86/include/kvm/kvm-arch.h
@@ -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() */

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

* [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io()
       [not found] <cover.1323141075.git.matt@ozlabs.org>
@ 2011-12-06  3:43   ` Matt Evans
  2011-12-06  3:37   ` Matt Evans
                     ` (26 subsequent siblings)
  27 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:43 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
index 15618f1..6f38c0c 100644
--- a/tools/kvm/include/kvm/kvm-cpu.h
+++ b/tools/kvm/include/kvm/kvm-cpu.h
@@ -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);
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index 884a89f..c9fbc81 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -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);
 	}
 
diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
index a0d10cc..665d742 100644
--- a/tools/kvm/x86/kvm-cpu.c
+++ b/tools/kvm/x86/kvm-cpu.c
@@ -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",

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

* [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io()
@ 2011-12-06  3:43   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-06  3:43 UTC (permalink / raw)
  To: kvm, kvm-ppc

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

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 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(-)

diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
index 15618f1..6f38c0c 100644
--- a/tools/kvm/include/kvm/kvm-cpu.h
+++ b/tools/kvm/include/kvm/kvm-cpu.h
@@ -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);
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index 884a89f..c9fbc81 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -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);
 	}
 
diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
index a0d10cc..665d742 100644
--- a/tools/kvm/x86/kvm-cpu.c
+++ b/tools/kvm/x86/kvm-cpu.c
@@ -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",

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

* Re: [PATCH 01/28] kvm tools: Split x86 arch-specific bits into x86/
  2011-12-06  3:37   ` Matt Evans
@ 2011-12-06  8:07     ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:07 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:37 +1100, Matt Evans wrote:
> 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.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  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%)
> 
> diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
> index bb5f6b0..243886e 100644
> --- a/tools/kvm/Makefile
> +++ b/tools/kvm/Makefile
> @@ -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)
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index 33de4f6..9148d83 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -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);
> diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
> index 5b857dd..61a70ec 100644
> --- a/tools/kvm/include/kvm/ioport.h
> +++ b/tools/kvm/include/kvm/ioport.h
> @@ -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);
>  
> diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
> index 01540ac..719e286 100644
> --- a/tools/kvm/include/kvm/kvm-cpu.h
> +++ b/tools/kvm/include/kvm/kvm-cpu.h
> @@ -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);
> diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
> index 2b3024a..ca1acc0 100644
> --- a/tools/kvm/include/kvm/kvm.h
> +++ b/tools/kvm/include/kvm/kvm.h
> @@ -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 */
> diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c
> index 7cbc44e..965cfc2 100644
> --- a/tools/kvm/ioport.c
> +++ b/tools/kvm/ioport.c
> @@ -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);
> -}
> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
> index 0ad6f3b..5aba3bb 100644
> --- a/tools/kvm/kvm-cpu.c
> +++ b/tools/kvm/kvm-cpu.c
> @@ -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)
> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
> index 252bd18..7ce1640 100644
> --- a/tools/kvm/kvm.c
> +++ b/tools/kvm/kvm.c
> @@ -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;
> diff --git a/tools/kvm/bios.c b/tools/kvm/x86/bios.c
> similarity index 100%
> rename from tools/kvm/bios.c
> rename to tools/kvm/x86/bios.c
> diff --git a/tools/kvm/bios/.gitignore b/tools/kvm/x86/bios/.gitignore
> similarity index 100%
> rename from tools/kvm/bios/.gitignore
> rename to tools/kvm/x86/bios/.gitignore
> diff --git a/tools/kvm/bios/bios-rom.S b/tools/kvm/x86/bios/bios-rom.S
> similarity index 80%
> rename from tools/kvm/bios/bios-rom.S
> rename to tools/kvm/x86/bios/bios-rom.S
> index dc52b1e..3269ce9 100644
> --- a/tools/kvm/bios/bios-rom.S
> +++ b/tools/kvm/x86/bios/bios-rom.S
> @@ -8,5 +8,5 @@
>  #endif
>  
>  GLOBAL(bios_rom)
> -	.incbin "bios/bios.bin"
> +	.incbin "x86/bios/bios.bin"
>  END(bios_rom)
> diff --git a/tools/kvm/bios/e820.c b/tools/kvm/x86/bios/e820.c
> similarity index 100%
> rename from tools/kvm/bios/e820.c
> rename to tools/kvm/x86/bios/e820.c
> diff --git a/tools/kvm/bios/entry.S b/tools/kvm/x86/bios/entry.S
> similarity index 100%
> rename from tools/kvm/bios/entry.S
> rename to tools/kvm/x86/bios/entry.S
> diff --git a/tools/kvm/bios/gen-offsets.sh b/tools/kvm/x86/bios/gen-offsets.sh
> similarity index 100%
> rename from tools/kvm/bios/gen-offsets.sh
> rename to tools/kvm/x86/bios/gen-offsets.sh
> diff --git a/tools/kvm/bios/int10.c b/tools/kvm/x86/bios/int10.c
> similarity index 100%
> rename from tools/kvm/bios/int10.c
> rename to tools/kvm/x86/bios/int10.c
> diff --git a/tools/kvm/bios/int15.c b/tools/kvm/x86/bios/int15.c
> similarity index 100%
> rename from tools/kvm/bios/int15.c
> rename to tools/kvm/x86/bios/int15.c
> diff --git a/tools/kvm/bios/local.S b/tools/kvm/x86/bios/local.S
> similarity index 100%
> rename from tools/kvm/bios/local.S
> rename to tools/kvm/x86/bios/local.S
> diff --git a/tools/kvm/bios/macro.S b/tools/kvm/x86/bios/macro.S
> similarity index 100%
> rename from tools/kvm/bios/macro.S
> rename to tools/kvm/x86/bios/macro.S
> diff --git a/tools/kvm/bios/memcpy.c b/tools/kvm/x86/bios/memcpy.c
> similarity index 100%
> rename from tools/kvm/bios/memcpy.c
> rename to tools/kvm/x86/bios/memcpy.c
> diff --git a/tools/kvm/bios/rom.ld.S b/tools/kvm/x86/bios/rom.ld.S
> similarity index 100%
> rename from tools/kvm/bios/rom.ld.S
> rename to tools/kvm/x86/bios/rom.ld.S
> diff --git a/tools/kvm/cpuid.c b/tools/kvm/x86/cpuid.c
> similarity index 100%
> rename from tools/kvm/cpuid.c
> rename to tools/kvm/x86/cpuid.c
> diff --git a/tools/kvm/include/kvm/assembly.h b/tools/kvm/x86/include/kvm/assembly.h
> similarity index 100%
> rename from tools/kvm/include/kvm/assembly.h
> rename to tools/kvm/x86/include/kvm/assembly.h
> diff --git a/tools/kvm/include/kvm/barrier.h b/tools/kvm/x86/include/kvm/barrier.h
> similarity index 100%
> rename from tools/kvm/include/kvm/barrier.h
> rename to tools/kvm/x86/include/kvm/barrier.h
> diff --git a/tools/kvm/include/kvm/bios-export.h b/tools/kvm/x86/include/kvm/bios-export.h
> similarity index 100%
> rename from tools/kvm/include/kvm/bios-export.h
> rename to tools/kvm/x86/include/kvm/bios-export.h
> diff --git a/tools/kvm/include/kvm/bios.h b/tools/kvm/x86/include/kvm/bios.h
> similarity index 100%
> rename from tools/kvm/include/kvm/bios.h
> rename to tools/kvm/x86/include/kvm/bios.h
> diff --git a/tools/kvm/include/kvm/boot-protocol.h b/tools/kvm/x86/include/kvm/boot-protocol.h
> similarity index 100%
> rename from tools/kvm/include/kvm/boot-protocol.h
> rename to tools/kvm/x86/include/kvm/boot-protocol.h
> diff --git a/tools/kvm/include/kvm/cpufeature.h b/tools/kvm/x86/include/kvm/cpufeature.h
> similarity index 100%
> rename from tools/kvm/include/kvm/cpufeature.h
> rename to tools/kvm/x86/include/kvm/cpufeature.h
> diff --git a/tools/kvm/include/kvm/interrupt.h b/tools/kvm/x86/include/kvm/interrupt.h
> similarity index 100%
> rename from tools/kvm/include/kvm/interrupt.h
> rename to tools/kvm/x86/include/kvm/interrupt.h
> diff --git a/tools/kvm/x86/include/kvm/kvm-arch.h b/tools/kvm/x86/include/kvm/kvm-arch.h
> new file mode 100644
> index 0000000..02aa8b9
> --- /dev/null
> +++ b/tools/kvm/x86/include/kvm/kvm-arch.h
> @@ -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 */
> diff --git a/tools/kvm/x86/include/kvm/kvm-cpu-arch.h b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
> new file mode 100644
> index 0000000..ed1c727
> --- /dev/null
> +++ b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
> @@ -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 */
> diff --git a/tools/kvm/include/kvm/mptable.h b/tools/kvm/x86/include/kvm/mptable.h
> similarity index 100%
> rename from tools/kvm/include/kvm/mptable.h
> rename to tools/kvm/x86/include/kvm/mptable.h
> diff --git a/tools/kvm/interrupt.c b/tools/kvm/x86/interrupt.c
> similarity index 100%
> rename from tools/kvm/interrupt.c
> rename to tools/kvm/x86/interrupt.c
> diff --git a/tools/kvm/x86/ioport.c b/tools/kvm/x86/ioport.c
> new file mode 100644
> index 0000000..8a91bf2
> --- /dev/null
> +++ b/tools/kvm/x86/ioport.c
> @@ -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);
> +}
> diff --git a/tools/kvm/irq.c b/tools/kvm/x86/irq.c
> similarity index 100%
> rename from tools/kvm/irq.c
> rename to tools/kvm/x86/irq.c
> diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
> new file mode 100644
> index 0000000..b26b208
> --- /dev/null
> +++ b/tools/kvm/x86/kvm-cpu.c
> @@ -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);
> +}
> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
> new file mode 100644
> index 0000000..ac6c91e
> --- /dev/null
> +++ b/tools/kvm/x86/kvm.c
> @@ -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);
> +}
> diff --git a/tools/kvm/mptable.c b/tools/kvm/x86/mptable.c
> 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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.

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

* Re: [PATCH 01/28] kvm tools: Split x86 arch-specific bits into x86/
@ 2011-12-06  8:07     ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:07 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:37 +1100, Matt Evans wrote:
> 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.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  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%)
> 
> diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
> index bb5f6b0..243886e 100644
> --- a/tools/kvm/Makefile
> +++ b/tools/kvm/Makefile
> @@ -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_BITSd
>  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)
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index 33de4f6..9148d83 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -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);
> diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
> index 5b857dd..61a70ec 100644
> --- a/tools/kvm/include/kvm/ioport.h
> +++ b/tools/kvm/include/kvm/ioport.h
> @@ -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);
>  
> diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
> index 01540ac..719e286 100644
> --- a/tools/kvm/include/kvm/kvm-cpu.h
> +++ b/tools/kvm/include/kvm/kvm-cpu.h
> @@ -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);
> diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
> index 2b3024a..ca1acc0 100644
> --- a/tools/kvm/include/kvm/kvm.h
> +++ b/tools/kvm/include/kvm/kvm.h
> @@ -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 */
> diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c
> index 7cbc44e..965cfc2 100644
> --- a/tools/kvm/ioport.c
> +++ b/tools/kvm/ioport.c
> @@ -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);
> -}
> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
> index 0ad6f3b..5aba3bb 100644
> --- a/tools/kvm/kvm-cpu.c
> +++ b/tools/kvm/kvm-cpu.c
> @@ -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)
> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
> index 252bd18..7ce1640 100644
> --- a/tools/kvm/kvm.c
> +++ b/tools/kvm/kvm.c
> @@ -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;
> diff --git a/tools/kvm/bios.c b/tools/kvm/x86/bios.c
> similarity index 100%
> rename from tools/kvm/bios.c
> rename to tools/kvm/x86/bios.c
> diff --git a/tools/kvm/bios/.gitignore b/tools/kvm/x86/bios/.gitignore
> similarity index 100%
> rename from tools/kvm/bios/.gitignore
> rename to tools/kvm/x86/bios/.gitignore
> diff --git a/tools/kvm/bios/bios-rom.S b/tools/kvm/x86/bios/bios-rom.S
> similarity index 80%
> rename from tools/kvm/bios/bios-rom.S
> rename to tools/kvm/x86/bios/bios-rom.S
> index dc52b1e..3269ce9 100644
> --- a/tools/kvm/bios/bios-rom.S
> +++ b/tools/kvm/x86/bios/bios-rom.S
> @@ -8,5 +8,5 @@
>  #endif
>  
>  GLOBAL(bios_rom)
> -	.incbin "bios/bios.bin"
> +	.incbin "x86/bios/bios.bin"
>  END(bios_rom)
> diff --git a/tools/kvm/bios/e820.c b/tools/kvm/x86/bios/e820.c
> similarity index 100%
> rename from tools/kvm/bios/e820.c
> rename to tools/kvm/x86/bios/e820.c
> diff --git a/tools/kvm/bios/entry.S b/tools/kvm/x86/bios/entry.S
> similarity index 100%
> rename from tools/kvm/bios/entry.S
> rename to tools/kvm/x86/bios/entry.S
> diff --git a/tools/kvm/bios/gen-offsets.sh b/tools/kvm/x86/bios/gen-offsets.sh
> similarity index 100%
> rename from tools/kvm/bios/gen-offsets.sh
> rename to tools/kvm/x86/bios/gen-offsets.sh
> diff --git a/tools/kvm/bios/int10.c b/tools/kvm/x86/bios/int10.c
> similarity index 100%
> rename from tools/kvm/bios/int10.c
> rename to tools/kvm/x86/bios/int10.c
> diff --git a/tools/kvm/bios/int15.c b/tools/kvm/x86/bios/int15.c
> similarity index 100%
> rename from tools/kvm/bios/int15.c
> rename to tools/kvm/x86/bios/int15.c
> diff --git a/tools/kvm/bios/local.S b/tools/kvm/x86/bios/local.S
> similarity index 100%
> rename from tools/kvm/bios/local.S
> rename to tools/kvm/x86/bios/local.S
> diff --git a/tools/kvm/bios/macro.S b/tools/kvm/x86/bios/macro.S
> similarity index 100%
> rename from tools/kvm/bios/macro.S
> rename to tools/kvm/x86/bios/macro.S
> diff --git a/tools/kvm/bios/memcpy.c b/tools/kvm/x86/bios/memcpy.c
> similarity index 100%
> rename from tools/kvm/bios/memcpy.c
> rename to tools/kvm/x86/bios/memcpy.c
> diff --git a/tools/kvm/bios/rom.ld.S b/tools/kvm/x86/bios/rom.ld.S
> similarity index 100%
> rename from tools/kvm/bios/rom.ld.S
> rename to tools/kvm/x86/bios/rom.ld.S
> diff --git a/tools/kvm/cpuid.c b/tools/kvm/x86/cpuid.c
> similarity index 100%
> rename from tools/kvm/cpuid.c
> rename to tools/kvm/x86/cpuid.c
> diff --git a/tools/kvm/include/kvm/assembly.h b/tools/kvm/x86/include/kvm/assembly.h
> similarity index 100%
> rename from tools/kvm/include/kvm/assembly.h
> rename to tools/kvm/x86/include/kvm/assembly.h
> diff --git a/tools/kvm/include/kvm/barrier.h b/tools/kvm/x86/include/kvm/barrier.h
> similarity index 100%
> rename from tools/kvm/include/kvm/barrier.h
> rename to tools/kvm/x86/include/kvm/barrier.h
> diff --git a/tools/kvm/include/kvm/bios-export.h b/tools/kvm/x86/include/kvm/bios-export.h
> similarity index 100%
> rename from tools/kvm/include/kvm/bios-export.h
> rename to tools/kvm/x86/include/kvm/bios-export.h
> diff --git a/tools/kvm/include/kvm/bios.h b/tools/kvm/x86/include/kvm/bios.h
> similarity index 100%
> rename from tools/kvm/include/kvm/bios.h
> rename to tools/kvm/x86/include/kvm/bios.h
> diff --git a/tools/kvm/include/kvm/boot-protocol.h b/tools/kvm/x86/include/kvm/boot-protocol.h
> similarity index 100%
> rename from tools/kvm/include/kvm/boot-protocol.h
> rename to tools/kvm/x86/include/kvm/boot-protocol.h
> diff --git a/tools/kvm/include/kvm/cpufeature.h b/tools/kvm/x86/include/kvm/cpufeature.h
> similarity index 100%
> rename from tools/kvm/include/kvm/cpufeature.h
> rename to tools/kvm/x86/include/kvm/cpufeature.h
> diff --git a/tools/kvm/include/kvm/interrupt.h b/tools/kvm/x86/include/kvm/interrupt.h
> similarity index 100%
> rename from tools/kvm/include/kvm/interrupt.h
> rename to tools/kvm/x86/include/kvm/interrupt.h
> diff --git a/tools/kvm/x86/include/kvm/kvm-arch.h b/tools/kvm/x86/include/kvm/kvm-arch.h
> new file mode 100644
> index 0000000..02aa8b9
> --- /dev/null
> +++ b/tools/kvm/x86/include/kvm/kvm-arch.h
> @@ -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 */
> diff --git a/tools/kvm/x86/include/kvm/kvm-cpu-arch.h b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
> new file mode 100644
> index 0000000..ed1c727
> --- /dev/null
> +++ b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
> @@ -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 */
> diff --git a/tools/kvm/include/kvm/mptable.h b/tools/kvm/x86/include/kvm/mptable.h
> similarity index 100%
> rename from tools/kvm/include/kvm/mptable.h
> rename to tools/kvm/x86/include/kvm/mptable.h
> diff --git a/tools/kvm/interrupt.c b/tools/kvm/x86/interrupt.c
> similarity index 100%
> rename from tools/kvm/interrupt.c
> rename to tools/kvm/x86/interrupt.c
> diff --git a/tools/kvm/x86/ioport.c b/tools/kvm/x86/ioport.c
> new file mode 100644
> index 0000000..8a91bf2
> --- /dev/null
> +++ b/tools/kvm/x86/ioport.c
> @@ -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);
> +}
> diff --git a/tools/kvm/irq.c b/tools/kvm/x86/irq.c
> similarity index 100%
> rename from tools/kvm/irq.c
> rename to tools/kvm/x86/irq.c
> diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
> new file mode 100644
> index 0000000..b26b208
> --- /dev/null
> +++ b/tools/kvm/x86/kvm-cpu.c
> @@ -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);
> +}
> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
> new file mode 100644
> index 0000000..ac6c91e
> --- /dev/null
> +++ b/tools/kvm/x86/kvm.c
> @@ -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);
> +}
> diff --git a/tools/kvm/mptable.c b/tools/kvm/x86/mptable.c
> 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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86
  2011-12-06  3:37   ` Matt Evans
@ 2011-12-06  8:11     ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:11 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:37 +1100, Matt Evans wrote:
> Not every architecture has an i8042 kbd controller, so only use this when
> building for x86.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/Makefile      |    2 +-
>  tools/kvm/builtin-run.c |    2 ++
>  2 files changed, 3 insertions(+), 1 deletions(-)
> 
> diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
> index 243886e..f58a1d8 100644
> --- a/tools/kvm/Makefile
> +++ b/tools/kvm/Makefile
> @@ -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
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index 9148d83..e4aa87e 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.

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

* Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86
@ 2011-12-06  8:11     ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:11 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:37 +1100, Matt Evans wrote:
> Not every architecture has an i8042 kbd controller, so only use this when
> building for x86.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/Makefile      |    2 +-
>  tools/kvm/builtin-run.c |    2 ++
>  2 files changed, 3 insertions(+), 1 deletions(-)
> 
> diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
> index 243886e..f58a1d8 100644
> --- a/tools/kvm/Makefile
> +++ b/tools/kvm/Makefile
> @@ -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
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index 9148d83..e4aa87e 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-06  3:38   ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
@ 2011-12-06  8:13     ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:13 UTC (permalink / raw)
  To: Matt Evans, Ingo Molnar; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:38 +1100, Matt Evans wrote:
> 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.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  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(-)
> 
> diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
> index 009a6ba..57dc521 100644
> --- a/tools/kvm/Makefile
> +++ b/tools/kvm/Makefile
> @@ -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    " $@
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index e4aa87e..7cf208d 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -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))
> diff --git a/tools/kvm/builtin-stat.c b/tools/kvm/builtin-stat.c
> index e28eb5b..c1f2605 100644
> --- a/tools/kvm/builtin-stat.c
> +++ b/tools/kvm/builtin-stat.c
> @@ -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");
>  
> diff --git a/tools/kvm/disk/core.c b/tools/kvm/disk/core.c
> index 4915efd..a135851 100644
> --- a/tools/kvm/disk/core.c
> +++ b/tools/kvm/disk/core.c
> @@ -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;
>  }
>  
> diff --git a/tools/kvm/mmio.c b/tools/kvm/mmio.c
> index de7320f..1158bff 100644
> --- a/tools/kvm/mmio.c
> +++ b/tools/kvm/mmio.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when
@ 2011-12-06  8:13     ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:13 UTC (permalink / raw)
  To: Matt Evans, Ingo Molnar; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:38 +1100, Matt Evans wrote:
> 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.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  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(-)
> 
> diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
> index 009a6ba..57dc521 100644
> --- a/tools/kvm/Makefile
> +++ b/tools/kvm/Makefile
> @@ -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    " $@
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index e4aa87e..7cf208d 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -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))
> diff --git a/tools/kvm/builtin-stat.c b/tools/kvm/builtin-stat.c
> index e28eb5b..c1f2605 100644
> --- a/tools/kvm/builtin-stat.c
> +++ b/tools/kvm/builtin-stat.c
> @@ -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");
>  
> diff --git a/tools/kvm/disk/core.c b/tools/kvm/disk/core.c
> index 4915efd..a135851 100644
> --- a/tools/kvm/disk/core.c
> +++ b/tools/kvm/disk/core.c
> @@ -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;
>  }
>  
> diff --git a/tools/kvm/mmio.c b/tools/kvm/mmio.c
> index de7320f..1158bff 100644
> --- a/tools/kvm/mmio.c
> +++ b/tools/kvm/mmio.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-06  3:39   ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Matt Evans
@ 2011-12-06  8:20     ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:20 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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.

On Tue, 2011-12-06 at 14:39 +1100, Matt Evans wrote:
> Architectures can recommend/count/determine number of CPUs differently, so move
> this out of generic code.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/kvm.c     |   30 ------------------------------
>  tools/kvm/x86/kvm.c |   30 ++++++++++++++++++++++++++++++
>  2 files changed, 30 insertions(+), 30 deletions(-)
> 
> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
> index 7ce1640..e526483 100644
> --- a/tools/kvm/kvm.c
> +++ b/tools/kvm/kvm.c
> @@ -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;
> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
> index ac6c91e..75e4a52 100644
> --- a/tools/kvm/x86/kvm.c
> +++ b/tools/kvm/x86/kvm.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to
@ 2011-12-06  8:20     ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:20 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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.

On Tue, 2011-12-06 at 14:39 +1100, Matt Evans wrote:
> Architectures can recommend/count/determine number of CPUs differently, so move
> this out of generic code.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/kvm.c     |   30 ------------------------------
>  tools/kvm/x86/kvm.c |   30 ++++++++++++++++++++++++++++++
>  2 files changed, 30 insertions(+), 30 deletions(-)
> 
> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
> index 7ce1640..e526483 100644
> --- a/tools/kvm/kvm.c
> +++ b/tools/kvm/kvm.c
> @@ -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;
> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
> index ac6c91e..75e4a52 100644
> --- a/tools/kvm/x86/kvm.c
> +++ b/tools/kvm/x86/kvm.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-06  3:39   ` Matt Evans
@ 2011-12-06  8:22     ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:22 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:39 +1100, Matt Evans wrote:
> 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.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/kvm-cpu.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
> index 9bc0796..884a89f 100644
> --- a/tools/kvm/kvm-cpu.c
> +++ b/tools/kvm/kvm-cpu.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-06  8:22     ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:22 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:39 +1100, Matt Evans wrote:
> 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.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/kvm-cpu.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
> index 9bc0796..884a89f 100644
> --- a/tools/kvm/kvm-cpu.c
> +++ b/tools/kvm/kvm-cpu.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 17/28] kvm tools: Only call symbol__init() if we have BFD
  2011-12-06  3:41   ` Matt Evans
@ 2011-12-06  8:26     ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:26 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:41 +1100, Matt Evans wrote:
> CONFIG_HAS_BFD is optional, symbol.c inclusion is optional -- so make its init
> call dependent on CONFIG_HAS_BFD.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/builtin-run.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index 1257c90..aaa5132 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.

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

* Re: [PATCH 17/28] kvm tools: Only call symbol__init() if we have BFD
@ 2011-12-06  8:26     ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:26 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:41 +1100, Matt Evans wrote:
> CONFIG_HAS_BFD is optional, symbol.c inclusion is optional -- so make its init
> call dependent on CONFIG_HAS_BFD.
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/builtin-run.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index 1257c90..aaa5132 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-06  8:13     ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when Sasha Levin
@ 2011-12-06  8:28       ` Ingo Molnar
  -1 siblings, 0 replies; 210+ messages in thread
From: Ingo Molnar @ 2011-12-06  8:28 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, kvm, kvm-ppc, Pekka Enberg


* Sasha Levin <levinsasha928@gmail.com> wrote:

> 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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-06  8:28       ` Ingo Molnar
  0 siblings, 0 replies; 210+ messages in thread
From: Ingo Molnar @ 2011-12-06  8:28 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, kvm, kvm-ppc, Pekka Enberg


* Sasha Levin <levinsasha928@gmail.com> wrote:

> 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

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

* Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path
  2011-12-06  3:41   ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory Matt Evans
@ 2011-12-06  8:32     ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:32 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:41 +1100, Matt Evans wrote:
> 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().
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  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(-)
> 
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index 84aa931..4c88169 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -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;
>  
> diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
> index 5fe6e75..7159952 100644
> --- a/tools/kvm/include/kvm/kvm.h
> +++ b/tools/kvm/include/kvm/kvm.h
> @@ -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);
> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
> index 6f33e1a..503ceae 100644
> --- a/tools/kvm/kvm.c
> +++ b/tools/kvm/kvm.c
> @@ -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;
>  
> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
> index 4ac21c0..76f805f 100644
> --- a/tools/kvm/x86/kvm.c
> +++ b/tools/kvm/x86/kvm.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify
@ 2011-12-06  8:32     ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:32 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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?

On Tue, 2011-12-06 at 14:41 +1100, Matt Evans wrote:
> 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().
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  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(-)
> 
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index 84aa931..4c88169 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -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;
>  
> diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
> index 5fe6e75..7159952 100644
> --- a/tools/kvm/include/kvm/kvm.h
> +++ b/tools/kvm/include/kvm/kvm.h
> @@ -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);
> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
> index 6f33e1a..503ceae 100644
> --- a/tools/kvm/kvm.c
> +++ b/tools/kvm/kvm.c
> @@ -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;
>  
> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
> index 4ac21c0..76f805f 100644
> --- a/tools/kvm/x86/kvm.c
> +++ b/tools/kvm/x86/kvm.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io()
  2011-12-06  3:43   ` Matt Evans
@ 2011-12-06  8:54     ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:54 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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'?

On Tue, 2011-12-06 at 14:43 +1100, Matt Evans wrote:
> 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
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  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(-)
> 
> diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
> index 15618f1..6f38c0c 100644
> --- a/tools/kvm/include/kvm/kvm-cpu.h
> +++ b/tools/kvm/include/kvm/kvm-cpu.h
> @@ -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);
> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
> index 884a89f..c9fbc81 100644
> --- a/tools/kvm/kvm-cpu.c
> +++ b/tools/kvm/kvm-cpu.c
> @@ -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);
>  	}
>  
> diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
> index a0d10cc..665d742 100644
> --- a/tools/kvm/x86/kvm-cpu.c
> +++ b/tools/kvm/x86/kvm-cpu.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 28/28] kvm tools: Create arch-specific
@ 2011-12-06  8:54     ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06  8:54 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

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'?

On Tue, 2011-12-06 at 14:43 +1100, Matt Evans wrote:
> 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
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  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(-)
> 
> diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
> index 15618f1..6f38c0c 100644
> --- a/tools/kvm/include/kvm/kvm-cpu.h
> +++ b/tools/kvm/include/kvm/kvm-cpu.h
> @@ -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);
> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
> index 884a89f..c9fbc81 100644
> --- a/tools/kvm/kvm-cpu.c
> +++ b/tools/kvm/kvm-cpu.c
> @@ -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);
>  	}
>  
> diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
> index a0d10cc..665d742 100644
> --- a/tools/kvm/x86/kvm-cpu.c
> +++ b/tools/kvm/x86/kvm-cpu.c
> @@ -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 majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 

Sasha.


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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-06  8:28       ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
@ 2011-12-06 10:05         ` Paul Mackerras
  -1 siblings, 0 replies; 210+ messages in thread
From: Paul Mackerras @ 2011-12-06 10:05 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Sasha Levin, Matt Evans, kvm, kvm-ppc, Pekka Enberg

On Tue, Dec 06, 2011 at 09:28:27AM +0100, Ingo Molnar wrote:
> 
> * Sasha Levin <levinsasha928@gmail.com> wrote:
> 
> > 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.

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.

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-06 10:05         ` Paul Mackerras
  0 siblings, 0 replies; 210+ messages in thread
From: Paul Mackerras @ 2011-12-06 10:05 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Sasha Levin, Matt Evans, kvm, kvm-ppc, Pekka Enberg

On Tue, Dec 06, 2011 at 09:28:27AM +0100, Ingo Molnar wrote:
> 
> * Sasha Levin <levinsasha928@gmail.com> wrote:
> 
> > 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.

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.

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

* Re: [PATCH 01/28] kvm tools: Split x86 arch-specific bits into x86/
  2011-12-06  8:07     ` Sasha Levin
@ 2011-12-06 10:10       ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:10 UTC (permalink / raw)
  To: Sasha Levin
  Cc: Matt Evans, kvm, kvm-ppc, Ingo Molnar, Asias He, Cyrill Gorcunov

On Tue, Dec 6, 2011 at 10:07 AM, Sasha Levin <levinsasha928@gmail.com> wrote:
> 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!

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

* Re: [PATCH 01/28] kvm tools: Split x86 arch-specific bits into x86/
@ 2011-12-06 10:10       ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:10 UTC (permalink / raw)
  To: Sasha Levin
  Cc: Matt Evans, kvm, kvm-ppc, Ingo Molnar, Asias He, Cyrill Gorcunov

On Tue, Dec 6, 2011 at 10:07 AM, Sasha Levin <levinsasha928@gmail.com> wrote:
> 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!

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-06 10:05         ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Paul Mackerras
@ 2011-12-06 10:24           ` Ingo Molnar
  -1 siblings, 0 replies; 210+ messages in thread
From: Ingo Molnar @ 2011-12-06 10:24 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Sasha Levin, Matt Evans, kvm, kvm-ppc, Pekka Enberg


* Paul Mackerras <paulus@samba.org> wrote:

> On Tue, Dec 06, 2011 at 09:28:27AM +0100, Ingo Molnar wrote:
> > 
> > * Sasha Levin <levinsasha928@gmail.com> wrote:
> > 
> > > 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.
> 
> 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!

> [...]  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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-06 10:24           ` Ingo Molnar
  0 siblings, 0 replies; 210+ messages in thread
From: Ingo Molnar @ 2011-12-06 10:24 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Sasha Levin, Matt Evans, kvm, kvm-ppc, Pekka Enberg


* Paul Mackerras <paulus@samba.org> wrote:

> On Tue, Dec 06, 2011 at 09:28:27AM +0100, Ingo Molnar wrote:
> > 
> > * Sasha Levin <levinsasha928@gmail.com> wrote:
> > 
> > > 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.
> 
> 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!

> [...]  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

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

* Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs
  2011-12-06  3:40   ` [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian Matt Evans
@ 2011-12-06 10:24     ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:24 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 6, 2011 at 5:40 AM, Matt Evans <matt@ozlabs.org> wrote:
> 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.
>
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/term.c |    5 ++---
>  1 files changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/tools/kvm/term.c b/tools/kvm/term.c
> index fb5d71c..440884e 100644
> --- a/tools/kvm/term.c
> +++ b/tools/kvm/term.c
> @@ -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);
>  }

Looks OK to me. Asias?

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

* Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs
@ 2011-12-06 10:24     ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:24 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 6, 2011 at 5:40 AM, Matt Evans <matt@ozlabs.org> wrote:
> 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.
>
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/term.c |    5 ++---
>  1 files changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/tools/kvm/term.c b/tools/kvm/term.c
> index fb5d71c..440884e 100644
> --- a/tools/kvm/term.c
> +++ b/tools/kvm/term.c
> @@ -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);
>  }

Looks OK to me. Asias?

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
  2011-12-06  3:42   ` Matt Evans
@ 2011-12-06 10:25     ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:25 UTC (permalink / raw)
  To: Matt Evans
  Cc: kvm, kvm-ppc, Asias He, Sasha Levin, Cyrill Gorcunov, Ingo Molnar

On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> 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.
>
> Signed-off-by: Matt Evans <matt@ozlabs.org>

Looks OK to me. Sasha, Cyrill?

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
@ 2011-12-06 10:25     ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:25 UTC (permalink / raw)
  To: Matt Evans
  Cc: kvm, kvm-ppc, Asias He, Sasha Levin, Cyrill Gorcunov, Ingo Molnar

On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> 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.
>
> Signed-off-by: Matt Evans <matt@ozlabs.org>

Looks OK to me. Sasha, Cyrill?

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

* Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
  2011-12-06  3:42   ` Matt Evans
@ 2011-12-06 10:26     ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:26 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> The field size is currently wrong, read into a 32bit word instead of 16.  This
> casues trouble when BE.
>
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/virtio/pci.c |    3 +--
>  1 files changed, 1 insertions(+), 2 deletions(-)
>
> diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
> index 0ae93fb..6b27ff8 100644
> --- a/tools/kvm/virtio/pci.c
> +++ b/tools/kvm/virtio/pci.c
> @@ -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?

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

* Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
@ 2011-12-06 10:26     ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:26 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> The field size is currently wrong, read into a 32bit word instead of 16.  This
> casues trouble when BE.
>
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/virtio/pci.c |    3 +--
>  1 files changed, 1 insertions(+), 2 deletions(-)
>
> diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
> index 0ae93fb..6b27ff8 100644
> --- a/tools/kvm/virtio/pci.c
> +++ b/tools/kvm/virtio/pci.c
> @@ -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?

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

* Re: [PATCH 15/28] kvm tools: Allow initrd_check() to match a cpio
  2011-12-06  3:40   ` Matt Evans
@ 2011-12-06 10:26     ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:26 UTC (permalink / raw)
  To: Matt Evans
  Cc: kvm, kvm-ppc, Sasha Levin, Asias He, Cyrill Gorcunov, Ingo Molnar

On Tue, Dec 6, 2011 at 5:40 AM, Matt Evans <matt@ozlabs.org> wrote:
> cpios are valid as initrds too, so allow them through the check.
>
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/kvm.c |    8 +++++---
>  1 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
> index 33243f1..457de1a 100644
> --- a/tools/kvm/kvm.c
> +++ b/tools/kvm/kvm.c
> @@ -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,

Looks good to me.

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

* Re: [PATCH 15/28] kvm tools: Allow initrd_check() to match a cpio
@ 2011-12-06 10:26     ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:26 UTC (permalink / raw)
  To: Matt Evans
  Cc: kvm, kvm-ppc, Sasha Levin, Asias He, Cyrill Gorcunov, Ingo Molnar

On Tue, Dec 6, 2011 at 5:40 AM, Matt Evans <matt@ozlabs.org> wrote:
> cpios are valid as initrds too, so allow them through the check.
>
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  tools/kvm/kvm.c |    8 +++++---
>  1 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
> index 33243f1..457de1a 100644
> --- a/tools/kvm/kvm.c
> +++ b/tools/kvm/kvm.c
> @@ -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,

Looks good to me.

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
  2011-12-06 10:25     ` Pekka Enberg
@ 2011-12-06 10:28       ` Cyrill Gorcunov
  -1 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-06 10:28 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> > 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.
> >
> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> 
> Looks OK to me. Sasha, Cyrill?
> 

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

	Cyrill

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device
@ 2011-12-06 10:28       ` Cyrill Gorcunov
  0 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-06 10:28 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> > 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.
> >
> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> 
> Looks OK to me. Sasha, Cyrill?
> 

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

	Cyrill

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

* Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside
  2011-12-06  3:41   ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd Matt Evans
@ 2011-12-06 10:29     ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:29 UTC (permalink / raw)
  To: Matt Evans
  Cc: kvm, kvm-ppc, Asias He, Cyrill Gorcunov, Ingo Molnar, Sasha Levin

On Tue, Dec 6, 2011 at 5:41 AM, Matt Evans <matt@ozlabs.org> wrote:
> 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. :-)
>
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  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(-)
>
> diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
> index fae2ba9..5fe6e75 100644
> --- a/tools/kvm/include/kvm/kvm.h
> +++ b/tools/kvm/include/kvm/kvm.h
> @@ -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);
>
>  /*
> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
> index 457de1a..6f33e1a 100644
> --- a/tools/kvm/kvm.c
> +++ b/tools/kvm/kvm.c
> @@ -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;
> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
> index 7071dc6..4ac21c0 100644
> --- a/tools/kvm/x86/kvm.c
> +++ b/tools/kvm/x86/kvm.c
> @@ -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.
> +        */

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.
        */

> +       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;
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Otherwise looks OK to me. Cyrill?

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

* Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an
@ 2011-12-06 10:29     ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 10:29 UTC (permalink / raw)
  To: Matt Evans
  Cc: kvm, kvm-ppc, Asias He, Cyrill Gorcunov, Ingo Molnar, Sasha Levin

On Tue, Dec 6, 2011 at 5:41 AM, Matt Evans <matt@ozlabs.org> wrote:
> 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. :-)
>
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ---
>  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(-)
>
> diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
> index fae2ba9..5fe6e75 100644
> --- a/tools/kvm/include/kvm/kvm.h
> +++ b/tools/kvm/include/kvm/kvm.h
> @@ -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);
>
>  /*
> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
> index 457de1a..6f33e1a 100644
> --- a/tools/kvm/kvm.c
> +++ b/tools/kvm/kvm.c
> @@ -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;
> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
> index 7071dc6..4ac21c0 100644
> --- a/tools/kvm/x86/kvm.c
> +++ b/tools/kvm/x86/kvm.c
> @@ -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.
> +        */

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.
        */

> +       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;
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Otherwise looks OK to me. Cyrill?

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

* Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
  2011-12-06 10:26     ` Pekka Enberg
@ 2011-12-06 11:28       ` Asias He
  -1 siblings, 0 replies; 210+ messages in thread
From: Asias He @ 2011-12-06 11:28 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Sasha Levin, Ingo Molnar

On 12/06/2011 06:26 PM, Pekka Enberg wrote:
> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
>> The field size is currently wrong, read into a 32bit word instead of 16.  This
>> casues trouble when BE.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/virtio/pci.c |    3 +--
>>  1 files changed, 1 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
>> index 0ae93fb..6b27ff8 100644
>> --- a/tools/kvm/virtio/pci.c
>> +++ b/tools/kvm/virtio/pci.c
>> @@ -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.

-- 
Asias He

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

* Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading
@ 2011-12-06 11:28       ` Asias He
  0 siblings, 0 replies; 210+ messages in thread
From: Asias He @ 2011-12-06 11:28 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Sasha Levin, Ingo Molnar

On 12/06/2011 06:26 PM, Pekka Enberg wrote:
> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
>> The field size is currently wrong, read into a 32bit word instead of 16.  This
>> casues trouble when BE.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/virtio/pci.c |    3 +--
>>  1 files changed, 1 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
>> index 0ae93fb..6b27ff8 100644
>> --- a/tools/kvm/virtio/pci.c
>> +++ b/tools/kvm/virtio/pci.c
>> @@ -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.

-- 
Asias He

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

* Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
  2011-12-06 11:28       ` [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading Asias He
@ 2011-12-06 11:39         ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 11:39 UTC (permalink / raw)
  To: Asias He; +Cc: Matt Evans, kvm, kvm-ppc, Sasha Levin, Ingo Molnar

On Tue, Dec 6, 2011 at 1:28 PM, Asias He <asias.hejun@gmail.com> wrote:
>>> @@ -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.

Applied, thanks!

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

* Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
@ 2011-12-06 11:39         ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 11:39 UTC (permalink / raw)
  To: Asias He; +Cc: Matt Evans, kvm, kvm-ppc, Sasha Levin, Ingo Molnar

On Tue, Dec 6, 2011 at 1:28 PM, Asias He <asias.hejun@gmail.com> wrote:
>>> @@ -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.

Applied, thanks!

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
  2011-12-06 10:28       ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Cyrill Gorcunov
@ 2011-12-06 11:41         ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 11:41 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 6, 2011 at 12:28 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote:
> On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
>> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
>> > 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.
>> >
>> > Signed-off-by: Matt Evans <matt@ozlabs.org>
>>
>> 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: dm-devel@redhat.com
[    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.

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
@ 2011-12-06 11:41         ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 11:41 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 6, 2011 at 12:28 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote:
> On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
>> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
>> > 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.
>> >
>> > Signed-off-by: Matt Evans <matt@ozlabs.org>
>>
>> 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\x15, HWalignd, 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&91682)
[    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 00 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: dm-devel@redhat.com
[    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.

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
  2011-12-06 11:41         ` Pekka Enberg
@ 2011-12-06 11:47           ` Cyrill Gorcunov
  -1 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-06 11:47 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 06, 2011 at 01:41:56PM +0200, Pekka Enberg wrote:
> On Tue, Dec 6, 2011 at 12:28 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote:
> > On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
> >> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> >> > 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.
> >> >
> >> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> >>
> >> 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

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device
@ 2011-12-06 11:47           ` Cyrill Gorcunov
  0 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-06 11:47 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 06, 2011 at 01:41:56PM +0200, Pekka Enberg wrote:
> On Tue, Dec 6, 2011 at 12:28 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote:
> > On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
> >> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> >> > 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.
> >> >
> >> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> >>
> >> 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

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
  2011-12-06 11:47           ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Cyrill Gorcunov
@ 2011-12-06 11:58             ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 11:58 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, 2011-12-06 at 15:47 +0400, Cyrill Gorcunov wrote:
> On Tue, Dec 06, 2011 at 01:41:56PM +0200, Pekka Enberg wrote:
> > On Tue, Dec 6, 2011 at 12:28 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote:
> > > On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
> > >> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> > >> > 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.
> > >> >
> > >> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> > >>
> > >> 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?

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

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device
@ 2011-12-06 11:58             ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 11:58 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, 2011-12-06 at 15:47 +0400, Cyrill Gorcunov wrote:
> On Tue, Dec 06, 2011 at 01:41:56PM +0200, Pekka Enberg wrote:
> > On Tue, Dec 6, 2011 at 12:28 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote:
> > > On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
> > >> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> > >> > 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.
> > >> >
> > >> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> > >>
> > >> 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?

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


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

* Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs
  2011-12-06 10:24     ` Pekka Enberg
@ 2011-12-06 12:00       ` Asias He
  -1 siblings, 0 replies; 210+ messages in thread
From: Asias He @ 2011-12-06 12:00 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Sasha Levin, Ingo Molnar

On 12/06/2011 06:24 PM, Pekka Enberg wrote:
> On Tue, Dec 6, 2011 at 5:40 AM, Matt Evans <matt@ozlabs.org> wrote:
>> 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.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/term.c |    5 ++---
>>  1 files changed, 2 insertions(+), 3 deletions(-)
>>
>> diff --git a/tools/kvm/term.c b/tools/kvm/term.c
>> index fb5d71c..440884e 100644
>> --- a/tools/kvm/term.c
>> +++ b/tools/kvm/term.c
>> @@ -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;
>> -

We can drop this line too.

	c &= 0xff;



>>        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);
>>  }
> 
> Looks OK to me. Asias?
> 

Otherwise, looks fine to me.


-- 
Asias He

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

* Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian
@ 2011-12-06 12:00       ` Asias He
  0 siblings, 0 replies; 210+ messages in thread
From: Asias He @ 2011-12-06 12:00 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Sasha Levin, Ingo Molnar

On 12/06/2011 06:24 PM, Pekka Enberg wrote:
> On Tue, Dec 6, 2011 at 5:40 AM, Matt Evans <matt@ozlabs.org> wrote:
>> 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.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/term.c |    5 ++---
>>  1 files changed, 2 insertions(+), 3 deletions(-)
>>
>> diff --git a/tools/kvm/term.c b/tools/kvm/term.c
>> index fb5d71c..440884e 100644
>> --- a/tools/kvm/term.c
>> +++ b/tools/kvm/term.c
>> @@ -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;
>> -

We can drop this line too.

	c &= 0xff;



>>        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);
>>  }
> 
> Looks OK to me. Asias?
> 

Otherwise, looks fine to me.


-- 
Asias He

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

* Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside
  2011-12-06 10:29     ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an Pekka Enberg
@ 2011-12-06 12:04       ` Cyrill Gorcunov
  -1 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-06 12:04 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Ingo Molnar, Sasha Levin

On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
...
> 
> 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

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

* Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an
@ 2011-12-06 12:04       ` Cyrill Gorcunov
  0 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-06 12:04 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Ingo Molnar, Sasha Levin

On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
...
> 
> 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

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
  2011-12-06 11:58             ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Pekka Enberg
@ 2011-12-06 12:10               ` Cyrill Gorcunov
  -1 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-06 12:10 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 06, 2011 at 01:58:24PM +0200, Pekka Enberg wrote:
> On Tue, 2011-12-06 at 15:47 +0400, Cyrill Gorcunov wrote:
> > On Tue, Dec 06, 2011 at 01:41:56PM +0200, Pekka Enberg wrote:
> > > On Tue, Dec 6, 2011 at 12:28 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote:
> > > > On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
> > > >> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> > > >> > 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.
> > > >> >
> > > >> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> > > >>
> > > >> 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?
> 
> 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
> 

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

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device
@ 2011-12-06 12:10               ` Cyrill Gorcunov
  0 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-06 12:10 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 06, 2011 at 01:58:24PM +0200, Pekka Enberg wrote:
> On Tue, 2011-12-06 at 15:47 +0400, Cyrill Gorcunov wrote:
> > On Tue, Dec 06, 2011 at 01:41:56PM +0200, Pekka Enberg wrote:
> > > On Tue, Dec 6, 2011 at 12:28 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote:
> > > > On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
> > > >> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> > > >> > 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.
> > > >> >
> > > >> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> > > >>
> > > >> 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?
> 
> 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
> 

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

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

* Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
  2011-12-06 10:26     ` Pekka Enberg
@ 2011-12-06 13:15       ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06 13:15 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Ingo Molnar

On Tue, 2011-12-06 at 12:26 +0200, Pekka Enberg wrote:
> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> > The field size is currently wrong, read into a 32bit word instead of 16.  This
> > casues trouble when BE.
> >
> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> > ---
> >  tools/kvm/virtio/pci.c |    3 +--
> >  1 files changed, 1 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
> > index 0ae93fb..6b27ff8 100644
> > --- a/tools/kvm/virtio/pci.c
> > +++ b/tools/kvm/virtio/pci.c
> > @@ -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.

-- 

Sasha.

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

* Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading
@ 2011-12-06 13:15       ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-06 13:15 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Ingo Molnar

On Tue, 2011-12-06 at 12:26 +0200, Pekka Enberg wrote:
> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
> > The field size is currently wrong, read into a 32bit word instead of 16.  This
> > casues trouble when BE.
> >
> > Signed-off-by: Matt Evans <matt@ozlabs.org>
> > ---
> >  tools/kvm/virtio/pci.c |    3 +--
> >  1 files changed, 1 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
> > index 0ae93fb..6b27ff8 100644
> > --- a/tools/kvm/virtio/pci.c
> > +++ b/tools/kvm/virtio/pci.c
> > @@ -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.

-- 

Sasha.


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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
  2011-12-06 12:10               ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Cyrill Gorcunov
@ 2011-12-06 13:29                 ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 13:29 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, 6 Dec 2011, Cyrill Gorcunov wrote:
> On Tue, Dec 06, 2011 at 01:58:24PM +0200, Pekka Enberg wrote:
>> On Tue, 2011-12-06 at 15:47 +0400, Cyrill Gorcunov wrote:
>>> On Tue, Dec 06, 2011 at 01:41:56PM +0200, Pekka Enberg wrote:
>>>> On Tue, Dec 6, 2011 at 12:28 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote:
>>>>> On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
>>>>>> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
>>>>>>> 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.
>>>>>>>
>>>>>>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>>>>>>
>>>>>> 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?
>>
>> 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
>>
>
> 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;
> };

Yup, that fixes it for me.

 			Pekka

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device
@ 2011-12-06 13:29                 ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-06 13:29 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, 6 Dec 2011, Cyrill Gorcunov wrote:
> On Tue, Dec 06, 2011 at 01:58:24PM +0200, Pekka Enberg wrote:
>> On Tue, 2011-12-06 at 15:47 +0400, Cyrill Gorcunov wrote:
>>> On Tue, Dec 06, 2011 at 01:41:56PM +0200, Pekka Enberg wrote:
>>>> On Tue, Dec 6, 2011 at 12:28 PM, Cyrill Gorcunov <gorcunov@gmail.com> wrote:
>>>>> On Tue, Dec 06, 2011 at 12:25:29PM +0200, Pekka Enberg wrote:
>>>>>> On Tue, Dec 6, 2011 at 5:42 AM, Matt Evans <matt@ozlabs.org> wrote:
>>>>>>> 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.
>>>>>>>
>>>>>>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>>>>>>
>>>>>> 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?
>>
>> 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
>>
>
> 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;
> };

Yup, that fixes it for me.

 			Pekka

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
  2011-12-06 13:29                 ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Pekka Enberg
@ 2011-12-06 13:38                   ` Cyrill Gorcunov
  -1 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-06 13:38 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 06, 2011 at 03:29:00PM +0200, Pekka Enberg wrote:
> >
> >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;
> >};
> 
> Yup, that fixes it for me.
> 

Good. Matt, mind to update?

	Cyrill

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device
@ 2011-12-06 13:38                   ` Cyrill Gorcunov
  0 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-06 13:38 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Matt Evans, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On Tue, Dec 06, 2011 at 03:29:00PM +0200, Pekka Enberg wrote:
> >
> >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;
> >};
> 
> Yup, that fixes it for me.
> 

Good. Matt, mind to update?

	Cyrill

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

* Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86
  2011-12-06  3:37   ` Matt Evans
@ 2011-12-06 18:59     ` Scott Wood
  -1 siblings, 0 replies; 210+ messages in thread
From: Scott Wood @ 2011-12-06 18:59 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

On 12/05/2011 09:37 PM, Matt Evans wrote:
> 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


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

* Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86
@ 2011-12-06 18:59     ` Scott Wood
  0 siblings, 0 replies; 210+ messages in thread
From: Scott Wood @ 2011-12-06 18:59 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

On 12/05/2011 09:37 PM, Matt Evans wrote:
> 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


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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-06  8:22     ` Sasha Levin
@ 2011-12-07  0:32       ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  0:32 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc, Alexander Graf

On 06/12/11 19:22, Sasha Levin wrote:
> 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


> 
> On Tue, 2011-12-06 at 14:39 +1100, Matt Evans wrote:
>> 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.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/kvm-cpu.c |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
>> index 9bc0796..884a89f 100644
>> --- a/tools/kvm/kvm-cpu.c
>> +++ b/tools/kvm/kvm-cpu.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-07  0:32       ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  0:32 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc, Alexander Graf

On 06/12/11 19:22, Sasha Levin wrote:
> 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


> 
> On Tue, 2011-12-06 at 14:39 +1100, Matt Evans wrote:
>> 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.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/kvm-cpu.c |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
>> index 9bc0796..884a89f 100644
>> --- a/tools/kvm/kvm-cpu.c
>> +++ b/tools/kvm/kvm-cpu.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


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

* Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path
  2011-12-06  8:32     ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify Sasha Levin
@ 2011-12-07  0:35       ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  0:35 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc

On 06/12/11 19:32, Sasha Levin wrote:
> 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

> 
> On Tue, 2011-12-06 at 14:41 +1100, Matt Evans wrote:
>> 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().
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  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(-)
>>
>> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
>> index 84aa931..4c88169 100644
>> --- a/tools/kvm/builtin-run.c
>> +++ b/tools/kvm/builtin-run.c
>> @@ -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;
>>  
>> diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
>> index 5fe6e75..7159952 100644
>> --- a/tools/kvm/include/kvm/kvm.h
>> +++ b/tools/kvm/include/kvm/kvm.h
>> @@ -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);
>> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
>> index 6f33e1a..503ceae 100644
>> --- a/tools/kvm/kvm.c
>> +++ b/tools/kvm/kvm.c
>> @@ -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;
>>  
>> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
>> index 4ac21c0..76f805f 100644
>> --- a/tools/kvm/x86/kvm.c
>> +++ b/tools/kvm/x86/kvm.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory
@ 2011-12-07  0:35       ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  0:35 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc

On 06/12/11 19:32, Sasha Levin wrote:
> 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

> 
> On Tue, 2011-12-06 at 14:41 +1100, Matt Evans wrote:
>> 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().
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  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(-)
>>
>> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
>> index 84aa931..4c88169 100644
>> --- a/tools/kvm/builtin-run.c
>> +++ b/tools/kvm/builtin-run.c
>> @@ -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;
>>  
>> diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
>> index 5fe6e75..7159952 100644
>> --- a/tools/kvm/include/kvm/kvm.h
>> +++ b/tools/kvm/include/kvm/kvm.h
>> @@ -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);
>> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
>> index 6f33e1a..503ceae 100644
>> --- a/tools/kvm/kvm.c
>> +++ b/tools/kvm/kvm.c
>> @@ -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;
>>  
>> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
>> index 4ac21c0..76f805f 100644
>> --- a/tools/kvm/x86/kvm.c
>> +++ b/tools/kvm/x86/kvm.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


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

* Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside
  2011-12-06 12:04       ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an Cyrill Gorcunov
@ 2011-12-07  0:42         ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  0:42 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: Pekka Enberg, kvm, kvm-ppc, Asias He, Ingo Molnar, Sasha Levin

Hi Cyrill,

On 06/12/11 23:04, Cyrill Gorcunov wrote:
> On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
> ...
>>
>> 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

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

* Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an
@ 2011-12-07  0:42         ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  0:42 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: Pekka Enberg, kvm, kvm-ppc, Asias He, Ingo Molnar, Sasha Levin

Hi Cyrill,

On 06/12/11 23:04, Cyrill Gorcunov wrote:
> On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
> ...
>>
>> 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

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

* Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs
  2011-12-06 12:00       ` [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian Asias He
@ 2011-12-07  2:39         ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  2:39 UTC (permalink / raw)
  To: Asias He; +Cc: Pekka Enberg, kvm, kvm-ppc, Sasha Levin, Ingo Molnar

Hi Asias,

On 06/12/11 23:00, Asias He wrote:
> On 12/06/2011 06:24 PM, Pekka Enberg wrote:
>> On Tue, Dec 6, 2011 at 5:40 AM, Matt Evans <matt@ozlabs.org> wrote:
>>> 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.
>>>
>>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>>> ---
>>>  tools/kvm/term.c |    5 ++---
>>>  1 files changed, 2 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/tools/kvm/term.c b/tools/kvm/term.c
>>> index fb5d71c..440884e 100644
>>> --- a/tools/kvm/term.c
>>> +++ b/tools/kvm/term.c
>>> @@ -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;
>>> -
> 
> We can drop this line too.
> 
> 	c &= 0xff;

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

>>>        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);
>>>  }
>>
>> Looks OK to me. Asias?
>>
> 
> Otherwise, looks fine to me.

Thanks for reviewing!


Matt

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

* Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian
@ 2011-12-07  2:39         ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  2:39 UTC (permalink / raw)
  To: Asias He; +Cc: Pekka Enberg, kvm, kvm-ppc, Sasha Levin, Ingo Molnar

Hi Asias,

On 06/12/11 23:00, Asias He wrote:
> On 12/06/2011 06:24 PM, Pekka Enberg wrote:
>> On Tue, Dec 6, 2011 at 5:40 AM, Matt Evans <matt@ozlabs.org> wrote:
>>> 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.
>>>
>>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>>> ---
>>>  tools/kvm/term.c |    5 ++---
>>>  1 files changed, 2 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/tools/kvm/term.c b/tools/kvm/term.c
>>> index fb5d71c..440884e 100644
>>> --- a/tools/kvm/term.c
>>> +++ b/tools/kvm/term.c
>>> @@ -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;
>>> -
> 
> We can drop this line too.
> 
> 	c &= 0xff;

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

>>>        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);
>>>  }
>>
>> Looks OK to me. Asias?
>>
> 
> Otherwise, looks fine to me.

Thanks for reviewing!


Matt


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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
  2011-12-06 13:38                   ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Cyrill Gorcunov
@ 2011-12-07  2:58                     ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  2:58 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: Pekka Enberg, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On 07/12/11 00:38, Cyrill Gorcunov wrote:
> On Tue, Dec 06, 2011 at 03:29:00PM +0200, Pekka Enberg wrote:
>>>
>>> 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;
>>> };
>>
>> 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

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

* Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device
@ 2011-12-07  2:58                     ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  2:58 UTC (permalink / raw)
  To: Cyrill Gorcunov
  Cc: Pekka Enberg, kvm, kvm-ppc, Asias He, Sasha Levin, Ingo Molnar

On 07/12/11 00:38, Cyrill Gorcunov wrote:
> On Tue, Dec 06, 2011 at 03:29:00PM +0200, Pekka Enberg wrote:
>>>
>>> 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;
>>> };
>>
>> 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

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

* Re: [PATCH 17/28] kvm tools: Only call symbol__init() if we have BFD
  2011-12-06  8:26     ` Sasha Levin
@ 2011-12-07  3:03       ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  3:03 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc

On 06/12/11 19:26, Sasha Levin wrote:
> 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

> 
> On Tue, 2011-12-06 at 14:41 +1100, Matt Evans wrote:
>> CONFIG_HAS_BFD is optional, symbol.c inclusion is optional -- so make its init
>> call dependent on CONFIG_HAS_BFD.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/builtin-run.c |    3 ++-
>>  1 files changed, 2 insertions(+), 1 deletions(-)
>>
>> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
>> index 1257c90..aaa5132 100644
>> --- a/tools/kvm/builtin-run.c
>> +++ b/tools/kvm/builtin-run.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH 17/28] kvm tools: Only call symbol__init() if we have
@ 2011-12-07  3:03       ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  3:03 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc

On 06/12/11 19:26, Sasha Levin wrote:
> 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

> 
> On Tue, 2011-12-06 at 14:41 +1100, Matt Evans wrote:
>> CONFIG_HAS_BFD is optional, symbol.c inclusion is optional -- so make its init
>> call dependent on CONFIG_HAS_BFD.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/builtin-run.c |    3 ++-
>>  1 files changed, 2 insertions(+), 1 deletions(-)
>>
>> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
>> index 1257c90..aaa5132 100644
>> --- a/tools/kvm/builtin-run.c
>> +++ b/tools/kvm/builtin-run.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


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

* Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path
  2011-12-07  0:35       ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory Matt Evans
@ 2011-12-07  6:01         ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-07  6:01 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

On Wed, 2011-12-07 at 11:35 +1100, Matt Evans wrote:
> On 06/12/11 19:32, Sasha Levin wrote:
> > 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.

-- 

Sasha.

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

* Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify
@ 2011-12-07  6:01         ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-07  6:01 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

On Wed, 2011-12-07 at 11:35 +1100, Matt Evans wrote:
> On 06/12/11 19:32, Sasha Levin wrote:
> > 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.

-- 

Sasha.


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-06  8:20     ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
@ 2011-12-07  6:17       ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  6:17 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc

On 06/12/11 19:20, Sasha Levin wrote:
> 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


> 
> On Tue, 2011-12-06 at 14:39 +1100, Matt Evans wrote:
>> Architectures can recommend/count/determine number of CPUs differently, so move
>> this out of generic code.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/kvm.c     |   30 ------------------------------
>>  tools/kvm/x86/kvm.c |   30 ++++++++++++++++++++++++++++++
>>  2 files changed, 30 insertions(+), 30 deletions(-)
>>
>> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
>> index 7ce1640..e526483 100644
>> --- a/tools/kvm/kvm.c
>> +++ b/tools/kvm/kvm.c
>> @@ -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;
>> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
>> index ac6c91e..75e4a52 100644
>> --- a/tools/kvm/x86/kvm.c
>> +++ b/tools/kvm/x86/kvm.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific
@ 2011-12-07  6:17       ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  6:17 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc

On 06/12/11 19:20, Sasha Levin wrote:
> 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


> 
> On Tue, 2011-12-06 at 14:39 +1100, Matt Evans wrote:
>> Architectures can recommend/count/determine number of CPUs differently, so move
>> this out of generic code.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/kvm.c     |   30 ------------------------------
>>  tools/kvm/x86/kvm.c |   30 ++++++++++++++++++++++++++++++
>>  2 files changed, 30 insertions(+), 30 deletions(-)
>>
>> diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
>> index 7ce1640..e526483 100644
>> --- a/tools/kvm/kvm.c
>> +++ b/tools/kvm/kvm.c
>> @@ -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;
>> diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
>> index ac6c91e..75e4a52 100644
>> --- a/tools/kvm/x86/kvm.c
>> +++ b/tools/kvm/x86/kvm.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


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

* Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside
  2011-12-07  0:42         ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an Matt Evans
@ 2011-12-07  6:33           ` Cyrill Gorcunov
  -1 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-07  6:33 UTC (permalink / raw)
  To: Matt Evans; +Cc: Pekka Enberg, kvm, kvm-ppc, Asias He, Ingo Molnar, Sasha Levin

On Wed, Dec 07, 2011 at 11:42:27AM +1100, Matt Evans wrote:
> Hi Cyrill,
> 
> On 06/12/11 23:04, Cyrill Gorcunov wrote:
> > On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
> > ...
> >>
> >> 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?)
> 

Ah, I see. Sorry for confusion. Thanks.

	Cyrill

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

* Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an
@ 2011-12-07  6:33           ` Cyrill Gorcunov
  0 siblings, 0 replies; 210+ messages in thread
From: Cyrill Gorcunov @ 2011-12-07  6:33 UTC (permalink / raw)
  To: Matt Evans; +Cc: Pekka Enberg, kvm, kvm-ppc, Asias He, Ingo Molnar, Sasha Levin

On Wed, Dec 07, 2011 at 11:42:27AM +1100, Matt Evans wrote:
> Hi Cyrill,
> 
> On 06/12/11 23:04, Cyrill Gorcunov wrote:
> > On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
> > ...
> >>
> >> 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?)
> 

Ah, I see. Sorry for confusion. Thanks.

	Cyrill

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07  6:17       ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Matt Evans
@ 2011-12-07  6:34         ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-07  6:34 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
> On 06/12/11 19:20, Sasha Levin wrote:
> > 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.)

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.

-- 

Sasha.

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to
@ 2011-12-07  6:34         ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-07  6:34 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
> On 06/12/11 19:20, Sasha Levin wrote:
> > 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.)

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.

-- 

Sasha.


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

* Re: [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io()
  2011-12-06  8:54     ` [PATCH 28/28] kvm tools: Create arch-specific Sasha Levin
@ 2011-12-07  6:36       ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  6:36 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc

On 06/12/11 19:54, Sasha Levin wrote:
> 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


> 
> On Tue, 2011-12-06 at 14:43 +1100, Matt Evans wrote:
>> 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
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  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(-)
>>
>> diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
>> index 15618f1..6f38c0c 100644
>> --- a/tools/kvm/include/kvm/kvm-cpu.h
>> +++ b/tools/kvm/include/kvm/kvm-cpu.h
>> @@ -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);
>> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
>> index 884a89f..c9fbc81 100644
>> --- a/tools/kvm/kvm-cpu.c
>> +++ b/tools/kvm/kvm-cpu.c
>> @@ -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);
>>  	}
>>  
>> diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
>> index a0d10cc..665d742 100644
>> --- a/tools/kvm/x86/kvm-cpu.c
>> +++ b/tools/kvm/x86/kvm-cpu.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io()
@ 2011-12-07  6:36       ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  6:36 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc

On 06/12/11 19:54, Sasha Levin wrote:
> 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


> 
> On Tue, 2011-12-06 at 14:43 +1100, Matt Evans wrote:
>> 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
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  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(-)
>>
>> diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
>> index 15618f1..6f38c0c 100644
>> --- a/tools/kvm/include/kvm/kvm-cpu.h
>> +++ b/tools/kvm/include/kvm/kvm-cpu.h
>> @@ -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);
>> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
>> index 884a89f..c9fbc81 100644
>> --- a/tools/kvm/kvm-cpu.c
>> +++ b/tools/kvm/kvm-cpu.c
>> @@ -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);
>>  	}
>>  
>> diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
>> index a0d10cc..665d742 100644
>> --- a/tools/kvm/x86/kvm-cpu.c
>> +++ b/tools/kvm/x86/kvm-cpu.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-07  0:32       ` Matt Evans
@ 2011-12-07  6:44         ` Alexander Graf
  -1 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-07  6:44 UTC (permalink / raw)
  To: Matt Evans; +Cc: Sasha Levin, kvm, kvm-ppc


On 07.12.2011, at 01:32, Matt Evans <matt@ozlabs.org> wrote:

> On 06/12/11 19:22, Sasha Levin wrote:
>> 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?

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

> 

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-07  6:44         ` Alexander Graf
  0 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-07  6:44 UTC (permalink / raw)
  To: Matt Evans; +Cc: Sasha Levin, kvm, kvm-ppc


On 07.12.2011, at 01:32, Matt Evans <matt@ozlabs.org> wrote:

> On 06/12/11 19:22, Sasha Levin wrote:
>> 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?

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

> 

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-06 10:24           ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
@ 2011-12-07  7:01             ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  7:01 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

Hi Ingo,


On 06/12/11 21:24, Ingo Molnar wrote:
> 
> * Paul Mackerras <paulus@samba.org> wrote:
> 
>> On Tue, Dec 06, 2011 at 09:28:27AM +0100, Ingo Molnar wrote:
>>>
>>> * Sasha Levin <levinsasha928@gmail.com> wrote:
>>>
>>>> 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.
>>
>> 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!
> 
>> [...]  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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-07  7:01             ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  7:01 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

Hi Ingo,


On 06/12/11 21:24, Ingo Molnar wrote:
> 
> * Paul Mackerras <paulus@samba.org> wrote:
> 
>> On Tue, Dec 06, 2011 at 09:28:27AM +0100, Ingo Molnar wrote:
>>>
>>> * Sasha Levin <levinsasha928@gmail.com> wrote:
>>>
>>>> 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.
>>
>> 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!
> 
>> [...]  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


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07  6:34         ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
@ 2011-12-07  7:19           ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  7:19 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc, Alexander Graf

On 07/12/11 17:34, Sasha Levin wrote:
> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
>> On 06/12/11 19:20, Sasha Levin wrote:
>>> 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.)
> 
> 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.

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


Cheers,


Matt

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


Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 arch/powerpc/kvm/powerpc.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 084d1c5..7c7220c 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -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;
 }
 
-- 
1.7.0.4


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific
@ 2011-12-07  7:19           ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  7:19 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc, Alexander Graf

On 07/12/11 17:34, Sasha Levin wrote:
> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
>> On 06/12/11 19:20, Sasha Levin wrote:
>>> 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.)
> 
> 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.

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


Cheers,


Matt

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


Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 arch/powerpc/kvm/powerpc.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 084d1c5..7c7220c 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -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;
 }
 
-- 
1.7.0.4


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07  7:19           ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Matt Evans
@ 2011-12-07  7:24             ` Alexander Graf
  -1 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-07  7:24 UTC (permalink / raw)
  To: Matt Evans; +Cc: Sasha Levin, kvm, kvm-ppc


On 07.12.2011, at 08:19, Matt Evans <matt@ozlabs.org> wrote:

> On 07/12/11 17:34, Sasha Levin wrote:
>> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
>>> On 06/12/11 19:20, Sasha Levin wrote:
>>>> 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.)
>> 
>> 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.
> 
> 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

> 

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
@ 2011-12-07  7:24             ` Alexander Graf
  0 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-07  7:24 UTC (permalink / raw)
  To: Matt Evans; +Cc: Sasha Levin, kvm, kvm-ppc


On 07.12.2011, at 08:19, Matt Evans <matt@ozlabs.org> wrote:

> On 07/12/11 17:34, Sasha Levin wrote:
>> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
>>> On 06/12/11 19:20, Sasha Levin wrote:
>>>> 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.)
>> 
>> 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.
> 
> 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

> 

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07  7:24             ` Alexander Graf
@ 2011-12-07  7:28               ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  7:28 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Sasha Levin, kvm, kvm-ppc

On 07/12/11 18:24, Alexander Graf wrote:
> 
> On 07.12.2011, at 08:19, Matt Evans <matt@ozlabs.org> wrote:
> 
>> On 07/12/11 17:34, Sasha Levin wrote:
>>> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
>>>> On 06/12/11 19:20, Sasha Levin wrote:
>>>>> 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.)
>>>
>>> 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.
>>
>> 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?

> I suppose this is stable material?

Good idea, (and if we're formal,
Signed-off-by: Matt Evans <matt@ozlabs.org>
).  I suppose no one's seen a vcpu fail to be created, yet.


Thanks,

Matt

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific
@ 2011-12-07  7:28               ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  7:28 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Sasha Levin, kvm, kvm-ppc

On 07/12/11 18:24, Alexander Graf wrote:
> 
> On 07.12.2011, at 08:19, Matt Evans <matt@ozlabs.org> wrote:
> 
>> On 07/12/11 17:34, Sasha Levin wrote:
>>> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
>>>> On 06/12/11 19:20, Sasha Levin wrote:
>>>>> 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.)
>>>
>>> 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.
>>
>> 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?

> I suppose this is stable material?

Good idea, (and if we're formal,
Signed-off-by: Matt Evans <matt@ozlabs.org>
).  I suppose no one's seen a vcpu fail to be created, yet.


Thanks,

Matt

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

* Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86
  2011-12-06 18:59     ` Scott Wood
@ 2011-12-07  7:39       ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  7:39 UTC (permalink / raw)
  To: Scott Wood; +Cc: kvm, kvm-ppc

On 07/12/11 05:59, Scott Wood wrote:
> On 12/05/2011 09:37 PM, Matt Evans wrote:
>> 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

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

* Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86
@ 2011-12-07  7:39       ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-07  7:39 UTC (permalink / raw)
  To: Scott Wood; +Cc: kvm, kvm-ppc

On 07/12/11 05:59, Scott Wood wrote:
> On 12/05/2011 09:37 PM, Matt Evans wrote:
>> 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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-07  7:01             ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
@ 2011-12-07  8:16               ` Ingo Molnar
  -1 siblings, 0 replies; 210+ messages in thread
From: Ingo Molnar @ 2011-12-07  8:16 UTC (permalink / raw)
  To: Matt Evans; +Cc: Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg


* Matt Evans <matt@ozlabs.org> wrote:

> >> [...]  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'

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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-07  8:16               ` Ingo Molnar
  0 siblings, 0 replies; 210+ messages in thread
From: Ingo Molnar @ 2011-12-07  8:16 UTC (permalink / raw)
  To: Matt Evans; +Cc: Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg


* Matt Evans <matt@ozlabs.org> wrote:

> >> [...]  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'

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

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07  7:28               ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Matt Evans
@ 2011-12-07  8:29                 ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-07  8:29 UTC (permalink / raw)
  To: Matt Evans; +Cc: Alexander Graf, kvm, kvm-ppc

On Wed, 2011-12-07 at 18:28 +1100, Matt Evans wrote:
> On 07/12/11 18:24, Alexander Graf wrote:
> > 
> > On 07.12.2011, at 08:19, Matt Evans <matt@ozlabs.org> wrote:
> > 
> >> On 07/12/11 17:34, Sasha Levin wrote:
> >>> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
> >>>> On 06/12/11 19:20, Sasha Levin wrote:
> >>>>> 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.)
> >>>
> >>> 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.
> >>
> >> 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?
> 
> > I suppose this is stable material?
> 
> Good idea, (and if we're formal,
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ).  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 <levinsasha928@gmail.com>
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.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 arch/powerpc/kvm/book3s_hv.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 0cb137a..e309099 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -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)

-- 

Sasha.

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to
@ 2011-12-07  8:29                 ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-07  8:29 UTC (permalink / raw)
  To: Matt Evans; +Cc: Alexander Graf, kvm, kvm-ppc

On Wed, 2011-12-07 at 18:28 +1100, Matt Evans wrote:
> On 07/12/11 18:24, Alexander Graf wrote:
> > 
> > On 07.12.2011, at 08:19, Matt Evans <matt@ozlabs.org> wrote:
> > 
> >> On 07/12/11 17:34, Sasha Levin wrote:
> >>> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
> >>>> On 06/12/11 19:20, Sasha Levin wrote:
> >>>>> 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.)
> >>>
> >>> 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.
> >>
> >> 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?
> 
> > I suppose this is stable material?
> 
> Good idea, (and if we're formal,
> Signed-off-by: Matt Evans <matt@ozlabs.org>
> ).  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 <levinsasha928@gmail.com>
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.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 arch/powerpc/kvm/book3s_hv.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 0cb137a..e309099 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -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)

-- 

Sasha.


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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-07  8:16               ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
@ 2011-12-07 12:49                 ` Paolo Bonzini
  -1 siblings, 0 replies; 210+ messages in thread
From: Paolo Bonzini @ 2011-12-07 12:49 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Matt Evans, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On 12/07/2011 09:16 AM, Ingo Molnar wrote:
>> >  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:-)

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

Paolo

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-07 12:49                 ` Paolo Bonzini
  0 siblings, 0 replies; 210+ messages in thread
From: Paolo Bonzini @ 2011-12-07 12:49 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Matt Evans, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On 12/07/2011 09:16 AM, Ingo Molnar wrote:
>> >  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:-)

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

Paolo

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07  8:29                 ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
@ 2011-12-07 14:11                   ` Avi Kivity
  -1 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-07 14:11 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, Alexander Graf, kvm, kvm-ppc

On 12/07/2011 10:29 AM, Sasha Levin wrote:
> 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

-- 
error compiling committee.c: too many arguments to function

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific
@ 2011-12-07 14:11                   ` Avi Kivity
  0 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-07 14:11 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, Alexander Graf, kvm, kvm-ppc

On 12/07/2011 10:29 AM, Sasha Levin wrote:
> 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

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-07  6:44         ` Alexander Graf
@ 2011-12-07 14:12           ` Avi Kivity
  -1 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-07 14:12 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Matt Evans, Sasha Levin, kvm, kvm-ppc

On 12/07/2011 08:44 AM, Alexander Graf wrote:
> On 07.12.2011, at 01:32, Matt Evans <matt@ozlabs.org> wrote:
>
> > On 06/12/11 19:22, Sasha Levin wrote:
> >> 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?
>
> 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.

-- 
error compiling committee.c: too many arguments to function

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-07 14:12           ` Avi Kivity
  0 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-07 14:12 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Matt Evans, Sasha Levin, kvm, kvm-ppc

On 12/07/2011 08:44 AM, Alexander Graf wrote:
> On 07.12.2011, at 01:32, Matt Evans <matt@ozlabs.org> wrote:
>
> > On 06/12/11 19:22, Sasha Levin wrote:
> >> 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?
>
> 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.

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07 14:11                   ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Avi Kivity
@ 2011-12-07 14:22                     ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-07 14:22 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Matt Evans, Alexander Graf, kvm, kvm-ppc

On Wed, 2011-12-07 at 16:11 +0200, Avi Kivity wrote:
> On 12/07/2011 10:29 AM, Sasha Levin wrote:
> > 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?

-- 

Sasha.

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to
@ 2011-12-07 14:22                     ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-07 14:22 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Matt Evans, Alexander Graf, kvm, kvm-ppc

On Wed, 2011-12-07 at 16:11 +0200, Avi Kivity wrote:
> On 12/07/2011 10:29 AM, Sasha Levin wrote:
> > 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?

-- 

Sasha.


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07 14:22                     ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
@ 2011-12-07 14:25                       ` Avi Kivity
  -1 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-07 14:25 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, Alexander Graf, kvm, kvm-ppc

On 12/07/2011 04:22 PM, Sasha Levin wrote:
> On Wed, 2011-12-07 at 16:11 +0200, Avi Kivity wrote:
> > On 12/07/2011 10:29 AM, Sasha Levin wrote:
> > > 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.

-- 
error compiling committee.c: too many arguments to function

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific
@ 2011-12-07 14:25                       ` Avi Kivity
  0 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-07 14:25 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, Alexander Graf, kvm, kvm-ppc

On 12/07/2011 04:22 PM, Sasha Levin wrote:
> On Wed, 2011-12-07 at 16:11 +0200, Avi Kivity wrote:
> > On 12/07/2011 10:29 AM, Sasha Levin wrote:
> > > 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.

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07 14:25                       ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Avi Kivity
@ 2011-12-07 15:00                         ` Alexander Graf
  -1 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-07 15:00 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Sasha Levin, Matt Evans, kvm, kvm-ppc


On 07.12.2011, at 15:25, Avi Kivity <avi@redhat.com> wrote:

> On 12/07/2011 04:22 PM, Sasha Levin wrote:
>> On Wed, 2011-12-07 at 16:11 +0200, Avi Kivity wrote:
>>> On 12/07/2011 10:29 AM, Sasha Levin wrote:
>>>> 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.

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

> 

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
@ 2011-12-07 15:00                         ` Alexander Graf
  0 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-07 15:00 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Sasha Levin, Matt Evans, kvm, kvm-ppc


On 07.12.2011, at 15:25, Avi Kivity <avi@redhat.com> wrote:

> On 12/07/2011 04:22 PM, Sasha Levin wrote:
>> On Wed, 2011-12-07 at 16:11 +0200, Avi Kivity wrote:
>>> On 12/07/2011 10:29 AM, Sasha Levin wrote:
>>>> 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.

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

> 

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-07 14:12           ` Avi Kivity
@ 2011-12-07 15:01             ` Alexander Graf
  -1 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-07 15:01 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Matt Evans, Sasha Levin, kvm, kvm-ppc


On 07.12.2011, at 15:12, Avi Kivity <avi@redhat.com> wrote:

> On 12/07/2011 08:44 AM, Alexander Graf wrote:
>> On 07.12.2011, at 01:32, Matt Evans <matt@ozlabs.org> wrote:
>> 
>>> On 06/12/11 19:22, Sasha Levin wrote:
>>>> 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?
>> 
>> 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

> 

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-07 15:01             ` Alexander Graf
  0 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-07 15:01 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Matt Evans, Sasha Levin, kvm, kvm-ppc


On 07.12.2011, at 15:12, Avi Kivity <avi@redhat.com> wrote:

> On 12/07/2011 08:44 AM, Alexander Graf wrote:
>> On 07.12.2011, at 01:32, Matt Evans <matt@ozlabs.org> wrote:
>> 
>>> On 06/12/11 19:22, Sasha Levin wrote:
>>>> 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?
>> 
>> 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

> 

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-07 15:01             ` Alexander Graf
@ 2011-12-07 15:05               ` Avi Kivity
  -1 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-07 15:05 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Matt Evans, Sasha Levin, kvm, kvm-ppc

On 12/07/2011 05:01 PM, Alexander Graf wrote:
> Will do when I'm back on a keyboard ;).

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

-- 
error compiling committee.c: too many arguments to function

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-07 15:05               ` Avi Kivity
  0 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-07 15:05 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Matt Evans, Sasha Levin, kvm, kvm-ppc

On 12/07/2011 05:01 PM, Alexander Graf wrote:
> Will do when I'm back on a keyboard ;).

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

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07 15:00                         ` Alexander Graf
@ 2011-12-07 15:25                           ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-07 15:25 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Avi Kivity, Matt Evans, kvm, kvm-ppc

On Wed, 2011-12-07 at 16:00 +0100, Alexander Graf wrote:
> On 07.12.2011, at 15:25, Avi Kivity <avi@redhat.com> wrote:
> 
> > On 12/07/2011 04:22 PM, Sasha Levin wrote:
> >> On Wed, 2011-12-07 at 16:11 +0200, Avi Kivity wrote:
> >>> On 12/07/2011 10:29 AM, Sasha Levin wrote:
> >>>> 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.
> 
> 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?

-- 

Sasha.

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to
@ 2011-12-07 15:25                           ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-07 15:25 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Avi Kivity, Matt Evans, kvm, kvm-ppc

On Wed, 2011-12-07 at 16:00 +0100, Alexander Graf wrote:
> On 07.12.2011, at 15:25, Avi Kivity <avi@redhat.com> wrote:
> 
> > On 12/07/2011 04:22 PM, Sasha Levin wrote:
> >> On Wed, 2011-12-07 at 16:11 +0200, Avi Kivity wrote:
> >>> On 12/07/2011 10:29 AM, Sasha Levin wrote:
> >>>> 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.
> 
> 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?

-- 

Sasha.


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07 15:25                           ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
@ 2011-12-07 15:58                             ` Alexander Graf
  -1 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-07 15:58 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Avi Kivity, Matt Evans, kvm, kvm-ppc


On 07.12.2011, at 16:25, Sasha Levin <levinsasha928@gmail.com> wrote:

> On Wed, 2011-12-07 at 16:00 +0100, Alexander Graf wrote:
>> On 07.12.2011, at 15:25, Avi Kivity <avi@redhat.com> wrote:
>> 
>>> On 12/07/2011 04:22 PM, Sasha Levin wrote:
>>>> On Wed, 2011-12-07 at 16:11 +0200, Avi Kivity wrote:
>>>>> On 12/07/2011 10:29 AM, Sasha Levin wrote:
>>>>>> 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.
>> 
>> 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?

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

> 

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
@ 2011-12-07 15:58                             ` Alexander Graf
  0 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-07 15:58 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Avi Kivity, Matt Evans, kvm, kvm-ppc


On 07.12.2011, at 16:25, Sasha Levin <levinsasha928@gmail.com> wrote:

> On Wed, 2011-12-07 at 16:00 +0100, Alexander Graf wrote:
>> On 07.12.2011, at 15:25, Avi Kivity <avi@redhat.com> wrote:
>> 
>>> On 12/07/2011 04:22 PM, Sasha Levin wrote:
>>>> On Wed, 2011-12-07 at 16:11 +0200, Avi Kivity wrote:
>>>>> On 12/07/2011 10:29 AM, Sasha Levin wrote:
>>>>>> 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.
>> 
>> 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?

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

> 

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-07  8:16               ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
@ 2011-12-07 17:14                 ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-07 17:14 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Matt Evans, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On Wed, 7 Dec 2011, Ingo Molnar wrote:

>
> * Matt Evans <matt@ozlabs.org> wrote:
>
>>>> [...]  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'
>
> 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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-07 17:14                 ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-07 17:14 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Matt Evans, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On Wed, 7 Dec 2011, Ingo Molnar wrote:

>
> * Matt Evans <matt@ozlabs.org> wrote:
>
>>>> [...]  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'
>
> 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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-07 12:49                 ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Paolo Bonzini
@ 2011-12-07 17:21                   ` Pekka Enberg
  -1 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-07 17:21 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Ingo Molnar, Matt Evans, Paul Mackerras, Sasha Levin, kvm, kvm-ppc

On 12/07/2011 09:16 AM, Ingo Molnar wrote:
>>> >  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:-)

On Wed, 7 Dec 2011, Paolo Bonzini wrote:
> 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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-07 17:21                   ` Pekka Enberg
  0 siblings, 0 replies; 210+ messages in thread
From: Pekka Enberg @ 2011-12-07 17:21 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Ingo Molnar, Matt Evans, Paul Mackerras, Sasha Levin, kvm, kvm-ppc

On 12/07/2011 09:16 AM, Ingo Molnar wrote:
>>> >  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:-)

On Wed, 7 Dec 2011, Paolo Bonzini wrote:
> 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

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-06  8:22     ` Sasha Levin
@ 2011-12-08  3:03       ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-08  3:03 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc

Hi Sasha,

On 06/12/11 19:22, Sasha Levin wrote:
> 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

> 
> On Tue, 2011-12-06 at 14:39 +1100, Matt Evans wrote:
>> 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.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/kvm-cpu.c |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
>> index 9bc0796..884a89f 100644
>> --- a/tools/kvm/kvm-cpu.c
>> +++ b/tools/kvm/kvm-cpu.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-08  3:03       ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-08  3:03 UTC (permalink / raw)
  To: Sasha Levin; +Cc: kvm, kvm-ppc

Hi Sasha,

On 06/12/11 19:22, Sasha Levin wrote:
> 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

> 
> On Tue, 2011-12-06 at 14:39 +1100, Matt Evans wrote:
>> 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.
>>
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ---
>>  tools/kvm/kvm-cpu.c |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
>> index 9bc0796..884a89f 100644
>> --- a/tools/kvm/kvm-cpu.c
>> +++ b/tools/kvm/kvm-cpu.c
>> @@ -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 majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-07 17:14                 ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Pekka Enberg
@ 2011-12-08  3:14                   ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-08  3:14 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Ingo Molnar, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On 08/12/11 04:14, Pekka Enberg wrote:
> On Wed, 7 Dec 2011, Ingo Molnar wrote:
> 
>>
>> * Matt Evans <matt@ozlabs.org> wrote:
>>
>>>>> [...]  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'
>>
>> 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?

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


Cheers,


Matt

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-08  3:14                   ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-08  3:14 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Ingo Molnar, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On 08/12/11 04:14, Pekka Enberg wrote:
> On Wed, 7 Dec 2011, Ingo Molnar wrote:
> 
>>
>> * Matt Evans <matt@ozlabs.org> wrote:
>>
>>>>> [...]  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'
>>
>> 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?

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


Cheers,


Matt


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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-08  3:14                   ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
@ 2011-12-08  4:49                     ` Ingo Molnar
  -1 siblings, 0 replies; 210+ messages in thread
From: Ingo Molnar @ 2011-12-08  4:49 UTC (permalink / raw)
  To: Matt Evans
  Cc: Pekka Enberg, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg


* Matt Evans <matt@ozlabs.org> wrote:

> On 08/12/11 04:14, Pekka Enberg wrote:
> > On Wed, 7 Dec 2011, Ingo Molnar wrote:
> > 
> >>
> >> * Matt Evans <matt@ozlabs.org> wrote:
> >>
> >>>>> [...]  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'
> >>
> >> 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?
> 
> 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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-08  4:49                     ` Ingo Molnar
  0 siblings, 0 replies; 210+ messages in thread
From: Ingo Molnar @ 2011-12-08  4:49 UTC (permalink / raw)
  To: Matt Evans
  Cc: Pekka Enberg, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg


* Matt Evans <matt@ozlabs.org> wrote:

> On 08/12/11 04:14, Pekka Enberg wrote:
> > On Wed, 7 Dec 2011, Ingo Molnar wrote:
> > 
> >>
> >> * Matt Evans <matt@ozlabs.org> wrote:
> >>
> >>>>> [...]  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'
> >>
> >> 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?
> 
> 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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-08  4:49                     ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
@ 2011-12-08  4:56                       ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-08  4:56 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Pekka Enberg, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On 08/12/11 15:49, Ingo Molnar wrote:
> 
> * Matt Evans <matt@ozlabs.org> wrote:
> 
>> On 08/12/11 04:14, Pekka Enberg wrote:
>>> On Wed, 7 Dec 2011, Ingo Molnar wrote:
>>>
>>>>
>>>> * Matt Evans <matt@ozlabs.org> wrote:
>>>>
>>>>>>> [...]  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'
>>>>
>>>> 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?
>>
>> 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 :-)

> 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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-08  4:56                       ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-08  4:56 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Pekka Enberg, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On 08/12/11 15:49, Ingo Molnar wrote:
> 
> * Matt Evans <matt@ozlabs.org> wrote:
> 
>> On 08/12/11 04:14, Pekka Enberg wrote:
>>> On Wed, 7 Dec 2011, Ingo Molnar wrote:
>>>
>>>>
>>>> * Matt Evans <matt@ozlabs.org> wrote:
>>>>
>>>>>>> [...]  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'
>>>>
>>>> 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?
>>
>> 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 :-)

> 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

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-08  3:03       ` Matt Evans
@ 2011-12-08  5:31         ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-08  5:31 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

On Thu, 2011-12-08 at 14:03 +1100, Matt Evans wrote:
> Hi Sasha,
> 
> On 06/12/11 19:22, Sasha Levin wrote:
> > 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 ;) )

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

-- 

Sasha.

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-08  5:31         ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-08  5:31 UTC (permalink / raw)
  To: Matt Evans; +Cc: kvm, kvm-ppc

On Thu, 2011-12-08 at 14:03 +1100, Matt Evans wrote:
> Hi Sasha,
> 
> On 06/12/11 19:22, Sasha Levin wrote:
> > 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 ;) )

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

-- 

Sasha.


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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-08  4:56                       ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
@ 2011-12-08  5:47                         ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-08  5:47 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Pekka Enberg, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On 08/12/11 15:56, Matt Evans wrote:
> On 08/12/11 15:49, Ingo Molnar wrote:
>>
>> * Matt Evans <matt@ozlabs.org> wrote:
>>
>>> On 08/12/11 04:14, Pekka Enberg wrote:
>>>> On Wed, 7 Dec 2011, Ingo Molnar wrote:
>>>>
>>>>>
>>>>> * Matt Evans <matt@ozlabs.org> wrote:
>>>>>
>>>>>>>> [...]  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'
>>>>>
>>>>> 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?
>>>
>>> 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 :-)
> 
>> 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.

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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-08  5:47                         ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-08  5:47 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Pekka Enberg, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On 08/12/11 15:56, Matt Evans wrote:
> On 08/12/11 15:49, Ingo Molnar wrote:
>>
>> * Matt Evans <matt@ozlabs.org> wrote:
>>
>>> On 08/12/11 04:14, Pekka Enberg wrote:
>>>> On Wed, 7 Dec 2011, Ingo Molnar wrote:
>>>>
>>>>>
>>>>> * Matt Evans <matt@ozlabs.org> wrote:
>>>>>
>>>>>>>> [...]  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'
>>>>>
>>>>> 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?
>>>
>>> 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 :-)
> 
>> 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.

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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-08  5:47                         ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
@ 2011-12-08  5:49                           ` Ingo Molnar
  -1 siblings, 0 replies; 210+ messages in thread
From: Ingo Molnar @ 2011-12-08  5:49 UTC (permalink / raw)
  To: Matt Evans
  Cc: Pekka Enberg, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg


* Matt Evans <matt@ozlabs.org> wrote:

> 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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-08  5:49                           ` Ingo Molnar
  0 siblings, 0 replies; 210+ messages in thread
From: Ingo Molnar @ 2011-12-08  5:49 UTC (permalink / raw)
  To: Matt Evans
  Cc: Pekka Enberg, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg


* Matt Evans <matt@ozlabs.org> wrote:

> 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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
  2011-12-08  5:49                           ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
@ 2011-12-08  6:17                             ` Matt Evans
  -1 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-08  6:17 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Pekka Enberg, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On 08/12/11 16:49, Ingo Molnar wrote:
> 
> * Matt Evans <matt@ozlabs.org> wrote:
> 
>> 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.

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

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

* Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing
@ 2011-12-08  6:17                             ` Matt Evans
  0 siblings, 0 replies; 210+ messages in thread
From: Matt Evans @ 2011-12-08  6:17 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Pekka Enberg, Paul Mackerras, Sasha Levin, kvm, kvm-ppc, Pekka Enberg

On 08/12/11 16:49, Ingo Molnar wrote:
> 
> * Matt Evans <matt@ozlabs.org> wrote:
> 
>> 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.

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

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07  7:19           ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Matt Evans
@ 2011-12-20 15:20             ` Alexander Graf
  -1 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-20 15:20 UTC (permalink / raw)
  To: Matt Evans; +Cc: Sasha Levin, kvm, kvm-ppc


On 07.12.2011, at 08:19, Matt Evans wrote:

> On 07/12/11 17:34, Sasha Levin wrote:
>> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
>>> On 06/12/11 19:20, Sasha Levin wrote:
>>>> 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.)
>> 
>> 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.
> 
> Yeah, that's b0rk.  Alex, a patch below. :)
> 
> 
> Cheers,
> 
> 
> Matt
> 
> ---
> Subject: [PATCH] KVM: PPC: Fix vcpu_create dereference before validity check.
> 
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>

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

Alex

> ---
> arch/powerpc/kvm/powerpc.c |    5 +++--
> 1 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 084d1c5..7c7220c 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -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;
> }
> 
> -- 
> 1.7.0.4
> 

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
@ 2011-12-20 15:20             ` Alexander Graf
  0 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-20 15:20 UTC (permalink / raw)
  To: Matt Evans; +Cc: Sasha Levin, kvm, kvm-ppc


On 07.12.2011, at 08:19, Matt Evans wrote:

> On 07/12/11 17:34, Sasha Levin wrote:
>> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
>>> On 06/12/11 19:20, Sasha Levin wrote:
>>>> 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.)
>> 
>> 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.
> 
> Yeah, that's b0rk.  Alex, a patch below. :)
> 
> 
> Cheers,
> 
> 
> Matt
> 
> ---
> Subject: [PATCH] KVM: PPC: Fix vcpu_create dereference before validity check.
> 
> 
> Signed-off-by: Matt Evans <matt@ozlabs.org>

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

Alex

> ---
> arch/powerpc/kvm/powerpc.c |    5 +++--
> 1 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 084d1c5..7c7220c 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -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;
> }
> 
> -- 
> 1.7.0.4
> 


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-07  8:29                 ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
@ 2011-12-20 15:23                   ` Alexander Graf
  -1 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-20 15:23 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, KVM list, kvm-ppc, Paul Mackerras


On 07.12.2011, at 09:29, Sasha Levin wrote:

> On Wed, 2011-12-07 at 18:28 +1100, Matt Evans wrote:
>> On 07/12/11 18:24, Alexander Graf wrote:
>>> 
>>> On 07.12.2011, at 08:19, Matt Evans <matt@ozlabs.org> wrote:
>>> 
>>>> On 07/12/11 17:34, Sasha Levin wrote:
>>>>> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
>>>>>> On 06/12/11 19:20, Sasha Levin wrote:
>>>>>>> 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.)
>>>>> 
>>>>> 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.
>>>> 
>>>> 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?
>> 
>>> I suppose this is stable material?
>> 
>> Good idea, (and if we're formal,
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ).  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.

> 
> ---
> 
> From: Sasha Levin <levinsasha928@gmail.com>
> 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.
> 
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
> arch/powerpc/kvm/book3s_hv.c |    6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 0cb137a..e309099 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -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

> 	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)
> 
> -- 
> 
> Sasha.
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
@ 2011-12-20 15:23                   ` Alexander Graf
  0 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-20 15:23 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, KVM list, kvm-ppc, Paul Mackerras


On 07.12.2011, at 09:29, Sasha Levin wrote:

> On Wed, 2011-12-07 at 18:28 +1100, Matt Evans wrote:
>> On 07/12/11 18:24, Alexander Graf wrote:
>>> 
>>> On 07.12.2011, at 08:19, Matt Evans <matt@ozlabs.org> wrote:
>>> 
>>>> On 07/12/11 17:34, Sasha Levin wrote:
>>>>> On Wed, 2011-12-07 at 17:17 +1100, Matt Evans wrote:
>>>>>> On 06/12/11 19:20, Sasha Levin wrote:
>>>>>>> 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.)
>>>>> 
>>>>> 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.
>>>> 
>>>> 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?
>> 
>>> I suppose this is stable material?
>> 
>> Good idea, (and if we're formal,
>> Signed-off-by: Matt Evans <matt@ozlabs.org>
>> ).  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.

> 
> ---
> 
> From: Sasha Levin <levinsasha928@gmail.com>
> 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.
> 
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
> arch/powerpc/kvm/book3s_hv.c |    6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 0cb137a..e309099 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -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

> 	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)
> 
> -- 
> 
> Sasha.
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-20 15:23                   ` Alexander Graf
@ 2011-12-21 22:17                     ` Paul Mackerras
  -1 siblings, 0 replies; 210+ messages in thread
From: Paul Mackerras @ 2011-12-21 22:17 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Sasha Levin, Matt Evans, KVM list, kvm-ppc

On Tue, Dec 20, 2011 at 04:23:28PM +0100, Alexander Graf wrote:

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

Acked-by: Paul Mackerras <paulus@samba.org>

Paul.

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to
@ 2011-12-21 22:17                     ` Paul Mackerras
  0 siblings, 0 replies; 210+ messages in thread
From: Paul Mackerras @ 2011-12-21 22:17 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Sasha Levin, Matt Evans, KVM list, kvm-ppc

On Tue, Dec 20, 2011 at 04:23:28PM +0100, Alexander Graf wrote:

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

Acked-by: Paul Mackerras <paulus@samba.org>

Paul.

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-08  5:31         ` Sasha Levin
@ 2011-12-22 10:03           ` Avi Kivity
  -1 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-22 10:03 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, kvm, kvm-ppc

On 12/08/2011 07:31 AM, Sasha Levin wrote:
> > 
> > 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.

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-22 10:03           ` Avi Kivity
  0 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-22 10:03 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, kvm, kvm-ppc

On 12/08/2011 07:31 AM, Sasha Levin wrote:
> > 
> > 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.

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-22 10:03           ` Avi Kivity
@ 2011-12-22 10:18             ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-22 10:18 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Matt Evans, kvm, kvm-ppc

On Thu, 2011-12-22 at 12:03 +0200, Avi Kivity wrote:
> On 12/08/2011 07:31 AM, Sasha Levin wrote:
> > > 
> > > 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.

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

-- 

Sasha.

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-22 10:18             ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-22 10:18 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Matt Evans, kvm, kvm-ppc

On Thu, 2011-12-22 at 12:03 +0200, Avi Kivity wrote:
> On 12/08/2011 07:31 AM, Sasha Levin wrote:
> > > 
> > > 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.

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

-- 

Sasha.


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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-22 10:18             ` Sasha Levin
@ 2011-12-22 10:21               ` Avi Kivity
  -1 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-22 10:21 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, kvm, kvm-ppc

On 12/22/2011 12:18 PM, Sasha Levin wrote:
> On Thu, 2011-12-22 at 12:03 +0200, Avi Kivity wrote:
> > On 12/08/2011 07:31 AM, Sasha Levin wrote:
> > > > 
> > > > 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.
>
>

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

-- 
error compiling committee.c: too many arguments to function

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-22 10:21               ` Avi Kivity
  0 siblings, 0 replies; 210+ messages in thread
From: Avi Kivity @ 2011-12-22 10:21 UTC (permalink / raw)
  To: Sasha Levin; +Cc: Matt Evans, kvm, kvm-ppc

On 12/22/2011 12:18 PM, Sasha Levin wrote:
> On Thu, 2011-12-22 at 12:03 +0200, Avi Kivity wrote:
> > On 12/08/2011 07:31 AM, Sasha Levin wrote:
> > > > 
> > > > 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.
>
>

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

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
  2011-12-22 10:21               ` Avi Kivity
@ 2011-12-22 10:34                 ` Sasha Levin
  -1 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-22 10:34 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Matt Evans, kvm, kvm-ppc

On Thu, 2011-12-22 at 12:21 +0200, Avi Kivity wrote:
> On 12/22/2011 12:18 PM, Sasha Levin wrote:
> > On Thu, 2011-12-22 at 12:03 +0200, Avi Kivity wrote:
> > > On 12/08/2011 07:31 AM, Sasha Levin wrote:
> > > > > 
> > > > > 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.
> >
> >
> 
> 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

-- 

Sasha.

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

* Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
@ 2011-12-22 10:34                 ` Sasha Levin
  0 siblings, 0 replies; 210+ messages in thread
From: Sasha Levin @ 2011-12-22 10:34 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Matt Evans, kvm, kvm-ppc

On Thu, 2011-12-22 at 12:21 +0200, Avi Kivity wrote:
> On 12/22/2011 12:18 PM, Sasha Levin wrote:
> > On Thu, 2011-12-22 at 12:03 +0200, Avi Kivity wrote:
> > > On 12/08/2011 07:31 AM, Sasha Levin wrote:
> > > > > 
> > > > > 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.
> >
> >
> 
> 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

-- 

Sasha.


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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
  2011-12-21 22:17                     ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Paul Mackerras
@ 2011-12-23 14:05                       ` Alexander Graf
  -1 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-23 14:05 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Sasha Levin, Matt Evans, KVM list, kvm-ppc


On 21.12.2011, at 23:17, Paul Mackerras wrote:

> On Tue, Dec 20, 2011 at 04:23:28PM +0100, Alexander Graf wrote:
> 
>>> -	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.
> 
> Acked-by: Paul Mackerras <paulus@samba.org>

Thanks, applied to kvm-ppc-next.


Alex

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

* Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
@ 2011-12-23 14:05                       ` Alexander Graf
  0 siblings, 0 replies; 210+ messages in thread
From: Alexander Graf @ 2011-12-23 14:05 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Sasha Levin, Matt Evans, KVM list, kvm-ppc


On 21.12.2011, at 23:17, Paul Mackerras wrote:

> On Tue, Dec 20, 2011 at 04:23:28PM +0100, Alexander Graf wrote:
> 
>>> -	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.
> 
> Acked-by: Paul Mackerras <paulus@samba.org>

Thanks, applied to kvm-ppc-next.


Alex


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

end of thread, other threads:[~2011-12-23 14:05 UTC | newest]

Thread overview: 210+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <cover.1323141075.git.matt@ozlabs.org>
2011-12-06  3:37 ` [PATCH 01/28] kvm tools: Split x86 arch-specific bits into x86/ Matt Evans
2011-12-06  3:37   ` Matt Evans
2011-12-06  8:07   ` Sasha Levin
2011-12-06  8:07     ` Sasha Levin
2011-12-06 10:10     ` Pekka Enberg
2011-12-06 10:10       ` Pekka Enberg
2011-12-06  3:37 ` [PATCH 02/28] kvm tools: Only build/init i8042 on x86 Matt Evans
2011-12-06  3:37   ` Matt Evans
2011-12-06  8:11   ` Sasha Levin
2011-12-06  8:11     ` Sasha Levin
2011-12-06 18:59   ` Scott Wood
2011-12-06 18:59     ` Scott Wood
2011-12-07  7:39     ` Matt Evans
2011-12-07  7:39       ` Matt Evans
2011-12-06  3:37 ` [PATCH 03/28] kvm tools: Add Makefile parameter for kernel include path Matt Evans
2011-12-06  3:37   ` [PATCH 03/28] kvm tools: Add Makefile parameter for kernel include Matt Evans
2011-12-06  3:38 ` [PATCH 04/28] kvm tools: Re-arrange Makefile to heed CFLAGS before checking for optional libs Matt Evans
2011-12-06  3:38   ` [PATCH 04/28] kvm tools: Re-arrange Makefile to heed CFLAGS before Matt Evans
2011-12-06  3:38 ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Matt Evans
2011-12-06  3:38   ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
2011-12-06  8:13   ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Sasha Levin
2011-12-06  8:13     ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when Sasha Levin
2011-12-06  8:28     ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Ingo Molnar
2011-12-06  8:28       ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
2011-12-06 10:05       ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Paul Mackerras
2011-12-06 10:05         ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Paul Mackerras
2011-12-06 10:24         ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Ingo Molnar
2011-12-06 10:24           ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
2011-12-07  7:01           ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Matt Evans
2011-12-07  7:01             ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
2011-12-07  8:16             ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Ingo Molnar
2011-12-07  8:16               ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
2011-12-07 12:49               ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Paolo Bonzini
2011-12-07 12:49                 ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Paolo Bonzini
2011-12-07 17:21                 ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Pekka Enberg
2011-12-07 17:21                   ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Pekka Enberg
2011-12-07 17:14               ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Pekka Enberg
2011-12-07 17:14                 ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Pekka Enberg
2011-12-08  3:14                 ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Matt Evans
2011-12-08  3:14                   ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
2011-12-08  4:49                   ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Ingo Molnar
2011-12-08  4:49                     ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
2011-12-08  4:56                     ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Matt Evans
2011-12-08  4:56                       ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
2011-12-08  5:47                       ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Matt Evans
2011-12-08  5:47                         ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
2011-12-08  5:49                         ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Ingo Molnar
2011-12-08  5:49                           ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Ingo Molnar
2011-12-08  6:17                           ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately Matt Evans
2011-12-08  6:17                             ` [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing Matt Evans
2011-12-06  3:39 ` [PATCH 06/28] kvm tools: Add arch-specific KVM_RUN exit handling via kvm_cpu__handle_exit() Matt Evans
2011-12-06  3:39   ` [PATCH 06/28] kvm tools: Add arch-specific KVM_RUN exit handling Matt Evans
2011-12-06  3:39 ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Matt Evans
2011-12-06  3:39   ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Matt Evans
2011-12-06  8:20   ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Sasha Levin
2011-12-06  8:20     ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
2011-12-07  6:17     ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Matt Evans
2011-12-07  6:17       ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Matt Evans
2011-12-07  6:34       ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Sasha Levin
2011-12-07  6:34         ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
2011-12-07  7:19         ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Matt Evans
2011-12-07  7:19           ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Matt Evans
2011-12-07  7:24           ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Alexander Graf
2011-12-07  7:24             ` Alexander Graf
2011-12-07  7:28             ` Matt Evans
2011-12-07  7:28               ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Matt Evans
2011-12-07  8:29               ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Sasha Levin
2011-12-07  8:29                 ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
2011-12-07 14:11                 ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Avi Kivity
2011-12-07 14:11                   ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Avi Kivity
2011-12-07 14:22                   ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Sasha Levin
2011-12-07 14:22                     ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
2011-12-07 14:25                     ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Avi Kivity
2011-12-07 14:25                       ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific Avi Kivity
2011-12-07 15:00                       ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Alexander Graf
2011-12-07 15:00                         ` Alexander Graf
2011-12-07 15:25                         ` Sasha Levin
2011-12-07 15:25                           ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Sasha Levin
2011-12-07 15:58                           ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Alexander Graf
2011-12-07 15:58                             ` Alexander Graf
2011-12-20 15:23                 ` Alexander Graf
2011-12-20 15:23                   ` Alexander Graf
2011-12-21 22:17                   ` Paul Mackerras
2011-12-21 22:17                     ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to Paul Mackerras
2011-12-23 14:05                     ` [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code Alexander Graf
2011-12-23 14:05                       ` Alexander Graf
2011-12-20 15:20           ` Alexander Graf
2011-12-20 15:20             ` Alexander Graf
2011-12-06  3:39 ` [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check Matt Evans
2011-12-06  3:39   ` Matt Evans
2011-12-06  8:22   ` Sasha Levin
2011-12-06  8:22     ` Sasha Levin
2011-12-07  0:32     ` Matt Evans
2011-12-07  0:32       ` Matt Evans
2011-12-07  6:44       ` Alexander Graf
2011-12-07  6:44         ` Alexander Graf
2011-12-07 14:12         ` Avi Kivity
2011-12-07 14:12           ` Avi Kivity
2011-12-07 15:01           ` Alexander Graf
2011-12-07 15:01             ` Alexander Graf
2011-12-07 15:05             ` Avi Kivity
2011-12-07 15:05               ` Avi Kivity
2011-12-08  3:03     ` Matt Evans
2011-12-08  3:03       ` Matt Evans
2011-12-08  5:31       ` Sasha Levin
2011-12-08  5:31         ` Sasha Levin
2011-12-22 10:03         ` Avi Kivity
2011-12-22 10:03           ` Avi Kivity
2011-12-22 10:18           ` Sasha Levin
2011-12-22 10:18             ` Sasha Levin
2011-12-22 10:21             ` Avi Kivity
2011-12-22 10:21               ` Avi Kivity
2011-12-22 10:34               ` Sasha Levin
2011-12-22 10:34                 ` Sasha Levin
2011-12-06  3:39 ` [PATCH 09/28] kvm tools: Add kvm__arch_periodic_poll() Matt Evans
2011-12-06  3:39   ` Matt Evans
2011-12-06  3:40 ` [PATCH 10/28] kvm tools: term.h needs to include stdbool.h Matt Evans
2011-12-06  3:40   ` Matt Evans
2011-12-06  3:40 ` [PATCH 11/28] kvm tools: kvm.c needs to include sys/stat.h for mkdir Matt Evans
2011-12-06  3:40   ` Matt Evans
2011-12-06  3:40 ` [PATCH 12/28] kvm tools: Move arch-specific cmdline init into kvm__arch_set_cmdline() Matt Evans
2011-12-06  3:40   ` Matt Evans
2011-12-06  3:40 ` [PATCH 13/28] kvm tools: Add CONSOLE_HV term type and allow it to be selected Matt Evans
2011-12-06  3:40   ` [PATCH 13/28] kvm tools: Add CONSOLE_HV term type and allow it to Matt Evans
2011-12-06  3:40 ` [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs Matt Evans
2011-12-06  3:40   ` [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian Matt Evans
2011-12-06 10:24   ` [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs Pekka Enberg
2011-12-06 10:24     ` Pekka Enberg
2011-12-06 12:00     ` Asias He
2011-12-06 12:00       ` [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian Asias He
2011-12-07  2:39       ` [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs Matt Evans
2011-12-07  2:39         ` [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian Matt Evans
2011-12-06  3:40 ` [PATCH 15/28] kvm tools: Allow initrd_check() to match a cpio Matt Evans
2011-12-06  3:40   ` Matt Evans
2011-12-06 10:26   ` Pekka Enberg
2011-12-06 10:26     ` Pekka Enberg
2011-12-06  3:41 ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside Matt Evans
2011-12-06  3:41   ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd Matt Evans
2011-12-06 10:29   ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside Pekka Enberg
2011-12-06 10:29     ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an Pekka Enberg
2011-12-06 12:04     ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside Cyrill Gorcunov
2011-12-06 12:04       ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an Cyrill Gorcunov
2011-12-07  0:42       ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside Matt Evans
2011-12-07  0:42         ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an Matt Evans
2011-12-07  6:33         ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside Cyrill Gorcunov
2011-12-07  6:33           ` [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an Cyrill Gorcunov
2011-12-06  3:41 ` [PATCH 17/28] kvm tools: Only call symbol__init() if we have BFD Matt Evans
2011-12-06  3:41   ` Matt Evans
2011-12-06  8:26   ` Sasha Levin
2011-12-06  8:26     ` Sasha Levin
2011-12-07  3:03     ` Matt Evans
2011-12-07  3:03       ` [PATCH 17/28] kvm tools: Only call symbol__init() if we have Matt Evans
2011-12-06  3:41 ` [PATCH 18/28] kvm tools: Initialise PCI before devices start getting registered with PCI Matt Evans
2011-12-06  3:41   ` [PATCH 18/28] kvm tools: Initialise PCI before devices start getting Matt Evans
2011-12-06  3:41 ` [PATCH 19/28] kvm tools: Perform CPU and firmware setup after devices are added Matt Evans
2011-12-06  3:41   ` [PATCH 19/28] kvm tools: Perform CPU and firmware setup after devices Matt Evans
2011-12-06  3:41 ` [PATCH 20/28] kvm tools: Init IRQs after determining nrcpus Matt Evans
2011-12-06  3:41   ` Matt Evans
2011-12-06  3:41 ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path Matt Evans
2011-12-06  3:41   ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory Matt Evans
2011-12-06  8:32   ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path Sasha Levin
2011-12-06  8:32     ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify Sasha Levin
2011-12-07  0:35     ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path Matt Evans
2011-12-07  0:35       ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory Matt Evans
2011-12-07  6:01       ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path Sasha Levin
2011-12-07  6:01         ` [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify Sasha Levin
2011-12-06  3:42 ` [PATCH 22/28] kvm tools: Move PCI_MAX_DEVICES to pci.h Matt Evans
2011-12-06  3:42   ` Matt Evans
2011-12-06  3:42 ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup Matt Evans
2011-12-06  3:42   ` Matt Evans
2011-12-06 10:25   ` Pekka Enberg
2011-12-06 10:25     ` Pekka Enberg
2011-12-06 10:28     ` Cyrill Gorcunov
2011-12-06 10:28       ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Cyrill Gorcunov
2011-12-06 11:41       ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup Pekka Enberg
2011-12-06 11:41         ` Pekka Enberg
2011-12-06 11:47         ` Cyrill Gorcunov
2011-12-06 11:47           ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Cyrill Gorcunov
2011-12-06 11:58           ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup Pekka Enberg
2011-12-06 11:58             ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Pekka Enberg
2011-12-06 12:10             ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup Cyrill Gorcunov
2011-12-06 12:10               ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Cyrill Gorcunov
2011-12-06 13:29               ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup Pekka Enberg
2011-12-06 13:29                 ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Pekka Enberg
2011-12-06 13:38                 ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup Cyrill Gorcunov
2011-12-06 13:38                   ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Cyrill Gorcunov
2011-12-07  2:58                   ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup Matt Evans
2011-12-07  2:58                     ` [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device Matt Evans
2011-12-06  3:42 ` [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM Matt Evans
2011-12-06  3:42   ` Matt Evans
2011-12-06 10:26   ` Pekka Enberg
2011-12-06 10:26     ` Pekka Enberg
2011-12-06 11:28     ` Asias He
2011-12-06 11:28       ` [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading Asias He
2011-12-06 11:39       ` [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM Pekka Enberg
2011-12-06 11:39         ` Pekka Enberg
2011-12-06 13:15     ` Sasha Levin
2011-12-06 13:15       ` [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading Sasha Levin
2011-12-06  3:42 ` [PATCH 25/28] kvm tools: Correctly set virtio-pci bar_size and remove hardwired address Matt Evans
2011-12-06  3:42   ` [PATCH 25/28] kvm tools: Correctly set virtio-pci bar_size and remove Matt Evans
2011-12-06  3:42 ` [PATCH 26/28] kvm tools: Add pci__config_{rd,wr}(), pci__find_dev() and fix PCI config register addressing Matt Evans
2011-12-06  3:42   ` [PATCH 26/28] kvm tools: Add pci__config_{rd,wr}(), pci__find_dev() Matt Evans
2011-12-06  3:43 ` [PATCH 27/28] kvm tools: Arch-specific define for PCI MMIO allocation area Matt Evans
2011-12-06  3:43   ` [PATCH 27/28] kvm tools: Arch-specific define for PCI MMIO allocation Matt Evans
2011-12-06  3:43 ` [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io() Matt Evans
2011-12-06  3:43   ` Matt Evans
2011-12-06  8:54   ` Sasha Levin
2011-12-06  8:54     ` [PATCH 28/28] kvm tools: Create arch-specific Sasha Levin
2011-12-07  6:36     ` [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io() Matt Evans
2011-12-07  6:36       ` Matt Evans

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.