diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-05-14 18:53:42 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-05-14 18:53:42 +0100 |
commit | fbd3a489df9953e2a5d017c922f3c103b2426952 (patch) | |
tree | f7c194210dd28ff40ac1b89337a7e819c58f69af /hw | |
parent | a9cb55a3562a16f7a4c22290f52e2313a3c05b6a (diff) | |
parent | b0dad618baad1efb014c88f4507492a79f2eaf1c (diff) |
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20180514' into staging
Some s390x fixes/cleanups, mainly in the reset area and build fixes
for recent compilers (GCC 8 and clang 6.0.0).
# gpg: Signature made Mon 14 May 2018 16:32:20 BST
# gpg: using RSA key DECF6B93C6F02FAF
# gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>"
# gpg: aka "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>"
# gpg: aka "Cornelia Huck <cohuck@kernel.org>"
# gpg: aka "Cornelia Huck <cohuck@redhat.com>"
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0 18CE DECF 6B93 C6F0 2FAF
* remotes/cohuck/tags/s390x-20180514:
target/s390x: Fix brace Werror with clang 6.0.0
s390x: refactor reset/reipl handling
s390x/ccw: make sure all ccw devices are properly reset
virtio-ccw: common reset handler
pc-bios/s390-ccw: struct tpi_info must be declared as aligned(4)
s390x/css: disabled subchannels cannot be status pending
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/s390x/ccw-device.c | 8 | ||||
-rw-r--r-- | hw/s390x/css.c | 8 | ||||
-rw-r--r-- | hw/s390x/ipl.c | 43 | ||||
-rw-r--r-- | hw/s390x/ipl.h | 16 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-ccw.c | 51 | ||||
-rw-r--r-- | hw/s390x/virtio-ccw.c | 20 | ||||
-rw-r--r-- | hw/s390x/virtio-ccw.h | 1 |
7 files changed, 119 insertions, 28 deletions
diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c index f9bfa154d6..7cd73df4aa 100644 --- a/hw/s390x/ccw-device.c +++ b/hw/s390x/ccw-device.c @@ -40,6 +40,13 @@ static Property ccw_device_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void ccw_device_reset(DeviceState *d) +{ + CcwDevice *ccw_dev = CCW_DEVICE(d); + + css_reset_sch(ccw_dev->sch); +} + static void ccw_device_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -48,6 +55,7 @@ static void ccw_device_class_init(ObjectClass *klass, void *data) k->realize = ccw_device_realize; k->refill_ids = ccw_device_refill_ids; dc->props = ccw_device_properties; + dc->reset = ccw_device_reset; } const VMStateDescription vmstate_ccw_dev = { diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 301bf1772f..56c3fa8c89 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -617,6 +617,14 @@ void css_inject_io_interrupt(SubchDev *sch) void css_conditional_io_interrupt(SubchDev *sch) { /* + * If the subchannel is not enabled, it is not made status pending + * (see PoP p. 16-17, "Status Control"). + */ + if (!(sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA)) { + return; + } + + /* * If the subchannel is not currently status pending, make it pending * with alert status. */ diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 150f6c0582..04245b5258 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -26,6 +26,7 @@ #include "qemu/config-file.h" #include "qemu/cutils.h" #include "qemu/option.h" +#include "exec/exec-all.h" #define KERN_IMAGE_START 0x010000UL #define KERN_PARM_AREA 0x010480UL @@ -488,12 +489,20 @@ IplParameterBlock *s390_ipl_get_iplb(void) return &ipl->iplb; } -void s390_reipl_request(void) +void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type) { S390IPLState *ipl = get_ipl_device(); - ipl->reipl_requested = true; - if (ipl->iplb_valid && + if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL) { + /* use CPU 0 for full resets */ + ipl->reset_cpu_index = 0; + } else { + ipl->reset_cpu_index = cs->cpu_index; + } + ipl->reset_type = reset_type; + + if (reset_type == S390_RESET_REIPL && + ipl->iplb_valid && !ipl->netboot && ipl->iplb.pbt == S390_IPL_TYPE_CCW && is_virtio_scsi_device(&ipl->iplb)) { @@ -510,6 +519,31 @@ void s390_reipl_request(void) } } qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + /* as this is triggered by a CPU, make sure to exit the loop */ + if (tcg_enabled()) { + cpu_loop_exit(cs); + } +} + +void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type) +{ + S390IPLState *ipl = get_ipl_device(); + + *cs = qemu_get_cpu(ipl->reset_cpu_index); + if (!*cs) { + /* use any CPU */ + *cs = first_cpu; + } + *reset_type = ipl->reset_type; +} + +void s390_ipl_clear_reset_request(void) +{ + S390IPLState *ipl = get_ipl_device(); + + ipl->reset_type = S390_RESET_EXTERNAL; + /* use CPU 0 for full resets */ + ipl->reset_cpu_index = 0; } static void s390_ipl_prepare_qipl(S390CPU *cpu) @@ -556,11 +590,10 @@ static void s390_ipl_reset(DeviceState *dev) { S390IPLState *ipl = S390_IPL(dev); - if (!ipl->reipl_requested) { + if (ipl->reset_type != S390_RESET_REIPL) { ipl->iplb_valid = false; memset(&ipl->iplb, 0, sizeof(IplParameterBlock)); } - ipl->reipl_requested = false; } static void s390_ipl_class_init(ObjectClass *klass, void *data) diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h index 0570d0ad75..4e87b89418 100644 --- a/hw/s390x/ipl.h +++ b/hw/s390x/ipl.h @@ -87,7 +87,17 @@ int s390_ipl_set_loadparm(uint8_t *loadparm); void s390_ipl_update_diag308(IplParameterBlock *iplb); void s390_ipl_prepare_cpu(S390CPU *cpu); IplParameterBlock *s390_ipl_get_iplb(void); -void s390_reipl_request(void); + +enum s390_reset { + /* default is a reset not triggered by a CPU e.g. issued by QMP */ + S390_RESET_EXTERNAL = 0, + S390_RESET_REIPL, + S390_RESET_MODIFIED_CLEAR, + S390_RESET_LOAD_NORMAL, +}; +void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type); +void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type); +void s390_ipl_clear_reset_request(void); #define QIPL_ADDRESS 0xcc @@ -129,9 +139,11 @@ struct S390IPLState { bool enforce_bios; IplParameterBlock iplb; bool iplb_valid; - bool reipl_requested; bool netboot; QemuIplParameters qipl; + /* reset related properties don't have to be migrated or reset */ + enum s390_reset reset_type; + int reset_cpu_index; /*< public >*/ char *kernel; diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 5796e24bd8..e548d341a0 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -93,7 +93,7 @@ static const char *const reset_dev_types[] = { "diag288", }; -void subsystem_reset(void) +static void subsystem_reset(void) { DeviceState *dev; int i; @@ -381,17 +381,54 @@ static void s390_cpu_plug(HotplugHandler *hotplug_dev, } } +static inline void s390_do_cpu_ipl(CPUState *cs, run_on_cpu_data arg) +{ + S390CPU *cpu = S390_CPU(cs); + + s390_ipl_prepare_cpu(cpu); + s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); +} + static void s390_machine_reset(void) { - S390CPU *ipl_cpu = S390_CPU(qemu_get_cpu(0)); + enum s390_reset reset_type; + CPUState *cs, *t; + /* get the reset parameters, reset them once done */ + s390_ipl_get_reset_request(&cs, &reset_type); + + /* all CPUs are paused and synchronized at this point */ s390_cmma_reset(); - qemu_devices_reset(); - s390_crypto_reset(); - /* all cpus are stopped - configure and start the ipl cpu only */ - s390_ipl_prepare_cpu(ipl_cpu); - s390_cpu_set_state(S390_CPU_STATE_OPERATING, ipl_cpu); + switch (reset_type) { + case S390_RESET_EXTERNAL: + case S390_RESET_REIPL: + qemu_devices_reset(); + s390_crypto_reset(); + + /* configure and start the ipl CPU only */ + run_on_cpu(cs, s390_do_cpu_ipl, RUN_ON_CPU_NULL); + break; + case S390_RESET_MODIFIED_CLEAR: + CPU_FOREACH(t) { + run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL); + } + subsystem_reset(); + s390_crypto_reset(); + run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL); + break; + case S390_RESET_LOAD_NORMAL: + CPU_FOREACH(t) { + run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL); + } + subsystem_reset(); + run_on_cpu(cs, s390_do_cpu_initial_reset, RUN_ON_CPU_NULL); + run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL); + break; + default: + g_assert_not_reached(); + } + s390_ipl_clear_reset_request(); } static void s390_machine_device_plug(HotplugHandler *hotplug_dev, diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index e51fbefd23..22df33b509 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1058,10 +1058,12 @@ static void virtio_ccw_reset(DeviceState *d) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); - CcwDevice *ccw_dev = CCW_DEVICE(d); + VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_GET_CLASS(dev); virtio_ccw_reset_virtio(dev, vdev); - css_reset_sch(ccw_dev->sch); + if (vdc->parent_reset) { + vdc->parent_reset(d); + } } static void virtio_ccw_vmstate_change(DeviceState *d, bool running) @@ -1345,7 +1347,6 @@ static void virtio_ccw_net_class_init(ObjectClass *klass, void *data) k->realize = virtio_ccw_net_realize; k->unrealize = virtio_ccw_unrealize; - dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_net_properties; set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); } @@ -1373,7 +1374,6 @@ static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data) k->realize = virtio_ccw_blk_realize; k->unrealize = virtio_ccw_unrealize; - dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_blk_properties; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); } @@ -1401,7 +1401,6 @@ static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data) k->realize = virtio_ccw_serial_realize; k->unrealize = virtio_ccw_unrealize; - dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_serial_properties; set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } @@ -1429,7 +1428,6 @@ static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data) k->realize = virtio_ccw_balloon_realize; k->unrealize = virtio_ccw_unrealize; - dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_balloon_properties; set_bit(DEVICE_CATEGORY_MISC, dc->categories); } @@ -1457,7 +1455,6 @@ static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data) k->realize = virtio_ccw_scsi_realize; k->unrealize = virtio_ccw_unrealize; - dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_scsi_properties; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); } @@ -1484,7 +1481,6 @@ static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data) k->realize = vhost_ccw_scsi_realize; k->unrealize = virtio_ccw_unrealize; - dc->reset = virtio_ccw_reset; dc->props = vhost_ccw_scsi_properties; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); } @@ -1521,7 +1517,6 @@ static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data) k->realize = virtio_ccw_rng_realize; k->unrealize = virtio_ccw_unrealize; - dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_rng_properties; set_bit(DEVICE_CATEGORY_MISC, dc->categories); } @@ -1559,7 +1554,6 @@ static void virtio_ccw_crypto_class_init(ObjectClass *klass, void *data) k->realize = virtio_ccw_crypto_realize; k->unrealize = virtio_ccw_unrealize; - dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_crypto_properties; set_bit(DEVICE_CATEGORY_MISC, dc->categories); } @@ -1597,7 +1591,6 @@ static void virtio_ccw_gpu_class_init(ObjectClass *klass, void *data) k->realize = virtio_ccw_gpu_realize; k->unrealize = virtio_ccw_unrealize; - dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_gpu_properties; dc->hotpluggable = false; set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); @@ -1626,7 +1619,6 @@ static void virtio_ccw_input_class_init(ObjectClass *klass, void *data) k->realize = virtio_ccw_input_realize; k->unrealize = virtio_ccw_unrealize; - dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_input_properties; set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } @@ -1725,11 +1717,13 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); CCWDeviceClass *k = CCW_DEVICE_CLASS(dc); + VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_CLASS(klass); k->unplug = virtio_ccw_busdev_unplug; dc->realize = virtio_ccw_busdev_realize; dc->unrealize = virtio_ccw_busdev_unrealize; dc->bus_type = TYPE_VIRTUAL_CSS_BUS; + device_class_set_parent_reset(dc, virtio_ccw_reset, &vdc->parent_reset); } static const TypeInfo virtio_ccw_device_info = { @@ -1806,7 +1800,6 @@ static void virtio_ccw_9p_class_init(ObjectClass *klass, void *data) k->unrealize = virtio_ccw_unrealize; k->realize = virtio_ccw_9p_realize; - dc->reset = virtio_ccw_reset; dc->props = virtio_ccw_9p_properties; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); } @@ -1856,7 +1849,6 @@ static void vhost_vsock_ccw_class_init(ObjectClass *klass, void *data) k->unrealize = virtio_ccw_unrealize; set_bit(DEVICE_CATEGORY_MISC, dc->categories); dc->props = vhost_vsock_ccw_properties; - dc->reset = virtio_ccw_reset; } static void vhost_vsock_ccw_instance_init(Object *obj) diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h index 2fc513001e..3453aa1f98 100644 --- a/hw/s390x/virtio-ccw.h +++ b/hw/s390x/virtio-ccw.h @@ -77,6 +77,7 @@ typedef struct VirtIOCCWDeviceClass { CCWDeviceClass parent_class; void (*realize)(VirtioCcwDevice *dev, Error **errp); void (*unrealize)(VirtioCcwDevice *dev, Error **errp); + void (*parent_reset)(DeviceState *dev); } VirtIOCCWDeviceClass; /* Performance improves when virtqueue kick processing is decoupled from the |