Commit ae7a4c0a authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents d21ee59a b576d582
Loading
Loading
Loading
Loading
+22 −16
Original line number Diff line number Diff line
@@ -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;
+3 −2
Original line number Diff line number Diff line
@@ -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
+21 −13
Original line number Diff line number Diff line
@@ -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;
+10 −0
Original line number Diff line number Diff line
@@ -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);
}
+3 −3
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ typedef struct SenseId {
    uint8_t unused;          /* padding byte */
    /* extended part */
    CIW ciw[MAX_CIWS];       /* variable # of CIWs */
} QEMU_PACKED SenseId;
} SenseId;                   /* Note: No QEMU_PACKED due to unaligned members */

/* Channel measurements, from linux/drivers/s390/cio/cmf.c. */
typedef struct CMB {
@@ -118,11 +118,12 @@ typedef enum IOInstEnding {
typedef struct SubchDev SubchDev;
struct SubchDev {
    /* channel-subsystem related things: */
    SCHIB curr_status;           /* Needs alignment and thus must come first */
    ORB orb;
    uint8_t cssid;
    uint8_t ssid;
    uint16_t schid;
    uint16_t devno;
    SCHIB curr_status;
    uint8_t sense_data[32];
    hwaddr channel_prog;
    CCW1 last_cmd;
@@ -131,7 +132,6 @@ struct SubchDev {
    bool thinint_active;
    uint8_t ccw_no_data_cnt;
    uint16_t migrated_schid; /* used for missmatch detection */
    ORB orb;
    CcwDataStream cds;
    /* transport-provided data: */
    int (*ccw_cb) (SubchDev *, CCW1);
Loading