aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-05-14 18:53:42 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-05-14 18:53:42 +0100
commitfbd3a489df9953e2a5d017c922f3c103b2426952 (patch)
treef7c194210dd28ff40ac1b89337a7e819c58f69af /hw
parenta9cb55a3562a16f7a4c22290f52e2313a3c05b6a (diff)
parentb0dad618baad1efb014c88f4507492a79f2eaf1c (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.c8
-rw-r--r--hw/s390x/css.c8
-rw-r--r--hw/s390x/ipl.c43
-rw-r--r--hw/s390x/ipl.h16
-rw-r--r--hw/s390x/s390-virtio-ccw.c51
-rw-r--r--hw/s390x/virtio-ccw.c20
-rw-r--r--hw/s390x/virtio-ccw.h1
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