diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-10-05 16:05:06 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-10-05 16:05:06 +0100 |
commit | ae7a4c0a4604bcfed40170db6cca576c44d872a2 (patch) | |
tree | d83bcc36c59924f4c1515d5cfad9a62e2bdafd9e /hw | |
parent | d21ee59ae5b6e3e7001b877c10c286d111bcf5b7 (diff) | |
parent | b576d582ea2b03f4eada186fff59308d22b40a6a (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.c | 38 | ||||
-rw-r--r-- | hw/s390x/ipl.h | 5 | ||||
-rw-r--r-- | hw/s390x/s390-pci-bus.c | 34 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-ccw.c | 10 |
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); } |