kvm tools: Split x86 arch-specific bits into x86/
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/28 kvm tools: Split x86 arch-specific bits into x86/
Create a new arch-specific subdirectory to contain architecture-specific code and includes.
The Makefile now adds various arch-specific objects based on detected architecture. That aside, this patch should only contain code moves. These include:
- x86-specific kvm_cpu setup, kernel loading, memory setup etc. now in x86/kvm{-cpu}.c
- BIOS now lives in x86/bios/
- ioport setup
- KVM extensions are asserted in arch-specific kvm.c now, so each architecture can manage its own dependencies.
- Various architecture-specific #defines are moved into $(ARCH)/include/kvm{-cpu}.h such as struct kvm_cpu, KVM_NR_CPUS, KVM_32BIT_GAP_SIZE.
---
tools/kvm/Makefile | 96 ++++---
tools/kvm/builtin-run.c | 6 +-
tools/kvm/include/kvm/ioport.h | 2 +-
tools/kvm/include/kvm/kvm-cpu.h | 27 +--
tools/kvm/include/kvm/kvm.h | 58 +---
tools/kvm/ioport.c | 54 ----
tools/kvm/kvm-cpu.c | 372 ----------------------
tools/kvm/kvm.c | 323 +-------------------
tools/kvm/{ => x86}/bios.c | 0
tools/kvm/{ => x86}/bios/.gitignore | 0
tools/kvm/{ => x86}/bios/bios-rom.S | 2 +-
tools/kvm/{ => x86}/bios/e820.c | 0
tools/kvm/{ => x86}/bios/entry.S | 0
tools/kvm/{ => x86}/bios/gen-offsets.sh | 0
tools/kvm/{ => x86}/bios/int10.c | 0
tools/kvm/{ => x86}/bios/int15.c | 0
tools/kvm/{ => x86}/bios/local.S | 0
tools/kvm/{ => x86}/bios/macro.S | 0
tools/kvm/{ => x86}/bios/memcpy.c | 0
tools/kvm/{ => x86}/bios/rom.ld.S | 0
tools/kvm/{ => x86}/cpuid.c | 0
tools/kvm/{ => x86}/include/kvm/assembly.h | 0
tools/kvm/{ => x86}/include/kvm/barrier.h | 0
tools/kvm/{ => x86}/include/kvm/bios-export.h | 0
tools/kvm/{ => x86}/include/kvm/bios.h | 0
tools/kvm/{ => x86}/include/kvm/boot-protocol.h | 0
tools/kvm/{ => x86}/include/kvm/cpufeature.h | 0
tools/kvm/{ => x86}/include/kvm/interrupt.h | 0
tools/kvm/x86/include/kvm/kvm-arch.h | 59 ++++
tools/kvm/x86/include/kvm/kvm-cpu-arch.h | 33 ++
tools/kvm/{ => x86}/include/kvm/mptable.h | 0
tools/kvm/{ => x86}/interrupt.c | 0
tools/kvm/x86/ioport.c | 59 ++++
tools/kvm/{ => x86}/irq.c | 0
tools/kvm/x86/kvm-cpu.c | 383 +++++++++++++++++++++++
tools/kvm/x86/kvm.c | 330 +++++++++++++++++++
tools/kvm/{ => x86}/mptable.c | 0
37 files changed, 951 insertions(+), 853 deletions(-)
rename tools/kvm/{ => x86}/bios.c (100%)
rename tools/kvm/{ => x86}/bios/.gitignore (100%)
rename tools/kvm/{ => x86}/bios/bios-rom.S (80%)
rename tools/kvm/{ => x86}/bios/e820.c (100%)
rename tools/kvm/{ => x86}/bios/entry.S (100%)
rename tools/kvm/{ => x86}/bios/gen-offsets.sh (100%)
rename tools/kvm/{ => x86}/bios/int10.c (100%)
rename tools/kvm/{ => x86}/bios/int15.c (100%)
rename tools/kvm/{ => x86}/bios/local.S (100%)
rename tools/kvm/{ => x86}/bios/macro.S (100%)
rename tools/kvm/{ => x86}/bios/memcpy.c (100%)
rename tools/kvm/{ => x86}/bios/rom.ld.S (100%)
rename tools/kvm/{ => x86}/cpuid.c (100%)
rename tools/kvm/{ => x86}/include/kvm/assembly.h (100%)
rename tools/kvm/{ => x86}/include/kvm/barrier.h (100%)
rename tools/kvm/{ => x86}/include/kvm/bios-export.h (100%)
rename tools/kvm/{ => x86}/include/kvm/bios.h (100%)
rename tools/kvm/{ => x86}/include/kvm/boot-protocol.h (100%)
rename tools/kvm/{ => x86}/include/kvm/cpufeature.h (100%)
rename tools/kvm/{ => x86}/include/kvm/interrupt.h (100%)
create mode 100644 tools/kvm/x86/include/kvm/kvm-arch.h
create mode 100644 tools/kvm/x86/include/kvm/kvm-cpu-arch.h
rename tools/kvm/{ => x86}/include/kvm/mptable.h (100%)
rename tools/kvm/{ => x86}/interrupt.c (100%)
create mode 100644 tools/kvm/x86/ioport.c
rename tools/kvm/{ => x86}/irq.c (100%)
create mode 100644 tools/kvm/x86/kvm-cpu.c
create mode 100644 tools/kvm/x86/kvm.c
rename tools/kvm/{ => x86}/mptable.c (100%)tools/kvm/Makefile +60 -36
@@ -33,13 +33,11 @@ OBJS += builtin-run.o OBJS += builtin-setup.o OBJS += builtin-stop.o OBJS += builtin-version.o -OBJS += cpuid.o OBJS += disk/core.o OBJS += framebuffer.o OBJS += guest_compat.o OBJS += hw/rtc.o OBJS += hw/serial.o -OBJS += interrupt.o OBJS += ioport.o OBJS += kvm-cpu.o OBJS += kvm.o
@@ -61,7 +59,6 @@ OBJS += disk/blk.o OBJS += disk/qcow.o OBJS += disk/raw.o OBJS += ioeventfd.o -OBJS += irq.o OBJS += net/uip/core.o OBJS += net/uip/arp.o OBJS += net/uip/icmp.o
@@ -72,7 +69,6 @@ OBJS += net/uip/buf.o OBJS += net/uip/csum.o OBJS += net/uip/dhcp.o OBJS += kvm-cmd.o -OBJS += mptable.o OBJS += rbtree.o OBJS += threadpool.o OBJS += util/parse-options.o
@@ -123,12 +119,6 @@ ifeq ($(has_AIO),y) LIBS += -laio endif -DEPS := $(patsubst %.o,%.d,$(OBJS)) - -# Exclude BIOS object files from header dependencies. -OBJS += bios.o -OBJS += bios/bios-rom.o - LIBS += -lrt LIBS += -lpthread LIBS += -lutil
@@ -150,12 +140,43 @@ ifeq ($(uname_M),x86_64) DEFINES += -DCONFIG_X86_64 endif + +### Arch-specific stuff + +#x86 +ifeq ($(ARCH),x86) + DEFINES += -DCONFIG_X86 + OBJS += x86/cpuid.o + OBJS += x86/interrupt.o + OBJS += x86/ioport.o + OBJS += x86/irq.o + OBJS += x86/kvm.o + OBJS += x86/kvm-cpu.o + OBJS += x86/mptable.o +# Exclude BIOS object files from header dependencies. + OTHEROBJS += x86/bios.o + OTHEROBJS += x86/bios/bios-rom.o + ARCH_INCLUDE := x86/include +endif + +### + +ifeq (,$(ARCH_INCLUDE)) + UNSUPP_ERR = @echo "This architecture is not supported in kvmtool." && exit 1 +else + UNSUPP_ERR = +endif + +DEPS := $(patsubst %.o,%.d,$(OBJS)) +OBJS += $(OTHEROBJS) + DEFINES += -D_FILE_OFFSET_BITS=64 DEFINES += -D_GNU_SOURCE DEFINES += -DKVMTOOLS_VERSION='"$(KVMTOOLS_VERSION)"' +DEFINES += -DBUILD_ARCH='"$(ARCH)"' KVM_INCLUDE := include -CFLAGS += $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -Os -g +CFLAGS += $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I$(ARCH_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -Os -g ifneq ($(WERROR),0) WARNINGS += -Werror
@@ -179,7 +200,10 @@ WARNINGS += -Wwrite-strings CFLAGS += $(WARNINGS) -all: $(PROGRAM) $(GUEST_INIT) +all: arch_support_check $(PROGRAM) $(GUEST_INIT) + +arch_support_check: + $(UNSUPP_ERR) KVMTOOLS-VERSION-FILE: @$(SHELL_PATH) util/KVMTOOLS-VERSION-GEN $(OUTPUT)
@@ -227,33 +251,33 @@ BIOS_CFLAGS += -mregparm=3 BIOS_CFLAGS += -fno-stack-protector BIOS_CFLAGS += -I../../arch/$(ARCH) -bios.o: bios/bios.bin bios/bios-rom.h - -bios/bios.bin.elf: bios/entry.S bios/e820.c bios/int10.c bios/int15.c bios/rom.ld.S - $(E) " CC bios/memcpy.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/memcpy.c -o bios/memcpy.o - $(E) " CC bios/e820.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/e820.c -o bios/e820.o - $(E) " CC bios/int10.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/int10.c -o bios/int10.o - $(E) " CC bios/int15.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/int15.c -o bios/int15.o - $(E) " CC bios/entry.o" - $(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/entry.S -o bios/entry.o +x86/bios.o: x86/bios/bios.bin x86/bios/bios-rom.h + +x86/bios/bios.bin.elf: x86/bios/entry.S x86/bios/e820.c x86/bios/int10.c x86/bios/int15.c x86/bios/rom.ld.S + $(E) " CC x86/bios/memcpy.o" + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/memcpy.c -o x86/bios/memcpy.o + $(E) " CC x86/bios/e820.o" + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/e820.c -o x86/bios/e820.o + $(E) " CC x86/bios/int10.o" + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int10.c -o x86/bios/int10.o + $(E) " CC x86/bios/int15.o" + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int15.c -o x86/bios/int15.o + $(E) " CC x86/bios/entry.o" + $(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/entry.S -o x86/bios/entry.o $(E) " LD " $@ - $(Q) ld -T bios/rom.ld.S -o bios/bios.bin.elf bios/memcpy.o bios/entry.o bios/e820.o bios/int10.o bios/int15.o + $(Q) ld -T x86/bios/rom.ld.S -o x86/bios/bios.bin.elf x86/bios/memcpy.o x86/bios/entry.o x86/bios/e820.o x86/bios/int10.o x86/bios/int15.o -bios/bios.bin: bios/bios.bin.elf +x86/bios/bios.bin: x86/bios/bios.bin.elf $(E) " OBJCOPY " $@ - $(Q) objcopy -O binary -j .text bios/bios.bin.elf bios/bios.bin + $(Q) objcopy -O binary -j .text x86/bios/bios.bin.elf x86/bios/bios.bin -bios/bios-rom.o: bios/bios-rom.S bios/bios.bin bios/bios-rom.h +x86/bios/bios-rom.o: x86/bios/bios-rom.S x86/bios/bios.bin x86/bios/bios-rom.h $(E) " CC " $@ - $(Q) $(CC) -c $(CFLAGS) bios/bios-rom.S -o bios/bios-rom.o + $(Q) $(CC) -c $(CFLAGS) x86/bios/bios-rom.S -o x86/bios/bios-rom.o -bios/bios-rom.h: bios/bios.bin.elf +x86/bios/bios-rom.h: x86/bios/bios.bin.elf $(E) " NM " $@ - $(Q) cd bios && sh gen-offsets.sh > bios-rom.h && cd .. + $(Q) cd x86/bios && sh gen-offsets.sh > bios-rom.h && cd .. check: $(PROGRAM) $(MAKE) -C tests
@@ -263,10 +287,10 @@ check: $(PROGRAM) clean: $(E) " CLEAN" - $(Q) rm -f bios/*.bin - $(Q) rm -f bios/*.elf - $(Q) rm -f bios/*.o - $(Q) rm -f bios/bios-rom.h + $(Q) rm -f x86/bios/*.bin + $(Q) rm -f x86/bios/*.elf + $(Q) rm -f x86/bios/*.o + $(Q) rm -f x86/bios/bios-rom.h $(Q) rm -f tests/boot/boot_test.iso $(Q) rm -rf tests/boot/rootfs/ $(Q) rm -f $(DEPS) $(OBJS) $(PROGRAM) $(GUEST_INIT)
tools/kvm/builtin-run.c +3 -3
@@ -568,7 +568,7 @@ static const char *host_kernels[] = {static const char *default_kernels[] = {"./bzImage" , -"../../arch/x86/boot/bzImage" , +"../../arch/" BUILD_ARCH "/boot/bzImage" ,NULL };
@@ -886,7 +886,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) kvm->vmlinux = vmlinux_filename; -ioport__setup_legacy (); +ioport__setup_arch ();rtc__init ();
@@ -931,7 +931,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)kvm__start_timer (kvm); -kvm__setup_bios (kvm); +kvm__arch_setup_firmware (kvm);for (i =0 ; i < nrcpus; i++) { kvm_cpus[i] =kvm_cpu__init (kvm, i);
tools/kvm/include/kvm/ioport.h +1 -1
@@ -28,7 +28,7 @@ struct ioport_operations {bool (*io_out)(struct ioport *ioport,struct kvm *kvm,u16 port,void *data,int size); }; -void ioport__setup_legacy (void ); +void ioport__setup_arch (void );u16 ioport__register (u16 port,struct ioport_operations *ops,int count,void *param);
tools/kvm/include/kvm/kvm-cpu.h +1 -26
@@ -1,32 +1,7 @@#ifndef KVM__KVM_CPU_H #define KVM__KVM_CPU_H -#include <linux/kvm.h> /* for struct kvm_regs */ - -#include <pthread.h> - -struct kvm ; - -struct kvm_cpu { -pthread_t thread;/* VCPU thread */ - -unsigned long cpu_id; - -struct kvm *kvm;/* parent KVM */ -int vcpu_fd;/* For VCPU ioctls() */ -struct kvm_run *kvm_run; - -struct kvm_regs regs; -struct kvm_sregs sregs; -struct kvm_fpu fpu; - -struct kvm_msrs *msrs;/* dynamically allocated */ - -u8 is_running; -u8 paused; - -struct kvm_coalesced_mmio_ring *ring; -}; +#include "kvm/kvm-cpu-arch.h" struct kvm_cpu *kvm_cpu__init (struct kvm *kvm,unsigned long cpu_id);void kvm_cpu__delete (struct kvm_cpu *vcpu);
tools/kvm/include/kvm/kvm.h +15 -43
94 lines not on this page · raw message
tools/kvm/ioport.c +0 -54
63 lines not on this page · raw message
tools/kvm/kvm-cpu.c +0 -372
399 lines not on this page · raw message
tools/kvm/kvm.c +6 -317
400 lines not on this page · raw message
tools/kvm/x86/bios.c renamed from tools/kvm/bios.c +0 -0
tools/kvm/x86/bios/.gitignore renamed from tools/kvm/bios/.gitignore +0 -0
tools/kvm/x86/bios/bios-rom.S renamed from tools/kvm/bios/bios-rom.S +1 -1
@@ -8,5 +8,5 @@ #endif GLOBAL(bios_rom) - .incbin "bios/bios.bin" + .incbin "x86/bios/bios.bin" END(bios_rom)
tools/kvm/x86/bios/e820.c renamed from tools/kvm/bios/e820.c +0 -0
tools/kvm/x86/bios/entry.S renamed from tools/kvm/bios/entry.S +0 -0
tools/kvm/x86/bios/gen-offsets.sh renamed from tools/kvm/bios/gen-offsets.sh +0 -0
tools/kvm/x86/bios/int10.c renamed from tools/kvm/bios/int10.c +0 -0
tools/kvm/x86/bios/int15.c renamed from tools/kvm/bios/int15.c +0 -0
tools/kvm/x86/bios/local.S renamed from tools/kvm/bios/local.S +0 -0
tools/kvm/x86/bios/macro.S renamed from tools/kvm/bios/macro.S +0 -0
tools/kvm/x86/bios/memcpy.c renamed from tools/kvm/bios/memcpy.c +0 -0
tools/kvm/x86/bios/rom.ld.S renamed from tools/kvm/bios/rom.ld.S +0 -0
tools/kvm/x86/cpuid.c renamed from tools/kvm/cpuid.c +0 -0
tools/kvm/x86/include/kvm/assembly.h renamed from tools/kvm/include/kvm/assembly.h +0 -0
tools/kvm/x86/include/kvm/barrier.h renamed from tools/kvm/include/kvm/barrier.h +0 -0
tools/kvm/x86/include/kvm/bios-export.h renamed from tools/kvm/include/kvm/bios-export.h +0 -0
tools/kvm/x86/include/kvm/bios.h renamed from tools/kvm/include/kvm/bios.h +0 -0
tools/kvm/x86/include/kvm/boot-protocol.h renamed from tools/kvm/include/kvm/boot-protocol.h +0 -0
tools/kvm/x86/include/kvm/cpufeature.h renamed from tools/kvm/include/kvm/cpufeature.h +0 -0
tools/kvm/x86/include/kvm/interrupt.h renamed from tools/kvm/include/kvm/interrupt.h +0 -0
tools/kvm/x86/include/kvm/kvm-arch.h new file +59 -0
59 lines not on this page · raw message
tools/kvm/x86/include/kvm/kvm-cpu-arch.h new file +33 -0
@@ -0,0 +1,33 @@ +#ifndef KVM__KVM_CPU_ARCH_H +#define KVM__KVM_CPU_ARCH_H + +/* Architecture-specific kvm_cpu definitions. */ + +#include <linux/kvm.h> /* for struct kvm_regs */ + +#include <pthread.h> + +struct kvm ; + +struct kvm_cpu { +pthread_t thread;/* VCPU thread */ + +unsigned long cpu_id; + +struct kvm *kvm;/* parent KVM */ +int vcpu_fd;/* For VCPU ioctls() */ +struct kvm_run *kvm_run; + +struct kvm_regs regs; +struct kvm_sregs sregs; +struct kvm_fpu fpu; + +struct kvm_msrs *msrs;/* dynamically allocated */ + +u8 is_running; +u8 paused; + +struct kvm_coalesced_mmio_ring *ring; +}; + +#endif /* KVM__KVM_CPU_ARCH_H */
tools/kvm/x86/include/kvm/mptable.h renamed from tools/kvm/include/kvm/mptable.h +0 -0
tools/kvm/x86/interrupt.c renamed from tools/kvm/interrupt.c +0 -0
tools/kvm/x86/ioport.c new file +59 -0
59 lines not on this page · raw message
tools/kvm/x86/irq.c renamed from tools/kvm/irq.c +0 -0
tools/kvm/x86/kvm-cpu.c new file +383 -0
383 lines not on this page · raw message
tools/kvm/x86/kvm.c new file +330 -0
330 lines not on this page · raw message
tools/kvm/x86/mptable.c renamed from tools/kvm/mptable.c +0 -0
The code doesn't build after this patch due to missing header issues which you fixed in patches #10 & #11. Could you please move those two to the beginning of the series for the sake of bisectablilty?
Quoted 2,339 lines · Matt Evans
Create a new arch-specific subdirectory to contain architecture-specific code and includes.
The
Makefilenow adds various arch-specific objects based on detected architecture. That aside, this patch should only contain code moves. These include:- x86-specific
kvm_cpusetup, kernel loading, memory setup etc. now inx86/kvm{-cpu}.c
- BIOS now lives in x86/bios/
- ioport setup
- KVM extensions are asserted in arch-specifickvm.cnow, so each architecture can manage its own dependencies.
- Various architecture-specific #defines are moved into $(ARCH)/include/kvm{-cpu}.h such as structkvm_cpu,KVM_NR_CPUS,KVM_32BIT_GAP_SIZE.Signed-off-by Matt Evans <[email protected]>--- tools/kvm/Makefile | 96 ++++--- tools/kvm/builtin-run.c | 6 +- tools/kvm/include/kvm/ioport.h | 2 +- tools/kvm/include/kvm/kvm-cpu.h | 27 +-- tools/kvm/include/kvm/kvm.h | 58 +--- tools/kvm/ioport.c | 54 ---- tools/kvm/kvm-cpu.c | 372 ---------------------- tools/kvm/kvm.c | 323 +------------------- tools/kvm/{ => x86}/bios.c | 0 tools/kvm/{ => x86}/bios/.gitignore | 0 tools/kvm/{ => x86}/bios/bios-rom.S | 2 +- tools/kvm/{ => x86}/bios/e820.c | 0 tools/kvm/{ => x86}/bios/entry.S | 0 tools/kvm/{ => x86}/bios/gen-offsets.sh | 0 tools/kvm/{ => x86}/bios/int10.c | 0 tools/kvm/{ => x86}/bios/int15.c | 0 tools/kvm/{ => x86}/bios/local.S | 0 tools/kvm/{ => x86}/bios/macro.S | 0 tools/kvm/{ => x86}/bios/memcpy.c | 0 tools/kvm/{ => x86}/bios/rom.ld.S | 0 tools/kvm/{ => x86}/cpuid.c | 0 tools/kvm/{ => x86}/include/kvm/assembly.h | 0 tools/kvm/{ => x86}/include/kvm/barrier.h | 0 tools/kvm/{ => x86}/include/kvm/bios-export.h | 0 tools/kvm/{ => x86}/include/kvm/bios.h | 0 tools/kvm/{ => x86}/include/kvm/boot-protocol.h | 0 tools/kvm/{ => x86}/include/kvm/cpufeature.h | 0 tools/kvm/{ => x86}/include/kvm/interrupt.h | 0 tools/kvm/x86/include/kvm/kvm-arch.h | 59 ++++ tools/kvm/x86/include/kvm/kvm-cpu-arch.h | 33 ++ tools/kvm/{ => x86}/include/kvm/mptable.h | 0 tools/kvm/{ => x86}/interrupt.c | 0 tools/kvm/x86/ioport.c | 59 ++++ tools/kvm/{ => x86}/irq.c | 0 tools/kvm/x86/kvm-cpu.c | 383 +++++++++++++++++++++++ tools/kvm/x86/kvm.c | 330 +++++++++++++++++++ tools/kvm/{ => x86}/mptable.c | 0 37 files changed, 951 insertions(+), 853 deletions(-) rename tools/kvm/{ => x86}/bios.c (100%) rename tools/kvm/{ => x86}/bios/.gitignore (100%) rename tools/kvm/{ => x86}/bios/bios-rom.S (80%) rename tools/kvm/{ => x86}/bios/e820.c (100%) rename tools/kvm/{ => x86}/bios/entry.S (100%) rename tools/kvm/{ => x86}/bios/gen-offsets.sh (100%) rename tools/kvm/{ => x86}/bios/int10.c (100%) rename tools/kvm/{ => x86}/bios/int15.c (100%) rename tools/kvm/{ => x86}/bios/local.S (100%) rename tools/kvm/{ => x86}/bios/macro.S (100%) rename tools/kvm/{ => x86}/bios/memcpy.c (100%) rename tools/kvm/{ => x86}/bios/rom.ld.S (100%) rename tools/kvm/{ => x86}/cpuid.c (100%) rename tools/kvm/{ => x86}/include/kvm/assembly.h (100%) rename tools/kvm/{ => x86}/include/kvm/barrier.h (100%) rename tools/kvm/{ => x86}/include/kvm/bios-export.h (100%) rename tools/kvm/{ => x86}/include/kvm/bios.h (100%) rename tools/kvm/{ => x86}/include/kvm/boot-protocol.h (100%) rename tools/kvm/{ => x86}/include/kvm/cpufeature.h (100%) rename tools/kvm/{ => x86}/include/kvm/interrupt.h (100%) create mode 100644 tools/kvm/x86/include/kvm/kvm-arch.h create mode 100644 tools/kvm/x86/include/kvm/kvm-cpu-arch.h rename tools/kvm/{ => x86}/include/kvm/mptable.h (100%) rename tools/kvm/{ => x86}/interrupt.c (100%) create mode 100644 tools/kvm/x86/ioport.c rename tools/kvm/{ => x86}/irq.c (100%) create mode 100644 tools/kvm/x86/kvm-cpu.c create mode 100644 tools/kvm/x86/kvm.c rename tools/kvm/{ => x86}/mptable.c (100%)tools/kvm/Makefile +60
-36@@ -33,13 +33,11 @@ OBJS += builtin-run.o OBJS += builtin-setup.o OBJS += builtin-stop.o OBJS += builtin-version.o -OBJS += cpuid.o OBJS += disk/core.o OBJS += framebuffer.o OBJS += guest_compat.o OBJS += hw/rtc.o OBJS += hw/serial.o -OBJS += interrupt.o OBJS += ioport.o OBJS += kvm-cpu.o OBJS += kvm.o@@ -61,7 +59,6 @@ OBJS += disk/blk.o OBJS += disk/qcow.o OBJS += disk/raw.o OBJS += ioeventfd.o -OBJS += irq.o OBJS += net/uip/core.o OBJS += net/uip/arp.o OBJS += net/uip/icmp.o@@ -72,7 +69,6 @@ OBJS += net/uip/buf.o OBJS += net/uip/csum.o OBJS += net/uip/dhcp.o OBJS += kvm-cmd.o -OBJS += mptable.o OBJS += rbtree.o OBJS += threadpool.o OBJS += util/parse-options.o@@ -123,12 +119,6 @@ ifeq ($(has_AIO),y) LIBS += -laio endif -DEPS := $(patsubst %.o,%.d,$(OBJS)) - -# Exclude BIOS object files from header dependencies. -OBJS += bios.o -OBJS += bios/bios-rom.o - LIBS += -lrt LIBS += -lpthread LIBS += -lutil@@ -150,12 +140,43 @@ ifeq ($(uname_M),x86_64) DEFINES += -DCONFIG_X86_64 endif + +### Arch-specific stuff + +#x86 +ifeq ($(ARCH),x86) + DEFINES += -DCONFIG_X86 + OBJS += x86/cpuid.o + OBJS += x86/interrupt.o + OBJS += x86/ioport.o + OBJS += x86/irq.o + OBJS += x86/kvm.o + OBJS += x86/kvm-cpu.o + OBJS += x86/mptable.o +# Exclude BIOS object files from header dependencies. + OTHEROBJS += x86/bios.o + OTHEROBJS += x86/bios/bios-rom.o + ARCH_INCLUDE := x86/include +endif + +### + +ifeq (,$(ARCH_INCLUDE)) + UNSUPP_ERR = @echo "This architecture is not supported in kvmtool." && exit 1 +else + UNSUPP_ERR = +endif + +DEPS := $(patsubst %.o,%.d,$(OBJS)) +OBJS += $(OTHEROBJS) + DEFINES += -D_FILE_OFFSET_BITS=64 DEFINES += -D_GNU_SOURCE DEFINES += -DKVMTOOLS_VERSION='"$(KVMTOOLS_VERSION)"' +DEFINES += -DBUILD_ARCH='"$(ARCH)"' KVM_INCLUDE := include -CFLAGS += $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -Os -g +CFLAGS += $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I$(ARCH_INCLUDE) -I../../include -I../../arch/$(ARCH)/include/ -Os -g ifneq ($(WERROR),0) WARNINGS += -Werror@@ -179,7 +200,10 @@ WARNINGS += -Wwrite-strings CFLAGS += $(WARNINGS) -all: $(PROGRAM) $(GUEST_INIT) +all: arch_support_check $(PROGRAM) $(GUEST_INIT) + +arch_support_check: + $(UNSUPP_ERR) KVMTOOLS-VERSION-FILE: @$(SHELL_PATH) util/KVMTOOLS-VERSION-GEN $(OUTPUT)@@ -227,33 +251,33 @@ BIOS_CFLAGS += -mregparm=3 BIOS_CFLAGS += -fno-stack-protector BIOS_CFLAGS += -I../../arch/$(ARCH) -bios.o: bios/bios.bin bios/bios-rom.h - -bios/bios.bin.elf: bios/entry.S bios/e820.c bios/int10.c bios/int15.c bios/rom.ld.S - $(E) " CC bios/memcpy.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/memcpy.c -o bios/memcpy.o - $(E) " CC bios/e820.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/e820.c -o bios/e820.o - $(E) " CC bios/int10.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/int10.c -o bios/int10.o - $(E) " CC bios/int15.o" - $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/int15.c -o bios/int15.o - $(E) " CC bios/entry.o" - $(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s bios/entry.S -o bios/entry.o +x86/bios.o: x86/bios/bios.bin x86/bios/bios-rom.h + +x86/bios/bios.bin.elf: x86/bios/entry.S x86/bios/e820.c x86/bios/int10.c x86/bios/int15.c x86/bios/rom.ld.S + $(E) " CC x86/bios/memcpy.o" + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/memcpy.c -o x86/bios/memcpy.o + $(E) " CC x86/bios/e820.o" + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/e820.c -o x86/bios/e820.o + $(E) " CC x86/bios/int10.o" + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int10.c -o x86/bios/int10.o + $(E) " CC x86/bios/int15.o" + $(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int15.c -o x86/bios/int15.o + $(E) " CC x86/bios/entry.o" + $(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/entry.S -o x86/bios/entry.o $(E) " LD " $@ - $(Q) ld -T bios/rom.ld.S -o bios/bios.bin.elf bios/memcpy.o bios/entry.o bios/e820.o bios/int10.o bios/int15.o + $(Q) ld -T x86/bios/rom.ld.S -o x86/bios/bios.bin.elf x86/bios/memcpy.o x86/bios/entry.o x86/bios/e820.o x86/bios/int10.o x86/bios/int15.o -bios/bios.bin: bios/bios.bin.elf +x86/bios/bios.bin: x86/bios/bios.bin.elf $(E) " OBJCOPY " $@ - $(Q) objcopy -O binary -j .text bios/bios.bin.elf bios/bios.bin + $(Q) objcopy -O binary -j .text x86/bios/bios.bin.elf x86/bios/bios.bin -bios/bios-rom.o: bios/bios-rom.S bios/bios.bin bios/bios-rom.h +x86/bios/bios-rom.o: x86/bios/bios-rom.S x86/bios/bios.bin x86/bios/bios-rom.h $(E) " CC " $@ - $(Q) $(CC) -c $(CFLAGS) bios/bios-rom.S -o bios/bios-rom.o + $(Q) $(CC) -c $(CFLAGS) x86/bios/bios-rom.S -o x86/bios/bios-rom.o -bios/bios-rom.h: bios/bios.bin.elf +x86/bios/bios-rom.h: x86/bios/bios.bin.elf $(E) " NM " $@ - $(Q) cd bios && sh gen-offsets.sh > bios-rom.h && cd .. + $(Q) cd x86/bios && sh gen-offsets.sh > bios-rom.h && cd .. check: $(PROGRAM) $(MAKE) -C tests@@ -263,10 +287,10 @@ check: $(PROGRAM) clean: $(E) " CLEAN" - $(Q) rm -f bios/*.bin - $(Q) rm -f bios/*.elf - $(Q) rm -f bios/*.o - $(Q) rm -f bios/bios-rom.h + $(Q) rm -f x86/bios/*.bin + $(Q) rm -f x86/bios/*.elf + $(Q) rm -f x86/bios/*.o + $(Q) rm -f x86/bios/bios-rom.h $(Q) rm -f tests/boot/boot_test.iso $(Q) rm -rf tests/boot/rootfs/ $(Q) rm -f $(DEPS) $(OBJS) $(PROGRAM) $(GUEST_INIT)tools/kvm/builtin-run.c +3
-3@@ -568,7 +568,7 @@ static const char *host_kernels[] = {static const char *default_kernels[] = {"./bzImage" , -"../../arch/x86/boot/bzImage" , +"../../arch/" BUILD_ARCH "/boot/bzImage" ,NULL };@@ -886,7 +886,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) kvm->vmlinux = vmlinux_filename; -ioport__setup_legacy (); +ioport__setup_arch ();rtc__init ();@@ -931,7 +931,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)kvm__start_timer (kvm); -kvm__setup_bios (kvm); +kvm__arch_setup_firmware (kvm);for (i =0 ; i < nrcpus; i++) { kvm_cpus[i] =kvm_cpu__init (kvm, i);tools/kvm/include/kvm/ioport.h +1
-1@@ -28,7 +28,7 @@ struct ioport_operations {bool (*io_out)(struct ioport *ioport,struct kvm *kvm,u16 port,void *data,int size); }; -void ioport__setup_legacy (void ); +void ioport__setup_arch (void );u16 ioport__register (u16 port,struct ioport_operations *ops,int count,void *param);tools/kvm/include/kvm/kvm-cpu.h +1
-26@@ -1,32 +1,7 @@#ifndef KVM__KVM_CPU_H #define KVM__KVM_CPU_H -#include <linux/kvm.h> /* for struct kvm_regs */ - -#include <pthread.h> - -struct kvm ; - -struct kvm_cpu { -pthread_t thread;/* VCPU thread */ - -unsigned long cpu_id; - -struct kvm *kvm;/* parent KVM */ -int vcpu_fd;/* For VCPU ioctls() */ -struct kvm_run *kvm_run; - -struct kvm_regs regs; -struct kvm_sregs sregs; -struct kvm_fpu fpu; - -struct kvm_msrs *msrs;/* dynamically allocated */ - -u8 is_running; -u8 paused; - -struct kvm_coalesced_mmio_ring *ring; -}; +#include "kvm/kvm-cpu-arch.h" struct kvm_cpu *kvm_cpu__init (struct kvm *kvm,unsigned long cpu_id);void kvm_cpu__delete (struct kvm_cpu *vcpu);tools/kvm/include/kvm/kvm.h +15
-43@@ -1,22 +1,13 @@#ifndef KVM__KVM_H #define KVM__KVM_H -#include "kvm/interrupt.h" -#include "kvm/segment.h" +#include "kvm/kvm-arch.h" #include <stdbool.h> #include <linux/types.h> #include <time.h> #include <signal.h> -#define KVM_NR_CPUS (255) - -/* -* The hole includes VESA framebuffer and PCI memory. -*/ -#define KVM_32BIT_GAP_SIZE (768 << 20) -#define KVM_32BIT_GAP_START ((1ULL << 32) - KVM_32BIT_GAP_SIZE) -#define SIGKVMEXIT (SIGRTMIN + 0)#define SIGKVMPAUSE (SIGRTMIN + 1)#define SIGKVMSTOP (SIGRTMIN + 4)@@ -25,33 +16,15 @@#define KVM_PID_FILE_PATH "/.kvm-tools/"#define HOME_DIR getenv("HOME") -struct kvm { -int sys_fd;/* For system ioctls(), i.e. /dev/kvm */ -int vm_fd;/* For VM ioctls() */ -timer_t timerid;/* Posix timer for interrupts */ - -int nrcpus;/* Number of cpus to run */ - -u32 mem_slots;/* for KVM_SET_USER_MEMORY_REGION */ - -u64 ram_size; -void *ram_start; - -bool nmi_disabled; - -bool single_step; +#define PAGE_SIZE (sysconf(_SC_PAGE_SIZE)) -u16 boot_selector; -u16 boot_ip; -u16 boot_sp; +#define DEFINE_KVM_EXT (ext) \ + .name = #ext, \ + .code = ext -struct interrupt_table interrupt_table; - -const char *vmlinux; -struct disk_image **disks; -int nr_disks; - -const char *name; +struct kvm_ext { +const char *name; +int code; };void kvm__set_dir (const char *fmt, ...);@@ -64,7 +37,6 @@ void kvm__init_ram(struct kvm *kvm);void kvm__delete (struct kvm *kvm);bool kvm__load_kernel (struct kvm *kvm,const char *kernel_filename,const char *initrd_filename,const char *kernel_cmdline,u16 vidmode); -void kvm__setup_bios (struct kvm *kvm);void kvm__start_timer (struct kvm *kvm);void kvm__stop_timer (struct kvm *kvm);void kvm__irq_line (struct kvm *kvm,int irq,int level);@@ -81,6 +53,13 @@ int kvm__get_sock_by_instance(const char *name);int kvm__enumerate_instances (int (*callback)(const char *name,int pid));void kvm__remove_socket (const char *name); +void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,u64 ram_size,const char *name); +void kvm__arch_setup_firmware (struct kvm *kvm); +bool kvm__arch_cpu_supports_vm (void ); + +int load_flat_binary (struct kvm *kvm,int fd); +bool load_bzimage (struct kvm *kvm,int fd_kernel,int fd_initrd,const char *kernel_cmdline,u16 vidmode); +/* * Debugging */ @@ -98,11 +77,4 @@ static inline void *guest_flat_to_host(struct kvm *kvm, unsigned long offset) return kvm->ram_start + offset; } -static inline void *guest_real_to_host (struct kvm *kvm,u16 selector,u16 offset) -{ -unsigned long flat =segment_to_flat (selector, offset); - -return guest_flat_to_host (kvm, flat); -} -#endif /* KVM__KVM_H */ tools/kvm/ioport.c +0
-54@@ -52,34 +52,6 @@ static int ioport_insert(struct rb_root *root, struct ioport *data)return rb_int_insert (root, &data->node); } -static bool debug_io_out (struct ioport *ioport,struct kvm *kvm,u16 port,void *data,int size) -{ -exit (EXIT_SUCCESS ); -} - -static struct ioport_operations debug_ops = { - .io_out = debug_io_out, -}; - -static bool dummy_io_in (struct ioport *ioport,struct kvm *kvm,u16 port,void *data,int size) -{ -return true; -} - -static bool dummy_io_out (struct ioport *ioport,struct kvm *kvm,u16 port,void *data,int size) -{ -return true; -} - -static struct ioport_operations dummy_read_write_ioport_ops = { - .io_in = dummy_io_in, - .io_out = dummy_io_out, -}; - -static struct ioport_operations dummy_write_only_ioport_ops = { - .io_out = dummy_io_out, -}; -u16 ioport__register (u16 port,struct ioport_operations *ops,int count,void *param) {struct ioport *entry;@@ -164,29 +136,3 @@ error:return !ioport_debug; } - -void ioport__setup_legacy (void ) -{ -/* 0x0020 - 0x003F - 8259A PIC 1 */ -ioport__register (0x0020 , &dummy_read_write_ioport_ops,2 ,NULL ); - -/* PORT 0040-005F - PIT - PROGRAMMABLE INTERVAL TIMER (8253, 8254) */ -ioport__register (0x0040 , &dummy_read_write_ioport_ops,4 ,NULL ); - -/* 0x00A0 - 0x00AF - 8259A PIC 2 */ -ioport__register (0x00A0 , &dummy_read_write_ioport_ops,2 ,NULL ); - -/* PORT 00E0-00EF are 'motherboard specific' so we use them for our -internal debugging purposes. */ -ioport__register (IOPORT_DBG , &debug_ops,1 ,NULL ); - -/* PORT 00ED - DUMMY PORT FOR DELAY??? */ -ioport__register (0x00ED , &dummy_write_only_ioport_ops,1 ,NULL ); - -/* 0x00F0 - 0x00FF - Math co-processor */ -ioport__register (0x00F0 , &dummy_write_only_ioport_ops,2 ,NULL ); - -/* PORT 03D4-03D5 - COLOR VIDEO - CRT CONTROL REGISTERS */ -ioport__register (0x03D4 , &dummy_read_write_ioport_ops,1 ,NULL ); -ioport__register (0x03D5 , &dummy_write_only_ioport_ops,1 ,NULL ); -}tools/kvm/kvm-cpu.c +0
-372@@ -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 __threadstruct 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 , ®s) <0 ) -die ("KVM_GET_REGS failed" ); - - rflags = regs.rflags; - - rip = regs.rip; rsp = regs.rsp; - rax = regs.rax; rbx = regs.rbx; rcx = regs.rcx; - rdx = regs.rdx; rsi = regs.rsi; rdi = regs.rdi; - rbp = regs.rbp; r8 = regs.r8; r9 = regs.r9; - r10 = regs.r10; r11 = regs.r11; r12 = regs.r12; - r13 = regs.r13; r14 = regs.r14; r15 = regs.r15; - -dprintf (debug_fd,"\n Registers:\n" ); -dprintf (debug_fd," ----------\n" ); -dprintf (debug_fd," rip: %016lx rsp: %016lx flags: %016lx\n" , rip, rsp, rflags); -dprintf (debug_fd," rax: %016lx rbx: %016lx rcx: %016lx\n" , rax, rbx, rcx); -dprintf (debug_fd," rdx: %016lx rsi: %016lx rdi: %016lx\n" , rdx, rsi, rdi); -dprintf (debug_fd," rbp: %016lx r8: %016lx r9: %016lx\n" , rbp, r8, r9); -dprintf (debug_fd," r10: %016lx r11: %016lx r12: %016lx\n" , r10, r11, r12); -dprintf (debug_fd," r13: %016lx r14: %016lx r15: %016lx\n" , r13, r14, r15); - -if (ioctl (vcpu->vcpu_fd,KVM_GET_SREGS , &sregs) <0 ) -die ("KVM_GET_REGS failed" ); - - cr0 = sregs.cr0; cr2 = sregs.cr2; cr3 = sregs.cr3; - cr4 = sregs.cr4; cr8 = sregs.cr8; - -dprintf (debug_fd," cr0: %016lx cr2: %016lx cr3: %016lx\n" , cr0, cr2, cr3); -dprintf (debug_fd," cr4: %016lx cr8: %016lx\n" , cr4, cr8); -dprintf (debug_fd,"\n Segment registers:\n" ); -dprintf (debug_fd," ------------------\n" ); -dprintf (debug_fd," register selector base limit type p dpl db s l g avl\n" ); -print_segment ("cs " , &sregs.cs); -print_segment ("ss " , &sregs.ss); -print_segment ("ds " , &sregs.ds); -print_segment ("es " , &sregs.es); -print_segment ("fs " , &sregs.fs); -print_segment ("gs " , &sregs.gs); -print_segment ("tr " , &sregs.tr); -print_segment ("ldt" , &sregs.ldt); -print_dtable ("gdt" , &sregs.gdt); -print_dtable ("idt" , &sregs.idt); - -dprintf (debug_fd,"\n APIC:\n" ); -dprintf (debug_fd," -----\n" ); -dprintf (debug_fd," efer: %016llx apic base: %016llx nmi: %s\n" , - (u64 ) sregs.efer, (u64 ) sregs.apic_base, - (vcpu->kvm->nmi_disabled ?"disabled" :"enabled" )); - -dprintf (debug_fd,"\n Interrupt bitmap:\n" ); -dprintf (debug_fd," -----------------\n" ); -for (i =0 ; i < (KVM_NR_INTERRUPTS +63 ) /64 ; i++) -dprintf (debug_fd," %016llx" , (u64 ) sregs.interrupt_bitmap[i]); -dprintf (debug_fd,"\n" ); -} - -#define MAX_SYM_LEN 128 - -void kvm_cpu__show_code (struct kvm_cpu *vcpu) -{ -unsigned int code_bytes =64 ; -unsigned int code_prologue = code_bytes *43 /64 ; -unsigned int code_len = code_bytes; -char sym[MAX_SYM_LEN ]; -unsigned char c; -unsigned int i; -u8 *ip; - -if (ioctl (vcpu->vcpu_fd,KVM_GET_REGS , &vcpu->regs) <0 ) -die ("KVM_GET_REGS failed" ); - -if (ioctl (vcpu->vcpu_fd,KVM_GET_SREGS , &vcpu->sregs) <0 ) -die ("KVM_GET_SREGS failed" ); - - ip =guest_flat_to_host (vcpu->kvm,ip_to_flat (vcpu, vcpu->regs.rip) - code_prologue); - -dprintf (debug_fd,"\n Code:\n" ); -dprintf (debug_fd," -----\n" ); - -symbol__lookup (vcpu->kvm, vcpu->regs.rip, sym,MAX_SYM_LEN ); - -dprintf (debug_fd," rip: [<%016lx>] %s\n\n" , (unsigned long ) vcpu->regs.rip, sym); - -for (i =0 ; i < code_len; i++, ip++) { -if (!host_ptr_in_ram (vcpu->kvm, ip)) -break ; - - c = *ip; - -if (ip ==guest_flat_to_host (vcpu->kvm,ip_to_flat (vcpu, vcpu->regs.rip))) -dprintf (debug_fd," <%02x>" , c); -else -dprintf (debug_fd," %02x" , c); - } - -dprintf (debug_fd,"\n" ); - -dprintf (debug_fd,"\n Stack:\n" ); -dprintf (debug_fd," ------\n" ); -kvm__dump_mem (vcpu->kvm, vcpu->regs.rsp,32 ); -} - -void kvm_cpu__show_page_tables (struct kvm_cpu *vcpu) -{ -u64 *pte1; -u64 *pte2; -u64 *pte3; -u64 *pte4; - -if (!is_in_protected_mode (vcpu)) -return ; - -if (ioctl (vcpu->vcpu_fd,KVM_GET_SREGS , &vcpu->sregs) <0 ) -die ("KVM_GET_SREGS failed" ); - - pte4 =guest_flat_to_host (vcpu->kvm, vcpu->sregs.cr3); -if (!host_ptr_in_ram (vcpu->kvm, pte4)) -return ; - - pte3 =guest_flat_to_host (vcpu->kvm, (*pte4 & ~0xfff )); -if (!host_ptr_in_ram (vcpu->kvm, pte3)) -return ; - - pte2 =guest_flat_to_host (vcpu->kvm, (*pte3 & ~0xfff )); -if (!host_ptr_in_ram (vcpu->kvm, pte2)) -return ; - - pte1 =guest_flat_to_host (vcpu->kvm, (*pte2 & ~0xfff )); -if (!host_ptr_in_ram (vcpu->kvm, pte1)) -return ; - -dprintf (debug_fd,"Page Tables:\n" ); -if (*pte2 & (1 <<7 )) -dprintf (debug_fd," pte4: %016llx pte3: %016llx" -" pte2: %016llx\n" , - *pte4, *pte3, *pte2); -else -dprintf (debug_fd," pte4: %016llx pte3: %016llx pte2: %016" -"llx pte1: %016llx\n" , - *pte4, *pte3, *pte2, *pte1); -} -void kvm_cpu__run (struct kvm_cpu *vcpu) {int err;@@ -454,7 +83,6 @@ int kvm_cpu__start(struct kvm_cpu *cpu)signal (SIGKVMEXIT , kvm_cpu_signal_handler);signal (SIGKVMPAUSE , kvm_cpu_signal_handler); -kvm_cpu__setup_cpuid (cpu);kvm_cpu__reset_vcpu (cpu);if (cpu->kvm->single_step)tools/kvm/kvm.c +6
-317@@ -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 (®s); - -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 (®s); - -if (regs.eax < eax_base +0x01 ) -return false; - - regs = (struct cpuid_regs ) { - .eax = eax_base +0x01 - }; -host_cpuid (®s); - -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 *userspacdie_perror ("KVM_SET_USER_MEMORY_REGION ioctl" ); } -/* -* Allocating RAM size bigger than 4GB requires us to leave a gap -* in the RAM which is used for PCI MMIO, hotplug, and unconfigured -* devices (see documentation of e820_setup_gap() for details). -* -* If we're required to initialize RAM bigger than 4GB, we will create -* a gap between 0xe0000000 and 0x100000000 in the guest virtual mem space. -*/ - -void kvm__init_ram (struct kvm *kvm) -{ -u64 phys_start, phys_size; -void *host_mem; - -if (kvm->ram_size <KVM_32BIT_GAP_START ) { -/* Use a single block of RAM for 32bit RAM */ - - phys_start =0 ; - phys_size = kvm->ram_size; - host_mem = kvm->ram_start; - -kvm__register_mem (kvm, phys_start, phys_size, host_mem); - }else { -/* First RAM range from zero to the PCI gap: */ - - phys_start =0 ; - phys_size =KVM_32BIT_GAP_START ; - host_mem = kvm->ram_start; - -kvm__register_mem (kvm, phys_start, phys_size, host_mem); - -/* Second RAM range from 4GB to the end of RAM: */ - - phys_start =0x100000000ULL ; - phys_size = kvm->ram_size - phys_size; - host_mem = kvm->ram_start + phys_start; - -kvm__register_mem (kvm, phys_start, phys_size, host_mem); - } -} -int kvm__recommended_cpus (struct kvm *kvm) {int ret;@@ -410,11 +303,10 @@ int kvm__max_cpus(struct kvm *kvm)struct kvm *kvm__init (const char *kvm_dev,u64 ram_size,const char *name) { -struct kvm_pit_config pit_config = { .flags =0 , };struct kvm *kvm;int ret; -if (!kvm__cpu_supports_vm ()) +if (!kvm__arch_cpu_supports_vm ())die ("Your CPU does not support hardware virtualization" ); kvm =kvm__new ();@@ -442,36 +334,7 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)if (kvm__check_extensions (kvm))die ("A required KVM extention is not supported by OS" ); - ret =ioctl (kvm->vm_fd,KVM_SET_TSS_ADDR ,0xfffbd000 ); -if (ret <0 ) -die_perror ("KVM_SET_TSS_ADDR ioctl" ); - - ret =ioctl (kvm->vm_fd,KVM_CREATE_PIT2 , &pit_config); -if (ret <0 ) -die_perror ("KVM_CREATE_PIT2 ioctl" ); - - kvm->ram_size = ram_size; - -if (kvm->ram_size <KVM_32BIT_GAP_START ) { - kvm->ram_start =mmap (NULL , ram_size,PROT_RW ,MAP_ANON_NORESERVE ,-1 ,0 ); - }else { - kvm->ram_start =mmap (NULL , ram_size +KVM_32BIT_GAP_SIZE ,PROT_RW ,MAP_ANON_NORESERVE ,-1 ,0 ); -if (kvm->ram_start !=MAP_FAILED ) { -/* -* We mprotect the gap (see kvm__init_ram() for details) PROT_NONE so that -* if we accidently write to it, we will know. -*/ -mprotect (kvm->ram_start +KVM_32BIT_GAP_START ,KVM_32BIT_GAP_SIZE ,PROT_NONE ); - } - } -if (kvm->ram_start ==MAP_FAILED ) -die ("out of memory" ); - -madvise (kvm->ram_start, kvm->ram_size,MADV_MERGEABLE ); - - ret =ioctl (kvm->vm_fd,KVM_CREATE_IRQCHIP ); -if (ret <0 ) -die_perror ("KVM_CREATE_IRQCHIP ioctl" ); +kvm__arch_init (kvm, kvm_dev, ram_size, name); kvm->name = name;@@ -480,141 +343,6 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)return kvm; } -#define BOOT_LOADER_SELECTOR 0x1000 -#define BOOT_LOADER_IP 0x0000 -#define BOOT_LOADER_SP 0x8000 -#define BOOT_CMDLINE_OFFSET 0x20000 - -#define BOOT_PROTOCOL_REQUIRED 0x206 -#define LOAD_HIGH 0x01 - -static int load_flat_binary (struct kvm *kvm,int fd) -{ -void *p; -int nr; - -if (lseek (fd,0 ,SEEK_SET ) <0 ) -die_perror ("lseek" ); - - p =guest_real_to_host (kvm,BOOT_LOADER_SELECTOR ,BOOT_LOADER_IP ); - -while ((nr =read (fd, p,65536 )) >0 ) - p += nr; - - kvm->boot_selector =BOOT_LOADER_SELECTOR ; - kvm->boot_ip =BOOT_LOADER_IP ; - kvm->boot_sp =BOOT_LOADER_SP ; - -return true; -} - -static const char *BZIMAGE_MAGIC ="HdrS" ; - -static bool load_bzimage (struct kvm *kvm,int fd_kernel, -int fd_initrd,const char *kernel_cmdline,u16 vidmode) -{ -struct boot_params *kern_boot; -unsigned long setup_sects; -struct boot_params boot; -size_t cmdline_size; -ssize_t setup_size; -void *p; -int nr; - -/* -* See Documentation/x86/boot.txt for details no bzImage on-disk and -* memory layout. -*/ - -if (lseek (fd_kernel,0 ,SEEK_SET ) <0 ) -die_perror ("lseek" ); - -if (read (fd_kernel, &boot,sizeof (boot)) !=sizeof (boot)) -return false; - -if (memcmp (&boot.hdr.header,BZIMAGE_MAGIC ,strlen (BZIMAGE_MAGIC ))) -return false; - -if (boot.hdr.version <BOOT_PROTOCOL_REQUIRED ) -die ("Too old kernel" ); - -if (lseek (fd_kernel,0 ,SEEK_SET ) <0 ) -die_perror ("lseek" ); - -if (!boot.hdr.setup_sects) - boot.hdr.setup_sects =BZ_DEFAULT_SETUP_SECTS ; - setup_sects = boot.hdr.setup_sects +1 ; - - setup_size = setup_sects <<9 ; - p =guest_real_to_host (kvm,BOOT_LOADER_SELECTOR ,BOOT_LOADER_IP ); - -/* copy setup.bin to mem*/ -if (read (fd_kernel, p, setup_size) != setup_size) -die_perror ("read" ); - -/* copy vmlinux.bin to BZ_KERNEL_START*/ - p =guest_flat_to_host (kvm,BZ_KERNEL_START ); - -while ((nr =read (fd_kernel, p,65536 )) >0 ) - p += nr; - - p =guest_flat_to_host (kvm,BOOT_CMDLINE_OFFSET ); -if (kernel_cmdline) { - cmdline_size =strlen (kernel_cmdline) +1 ; -if (cmdline_size > boot.hdr.cmdline_size) - cmdline_size = boot.hdr.cmdline_size; - -memset (p,0 , boot.hdr.cmdline_size); -memcpy (p, kernel_cmdline, cmdline_size -1 ); - } - - kern_boot =guest_real_to_host (kvm,BOOT_LOADER_SELECTOR ,0x00 ); - - kern_boot->hdr.cmd_line_ptr =BOOT_CMDLINE_OFFSET ; - kern_boot->hdr.type_of_loader =0xff ; - kern_boot->hdr.heap_end_ptr =0xfe00 ; - kern_boot->hdr.loadflags |=CAN_USE_HEAP ; - kern_boot->hdr.vid_mode = vidmode; - -/* -* Read initrd image into guest memory -*/ -if (fd_initrd >=0 ) { -struct stat initrd_stat; -unsigned long addr; - -if (fstat (fd_initrd, &initrd_stat)) -die_perror ("fstat" ); - - addr = boot.hdr.initrd_addr_max & ~0xfffff ; -for (;;) { -if (addr <BZ_KERNEL_START ) -die ("Not enough memory for initrd" ); -else if (addr < (kvm->ram_size - initrd_stat.st_size)) -break ; - addr -=0x100000 ; - } - - p =guest_flat_to_host (kvm, addr); - nr =read (fd_initrd, p, initrd_stat.st_size); -if (nr != initrd_stat.st_size) -die ("Failed to read initrd" ); - - kern_boot->hdr.ramdisk_image = addr; - kern_boot->hdr.ramdisk_size = initrd_stat.st_size; - } - - kvm->boot_selector =BOOT_LOADER_SELECTOR ; -/* -* The real-mode setup code starts at offset 0x200 of a bzImage. See -* Documentation/x86/boot.txt for details. -*/ - kvm->boot_ip =BOOT_LOADER_IP +0x200 ; - kvm->boot_sp =BOOT_LOADER_SP ; - -return true; -} -/* RFC 1952 */ #define GZIP_ID1 0x1f#define GZIP_ID2 0x8b@@ -675,24 +403,6 @@ found_kernel:return ret; } -/** -* kvm__setup_bios - inject BIOS into guest system memory -* @kvm - guest system descriptor -* -* This function is a main routine where we poke guest memory -* and install BIOS there. -*/ -void kvm__setup_bios (struct kvm *kvm) -{ -/* standart minimal configuration */ -setup_bios (kvm); - -/* FIXME: SMP, ACPI and friends here */ - -/* MP table */ -mptable_setup (kvm, kvm->nrcpus); -} -#define TIMER_INTERVAL_NS 1000000/* 1 msec */ /* @@ -732,27 +442,6 @@ void kvm__stop_timer(struct kvm *kvm) kvm->timerid =0 ; } -void kvm__irq_line (struct kvm *kvm,int irq,int level) -{ -struct kvm_irq_level irq_level; - - irq_level = (struct kvm_irq_level ) { - { - .irq = irq, - }, - .level = level, - }; - -if (ioctl (kvm->vm_fd,KVM_IRQ_LINE , &irq_level) <0 ) -die_perror ("KVM_IRQ_LINE failed" ); -} - -void kvm__irq_trigger (struct kvm *kvm,int irq) -{ -kvm__irq_line (kvm, irq,1 ); -kvm__irq_line (kvm, irq,0 ); -} -void kvm__dump_mem (struct kvm *kvm,unsigned long addr,unsigned long size) {unsigned char *p;tools/kvm/x86/bios.c renamed from tools/kvm/bios.c +0
-0tools/kvm/x86/bios/.gitignore renamed from tools/kvm/bios/.gitignore +0
-0tools/kvm/x86/bios/bios-rom.S renamed from tools/kvm/bios/bios-rom.S +1
-1@@ -8,5 +8,5 @@ #endif GLOBAL(bios_rom) - .incbin "bios/bios.bin" + .incbin "x86/bios/bios.bin" END(bios_rom)tools/kvm/x86/bios/e820.c renamed from tools/kvm/bios/e820.c +0
-0tools/kvm/x86/bios/entry.S renamed from tools/kvm/bios/entry.S +0
-0tools/kvm/x86/bios/gen-offsets.sh renamed from tools/kvm/bios/gen-offsets.sh +0
-0tools/kvm/x86/bios/int10.c renamed from tools/kvm/bios/int10.c +0
-0tools/kvm/x86/bios/int15.c renamed from tools/kvm/bios/int15.c +0
-0tools/kvm/x86/bios/local.S renamed from tools/kvm/bios/local.S +0
-0tools/kvm/x86/bios/macro.S renamed from tools/kvm/bios/macro.S +0
-0tools/kvm/x86/bios/memcpy.c renamed from tools/kvm/bios/memcpy.c +0
-0tools/kvm/x86/bios/rom.ld.S renamed from tools/kvm/bios/rom.ld.S +0
-0tools/kvm/x86/cpuid.c renamed from tools/kvm/cpuid.c +0
-0tools/kvm/x86/include/kvm/assembly.h renamed from tools/kvm/include/kvm/assembly.h +0
-0tools/kvm/x86/include/kvm/barrier.h renamed from tools/kvm/include/kvm/barrier.h +0
-0tools/kvm/x86/include/kvm/bios-export.h renamed from tools/kvm/include/kvm/bios-export.h +0
-0tools/kvm/x86/include/kvm/bios.h renamed from tools/kvm/include/kvm/bios.h +0
-0tools/kvm/x86/include/kvm/boot-protocol.h renamed from tools/kvm/include/kvm/boot-protocol.h +0
-0tools/kvm/x86/include/kvm/cpufeature.h renamed from tools/kvm/include/kvm/cpufeature.h +0
-0tools/kvm/x86/include/kvm/interrupt.h renamed from tools/kvm/include/kvm/interrupt.h +0
-0tools/kvm/x86/include/kvm/kvm-arch.h new file +59
-0@@ -0,0 +1,59 @@ +#ifndef KVM__KVM_ARCH_H +#define KVM__KVM_ARCH_H + +#include "kvm/interrupt.h" +#include "kvm/segment.h" + +#include <stdbool.h> +#include <linux/types.h> +#include <time.h> + +#define KVM_NR_CPUS (255) + +/* +* The hole includes VESA framebuffer and PCI memory. +*/ +#define KVM_32BIT_GAP_SIZE (768 << 20) +#define KVM_32BIT_GAP_START ((1ULL << 32) - KVM_32BIT_GAP_SIZE) + +#define KVM_MMIO_START KVM_32BIT_GAP_START + +struct kvm { +int sys_fd;/* For system ioctls(), i.e. /dev/kvm */ +int vm_fd;/* For VM ioctls() */ +timer_t timerid;/* Posix timer for interrupts */ + +int nrcpus;/* Number of cpus to run */ + +u32 mem_slots;/* for KVM_SET_USER_MEMORY_REGION */ + +u64 ram_size; +void *ram_start; + +bool nmi_disabled; + +bool single_step; + +u16 boot_selector; +u16 boot_ip; +u16 boot_sp; + +struct interrupt_table interrupt_table; + +const char *vmlinux; +struct disk_image **disks; +int nr_disks; + +const char *name; +}; + +static inline void *guest_flat_to_host (struct kvm *kvm,unsigned long offset);/* In kvm.h */ + +static inline void *guest_real_to_host (struct kvm *kvm,u16 selector,u16 offset) +{ +unsigned long flat =segment_to_flat (selector, offset); + +return guest_flat_to_host (kvm, flat); +} + +#endif /* KVM__KVM_ARCH_H */ tools/kvm/x86/include/kvm/kvm-cpu-arch.h new file +33
-0@@ -0,0 +1,33 @@ +#ifndef KVM__KVM_CPU_ARCH_H +#define KVM__KVM_CPU_ARCH_H + +/* Architecture-specific kvm_cpu definitions. */ + +#include <linux/kvm.h> /* for struct kvm_regs */ + +#include <pthread.h> + +struct kvm ; + +struct kvm_cpu { +pthread_t thread;/* VCPU thread */ + +unsigned long cpu_id; + +struct kvm *kvm;/* parent KVM */ +int vcpu_fd;/* For VCPU ioctls() */ +struct kvm_run *kvm_run; + +struct kvm_regs regs; +struct kvm_sregs sregs; +struct kvm_fpu fpu; + +struct kvm_msrs *msrs;/* dynamically allocated */ + +u8 is_running; +u8 paused; + +struct kvm_coalesced_mmio_ring *ring; +}; + +#endif /* KVM__KVM_CPU_ARCH_H */ tools/kvm/x86/include/kvm/mptable.h renamed from tools/kvm/include/kvm/mptable.h +0
-0tools/kvm/x86/interrupt.c renamed from tools/kvm/interrupt.c +0
-0tools/kvm/x86/ioport.c new file +59
-0@@ -0,0 +1,59 @@ +#include "kvm/ioport.h" + +#include <stdlib.h> + +static bool debug_io_out (struct ioport *ioport,struct kvm *kvm,u16 port,void *data,int size) +{ +exit (EXIT_SUCCESS ); +} + +static struct ioport_operations debug_ops = { + .io_out = debug_io_out, +}; + +static bool dummy_io_in (struct ioport *ioport,struct kvm *kvm,u16 port,void *data,int size) +{ +return true; +} + +static bool dummy_io_out (struct ioport *ioport,struct kvm *kvm,u16 port,void *data,int size) +{ +return true; +} + +static struct ioport_operations dummy_read_write_ioport_ops = { + .io_in = dummy_io_in, + .io_out = dummy_io_out, +}; + +static struct ioport_operations dummy_write_only_ioport_ops = { + .io_out = dummy_io_out, +}; + +void ioport__setup_arch (void ) +{ +/* Legacy ioport setup */ + +/* 0x0020 - 0x003F - 8259A PIC 1 */ +ioport__register (0x0020 , &dummy_read_write_ioport_ops,2 ,NULL ); + +/* PORT 0040-005F - PIT - PROGRAMMABLE INTERVAL TIMER (8253, 8254) */ +ioport__register (0x0040 , &dummy_read_write_ioport_ops,4 ,NULL ); + +/* 0x00A0 - 0x00AF - 8259A PIC 2 */ +ioport__register (0x00A0 , &dummy_read_write_ioport_ops,2 ,NULL ); + +/* PORT 00E0-00EF are 'motherboard specific' so we use them for our +internal debugging purposes. */ +ioport__register (IOPORT_DBG , &debug_ops,1 ,NULL ); + +/* PORT 00ED - DUMMY PORT FOR DELAY??? */ +ioport__register (0x00ED , &dummy_write_only_ioport_ops,1 ,NULL ); + +/* 0x00F0 - 0x00FF - Math co-processor */ +ioport__register (0x00F0 , &dummy_write_only_ioport_ops,2 ,NULL ); + +/* PORT 03D4-03D5 - COLOR VIDEO - CRT CONTROL REGISTERS */ +ioport__register (0x03D4 , &dummy_read_write_ioport_ops,1 ,NULL ); +ioport__register (0x03D5 , &dummy_write_only_ioport_ops,1 ,NULL ); +}tools/kvm/x86/irq.c renamed from tools/kvm/irq.c +0
-0tools/kvm/x86/kvm-cpu.c new file +383
-0@@ -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 , ®s) <0 ) +die ("KVM_GET_REGS failed" ); + + rflags = regs.rflags; + + rip = regs.rip; rsp = regs.rsp; + rax = regs.rax; rbx = regs.rbx; rcx = regs.rcx; + rdx = regs.rdx; rsi = regs.rsi; rdi = regs.rdi; + rbp = regs.rbp; r8 = regs.r8; r9 = regs.r9; + r10 = regs.r10; r11 = regs.r11; r12 = regs.r12; + r13 = regs.r13; r14 = regs.r14; r15 = regs.r15; + +dprintf (debug_fd,"\n Registers:\n" ); +dprintf (debug_fd," ----------\n" ); +dprintf (debug_fd," rip: %016lx rsp: %016lx flags: %016lx\n" , rip, rsp, rflags); +dprintf (debug_fd," rax: %016lx rbx: %016lx rcx: %016lx\n" , rax, rbx, rcx); +dprintf (debug_fd," rdx: %016lx rsi: %016lx rdi: %016lx\n" , rdx, rsi, rdi); +dprintf (debug_fd," rbp: %016lx r8: %016lx r9: %016lx\n" , rbp, r8, r9); +dprintf (debug_fd," r10: %016lx r11: %016lx r12: %016lx\n" , r10, r11, r12); +dprintf (debug_fd," r13: %016lx r14: %016lx r15: %016lx\n" , r13, r14, r15); + +if (ioctl (vcpu->vcpu_fd,KVM_GET_SREGS , &sregs) <0 ) +die ("KVM_GET_REGS failed" ); + + cr0 = sregs.cr0; cr2 = sregs.cr2; cr3 = sregs.cr3; + cr4 = sregs.cr4; cr8 = sregs.cr8; + +dprintf (debug_fd," cr0: %016lx cr2: %016lx cr3: %016lx\n" , cr0, cr2, cr3); +dprintf (debug_fd," cr4: %016lx cr8: %016lx\n" , cr4, cr8); +dprintf (debug_fd,"\n Segment registers:\n" ); +dprintf (debug_fd," ------------------\n" ); +dprintf (debug_fd," register selector base limit type p dpl db s l g avl\n" ); +print_segment ("cs " , &sregs.cs); +print_segment ("ss " , &sregs.ss); +print_segment ("ds " , &sregs.ds); +print_segment ("es " , &sregs.es); +print_segment ("fs " , &sregs.fs); +print_segment ("gs " , &sregs.gs); +print_segment ("tr " , &sregs.tr); +print_segment ("ldt" , &sregs.ldt); +print_dtable ("gdt" , &sregs.gdt); +print_dtable ("idt" , &sregs.idt); + +dprintf (debug_fd,"\n APIC:\n" ); +dprintf (debug_fd," -----\n" ); +dprintf (debug_fd," efer: %016llx apic base: %016llx nmi: %s\n" , + (u64 ) sregs.efer, (u64 ) sregs.apic_base, + (vcpu->kvm->nmi_disabled ?"disabled" :"enabled" )); + +dprintf (debug_fd,"\n Interrupt bitmap:\n" ); +dprintf (debug_fd," -----------------\n" ); +for (i =0 ; i < (KVM_NR_INTERRUPTS +63 ) /64 ; i++) +dprintf (debug_fd," %016llx" , (u64 ) sregs.interrupt_bitmap[i]); +dprintf (debug_fd,"\n" ); +} + +#define MAX_SYM_LEN 128 + +void kvm_cpu__show_code (struct kvm_cpu *vcpu) +{ +unsigned int code_bytes =64 ; +unsigned int code_prologue = code_bytes *43 /64 ; +unsigned int code_len = code_bytes; +char sym[MAX_SYM_LEN ]; +unsigned char c; +unsigned int i; +u8 *ip; + +if (ioctl (vcpu->vcpu_fd,KVM_GET_REGS , &vcpu->regs) <0 ) +die ("KVM_GET_REGS failed" ); + +if (ioctl (vcpu->vcpu_fd,KVM_GET_SREGS , &vcpu->sregs) <0 ) +die ("KVM_GET_SREGS failed" ); + + ip =guest_flat_to_host (vcpu->kvm,ip_to_flat (vcpu, vcpu->regs.rip) - code_prologue); + +dprintf (debug_fd,"\n Code:\n" ); +dprintf (debug_fd," -----\n" ); + +symbol__lookup (vcpu->kvm, vcpu->regs.rip, sym,MAX_SYM_LEN ); + +dprintf (debug_fd," rip: [<%016lx>] %s\n\n" , (unsigned long ) vcpu->regs.rip, sym); + +for (i =0 ; i < code_len; i++, ip++) { +if (!host_ptr_in_ram (vcpu->kvm, ip)) +break ; + + c = *ip; + +if (ip ==guest_flat_to_host (vcpu->kvm,ip_to_flat (vcpu, vcpu->regs.rip))) +dprintf (debug_fd," <%02x>" , c); +else +dprintf (debug_fd," %02x" , c); + } + +dprintf (debug_fd,"\n" ); + +dprintf (debug_fd,"\n Stack:\n" ); +dprintf (debug_fd," ------\n" ); +kvm__dump_mem (vcpu->kvm, vcpu->regs.rsp,32 ); +} + +void kvm_cpu__show_page_tables (struct kvm_cpu *vcpu) +{ +u64 *pte1; +u64 *pte2; +u64 *pte3; +u64 *pte4; + +if (!is_in_protected_mode (vcpu)) +return ; + +if (ioctl (vcpu->vcpu_fd,KVM_GET_SREGS , &vcpu->sregs) <0 ) +die ("KVM_GET_SREGS failed" ); + + pte4 =guest_flat_to_host (vcpu->kvm, vcpu->sregs.cr3); +if (!host_ptr_in_ram (vcpu->kvm, pte4)) +return ; + + pte3 =guest_flat_to_host (vcpu->kvm, (*pte4 & ~0xfff )); +if (!host_ptr_in_ram (vcpu->kvm, pte3)) +return ; + + pte2 =guest_flat_to_host (vcpu->kvm, (*pte3 & ~0xfff )); +if (!host_ptr_in_ram (vcpu->kvm, pte2)) +return ; + + pte1 =guest_flat_to_host (vcpu->kvm, (*pte2 & ~0xfff )); +if (!host_ptr_in_ram (vcpu->kvm, pte1)) +return ; + +dprintf (debug_fd,"Page Tables:\n" ); +if (*pte2 & (1 <<7 )) +dprintf (debug_fd," pte4: %016llx pte3: %016llx" +" pte2: %016llx\n" , + *pte4, *pte3, *pte2); +else +dprintf (debug_fd," pte4: %016llx pte3: %016llx pte2: %016" +"llx pte1: %016llx\n" , + *pte4, *pte3, *pte2, *pte1); +}tools/kvm/x86/kvm.c new file +330
-0@@ -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 (®s); + +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 (®s); + +if (regs.eax < eax_base +0x01 ) +return false; + + regs = (struct cpuid_regs ) { + .eax = eax_base +0x01 + }; +host_cpuid (®s); + +return regs.ecx & (1 << feature); +} + +/* +* Allocating RAM size bigger than 4GB requires us to leave a gap +* in the RAM which is used for PCI MMIO, hotplug, and unconfigured +* devices (see documentation of e820_setup_gap() for details). +* +* If we're required to initialize RAM bigger than 4GB, we will create +* a gap between 0xe0000000 and 0x100000000 in the guest virtual mem space. +*/ + +void kvm__init_ram (struct kvm *kvm) +{ +u64 phys_start, phys_size; +void *host_mem; + +if (kvm->ram_size <KVM_32BIT_GAP_START ) { +/* Use a single block of RAM for 32bit RAM */ + + phys_start =0 ; + phys_size = kvm->ram_size; + host_mem = kvm->ram_start; + +kvm__register_mem (kvm, phys_start, phys_size, host_mem); + }else { +/* First RAM range from zero to the PCI gap: */ + + phys_start =0 ; + phys_size =KVM_32BIT_GAP_START ; + host_mem = kvm->ram_start; + +kvm__register_mem (kvm, phys_start, phys_size, host_mem); + +/* Second RAM range from 4GB to the end of RAM: */ + + phys_start =0x100000000ULL ; + phys_size = kvm->ram_size - phys_size; + host_mem = kvm->ram_start + phys_start; + +kvm__register_mem (kvm, phys_start, phys_size, host_mem); + } +} + +/* Architecture-specific KVM init */ +void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,u64 ram_size,const char *name) +{ +struct kvm_pit_config pit_config = { .flags =0 , }; +int ret; + + ret =ioctl (kvm->vm_fd,KVM_SET_TSS_ADDR ,0xfffbd000 ); +if (ret <0 ) +die_perror ("KVM_SET_TSS_ADDR ioctl" ); + + ret =ioctl (kvm->vm_fd,KVM_CREATE_PIT2 , &pit_config); +if (ret <0 ) +die_perror ("KVM_CREATE_PIT2 ioctl" ); + + kvm->ram_size = ram_size; + +if (kvm->ram_size <KVM_32BIT_GAP_START ) { + kvm->ram_start =mmap (NULL , ram_size,PROT_RW ,MAP_ANON_NORESERVE ,-1 ,0 ); + }else { + kvm->ram_start =mmap (NULL , ram_size +KVM_32BIT_GAP_SIZE ,PROT_RW ,MAP_ANON_NORESERVE ,-1 ,0 ); +if (kvm->ram_start !=MAP_FAILED ) { +/* +* We mprotect the gap (see kvm__init_ram() for details) PROT_NONE so that +* if we accidently write to it, we will know. +*/ +mprotect (kvm->ram_start +KVM_32BIT_GAP_START ,KVM_32BIT_GAP_SIZE ,PROT_NONE ); + } + } +if (kvm->ram_start ==MAP_FAILED ) +die ("out of memory" ); + +madvise (kvm->ram_start, kvm->ram_size,MADV_MERGEABLE ); + + ret =ioctl (kvm->vm_fd,KVM_CREATE_IRQCHIP ); +if (ret <0 ) +die_perror ("KVM_CREATE_IRQCHIP ioctl" ); +} + +void kvm__irq_line (struct kvm *kvm,int irq,int level) +{ +struct kvm_irq_level irq_level; + + irq_level = (struct kvm_irq_level ) { + { + .irq = irq, + }, + .level = level, + }; + +if (ioctl (kvm->vm_fd,KVM_IRQ_LINE , &irq_level) <0 ) +die_perror ("KVM_IRQ_LINE failed" ); +} + +void kvm__irq_trigger (struct kvm *kvm,int irq) +{ +kvm__irq_line (kvm, irq,1 ); +kvm__irq_line (kvm, irq,0 ); +} + +#define BOOT_LOADER_SELECTOR 0x1000 +#define BOOT_LOADER_IP 0x0000 +#define BOOT_LOADER_SP 0x8000 +#define BOOT_CMDLINE_OFFSET 0x20000 + +#define BOOT_PROTOCOL_REQUIRED 0x206 +#define LOAD_HIGH 0x01 + +int load_flat_binary (struct kvm *kvm,int fd) +{ +void *p; +int nr; + +if (lseek (fd,0 ,SEEK_SET ) <0 ) +die_perror ("lseek" ); + + p =guest_real_to_host (kvm,BOOT_LOADER_SELECTOR ,BOOT_LOADER_IP ); + +while ((nr =read (fd, p,65536 )) >0 ) + p += nr; + + kvm->boot_selector =BOOT_LOADER_SELECTOR ; + kvm->boot_ip =BOOT_LOADER_IP ; + kvm->boot_sp =BOOT_LOADER_SP ; + +return true; +} + +static const char *BZIMAGE_MAGIC ="HdrS" ; + +bool load_bzimage (struct kvm *kvm,int fd_kernel, +int fd_initrd,const char *kernel_cmdline,u16 vidmode) +{ +struct boot_params *kern_boot; +unsigned long setup_sects; +struct boot_params boot; +size_t cmdline_size; +ssize_t setup_size; +void *p; +int nr; + +/* +* See Documentation/x86/boot.txt for details no bzImage on-disk and +* memory layout. +*/ + +if (lseek (fd_kernel,0 ,SEEK_SET ) <0 ) +die_perror ("lseek" ); + +if (read (fd_kernel, &boot,sizeof (boot)) !=sizeof (boot)) +return false; + +if (memcmp (&boot.hdr.header,BZIMAGE_MAGIC ,strlen (BZIMAGE_MAGIC ))) +return false; + +if (boot.hdr.version <BOOT_PROTOCOL_REQUIRED ) +die ("Too old kernel" ); + +if (lseek (fd_kernel,0 ,SEEK_SET ) <0 ) +die_perror ("lseek" ); + +if (!boot.hdr.setup_sects) + boot.hdr.setup_sects =BZ_DEFAULT_SETUP_SECTS ; + setup_sects = boot.hdr.setup_sects +1 ; + + setup_size = setup_sects <<9 ; + p =guest_real_to_host (kvm,BOOT_LOADER_SELECTOR ,BOOT_LOADER_IP ); + +/* copy setup.bin to mem*/ +if (read (fd_kernel, p, setup_size) != setup_size) +die_perror ("read" ); + +/* copy vmlinux.bin to BZ_KERNEL_START*/ + p =guest_flat_to_host (kvm,BZ_KERNEL_START ); + +while ((nr =read (fd_kernel, p,65536 )) >0 ) + p += nr; + + p =guest_flat_to_host (kvm,BOOT_CMDLINE_OFFSET ); +if (kernel_cmdline) { + cmdline_size =strlen (kernel_cmdline) +1 ; +if (cmdline_size > boot.hdr.cmdline_size) + cmdline_size = boot.hdr.cmdline_size; + +memset (p,0 , boot.hdr.cmdline_size); +memcpy (p, kernel_cmdline, cmdline_size -1 ); + } + + kern_boot =guest_real_to_host (kvm,BOOT_LOADER_SELECTOR ,0x00 ); + + kern_boot->hdr.cmd_line_ptr =BOOT_CMDLINE_OFFSET ; + kern_boot->hdr.type_of_loader =0xff ; + kern_boot->hdr.heap_end_ptr =0xfe00 ; + kern_boot->hdr.loadflags |=CAN_USE_HEAP ; + kern_boot->hdr.vid_mode = vidmode; + +/* +* Read initrd image into guest memory +*/ +if (fd_initrd >=0 ) { +struct stat initrd_stat; +unsigned long addr; + +if (fstat (fd_initrd, &initrd_stat)) +die_perror ("fstat" ); + + addr = boot.hdr.initrd_addr_max & ~0xfffff ; +for (;;) { +if (addr <BZ_KERNEL_START ) +die ("Not enough memory for initrd" ); +else if (addr < (kvm->ram_size - initrd_stat.st_size)) +break ; + addr -=0x100000 ; + } + + p =guest_flat_to_host (kvm, addr); + nr =read (fd_initrd, p, initrd_stat.st_size); +if (nr != initrd_stat.st_size) +die ("Failed to read initrd" ); + + kern_boot->hdr.ramdisk_image = addr; + kern_boot->hdr.ramdisk_size = initrd_stat.st_size; + } + + kvm->boot_selector =BOOT_LOADER_SELECTOR ; +/* +* The real-mode setup code starts at offset 0x200 of a bzImage. See +* Documentation/x86/boot.txt for details. +*/ + kvm->boot_ip =BOOT_LOADER_IP +0x200 ; + kvm->boot_sp =BOOT_LOADER_SP ; + +return true; +} + +/** +* kvm__arch_setup_firmware - inject BIOS into guest system memory +* @kvm - guest system descriptor +* +* This function is a main routine where we poke guest memory +* and install BIOS there. +*/ +void kvm__arch_setup_firmware (struct kvm *kvm) +{ +/* standart minimal configuration */ +setup_bios (kvm); + +/* FIXME: SMP, ACPI and friends here */ + +/* MP table */ +mptable_setup (kvm, kvm->nrcpus); +}tools/kvm/x86/mptable.c renamed from tools/kvm/mptable.c +0
-1--To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Sasha.
Quoted 3 lines · Sasha Levin
The code doesn't build after this patch due to missing header issues which you fixed in patches #10 & #11. Could you please move those two to the beginning of the series for the sake of bisectablilty?
I did that myself. Patches 10, 11, and 1 applied, thanks!
PATCH 2/28 kvm tools: Only build/init i8042 on x86
In reply to a message not in the archiveNot every architecture has an i8042 kbd controller, so only use this when building for x86.
--- tools/kvm/Makefile | 2 +- tools/kvm/builtin-run.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-)
tools/kvm/Makefile +1 -1
@@ -77,7 +77,6 @@ OBJS += util/strbuf.o OBJS += virtio/9p.o OBJS += virtio/9p-pdu.o OBJS += hw/vesa.o -OBJS += hw/i8042.o OBJS += hw/pci-shmem.o OBJS += kvm-ipc.o
@@ -153,6 +152,7 @@ ifeq ($(ARCH),x86) OBJS += x86/kvm.o OBJS += x86/kvm-cpu.o OBJS += x86/mptable.o + OBJS += hw/i8042.o # Exclude BIOS object files from header dependencies. OTHEROBJS += x86/bios.o OTHEROBJS += x86/bios/bios-rom.o
tools/kvm/builtin-run.c +2 -0
@@ -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);
Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86
For some reason I can't explain, I'm getting this error after applying this patch:
Applying: kvm tools: Only build/init i8042 on x86
fatal: mode change for tools/kvm/bios.c, which is not in current HEAD Repository lacks necessary blobs to fall back on 3-way merge. Cannot fall back to three-way merge.
Patch failed at 0002 kvm tools: Only build/init i8042 on x86
Any idea why it would happen?
Quoted 47 lines · Matt Evans
Not every architecture has an i8042 kbd controller, so only use this when building for x86.
Signed-off-by Matt Evans <[email protected]>--- tools/kvm/Makefile | 2 +- tools/kvm/builtin-run.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-)tools/kvm/Makefile +1
-1@@ -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.otools/kvm/builtin-run.c +2
-1@@ -941,7 +941,9 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)kvm__init_ram (kvm); +#ifdef CONFIG_X86 kbd__init (kvm); +#endif pci_shmem__init (kvm); --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Sasha.
Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86
In reply to Matt EvansQuoted 2 lines · Matt Evans
Not every architecture has an i8042 kbd controller, so only use this when building for x86.
There are non-x86 machines that have one, though -- does KVM tool have any sort of target configuration mechanism?
-Scott
Re: [PATCH 02/28] kvm tools: Only build/init i8042 on x86
Quoted 6 lines · Scott Wood
Quoted 2 lines · Matt Evans
Not every architecture has an i8042 kbd controller, so only use this when building for x86.
There are non-x86 machines that have one, though -- does KVM tool have any sort of target configuration mechanism?
See my other mail (of 1m ago), there isn't a configuration mechanism nor a way to select devices at run-time (nor buses to attach them to, etc.). This patch is a bit of a hack, though there's no other way without the extra infrastructure. This patch will get a 2nd platform going, and can be revisited when another rears its head.
Cheers,
Matt
PATCH 3/28 kvm tools: Add Makefile parameter for kernel include path
In reply to a message not in the archiveThis patch adds an 'I' parameter to override the default kernel include path of '../../include'.
--- tools/kvm/Makefile | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
tools/kvm/Makefile +7 -2
@@ -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
PATCH 4/28 kvm tools: Re-arrange Makefile to heed CFLAGS before checking for optional libs
In reply to a message not in the archiveThe checks for optional libraries build code to perform the tests, so should respect certain CFLAGS -- in particular, -m64 so we check for 64bit libraries if they're required.
--- tools/kvm/Makefile | 86 ++++++++++++++++++++++++++------------------------- 1 files changed, 44 insertions(+), 42 deletions(-)
tools/kvm/Makefile +44 -42
@@ -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)
PATCH 5/28 kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
In reply to a message not in the archiveOn LP64 systems our u64s are just longs; remove the %llx'es in favour of PRIx64 etc.
This patch also adds CFLAGS to the final link, so that any -m64 is obeyed when linking, too.
--- tools/kvm/Makefile | 2 +- tools/kvm/builtin-run.c | 14 ++++++++------ tools/kvm/builtin-stat.c | 4 +++- tools/kvm/disk/core.c | 4 +++- tools/kvm/mmio.c | 4 +++- 5 files changed, 18 insertions(+), 10 deletions(-)
tools/kvm/Makefile +1 -1
@@ -218,7 +218,7 @@ KVMTOOLS-VERSION-FILE: $(PROGRAM): $(DEPS) $(OBJS) $(E) " LINK " $@ - $(Q) $(CC) $(OBJS) $(LIBS) -o $@ + $(Q) $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $@ $(GUEST_INIT): guest/init.c $(E) " LINK " $@
tools/kvm/builtin-run.c +8 -6
@@ -42,6 +42,8 @@#include <stdlib.h> #include <string.h> #include <unistd.h> +#define __STDC_FORMAT_MACROS +#include <inttypes.h> #include <ctype.h> #include <stdio.h>
@@ -383,8 +385,8 @@ static int shmem_parser(const struct option *opt, const char *arg, int unset)strcpy (handle, default_handle); }if (verbose) { -pr_info ("shmem: phys_addr = %llx" , phys_addr); -pr_info ("shmem: size = %llx" , size); +pr_info ("shmem: phys_addr = %" PRIx64, phys_addr); +pr_info ("shmem: size = %" PRIx64, size);pr_info ("shmem: handle = %s" , handle);pr_info ("shmem: create = %d" , create); }
@@ -545,7 +547,7 @@ panic_kvm: current_kvm_cpu->kvm_run->exit_reason, kvm_exit_reasons[current_kvm_cpu->kvm_run->exit_reason]);if (current_kvm_cpu->kvm_run->exit_reason ==KVM_EXIT_UNKNOWN ) -fprintf (stderr,"KVM exit code: 0x%Lu\n" , +fprintf (stderr,"KVM exit code: 0x%" PRIx64"\n" , current_kvm_cpu->kvm_run->hw.hardware_exit_reason);kvm_cpu__set_debug_fd (STDOUT_FILENO );
@@ -760,10 +762,10 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) ram_size =get_ram_size (nrcpus);if (ram_size <MIN_RAM_SIZE_MB ) -die ("Not enough memory specified: %lluMB (min %lluMB)" , ram_size,MIN_RAM_SIZE_MB ); +die ("Not enough memory specified: %" PRIu64"MB (min %lluMB)" , ram_size,MIN_RAM_SIZE_MB );if (ram_size >host_ram_size ()) -pr_warning ("Guest memory size %lluMB exceeds host physical RAM size %lluMB" , ram_size,host_ram_size ()); +pr_warning ("Guest memory size %" PRIu64"MB exceeds host physical RAM size %" PRIu64"MB" , ram_size,host_ram_size ()); ram_size <<=MB_SHIFT ;
@@ -878,7 +880,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)virtio_blk__init_all (kvm); } -printf (" # kvm run -k %s -m %Lu -c %d --name %s\n" , kernel_filename, ram_size /1024 /1024 , nrcpus, guest_name); +printf (" # kvm run -k %s -m %" PRId64" -c %d --name %s\n" , kernel_filename, ram_size /1024 /1024 , nrcpus, guest_name);if (!kvm__load_kernel (kvm, kernel_filename, initrd_filename, real_cmdline, vidmode))
tools/kvm/builtin-stat.c +3 -1
@@ -9,6 +9,8 @@#include <stdio.h> #include <string.h> #include <signal.h> +#define __STDC_FORMAT_MACROS +#include <inttypes.h> #include <linux/virtio_balloon.h>
@@ -97,7 +99,7 @@ static int do_memstat(const char *name, int sock)printf ("The total amount of memory available (in bytes):" );break ; } -printf ("%llu\n" , stats[i].val); +printf ("%" PRId64"\n" , stats[i].val); }printf ("\n" );
tools/kvm/disk/core.c +3 -1
@@ -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 *lif (fstat (disk->fd, &st) !=0 )return 0 ; - *len =snprintf (buffer, *len,"%llu%llu%llu" , (u64 )st.st_dev, (u64 )st.st_rdev, (u64 )st.st_ino); + *len =snprintf (buffer, *len,"%" PRId64"%" PRId64"%" PRId64, (u64 )st.st_dev, (u64 )st.st_rdev, (u64 )st.st_ino);return *len; }
tools/kvm/mmio.c +3 -1
@@ -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 ();
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Ingo actually got us to remove all the PRI* specifiers, but that was back when we only did x86 :)
Ingo, does it make sense to use them now when we support different architectures?
Quoted 153 lines · Matt Evans
On LP64 systems our u64s are just longs; remove the %llx'es in favour of PRIx64 etc.
This patch also adds CFLAGS to the final link, so that any -m64 is obeyed when linking, too.
Signed-off-by Matt Evans <[email protected]>--- tools/kvm/Makefile | 2 +- tools/kvm/builtin-run.c | 14 ++++++++------ tools/kvm/builtin-stat.c | 4 +++- tools/kvm/disk/core.c | 4 +++- tools/kvm/mmio.c | 4 +++- 5 files changed, 18 insertions(+), 10 deletions(-)tools/kvm/Makefile +1
-1@@ -218,7 +218,7 @@ KVMTOOLS-VERSION-FILE: $(PROGRAM): $(DEPS) $(OBJS) $(E) " LINK " $@ - $(Q) $(CC) $(OBJS) $(LIBS) -o $@ + $(Q) $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $@ $(GUEST_INIT): guest/init.c $(E) " LINK " $@tools/kvm/builtin-run.c +8
-6@@ -42,6 +42,8 @@#include <stdlib.h> #include <string.h> #include <unistd.h> +#define __STDC_FORMAT_MACROS +#include <inttypes.h> #include <ctype.h> #include <stdio.h> @@ -383,8 +385,8 @@ static int shmem_parser(const struct option *opt, const char *arg, int unset)strcpy (handle, default_handle); }if (verbose) { -pr_info ("shmem: phys_addr = %llx" , phys_addr); -pr_info ("shmem: size = %llx" , size); +pr_info ("shmem: phys_addr = %" PRIx64, phys_addr); +pr_info ("shmem: size = %" PRIx64, size);pr_info ("shmem: handle = %s" , handle);pr_info ("shmem: create = %d" , create); }@@ -545,7 +547,7 @@ panic_kvm: current_kvm_cpu->kvm_run->exit_reason, kvm_exit_reasons[current_kvm_cpu->kvm_run->exit_reason]);if (current_kvm_cpu->kvm_run->exit_reason =KVM_EXIT_UNKNOWN ) -fprintf (stderr,"KVM exit code: 0x%Lu\n" , +fprintf (stderr,"KVM exit code: 0x%" PRIx64"\n" , current_kvm_cpu->kvm_run->hw.hardware_exit_reason);kvm_cpu__set_debug_fd (STDOUT_FILENO );@@ -760,10 +762,10 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) ram_size =get_ram_size (nrcpus);if (ram_size <MIN_RAM_SIZE_MB ) -die ("Not enough memory specified: %lluMB (min %lluMB)" , ram_size,MIN_RAM_SIZE_MB ); +die ("Not enough memory specified: %" PRIu64"MB (min %lluMB)" , ram_size,MIN_RAM_SIZE_MB );if (ram_size >host_ram_size ()) -pr_warning ("Guest memory size %lluMB exceeds host physical RAM size %lluMB" , ram_size,host_ram_size ()); +pr_warning ("Guest memory size %" PRIu64"MB exceeds host physical RAM size %" PRIu64"MB" , ram_size,host_ram_size ()); ram_size <<=MB_SHIFT ;@@ -878,7 +880,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)virtio_blk__init_all (kvm); } -printf (" # kvm run -k %s -m %Lu -c %d --name %s\n" , kernel_filename, ram_size /1024 /1024 , nrcpus, guest_name); +printf (" # kvm run -k %s -m %" PRId64" -c %d --name %s\n" , kernel_filename, ram_size /1024 /1024 , nrcpus, guest_name);if (!kvm__load_kernel (kvm, kernel_filename, initrd_filename, real_cmdline, vidmode))tools/kvm/builtin-stat.c +3
-1@@ -9,6 +9,8 @@#include <stdio.h> #include <string.h> #include <signal.h> +#define __STDC_FORMAT_MACROS +#include <inttypes.h> #include <linux/virtio_balloon.h> @@ -97,7 +99,7 @@ static int do_memstat(const char *name, int sock)printf ("The total amount of memory available (in bytes):" );break ; } -printf ("%llu\n" , stats[i].val); +printf ("%" PRId64"\n" , stats[i].val); }printf ("\n" );tools/kvm/disk/core.c +3
-1@@ -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 *lif (fstat (disk->fd, &st) !=0 )return 0 ; - *len =snprintf (buffer, *len,"%llu%llu%llu" , (u64 )st.st_dev, (u64 )st.st_rdev, (u64 )st.st_ino); + *len =snprintf (buffer, *len,"%" PRId64"%" PRId64"%" PRId64, (u64 )st.st_dev, (u64 )st.st_rdev, (u64 )st.st_ino);return *len; }tools/kvm/mmio.c +3
-2@@ -9,6 +9,8 @@#include <linux/kvm.h> #include <linux/types.h> #include <linux/rbtree.h> +#define __STDC_FORMAT_MACROS +#include <inttypes.h> #define mmio_node (n) rb_entry(n, struct mmio_mapping, node)@@ -124,7 +126,7 @@ bool kvm__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_if (mmio) mmio->mmio_fn (phys_addr, data, len, is_write, mmio->ptr);else -fprintf (stderr,"Warning: Ignoring MMIO %s at %016llx (length %u)\n" , +fprintf (stderr,"Warning: Ignoring MMIO %s at %016" PRIx64" (length %u)\n" ,to_direction (is_write), phys_addr, len);br_read_unlock (); --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Sasha.
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 5 lines · Sasha Levin
Ingo actually got us to remove all the PRI* specifiers, but that was back when we only did x86 :)
Ingo, does it make sense to use them now when we support different architectures?
Not at all - ppc should use a sane u64/s64 definition, i.e. int-ll64.h instead of the int-l64.h crap.
The powerpc maintainers indicated that they'd fix that, a couple of years ago, but nothing appears to have come out of that.
Thanks,
Ingo
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 6 lines · Ingo Molnar
Quoted 3 lines · Sasha Levin
Ingo actually got us to remove all the PRI* specifiers, but that was back when we only did x86 :)
Quoted 8 lines
Quoted 2 lines
Ingo, does it make sense to use them now when we support different architectures?
Not at all - ppc should use a sane u64/s64 definition, i.e.
int-ll64.hinstead of theint-l64.hcrap.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.
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 13 lines · Paul Mackerras
Quoted 12 lines · Ingo Molnar
Quoted 5 lines · Sasha Levin
Ingo actually got us to remove all the PRI* specifiers, but that was back when we only did x86 :)
Ingo, does it make sense to use them now when we support different architectures?
Not at all - ppc should use a sane u64/s64 definition, i.e.
int-ll64.hinstead of theint-l64.hcrap.
Quoted 6 lines
Quoted 2 lines
The powerpc maintainers indicated that they'd fix that, a couple of years ago, but nothing appears to have come out of that.
We changed it for the kernel, but not for userspace (i.e. glibc) because of concerns about possibly breaking existing userspace programs. [...]
Indeed, you do:
#if defined(__powerpc64__) && !defined(__KERNEL__)
# include <asm-generic/int-l64.h> #else # include <asm-generic/int-ll64.h> #endif
which correctly uses int-ll64.h everywhere except 64-bit userspace inclusions. So i take back my 'nothing appears to have come out of that' comment - it's all nicely fixed!
Quoted 3 lines
[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.
In tools/kvm/ we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick up int-l64.h accidentally via the arch/powerpc/include/asm/types.h exception for user-space.
Stray uses of int64 should be converted to u64 (i see some in tools/kvm/virtio/9p-pdu.c) but otherwise we should be ok - unless i'm missing some complication.
Thanks,
Ingo
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Hi Ingo,
Quoted 35 lines · Ingo Molnar
Quoted 13 lines · Paul Mackerras
Quoted 12 lines · Ingo Molnar
Quoted 5 lines · Sasha Levin
Ingo actually got us to remove all the PRI* specifiers, but that was back when we only did x86 :)
Ingo, does it make sense to use them now when we support different architectures?
Not at all - ppc should use a sane u64/s64 definition, i.e.
int-ll64.hinstead of theint-l64.hcrap.Quoted 6 lines
Quoted 2 lines
The powerpc maintainers indicated that they'd fix that, a couple of years ago, but nothing appears to have come out of that.
We changed it for the kernel, but not for userspace (i.e. glibc) because of concerns about possibly breaking existing userspace programs. [...]
Indeed, you do:
#if
defined(__powerpc64__)&& !defined(__KERNEL__)# include <asm-generic/int-l64.h> #else # include <asm-generic/int-ll64.h> #endifwhich correctly uses
int-ll64.heverywhere except 64-bit userspace inclusions. So i take back my 'nothing appears to have come out of that' comment - it's all nicely fixed!
Quoted 8 lines
Quoted 3 lines
[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.In
tools/kvm/we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick upint-l64.haccidentally via thearch/powerpc/include/asm/types.hexception 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
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines
[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.In
tools/kvm/we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick upint-l64.haccidentally via thearch/powerpc/include/asm/types.hexception for user-space.
Quoted 7 lines
That's what's happening here; we're
__powerpc64__and !__KERNEL__,tools/kvm/include/linux/types.hincludesasm/types.hso gets theint-l64.hdefinition of__u64, as above. :/builtin-run.c:389: error: format
%llx' expects typelong 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
Paolo Bonzini
maintainerRe: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 5 lines · Ingo Molnar
Quoted 5 lines
Quoted 5 lines
That's what's happening here; we're
__powerpc64__and !__KERNEL__,tools/kvm/include/linux/types.hincludesasm/types.hso gets theint-l64.hdefinition of__u64, as above. :/
Quoted 8 lines
Quoted 2 lines
Quoted 2 lines
builtin-run.c:389: error: format
%llx' expects typelong long unsigned int', but argument 2 has type `u64'So either define
__KERNEL__or patch a__NEW_USERSPACE__define intopower/asm/types.hand 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
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 13 lines · Ingo Molnar
Quoted 13 lines
Quoted 7 lines
Quoted 7 lines
That's what's happening here; we're
__powerpc64__and !__KERNEL__,tools/kvm/include/linux/types.hincludesasm/types.hso gets theint-l64.hdefinition of__u64, as above. :/builtin-run.c:389: error: format
%llx' expects typelong long unsigned int', but argument 2 has type `u64'So either define
__KERNEL__or patch a__NEW_USERSPACE__define intopower/asm/types.hand use it - if the PowerPC folks agree with that approach.Sane userspace should not be prevented from using the same sane types the kernel is already using:-)
Quoted 1 line · Paolo Bonzini
I should dig up that patent of mine for "apparatus for conversion of circular motion to rectilinear ('wheel')".
What's your point?
We use kernel types for obvious reasons and it trying to use <stdint.h> for the PPC port is just begging for trouble.
Pekka
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
In reply to Ingo MolnarQuoted 20 lines · Ingo Molnar
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines
[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.In
tools/kvm/we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick upint-l64.haccidentally via thearch/powerpc/include/asm/types.hexception for user-space.Quoted 7 lines
That's what's happening here; we're
__powerpc64__and !__KERNEL__,tools/kvm/include/linux/types.hincludesasm/types.hso gets theint-l64.hdefinition of__u64, as above. :/builtin-run.c:389: error: format
%llx' expects typelong long unsigned int', but argument 2 has type `u64'
Quoted 6 lines
So either define
__KERNEL__or patch a__NEW_USERSPACE__define intopower/asm/types.hand 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
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 26 lines · Pekka Enberg
Quoted 24 lines · Ingo Molnar
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines
[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.In
tools/kvm/we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick upint-l64.haccidentally via thearch/powerpc/include/asm/types.hexception for user-space.Quoted 7 lines
That's what's happening here; we're
__powerpc64__and !__KERNEL__,tools/kvm/include/linux/types.hincludesasm/types.hso gets theint-l64.hdefinition of__u64, as above. :/builtin-run.c:389: error: format
%llx' expects typelong long unsigned int', but argument 2 has type `u64'So either define
__KERNEL__or patch a__NEW_USERSPACE__define intopower/asm/types.hand use it - if the PowerPC folks agree with that approach.
Quoted 5 lines
Quoted 2 lines
Sane userspace should not be prevented from using the same sane types the kernel is already using :-)
How does perf handle this? I'm sure it has the exact same issue, doesn't it?
It does; ironically it uses PRIblah, so I had followed its example.
Cheers,
Matt
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 27 lines · Matt Evans
Quoted 26 lines · Pekka Enberg
Quoted 24 lines · Ingo Molnar
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines
[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.In
tools/kvm/we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick upint-l64.haccidentally via thearch/powerpc/include/asm/types.hexception for user-space.Quoted 7 lines
That's what's happening here; we're
__powerpc64__and !__KERNEL__,tools/kvm/include/linux/types.hincludesasm/types.hso gets theint-l64.hdefinition of__u64, as above. :/builtin-run.c:389: error: format
%llx' expects typelong long unsigned int', but argument 2 has type `u64'So either define
__KERNEL__or patch a__NEW_USERSPACE__define intopower/asm/types.hand use it - if the PowerPC folks agree with that approach.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Sane userspace should not be prevented from using the same sane types the kernel is already using :-)
How does perf handle this? I'm sure it has the exact same issue, doesn't it?
It does; ironically it uses PRIblah, so I had followed its example.
Sadly it regressed lately in that area - it was certainly PRIblah-less in the early stages :-)
Pekka, how do the headers react if we define __KERNEL__? Alternatively, allowing an override in powerpc/types.h beyond __KERNEL__ looks sensible as well.
Thanks,
Ingo
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 33 lines · Ingo Molnar
Quoted 30 lines · Matt Evans
Quoted 29 lines · Pekka Enberg
Quoted 26 lines · Ingo Molnar
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines
[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.In
tools/kvm/we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick upint-l64.haccidentally via thearch/powerpc/include/asm/types.hexception for user-space.Quoted 7 lines
That's what's happening here; we're
__powerpc64__and !__KERNEL__,tools/kvm/include/linux/types.hincludesasm/types.hso gets theint-l64.hdefinition of__u64, as above. :/builtin-run.c:389: error: format
%llx' expects typelong long unsigned int', but argument 2 has type `u64'So either define
__KERNEL__or patch a__NEW_USERSPACE__define intopower/asm/types.hand use it - if the PowerPC folks agree with that approach.Sane userspace should not be prevented from using the same sane types the kernel is already using :-)
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
How does perf handle this? I'm sure it has the exact same issue, doesn't it?
It does; ironically it uses PRIblah, so I had followed its example.
Sadly it regressed lately in that area - it was certainly PRIblah-less in the early stages :-)
Oh dear :-)
Quoted 3 lines
Pekka, how do the headers react if we define
__KERNEL__? Alternatively, allowing an override inpowerpc/types.hbeyond__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
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 49 lines · Matt Evans
Quoted 33 lines · Ingo Molnar
Quoted 30 lines · Matt Evans
Quoted 29 lines · Pekka Enberg
Quoted 26 lines · Ingo Molnar
Quoted 9 lines · Matt Evans
Quoted 8 lines
Quoted 3 lines
[...] I haven't looked closely at Matt's
patches, but it should be possible to use [un]signed long long for the u64/s64 types, I would think.In
tools/kvm/we are using our own u64/s64 definitions, not glibc's, so i think it should be fine - as long as we don't pick upint-l64.haccidentally via thearch/powerpc/include/asm/types.hexception for user-space.Quoted 7 lines
That's what's happening here; we're
__powerpc64__and !__KERNEL__,tools/kvm/include/linux/types.hincludesasm/types.hso gets theint-l64.hdefinition of__u64, as above. :/builtin-run.c:389: error: format
%llx' expects typelong long unsigned int', but argument 2 has type `u64'So either define
__KERNEL__or patch a__NEW_USERSPACE__define intopower/asm/types.hand use it - if the PowerPC folks agree with that approach.Sane userspace should not be prevented from using the same sane types the kernel is already using :-)
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
How does perf handle this? I'm sure it has the exact same issue, doesn't it?
It does; ironically it uses PRIblah, so I had followed its example.
Sadly it regressed lately in that area - it was certainly PRIblah-less in the early stages :-)
Oh dear :-)
Quoted 3 lines
Pekka, how do the headers react if we define
__KERNEL__? Alternatively, allowing an override inpowerpc/types.hbeyond__KERNEL__looks sensible as well.
Quoted 6 lines
Well, I just tried it and it ended in tears; various things bring in tons more (ppc) stuff from asm/, quite a few conflicts.
I've resorted to defining
__KERNEL__inlinux/types.h*only* around #include <asm/types.h> (i.e. undefining it afterwards). This picks up the correctint-ll64.hon 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
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 7 lines · Matt Evans
Since
tools/kvm/include/linux/types.honly requires__u32,__u64et 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
Re: [PATCH 05/28] kvm tools: 64-bit tidy; use PRIx64 when printf'ing u64s and link appropriately
Quoted 15 lines · Ingo Molnar
Quoted 7 lines · Matt Evans
Since
tools/kvm/include/linux/types.honly requires__u32,__u64et 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.hwith the extra__SANE_USERSPACE__define (or any suitable name) and the KVM tool should work as-is.
Quoted 5 lines
The beauty of
tools/kvm/being integrated into the kernel tree.Really, if that works and if the PowerPC folks agree then we have an immediate, fully adequate, instantly applicable solution.
Ahh, I finally understand you-- I'd earlier thought you were referring to the system headers' asm/types.h, etc. Thanks for your patience on this very trivial point :-) I'll add __SANE_USERSPACE_TYPES__ and we'll see how the others like it. >:) (Paul, that sound OK?)
Thanks,
Matt
PATCH 6/28 kvm tools: Add arch-specific KVM_RUN exit handling via kvm_cpu__handle_exit()
In reply to a message not in the archiveThis patch creates a new function in x86/kvm-cpu.c, kvm_cpu__handle_exit(), in which arch-specific exit reasons can be handled outside of the common runloop.
--- tools/kvm/include/kvm/kvm-cpu.h | 2 ++ tools/kvm/kvm-cpu.c | 10 ++++++++-- tools/kvm/x86/kvm-cpu.c | 5 +++++ 3 files changed, 15 insertions(+), 2 deletions(-)
tools/kvm/include/kvm/kvm-cpu.h +2 -0
@@ -2,6 +2,7 @@#define KVM__KVM_CPU_H #include "kvm/kvm-cpu-arch.h" +#include <stdbool.h> struct kvm_cpu *kvm_cpu__init (struct kvm *kvm,unsigned long cpu_id);void kvm_cpu__delete (struct kvm_cpu *vcpu);
@@ -11,6 +12,7 @@ void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu);void kvm_cpu__run (struct kvm_cpu *vcpu);void kvm_cpu__reboot (void );int kvm_cpu__start (struct kvm_cpu *cpu); +bool kvm_cpu__handle_exit (struct kvm_cpu *vcpu);int kvm_cpu__get_debug_fd (void );void kvm_cpu__set_debug_fd (int fd);
tools/kvm/kvm-cpu.c +8 -2
@@ -137,8 +137,14 @@ int kvm_cpu__start(struct kvm_cpu *cpu) goto exit_kvm;case KVM_EXIT_SHUTDOWN : goto exit_kvm; -default : - goto panic_kvm; +default : { +bool ret; + + ret =kvm_cpu__handle_exit (cpu); +if (!ret) + goto panic_kvm; +break ; + } }kvm_cpu__handle_coalesced_mmio (cpu); }
tools/kvm/x86/kvm-cpu.c +5 -0
@@ -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",
PATCH 7/28 kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
In reply to a message not in the archiveArchitectures can recommend/count/determine number of CPUs differently, so move this out of generic code.
--- tools/kvm/kvm.c | 30 ------------------------------ tools/kvm/x86/kvm.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 30 deletions(-)
tools/kvm/kvm.c +0 -30
@@ -259,17 +259,6 @@ void kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspacdie_perror ("KVM_SET_USER_MEMORY_REGION ioctl" ); } -int kvm__recommended_cpus (struct kvm *kvm) -{ -int ret; - - ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_NR_VCPUS ); -if (ret <=0 ) -die_perror ("KVM_CAP_NR_VCPUS" ); - -return ret; -} -static void kvm__pid (int fd,u32 type,u32 len,u8 *msg) {pid_t pid =getpid ();
@@ -282,25 +271,6 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)pr_warning ("Failed sending PID" ); } -/* -* The following hack should be removed once 'x86: Raise the hard -* VCPU count limit' makes it's way into the mainline. -*/ -#ifndef KVM_CAP_MAX_VCPUS -#define KVM_CAP_MAX_VCPUS 66 -#endif - -int kvm__max_cpus (struct kvm *kvm) -{ -int ret; - - ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_MAX_VCPUS ); -if (ret <=0 ) - ret =kvm__recommended_cpus (kvm); - -return ret; -} -struct kvm *kvm__init (const char *kvm_dev,u64 ram_size,const char *name) {struct kvm *kvm;
tools/kvm/x86/kvm.c +30 -0
@@ -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
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Why is it getting moved out of generic code?
This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS are not arch specific.
Quoted 102 lines · Matt Evans
Architectures can recommend/count/determine number of CPUs differently, so move this out of generic code.
Signed-off-by Matt Evans <[email protected]>--- tools/kvm/kvm.c | 30 ------------------------------ tools/kvm/x86/kvm.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 30 deletions(-)tools/kvm/kvm.c +0
-30@@ -259,17 +259,6 @@ void kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspacdie_perror ("KVM_SET_USER_MEMORY_REGION ioctl" ); } -int kvm__recommended_cpus (struct kvm *kvm) -{ -int ret; - - ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_NR_VCPUS ); -if (ret <=0 ) -die_perror ("KVM_CAP_NR_VCPUS" ); - -return ret; -} -static void kvm__pid (int fd,u32 type,u32 len,u8 *msg) {pid_t pid =getpid ();@@ -282,25 +271,6 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)pr_warning ("Failed sending PID" ); } -/* -* The following hack should be removed once 'x86: Raise the hard -* VCPU count limit' makes it's way into the mainline. -*/ -#ifndef KVM_CAP_MAX_VCPUS -#define KVM_CAP_MAX_VCPUS 66 -#endif - -int kvm__max_cpus (struct kvm *kvm) -{ -int ret; - - ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_MAX_VCPUS ); -if (ret <=0 ) - ret =kvm__recommended_cpus (kvm); - -return ret; -} -struct kvm *kvm__init (const char *kvm_dev,u64 ram_size,const char *name) {struct kvm *kvm;tools/kvm/x86/kvm.c +30
-1@@ -76,6 +76,36 @@ bool kvm__arch_cpu_supports_vm(void)return regs.ecx & (1 << feature); } +int kvm__recommended_cpus (struct kvm *kvm) +{ +int ret; + + ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_NR_VCPUS ); +if (ret <=0 ) +die_perror ("KVM_CAP_NR_VCPUS" ); + +return ret; +} + +/* +* The following hack should be removed once 'x86: Raise the hard +* VCPU count limit' makes it's way into the mainline. +*/ +#ifndef KVM_CAP_MAX_VCPUS +#define KVM_CAP_MAX_VCPUS 66 +#endif + +int kvm__max_cpus (struct kvm *kvm) +{ +int ret; + + ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_MAX_VCPUS ); +if (ret <=0 ) + ret =kvm__recommended_cpus (kvm); + +return ret; +} +/* * Allocating RAM size bigger than 4GB requires us to leave a gap * in the RAM which is used for PCI MMIO, hotplug, and unconfigured -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Sasha.
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 5 lines · Sasha Levin
Why is it getting moved out of generic code?
This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know
KVM_CAP_NR_VCPUSandKVM_CAP_MAX_VCPUSare not arch specific.
I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if KVM_CAP_NR_VCPUS fails, use 4" instead of die(); you'll see that when I repost.
This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)
Thanks,
Matt
Quoted 105 lines · Matt Evans
Quoted 102 lines
Architectures can recommend/count/determine number of CPUs differently, so move this out of generic code.
Signed-off-by Matt Evans <[email protected]>--- tools/kvm/kvm.c | 30 ------------------------------ tools/kvm/x86/kvm.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 30 deletions(-)tools/kvm/kvm.c +0
-30@@ -259,17 +259,6 @@ void kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspacdie_perror ("KVM_SET_USER_MEMORY_REGION ioctl" ); } -int kvm__recommended_cpus (struct kvm *kvm) -{ -int ret; - - ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_NR_VCPUS ); -if (ret <=0 ) -die_perror ("KVM_CAP_NR_VCPUS" ); - -return ret; -} -static void kvm__pid (int fd,u32 type,u32 len,u8 *msg) {pid_t pid =getpid ();@@ -282,25 +271,6 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)pr_warning ("Failed sending PID" ); } -/* -* The following hack should be removed once 'x86: Raise the hard -* VCPU count limit' makes it's way into the mainline. -*/ -#ifndef KVM_CAP_MAX_VCPUS -#define KVM_CAP_MAX_VCPUS 66 -#endif - -int kvm__max_cpus (struct kvm *kvm) -{ -int ret; - - ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_MAX_VCPUS ); -if (ret <=0 ) - ret =kvm__recommended_cpus (kvm); - -return ret; -} -struct kvm *kvm__init (const char *kvm_dev,u64 ram_size,const char *name) {struct kvm *kvm;tools/kvm/x86/kvm.c +30
-1@@ -76,6 +76,36 @@ bool kvm__arch_cpu_supports_vm(void)return regs.ecx & (1 << feature); } +int kvm__recommended_cpus (struct kvm *kvm) +{ +int ret; + + ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_NR_VCPUS ); +if (ret <=0 ) +die_perror ("KVM_CAP_NR_VCPUS" ); + +return ret; +} + +/* +* The following hack should be removed once 'x86: Raise the hard +* VCPU count limit' makes it's way into the mainline. +*/ +#ifndef KVM_CAP_MAX_VCPUS +#define KVM_CAP_MAX_VCPUS 66 +#endif + +int kvm__max_cpus (struct kvm *kvm) +{ +int ret; + + ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_MAX_VCPUS ); +if (ret <=0 ) + ret =kvm__recommended_cpus (kvm); + +return ret; +} +/* * Allocating RAM size bigger than 4GB requires us to leave a gap * in the RAM which is used for PCI MMIO, hotplug, and unconfigured -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin
Why is it getting moved out of generic code?
This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know
KVM_CAP_NR_VCPUSandKVM_CAP_MAX_VCPUSare not arch specific.
Quoted 7 lines
I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if
KVM_CAP_NR_VCPUSfails, use 4" instead ofdie(); you'll see that when I repost.This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)
I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in kvmppc_core_vcpu_create() in the book3s code:
vcpu = kvmppc_core_vcpu_create(kvm, id); vcpu->arch.wqp = &vcpu->wq; if (!IS_ERR(vcpu)) kvmppc_create_vcpu_debugfs(vcpu, id);
This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.
Signature · 1 line
Sasha.
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 19 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin
Why is it getting moved out of generic code?
This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know
KVM_CAP_NR_VCPUSandKVM_CAP_MAX_VCPUSare not arch specific.Quoted 7 lines
I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if
KVM_CAP_NR_VCPUSfails, use 4" instead ofdie(); you'll see that when I repost.This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)
I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in
kvmppc_core_vcpu_create()in the book3s code:
Quoted 7 lines
vcpu = kvmppc_core_vcpu_create(kvm, id); vcpu->arch.wqp = &vcpu->wq; if (!IS_ERR(vcpu)) kvmppc_create_vcpu_debugfs(vcpu, id);This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.
Yeah, that's b0rk. Alex, a patch below. :)
Cheers,
Matt
---
Subject: [PATCH] KVM: PPC: Fix vcpu_create dereference before validity check.
--- arch/powerpc/kvm/powerpc.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-)
arch/powerpc/kvm/powerpc.c +3 -2
@@ -285,9 +285,10 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) {struct kvm_vcpu *vcpu; vcpu =kvmppc_core_vcpu_create (kvm, id); - vcpu->arch.wqp = &vcpu->wq; -if (!IS_ERR (vcpu)) +if (!IS_ERR (vcpu)) { + vcpu->arch.wqp = &vcpu->wq;kvmppc_create_vcpu_debugfs (vcpu, id); + }return vcpu; }
Signature · 1 line
1.7.0.4
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 25 lines · Matt Evans
Quoted 24 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin
Why is it getting moved out of generic code?
This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know
KVM_CAP_NR_VCPUSandKVM_CAP_MAX_VCPUSare not arch specific.Quoted 7 lines
I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if
KVM_CAP_NR_VCPUSfails, use 4" instead ofdie(); you'll see that when I repost.This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)
I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in
kvmppc_core_vcpu_create()in the book3s code:vcpu = kvmppc_core_vcpu_create(kvm, id); vcpu->arch.wqp = &vcpu->wq; if (!IS_ERR(vcpu)) kvmppc_create_vcpu_debugfs(vcpu, id);
Quoted 4 lines
Quoted 2 lines
This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.
Yeah, that's b0rk. Alex, a patch below. :)
Thanks :). Will apply asap but don't have a real keyboard today :).
I suppose this is stable material?
Alex
Quoted 1 line
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 28 lines · Alexander Graf
Quoted 25 lines · Matt Evans
Quoted 24 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin
Why is it getting moved out of generic code?
This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know
KVM_CAP_NR_VCPUSandKVM_CAP_MAX_VCPUSare not arch specific.Quoted 7 lines
I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if
KVM_CAP_NR_VCPUSfails, use 4" instead ofdie(); you'll see that when I repost.This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)
I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in
kvmppc_core_vcpu_create()in the book3s code:vcpu = kvmppc_core_vcpu_create(kvm, id); vcpu->arch.wqp = &vcpu->wq; if (!IS_ERR(vcpu)) kvmppc_create_vcpu_debugfs(vcpu, id);
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.
Yeah, that's b0rk. Alex, a patch below. :)
Thanks :). Will apply asap but don't have a real keyboard today :).
Ha! Voice control on your phone, what could go wrong?
Quoted 1 line
I suppose this is stable material?
Good idea, (and if we're formal,
). I suppose no one's seen a vcpu fail to be created, yet.
Thanks,
Matt
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 36 lines · Matt Evans
Quoted 28 lines · Alexander Graf
Quoted 25 lines · Matt Evans
Quoted 24 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin
Why is it getting moved out of generic code?
This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know
KVM_CAP_NR_VCPUSandKVM_CAP_MAX_VCPUSare not arch specific.Quoted 7 lines
I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if
KVM_CAP_NR_VCPUSfails, use 4" instead ofdie(); you'll see that when I repost.This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)
I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in
kvmppc_core_vcpu_create()in the book3s code:vcpu = kvmppc_core_vcpu_create(kvm, id); vcpu->arch.wqp = &vcpu->wq; if (!IS_ERR(vcpu)) kvmppc_create_vcpu_debugfs(vcpu, id);Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.
Yeah, that's b0rk. Alex, a patch below. :)
Thanks :). Will apply asap but don't have a real keyboard today :).
Quoted 7 lines
Ha! Voice control on your phone, what could go wrong?
Quoted 1 line
I suppose this is stable material?
Good idea, (and if we're formal,
Signed-off-by Matt Evans <[email protected]>). I suppose no one's seen a vcpu fail to be created, yet.
I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?
---
From: Sasha Levin <[email protected]>
Date: Wed, 7 Dec 2011 10:24:56 +0200
Subject: [PATCH] KVM: PPC: Use the vcpu kmem_cache when allocating new VCPUs
Currently the code kzalloc()s new VCPUs instead of using the kmem_cache which is created when KVM is initialized.
Modify it to allocate VCPUs from that kmem_cache.
--- arch/powerpc/kvm/book3s_hv.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
arch/powerpc/kvm/book3s_hv.c +3 -3
@@ -411,7 +411,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) goto out; err = -ENOMEM ; - vcpu =kzalloc (sizeof (struct kvm_vcpu ),GFP_KERNEL ); + vcpu =kmem_cache_zalloc (kvm_vcpu_cache,GFP_KERNEL );if (!vcpu) goto out;
@@ -463,7 +463,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)return vcpu; free_vcpu: -kfree (vcpu); +kmem_cache_free (kvm_vcpu_cache, vcpu); out:return ERR_PTR (err); }
@@ -471,7 +471,7 @@ out:void kvmppc_core_vcpu_free (struct kvm_vcpu *vcpu) {kvm_vcpu_uninit (vcpu); -kfree (vcpu); +kmem_cache_free (kvm_vcpu_cache, vcpu); }static void kvmppc_set_timer (struct kvm_vcpu *vcpu)
Signature · 1 line
Sasha.
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 4 lines · Sasha Levin
I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?
qemu offers free ppc shells
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Sasha Levin
I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?
qemu offers free ppc shells
qemu would let me nest a guest inside a ppc guest on my x86?
Signature · 1 line
Sasha.
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 10 lines · Sasha Levin
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Sasha Levin
I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?
qemu offers free ppc shells
qemu would let me nest a guest inside a ppc guest on my x86?
On supervisor mode only (trap-and-emulate virtualization); I don't think qemu emulates ppc hypervisor mode.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 8 lines · Avi Kivity
Quoted 7 lines · Sasha Levin
Quoted 6 lines · Avi Kivity
Quoted 4 lines · Sasha Levin
I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
qemu offers free ppc shells
qemu would let me nest a guest inside a ppc guest on my x86?
On supervisor mode only (trap-and-emulate virtualization); I don't think qemu emulates ppc hypervisor mode.
Yup, that should work for PR KVM. I'm not sure Matt's patches work in that mode though.
So you should be able to run qemu-system-ppc64 -M pseries -nographic to emulate a ppc box and then do the same in the guest with -enable-kvm.
If that works, you can try with kvm tool in the first guest :).
Alex
Quoted 1 line
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 14 lines · Alexander Graf
Quoted 12 lines · Avi Kivity
Quoted 10 lines · Sasha Levin
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Sasha Levin
I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?
qemu offers free ppc shells
qemu would let me nest a guest inside a ppc guest on my x86?
Quoted 8 lines
Quoted 2 lines
On supervisor mode only (trap-and-emulate virtualization); I don't think qemu emulates ppc hypervisor mode.
Yup, that should work for PR KVM. I'm not sure Matt's patches work in that mode though.
So you should be able to run qemu-system-ppc64 -M pseries -nographic to emulate a ppc box and then do the same in the guest with -enable-kvm.
If that works, you can try with kvm tool in the first guest :).
Tried that, got the following (qemu-kvm-1.0 on qemu-kvm.git):
LINK ppc64-softmmu/qemu-system-ppc64../libhw64/i8259.o: In function `kvm_i8259_set_irq':/root/work/src/qemu-kvm/hw/i8259.c:707: undefined reference to apic_set_irq_delivered' ../libhw64/i8259.o: In function pic_read_irq':/root/work/src/qemu-kvm/hw/i8259.c:240: undefined reference to timer_acks' /root/work/src/qemu-kvm/hw/i8259.c:241: undefined reference to timer_ints_to_push'
collect2: ld returned 1 exit status
make[1]: *** [qemu-system-ppc64] Error 1
make: *** [subdir-ppc64-softmmu] Error 2
What am I doing wrong?
Signature · 1 line
Sasha.
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 36 lines · Sasha Levin
Quoted 14 lines · Alexander Graf
Quoted 12 lines · Avi Kivity
Quoted 10 lines · Sasha Levin
Quoted 7 lines · Avi Kivity
Quoted 4 lines · Sasha Levin
I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?
qemu offers free ppc shells
qemu would let me nest a guest inside a ppc guest on my x86?
Quoted 8 lines
Quoted 2 lines
On supervisor mode only (trap-and-emulate virtualization); I don't think qemu emulates ppc hypervisor mode.
Yup, that should work for PR KVM. I'm not sure Matt's patches work in that mode though.
So you should be able to run qemu-system-ppc64 -M pseries -nographic to emulate a ppc box and then do the same in the guest with -enable-kvm.
If that works, you can try with kvm tool in the first guest :).
Tried that, got the following (qemu-kvm-1.0 on qemu-kvm.git):
LINK ppc64-softmmu/qemu-system-ppc64
../libhw64/i8259.o: In function `kvm_i8259_set_irq':/root/work/src/qemu-kvm/hw/i8259.c:707: undefined reference toapic_set_irq_delivered' ../libhw64/i8259.o: In functionpic_read_irq':/root/work/src/qemu-kvm/hw/i8259.c:240: undefined reference totimer_acks' /root/work/src/qemu-kvm/hw/i8259.c:241: undefined reference totimer_ints_to_push'
collect2: ld returned 1 exit status
make[1]: *** [qemu-system-ppc64] Error 1
make: *** [subdir-ppc64-softmmu] Error 2
Quoted 1 line
What am I doing wrong?
You're probably using the wrong tree :). The qemu-kvm fork used to work a while back, but I don't autotest it. Try again with
git://git.qemu.org/qemu.git
and make sure to have libfdt installed :)
Alex
Quoted 1 line
Re: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
In reply to Sasha LevinQuoted 41 lines · Sasha Levin
Quoted 40 lines · Matt Evans
Quoted 28 lines · Alexander Graf
Quoted 25 lines · Matt Evans
Quoted 24 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin
Why is it getting moved out of generic code?
This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know
KVM_CAP_NR_VCPUSandKVM_CAP_MAX_VCPUSare not arch specific.Quoted 7 lines
I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if
KVM_CAP_NR_VCPUSfails, use 4" instead ofdie(); you'll see that when I repost.This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)
I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in
kvmppc_core_vcpu_create()in the book3s code:vcpu = kvmppc_core_vcpu_create(kvm, id); vcpu->arch.wqp = &vcpu->wq; if (!IS_ERR(vcpu)) kvmppc_create_vcpu_debugfs(vcpu, id);Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.
Yeah, that's b0rk. Alex, a patch below. :)
Thanks :). Will apply asap but don't have a real keyboard today :).
Ha! Voice control on your phone, what could go wrong?
Quoted 1 line
I suppose this is stable material?
Quoted 7 lines
Quoted 3 lines
Good idea, (and if we're formal,
Signed-off-by Matt Evans <[email protected]>). I suppose no one's seen a vcpu fail to be created, yet.
I also got another one, but it's **completely untested** (not even compiled). Alex, Matt, any chance one of you can loan a temporary ppc shell for the upcoming tests of KVM tool/ppc KVM?
The problem with giving you a shell on a PPC box is really that the hardware Matt's work is focusing on is not available to the public yet. I could maybe try and get you access on a G5 box, but I'm not sure how useful that is to you really, as you'll only be able to run PR KVM, not HV KVM.
Quoted 22 lines
---
From: Sasha Levin <[email protected]>
Date: Wed, 7 Dec 2011 10:24:56 +0200
Subject: [PATCH] KVM: PPC: Use the vcpukmem_cachewhen allocating new VCPUsCurrently the code kzalloc()s new VCPUs instead of using the
kmem_cachewhich is created when KVM is initialized.Modify it to allocate VCPUs from that
kmem_cache.Signed-off-by Sasha Levin <[email protected]>---
arch/powerpc/kvm/book3s_hv.c| 6 +++---1 files changed, 3 insertions(+), 3 deletions(-)arch/powerpc/kvm/book3s_hv.c +0
-0
arch/powerpc/kvm/book3s_hv.c struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) · line 414
Quoted 5 lines
arch/powerpc/kvm/book3s_hv.c +1
-1@@ -411,7 +411,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) goto out; err = -ENOMEM ; - vcpu =kzalloc (sizeof (struct kvm_vcpu ),GFP_KERNEL ); + vcpu =kmem_cache_zalloc (kvm_vcpu_cache,GFP_KERNEL );
Paul, is there any rationale on why not to use the kmem cache? Are we bound by real mode magic again?
Alex
Quoted 30 lines
arch/powerpc/kvm/book3s_hv.c +0
-0if (!vcpu) goto out;@@ -463,7 +463,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)return vcpu;
free_vcpu:arch/powerpc/kvm/book3s_hv.c +1
-1-kfree (vcpu); +kmem_cache_free (kvm_vcpu_cache, vcpu);out:
return ERR_PTR(err); }arch/powerpc/kvm/book3s_hv.c +1
-1@@ -471,7 +471,7 @@ out:void kvmppc_core_vcpu_free (struct kvm_vcpu *vcpu) {kvm_vcpu_uninit (vcpu); -kfree (vcpu); +kmem_cache_free (kvm_vcpu_cache, vcpu); }static void kvmppc_set_timer (struct kvm_vcpu *vcpu)Signature · 8 lines
-- Sasha. -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Paul Mackerras
Acked-byRe: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 5 lines · Alexander Graf
arch/powerpc/kvm/book3s_hv.c struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) · line 414
Quoted 2 lines
arch/powerpc/kvm/book3s_hv.c +1
-1- vcpu =kzalloc (sizeof (struct kvm_vcpu ),GFP_KERNEL ); + vcpu =kmem_cache_zalloc (kvm_vcpu_cache,GFP_KERNEL );Paul, is there any rationale on why not to use the kmem cache? Are we bound by real mode magic again?
No, I just hadn't realized it existed. This looks fine to me.
Paul.
Alexander Graf
AppliedRe: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
Quoted 11 lines · Paul Mackerras
Quoted 5 lines · Alexander Graf
arch/powerpc/kvm/book3s_hv.c struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) · line 414
Quoted 2 lines
arch/powerpc/kvm/book3s_hv.c +1
-1- vcpu =kzalloc (sizeof (struct kvm_vcpu ),GFP_KERNEL ); + vcpu =kmem_cache_zalloc (kvm_vcpu_cache,GFP_KERNEL );Paul, is there any rationale on why not to use the kmem cache? Are we bound by real mode magic again?
No, I just hadn't realized it existed. This looks fine to me.
Acked-by Paul Mackerras <[email protected]>
Thanks, applied to kvm-ppc-next.
Alex
Alexander Graf
AppliedRe: [PATCH 07/28] kvm tools: Move 'kvm__recommended_cpus' to arch-specific code
In reply to Matt EvansQuoted 34 lines · Matt Evans
Quoted 19 lines · Sasha Levin
Quoted 7 lines · Matt Evans
Quoted 5 lines · Sasha Levin
Why is it getting moved out of generic code?
This is used to determine the maximum amount of vcpus supported by the host for a single guest, and as far as I know
KVM_CAP_NR_VCPUSandKVM_CAP_MAX_VCPUSare not arch specific.Quoted 7 lines
I checked api.txt and you're right, it isn't arch-specific. I assumed it was, because PPC KVM doesn't support it ;-) I've dropped this patch and in its place implemented the api.txt suggestion of "if
KVM_CAP_NR_VCPUSfails, use 4" instead ofdie(); you'll see that when I repost.This will have the effect of PPC being limited to 4 CPUs until the kernel supports that CAP. (I'll see about this part too.)
I went to look at which limitation PPC places on amount of vcpus in guest, and saw this in
kvmppc_core_vcpu_create()in the book3s code:Quoted 7 lines
vcpu = kvmppc_core_vcpu_create(kvm, id); vcpu->arch.wqp = &vcpu->wq; if (!IS_ERR(vcpu)) kvmppc_create_vcpu_debugfs(vcpu, id);This is wrong, right? The VCPU is dereferenced before actually checking that it's not an error.
Yeah, that's b0rk. Alex, a patch below. :)
Cheers,
Quoted 7 lines
Matt
---
Subject: [PATCH] KVM: PPC: Fixvcpu_createdereference before validity check.Signed-off-by Matt Evans <[email protected]>
Thanks, applied to kvm-ppc-next with an actual patch description added.
Alex
Quoted 24 lines
---
arch/powerpc/kvm/powerpc.c| 5 +++--1 files changed, 3 insertions(+), 2 deletions(-)arch/powerpc/kvm/powerpc.c +3
-2@@ -285,9 +285,10 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) {struct kvm_vcpu *vcpu; vcpu =kvmppc_core_vcpu_create (kvm, id); - vcpu->arch.wqp = &vcpu->wq; -if (!IS_ERR (vcpu)) +if (!IS_ERR (vcpu)) { + vcpu->arch.wqp = &vcpu->wq;kvmppc_create_vcpu_debugfs (vcpu, id); + }return vcpu; }Signature · 1 line
1.7.0.4
PATCH 8/28 kvm tools: Fix KVM_RUN exit code check
In reply to a message not in the archivekvm_cpu__run() currently die()s if KVM_RUN returns non-zero. Some architectures may return positive values in non-error cases, whereas real errors are always negative return values. Check for those instead.
--- tools/kvm/kvm-cpu.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
tools/kvm/kvm-cpu.c +1 -1
@@ -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" ); }
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
If KVM_RUN can actually return anything besides 0 or -1 it may be also worthwhile to update Documentation/virtual/kvm/api.txt .
What are the cases where it happens?
Quoted 26 lines · Matt Evans
kvm_cpu__run()currently die()s ifKVM_RUNreturns 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 <[email protected]>--- tools/kvm/kvm-cpu.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)tools/kvm/kvm-cpu.c +1
-2@@ -30,7 +30,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu)int err; err =ioctl (vcpu->vcpu_fd,KVM_RUN ,0 ); -if (err && (errno !=EINTR && errno !=EAGAIN )) +if (err <0 && (errno !=EINTR && errno !=EAGAIN ))die_perror ("KVM_RUN failed" ); } --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Sasha.
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
Quoted 4 lines · Sasha Levin
If
KVM_RUNcan actually return anything besides 0 or -1 it may be also worthwhile to updateDocumentation/virtual/kvm/api.txt.What are the cases where it happens?
Well, on PPC the internal kvmppc_run_vcpu() returns either RESUME_GUEST (which stays in-kernel and drops back to the guest) or RESUME_HOST, which is propagated back out to userland as the return value of ioctl(KVM_RUN). So, anything kvmtool sees is either <0 for error or RESUME_HOST, i.e. 2.
Alex, do you think the PPC KVM code should be forced to 0 on success, or is there any value to the expanded the return codes (and updating api.txt) for varying kinds of positive success?
Cheers,
Matt
Quoted 29 lines · Matt Evans
Quoted 26 lines
kvm_cpu__run()currently die()s ifKVM_RUNreturns 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 <[email protected]>--- tools/kvm/kvm-cpu.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)tools/kvm/kvm-cpu.c +1
-2@@ -30,7 +30,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu)int err; err =ioctl (vcpu->vcpu_fd,KVM_RUN ,0 ); -if (err && (errno !=EINTR && errno !=EAGAIN )) +if (err <0 && (errno !=EINTR && errno !=EAGAIN ))die_perror ("KVM_RUN failed" ); } --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
Quoted 6 lines · Matt Evans
Quoted 4 lines · Sasha Levin
If
KVM_RUNcan actually return anything besides 0 or -1 it may be also worthwhile to updateDocumentation/virtual/kvm/api.txt.What are the cases where it happens?
Quoted 8 lines
Well, on PPC the internal
kvmppc_run_vcpu()returns eitherRESUME_GUEST(which stays in-kernel and drops back to the guest) orRESUME_HOST, which is propagated back out to userland as the return value ofioctl(KVM_RUN). So, anything kvmtool sees is either <0 for error orRESUME_HOST, i.e. 2.Alex, do you think the PPC KVM code should be forced to 0 on success, or is there any value to the expanded the return codes (and updating api.txt) for varying kinds of positive success?
I don't think it's worth the potential ABI breakage to change the current behavior :). Even if we did change it, you would still have to touch kvm tool to work with older kernels.
Alex
Quoted 1 line
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
Quoted 13 lines · Alexander Graf
Quoted 11 lines · Matt Evans
Quoted 4 lines · Sasha Levin
If
KVM_RUNcan actually return anything besides 0 or -1 it may be also worthwhile to updateDocumentation/virtual/kvm/api.txt.What are the cases where it happens?
Well, on PPC the internal
kvmppc_run_vcpu()returns eitherRESUME_GUEST(which stays in-kernel and drops back to the guest) orRESUME_HOST, which is propagated back out to userland as the return value ofioctl(KVM_RUN). So, anything kvmtool sees is either <0 for error orRESUME_HOST, i.e. 2.
Quoted 5 lines
Quoted 3 lines
Alex, do you think the PPC KVM code should be forced to 0 on success, or is there any value to the expanded the return codes (and updating api.txt) for varying kinds of positive success?
I don't think it's worth the potential ABI breakage to change the current behavior :). Even if we did change it, you would still have to touch kvm tool to work with older kernels.
Well it deviates from api.txt, so please fix one or the other.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
Quoted 14 lines · Avi Kivity
Quoted 13 lines · Alexander Graf
Quoted 11 lines · Matt Evans
Quoted 4 lines · Sasha Levin
If
KVM_RUNcan actually return anything besides 0 or -1 it may be also worthwhile to updateDocumentation/virtual/kvm/api.txt.What are the cases where it happens?
Well, on PPC the internal
kvmppc_run_vcpu()returns eitherRESUME_GUEST(which stays in-kernel and drops back to the guest) orRESUME_HOST, which is propagated back out to userland as the return value ofioctl(KVM_RUN). So, anything kvmtool sees is either <0 for error orRESUME_HOST, i.e. 2.
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
Alex, do you think the PPC KVM code should be forced to 0 on success, or is there any value to the expanded the return codes (and updating api.txt) for varying kinds of positive success?
I don't think it's worth the potential ABI breakage to change the current behavior :). Even if we did change it, you would still have to touch kvm tool to work with older kernels.
Well it deviates from api.txt, so please fix one or the other.
Hrm - let me check all users. Maybe we can change the return argument. Will do when I'm back on a keyboard ;).
Alex
Quoted 1 line
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
Quoted 1 line · Alexander Graf
Will do when I'm back on a keyboard ;).
Siri, write a patch for bugzilla #123456 and post it upstream.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
In reply to Sasha LevinHi Sasha,
Quoted 4 lines · Sasha Levin
If
KVM_RUNcan actually return anything besides 0 or -1 it may be also worthwhile to updateDocumentation/virtual/kvm/api.txt.What are the cases where it happens?
It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's KVM_RUN return val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )
Cheers,
Matt
Quoted 29 lines · Matt Evans
Quoted 26 lines
kvm_cpu__run()currently die()s ifKVM_RUNreturns 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 <[email protected]>--- tools/kvm/kvm-cpu.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)tools/kvm/kvm-cpu.c +1
-2@@ -30,7 +30,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu)int err; err =ioctl (vcpu->vcpu_fd,KVM_RUN ,0 ); -if (err && (errno !=EINTR && errno !=EAGAIN )) +if (err <0 && (errno !=EINTR && errno !=EAGAIN ))die_perror ("KVM_RUN failed" ); } --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
Quoted 6 lines · Matt Evans
Hi Sasha,
Quoted 3 lines · Sasha Levin
If
KVM_RUNcan actually return anything besides 0 or -1 it may be also worthwhile to updateDocumentation/virtual/kvm/api.txt.
Quoted 7 lines
Quoted 1 line
What are the cases where it happens?
It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's
KVM_RUNreturn val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )
'<0' is fine as it's what api.txt says :)
Signature · 1 line
Sasha.
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
Quoted 8 lines · Sasha Levin
Quoted 6 lines
It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's
KVM_RUNreturn val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )'<0' is fine as it's what api.txt says :)
What? ioctls return -1 on error, not <0.
The syscalls do return <0, but libc converts that to -1/errno.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
Quoted 11 lines · Avi Kivity
Quoted 8 lines · Sasha Levin
Quoted 6 lines
It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's
KVM_RUNreturn val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )'<0' is fine as it's what api.txt says :)
What? ioctls return -1 on error, not <0.
<0 as opposed to the !=0 check we had there before.
Theres no harm in checking for <0 even if the only possible negative result is -1.
Quoted 3 lines
The syscalls do return <0, but libc converts that to -1/errno.
Signature · 1 line
Sasha.
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
Quoted 9 lines · Sasha Levin
Quoted 8 lines · Avi Kivity
Quoted 7 lines · Sasha Levin
Quoted 6 lines
It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's
KVM_RUNreturn val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )
Quoted 10 lines
Quoted 3 lines
Quoted 1 line
'<0' is fine as it's what api.txt says :)
What? ioctls return -1 on error, not <0.
<0 as opposed to the !=0 check we had there before.
Theres no harm in checking for <0 even if the only possible negative result is -1.
Yes, but the documentation should say -1. Which ioctl is this?
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH 08/28] kvm tools: Fix KVM_RUN exit code check
Quoted 14 lines · Avi Kivity
Quoted 13 lines · Sasha Levin
Quoted 11 lines · Avi Kivity
Quoted 8 lines · Sasha Levin
Quoted 6 lines
It sounds like Alex is considering KVM PPC's return value in this case (and updating api.txt if appropriate) -- what say you on this patch? It actually brings kvmtool's
KVM_RUNreturn val check in line with QEMU's (also "< 0") and nothing PPC will run without it, currently. (I'm about to repost a new series, will include it for these reasons, until I hear more complaint ;) )'<0' is fine as it's what api.txt says :)
What? ioctls return -1 on error, not <0.
Quoted 8 lines
Quoted 6 lines
<0 as opposed to the !=0 check we had there before.
Theres no harm in checking for <0 even if the only possible negative result is -1.
Yes, but the documentation should say -1. Which ioctl is this?
That was KVM_RUN, but the documentation on that is correct (-1), so I'm not sure what I was thinking.
On the other hand, there are several ioctls that do need fixing:
- KVM_IOEVENTFD
- KVM_PPC_GET_PVINFO
- KVM_CAP_GET_TSC_KHZ
Signature · 1 line
Sasha.
PATCH 9/28 kvm tools: Add kvm__arch_periodic_poll()
In reply to a message not in the archiveCurrently, the SIGALRM handler calls device poll functions (for serial, virtio console) directly. Which devices are present and which require polling is a system-specific decision, so create a new function called from common code & move the x86-specific poll calls into it.
--- tools/kvm/builtin-run.c | 3 +-- tools/kvm/include/kvm/kvm.h | 1 + tools/kvm/x86/kvm.c | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-)
tools/kvm/builtin-run.c +1 -2
@@ -522,8 +522,7 @@ static void handle_debug(int fd, u32 type, u32 len, u8 *msg)static void handle_sigalrm (int sig) { -serial8250__inject_interrupt (kvm); -virtio_console__inject_interrupt (kvm); +kvm__arch_periodic_poll (kvm); }static void handle_stop (int fd,u32 type,u32 len,u8 *msg)
tools/kvm/include/kvm/kvm.h +1 -0
@@ -56,6 +56,7 @@ void kvm__remove_socket(const char *name);void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,u64 ram_size,const char *name);void kvm__arch_setup_firmware (struct kvm *kvm);bool kvm__arch_cpu_supports_vm (void ); +void kvm__arch_periodic_poll (struct kvm *kvm);int load_flat_binary (struct kvm *kvm,int fd);bool load_bzimage (struct kvm *kvm,int fd_kernel,int fd_initrd,const char *kernel_cmdline,u16 vidmode);
tools/kvm/x86/kvm.c +8 -0
@@ -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); +}
PATCH 10/28 kvm tools: term.h needs to include stdbool.h
In reply to a message not in the archiveFix a missing include.
--- tools/kvm/include/kvm/term.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
tools/kvm/include/kvm/term.h +1 -0
@@ -2,6 +2,7 @@#define KVM__TERM_H #include <sys/uio.h> +#include <stdbool.h> #define CONSOLE_8250 1#define CONSOLE_VIRTIO 2
PATCH 11/28 kvm tools: kvm.c needs to include sys/stat.h for mkdir
In reply to a message not in the archiveFix a missing include.
--- tools/kvm/kvm.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
tools/kvm/kvm.c +1 -0
@@ -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>
PATCH 12/28 kvm tools: Move arch-specific cmdline init into kvm__arch_set_cmdline()
In reply to a message not in the archiveDifferent systems will want different base kernel commandlines, e.g. non-x86 systems probably don't need noapic, i8042.* etc., so set the commandline up in arch-specific code. Then, if the resulting commandline is empty, don't strcat a space onto the front.
--- tools/kvm/builtin-run.c | 12 +++++------- tools/kvm/include/kvm/kvm.h | 1 + tools/kvm/x86/kvm.c | 11 +++++++++++ 3 files changed, 17 insertions(+), 7 deletions(-)
tools/kvm/builtin-run.c +5 -7
@@ -835,13 +835,11 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) vidmode =0 ;memset (real_cmdline,0 ,sizeof (real_cmdline)); -strcpy (real_cmdline,"noapic noacpi pci=conf1 reboot=k panic=1 i8042.direct=1 " -"i8042.dumbkbd=1 i8042.nopnp=1" ); -if (vnc || sdl) { -strcat (real_cmdline," video=vesafb console=tty0" ); - }else -strcat (real_cmdline," console=ttyS0 earlyprintk=serial i8042.noaux=1" ); -strcat (real_cmdline," " ); +kvm__arch_set_cmdline (real_cmdline, vnc || sdl); + +if (strlen (real_cmdline) >0 ) +strcat (real_cmdline," " ); +if (kernel_cmdline)strlcat (real_cmdline, kernel_cmdline,sizeof (real_cmdline));
tools/kvm/include/kvm/kvm.h +1 -0
@@ -53,6 +53,7 @@ int kvm__get_sock_by_instance(const char *name);int kvm__enumerate_instances (int (*callback)(const char *name,int pid));void kvm__remove_socket (const char *name); +void kvm__arch_set_cmdline (char *cmdline,bool video);void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,u64 ram_size,const char *name);void kvm__arch_setup_firmware (struct kvm *kvm);bool kvm__arch_cpu_supports_vm (void );
tools/kvm/x86/kvm.c +11 -0
@@ -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) {
PATCH 13/28 kvm tools: Add CONSOLE_HV term type and allow it to be selected
In reply to a message not in the archiveThis patch paves the way for adding a hypervisor console, useful on systems that support one out of the box yet don't have either serial port or virtio console support (e.g. kernels expecting POWER SPAPR).
--- tools/kvm/builtin-run.c | 8 ++++++-- tools/kvm/include/kvm/term.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-)
tools/kvm/builtin-run.c +6 -2
@@ -416,7 +416,7 @@ static const struct option options[] = {OPT_BOOLEAN ('\0' ,"rng" , &virtio_rng,"Enable virtio Random Number Generator" ),OPT_CALLBACK ('\0' ,"9p" ,NULL ,"dir_to_share,tag_name" ,"Enable virtio 9p to share files between host and guest" , virtio_9p_rootdir_parser), -OPT_STRING ('\0' ,"console" , &console,"serial or virtio" , +OPT_STRING ('\0' ,"console" , &console,"serial, virtio or hv" ,"Console to use" ),OPT_STRING ('\0' ,"dev" , &dev,"device_file" ,"KVM device file" ), OPT_CALLBACK('\0', "tty", NULL, "tty id",
@@ -776,8 +776,12 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)if (!strncmp (console,"virtio" ,6 )) active_console =CONSOLE_VIRTIO ; -else +else if (!strncmp (console,"serial" ,6 )) active_console =CONSOLE_8250 ; +else if (!strncmp (console,"hv" ,2 )) + active_console =CONSOLE_HV ; +else +pr_warning ("No console!" );if (!host_ip) host_ip =DEFAULT_HOST_ADDR ;
tools/kvm/include/kvm/term.h +1 -0
@@ -6,6 +6,7 @@#define CONSOLE_8250 1#define CONSOLE_VIRTIO 2 +#define CONSOLE_HV 3int 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);
PATCH 14/28 kvm tools: Fix term_getc(), term_getc_iov() endian bugs
In reply to a message not in the archiveterm_getc()'s int c has one byte written into it (at its lowest address) by read_in_full(). This is expected to be the least significant byte, but that isn't the case on BE! Use correct type, unsigned char. A similar issue exists in term_getc_iov(), which needs to write a char to the iov rather than an int.
--- tools/kvm/term.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)
tools/kvm/term.c +2 -3
@@ -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 ); }
Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs
Quoted 28 lines · Matt Evans
term_getc()'s int c has one byte written into it (at its lowest address) by
read_in_full(). This is expected to be the least significant byte, but that isn't the case on BE! Use correct type, unsigned char. A similar issue exists interm_getc_iov(), which needs to write a char to the iov rather than an int.Signed-off-by Matt Evans <[email protected]>---
tools/kvm/term.c | 5 ++---1 files changed, 2 insertions(+), 3 deletions(-)tools/kvm/term.c +1
-2@@ -30,11 +30,10 @@ int term_fds[4][2]; int term_getc(int who, int term) { - int c; + unsigned char c; if (who != active_console) return -1; - if (read_in_full(term_fds[term][TERM_FD_IN], &c, 1) < 0) return -1;
tools/kvm/term.c int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term) · line 89
Quoted 8 lines
tools/kvm/term.c +1
-1@@ -84,7 +83,7 @@ int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term) if (c < 0) return 0; - *((int *)iov[TERM_FD_IN].iov_base) = c; + *((char *)iov[TERM_FD_IN].iov_base) = (char)c; return sizeof(char); }
Looks OK to me. Asias?
Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs
Quoted 17 lines · Pekka Enberg
Quoted 16 lines · Matt Evans
term_getc()'s int c has one byte written into it (at its lowest address) by
read_in_full(). This is expected to be the least significant byte, but that isn't the case on BE! Use correct type, unsigned char. A similar issue exists interm_getc_iov(), which needs to write a char to the iov rather than an int.Signed-off-by Matt Evans <[email protected]>--- tools/kvm/term.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)tools/kvm/term.c +0
-0@@ -30,11 +30,10 @@ int term_fds[4][2];
Quoted 8 lines
tools/kvm/term.c int term_fds[4][2]; · line 37
Quoted 8 lines
tools/kvm/term.c +1
-2int term_getc (int who,int term) { -int c; +unsigned char c;if (who != active_console)return -1 ; -
We can drop this line too.
c &= 0xff;
Quoted 7 lines
Quoted 7 lines
tools/kvm/term.c +0
-0if (read_in_full (term_fds[term][TERM_FD_IN ], &c,1 ) <0 )return -1 ;@@ -84,7 +83,7 @@ int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term)if (c <0 )return 0 ;
Quoted 8 lines
tools/kvm/term.c int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term) · line 89
Quoted 5 lines
tools/kvm/term.c +1
-1- *((int *)iov[TERM_FD_IN ].iov_base) = c; + *((char *)iov[TERM_FD_IN ].iov_base) = (char )c;return sizeof (char ); }Looks OK to me. Asias?
Otherwise, looks fine to me.
Signature · 1 line
Asias He
Re: [PATCH 14/28] kvm tools: Fix term_getc(), term_getc_iov() endian bugs
Hi Asias,
Quoted 23 lines · Asias He
Quoted 22 lines · Pekka Enberg
Quoted 21 lines · Matt Evans
term_getc()'s int c has one byte written into it (at its lowest address) by
read_in_full(). This is expected to be the least significant byte, but that isn't the case on BE! Use correct type, unsigned char. A similar issue exists interm_getc_iov(), which needs to write a char to the iov rather than an int.Signed-off-by Matt Evans <[email protected]>--- tools/kvm/term.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)tools/kvm/term.c +1
-1@@ -30,11 +30,10 @@ int term_fds[4][2];int term_getc (int who,int term) { -int c; +unsigned char c;
Quoted 7 lines
Quoted 3 lines
tools/kvm/term.c int term_fds[4][2]; · line 37
Quoted 3 lines
tools/kvm/term.c +0
-1if (who != active_console)return -1 ; -We can drop this line too.
c &= 0xff;
D'oh! Of course it can -- I'll remove it & repost.
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
tools/kvm/term.c +1
-1if (read_in_full (term_fds[term][TERM_FD_IN ], &c,1 ) <0 )return -1 ;@@ -84,7 +83,7 @@ int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term)if (c <0 )return 0 ; - *((int *)iov[TERM_FD_IN ].iov_base) = c; + *((char *)iov[TERM_FD_IN ].iov_base) = (char )c;
Quoted 7 lines
Quoted 5 lines
tools/kvm/term.c int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term) · line 89
Quoted 2 lines
tools/kvm/term.c +0
-0return sizeof (char ); }Looks OK to me. Asias?
Otherwise, looks fine to me.
Thanks for reviewing!
Matt
PATCH 15/28 kvm tools: Allow initrd_check() to match a cpio
In reply to a message not in the archivecpios are valid as initrds too, so allow them through the check.
--- tools/kvm/kvm.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
tools/kvm/kvm.c +5 -3
@@ -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,
Re: [PATCH 15/28] kvm tools: Allow initrd_check() to match a cpio
Quoted 26 lines · Matt Evans
cpios are valid as initrds too, so allow them through the check.
Signed-off-by Matt Evans <[email protected]>---
tools/kvm/kvm.c | 8 +++++---1 files changed, 5 insertions(+), 3 deletions(-)tools/kvm/kvm.c +3
-2@@ -317,10 +317,11 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name) /* RFC 1952 */ #define GZIP_ID1 0x1f #define GZIP_ID2 0x8b - +#define CPIO_MAGIC "0707" +/* initrd may be gzipped, or a plain cpio */ static bool initrd_check(int fd) { - unsigned char id[2]; + unsigned char id[4]; if (read_in_full(fd, id, ARRAY_SIZE(id)) < 0) return false;
tools/kvm/kvm.c static bool initrd_check(int fd) · line 336
Quoted 9 lines
tools/kvm/kvm.c +2
-1@@ -328,7 +329,8 @@ static bool initrd_check(int fd) if (lseek(fd, 0, SEEK_SET) < 0) die_perror("lseek"); - return id[0] == GZIP_ID1 && id[1] == GZIP_ID2; + return (id[0] == GZIP_ID1 && id[1] == GZIP_ID2) || + !memcmp(id, CPIO_MAGIC, 4); } bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
Looks good to me.
PATCH 16/28 kvm tools: Allow load_flat_binary() to load an initrd alongside
In reply to a message not in the archiveThis patch passes the initrd fd and commandline to load_flat_binary(), which may be used to load both the kernel & an initrd (stashing or inserting the commandline as appropriate) in the same way that load_bzimage() does. This is especially useful when load_bzimage() is unused for a particular architecture. :-)
--- tools/kvm/include/kvm/kvm.h | 2 +- tools/kvm/kvm.c | 10 ++++++---- tools/kvm/x86/kvm.c | 12 +++++++++--- 3 files changed, 16 insertions(+), 8 deletions(-)
tools/kvm/include/kvm/kvm.h +1 -1
@@ -59,7 +59,7 @@ void kvm__arch_setup_firmware(struct kvm *kvm);bool kvm__arch_cpu_supports_vm (void );void kvm__arch_periodic_poll (struct kvm *kvm); -int load_flat_binary (struct kvm *kvm,int fd); +int load_flat_binary (struct kvm *kvm,int fd_kernel,int fd_initrd,const char *kernel_cmdline);bool load_bzimage (struct kvm *kvm,int fd_kernel,int fd_initrd,const char *kernel_cmdline,u16 vidmode);/*
tools/kvm/kvm.c +6 -4
@@ -354,23 +354,25 @@ bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename, ret =load_bzimage (kvm, fd_kernel, fd_initrd, kernel_cmdline, vidmode); -if (initrd_filename) -close (fd_initrd); -if (ret) goto found_kernel;pr_warning ("%s is not a bzImage. Trying to load it as a flat binary..." , kernel_filename); - ret =load_flat_binary (kvm, fd_kernel); + ret =load_flat_binary (kvm, fd_kernel, fd_initrd, kernel_cmdline); +if (ret) goto found_kernel; +if (initrd_filename) +close (fd_initrd);close (fd_kernel);die ("%s is not a valid bzImage or flat binary" , kernel_filename); found_kernel: +if (initrd_filename) +close (fd_initrd);close (fd_kernel);return ret;
tools/kvm/x86/kvm.c +9 -3
@@ -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 ;
Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside
Quoted 68 lines · Matt Evans
This patch passes the initrd fd and commandline to
load_flat_binary(), which may be used to load both the kernel & an initrd (stashing or inserting the commandline as appropriate) in the same way thatload_bzimage()does. This is especially useful whenload_bzimage()is unused for a particular architecture. :-)Signed-off-by Matt Evans <[email protected]>---
tools/kvm/include/kvm/kvm.h | 2 +-
tools/kvm/kvm.c | 10 ++++++----
tools/kvm/x86/kvm.c | 12 +++++++++---3 files changed, 16 insertions(+), 8 deletions(-)tools/kvm/include/kvm/kvm.h +1
-1@@ -59,7 +59,7 @@ void kvm__arch_setup_firmware(struct kvm *kvm); bool kvm__arch_cpu_supports_vm(void); void kvm__arch_periodic_poll(struct kvm *kvm); -int load_flat_binary (struct kvm *kvm,int fd); +int load_flat_binary (struct kvm *kvm,int fd_kernel,int fd_initrd,const char *kernel_cmdline); bool load_bzimage(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline, u16 vidmode); /*tools/kvm/kvm.c +4
-4@@ -354,23 +354,25 @@ bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename, ret = load_bzimage(kvm, fd_kernel, fd_initrd, kernel_cmdline, vidmode); - if (initrd_filename) - close(fd_initrd); - if (ret) goto found_kernel; pr_warning("%s is not a bzImage. Trying to load it as a flat binary...", kernel_filename); - ret = load_flat_binary(kvm, fd_kernel); + ret = load_flat_binary(kvm, fd_kernel, fd_initrd, kernel_cmdline); + if (ret) goto found_kernel; + if (initrd_filename) + close(fd_initrd); close(fd_kernel); die("%s is not a valid bzImage or flat binary", kernel_filename);found_kernel:
+ if (initrd_filename)
+close(fd_initrd);
close(fd_kernel);return ret;
tools/kvm/x86/kvm.c +0
-0@@ -227,17 +227,23 @@ void kvm__irq_trigger(struct kvm *kvm, int irq) #define BOOT_PROTOCOL_REQUIRED 0x206 #define LOAD_HIGH 0x01
tools/kvm/x86/kvm.c void kvm__irq_trigger(struct kvm *kvm, int irq) · line 237
Quoted 10 lines
tools/kvm/x86/kvm.c +4
-2-int load_flat_binary (struct kvm *kvm,int fd) +int load_flat_binary (struct kvm *kvm,int fd_kernel,int fd_initrd,const char *kernel_cmdline) { void *p; int nr; - if (lseek(fd, 0, SEEK_SET) < 0) + /* Some architectures may support loading an initrd alongside the flat kernel, +* but we do not. +*/
Minor nit - we use comment format where the first line is left empty from text:
/*
* Some architectures may support loading an initrd alongside
the flat kernel,
* but we do not.
*/
Quoted 14 lines
tools/kvm/x86/kvm.c +5
-2+ if (fd_initrd != -1) + pr_warning("Loading initrd with flat binary not supported."); + + if (lseek(fd_kernel, 0, SEEK_SET) < 0) die_perror("lseek"); p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP); - while ((nr = read(fd, p, 65536)) > 0) + while ((nr = read(fd_kernel, p, 65536)) > 0) p += nr; kvm->boot_selector = BOOT_LOADER_SELECTOR; --
Quoted 3 lines
To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Otherwise looks OK to me. Cyrill?
Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside
On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
...
Quoted 3 lines
Otherwise looks OK to me. Cyrill?
It might be not seen from patch (or my local kvm repo is not yet updated well) but I somehow miss who will be reading initrd in case of loading flat image? If noone, then what's the point to pass fd there at all?
Cyrill
Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside
Hi Cyrill,
Quoted 10 lines · Cyrill Gorcunov
On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
...Quoted 3 lines
Otherwise looks OK to me. Cyrill?
It might be not seen from patch (or my local kvm repo is not yet updated well) but I somehow miss who will be reading initrd in case of loading flat image? If noone, then what's the point to pass fd there at all?
I pass in the initrd fd in generic code in preparation for the PPC support in "[PATCH 1/8] kvm tools: Add initial SPAPR PPC64 architecture support" which uses it. As you saw, I haven't made x86 load the initrd in the case of a flat kernel binary being loaded; I didn't think a flat kernel can have a non-embedded initrd on x86? (My x86 is rusty, this may not be true ;) bootparams are [b]zImage only?)
Thanks for reviewing,
Matt
Re: [PATCH 16/28] kvm tools: Allow load_flat_binary() to load an initrd alongside
Quoted 14 lines · Matt Evans
Hi Cyrill,
Quoted 10 lines · Cyrill Gorcunov
On Tue, Dec 06, 2011 at 12:29:48PM +0200, Pekka Enberg wrote:
...Quoted 3 lines
Otherwise looks OK to me. Cyrill?
It might be not seen from patch (or my local kvm repo is not yet updated well) but I somehow miss who will be reading initrd in case of loading flat image? If noone, then what's the point to pass fd there at all?
Quoted 7 lines
I pass in the initrd fd in generic code in preparation for the PPC support in "[PATCH 1/8] kvm tools: Add initial SPAPR PPC64 architecture support" which uses it. As you saw, I haven't made x86 load the initrd in the case of a flat kernel binary being loaded; I didn't think a flat kernel can have a non-embedded initrd on x86? (My x86 is rusty, this may not be true ;) bootparams are [b]zImage only?)
Ah, I see. Sorry for confusion. Thanks.
Cyrill
PATCH 17/28 kvm tools: Only call symbol__init() if we have BFD
In reply to a message not in the archiveCONFIG_HAS_BFD is optional, symbol.c inclusion is optional -- so make its init call dependent on CONFIG_HAS_BFD.
--- tools/kvm/builtin-run.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
tools/kvm/builtin-run.c +2 -1
@@ -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) {
Re: [PATCH 17/28] kvm tools: Only call symbol__init() if we have BFD
It's optional, but when CONFIG_HAS_BFD is not defined symbol__init() is defined as an empty static function.
Why was there a need to wrap it in a #ifdef here?
Quoted 27 lines · Matt Evans
CONFIG_HAS_BFDis optional,symbol.cinclusion is optional -- so make its init call dependent onCONFIG_HAS_BFD.Signed-off-by Matt Evans <[email protected]>--- tools/kvm/builtin-run.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)tools/kvm/builtin-run.c +2
-2@@ -798,8 +798,9 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)if (!script) script =DEFAULT_SCRIPT ; +#ifdef CONFIG_HAS_BFD symbol__init (vmlinux_filename); - +#endif term_init ();if (!guest_name) { --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Sasha.
Re: [PATCH 17/28] kvm tools: Only call symbol__init() if we have BFD
Quoted 4 lines · Sasha Levin
It's optional, but when
CONFIG_HAS_BFDis not definedsymbol__init()is defined as an empty static function.Why was there a need to wrap it in a #ifdef here?
That's an excellent question and I think the true answer is just embarrassing so I'll just drop this patch from the series. ;-)
Thanks,
Matt
Quoted 30 lines · Matt Evans
Quoted 27 lines
CONFIG_HAS_BFDis optional,symbol.cinclusion is optional -- so make its init call dependent onCONFIG_HAS_BFD.Signed-off-by Matt Evans <[email protected]>--- tools/kvm/builtin-run.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)tools/kvm/builtin-run.c +2
-2@@ -798,8 +798,9 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)if (!script) script =DEFAULT_SCRIPT ; +#ifdef CONFIG_HAS_BFD symbol__init (vmlinux_filename); - +#endif term_init ();if (!guest_name) { --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 18/28 kvm tools: Initialise PCI before devices start getting registered with PCI
In reply to a message not in the archiveRe-arrange pci__init() in builtin-run such that it comes before devices are initialised.
--- tools/kvm/builtin-run.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
tools/kvm/builtin-run.c +2 -2
@@ -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);
PATCH 19/28 kvm tools: Perform CPU and firmware setup after devices are added
In reply to a message not in the archiveCurrently some devices (in this case kbd, fb, vesa) are initialised after CPU/firmware setup. On some platforms (e.g. PPC) kvm__arch_setup_firmware() may be making a device tree. Any devices added after this point will be missed!
Tiny refactor of builtin-run.c, moving timer start, firmware setup, cpu init to occur last.
--- tools/kvm/builtin-run.c | 24 ++++++++++++++---------- 1 files changed, 14 insertions(+), 10 deletions(-)
tools/kvm/builtin-run.c +14 -10
@@ -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 ();
PATCH 20/28 kvm tools: Init IRQs after determining nrcpus
In reply to a message not in the archiveIRQ init may involve per-CPU setup/allocation of resources, so make sure kvm->nrcpus is initialised before calling irq__init().
--- tools/kvm/builtin-run.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
tools/kvm/builtin-run.c +2 -2
@@ -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 ();/*
PATCH 21/28 kvm tools: Add --hugetlbfs option to specify memory path
In reply to a message not in the archiveSome architectures may want to use hugetlbfs to mmap() their guest memory, so allow a path to be specified on the commandline and pass it to kvm__arch_init().
--- tools/kvm/builtin-run.c | 4 +++- tools/kvm/include/kvm/kvm.h | 4 ++-- tools/kvm/kvm.c | 4 ++-- tools/kvm/x86/kvm.c | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-)
tools/kvm/builtin-run.c +3 -1
@@ -84,6 +84,7 @@ static const char *guest_mac;static const char *host_mac;static const char *script;static const char *guest_name; +static const char *hugetlbfs_path;static struct virtio_net_params *net_params;static bool single_step;static bool readonly_image[MAX_DISK_IMAGES ];
@@ -422,6 +423,7 @@ static const struct option options[] = {OPT_CALLBACK ('\0' ,"tty" ,NULL ,"tty id" ,"Remap guest TTY into a pty on the host" , tty_parser), +OPT_STRING ('\0' ,"hugetlbfs" , &hugetlbfs_path,"path" ,"Hugetlbfs path" ),OPT_GROUP ("Kernel options:" ), OPT_STRING('k', "kernel", &kernel_filename, "kernel",
@@ -808,7 +810,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) guest_name = default_name; } - kvm =kvm__init (dev, ram_size, guest_name); + kvm =kvm__init (dev, hugetlbfs_path, ram_size, guest_name); kvm->single_step = single_step;
tools/kvm/include/kvm/kvm.h +2 -2
@@ -30,7 +30,7 @@ struct kvm_ext {void kvm__set_dir (const char *fmt, ...);const char *kvm__get_dir (void ); -struct kvm *kvm__init (const char *kvm_dev,u64 ram_size,const char *name); +struct kvm *kvm__init (const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name);int kvm__recommended_cpus (struct kvm *kvm);int kvm__max_cpus (struct kvm *kvm);void kvm__init_ram (struct kvm *kvm);
@@ -54,7 +54,7 @@ int kvm__enumerate_instances(int (*callback)(const char *name, int pid));void kvm__remove_socket (const char *name);void kvm__arch_set_cmdline (char *cmdline,bool video); -void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,u64 ram_size,const char *name); +void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name);void kvm__arch_setup_firmware (struct kvm *kvm);bool kvm__arch_cpu_supports_vm (void );void kvm__arch_periodic_poll (struct kvm *kvm);
tools/kvm/kvm.c +2 -2
@@ -272,7 +272,7 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)pr_warning ("Failed sending PID" ); } -struct kvm *kvm__init (const char *kvm_dev,u64 ram_size,const char *name) +struct kvm *kvm__init (const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name) {struct kvm *kvm;int ret;
@@ -305,7 +305,7 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)if (kvm__check_extensions (kvm))die ("A required KVM extention is not supported by OS" ); -kvm__arch_init (kvm, kvm_dev, ram_size, name); +kvm__arch_init (kvm, kvm_dev, hugetlbfs_path, ram_size, name); kvm->name = name;
tools/kvm/x86/kvm.c +1 -1
@@ -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;
Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path
I'm seeing hugetlbfs_path being passed around, but I don't see anything that actually does something with it.
Did it get into a different patch? or maybe it wasn't 'git add'ed?
Quoted 101 lines · Matt Evans
Some architectures may want to use hugetlbfs to
mmap()their guest memory, so allow a path to be specified on the commandline and pass it tokvm__arch_init().Signed-off-by Matt Evans <[email protected]>--- tools/kvm/builtin-run.c | 4 +++- tools/kvm/include/kvm/kvm.h | 4 ++-- tools/kvm/kvm.c | 4 ++-- tools/kvm/x86/kvm.c | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-)tools/kvm/builtin-run.c +3
-1@@ -84,6 +84,7 @@ static const char *guest_mac;static const char *host_mac;static const char *script;static const char *guest_name; +static const char *hugetlbfs_path;static struct virtio_net_params *net_params;static bool single_step;static bool readonly_image[MAX_DISK_IMAGES ];@@ -422,6 +423,7 @@ static const struct option options[] = {OPT_CALLBACK ('\0' ,"tty" ,NULL ,"tty id" ,"Remap guest TTY into a pty on the host" , tty_parser), +OPT_STRING ('\0' ,"hugetlbfs" , &hugetlbfs_path,"path" ,"Hugetlbfs path" ),OPT_GROUP ("Kernel options:" ), OPT_STRING('k', "kernel", &kernel_filename, "kernel",@@ -808,7 +810,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) guest_name = default_name; } - kvm =kvm__init (dev, ram_size, guest_name); + kvm =kvm__init (dev, hugetlbfs_path, ram_size, guest_name); kvm->single_step = single_step;tools/kvm/include/kvm/kvm.h +2
-2@@ -30,7 +30,7 @@ struct kvm_ext {void kvm__set_dir (const char *fmt, ...);const char *kvm__get_dir (void ); -struct kvm *kvm__init (const char *kvm_dev,u64 ram_size,const char *name); +struct kvm *kvm__init (const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name);int kvm__recommended_cpus (struct kvm *kvm);int kvm__max_cpus (struct kvm *kvm);void kvm__init_ram (struct kvm *kvm);@@ -54,7 +54,7 @@ int kvm__enumerate_instances(int (*callback)(const char *name, int pid));void kvm__remove_socket (const char *name);void kvm__arch_set_cmdline (char *cmdline,bool video); -void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,u64 ram_size,const char *name); +void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name);void kvm__arch_setup_firmware (struct kvm *kvm);bool kvm__arch_cpu_supports_vm (void );void kvm__arch_periodic_poll (struct kvm *kvm);tools/kvm/kvm.c +2
-2@@ -272,7 +272,7 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)pr_warning ("Failed sending PID" ); } -struct kvm *kvm__init (const char *kvm_dev,u64 ram_size,const char *name) +struct kvm *kvm__init (const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name) {struct kvm *kvm;int ret;@@ -305,7 +305,7 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)if (kvm__check_extensions (kvm))die ("A required KVM extention is not supported by OS" ); -kvm__arch_init (kvm, kvm_dev, ram_size, name); +kvm__arch_init (kvm, kvm_dev, hugetlbfs_path, ram_size, name); kvm->name = name;tools/kvm/x86/kvm.c +1
-2@@ -161,7 +161,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video) }/* Architecture-specific KVM init */ -void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,u64 ram_size,const char *name) +void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name) {struct kvm_pit_config pit_config = { .flags =0 , };int ret; --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Sasha.
Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path
Quoted 4 lines · Sasha Levin
I'm seeing
hugetlbfs_pathbeing passed around, but I don't see anything that actually does something with it.Did it get into a different patch? or maybe it wasn't 'git add'ed?
It's actually moved in preparation for the later "[PATCH 1/8] kvm tools: Add initial SPAPR PPC64 architecture support" patch, which uses it. I could've mushed that into the later PPC series but I thought it'd be clearer to do the generic/x86 stuff separately.
Matt
Quoted 104 lines · Matt Evans
Quoted 101 lines
Some architectures may want to use hugetlbfs to
mmap()their guest memory, so allow a path to be specified on the commandline and pass it tokvm__arch_init().Signed-off-by Matt Evans <[email protected]>--- tools/kvm/builtin-run.c | 4 +++- tools/kvm/include/kvm/kvm.h | 4 ++-- tools/kvm/kvm.c | 4 ++-- tools/kvm/x86/kvm.c | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-)tools/kvm/builtin-run.c +3
-1@@ -84,6 +84,7 @@ static const char *guest_mac;static const char *host_mac;static const char *script;static const char *guest_name; +static const char *hugetlbfs_path;static struct virtio_net_params *net_params;static bool single_step;static bool readonly_image[MAX_DISK_IMAGES ];@@ -422,6 +423,7 @@ static const struct option options[] = {OPT_CALLBACK ('\0' ,"tty" ,NULL ,"tty id" ,"Remap guest TTY into a pty on the host" , tty_parser), +OPT_STRING ('\0' ,"hugetlbfs" , &hugetlbfs_path,"path" ,"Hugetlbfs path" ),OPT_GROUP ("Kernel options:" ), OPT_STRING('k', "kernel", &kernel_filename, "kernel",@@ -808,7 +810,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) guest_name = default_name; } - kvm =kvm__init (dev, ram_size, guest_name); + kvm =kvm__init (dev, hugetlbfs_path, ram_size, guest_name); kvm->single_step = single_step;tools/kvm/include/kvm/kvm.h +2
-2@@ -30,7 +30,7 @@ struct kvm_ext {void kvm__set_dir (const char *fmt, ...);const char *kvm__get_dir (void ); -struct kvm *kvm__init (const char *kvm_dev,u64 ram_size,const char *name); +struct kvm *kvm__init (const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name);int kvm__recommended_cpus (struct kvm *kvm);int kvm__max_cpus (struct kvm *kvm);void kvm__init_ram (struct kvm *kvm);@@ -54,7 +54,7 @@ int kvm__enumerate_instances(int (*callback)(const char *name, int pid));void kvm__remove_socket (const char *name);void kvm__arch_set_cmdline (char *cmdline,bool video); -void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,u64 ram_size,const char *name); +void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name);void kvm__arch_setup_firmware (struct kvm *kvm);bool kvm__arch_cpu_supports_vm (void );void kvm__arch_periodic_poll (struct kvm *kvm);tools/kvm/kvm.c +2
-2@@ -272,7 +272,7 @@ static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)pr_warning ("Failed sending PID" ); } -struct kvm *kvm__init (const char *kvm_dev,u64 ram_size,const char *name) +struct kvm *kvm__init (const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name) {struct kvm *kvm;int ret;@@ -305,7 +305,7 @@ struct kvm *kvm__init(const char *kvm_dev, u64 ram_size, const char *name)if (kvm__check_extensions (kvm))die ("A required KVM extention is not supported by OS" ); -kvm__arch_init (kvm, kvm_dev, ram_size, name); +kvm__arch_init (kvm, kvm_dev, hugetlbfs_path, ram_size, name); kvm->name = name;tools/kvm/x86/kvm.c +1
-2@@ -161,7 +161,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video) }/* Architecture-specific KVM init */ -void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,u64 ram_size,const char *name) +void kvm__arch_init (struct kvm *kvm,const char *kvm_dev,const char *hugetlbfs_path,u64 ram_size,const char *name) {struct kvm_pit_config pit_config = { .flags =0 , };int ret; --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 21/28] kvm tools: Add --hugetlbfs option to specify memory path
Quoted 10 lines · Matt Evans
Quoted 4 lines · Sasha Levin
I'm seeing
hugetlbfs_pathbeing passed around, but I don't see anything that actually does something with it.Did it get into a different patch? or maybe it wasn't 'git add'ed?
It's actually moved in preparation for the later "[PATCH 1/8] kvm tools: Add initial SPAPR PPC64 architecture support" patch, which uses it. I could've mushed that into the later PPC series but I thought it'd be clearer to do the generic/x86 stuff separately.
I actually would like to see everything moved into the generic code out of the PPC series :)
hugetlb allocation should probably be done in the generic code as it would work on x86 as well.
Signature · 1 line
Sasha.
PATCH 22/28 kvm tools: Move PCI_MAX_DEVICES to pci.h
In reply to a message not in the archiveOther pieces of kvmtool may be interested in PCI_MAX_DEVICES.
--- tools/kvm/include/kvm/pci.h | 1 + tools/kvm/pci.c | 1 - 2 files changed, 1 insertions(+), 1 deletions(-)
tools/kvm/include/kvm/pci.h +1 -0
@@ -6,6 +6,7 @@#include <linux/pci_regs.h> #include <linux/msi.h> +#define PCI_MAX_DEVICES 256/* * PCI Configuration Mechanism #1 I/O ports. See Section 3.7.4.1. * ("Configuration Mechanism #1") of the PCI Local Bus Specification 2.1 for
tools/kvm/pci.c +0 -1
@@ -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 ];
PATCH 23/28 kvm tools: Endian-sanitise pci.h and PCI device setup
In reply to a message not in the archivevesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The pci_config_address bitfield also needs to be reversed when building on BE systems.
--- tools/kvm/hw/pci-shmem.c | 23 +++++++++++---------- tools/kvm/hw/vesa.c | 15 +++++++------ tools/kvm/include/kvm/ioport.h | 11 +++++---- tools/kvm/include/kvm/pci.h | 24 +++++++++++++++++----- tools/kvm/pci.c | 4 +- tools/kvm/virtio/pci.c | 41 +++++++++++++++++++++------------------ 6 files changed, 68 insertions(+), 50 deletions(-)
tools/kvm/hw/pci-shmem.c +12 -11
@@ -8,21 +8,22 @@#include "kvm/ioeventfd.h" #include <linux/kvm.h> +#include <linux/byteorder.h> #include <sys/ioctl.h> #include <fcntl.h> #include <sys/mman.h> static struct pci_device_header pci_shmem_pci_device = { - .vendor_id =PCI_VENDOR_ID_REDHAT_QUMRANET , - .device_id =0x1110 , + .vendor_id =cpu_to_le16 (PCI_VENDOR_ID_REDHAT_QUMRANET ), + .device_id =cpu_to_le16 (0x1110 ), .header_type =PCI_HEADER_TYPE_NORMAL , - .class =0xFF0000 ,/* misc pci device */ - .status =PCI_STATUS_CAP_LIST , + .class[2 ] =0xFF ,/* misc pci device */ + .status =cpu_to_le16 (PCI_STATUS_CAP_LIST ), .capabilities = (void *)&pci_shmem_pci_device.msix - (void *)&pci_shmem_pci_device, .msix.cap =PCI_CAP_ID_MSIX , - .msix.ctrl =1 , - .msix.table_offset =1 ,/* Use BAR 1 */ - .msix.pba_offset =0x1001 ,/* Use BAR 1 */ + .msix.ctrl =cpu_to_le16 (1 ), + .msix.table_offset =cpu_to_le32 (1 ),/* Use BAR 1 */ + .msix.pba_offset =cpu_to_le32 (0x1001 ),/* Use BAR 1 */ };/* registers for the Inter-VM shared memory device */
@@ -123,7 +124,7 @@ int pci_shmem__get_local_irqfd(struct kvm *kvm)if (fd <0 )return fd; -if (pci_shmem_pci_device.msix.ctrl &PCI_MSIX_FLAGS_ENABLE ) { +if (pci_shmem_pci_device.msix.ctrl &cpu_to_le16 (PCI_MSIX_FLAGS_ENABLE )) { gsi =irq__add_msix_route (kvm, &msix_table[0 ].msg); }else { gsi = pci_shmem_pci_device.irq_line;
@@ -241,11 +242,11 @@ int pci_shmem__init(struct kvm *kvm)* 1 - MSI-X MMIO space * 2 - Shared memory block */ - pci_shmem_pci_device.bar[0 ] = ivshmem_registers |PCI_BASE_ADDRESS_SPACE_IO ; + pci_shmem_pci_device.bar[0 ] =cpu_to_le32 (ivshmem_registers |PCI_BASE_ADDRESS_SPACE_IO ); pci_shmem_pci_device.bar_size[0 ] = shmem_region->size; - pci_shmem_pci_device.bar[1 ] = msix_block |PCI_BASE_ADDRESS_SPACE_MEMORY ; + pci_shmem_pci_device.bar[1 ] =cpu_to_le32 (msix_block |PCI_BASE_ADDRESS_SPACE_MEMORY ); pci_shmem_pci_device.bar_size[1 ] =0x1010 ; - pci_shmem_pci_device.bar[2 ] = shmem_region->phys_addr |PCI_BASE_ADDRESS_SPACE_MEMORY ; + pci_shmem_pci_device.bar[2 ] =cpu_to_le32 (shmem_region->phys_addr |PCI_BASE_ADDRESS_SPACE_MEMORY ); pci_shmem_pci_device.bar_size[2 ] = shmem_region->size;pci__register (&pci_shmem_pci_device, dev);
tools/kvm/hw/vesa.c +8 -7
@@ -8,6 +8,7 @@#include "kvm/irq.h" #include "kvm/kvm.h" #include "kvm/pci.h" +#include <linux/byteorder.h> #include <sys/mman.h> #include <sys/types.h>
@@ -31,14 +32,14 @@ static struct ioport_operations vesa_io_ops = { };static struct pci_device_header vesa_pci_device = { - .vendor_id =PCI_VENDOR_ID_REDHAT_QUMRANET , - .device_id =PCI_DEVICE_ID_VESA , + .vendor_id =cpu_to_le16 (PCI_VENDOR_ID_REDHAT_QUMRANET ), + .device_id =cpu_to_le16 (PCI_DEVICE_ID_VESA ), .header_type =PCI_HEADER_TYPE_NORMAL , .revision_id =0 , - .class =0x030000 , - .subsys_vendor_id =PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET , - .subsys_id =PCI_SUBSYSTEM_ID_VESA , - .bar[1 ] =VESA_MEM_ADDR |PCI_BASE_ADDRESS_SPACE_MEMORY , + .class[2 ] =0x03 , + .subsys_vendor_id =cpu_to_le16 (PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET ), + .subsys_id =cpu_to_le16 (PCI_SUBSYSTEM_ID_VESA ), + .bar[1 ] =cpu_to_le32 (VESA_MEM_ADDR |PCI_BASE_ADDRESS_SPACE_MEMORY ), .bar_size[1 ] =VESA_MEM_SIZE , };
@@ -56,7 +57,7 @@ struct framebuffer *vesa__init(struct kvm *kvm) vesa_pci_device.irq_pin = pin; vesa_pci_device.irq_line = line; vesa_base_addr =ioport__register (IOPORT_EMPTY , &vesa_io_ops,IOPORT_SIZE ,NULL ); - vesa_pci_device.bar[0 ] = vesa_base_addr |PCI_BASE_ADDRESS_SPACE_IO ; + vesa_pci_device.bar[0 ] =cpu_to_le32 (vesa_base_addr |PCI_BASE_ADDRESS_SPACE_IO );pci__register (&vesa_pci_device, dev); mem =mmap (NULL ,VESA_MEM_SIZE ,PROT_RW ,MAP_ANON_NORESERVE ,-1 ,0 );
tools/kvm/include/kvm/ioport.h +6 -5
@@ -7,6 +7,7 @@#include <limits.h> #include <asm/types.h> #include <linux/types.h> +#include <linux/byteorder.h> /* some ports we reserve for own use */ #define IOPORT_DBG 0xe0
@@ -36,15 +37,15 @@ static inline u8 ioport__read8(u8 *data) {return *data; } - +/* On BE platforms, PCI I/O is byteswapped, i.e. LE, so swap back. */ static inline u16 ioport__read16 (u16 *data) { -return *data; +return le16_to_cpu (*data); }static inline u32 ioport__read32 (u32 *data) { -return *data; +return le32_to_cpu (*data); }static inline void ioport__write8 (u8 *data,u8 value)
@@ -54,12 +55,12 @@ static inline void ioport__write8(u8 *data, u8 value)static inline void ioport__write16 (u16 *data,u16 value) { - *data = value; + *data =cpu_to_le16 (value); }static inline void ioport__write32 (u32 *data,u32 value) { - *data = value; + *data =cpu_to_le32 (value); }#endif /* KVM__IOPORT_H */
tools/kvm/include/kvm/pci.h +18 -6
@@ -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_ENDIANunsigned zeros :2 ;/* 1 .. 0 */ unsigned register_number :6 ;/* 7 .. 2 */ unsigned function_number :3 ;/* 10 .. 8 */
@@ -25,6 +27,16 @@ struct pci_config_address { unsigned bus_number : 8; /* 23 .. 16 */ unsigned reserved : 7; /* 30 .. 24 */ unsigned enable_bit : 1; /* 31 */ +#else + unsigned enable_bit : 1; /* 31 */ + unsigned reserved : 7; /* 30 .. 24 */ + unsigned bus_number : 8; /* 23 .. 16 */ + unsigned device_number : 5; /* 15 .. 11 */ + unsigned function_number : 3; /* 10 .. 8 */ + unsigned register_number : 6; /* 7 .. 2 */ + unsigned zeros : 2; /* 1 .. 0 */ +#endif +u32 w; };struct msix_table {
@@ -45,8 +57,8 @@ struct pci_device_header {u16 device_id;u16 command;u16 status; - u16 revision_id : 8; - u32 class : 24; +u8 revision_id; +u8 class[3 ];u8 cacheline_size;u8 latency_timer;u8 header_type;
@@ -56,8 +68,8 @@ struct pci_device_header {u16 subsys_vendor_id;u16 subsys_id;u32 exp_rom_bar; - u32 capabilities : 8; - u32 reserved1 : 24; +u8 capabilities; +u8 reserved1[3 ];u32 reserved2;u8 irq_line;u8 irq_pin;
@@ -66,7 +78,7 @@ struct pci_device_header {struct msix_cap msix;u8 empty[136 ];/* Rest of PCI config space */ u32 bar_size[6 ]; -}; +} __attribute__((packed));void pci__init (void );void pci__register (struct pci_device_header *dev,u8 dev_num);
tools/kvm/pci.c +2 -2
@@ -9,7 +9,7 @@static struct pci_device_header *pci_devices[PCI_MAX_DEVICES ]; -static struct pci_config_address pci_config_address; +static union pci_config_address pci_config_address;/* This is within our PCI gap - in an unused area */ static u32 io_space_blocks =KVM_32BIT_GAP_START +0x1000000 ;
@@ -105,7 +105,7 @@ static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port* When the kernel got the size it would write the address * back. */ -if (ioport__read32 (p + offset)) { +if (*(u32 *)(p + offset)) {/* See if kernel tries to mask one of the BARs */ if ((offset >= PCI_BAR_OFFSET(0)) && (offset <= PCI_BAR_OFFSET(6)) &&
tools/kvm/virtio/pci.c +22 -19
84 lines not on this page · raw message
Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
Quoted 5 lines · Matt Evans
vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The
pci_config_addressbitfield also needs to be reversed when building on BE systems.Signed-off-by Matt Evans <[email protected]>
Looks OK to me. Sasha, Cyrill?
Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
Quoted 9 lines · Pekka Enberg
Quoted 5 lines · Matt Evans
vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The
pci_config_addressbitfield also needs to be reversed when building on BE systems.Signed-off-by Matt Evans <[email protected]>Looks OK to me. Sasha, Cyrill?
BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!
Cyrill
Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines · Pekka Enberg
Quoted 4 lines · Matt Evans
vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The
pci_config_addressbitfield also needs to be reversed when building on BE systems.
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Signed-off-by Matt Evans <[email protected]>Looks OK to me. Sasha, Cyrill?
BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!
Hmm. This seems to break "make check" for me:
./kvm run -d tests/boot/boot_test.iso -p "init=init"
# kvm run -k ../../arch/x86/boot/bzImage -m 448 -c 4 --name guest-2845 [ 0.000000] Initializing cgroup subsys cpuset [ 0.000000] Initializing cgroup subsys cpu [ 0.000000] Linux version 3.2.0-rc3 (penberg@tux) (gcc version 4.6.0 20110603 (Red Hat 4.6.0-10) (GCC) ) #67 SMP Thu Nov 24 11:05:24 EET 2011 [ 0.000000] Command line: noapic noacpi pci=conf1 reboot=k panic=1 i8042.direct=1 i8042.dumbkbd=1 i8042.nopnp=1 console=ttyS0 earlyprintk=serial i8042.noaux=1 init=init root=/dev/vda rw [ 0.000000] BIOS-provided physical RAM map: [ 0.000000] BIOS-e820: 0000000000000000 - 000000000009fc00 (usable) [ 0.000000] BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved) [ 0.000000] BIOS-e820: 00000000000f0000 - 00000000000fffff (reserved) [ 0.000000] BIOS-e820: 0000000000100000 - 000000001c000000 (usable) [ 0.000000] bootconsole [earlyser0] enabled [ 0.000000] NX (Execute Disable) protection: active [ 0.000000] DMI not present or invalid. [ 0.000000] No AGP bridge found [ 0.000000] last_pfn = 0x1c000 max_arch_pfn = 0x400000000 [ 0.000000] x86 PAT enabled: cpu 0, old 0x70106, new 0x7010600070106 [ 0.000000] CPU MTRRs all blank - virtualized system. [ 0.000000] found SMP MP-table at [ffff8800000f0390] f0390 [ 0.000000] init_memory_mapping: 0000000000000000-000000001c000000 [ 0.000000] ACPI Error: A valid RSDP was not found (20110623/tbxfroot-219) [ 0.000000] No NUMA configuration found [ 0.000000] Faking a node at 0000000000000000-000000001c000000 [ 0.000000] Initmem setup node 0 0000000000000000-000000001c000000 [ 0.000000] NODE_DATA [000000001bfec000 - 000000001bffffff] [ 0.000000] kvm-clock: Using msrs 4b564d01 and 4b564d00 [ 0.000000] kvm-clock: cpu 0, msr 0:1b71301, boot clock [ 0.000000] Zone PFN ranges: [ 0.000000] DMA 0x00000010 -> 0x00001000 [ 0.000000] DMA32 0x00001000 -> 0x00100000 [ 0.000000] Normal empty [ 0.000000] Movable zone start PFN for each node [ 0.000000] early_node_map[2] active PFN ranges [ 0.000000] 0: 0x00000010 -> 0x0000009f [ 0.000000] 0: 0x00000100 -> 0x0001c000 [ 0.000000] SFI: Simple Firmware Interface v0.81 http://simplefirmware.org [ 0.000000] Intel MultiProcessor Specification v1.4 [ 0.000000] MPTABLE: OEM ID: KVMCPU00 [ 0.000000] MPTABLE: Product ID: 0.1 [ 0.000000] MPTABLE: APIC at: 0xFEE00000 [ 0.000000] Processor #0 (Bootup-CPU) [ 0.000000] Processor #1 [ 0.000000] Processor #2 [ 0.000000] Processor #3 [ 0.000000] IOAPIC[0]: apic_id 5, version 17, address 0xfec00000, GSI 0-23 [ 0.000000] Processors: 4 [ 0.000000] SMP: Allowing 4 CPUs, 0 hotplug CPUs [ 0.000000] PM: Registered nosave memory: 000000000009f000 - 00000000000a0000 [ 0.000000] PM: Registered nosave memory: 00000000000a0000 - 00000000000f0000 [ 0.000000] PM: Registered nosave memory: 00000000000f0000 - 00000000000ff000 [ 0.000000] PM: Registered nosave memory: 00000000000ff000 - 0000000000100000 [ 0.000000] Allocating PCI resources starting at 1c000000 (gap: 1c000000:e4000000) [ 0.000000] Booting paravirtualized kernel on KVM [ 0.000000] setup_percpu: NR_CPUS:256 nr_cpumask_bits:256 nr_cpu_ids:4 nr_node_ids:1 [ 0.000000] PERCPU: Embedded 27 pages/cpu @ffff88001bc00000 s77888 r8192 d24512 u524288 [ 0.000000] kvm-clock: cpu 0, msr 0:1bc12301, primary cpu clock [ 0.000000] KVM setup async PF for cpu 0 [ 0.000000] kvm-stealtime: cpu 0, msr 1bc0d000 [ 0.000000] Built 1 zonelists in Node order, mobility grouping on. Total pages: 112778 [ 0.000000] Policy zone: DMA32 [ 0.000000] Kernel command line: noapic noacpi pci=conf1 reboot=k panic=1 i8042.direct=1 i8042.dumbkbd=1 i8042.nopnp=1 console=ttyS0 earlyprintk=serial i8042.noaux=1 init=init root=/dev/vda rw [ 0.000000] PID hash table entries: 2048 (order: 2, 16384 bytes) [ 0.000000] xsave/xrstor: enabled xstate_bv 0x7, cntxt size 0x340 [ 0.000000] Checking aperture... [ 0.000000] No AGP bridge found [ 0.000000] Memory: 435408k/458752k available (4752k kernel code, 452k absent, 22892k reserved, 6886k data, 908k init) [ 0.000000] SLUB: Genslabs=15, HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1 [ 0.000000] Hierarchical RCU implementation. [ 0.000000] RCU dyntick-idle grace-period acceleration is enabled. [ 0.000000] NR_IRQS:16640 nr_irqs:712 16 [ 0.000000] Console: colour *CGA 80x25 [ 0.000000] console [ttyS0] enabled, bootconsole disabled [ 0.000000] console [ttyS0] enabled, bootconsole disabled [ 0.000000] allocated 4194304 bytes of page_cgroup [ 0.000000] please try 'cgroup_disable=memory' option if you don't want memory cgroups [ 0.000000] Detected 2691.682 MHz processor. [ 0.000999] Calibrating delay loop (skipped) preset value.. 5383.36 BogoMIPS (lpj=2691682) [ 0.002009] pid_max: default: 32768 minimum: 301 [ 0.002722] Security Framework initialized [ 0.003146] Dentry cache hash table entries: 65536 (order: 7, 524288 bytes) [ 0.005202] Inode-cache hash table entries: 32768 (order: 6, 262144 bytes) [ 0.006221] Mount-cache hash table entries: 256 [ 0.007267] Initializing cgroup subsys cpuacct [ 0.007810] Initializing cgroup subsys memory [ 0.008042] Initializing cgroup subsys devices [ 0.008591] Initializing cgroup subsys freezer [ 0.009003] Initializing cgroup subsys net_cls [ 0.009452] Initializing cgroup subsys blkio [ 0.010015] Initializing cgroup subsys perf_event [ 0.010554] CPU: Physical Processor ID: 0 [ 0.011002] CPU: Processor Core ID: 0 [ 0.011390] mce: CPU supports 32 MCE banks [ 0.013371] ftrace: allocating 24096 entries in 95 pages [ 0.016161] CPU0: Intel 06/2a stepping 07 [ 0.118022] Performance Events: unsupported p6 CPU model 42 no PMU driver, software events only. [ 0.119085] NMI watchdog disabled (cpu0): hardware events not enabled [ 0.119886] Booting Node 0, Processors #1 [ 0.132990] kvm-clock: cpu 1, msr 0:1bc92301, secondary cpu clock [ 0.133013] NMI watchdog disabled (cpu1): hardware events not enabled [ 0.133155] #2 [ 0.133035] KVM setup async PF for cpu 1 [ 0.133035] kvm-stealtime: cpu 1, msr 1bc8d000 [ 0.146998] kvm-clock: cpu 2, msr 0:1bd12301, secondary cpu clock [ 0.147018] NMI watchdog disabled (cpu2): hardware events not enabled [ 0.147158] #3 Ok. [ 0.147042] KVM setup async PF for cpu 2 [ 0.147042] kvm-stealtime: cpu 2, msr 1bd0d000 [ 0.159987] kvm-clock: cpu 3, msr 0:1bd92301, secondary cpu clock [ 0.160018] NMI watchdog disabled (cpu3): hardware events not enabled [ 0.160052] Brought up 4 CPUs [ 0.160054] Total of 4 processors activated (21533.45 BogoMIPS). [ 0.160050] KVM setup async PF for cpu 3 [ 0.160050] kvm-stealtime: cpu 3, msr 1bd8d000 [ 0.166066] devtmpfs: initialized [ 0.169332] atomic64 test passed for x86-64 platform with CX8 and with SSE [ 0.170095] RTC time: 11:40:38, date: 12/06/11 [ 0.170631] NET: Registered protocol family 16 [ 0.173092] PCI: Using configuration type 1 for base access [ 0.175422] bio: create slab <bio-0> at 0 [ 0.176087] ACPI: Interpreter disabled. [ 0.177069] vgaarb: loaded [ 0.177585] SCSI subsystem initialized [ 0.178077] usbcore: registered new interface driver usbfs [ 0.179013] usbcore: registered new interface driver hub [ 0.180077] usbcore: registered new device driver usb [ 0.181129] PCI: Probing PCI hardware [ 0.182273] NetLabel: Initializing [ 0.182984] NetLabel: domain hash size = 128 [ 0.183675] NetLabel: protocols = UNLABELED CIPSOv4 [ 0.183994] NetLabel: unlabeled traffic allowed by default [ 0.184986] Switching to clocksource kvm-clock [ 0.193502] pnp: PnP ACPI: disabled [ 0.201702] NET: Registered protocol family 2 [ 0.202465] IP route cache hash table entries: 4096 (order: 3, 32768 bytes) [ 0.203701] TCP established hash table entries: 16384 (order: 6, 262144 bytes) [ 0.204975] TCP bind hash table entries: 16384 (order: 6, 262144 bytes) [ 0.206334] TCP: Hash tables configured (established 16384 bind 16384) [ 0.207420] TCP reno registered [ 0.207919] UDP hash table entries: 256 (order: 1, 8192 bytes) [ 0.208865] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes) [ 0.209934] NET: Registered protocol family 1 [ 0.210904] kvm: no hardware support [ 0.211689] platform rtc_cmos: registered platform RTC device (no PNP device found) [ 0.217236] alg: No test for __gcm-aes-aesni (__driver-gcm-aes-aesni) [ 0.218979] audit: initializing netlink socket (disabled) [ 0.220207] type=2000 audit(1323171638.219:1): initialized [ 0.237755] HugeTLB registered 2 MB page size, pre-allocated 0 pages [ 0.240695] VFS: Disk quotas dquot_6.5.2 [ 0.241409] Dquot-cache hash table entries: 512 (order 0, 4096 bytes) [ 0.242980] Installing v9fs 9p2000 file system support [ 0.243865] msgmni has been set to 850 [ 0.245846] alg: No test for stdrng (krng) [ 0.246747] NET: Registered protocol family 38 [ 0.247489] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253) [ 0.248841] io scheduler noop registered [ 0.249551] io scheduler deadline registered [ 0.250295] io scheduler cfq registered (default) [ 0.251156] pci_hotplug: PCI Hot Plug PCI Core version: 0.5 [ 0.252108] pciehp: PCI Express Hot Plug Controller Driver version: 0.4 [ 0.253206] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5 [ 0.254505] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled [ 0.276481] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A [ 0.306891] serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A [ 0.333156] serial8250: ttyS2 at I/O 0x3e8 (irq = 4) is a 16550A [ 0.334767] Non-volatile memory driver v1.3 [ 0.335276] Linux agpgart interface v0.103 [ 0.338190] brd: module loaded [ 0.339946] loop: module loaded [ 0.340440] Fixed MDIO Bus: probed [ 0.340946] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 0.341698] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver [ 0.342413] uhci_hcd: USB Universal Host Controller Interface driver [ 0.343194] usbcore: registered new interface driver usbserial [ 0.343840] USB Serial support registered for generic [ 0.344436] usbcore: registered new interface driver usbserial_generic [ 0.345170] usbserial: USB Serial Driver core [ 0.345649] i8042: PNP detection disabled [ 0.346277] serio: i8042 KBD port at 0x60,0x64 irq 1 [ 0.347061] mousedev: PS/2 mouse device common for all mice [ 0.348078] input: AT Raw Set 2 keyboard as /devices/platform/i8042/serio0/input/input0 [ 0.349770] rtc_cmos rtc_cmos: rtc core: registered rtc_cmos as rtc0 [ 0.350818] rtc_cmos rtc_cmos: only 24-hr supported [ 0.351831] device-mapper: uevent: version 1.0.3 [ 0.352788] device-mapper: ioctl: 4.22.0-ioctl (2011-10-19) initialised: [email protected] [ 0.354096] cpuidle: using governor ladder [ 0.354554] cpuidle: using governor menu [ 0.354982] EFI Variables Facility v0.08 2004-May-17 [ 0.355676] usbcore: registered new interface driver usbhid [ 0.356297] usbhid: USB HID core driver [ 0.356748] ip_tables: (C) 2000-2006 Netfilter Core Team [ 0.357344] TCP cubic registered [ 0.357705] NET: Registered protocol family 17 [ 0.358214] Installing 9P2000 support [ 0.358627] Registering the dns_resolver key type [ 0.359358] registered taskstats version 1 [ 0.359824] IMA: No TPM chip found, activating TPM-bypass! [ 0.360677] Magic number: 7:784:680 [ 0.361129] drivers/rtc/hctosys.c: unable to open rtc device (rtc0) [ 0.361841] Initializing network drop monitor service [ 0.362933] md: Waiting for all devices to be available before autodetect [ 0.363691] md: If you don't use raid, use raid=noautodetect [ 0.364537] md: Autodetecting RAID arrays. [ 0.364997] md: Scanned 0 and added 0 devices. [ 0.365502] md: autorun ... [ 0.365809] md: ... autorun DONE. [ 0.366234] VFS: Cannot open root device "vda" or unknown-block(0,0) [ 0.367056] Please append a correct "root=" boot option; here are the available partitions: [ 0.368484] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) [ 0.369907] Pid: 1, comm: swapper Not tainted 3.2.0-rc3 #67 [ 0.370644] Call Trace: [ 0.370922] [<ffffffff8148f63b>] panic+0x91/0x1a5 [ 0.371450] [<ffffffff81b73fc9>] mount_block_root+0x250/0x27b [ 0.372107] [<ffffffff81b7417a>] mount_root+0x53/0x57 [ 0.372662] [<ffffffff81b742eb>] prepare_namespace+0x16d/0x1a6 [ 0.373312] [<ffffffff8109b4a3>] ? release_tgcred+0x2f/0x2f [ 0.373923] [<ffffffff81b73cb5>] kernel_init+0x153/0x158 [ 0.374527] [<ffffffff81076758>] ? schedule_tail+0x27/0x6c [ 0.375147] [<ffffffff814a0474>] kernel_thread_helper+0x4/0x10 [ 0.375785] [<ffffffff81b73b62>] ? start_kernel+0x3bd/0x3bd [ 0.376408] [<ffffffff814a0470>] ? gs_change+0x13/0x13 [ 0.377064] Rebooting in 1 seconds..
*** Compatibility Warning ***
virtio-blk device was not detected
While you have requested a virtio-blk device, the guest kernel did not initialize it.
Please make sure that the guest kernel was compiled with CONFIG_VIRTIO_BLK=y enabled in its .config
# KVM session ended normally.
Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
Quoted 7 lines · Pekka Enberg
Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines · Pekka Enberg
Quoted 4 lines · Matt Evans
vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The
pci_config_addressbitfield also needs to be reversed when building on BE systems.
Quoted 9 lines
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Signed-off-by Matt Evans <[email protected]>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
Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
Quoted 20 lines · Cyrill Gorcunov
Quoted 7 lines · Pekka Enberg
Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines · Pekka Enberg
Quoted 4 lines · Matt Evans
vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The
pci_config_addressbitfield also needs to be reversed when building on BE systems.Quoted 9 lines
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Signed-off-by Matt Evans <[email protected]>Looks OK to me. Sasha, Cyrill?
BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!
Hmm. This seems to break "make check" for me:
If you change back to
Quoted 7 lines
static struct pci_device_header pci_shmem_pci_device = { ... .class = 0xFF0000, /* misc pci device */ ...};
does it help?
No but dropping these hunks fixes it for me:
@@ -17,7 +18,8 @@
#define PCI_CONFIG_BUS_FORWARD 0xcfa
#define PCI_IO_SIZE 0x100
-struct pci_config_address {
+union pci_config_address {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned zeros : 2; /* 1 .. 0 */
unsigned register_number : 6; /* 7 .. 2 */
unsigned function_number : 3; /* 10 .. 8 */
@@ -25,6 +27,16 @@ struct pci_config_address {
unsigned bus_number : 8; /* 23 .. 16 */
unsigned reserved : 7; /* 30 .. 24 */
unsigned enable_bit : 1; /* 31 */
+#else
+ unsigned enable_bit : 1; /* 31 */
+ unsigned reserved : 7; /* 30 .. 24 */
+ unsigned bus_number : 8; /* 23 .. 16 */
+ unsigned device_number : 5; /* 15 .. 11 */
+ unsigned function_number : 3; /* 10 .. 8 */
+ unsigned register_number : 6; /* 7 .. 2 */
+ unsigned zeros : 2; /* 1 .. 0 */+#endif
+ u32 w;
};
Pekka
Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
Quoted 49 lines · Pekka Enberg
Quoted 20 lines · Cyrill Gorcunov
Quoted 7 lines · Pekka Enberg
Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines · Pekka Enberg
Quoted 4 lines · Matt Evans
vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The
pci_config_addressbitfield also needs to be reversed when building on BE systems.Quoted 9 lines
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Signed-off-by Matt Evans <[email protected]>Looks OK to me. Sasha, Cyrill?
BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!
Hmm. This seems to break "make check" for me:
If you change back to
Quoted 7 lines
static struct pci_device_header pci_shmem_pci_device = { ... .class = 0xFF0000, /* misc pci device */ ...};
does it help?
No but dropping these hunks fixes it for me:
tools/kvm/include/kvm/pci.h +5
-1@@ -17,7 +18,8 @@#define PCI_CONFIG_BUS_FORWARD 0xcfa#define PCI_IO_SIZE 0x100 -struct pci_config_address { +union pci_config_address { +#if __BYTE_ORDER == __LITTLE_ENDIANunsigned zeros :2 ;/* 1 .. 0 */ unsigned register_number :6 ;/* 7 .. 2 */ unsigned function_number :3 ;/* 10 .. 8 */ @@ -25,6 +27,16 @@ struct pci_config_address { unsigned bus_number : 8; /* 23 .. 16 */ unsigned reserved : 7; /* 30 .. 24 */ unsigned enable_bit : 1; /* 31 */ +#else + unsigned enable_bit : 1; /* 31 */ + unsigned reserved : 7; /* 30 .. 24 */
tools/kvm/include/kvm/pci.h struct pci_config_address { · line 42
Quoted 10 lines
tools/kvm/include/kvm/pci.h +7
-0+ unsigned bus_number : 8; /* 23 .. 16 */ + unsigned device_number : 5; /* 15 .. 11 */ + unsigned function_number : 3; /* 10 .. 8 */ + unsigned register_number : 6; /* 7 .. 2 */ + unsigned zeros : 2; /* 1 .. 0 */ +#endif +u32 w; }; Pekka
Hehe, this is because it should be rtaher defined as
union pci_config_address {
struct {
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned zeros : 2;
unsigned register_number : 6;
#else
... #endif
}
u32 w;
};
Cyrill
Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
Quoted 70 lines · Cyrill Gorcunov
Quoted 49 lines · Pekka Enberg
Quoted 20 lines · Cyrill Gorcunov
Quoted 7 lines · Pekka Enberg
Quoted 6 lines · Cyrill Gorcunov
Quoted 5 lines · Pekka Enberg
Quoted 4 lines · Matt Evans
vesa, pci-shmem and virtio-pci devices need to set up config space with little-endian conversions (as config space is LE). The
pci_config_addressbitfield also needs to be reversed when building on BE systems.Quoted 9 lines
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Signed-off-by Matt Evans <[email protected]>Looks OK to me. Sasha, Cyrill?
BIOS part looks pretty good to me. LE/BE part as well. Thanks Matt!
Hmm. This seems to break "make check" for me:
If you change back to
Quoted 7 lines
static struct pci_device_header pci_shmem_pci_device = { ... .class = 0xFF0000, /* misc pci device */ ...};
does it help?
No but dropping these hunks fixes it for me:
(quoted diff) +5
-1@@ -17,7 +18,8 @@ #define PCI_CONFIG_BUS_FORWARD 0xcfa #define PCI_IO_SIZE 0x100 -struct pci_config_address { +union pci_config_address { +#if __BYTE_ORDER == __LITTLE_ENDIAN unsigned zeros : 2; /* 1 .. 0 */ unsigned register_number : 6; /* 7 .. 2 */ unsigned function_number : 3; /* 10 .. 8 */@@ -25,6 +27,16 @@ struct pci_config_address { unsigned bus_number : 8; /* 23 .. 16 */ unsigned reserved : 7; /* 30 .. 24 */ unsigned enable_bit : 1; /* 31 */ +#else + unsigned enable_bit : 1; /* 31 */ + unsigned reserved : 7; /* 30 .. 24 */Review struct pci_config_address { · line 42
Quoted 10 lines
(quoted diff) +7
-0+ unsigned bus_number : 8; /* 23 .. 16 */ + unsigned device_number : 5; /* 15 .. 11 */ + unsigned function_number : 3; /* 10 .. 8 */ + unsigned register_number : 6; /* 7 .. 2 */ + unsigned zeros : 2; /* 1 .. 0 */ +#endif + u32 w; }; PekkaHehe, this is because it should be rtaher defined as
union
pci_config_address{
struct {#if __BYTE_ORDER == __LITTLE_ENDIAN unsigned zeros : 2; unsigned register_number : 6; #else ...
Quoted 4 lines
#endif
}
u32 w;
};
Yup, that fixes it for me.
Pekka
Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
Quoted 15 lines · Pekka Enberg
Quoted 14 lines
Hehe, this is because it should be rtaher defined as
union
pci_config_address{
struct {
#if__BYTE_ORDER==__LITTLE_ENDIAN
unsigned zeros : 2;
unsignedregister_number: 6;
#else
...
#endif
}
u32 w;
};
Quoted 2 lines
Yup, that fixes it for me.
Good. Matt, mind to update?
Cyrill
Re: [PATCH 23/28] kvm tools: Endian-sanitise pci.h and PCI device setup
Quoted 16 lines · Cyrill Gorcunov
Quoted 15 lines · Pekka Enberg
Quoted 14 lines
Hehe, this is because it should be rtaher defined as
union
pci_config_address{
struct {
#if__BYTE_ORDER==__LITTLE_ENDIAN
unsigned zeros : 2;
unsignedregister_number: 6;
#else
...
#endif
}
u32 w;
};
Quoted 4 lines
Quoted 2 lines
Yup, that fixes it for me.
Good. Matt, mind to update?
Absolutely -- thank you for digging in and debugging that! I'll repost a V2.
Cheers,
Matt
PATCH 24/28 kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
In reply to a message not in the archiveThe field size is currently wrong, read into a 32bit word instead of 16. This casues trouble when BE.
--- tools/kvm/virtio/pci.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
tools/kvm/virtio/pci.c +1 -2
@@ -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);
Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
Quoted 14 lines · Matt Evans
The field size is currently wrong, read into a 32bit word instead of 16. This casues trouble when BE.
Signed-off-by Matt Evans <[email protected]>---
tools/kvm/virtio/pci.c | 3 +--1 files changed, 1 insertions(+), 2 deletions(-)tools/kvm/virtio/pci.c +0
-0@@ -116,8 +116,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, break;
Quoted 8 lines
case
VIRTIO_PCI_QUEUE_NUM:
val =vtrans->virtio_ops->get_size_vq(kvm, vpci->dev, vpci->queue_selector);
-ioport__write32(data, val);
- break;
+ioport__write16(data, val);
break;
caseVIRTIO_PCI_STATUS:
ioport__write8(data,vpci->status);
Looks good to me. Asias, Sasha?
Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
Quoted 9 lines · Pekka Enberg
Quoted 8 lines · Matt Evans
The field size is currently wrong, read into a 32bit word instead of 16. This casues trouble when BE.
Signed-off-by Matt Evans <[email protected]>--- tools/kvm/virtio/pci.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
Quoted 16 lines
Quoted 5 lines
tools/kvm/virtio/pci.c +0
-0tools/kvm/virtio/pci.c static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, · line 122
Quoted 9 lines
tools/kvm/virtio/pci.c +1
-2@@ -116,8 +116,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port,break ;case VIRTIO_PCI_QUEUE_NUM : val = vtrans->virtio_ops->get_size_vq (kvm, vpci->dev, vpci->queue_selector); -ioport__write32 (data, val); -break ; +ioport__write16 (data, val);break ;case VIRTIO_PCI_STATUS :ioport__write8 (data, vpci->status);Looks good to me. Asias, Sasha?
Looks good to me.
Signature · 1 line
Asias He
Pekka Enberg
AppliedRe: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
Quoted 13 lines · Asias He
Quoted 4 lines
Quoted 4 lines
(quoted diff) +0
-0@@ -116,8 +116,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, break;case
VIRTIO_PCI_QUEUE_NUM:
val =vtrans->virtio_ops->get_size_vq(kvm, vpci->dev, vpci->queue_selector);Quoted 8 lines
Quoted 6 lines
-
ioport__write32(data, val);
- break;
+ioport__write16(data, val); break;
caseVIRTIO_PCI_STATUS:
ioport__write8(data,vpci->status);Looks good to me. Asias, Sasha?
Quoted 1 line
Looks good to me.
Applied, thanks!
Re: [PATCH 24/28] kvm tools: Fix virtio-pci endian bug when reading VIRTIO_PCI_QUEUE_NUM
In reply to Pekka EnbergQuoted 9 lines · Pekka Enberg
Quoted 8 lines · Matt Evans
The field size is currently wrong, read into a 32bit word instead of 16. This casues trouble when BE.
Signed-off-by Matt Evans <[email protected]>--- tools/kvm/virtio/pci.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
Quoted 16 lines
Quoted 5 lines
tools/kvm/virtio/pci.c +0
-0tools/kvm/virtio/pci.c static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, · line 122
Quoted 9 lines
tools/kvm/virtio/pci.c +1
-2@@ -116,8 +116,7 @@ static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port,break ;case VIRTIO_PCI_QUEUE_NUM : val = vtrans->virtio_ops->get_size_vq (kvm, vpci->dev, vpci->queue_selector); -ioport__write32 (data, val); -break ; +ioport__write16 (data, val);break ;case VIRTIO_PCI_STATUS :ioport__write8 (data, vpci->status);Looks good to me. Asias, Sasha?
Looks good.
Signature · 1 line
Sasha.
PATCH 25/28 kvm tools: Correctly set virtio-pci bar_size and remove hardwired address
In reply to a message not in the archiveThe BAR addresses are set up fine, but missed the bar_size[] array which is now updated correspondingly.
Use PCI_IO_SIZE instead of '0x100'.
--- tools/kvm/virtio/pci.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)
tools/kvm/virtio/pci.c +5 -2
@@ -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 ;
PATCH 26/28 kvm tools: Add pci__config_{rd,wr}(), pci__find_dev() and fix PCI config register addressing
In reply to a message not in the archiveThis allows config space access in a more natural manner than clunky x86 IO ports, and is useful for other architectures.
Furthermore, the actual registers were only accessed in 32bit chunks; other systems (e.g. PPC) allow smaller accesses so that, for example, the 16-bit config field can be read directly. This patch allows this sort of addressing.
--- tools/kvm/include/kvm/pci.h | 5 +++ tools/kvm/pci.c | 63 +++++++++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 23 deletions(-)
tools/kvm/include/kvm/pci.h +5 -0
@@ -7,6 +7,8 @@#include <linux/msi.h> #include <endian.h> +#include "kvm/kvm.h" +#define PCI_MAX_DEVICES 256/* * PCI Configuration Mechanism #1 I/O ports. See Section 3.7.4.1.
@@ -82,6 +84,9 @@ struct pci_device_header {void pci__init (void );void pci__register (struct pci_device_header *dev,u8 dev_num); +struct pci_device_header *pci__find_dev (u8 dev_num);u32 pci_get_io_space_block (u32 size); +void pci__config_wr (struct kvm *kvm,union pci_config_address addr,void *data,int size); +void pci__config_rd (struct kvm *kvm,union pci_config_address addr,void *data,int size);#endif /* KVM__PCI_H */
tools/kvm/pci.c +40 -23
108 lines not on this page · raw message
PATCH 27/28 kvm tools: Arch-specific define for PCI MMIO allocation area
In reply to a message not in the archivepci_get_io_space_block() used to grab addresses from KVM_32BIT_GAP_START + 0x1000000, which is x86-specific. Create a new define, KVM_PCI_MMIO_AREA, to specify a bus address these allocations can come from.
--- tools/kvm/pci.c | 8 ++++++-- tools/kvm/x86/include/kvm/kvm-arch.h | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-)
tools/kvm/pci.c +6 -2
@@ -11,8 +11,12 @@ static struct pci_device_header *pci_devices[PCI_MAX_DEVICES];static union pci_config_address pci_config_address; -/* This is within our PCI gap - in an unused area */ -static u32 io_space_blocks =KVM_32BIT_GAP_START +0x1000000 ; +/* This is within our PCI gap - in an unused area. +* Note this is a PCI *bus address*, is used to assign BARs etc.! +* (That's why it can still 32bit even with 64bit guests-- 64bit +* PCI isn't currently supported.) +*/ +static u32 io_space_blocks =KVM_PCI_MMIO_AREA ;u32 pci_get_io_space_block (u32 size) {
tools/kvm/x86/include/kvm/kvm-arch.h +5 -0
@@ -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() */
PATCH 28/28 kvm tools: Create arch-specific kvm_cpu__emulate_io()
In reply to a message not in the archiveDifferent architectures will deal with MMIO exits differently. For example, KVM_EXIT_IO is x86-specific, and I/O cycles are often synthesisted by steering into windows in PCI bridges on other architectures.
This patch moves the IO/MMIO exit code from the main runloop into x86/kvm-cpu.c
--- tools/kvm/include/kvm/kvm-cpu.h | 1 + tools/kvm/kvm-cpu.c | 37 +++++-------------------------------- tools/kvm/x86/kvm-cpu.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 32 deletions(-)
tools/kvm/include/kvm/kvm-cpu.h +1 -0
@@ -13,6 +13,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu);void kvm_cpu__reboot (void );int kvm_cpu__start (struct kvm_cpu *cpu);bool kvm_cpu__handle_exit (struct kvm_cpu *vcpu); +bool kvm_cpu__emulate_io (struct kvm_cpu *cpu,struct kvm_run *kvm_run);int kvm_cpu__get_debug_fd (void );void kvm_cpu__set_debug_fd (int fd);
tools/kvm/kvm-cpu.c +5 -32
@@ -103,49 +103,22 @@ int kvm_cpu__start(struct kvm_cpu *cpu)kvm_cpu__show_registers (cpu);kvm_cpu__show_code (cpu);break ; -case KVM_EXIT_IO : { -bool ret; - - ret =kvm__emulate_io (cpu->kvm, - cpu->kvm_run->io.port, - (u8 *)cpu->kvm_run + - cpu->kvm_run->io.data_offset, - cpu->kvm_run->io.direction, - cpu->kvm_run->io.size, - cpu->kvm_run->io.count); - -if (!ret) +case KVM_EXIT_IO : +case KVM_EXIT_MMIO : +if (!kvm_cpu__emulate_io (cpu, cpu->kvm_run)) goto panic_kvm;break ; - } -case KVM_EXIT_MMIO : { -bool ret; - - ret =kvm__emulate_mmio (cpu->kvm, - cpu->kvm_run->mmio.phys_addr, - cpu->kvm_run->mmio.data, - cpu->kvm_run->mmio.len, - cpu->kvm_run->mmio.is_write); - -if (!ret) - goto panic_kvm; -break ; - }case KVM_EXIT_INTR :if (cpu->is_running)break ; goto exit_kvm;case KVM_EXIT_SHUTDOWN : goto exit_kvm; -default : { -bool ret; - - ret =kvm_cpu__handle_exit (cpu); -if (!ret) +default : +if (!kvm_cpu__handle_exit (cpu)) goto panic_kvm;break ; } - }kvm_cpu__handle_coalesced_mmio (cpu); }
tools/kvm/x86/kvm-cpu.c +37 -0
@@ -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",
Re: [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io()
Can we possibly do it by getting the generic code to call both 'kvm_cpu__arch_emulate_io' and 'kvm_cpu__arch_emulate_mmio', and have the ppc code have an empty static for 'kvm_cpu__arch_emulate_io'?
Quoted 136 lines · Matt Evans
Different architectures will deal with MMIO exits differently. For example,
KVM_EXIT_IOis 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.cSigned-off-by Matt Evans <[email protected]>--- tools/kvm/include/kvm/kvm-cpu.h | 1 + tools/kvm/kvm-cpu.c | 37 +++++-------------------------------- tools/kvm/x86/kvm-cpu.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 32 deletions(-)tools/kvm/include/kvm/kvm-cpu.h +1
-0@@ -13,6 +13,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu);void kvm_cpu__reboot (void );int kvm_cpu__start (struct kvm_cpu *cpu);bool kvm_cpu__handle_exit (struct kvm_cpu *vcpu); +bool kvm_cpu__emulate_io (struct kvm_cpu *cpu,struct kvm_run *kvm_run);int kvm_cpu__get_debug_fd (void );void kvm_cpu__set_debug_fd (int fd);tools/kvm/kvm-cpu.c +5
-32@@ -103,49 +103,22 @@ int kvm_cpu__start(struct kvm_cpu *cpu)kvm_cpu__show_registers (cpu);kvm_cpu__show_code (cpu);break ; -case KVM_EXIT_IO : { -bool ret; - - ret =kvm__emulate_io (cpu->kvm, - cpu->kvm_run->io.port, - (u8 *)cpu->kvm_run + - cpu->kvm_run->io.data_offset, - cpu->kvm_run->io.direction, - cpu->kvm_run->io.size, - cpu->kvm_run->io.count); - -if (!ret) +case KVM_EXIT_IO : +case KVM_EXIT_MMIO : +if (!kvm_cpu__emulate_io (cpu, cpu->kvm_run)) goto panic_kvm;break ; - } -case KVM_EXIT_MMIO : { -bool ret; - - ret =kvm__emulate_mmio (cpu->kvm, - cpu->kvm_run->mmio.phys_addr, - cpu->kvm_run->mmio.data, - cpu->kvm_run->mmio.len, - cpu->kvm_run->mmio.is_write); - -if (!ret) - goto panic_kvm; -break ; - }case KVM_EXIT_INTR :if (cpu->is_running)break ; goto exit_kvm;case KVM_EXIT_SHUTDOWN : goto exit_kvm; -default : { -bool ret; - - ret =kvm_cpu__handle_exit (cpu); -if (!ret) +default : +if (!kvm_cpu__handle_exit (cpu)) goto panic_kvm;break ; } - }kvm_cpu__handle_coalesced_mmio (cpu); }tools/kvm/x86/kvm-cpu.c +37
-1@@ -217,6 +217,43 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)return false; } +bool kvm_cpu__emulate_io (struct kvm_cpu *cpu,struct kvm_run *kvm_run) +{ +bool ret; +switch (kvm_run->exit_reason) { +case KVM_EXIT_IO : { + ret =kvm__emulate_io (cpu->kvm, + cpu->kvm_run->io.port, + (u8 *)cpu->kvm_run + + cpu->kvm_run->io.data_offset, + cpu->kvm_run->io.direction, + cpu->kvm_run->io.size, + cpu->kvm_run->io.count); + +if (!ret) + goto panic_kvm; +break ; + } +case KVM_EXIT_MMIO : { + ret =kvm__emulate_mmio (cpu->kvm, + cpu->kvm_run->mmio.phys_addr, + cpu->kvm_run->mmio.data, + cpu->kvm_run->mmio.len, + cpu->kvm_run->mmio.is_write); + +if (!ret) + goto panic_kvm; +break ; + } +default : +pr_warning ("Unknown exit reason %d in %s\n" , kvm_run->exit_reason, __FUNCTION__); +return false; + } +return true; +panic_kvm: +return false; +} +static void print_dtable (const char *name,struct kvm_dtable *dtable) { dprintf(debug_fd, " %s %016llx %08hx\n", --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Sasha.
Re: [PATCH 28/28] kvm tools: Create arch-specific kvm_cpu__emulate_io()
Quoted 3 lines · Sasha Levin
Can we possibly do it by getting the generic code to call both '
kvm_cpu__arch_emulate_io' and 'kvm_cpu__arch_emulate_mmio', and have the ppc code have an empty static for 'kvm_cpu__arch_emulate_io'?
Yeah that's nicer, I'll make that change... less invasive.
Cheers,
Matt
Quoted 139 lines · Matt Evans
Quoted 136 lines
Different architectures will deal with MMIO exits differently. For example,
KVM_EXIT_IOis 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.cSigned-off-by Matt Evans <[email protected]>--- tools/kvm/include/kvm/kvm-cpu.h | 1 + tools/kvm/kvm-cpu.c | 37 +++++-------------------------------- tools/kvm/x86/kvm-cpu.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 32 deletions(-)tools/kvm/include/kvm/kvm-cpu.h +1
-0@@ -13,6 +13,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu);void kvm_cpu__reboot (void );int kvm_cpu__start (struct kvm_cpu *cpu);bool kvm_cpu__handle_exit (struct kvm_cpu *vcpu); +bool kvm_cpu__emulate_io (struct kvm_cpu *cpu,struct kvm_run *kvm_run);int kvm_cpu__get_debug_fd (void );void kvm_cpu__set_debug_fd (int fd);tools/kvm/kvm-cpu.c +5
-32@@ -103,49 +103,22 @@ int kvm_cpu__start(struct kvm_cpu *cpu)kvm_cpu__show_registers (cpu);kvm_cpu__show_code (cpu);break ; -case KVM_EXIT_IO : { -bool ret; - - ret =kvm__emulate_io (cpu->kvm, - cpu->kvm_run->io.port, - (u8 *)cpu->kvm_run + - cpu->kvm_run->io.data_offset, - cpu->kvm_run->io.direction, - cpu->kvm_run->io.size, - cpu->kvm_run->io.count); - -if (!ret) +case KVM_EXIT_IO : +case KVM_EXIT_MMIO : +if (!kvm_cpu__emulate_io (cpu, cpu->kvm_run)) goto panic_kvm;break ; - } -case KVM_EXIT_MMIO : { -bool ret; - - ret =kvm__emulate_mmio (cpu->kvm, - cpu->kvm_run->mmio.phys_addr, - cpu->kvm_run->mmio.data, - cpu->kvm_run->mmio.len, - cpu->kvm_run->mmio.is_write); - -if (!ret) - goto panic_kvm; -break ; - }case KVM_EXIT_INTR :if (cpu->is_running)break ; goto exit_kvm;case KVM_EXIT_SHUTDOWN : goto exit_kvm; -default : { -bool ret; - - ret =kvm_cpu__handle_exit (cpu); -if (!ret) +default : +if (!kvm_cpu__handle_exit (cpu)) goto panic_kvm;break ; } - }kvm_cpu__handle_coalesced_mmio (cpu); }tools/kvm/x86/kvm-cpu.c +37
-1@@ -217,6 +217,43 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)return false; } +bool kvm_cpu__emulate_io (struct kvm_cpu *cpu,struct kvm_run *kvm_run) +{ +bool ret; +switch (kvm_run->exit_reason) { +case KVM_EXIT_IO : { + ret =kvm__emulate_io (cpu->kvm, + cpu->kvm_run->io.port, + (u8 *)cpu->kvm_run + + cpu->kvm_run->io.data_offset, + cpu->kvm_run->io.direction, + cpu->kvm_run->io.size, + cpu->kvm_run->io.count); + +if (!ret) + goto panic_kvm; +break ; + } +case KVM_EXIT_MMIO : { + ret =kvm__emulate_mmio (cpu->kvm, + cpu->kvm_run->mmio.phys_addr, + cpu->kvm_run->mmio.data, + cpu->kvm_run->mmio.len, + cpu->kvm_run->mmio.is_write); + +if (!ret) + goto panic_kvm; +break ; + } +default : +pr_warning ("Unknown exit reason %d in %s\n" , kvm_run->exit_reason, __FUNCTION__); +return false; + } +return true; +panic_kvm: +return false; +} +static void print_dtable (const char *name,struct kvm_dtable *dtable) { dprintf(debug_fd, " %s %016llx %08hx\n", --To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html