kvm tools: Only build/init i8042 on x86
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH v2 1/23 kvm tools: Only build/init i8042 on x86
Not every architecture has an i8042 kbd controller, so only use this when building for x86.
--- tools/kvm/Makefile | 2 +- tools/kvm/builtin-run.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-)
tools/kvm/Makefile +1 -1
@@ -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
@@ -943,7 +943,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);
PATCH v2 2/23 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 v2 3/23 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 v2 4/23 kvm tools: Get correct 64-bit types on PPC64 and link appropriately
In reply to a message not in the archivekvmtool's types.h includes <asm/types.h>, which by default on PPC64 brings in int-l64.h; define __SANE_USERSPACE_TYPES__ to get LL64 types.
This patch also adds CFLAGS to the final link, so that any -m64 is obeyed when linking, too.
--- tools/kvm/Makefile | 2 +- tools/kvm/include/linux/types.h | 1 + 2 files changed, 2 insertions(+), 1 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/include/linux/types.h +1 -0
@@ -2,6 +2,7 @@#define LINUX_TYPES_H #include <kvm/compiler.h> +#define __SANE_USERSPACE_TYPES__/* For PPC64, to get LL64 types */ #include <asm/types.h> typedef __u64 u64 ;
Re: [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately
If you also got kernel patches that add __SANE_USERSPACE_TYPES__ to the headers, and KVM_CAP_NR_VCPUS to KVM PPC, we can carry them in the KVM tools tree as well.
Quoted 37 lines · Matt Evans
kvmtool's
types.hincludes <asm/types.h>, which by default on PPC64 brings inint-l64.h; define__SANE_USERSPACE_TYPES__to get LL64 types.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/include/linux/types.h | 1 + 2 files changed, 2 insertions(+), 1 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/include/linux/types.h +1
-0@@ -2,6 +2,7 @@#define LINUX_TYPES_H #include <kvm/compiler.h> +#define __SANE_USERSPACE_TYPES__/* For PPC64, to get LL64 types */ #include <asm/types.h> typedef __u64 u64 ;
Signature · 1 line
Sasha.
Re: [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately
Quoted 3 lines · Sasha Levin
If you also got kernel patches that add
__SANE_USERSPACE_TYPES__to the headers, andKVM_CAP_NR_VCPUSto KVM PPC, we can carry them in the KVM tools tree as well.
Yup, all we need is ACKs from PPC maintainers.
Pekka
Re: [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately
Quoted 6 lines · Pekka Enberg
Quoted 3 lines · Sasha Levin
If you also got kernel patches that add
__SANE_USERSPACE_TYPES__to the headers, andKVM_CAP_NR_VCPUSto KVM PPC, we can carry them in the KVM tools tree as well.Yup, all we need is ACKs from PPC maintainers.
Cool, I've pinged them re. __SANE_USERSPACE_TYPES__, and that would be useful to carry in your tree. But, IMHO, the patch I sent to Alex ("[PATCH] KVM: PPC: Add KVM_CAP_NR_VCPUS and KVM_CAP_MAX_VCPUS") should go in via his tree. The KVM/PPC-HV kernel folk will get it quicker in their trees (pulled from Alex) and it's not a build problem, "only" a limit of SMP CPU numbers. That is, if you're building a kernel for PPC KVM today you'll probably use something more similar to Alex's tree than mainline/kvm tools tree.
Cheers,
Matt
Re: [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately
Quoted 8 lines · Matt Evans
Quoted 6 lines · Pekka Enberg
Quoted 3 lines · Sasha Levin
If you also got kernel patches that add
__SANE_USERSPACE_TYPES__to the headers, andKVM_CAP_NR_VCPUSto KVM PPC, we can carry them in the KVM tools tree as well.Yup, all we need is ACKs from PPC maintainers.
Quoted 7 lines
Cool, I've pinged them re.
__SANE_USERSPACE_TYPES__, and that would be useful to carry in your tree. But, IMHO, the patch I sent to Alex ("[PATCH] KVM: PPC: AddKVM_CAP_NR_VCPUSandKVM_CAP_MAX_VCPUS") should go in via his tree. The KVM/PPC-HV kernel folk will get it quicker in their trees (pulled from Alex) and it's not a build problem, "only" a limit of SMP CPU numbers. That is, if you're building a kernel for PPC KVM today you'll probably use something more similar to Alex's tree than mainline/kvm tools tree.
Definitely. The __SANE_USERSPACE_TYPES__ patch should probably go to powerpc git tree in addition to our tree.
Pekka
Re: [PATCH V2 04/23] kvm tools: Get correct 64-bit types on PPC64 and link appropriately
In reply to Matt EvansHi Pekka,
Quoted 5 lines · Matt Evans
kvmtool's
types.hincludes <asm/types.h>, which by default on PPC64 brings inint-l64.h; define__SANE_USERSPACE_TYPES__to get LL64 types.This patch also adds CFLAGS to the final link, so that any -m64 is obeyed when linking, too.
Just noticed this patch wasn't included in what you committed from this series, but is required for the PPC64 series to build.
I'm waiting on an ack on the /other/ patch (that adds SANE_USERSPACE_TYPES to PPC64 headers); I have a verbal one, but on-list is better :-) But, /this/ patch is somewhat independent from that.
If you're waiting so they can both go in together, then that's fine too. Just a reminder.
Cheers,
Matt
Quoted 36 lines
Signed-off-by Matt Evans <[email protected]>--- tools/kvm/Makefile | 2 +- tools/kvm/include/linux/types.h | 1 + 2 files changed, 2 insertions(+), 1 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/include/linux/types.h +1
-1@@ -2,6 +2,7 @@#define LINUX_TYPES_H #include <kvm/compiler.h> +#define __SANE_USERSPACE_TYPES__/* For PPC64, to get LL64 types */ #include <asm/types.h> typedef __u64 u64 ; --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 v2 5/23 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 v2 6/23 kvm tools: Don't die if KVM_CAP_NR_VCPUS isn't available
In reply to a message not in the archiveWe die() if we can't read KVM_CAP_NR_VCPUS, but the API docs suggest to assume the value 4 in this case. This is pertinent to PPC KVM, which currently does not support this CAP.
--- tools/kvm/kvm.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
tools/kvm/kvm.c +5 -1
@@ -266,7 +266,11 @@ int kvm__recommended_cpus(struct kvm *kvm) ret =ioctl (kvm->sys_fd,KVM_CHECK_EXTENSION ,KVM_CAP_NR_VCPUS );if (ret <=0 ) -die_perror ("KVM_CAP_NR_VCPUS" ); +/* +* api.txt states that if KVM_CAP_NR_VCPUS does not exist, +* assume 4. +*/ +return 4 ;return ret; }
PATCH v2 7/23 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" ); }
PATCH v2 8/23 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>
@@ -328,3 +330,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 v2 9/23 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
@@ -119,6 +119,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 v2 10/23 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 v2 11/23 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 | 7 ++----- 1 files changed, 2 insertions(+), 5 deletions(-)
tools/kvm/term.c +2 -5
@@ -30,16 +30,13 @@ 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 ; - c &=0xff ; -if (term_got_escape) { term_got_escape = false;if (c =='x' )
@@ -84,7 +81,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 ); }
PATCH v2 12/23 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
@@ -351,10 +351,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;
@@ -362,7 +363,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,
PATCH v2 13/23 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 | 13 ++++++++++--- 3 files changed, 17 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
@@ -388,23 +388,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 +10 -3
@@ -197,17 +197,24 @@ 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 ;
PATCH v2 14/23 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
@@ -828,6 +828,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
@@ -895,8 +897,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 v2 15/23 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
@@ -932,16 +932,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
@@ -965,6 +955,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 v2 16/23 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
@@ -809,8 +809,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 ();
@@ -828,6 +826,8 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) kvm->nrcpus = nrcpus; +irq__init (kvm); +pci__init ();/*
PATCH v2 17/23 kvm tools: Add ability to map guest RAM from hugetlbfs
In reply to a message not in the archiveAdd a --hugetlbfs commandline option to give a path to hugetlbfs-map guest memory (down in kvm__arch_init()). For x86, guest memory is a normal ANON mmap() if this option is not provided, otherwise a hugetlbfs mmap.
--- tools/kvm/builtin-run.c | 4 ++- tools/kvm/include/kvm/kvm.h | 4 +- tools/kvm/include/kvm/util.h | 4 +++ tools/kvm/kvm.c | 4 +- tools/kvm/util.c | 45 ++++++++++++++++++++++++++++++++++++++++++ tools/kvm/x86/kvm.c | 20 +++++++++++++++-- 6 files changed, 73 insertions(+), 8 deletions(-)
tools/kvm/builtin-run.c +3 -1
@@ -82,6 +82,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",
@@ -807,7 +809,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/include/kvm/util.h +4 -0
@@ -20,6 +20,7 @@#include <limits.h> #include <sys/param.h> #include <sys/types.h> +#include <linux/types.h> #ifdef __GNUC__#define NORETURN __attribute__((__noreturn__))
@@ -75,4 +76,7 @@ static inline void msleep(unsigned int msecs) {usleep (MSECS_TO_USECS (msecs)); } + +void *mmap_hugetlbfs (const char *htlbfs_path,u64 size); +#endif /* KVM__UTIL_H */
tools/kvm/kvm.c +2 -2
@@ -306,7 +306,7 @@ int kvm__max_cpus(struct kvm *kvm)return ret; } -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;
@@ -339,7 +339,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/util.c +45 -0
54 lines not on this page · raw message
tools/kvm/x86/kvm.c +17 -3
@@ -130,8 +130,22 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)strcat (cmdline," console=ttyS0 earlyprintk=serial i8042.noaux=1" ); } +/* This function wraps the decision between hugetlbfs map (if requested) or normal mmap */ +static void *mmap_anon_or_hugetlbfs (const char *hugetlbfs_path,u64 size) +{ +if (hugetlbfs_path) { +/* +* We don't /need/ to map guest RAM from hugetlbfs, but we do so +* if the user specifies a hugetlbfs path. +*/ +return mmap_hugetlbfs (hugetlbfs_path, size); + }else { +return mmap (NULL , size,PROT_RW ,MAP_ANON_NORESERVE ,-1 ,0 ); + } +} +/* 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;
@@ -147,9 +161,9 @@ void kvm__arch_init(struct kvm *kvm, const char *kvm_dev, u64 ram_size, const ch 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 ); + kvm->ram_start =mmap_anon_or_hugetlbfs (hugetlbfs_path, ram_size); }else { - kvm->ram_start =mmap (NULL , ram_size +KVM_32BIT_GAP_SIZE ,PROT_RW ,MAP_ANON_NORESERVE ,-1 ,0 ); + kvm->ram_start =mmap_anon_or_hugetlbfs (hugetlbfs_path, ram_size +KVM_32BIT_GAP_SIZE );if (kvm->ram_start !=MAP_FAILED ) {/* * We mprotect the gap (see kvm__init_ram() for details) PROT_NONE so that
Re: [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs
Quoted 152 lines · Matt Evans
Add a --hugetlbfs commandline option to give a path to hugetlbfs-map guest memory (down in
kvm__arch_init()). For x86, guest memory is a normal ANONmmap()if this option is not provided, otherwise a hugetlbfs mmap.Signed-off-by Matt Evans <[email protected]>--- tools/kvm/builtin-run.c | 4 ++- tools/kvm/include/kvm/kvm.h | 4 +- tools/kvm/include/kvm/util.h | 4 +++ tools/kvm/kvm.c | 4 +- tools/kvm/util.c | 45 ++++++++++++++++++++++++++++++++++++++++++ tools/kvm/x86/kvm.c | 20 +++++++++++++++-- 6 files changed, 73 insertions(+), 8 deletions(-)tools/kvm/builtin-run.c +3
-1@@ -82,6 +82,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",@@ -807,7 +809,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/include/kvm/util.h +4
-0@@ -20,6 +20,7 @@#include <limits.h> #include <sys/param.h> #include <sys/types.h> +#include <linux/types.h> #ifdef __GNUC__#define NORETURN __attribute__((__noreturn__))@@ -75,4 +76,7 @@ static inline void msleep(unsigned int msecs) {usleep (MSECS_TO_USECS (msecs)); } + +void *mmap_hugetlbfs (const char *htlbfs_path,u64 size); +#endif /* KVM__UTIL_H */ tools/kvm/kvm.c +2
-2@@ -306,7 +306,7 @@ int kvm__max_cpus(struct kvm *kvm)return ret; } -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;@@ -339,7 +339,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/util.c +30
-0@@ -4,6 +4,11 @@#include "kvm/util.h" +#include <linux/magic.h> /* For HUGETLBFS_MAGIC */ +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/statfs.h> +static void report (const char *prefix,const char *err,va_list params) {char msg[1024 ];@@ -99,3 +104,43 @@ size_t strlcat(char *dest, const char *src, size_t count)return res; } + +void *mmap_hugetlbfs (const char *htlbfs_path,u64 size) +{ +char mpath[PATH_MAX ]; +int fd; +int r; +struct statfs sfs; +void *addr; + +do { +/* +* QEMU seems to work around this returning EINTR... Let's do +* that too. +*/ + r =statfs (htlbfs_path, &sfs); + }while (r && errno ==EINTR ); + +if (r) +die ("Can't stat %s\n" , htlbfs_path); + +if (sfs.f_type !=HUGETLBFS_MAGIC ) { +die ("%s is not hugetlbfs!\n" , htlbfs_path); + } + +if (sfs.f_bsize ==0 || (unsigned long )sfs.f_bsize > size) {
tools/kvm/util.c size_t strlcat(char *dest, const char *src, size_t count) · line 141
Quoted 10 lines
tools/kvm/util.c +10
-0+die ("Can't use hugetlbfs pagesize %ld for mem size %lld\n" , + sfs.f_bsize, size); + } + +snprintf (mpath,PATH_MAX ,"%s/kvmtoolXXXXXX" , htlbfs_path); + fd =mkstemp (mpath); +if (fd <0 ) +die ("Can't open %s for hugetlbfs map\n" , mpath); +unlink (mpath); +ftruncate (fd, size);
Getting this thing here:
cc1: warnings being treated as errorsutil.c: In function 'mmap_hugetlbfs':
util.c:141:11: error: ignoring return value of 'ftruncate', declared with attribute warn_unused_result
make: *** [util.o] Error 1
Signature · 1 line
Sasha.
Re: [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs
Quoted 166 lines · Sasha Levin
Quoted 152 lines · Matt Evans
Add a --hugetlbfs commandline option to give a path to hugetlbfs-map guest memory (down in
kvm__arch_init()). For x86, guest memory is a normal ANONmmap()if this option is not provided, otherwise a hugetlbfs mmap.Signed-off-by Matt Evans <[email protected]>--- tools/kvm/builtin-run.c | 4 ++- tools/kvm/include/kvm/kvm.h | 4 +- tools/kvm/include/kvm/util.h | 4 +++ tools/kvm/kvm.c | 4 +- tools/kvm/util.c | 45 ++++++++++++++++++++++++++++++++++++++++++ tools/kvm/x86/kvm.c | 20 +++++++++++++++-- 6 files changed, 73 insertions(+), 8 deletions(-)tools/kvm/builtin-run.c +3
-1@@ -82,6 +82,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",@@ -807,7 +809,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/include/kvm/util.h +4
-0@@ -20,6 +20,7 @@#include <limits.h> #include <sys/param.h> #include <sys/types.h> +#include <linux/types.h> #ifdef __GNUC__#define NORETURN __attribute__((__noreturn__))@@ -75,4 +76,7 @@ static inline void msleep(unsigned int msecs) {usleep (MSECS_TO_USECS (msecs)); } + +void *mmap_hugetlbfs (const char *htlbfs_path,u64 size); +#endif /* KVM__UTIL_H */ tools/kvm/kvm.c +2
-2@@ -306,7 +306,7 @@ int kvm__max_cpus(struct kvm *kvm)return ret; } -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;@@ -339,7 +339,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/util.c +30
-0@@ -4,6 +4,11 @@#include "kvm/util.h" +#include <linux/magic.h> /* For HUGETLBFS_MAGIC */ +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/statfs.h> +static void report (const char *prefix,const char *err,va_list params) {char msg[1024 ];@@ -99,3 +104,43 @@ size_t strlcat(char *dest, const char *src, size_t count)return res; } + +void *mmap_hugetlbfs (const char *htlbfs_path,u64 size) +{ +char mpath[PATH_MAX ]; +int fd; +int r; +struct statfs sfs; +void *addr; + +do { +/* +* QEMU seems to work around this returning EINTR... Let's do +* that too. +*/ + r =statfs (htlbfs_path, &sfs); + }while (r && errno ==EINTR ); + +if (r) +die ("Can't stat %s\n" , htlbfs_path); + +if (sfs.f_type !=HUGETLBFS_MAGIC ) { +die ("%s is not hugetlbfs!\n" , htlbfs_path); + } + +if (sfs.f_bsize ==0 || (unsigned long )sfs.f_bsize > size) {tools/kvm/util.c size_t strlcat(char *dest, const char *src, size_t count) · line 141
Quoted 10 lines
tools/kvm/util.c +10
-0+die ("Can't use hugetlbfs pagesize %ld for mem size %lld\n" , + sfs.f_bsize, size); + } + +snprintf (mpath,PATH_MAX ,"%s/kvmtoolXXXXXX" , htlbfs_path); + fd =mkstemp (mpath); +if (fd <0 ) +die ("Can't open %s for hugetlbfs map\n" , mpath); +unlink (mpath); +ftruncate (fd, size);Getting this thing here:
Quoted 5 lines
cc1: warnings being treated as errors
util.c: In function 'mmap_hugetlbfs':
util.c:141:11: error: ignoring return value of 'ftruncate', declared with attributewarn_unused_result
make: *** [util.o] Error 1
Ooookay, I swear I'm not seeing that here, GCC 4.6.2 & no extra -W flags added.
I've added a check of ftruncate()'s return value, anyway.
Thanks,
Matt
Re: [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs
In reply to Matt EvansQuoted 11 lines · Matt Evans
Add a --hugetlbfs commandline option to give a path to hugetlbfs-map guest memory (down in
kvm__arch_init()). For x86, guest memory is a normal ANONmmap()if this option is not provided, otherwise a hugetlbfs mmap.Signed-off-by Matt Evans <[email protected]>tools/kvm/util.c +5
-0+void *mmap_hugetlbfs (const char *htlbfs_path,u64 size) +{ + char mpath[PATH_MAX]; + int fd; + int r;
tools/kvm/util.c size_t strlcat(char *dest, const char *src, size_t count)
Quoted 10 lines
tools/kvm/util.c +10
-0+ struct statfs sfs; + void *addr; + + do { + /* + * QEMU seems to work around this returning EINTR... Let's do + * that too. + */ + r = statfs(htlbfs_path, &sfs); + } while (r && errno = EINTR);
Can this really happen? What about EAGAIN? The retry logic really wants to live in tools/kvm/read-write.c as a xstatfs() wrapper if we do need this.
Pekka
Re: [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs
Quoted 18 lines · Pekka Enberg
Quoted 17 lines · Matt Evans
Add a --hugetlbfs commandline option to give a path to hugetlbfs-map guest memory (down in
kvm__arch_init()). For x86, guest memory is a normal ANONmmap()if this option is not provided, otherwise a hugetlbfs mmap.Signed-off-by Matt Evans <[email protected]>tools/kvm/util.c +11
-0+void *mmap_hugetlbfs (const char *htlbfs_path,u64 size) +{ +char mpath[PATH_MAX ]; +int fd; +int r; +struct statfs sfs; +void *addr; + + do { + /* + * QEMU seems to work around this returning EINTR... Let's do
Quoted 8 lines
tools/kvm/util.c size_t strlcat(char *dest, const char *src, size_t count) · line 122
Quoted 4 lines
tools/kvm/util.c +4
-0+* that too. +*/ + r =statfs (htlbfs_path, &sfs); + }while (r && errno ==EINTR );Can this really happen? What about EAGAIN? The retry logic really wants to live in
tools/kvm/read-write.cas axstatfs()wrapper if we do need this.
I don't think it can. As per the comment, I thought QEMU knew something I didn't but I haven't seen any other reason for doing this. I'll remove it, thanks for the sanity jolt.
Matt
Re: [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs
In reply to Matt EvansQuoted 5 lines · Matt Evans
Add a --hugetlbfs commandline option to give a path to hugetlbfs-map guest memory (down in
kvm__arch_init()). For x86, guest memory is a normal ANONmmap()if this option is not provided, otherwise a hugetlbfs mmap.Signed-off-by Matt Evans <[email protected]>
Btw, why don't you want to use MADV_HUGEPAGE for this? You could just do it unconditionally, no?
Re: [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs
Quoted 9 lines · Pekka Enberg
Quoted 5 lines · Matt Evans
Add a --hugetlbfs commandline option to give a path to hugetlbfs-map guest memory (down in
kvm__arch_init()). For x86, guest memory is a normal ANONmmap()if this option is not provided, otherwise a hugetlbfs mmap.Signed-off-by Matt Evans <[email protected]>Btw, why don't you want to use
MADV_HUGEPAGEfor this? You could just do it unconditionally, no?
Well, I'm manually mapping from hugetlbfs as currently* PPC KVM requires hugepages to back guest RAM and MADV_HUGEPAGE is just a hint, no? I also wanted things to work on kernels without transparent hugepages enabled. I think it's safer to do things explicitly, as if the user requests hugepages it's more transparent (I'm thinking benchmarking, etc.) to be definitely using hugepages.
Cheers,
Matt
*: I know Paul's posted patches to implement smallpage support... so this will
change in time.
Re: [PATCH V2 17/23] kvm tools: Add ability to map guest RAM from hugetlbfs
Quoted 5 lines · Matt Evans
Well, I'm manually mapping from hugetlbfs as currently* PPC KVM requires hugepages to back guest RAM and
MADV_HUGEPAGEis just a hint, no? I also wanted things to work on kernels without transparent hugepages enabled. I think it's safer to do things explicitly, as if the user requests hugepages it's more transparent (I'm thinking benchmarking, etc.) to be definitely using hugepages.
OK, makes sense. You should probably mention that in the changelog.
PATCH v2 18/23 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 v2 19/23 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 | 40 ++++++++++++++++++++++++++------------ tools/kvm/pci.c | 4 +- tools/kvm/virtio/pci.c | 41 +++++++++++++++++++++------------------ 6 files changed, 77 insertions(+), 57 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 +27 -13
@@ -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,14 +18,27 @@#define PCI_CONFIG_BUS_FORWARD 0xcfa#define PCI_IO_SIZE 0x100 -struct pci_config_address { -unsigned zeros :2 ;/* 1 .. 0 */ -unsigned register_number :6 ;/* 7 .. 2 */ -unsigned function_number :3 ;/* 10 .. 8 */ -unsigned device_number :5 ;/* 15 .. 11 */ -unsigned bus_number :8 ;/* 23 .. 16 */ -unsigned reserved :7 ;/* 30 .. 24 */ -unsigned enable_bit :1 ;/* 31 */ +union pci_config_address { +struct { +#if __BYTE_ORDER == __LITTLE_ENDIAN +unsigned zeros :2 ;/* 1 .. 0 */ +unsigned register_number :6 ;/* 7 .. 2 */ +unsigned function_number :3 ;/* 10 .. 8 */ +unsigned device_number :5 ;/* 15 .. 11 */ +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 +59,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 +70,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 +80,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
PATCH v2 20/23 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 v2 21/23 kvm tools: Add pci__config_{rd,wr}(), pci__find_dev()
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. Internally, the x86 IO port access uses these new config space interfaces.
--- tools/kvm/include/kvm/pci.h | 9 +++++- tools/kvm/pci.c | 63 ++++++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 27 deletions(-)
tools/kvm/include/kvm/pci.h +7 -2
@@ -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.
@@ -21,7 +23,7 @@union pci_config_address {struct {#if __BYTE_ORDER == __LITTLE_ENDIAN -unsigned zeros :2 ;/* 1 .. 0 */ +unsigned reg_offset :2 ;/* 1 .. 0 */ unsigned register_number :6 ;/* 7 .. 2 */ unsigned function_number :3 ;/* 10 .. 8 */ unsigned device_number :5 ;/* 15 .. 11 */
@@ -35,7 +37,7 @@ union pci_config_address { unsigned device_number : 5; /* 15 .. 11 */ unsigned function_number : 3; /* 10 .. 8 */ unsigned register_number : 6; /* 7 .. 2 */ - unsigned zeros : 2; /* 1 .. 0 */ + unsigned reg_offset : 2; /* 1 .. 0 */#endif };u32 w;
@@ -84,6 +86,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 +38 -25
108 lines not on this page · raw message
PATCH v2 22/23 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 v2 23/23 kvm tools: Create arch-specific kvm_cpu__emulate_{mm}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 synthesised by steering into windows in PCI bridges on other architectures.
This patch calls arch-specific kvm_cpu__emulate_io() and kvm_cpu__emulate_mmio() from the main runloop's IO and MMIO exit handlers. For x86, these directly call kvm__emulate_io() and kvm__emulate_mmio() but other architectures will perform some address munging before passing on the call.
--- tools/kvm/kvm-cpu.c | 34 +++++++++++++++--------------- tools/kvm/x86/include/kvm/kvm-cpu-arch.h | 17 ++++++++++++++- 2 files changed, 33 insertions(+), 18 deletions(-)
tools/kvm/kvm-cpu.c +17 -17
@@ -52,11 +52,11 @@ static void kvm_cpu__handle_coalesced_mmio(struct kvm_cpu *cpu)while (cpu->ring->first != cpu->ring->last) {struct kvm_coalesced_mmio *m; m = &cpu->ring->coalesced_mmio[cpu->ring->first]; -kvm__emulate_mmio (cpu->kvm, - m->phys_addr, - m->data, - m->len, -1 ); +kvm_cpu__emulate_mmio (cpu->kvm, + m->phys_addr, + m->data, + m->len, +1 ); cpu->ring->first = (cpu->ring->first +1 ) %KVM_COALESCED_MMIO_MAX ; } }
@@ -106,13 +106,13 @@ int kvm_cpu__start(struct kvm_cpu *cpu)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); + ret =kvm_cpu__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;
@@ -121,11 +121,11 @@ int kvm_cpu__start(struct kvm_cpu *cpu)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); + ret =kvm_cpu__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;
tools/kvm/x86/include/kvm/kvm-cpu-arch.h +16 -1
@@ -4,7 +4,8 @@/* Architecture-specific kvm_cpu definitions. */ #include <linux/kvm.h> /* for struct kvm_regs */ - +#include "kvm/kvm.h" /* for kvm__emulate_{mm}io() */ +#include <stdbool.h> #include <pthread.h> struct kvm ;
@@ -30,4 +31,18 @@ struct kvm_cpu { struct kvm_coalesced_mmio_ring *ring; }; +/* +* As these are such simple wrappers, let's have them in the header so they'll +* be cheaper to call: +*/ +static inline bool kvm_cpu__emulate_io (struct kvm *kvm,u16 port,void *data,int direction,int size,u32 count) +{ +return kvm__emulate_io (kvm, port, data, direction, size, count); +} + +static inline bool kvm_cpu__emulate_mmio (struct kvm *kvm,u64 phys_addr,u8 *data,u32 len,u8 is_write) +{ +return kvm_cpu__emulate_mmio (kvm, phys_addr, data, len, is_write); +} +#endif /* KVM__KVM_CPU_ARCH_H */
Re: [PATCH V2 23/23] kvm tools: Create arch-specific kvm_cpu__emulate_{mm}io()
Quoted 6 lines · Matt Evans
tools/kvm/x86/include/kvm/kvm-cpu-arch.h +2
-0@@ -30,4 +31,18 @@ struct kvm_cpu {struct kvm_coalesced_mmio_ring *ring; }; +/* +* As these are such simple wrappers, let's have them in the header so they'll
tools/kvm/x86/include/kvm/kvm-cpu-arch.h struct kvm_cpu { · line 45
Quoted 10 lines
tools/kvm/x86/include/kvm/kvm-cpu-arch.h +10
-0+* be cheaper to call: +*/ +static inline bool kvm_cpu__emulate_io (struct kvm *kvm,u16 port,void *data,int direction,int size,u32 count) +{ +return kvm__emulate_io (kvm, port, data, direction, size, count); +} + +static inline bool kvm_cpu__emulate_mmio (struct kvm *kvm,u64 phys_addr,u8 *data,u32 len,u8 is_write) +{ +return kvm_cpu__emulate_mmio (kvm, phys_addr, data, len, is_write);
This is probably wrong. kvm_cpu__emulate_mmio just calls itself over and over.
Quoted 3 lines
tools/kvm/x86/include/kvm/kvm-cpu-arch.h +2
-0+} +#endif /* KVM__KVM_CPU_ARCH_H */
Signature · 1 line
Sasha.
Re: [PATCH V2 23/23] kvm tools: Create arch-specific kvm_cpu__emulate_{mm}io()
Quoted 5 lines · Sasha Levin
Quoted 4 lines · Matt Evans
tools/kvm/x86/include/kvm/kvm-cpu-arch.h +0
-0@@ -30,4 +31,18 @@ struct kvm_cpu {struct kvm_coalesced_mmio_ring *ring; };
Quoted 15 lines
tools/kvm/x86/include/kvm/kvm-cpu-arch.h struct kvm_cpu { · line 45
Quoted 12 lines
tools/kvm/x86/include/kvm/kvm-cpu-arch.h +12
-0+/* +* As these are such simple wrappers, let's have them in the header so they'll +* be cheaper to call: +*/ +static inline bool kvm_cpu__emulate_io (struct kvm *kvm,u16 port,void *data,int direction,int size,u32 count) +{ +return kvm__emulate_io (kvm, port, data, direction, size, count); +} + +static inline bool kvm_cpu__emulate_mmio (struct kvm *kvm,u64 phys_addr,u8 *data,u32 len,u8 is_write) +{ +return kvm_cpu__emulate_mmio (kvm, phys_addr, data, len, is_write);This is probably wrong.
kvm_cpu__emulate_mmiojust calls itself over and over.
Urgh, not just probably -- C&P strikes again. Consider it fixed.
Thanks!
Matt