aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-10-05 16:05:06 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-10-05 16:05:06 +0100
commitae7a4c0a4604bcfed40170db6cca576c44d872a2 (patch)
treed83bcc36c59924f4c1515d5cfad9a62e2bdafd9e /hw
parentd21ee59ae5b6e3e7001b877c10c286d111bcf5b7 (diff)
parentb576d582ea2b03f4eada186fff59308d22b40a6a (diff)
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20181004' into staging
Various s390x updates: - fix several struct definitions so that sparc hosts do not trip over unaligned accesses - fence enabling huge pages for pre-3.1 machines - sysbus init -> realize conversion - fixes and improvements in tcg (instruction flags and AFP registers) # gpg: Signature made Thu 04 Oct 2018 16:22: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-20181004: hw/s390x/s390-pci-bus: Convert sysbus init function to realize function s390x/tcg: refactor specification checking s390x/tcg: fix FP register pair checks s390x/tcg: handle privileged instructions via flags s390x/tcg: check for AFP-register, BFP and DFP data exceptions s390x/tcg: add instruction flags for floating point instructions s390x/tcg: support flags for instructions s390x/tcg: store in the TB flags if AFP is enabled s390x/tcg: factor out and fix DATA exception injection s390x: move tcg_s390_program_interrupt() into TCG code and mark it noreturn target/s390x: exception on non-aligned LPSW(E) s390x: Fence huge pages prior to 3.1 hw/s390x/ioinst: Fix alignment problem in struct SubchDev hw/s390x/css: Remove QEMU_PACKED from struct SenseId hw/s390x/ipl: Fix alignment problems of S390IPLState members Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/s390x/css.c38
-rw-r--r--hw/s390x/ipl.h5
-rw-r--r--hw/s390x/s390-pci-bus.c34
-rw-r--r--hw/s390x/s390-virtio-ccw.c10
4 files changed, 56 insertions, 31 deletions
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 5a9fe45ce8..04ec5cc970 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -750,20 +750,25 @@ static void sch_handle_halt_func(SubchDev *sch)
}
-static void copy_sense_id_to_guest(SenseId *dest, SenseId *src)
+/*
+ * As the SenseId struct cannot be packed (would cause unaligned accesses), we
+ * have to copy the individual fields to an unstructured area using the correct
+ * layout (see SA22-7204-01 "Common I/O-Device Commands").
+ */
+static void copy_sense_id_to_guest(uint8_t *dest, SenseId *src)
{
int i;
- dest->reserved = src->reserved;
- dest->cu_type = cpu_to_be16(src->cu_type);
- dest->cu_model = src->cu_model;
- dest->dev_type = cpu_to_be16(src->dev_type);
- dest->dev_model = src->dev_model;
- dest->unused = src->unused;
- for (i = 0; i < ARRAY_SIZE(dest->ciw); i++) {
- dest->ciw[i].type = src->ciw[i].type;
- dest->ciw[i].command = src->ciw[i].command;
- dest->ciw[i].count = cpu_to_be16(src->ciw[i].count);
+ dest[0] = src->reserved;
+ stw_be_p(dest + 1, src->cu_type);
+ dest[3] = src->cu_model;
+ stw_be_p(dest + 4, src->dev_type);
+ dest[6] = src->dev_model;
+ dest[7] = src->unused;
+ for (i = 0; i < ARRAY_SIZE(src->ciw); i++) {
+ dest[8 + i * 4] = src->ciw[i].type;
+ dest[9 + i * 4] = src->ciw[i].command;
+ stw_be_p(dest + 10 + i * 4, src->ciw[i].count);
}
}
@@ -1044,9 +1049,10 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
break;
case CCW_CMD_SENSE_ID:
{
- SenseId sense_id;
+ /* According to SA22-7204-01, Sense-ID can store up to 256 bytes */
+ uint8_t sense_id[256];
- copy_sense_id_to_guest(&sense_id, &sch->id);
+ copy_sense_id_to_guest(sense_id, &sch->id);
/* Sense ID information is device specific. */
if (check_len) {
if (ccw.count != sizeof(sense_id)) {
@@ -1060,11 +1066,11 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
* have enough place to store at least bytes 0-3.
*/
if (len >= 4) {
- sense_id.reserved = 0xff;
+ sense_id[0] = 0xff;
} else {
- sense_id.reserved = 0;
+ sense_id[0] = 0;
}
- ccw_dstream_write_buf(&sch->cds, &sense_id, len);
+ ccw_dstream_write_buf(&sch->cds, sense_id, len);
sch->curr_status.scsw.count = ccw_dstream_residual_count(&sch->cds);
ret = 0;
break;
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index 4e87b89418..b3a07a12d8 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -132,15 +132,15 @@ typedef struct QemuIplParameters QemuIplParameters;
struct S390IPLState {
/*< private >*/
DeviceState parent_obj;
+ IplParameterBlock iplb;
+ QemuIplParameters qipl;
uint64_t start_addr;
uint64_t compat_start_addr;
uint64_t bios_start_addr;
uint64_t compat_bios_start_addr;
bool enforce_bios;
- IplParameterBlock iplb;
bool iplb_valid;
bool netboot;
- QemuIplParameters qipl;
/* reset related properties don't have to be migrated or reset */
enum s390_reset reset_type;
int reset_cpu_index;
@@ -157,6 +157,7 @@ struct S390IPLState {
bool iplbext_migration;
};
typedef struct S390IPLState S390IPLState;
+QEMU_BUILD_BUG_MSG(offsetof(S390IPLState, iplb) & 3, "alignment of iplb wrong");
#define S390_IPL_TYPE_FCP 0x00
#define S390_IPL_TYPE_CCW 0x02
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index e3e0ebb7f6..e42e1b80d6 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -692,27 +692,35 @@ static void s390_pci_iommu_free(S390pciState *s, PCIBus *bus, int32_t devfn)
object_unref(OBJECT(iommu));
}
-static int s390_pcihost_init(SysBusDevice *dev)
+static void s390_pcihost_realize(DeviceState *dev, Error **errp)
{
PCIBus *b;
BusState *bus;
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
S390pciState *s = S390_PCI_HOST_BRIDGE(dev);
+ Error *local_err = NULL;
DPRINTF("host_init\n");
- b = pci_register_root_bus(DEVICE(dev), NULL,
- s390_pci_set_irq, s390_pci_map_irq, NULL,
- get_system_memory(), get_system_io(), 0, 64,
- TYPE_PCI_BUS);
+ b = pci_register_root_bus(dev, NULL, s390_pci_set_irq, s390_pci_map_irq,
+ NULL, get_system_memory(), get_system_io(), 0,
+ 64, TYPE_PCI_BUS);
pci_setup_iommu(b, s390_pci_dma_iommu, s);
bus = BUS(b);
- qbus_set_hotplug_handler(bus, DEVICE(dev), NULL);
+ qbus_set_hotplug_handler(bus, dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
phb->bus = b;
- s->bus = S390_PCI_BUS(qbus_create(TYPE_S390_PCI_BUS, DEVICE(s), NULL));
- qbus_set_hotplug_handler(BUS(s->bus), DEVICE(s), NULL);
+ s->bus = S390_PCI_BUS(qbus_create(TYPE_S390_PCI_BUS, dev, NULL));
+ qbus_set_hotplug_handler(BUS(s->bus), dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
s->iommu_table = g_hash_table_new_full(g_int64_hash, g_int64_equal,
NULL, g_free);
@@ -722,9 +730,10 @@ static int s390_pcihost_init(SysBusDevice *dev)
QTAILQ_INIT(&s->zpci_devs);
css_register_io_adapters(CSS_IO_ADAPTER_PCI, true, false,
- S390_ADAPTER_SUPPRESSIBLE, &error_abort);
-
- return 0;
+ S390_ADAPTER_SUPPRESSIBLE, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ }
}
static int s390_pci_msix_init(S390PCIBusDevice *pbdev)
@@ -1018,12 +1027,11 @@ static void s390_pcihost_reset(DeviceState *dev)
static void s390_pcihost_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
dc->reset = s390_pcihost_reset;
- k->init = s390_pcihost_init;
+ dc->realize = s390_pcihost_realize;
hc->plug = s390_pcihost_hot_plug;
hc->unplug = s390_pcihost_hot_unplug;
msi_nonbroken = true;
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index f0f7fdcadd..53fd7c975f 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -456,6 +456,7 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data)
s390mc->ri_allowed = true;
s390mc->cpu_model_allowed = true;
s390mc->css_migration_enabled = true;
+ s390mc->hpage_1m_allowed = true;
mc->init = ccw_init;
mc->reset = s390_machine_reset;
mc->hot_add_cpu = s390_hot_add_cpu;
@@ -535,6 +536,12 @@ bool cpu_model_allowed(void)
return get_machine_class()->cpu_model_allowed;
}
+bool hpage_1m_allowed(void)
+{
+ /* for "none" machine this results in true */
+ return get_machine_class()->hpage_1m_allowed;
+}
+
static char *machine_get_loadparm(Object *obj, Error **errp)
{
S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
@@ -747,6 +754,9 @@ static void ccw_machine_3_0_instance_options(MachineState *machine)
static void ccw_machine_3_0_class_options(MachineClass *mc)
{
+ S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
+
+ s390mc->hpage_1m_allowed = false;
ccw_machine_3_1_class_options(mc);
SET_MACHINE_COMPAT(mc, CCW_COMPAT_3_0);
}