diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h index cb4c1eb8a0a5097c1524b1ec037be283cb923fca..c003c6a73b1e3e883b814aff03704a43c3c0d9a4 100644 --- a/linux-headers/asm-s390/kvm.h +++ b/linux-headers/asm-s390/kvm.h @@ -22,6 +22,8 @@ #define KVM_DEV_FLIC_CLEAR_IRQS 3 #define KVM_DEV_FLIC_APF_ENABLE 4 #define KVM_DEV_FLIC_APF_DISABLE_WAIT 5 +#define KVM_DEV_FLIC_ADAPTER_REGISTER 6 +#define KVM_DEV_FLIC_ADAPTER_MODIFY 7 /* * We can have up to 4*64k pending subchannels + 8 adapter interrupts, * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. @@ -32,6 +34,26 @@ #define KVM_S390_MAX_FLOAT_IRQS 266250 #define KVM_S390_FLIC_MAX_BUFFER 0x2000000 +struct kvm_s390_io_adapter { + __u32 id; + __u8 isc; + __u8 maskable; + __u8 swap; + __u8 pad; +}; + +#define KVM_S390_IO_ADAPTER_MASK 1 +#define KVM_S390_IO_ADAPTER_MAP 2 +#define KVM_S390_IO_ADAPTER_UNMAP 3 + +struct kvm_s390_io_adapter_req { + __u32 id; + __u8 type; + __u8 mask; + __u16 pad0; + __u64 addr; +}; + /* for KVM_GET_REGS and KVM_SET_REGS */ struct kvm_regs { /* general purpose regs for s390 */ @@ -76,4 +98,6 @@ struct kvm_sync_regs { #define KVM_REG_S390_PFTOKEN (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x5) #define KVM_REG_S390_PFCOMPARE (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x6) #define KVM_REG_S390_PFSELECT (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x7) +#define KVM_REG_S390_PP (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x8) +#define KVM_REG_S390_GBEA (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x9) #endif diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index e27a4b33cfacd27fc4ea4d98ca8ed70a5352df95..b278ab33269fc8baedd00cfd819cfdda91218dc6 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -740,6 +740,9 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_SPAPR_MULTITCE 94 #define KVM_CAP_EXT_EMUL_CPUID 95 #define KVM_CAP_HYPERV_TIME 96 +#define KVM_CAP_IOAPIC_POLARITY_IGNORED 97 +#define KVM_CAP_ENABLE_CAP_VM 98 +#define KVM_CAP_S390_IRQCHIP 99 #ifdef KVM_CAP_IRQ_ROUTING @@ -755,9 +758,18 @@ struct kvm_irq_routing_msi { __u32 pad; }; +struct kvm_irq_routing_s390_adapter { + __u64 ind_addr; + __u64 summary_addr; + __u64 ind_offset; + __u32 summary_offset; + __u32 adapter_id; +}; + /* gsi routing entry types */ #define KVM_IRQ_ROUTING_IRQCHIP 1 #define KVM_IRQ_ROUTING_MSI 2 +#define KVM_IRQ_ROUTING_S390_ADAPTER 3 struct kvm_irq_routing_entry { __u32 gsi; @@ -767,6 +779,7 @@ struct kvm_irq_routing_entry { union { struct kvm_irq_routing_irqchip irqchip; struct kvm_irq_routing_msi msi; + struct kvm_irq_routing_s390_adapter adapter; __u32 pad[8]; } u; }; @@ -1075,6 +1088,10 @@ struct kvm_s390_ucas_mapping { /* Available with KVM_CAP_DEBUGREGS */ #define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) +/* + * vcpu version available with KVM_ENABLE_CAP + * vm version available with KVM_CAP_ENABLE_CAP_VM + */ #define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) /* Available with KVM_CAP_XSAVE */ #define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave) diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h index 17c58e0ede4207855e6b9c1acd30a7fbdda2241a..26c218e6920e1c001f5b2041676804a02d39fceb 100644 --- a/linux-headers/linux/vfio.h +++ b/linux-headers/linux/vfio.h @@ -23,6 +23,12 @@ #define VFIO_TYPE1_IOMMU 1 #define VFIO_SPAPR_TCE_IOMMU 2 +#define VFIO_TYPE1v2_IOMMU 3 +/* + * IOMMU enforces DMA cache coherence (ex. PCIe NoSnoop stripping). This + * capability is subject to change as groups are added or removed. + */ +#define VFIO_DMA_CC_IOMMU 4 /* * The IOCTL interface is designed for extensibility by embedding the diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index f332d41b9443dbf1239f91ad226281a4813d9586..41903a93fbbeaaf547f410a0ec64dda7db712df5 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -126,6 +126,9 @@ typedef struct CPUS390XState { uint64_t pfault_compare; uint64_t pfault_select; + uint64_t gbea; + uint64_t pp; + CPU_COMMON /* reset does memset(0) up to here */ diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 56b9af75054e15385d9a4618433f57c968a67a7b..a30d1bc060050bd6134c96bb9e76feeed21694e3 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -36,6 +36,7 @@ #include "sysemu/device_tree.h" #include "qapi/qmp/qjson.h" #include "monitor/monitor.h" +#include "trace.h" /* #define DEBUG_KVM */ @@ -128,14 +129,42 @@ void kvm_arch_reset_vcpu(CPUState *cpu) } } +static int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source) +{ + struct kvm_one_reg reg; + int r; + + reg.id = id; + reg.addr = (uint64_t) source; + r = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (r) { + trace_kvm_failed_reg_set(id, strerror(errno)); + } + return r; +} + +static int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target) +{ + struct kvm_one_reg reg; + int r; + + reg.id = id; + reg.addr = (uint64_t) target; + r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + if (r) { + trace_kvm_failed_reg_get(id, strerror(errno)); + } + return r; +} + + int kvm_arch_put_registers(CPUState *cs, int level) { S390CPU *cpu = S390_CPU(cs); CPUS390XState *env = &cpu->env; - struct kvm_one_reg reg; struct kvm_sregs sregs; struct kvm_regs regs; - int ret; + int r; int i; /* always save the PSW and the GPRS*/ @@ -151,9 +180,9 @@ int kvm_arch_put_registers(CPUState *cs, int level) for (i = 0; i < 16; i++) { regs.gprs[i] = env->regs[i]; } - ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); - if (ret < 0) { - return ret; + r = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); + if (r < 0) { + return r; } } @@ -162,47 +191,29 @@ int kvm_arch_put_registers(CPUState *cs, int level) return 0; } - reg.id = KVM_REG_S390_CPU_TIMER; - reg.addr = (__u64)&(env->cputm); - ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); - if (ret < 0) { - return ret; - } - - reg.id = KVM_REG_S390_CLOCK_COMP; - reg.addr = (__u64)&(env->ckc); - ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); - if (ret < 0) { - return ret; - } - - reg.id = KVM_REG_S390_TODPR; - reg.addr = (__u64)&(env->todpr); - ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); - if (ret < 0) { - return ret; - } + /* + * These ONE_REGS are not protected by a capability. As they are only + * necessary for migration we just trace a possible error, but don't + * return with an error return code. + */ + kvm_set_one_reg(cs, KVM_REG_S390_CPU_TIMER, &env->cputm); + kvm_set_one_reg(cs, KVM_REG_S390_CLOCK_COMP, &env->ckc); + kvm_set_one_reg(cs, KVM_REG_S390_TODPR, &env->todpr); + kvm_set_one_reg(cs, KVM_REG_S390_GBEA, &env->gbea); + kvm_set_one_reg(cs, KVM_REG_S390_PP, &env->pp); if (cap_async_pf) { - reg.id = KVM_REG_S390_PFTOKEN; - reg.addr = (__u64)&(env->pfault_token); - ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); - if (ret < 0) { - return ret; + r = kvm_set_one_reg(cs, KVM_REG_S390_PFTOKEN, &env->pfault_token); + if (r < 0) { + return r; } - - reg.id = KVM_REG_S390_PFCOMPARE; - reg.addr = (__u64)&(env->pfault_compare); - ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); - if (ret < 0) { - return ret; + r = kvm_set_one_reg(cs, KVM_REG_S390_PFCOMPARE, &env->pfault_compare); + if (r < 0) { + return r; } - - reg.id = KVM_REG_S390_PFSELECT; - reg.addr = (__u64)&(env->pfault_select); - ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); - if (ret < 0) { - return ret; + r = kvm_set_one_reg(cs, KVM_REG_S390_PFSELECT, &env->pfault_select); + if (r < 0) { + return r; } } @@ -220,9 +231,9 @@ int kvm_arch_put_registers(CPUState *cs, int level) sregs.acrs[i] = env->aregs[i]; sregs.crs[i] = env->cregs[i]; } - ret = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs); - if (ret < 0) { - return ret; + r = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs); + if (r < 0) { + return r; } } @@ -240,7 +251,6 @@ int kvm_arch_get_registers(CPUState *cs) { S390CPU *cpu = S390_CPU(cs); CPUS390XState *env = &cpu->env; - struct kvm_one_reg reg; struct kvm_sregs sregs; struct kvm_regs regs; int i, r; @@ -288,46 +298,27 @@ int kvm_arch_get_registers(CPUState *cs) env->psa = cs->kvm_run->s.regs.prefix; } - /* One Regs */ - reg.id = KVM_REG_S390_CPU_TIMER; - reg.addr = (__u64)&(env->cputm); - r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); - if (r < 0) { - return r; - } - - reg.id = KVM_REG_S390_CLOCK_COMP; - reg.addr = (__u64)&(env->ckc); - r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); - if (r < 0) { - return r; - } - - reg.id = KVM_REG_S390_TODPR; - reg.addr = (__u64)&(env->todpr); - r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); - if (r < 0) { - return r; - } + /* + * These ONE_REGS are not protected by a capability. As they are only + * necessary for migration we just trace a possible error, but don't + * return with an error return code. + */ + kvm_get_one_reg(cs, KVM_REG_S390_CPU_TIMER, &env->cputm); + kvm_get_one_reg(cs, KVM_REG_S390_CLOCK_COMP, &env->ckc); + kvm_get_one_reg(cs, KVM_REG_S390_TODPR, &env->todpr); + kvm_get_one_reg(cs, KVM_REG_S390_GBEA, &env->gbea); + kvm_get_one_reg(cs, KVM_REG_S390_PP, &env->pp); if (cap_async_pf) { - reg.id = KVM_REG_S390_PFTOKEN; - reg.addr = (__u64)&(env->pfault_token); - r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + r = kvm_get_one_reg(cs, KVM_REG_S390_PFTOKEN, &env->pfault_token); if (r < 0) { return r; } - - reg.id = KVM_REG_S390_PFCOMPARE; - reg.addr = (__u64)&(env->pfault_compare); - r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + r = kvm_get_one_reg(cs, KVM_REG_S390_PFCOMPARE, &env->pfault_compare); if (r < 0) { return r; } - - reg.id = KVM_REG_S390_PFSELECT; - reg.addr = (__u64)&(env->pfault_select); - r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + r = kvm_get_one_reg(cs, KVM_REG_S390_PFSELECT, &env->pfault_select); if (r < 0) { return r; } @@ -383,6 +374,26 @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) return 0; } +int kvm_arch_insert_hw_breakpoint(target_ulong addr, + target_ulong len, int type) +{ + return -ENOSYS; +} + +int kvm_arch_remove_hw_breakpoint(target_ulong addr, + target_ulong len, int type) +{ + return -ENOSYS; +} + +void kvm_arch_remove_all_hw_breakpoints(void) +{ +} + +void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) +{ +} + void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run) { } @@ -844,6 +855,11 @@ static int handle_tsch(S390CPU *cpu) return ret; } +static int kvm_arch_handle_debug_exit(S390CPU *cpu) +{ + return -ENOSYS; +} + int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { S390CPU *cpu = S390_CPU(cs); @@ -859,6 +875,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) case KVM_EXIT_S390_TSCH: ret = handle_tsch(cpu); break; + case KVM_EXIT_DEBUG: + ret = kvm_arch_handle_debug_exit(cpu); + break; default: fprintf(stderr, "Unknown KVM exit: %d\n", run->exit_reason); break; diff --git a/trace-events b/trace-events index 6ecaab2f274b6d0eedcd7d021598d9ea01289853..a5218ba3938289272008d6f09bc795e944587bcd 100644 --- a/trace-events +++ b/trace-events @@ -1243,3 +1243,7 @@ xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (ad # hw/pci/pci_host.c pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x -> 0x%x" pci_cfg_write(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x <- 0x%x" + +# target-s390/kvm.c +kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s" +kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s"