diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-07-14 14:19:35 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-07-14 14:19:35 +0100 |
commit | fbc8ea1ed0704b0cd393e5dc429816a36cb5ed05 (patch) | |
tree | 889e3e593b0feb364012d94350b43a130b832d32 /hw/intc/s390_flic_kvm.c | |
parent | 6c6076662d98c068059983d411cb2a8987ba5670 (diff) | |
parent | 86158a2a2b81f075c84d0b95c6d72b98dbf1dc61 (diff) |
Merge remote-tracking branch 'remotes/borntraeger/tags/s390x-20170714' into staging
s390x/kvm/migration/cpumodel: fixes, enhancements and cleanups
- add a network boot rom for s390 (Thomas Huth)
- migration of storage attributes like the CMMA used/unused state
- PCI related enhancements - full support for aen, ais and zpci
- migration support for css with vmstates (Halil Pasic)
- cpu model enhancements for cpu features
- guarded storage support
# gpg: Signature made Fri 14 Jul 2017 11:33:04 BST
# gpg: using RSA key 0x117BBC80B5A61C7C
# gpg: Good signature from "Christian Borntraeger (IBM) <borntraeger@de.ibm.com>"
# Primary key fingerprint: F922 9381 A334 08F9 DBAB FBCA 117B BC80 B5A6 1C7C
* remotes/borntraeger/tags/s390x-20170714: (40 commits)
s390x/gdb: add gs registers
s390x/arch_dump: also dump guarded storage control block
s390x/kvm: enable guarded storage
s390x/kvm: Enable KSS facility for nested virtualization
s390x/cpumodel: add esop/esop2 to z12 model
s390x/cpumodel: we are always in zarchitecture mode
s390x/cpumodel: wire up new hardware features
s390x/flic: migrate ais states
s390x/cpumodel: add zpci, aen and ais facilities
s390x: initialize cpu firstly
pc-bios/s390: rebuild s390-ccw.img
pc-bios/s390: add s390-netboot.img
pc-bios/s390-ccw: Link libnet into the netboot image and do the TFTP load
pc-bios/s390-ccw: Add virtio-net driver code
pc-bios/s390-ccw: Add core files for the network bootloading program
roms/SLOF: Update submodule to latest status
pc-bios/s390-ccw: Add code for virtio feature negotiation
pc-bios/s390-ccw: Remove unused structs from virtio.h
pc-bios/s390-ccw: Move byteswap functions to a separate header
pc-bios/s390-ccw: Add a write() function for stdio
...
Conflicts:
target/s390x/kvm.c
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc/s390_flic_kvm.c')
-rw-r--r-- | hw/intc/s390_flic_kvm.c | 137 |
1 files changed, 135 insertions, 2 deletions
diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c index 0bcd49f08b..be3fd00a57 100644 --- a/hw/intc/s390_flic_kvm.c +++ b/hw/intc/s390_flic_kvm.c @@ -20,6 +20,7 @@ #include "sysemu/kvm.h" #include "hw/s390x/s390_flic.h" #include "hw/s390x/adapter.h" +#include "hw/s390x/css.h" #include "trace.h" #define FLIC_SAVE_INITIAL_SIZE getpagesize() @@ -149,6 +150,43 @@ static int kvm_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id, return rc ? -errno : 0; } +static int kvm_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc, + uint16_t mode) +{ + KVMS390FLICState *flic = KVM_S390_FLIC(fs); + struct kvm_s390_ais_req req = { + .isc = isc, + .mode = mode, + }; + struct kvm_device_attr attr = { + .group = KVM_DEV_FLIC_AISM, + .addr = (uint64_t)&req, + }; + + if (!fs->ais_supported) { + return -ENOSYS; + } + + return ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr) ? -errno : 0; +} + +static int kvm_s390_inject_airq(S390FLICState *fs, uint8_t type, + uint8_t isc, uint8_t flags) +{ + KVMS390FLICState *flic = KVM_S390_FLIC(fs); + uint32_t id = css_get_adapter_id(type, isc); + struct kvm_device_attr attr = { + .group = KVM_DEV_FLIC_AIRQ_INJECT, + .attr = id, + }; + + if (!fs->ais_supported) { + return -ENOSYS; + } + + return ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr) ? -errno : 0; +} + /** * __get_all_irqs - store all pending irqs in buffer * @flic: pointer to flic device state @@ -186,13 +224,14 @@ static int __get_all_irqs(KVMS390FLICState *flic, static int kvm_s390_register_io_adapter(S390FLICState *fs, uint32_t id, uint8_t isc, bool swap, - bool is_maskable) + bool is_maskable, uint8_t flags) { struct kvm_s390_io_adapter adapter = { .id = id, .isc = isc, .maskable = is_maskable, .swap = swap, + .flags = flags, }; KVMS390FLICState *flic = KVM_S390_FLIC(fs); int r; @@ -374,7 +413,84 @@ out: return r; } +typedef struct KVMS390FLICStateMigTmp { + KVMS390FLICState *parent; + uint8_t simm; + uint8_t nimm; +} KVMS390FLICStateMigTmp; + +static void kvm_flic_ais_pre_save(void *opaque) +{ + KVMS390FLICStateMigTmp *tmp = opaque; + KVMS390FLICState *flic = tmp->parent; + struct kvm_s390_ais_all ais; + struct kvm_device_attr attr = { + .group = KVM_DEV_FLIC_AISM_ALL, + .addr = (uint64_t)&ais, + .attr = sizeof(ais), + }; + + if (ioctl(flic->fd, KVM_GET_DEVICE_ATTR, &attr)) { + error_report("Failed to retrieve kvm flic ais states"); + return; + } + + tmp->simm = ais.simm; + tmp->nimm = ais.nimm; +} + +static int kvm_flic_ais_post_load(void *opaque, int version_id) +{ + KVMS390FLICStateMigTmp *tmp = opaque; + KVMS390FLICState *flic = tmp->parent; + struct kvm_s390_ais_all ais = { + .simm = tmp->simm, + .nimm = tmp->nimm, + }; + struct kvm_device_attr attr = { + .group = KVM_DEV_FLIC_AISM_ALL, + .addr = (uint64_t)&ais, + }; + + /* This can happen when the user mis-configures its guests in an + * incompatible fashion or without a CPU model. For example using + * qemu with -cpu host (which is not migration safe) and do a + * migration from a host that has AIS to a host that has no AIS. + * In that case the target system will reject the migration here. + */ + if (!ais_needed(flic)) { + return -ENOSYS; + } + + return ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr) ? -errno : 0; +} + +static const VMStateDescription kvm_s390_flic_ais_tmp = { + .name = "s390-flic-ais-tmp", + .pre_save = kvm_flic_ais_pre_save, + .post_load = kvm_flic_ais_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT8(simm, KVMS390FLICStateMigTmp), + VMSTATE_UINT8(nimm, KVMS390FLICStateMigTmp), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription kvm_s390_flic_vmstate_ais = { + .name = "s390-flic/ais", + .version_id = 1, + .minimum_version_id = 1, + .needed = ais_needed, + .fields = (VMStateField[]) { + VMSTATE_WITH_TMP(KVMS390FLICState, KVMS390FLICStateMigTmp, + kvm_s390_flic_ais_tmp), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription kvm_s390_flic_vmstate = { + /* should have been like kvm-s390-flic, + * can't change without breaking compat */ .name = "s390-flic", .version_id = FLIC_SAVEVM_VERSION, .minimum_version_id = FLIC_SAVEVM_VERSION, @@ -389,6 +505,10 @@ static const VMStateDescription kvm_s390_flic_vmstate = { .flags = VMS_SINGLE, }, VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription * []) { + &kvm_s390_flic_vmstate_ais, + NULL } }; @@ -436,7 +556,6 @@ static void kvm_s390_flic_realize(DeviceState *dev, Error **errp) test_attr.group = KVM_DEV_FLIC_CLEAR_IO_IRQ; flic_state->clear_io_supported = !ioctl(flic_state->fd, KVM_HAS_DEVICE_ATTR, test_attr); - return; fail: error_propagate(errp, errp_local); @@ -445,10 +564,12 @@ fail: static void kvm_s390_flic_reset(DeviceState *dev) { KVMS390FLICState *flic = KVM_S390_FLIC(dev); + S390FLICState *fs = S390_FLIC_COMMON(dev); struct kvm_device_attr attr = { .group = KVM_DEV_FLIC_CLEAR_IRQS, }; int rc = 0; + uint8_t isc; if (flic->fd == -1) { return; @@ -456,6 +577,16 @@ static void kvm_s390_flic_reset(DeviceState *dev) flic_disable_wait_pfault(flic); + if (fs->ais_supported) { + for (isc = 0; isc <= MAX_ISC; isc++) { + rc = kvm_s390_modify_ais_mode(fs, isc, SIC_IRQ_MODE_ALL); + if (rc) { + error_report("Failed to reset ais mode for isc %d: %s", + isc, strerror(-rc)); + } + } + } + rc = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr); if (rc) { trace_flic_reset_failed(errno); @@ -478,6 +609,8 @@ static void kvm_s390_flic_class_init(ObjectClass *oc, void *data) fsc->add_adapter_routes = kvm_s390_add_adapter_routes; fsc->release_adapter_routes = kvm_s390_release_adapter_routes; fsc->clear_io_irq = kvm_s390_clear_io_flic; + fsc->modify_ais_mode = kvm_s390_modify_ais_mode; + fsc->inject_airq = kvm_s390_inject_airq; } static const TypeInfo kvm_s390_flic_info = { |