Re: [PATCH] Make S390x work in qemu-kvm
On 12/08/2009 05:35 PM, Alexander Graf wrote: We now have S390x KVM support in qemu upstream. Unfortunately it doesn't work in qemu-kvm, because that has its own main loop and slightly different calling conventions for the KVM helpers. So let's hack in some small compat ifdefs that make qemu-kvm work on S390x! diff --git a/hw/msix.c b/hw/msix.c index 6d598ee..b2c2857 100644 --- a/hw/msix.c +++ b/hw/msix.c @@ -11,6 +11,8 @@ * the COPYING file in the top-level directory. */ +#ifndef __s390x__ + This should be CONFIG_PCI or CONFIG_PCI_MSI. Also, better to hack it at the Makefile level. diff --git a/hw/msix.h b/hw/msix.h index a9f7993..643b3a1 100644 --- a/hw/msix.h +++ b/hw/msix.h @@ -4,6 +4,37 @@ #include qemu-common.h #include pci.h +#ifdef __s390x__ Ditto (minus Makefile). diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c index cc21ee6..ea74955 100644 --- a/hw/s390-virtio.c +++ b/hw/s390-virtio.c @@ -179,7 +179,9 @@ static void s390_init(ram_addr_t ram_size, exit(1); } +#ifdef KVM_UPSTREAM cpu_synchronize_state(env); +#endif env-psw.addr = KERN_IMAGE_START; env-psw.mask = 0x00018000UL; } @@ -236,6 +238,10 @@ static void s390_init(ram_addr_t ram_size, qdev_prop_set_drive(dev, drive, dinfo); qdev_init_nofail(dev); } + +#ifndef KVM_UPSTREAM +kvm_arch_load_regs(env); +#endif } Why isn't cpu_synchronize_state() suitable? static QEMUMachine s390_machine = { diff --git a/kvm-tpr-opt.c b/kvm-tpr-opt.c index 2565d79..e8c4185 100644 --- a/kvm-tpr-opt.c +++ b/kvm-tpr-opt.c @@ -6,6 +6,8 @@ * Licensed under the terms of the GNU GPL version 2 or higher. */ +#ifndef __s390x__ @Makefile. diff --git a/kvm/include/linux/kvm.h b/kvm/include/linux/kvm.h index db10887..2d241da 100644 --- a/kvm/include/linux/kvm.h +++ b/kvm/include/linux/kvm.h Please post kvm header changes as a separate patch. diff --git a/qemu-kvm-helper.c b/qemu-kvm-helper.c index 9420eb1..d5b75bd 100644 --- a/qemu-kvm-helper.c +++ b/qemu-kvm-helper.c @@ -30,7 +30,9 @@ void qemu_kvm_call_with_env(void (*func)(void *), void *data, CPUState *newenv) static void call_helper_cpuid(void *junk) { +#ifndef __s390x__ helper_cpuid(); +#endif } That just has to die (but not in your patches). It dates from the pre-tcg days. @@ -157,7 +157,7 @@ static void init_slots(void) static int get_free_slot(kvm_context_t kvm) { -int i; +int i = 0; int tss_ext; #if defined(KVM_CAP_SET_TSS_ADDR) !defined(__s390__) @@ -171,10 +171,12 @@ static int get_free_slot(kvm_context_t kvm) * slot 0 to hold the extended memory, as the vmx will use the last 3 * pages of this slot. */ +#ifndef __s390x__ if (tss_ext 0) i = 0; else i = 1; +#endif That should conditioned on x86, not s390. While you're at it, drop the i = 0 assignment please. for (; i KVM_MAX_NUM_MEM_REGIONS; ++i) if (!slots[i].len) @@ -450,6 +452,14 @@ static void kvm_create_vcpu(CPUState *env, int id) env-kvm_fd = r; env-kvm_state = kvm_state; +#ifdef __s390x__ +r = kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, 0); +if (r 0) { +fprintf(stderr, kvm_s390_initial_reset: %m\n); +exit(1); +} +#endif Isn't there an arch hook for this? TARGET_S390 or similar. switch (run-exit_reason) { case KVM_EXIT_UNKNOWN: @@ -981,14 +990,6 @@ int kvm_run(CPUState *env) case KVM_EXIT_SHUTDOWN: r = handle_shutdown(kvm, env); break; -#if defined(__s390__) -case KVM_EXIT_S390_SIEIC: -r = kvm_s390_handle_intercept(kvm, env, run); -break; -case KVM_EXIT_S390_RESET: -r = kvm_s390_handle_reset(kvm, env, run); -break; -#endif Ditto. +#ifdef __s390x__ +static +#endif Lovely. Why? int kvm_arch_init_vcpu(CPUState *env) { @@ -86,12 +88,27 @@ int kvm_arch_init_vcpu(CPUState *env) return ret; } +#ifdef KVM_UPSTREAM void kvm_arch_reset_vcpu(CPUState *env) +#else +void kvm_arch_cpu_reset(CPUState *env) +#endif :( index 000..9a6bcd6 --- /dev/null +++ b/target-s390x/libkvm.h @@ -0,0 +1,26 @@ +/* + * This header is for functions variables that will ONLY be + * used inside libkvm for x86. + * THESE ARE NOT EXPOSED TO THE USER AND ARE ONLY FOR USE + * WITHIN LIBKVM. + * + * derived from libkvm.c + * + * Copyright (C) 2006 Qumranet, Inc. + * + * Authors: + * Avi Kivitya...@qumranet.com + * Yaniv Kamayya...@qumranet.com + * + * This work is licensed under the GNU LGPL license, version 2. + */ + +#ifndef KVM_X86_H +#define KVM_X86_H + +#define PAGE_SIZE 4096ul +#define PAGE_MASK (~(PAGE_SIZE - 1)) + +#define smp_wmb() asm volatile( ::: memory) + +#endif I thought we no longer include libkvm.h! -- error compiling committee.c: too many arguments
Re: [PATCH] Make S390x work in qemu-kvm
Avi Kivity wrote: On 12/08/2009 05:35 PM, Alexander Graf wrote: We now have S390x KVM support in qemu upstream. Unfortunately it doesn't work in qemu-kvm, because that has its own main loop and slightly different calling conventions for the KVM helpers. So let's hack in some small compat ifdefs that make qemu-kvm work on S390x! diff --git a/hw/msix.c b/hw/msix.c index 6d598ee..b2c2857 100644 --- a/hw/msix.c +++ b/hw/msix.c @@ -11,6 +11,8 @@ * the COPYING file in the top-level directory. */ +#ifndef __s390x__ + This should be CONFIG_PCI or CONFIG_PCI_MSI. Also, better to hack it at the Makefile level. That's what I did at first in a hacky way. To be honest, the new makefile structure scares me a bit, so I'm not sure I'll easily figure out how to do that properly :). diff --git a/hw/msix.h b/hw/msix.h index a9f7993..643b3a1 100644 --- a/hw/msix.h +++ b/hw/msix.h @@ -4,6 +4,37 @@ #include qemu-common.h #include pci.h +#ifdef __s390x__ Ditto (minus Makefile). diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c index cc21ee6..ea74955 100644 --- a/hw/s390-virtio.c +++ b/hw/s390-virtio.c @@ -179,7 +179,9 @@ static void s390_init(ram_addr_t ram_size, exit(1); } +#ifdef KVM_UPSTREAM cpu_synchronize_state(env); +#endif env-psw.addr = KERN_IMAGE_START; env-psw.mask = 0x00018000UL; } @@ -236,6 +238,10 @@ static void s390_init(ram_addr_t ram_size, qdev_prop_set_drive(dev, drive, dinfo); qdev_init_nofail(dev); } + +#ifndef KVM_UPSTREAM +kvm_arch_load_regs(env); +#endif } Why isn't cpu_synchronize_state() suitable? Because the KVM fd's are not available yet. static QEMUMachine s390_machine = { diff --git a/kvm-tpr-opt.c b/kvm-tpr-opt.c index 2565d79..e8c4185 100644 --- a/kvm-tpr-opt.c +++ b/kvm-tpr-opt.c @@ -6,6 +6,8 @@ * Licensed under the terms of the GNU GPL version 2 or higher. */ +#ifndef __s390x__ @Makefile. diff --git a/kvm/include/linux/kvm.h b/kvm/include/linux/kvm.h index db10887..2d241da 100644 --- a/kvm/include/linux/kvm.h +++ b/kvm/include/linux/kvm.h Please post kvm header changes as a separate patch. Ok. diff --git a/qemu-kvm-helper.c b/qemu-kvm-helper.c index 9420eb1..d5b75bd 100644 --- a/qemu-kvm-helper.c +++ b/qemu-kvm-helper.c @@ -30,7 +30,9 @@ void qemu_kvm_call_with_env(void (*func)(void *), void *data, CPUState *newenv) static void call_helper_cpuid(void *junk) { +#ifndef __s390x__ helper_cpuid(); +#endif } That just has to die (but not in your patches). It dates from the pre-tcg days. Yep. IMHO all the code duplication should die :). @@ -157,7 +157,7 @@ static void init_slots(void) static int get_free_slot(kvm_context_t kvm) { -int i; +int i = 0; int tss_ext; #if defined(KVM_CAP_SET_TSS_ADDR) !defined(__s390__) @@ -171,10 +171,12 @@ static int get_free_slot(kvm_context_t kvm) * slot 0 to hold the extended memory, as the vmx will use the last 3 * pages of this slot. */ +#ifndef __s390x__ if (tss_ext 0) i = 0; else i = 1; +#endif That should conditioned on x86, not s390. While you're at it, drop the i = 0 assignment please. So it's useless for IA64 as well? for (; i KVM_MAX_NUM_MEM_REGIONS; ++i) if (!slots[i].len) @@ -450,6 +452,14 @@ static void kvm_create_vcpu(CPUState *env, int id) env-kvm_fd = r; env-kvm_state = kvm_state; +#ifdef __s390x__ +r = kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, 0); +if (r 0) { +fprintf(stderr, kvm_s390_initial_reset: %m\n); +exit(1); +} +#endif Isn't there an arch hook for this? TARGET_S390 or similar. Yes, there is. I figured this is just a temporary hack, so who cares :-). switch (run-exit_reason) { case KVM_EXIT_UNKNOWN: @@ -981,14 +990,6 @@ int kvm_run(CPUState *env) case KVM_EXIT_SHUTDOWN: r = handle_shutdown(kvm, env); break; -#if defined(__s390__) -case KVM_EXIT_S390_SIEIC: -r = kvm_s390_handle_intercept(kvm, env, run); -break; -case KVM_EXIT_S390_RESET: -r = kvm_s390_handle_reset(kvm, env, run); -break; -#endif Ditto. Ditto what? This is code removal. +#ifdef __s390x__ +static +#endif Lovely. Why? Because it collided with the init function provided by target-s390x/kvm.c. int kvm_arch_init_vcpu(CPUState *env) { @@ -86,12 +88,27 @@ int kvm_arch_init_vcpu(CPUState *env) return ret; } +#ifdef KVM_UPSTREAM void kvm_arch_reset_vcpu(CPUState *env) +#else +void kvm_arch_cpu_reset(CPUState *env) +#endif :( Yeah, feel like getting the naming a bit closer? :) index 000..9a6bcd6 --- /dev/null +++ b/target-s390x/libkvm.h
Re: [PATCH] Make S390x work in qemu-kvm
On 12/15/2009 01:13 PM, Alexander Graf wrote: This should be CONFIG_PCI or CONFIG_PCI_MSI. Also, better to hack it at the Makefile level. That's what I did at first in a hacky way. To be honest, the new makefile structure scares me a bit, so I'm not sure I'll easily figure out how to do that properly :). I'm sure Juan will be glad to help. + +#ifndef KVM_UPSTREAM +kvm_arch_load_regs(env); +#endif } Why isn't cpu_synchronize_state() suitable? Because the KVM fd's are not available yet. Then kvm_arch_load_regs() will fail as well, no? static int get_free_slot(kvm_context_t kvm) { -int i; +int i = 0; int tss_ext; #if defined(KVM_CAP_SET_TSS_ADDR) !defined(__s390__) @@ -171,10 +171,12 @@ static int get_free_slot(kvm_context_t kvm) * slot 0 to hold the extended memory, as the vmx will use the last 3 * pages of this slot. */ +#ifndef __s390x__ if (tss_ext 0) i = 0; else i = 1; +#endif That should conditioned on x86, not s390. While you're at it, drop the i = 0 assignment please. So it's useless for IA64 as well? Yes. for (; i KVM_MAX_NUM_MEM_REGIONS; ++i) if (!slots[i].len) @@ -450,6 +452,14 @@ static void kvm_create_vcpu(CPUState *env, int id) env-kvm_fd = r; env-kvm_state = kvm_state; +#ifdef __s390x__ +r = kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, 0); +if (r 0) { +fprintf(stderr, kvm_s390_initial_reset: %m\n); +exit(1); +} +#endif Isn't there an arch hook for this? TARGET_S390 or similar. Yes, there is. I figured this is just a temporary hack, so who cares :-). The whole of qemu-kvm.c is a temporary hack. No reason to make it uglier than it needs to be. break; -#if defined(__s390__) -case KVM_EXIT_S390_SIEIC: -r = kvm_s390_handle_intercept(kvm, env, run); -break; -case KVM_EXIT_S390_RESET: -r = kvm_s390_handle_reset(kvm, env, run); -break; -#endif Ditto. Ditto what? This is code removal. Um, yes. +#ifdef __s390x__ +static +#endif Lovely. Why? Because it collided with the init function provided by target-s390x/kvm.c. I'd prefer a separate rename then. int kvm_arch_init_vcpu(CPUState *env) { @@ -86,12 +88,27 @@ int kvm_arch_init_vcpu(CPUState *env) return ret; } +#ifdef KVM_UPSTREAM void kvm_arch_reset_vcpu(CPUState *env) +#else +void kvm_arch_cpu_reset(CPUState *env) +#endif :( Yeah, feel like getting the naming a bit closer? :) A renaming patch would be welcome. I thought we no longer include libkvm.h! Some file failed to build without it. IIRC because PAGE_* was not defined. There's a TARGET_PAGE_SIZE or something, we can use that instead. -- error compiling committee.c: too many arguments to function -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Make S390x work in qemu-kvm
Avi Kivity wrote: On 12/15/2009 01:13 PM, Alexander Graf wrote: This should be CONFIG_PCI or CONFIG_PCI_MSI. Also, better to hack it at the Makefile level. That's what I did at first in a hacky way. To be honest, the new makefile structure scares me a bit, so I'm not sure I'll easily figure out how to do that properly :). I'm sure Juan will be glad to help. + +#ifndef KVM_UPSTREAM +kvm_arch_load_regs(env); +#endif } Why isn't cpu_synchronize_state() suitable? Because the KVM fd's are not available yet. Then kvm_arch_load_regs() will fail as well, no? Eeeh - there was a reason this didn't fail :-). I don't remember. static int get_free_slot(kvm_context_t kvm) { -int i; +int i = 0; int tss_ext; #if defined(KVM_CAP_SET_TSS_ADDR) !defined(__s390__) @@ -171,10 +171,12 @@ static int get_free_slot(kvm_context_t kvm) * slot 0 to hold the extended memory, as the vmx will use the last 3 * pages of this slot. */ +#ifndef __s390x__ if (tss_ext 0) i = 0; else i = 1; +#endif That should conditioned on x86, not s390. While you're at it, drop the i = 0 assignment please. So it's useless for IA64 as well? Yes. for (; i KVM_MAX_NUM_MEM_REGIONS; ++i) if (!slots[i].len) @@ -450,6 +452,14 @@ static void kvm_create_vcpu(CPUState *env, int id) env-kvm_fd = r; env-kvm_state = kvm_state; +#ifdef __s390x__ +r = kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, 0); +if (r 0) { +fprintf(stderr, kvm_s390_initial_reset: %m\n); +exit(1); +} +#endif Isn't there an arch hook for this? TARGET_S390 or similar. Yes, there is. I figured this is just a temporary hack, so who cares :-). The whole of qemu-kvm.c is a temporary hack. No reason to make it uglier than it needs to be. break; -#if defined(__s390__) -case KVM_EXIT_S390_SIEIC: -r = kvm_s390_handle_intercept(kvm, env, run); -break; -case KVM_EXIT_S390_RESET: -r = kvm_s390_handle_reset(kvm, env, run); -break; -#endif Ditto. Ditto what? This is code removal. Um, yes. +#ifdef __s390x__ +static +#endif Lovely. Why? Because it collided with the init function provided by target-s390x/kvm.c. I'd prefer a separate rename then. Rename in kvm.c? int kvm_arch_init_vcpu(CPUState *env) { @@ -86,12 +88,27 @@ int kvm_arch_init_vcpu(CPUState *env) return ret; } +#ifdef KVM_UPSTREAM void kvm_arch_reset_vcpu(CPUState *env) +#else +void kvm_arch_cpu_reset(CPUState *env) +#endif :( Yeah, feel like getting the naming a bit closer? :) A renaming patch would be welcome. I thought we no longer include libkvm.h! Some file failed to build without it. IIRC because PAGE_* was not defined. There's a TARGET_PAGE_SIZE or something, we can use that instead. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Make S390x work in qemu-kvm
On 12/15/2009 03:03 PM, Alexander Graf wrote: Why isn't cpu_synchronize_state() suitable? Because the KVM fd's are not available yet. Then kvm_arch_load_regs() will fail as well, no? Eeeh - there was a reason this didn't fail :-). I don't remember. Please find out. Because it collided with the init function provided by target-s390x/kvm.c. I'd prefer a separate rename then. Rename in kvm.c? kvm.c is harder to coordinate (need to rename in upstream), so rename the qemu-kvm specific function. -- error compiling committee.c: too many arguments to function -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Make S390x work in qemu-kvm
We now have S390x KVM support in qemu upstream. Unfortunately it doesn't work in qemu-kvm, because that has its own main loop and slightly different calling conventions for the KVM helpers. So let's hack in some small compat ifdefs that make qemu-kvm work on S390x! Signed-off-by: Alexander Graf ag...@suse.de --- configure |4 ++ hw/msix.c |4 ++ hw/msix.h | 33 + hw/s390-virtio.c |6 +++ kvm-tpr-opt.c |3 + kvm/include/linux/kvm.h| 10 +++- kvm/include/s390/asm/kvm.h | 44 ++ qemu-kvm-helper.c |2 + qemu-kvm.c | 32 - qemu-kvm.h |8 --- target-s390x/kvm.c | 108 target-s390x/libkvm.h | 26 +++ 12 files changed, 256 insertions(+), 24 deletions(-) create mode 100644 kvm/include/s390/asm/kvm.h create mode 100644 target-s390x/libkvm.h diff --git a/configure b/configure index e804a92..b6381ae 100755 --- a/configure +++ b/configure @@ -188,6 +188,7 @@ case $cpu in ;; s390x) cpu=s390x +target_list=s390x-softmmu ;; sparc|sun4[cdmuv]) cpu=sparc @@ -1430,6 +1431,9 @@ EOF ppc) kvm_arch=powerpc ;; + s390x) +kvm_arch=s390 +;; *) kvm_arch=$cpu ;; diff --git a/hw/msix.c b/hw/msix.c index 6d598ee..b2c2857 100644 --- a/hw/msix.c +++ b/hw/msix.c @@ -11,6 +11,8 @@ * the COPYING file in the top-level directory. */ +#ifndef __s390x__ + #include hw.h #include msix.h #include pci.h @@ -559,3 +561,5 @@ void msix_unuse_all_vectors(PCIDevice *dev) return; msix_free_irq_entries(dev); } + +#endif diff --git a/hw/msix.h b/hw/msix.h index a9f7993..643b3a1 100644 --- a/hw/msix.h +++ b/hw/msix.h @@ -4,6 +4,37 @@ #include qemu-common.h #include pci.h +#ifdef __s390x__ + +static int msix_init(PCIDevice *pdev, unsigned short nentries, + unsigned bar_nr, unsigned bar_size) { return 0; } + +static void msix_write_config(PCIDevice *pci_dev, uint32_t address, + uint32_t val, int len) { } + +static void msix_mmio_map(PCIDevice *pci_dev, int region_num, + pcibus_t addr, pcibus_t size, int type) { } + +static int msix_uninit(PCIDevice *d) { return 0; } + +static void msix_save(PCIDevice *dev, QEMUFile *f) { } +static void msix_load(PCIDevice *dev, QEMUFile *f) { } + +static int msix_enabled(PCIDevice *dev) { return 0; } +static int msix_present(PCIDevice *dev) { return 0; } + +static uint32_t msix_bar_size(PCIDevice *dev) { return 0; } + +static int msix_vector_use(PCIDevice *dev, unsigned vector) { return 0; } +static void msix_vector_unuse(PCIDevice *dev, unsigned vector) { } +static void msix_unuse_all_vectors(PCIDevice *dev) { } + +static void msix_notify(PCIDevice *dev, unsigned vector) { } + +static void msix_reset(PCIDevice *dev) { } + +#else + int msix_init(PCIDevice *pdev, unsigned short nentries, unsigned bar_nr, unsigned bar_size); @@ -34,3 +65,5 @@ void msix_reset(PCIDevice *dev); extern int msix_supported; #endif + +#endif diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c index cc21ee6..ea74955 100644 --- a/hw/s390-virtio.c +++ b/hw/s390-virtio.c @@ -179,7 +179,9 @@ static void s390_init(ram_addr_t ram_size, exit(1); } +#ifdef KVM_UPSTREAM cpu_synchronize_state(env); +#endif env-psw.addr = KERN_IMAGE_START; env-psw.mask = 0x00018000UL; } @@ -236,6 +238,10 @@ static void s390_init(ram_addr_t ram_size, qdev_prop_set_drive(dev, drive, dinfo); qdev_init_nofail(dev); } + +#ifndef KVM_UPSTREAM +kvm_arch_load_regs(env); +#endif } static QEMUMachine s390_machine = { diff --git a/kvm-tpr-opt.c b/kvm-tpr-opt.c index 2565d79..e8c4185 100644 --- a/kvm-tpr-opt.c +++ b/kvm-tpr-opt.c @@ -6,6 +6,8 @@ * Licensed under the terms of the GNU GPL version 2 or higher. */ +#ifndef __s390x__ + #include config.h #include config-host.h @@ -401,3 +403,4 @@ void kvm_tpr_opt_setup(void) register_ioport_write(0x7e, 2, 2, vtpr_ioport_write16, NULL); } +#endif diff --git a/kvm/include/linux/kvm.h b/kvm/include/linux/kvm.h index db10887..2d241da 100644 --- a/kvm/include/linux/kvm.h +++ b/kvm/include/linux/kvm.h @@ -181,6 +181,11 @@ struct kvm_run { __u64 cr8; __u64 apic_base; +#ifdef __KVM_S390 + /* the processor status word for s390 */ + __u64 psw_mask; /* psw upper half */ + __u64 psw_addr; /* psw lower half */ +#endif union { /* KVM_EXIT_UNKNOWN */ struct { @@ -232,8 +237,6 @@ struct kvm_run { /* KVM_EXIT_S390_SIEIC */ struct { __u8 icptcode; - __u64 mask; /* psw upper half */ - __u64 addr; /* psw lower half */