Commit 9fa673c3 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20180308' into staging



Fixes and cleanups for the 2.12 softfreeze.

# gpg: Signature made Thu 08 Mar 2018 17:53:14 GMT
# 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-20180308:
  s390x/virtio: Convert virtio-ccw from *_exit to *_unrealize
  pc-bios/s390-ccw: Move string arrays from bootmap header to .c file
  s390x/sclp: clean up sclp masks
  s390x/sclp: proper support of larger send and receive masks
  vfio-ccw: license text should indicate GPL v2 or later
  s390x/sclpconsole: Remove dead code - remove exit handlers
  numa: we don't implement NUMA for s390x
  hw/s390x: Add the possibility to specify the netboot image on the command line
  target/s390x: Remove leading underscores from #defines
  s390/ipl: only print boot menu error if -boot menu=on was specified
  hw/s390x/ipl: Bail out if the network bootloader can not be found

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents f6d81cde 24118af8
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -102,12 +102,12 @@ static bool can_handle_event(uint8_t type)
    return type == SCLP_EVENT_MESSAGE || type == SCLP_EVENT_PMSGCMD;
}

static unsigned int send_mask(void)
static sccb_mask_t send_mask(void)
{
    return SCLP_EVENT_MASK_OP_CMD | SCLP_EVENT_MASK_PMSGCMD;
}

static unsigned int receive_mask(void)
static sccb_mask_t receive_mask(void)
{
    return SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_PMSGCMD;
}
@@ -318,11 +318,6 @@ static int console_init(SCLPEvent *event)
    return 0;
}

static int console_exit(SCLPEvent *event)
{
    return 0;
}

static void console_reset(DeviceState *dev)
{
   SCLPEvent *event = SCLP_EVENT(dev);
@@ -349,7 +344,6 @@ static void console_class_init(ObjectClass *klass, void *data)
    dc->reset = console_reset;
    dc->vmsd = &vmstate_sclplmconsole;
    ec->init = console_init;
    ec->exit = console_exit;
    ec->get_send_mask = send_mask;
    ec->get_receive_mask = receive_mask;
    ec->can_handle_event = can_handle_event;
+2 −8
Original line number Diff line number Diff line
@@ -83,12 +83,12 @@ static bool can_handle_event(uint8_t type)
    return type == SCLP_EVENT_ASCII_CONSOLE_DATA;
}

static unsigned int send_mask(void)
static sccb_mask_t send_mask(void)
{
    return SCLP_EVENT_MASK_MSG_ASCII;
}

static unsigned int receive_mask(void)
static sccb_mask_t receive_mask(void)
{
    return SCLP_EVENT_MASK_MSG_ASCII;
}
@@ -246,11 +246,6 @@ static void console_reset(DeviceState *dev)
   scon->notify = false;
}

static int console_exit(SCLPEvent *event)
{
    return 0;
}

static Property console_properties[] = {
    DEFINE_PROP_CHR("chardev", SCLPConsole, chr),
    DEFINE_PROP_END_OF_LIST(),
@@ -265,7 +260,6 @@ static void console_class_init(ObjectClass *klass, void *data)
    dc->reset = console_reset;
    dc->vmsd = &vmstate_sclpconsole;
    ec->init = console_init;
    ec->exit = console_exit;
    ec->get_send_mask = send_mask;
    ec->get_receive_mask = receive_mask;
    ec->can_handle_event = can_handle_event;
+78 −37
Original line number Diff line number Diff line
@@ -29,8 +29,17 @@ typedef struct SCLPEventsBus {
struct SCLPEventFacility {
    SysBusDevice parent_obj;
    SCLPEventsBus sbus;
    /* guest' receive mask */
    unsigned int receive_mask;
    /* guest's receive mask */
    sccb_mask_t receive_mask;
    /*
     * when false, we keep the same broken, backwards compatible behaviour as
     * before, allowing only masks of size exactly 4; when true, we implement
     * the architecture correctly, allowing all valid mask sizes. Needed for
     * migration toward older versions.
     */
    bool allow_all_mask_sizes;
    /* length of the receive mask */
    uint16_t mask_length;
};

/* return true if any child has event pending set */
@@ -52,9 +61,9 @@ static bool event_pending(SCLPEventFacility *ef)
    return false;
}

static unsigned int get_host_send_mask(SCLPEventFacility *ef)
static sccb_mask_t get_host_send_mask(SCLPEventFacility *ef)
{
    unsigned int mask;
    sccb_mask_t mask;
    BusChild *kid;
    SCLPEventClass *child;

@@ -68,9 +77,9 @@ static unsigned int get_host_send_mask(SCLPEventFacility *ef)
    return mask;
}

static unsigned int get_host_receive_mask(SCLPEventFacility *ef)
static sccb_mask_t get_host_receive_mask(SCLPEventFacility *ef)
{
    unsigned int mask;
    sccb_mask_t mask;
    BusChild *kid;
    SCLPEventClass *child;

@@ -180,7 +189,7 @@ out:
}

static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb,
                                        unsigned int mask)
                                        sccb_mask_t mask)
{
    uint16_t rc;
    int slen;
@@ -220,10 +229,21 @@ static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb,
    return rc;
}

/* copy up to src_len bytes and fill the rest of dst with zeroes */
static void copy_mask(uint8_t *dst, uint8_t *src, uint16_t dst_len,
                      uint16_t src_len)
{
    int i;

    for (i = 0; i < dst_len; i++) {
        dst[i] = i < src_len ? src[i] : 0;
    }
}

static void read_event_data(SCLPEventFacility *ef, SCCB *sccb)
{
    unsigned int sclp_active_selection_mask;
    unsigned int sclp_cp_receive_mask;
    sccb_mask_t sclp_active_selection_mask;
    sccb_mask_t sclp_cp_receive_mask;

    ReadEventData *red = (ReadEventData *) sccb;

@@ -240,7 +260,9 @@ static void read_event_data(SCLPEventFacility *ef, SCCB *sccb)
        sclp_active_selection_mask = sclp_cp_receive_mask;
        break;
    case SCLP_SELECTIVE_READ:
        sclp_active_selection_mask = be32_to_cpu(red->mask);
        copy_mask((uint8_t *)&sclp_active_selection_mask, (uint8_t *)&red->mask,
                  sizeof(sclp_active_selection_mask), ef->mask_length);
        sclp_active_selection_mask = be32_to_cpu(sclp_active_selection_mask);
        if (!sclp_cp_receive_mask ||
            (sclp_active_selection_mask & ~sclp_cp_receive_mask)) {
            sccb->h.response_code =
@@ -259,24 +281,14 @@ out:
    return;
}

/* copy up to dst_len bytes and fill the rest of dst with zeroes */
static void copy_mask(uint8_t *dst, uint8_t *src, uint16_t dst_len,
                      uint16_t src_len)
{
    int i;

    for (i = 0; i < dst_len; i++) {
        dst[i] = i < src_len ? src[i] : 0;
    }
}

static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
{
    WriteEventMask *we_mask = (WriteEventMask *) sccb;
    uint16_t mask_length = be16_to_cpu(we_mask->mask_length);
    uint32_t tmp_mask;
    sccb_mask_t tmp_mask;

    if (!mask_length || (mask_length > SCLP_EVENT_MASK_LEN_MAX)) {
    if (!mask_length || (mask_length > SCLP_EVENT_MASK_LEN_MAX) ||
        ((mask_length != 4) && !ef->allow_all_mask_sizes)) {
        sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_MASK_LENGTH);
        goto out;
    }
@@ -301,6 +313,7 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
              mask_length, sizeof(tmp_mask));

    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
    ef->mask_length = mask_length;

out:
    return;
@@ -356,6 +369,24 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code)
    }
}

static bool vmstate_event_facility_mask_length_needed(void *opaque)
{
    SCLPEventFacility *ef = opaque;

    return ef->allow_all_mask_sizes;
}

static const VMStateDescription vmstate_event_facility_mask_length = {
    .name = "vmstate-event-facility/mask_length",
    .version_id = 0,
    .minimum_version_id = 0,
    .needed = vmstate_event_facility_mask_length_needed,
    .fields = (VMStateField[]) {
        VMSTATE_UINT16(mask_length, SCLPEventFacility),
        VMSTATE_END_OF_LIST()
     }
};

static const VMStateDescription vmstate_event_facility = {
    .name = "vmstate-event-facility",
    .version_id = 0,
@@ -363,15 +394,39 @@ static const VMStateDescription vmstate_event_facility = {
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(receive_mask, SCLPEventFacility),
        VMSTATE_END_OF_LIST()
     },
    .subsections = (const VMStateDescription * []) {
        &vmstate_event_facility_mask_length,
        NULL
     }
};

static void sclp_event_set_allow_all_mask_sizes(Object *obj, bool value,
                                                       Error **errp)
{
    SCLPEventFacility *ef = (SCLPEventFacility *)obj;

    ef->allow_all_mask_sizes = value;
}

static bool sclp_event_get_allow_all_mask_sizes(Object *obj, Error **e)
{
    SCLPEventFacility *ef = (SCLPEventFacility *)obj;

    return ef->allow_all_mask_sizes;
}

static void init_event_facility(Object *obj)
{
    SCLPEventFacility *event_facility = EVENT_FACILITY(obj);
    DeviceState *sdev = DEVICE(obj);
    Object *new;

    event_facility->mask_length = 4;
    event_facility->allow_all_mask_sizes = true;
    object_property_add_bool(obj, "allow_all_mask_sizes",
                             sclp_event_get_allow_all_mask_sizes,
                             sclp_event_set_allow_all_mask_sizes, NULL);
    /* Spawn a new bus for SCLP events */
    qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
                        TYPE_SCLP_EVENTS_BUS, sdev, NULL);
@@ -431,26 +486,12 @@ static void event_realize(DeviceState *qdev, Error **errp)
    }
}

static void event_unrealize(DeviceState *qdev, Error **errp)
{
    SCLPEvent *event = SCLP_EVENT(qdev);
    SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event);
    if (child->exit) {
        int rc = child->exit(event);
        if (rc < 0) {
            error_setg(errp, "SCLP event exit failed.");
            return;
        }
    }
}

static void event_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->bus_type = TYPE_SCLP_EVENTS_BUS;
    dc->realize = event_realize;
    dc->unrealize = event_unrealize;
}

static const TypeInfo sclp_event_type_info = {
+9 −6
Original line number Diff line number Diff line
@@ -234,7 +234,7 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
    if (!get_boot_device(0)) {
        if (boot_menu) {
            error_report("boot menu requires a bootindex to be specified for "
                         "the IPL device.");
                         "the IPL device");
        }
        return;
    }
@@ -250,7 +250,9 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
    case S390_IPL_TYPE_QEMU_SCSI:
        break;
    default:
        error_report("boot menu is not supported for this device type.");
        if (boot_menu) {
            error_report("boot menu is not supported for this device type");
        }
        return;
    }

@@ -263,13 +265,13 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
    tmp = qemu_opt_get(opts, "splash-time");

    if (tmp && qemu_strtoul(tmp, NULL, 10, &splash_time)) {
        error_report("splash-time is invalid, forcing it to 0.");
        error_report("splash-time is invalid, forcing it to 0");
        *timeout = 0;
        return;
    }

    if (splash_time > 0xffffffff) {
        error_report("splash-time is too large, forcing it to max value.");
        error_report("splash-time is too large, forcing it to max value");
        *timeout = 0xffffffff;
        return;
    }
@@ -380,7 +382,8 @@ static int load_netboot_image(Error **errp)

    netboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->netboot_fw);
    if (netboot_filename == NULL) {
        error_setg(errp, "Could not find network bootloader");
        error_setg(errp, "Could not find network bootloader '%s'",
                   ipl->netboot_fw);
        goto unref_mr;
    }

@@ -489,7 +492,7 @@ void s390_ipl_prepare_cpu(S390CPU *cpu)
    if (ipl->netboot) {
        if (load_netboot_image(&err) < 0) {
            error_report_err(err);
            vm_stop(RUN_STATE_INTERNAL_ERROR);
            exit(1);
        }
        ipl->qipl.netboot_start_addr = cpu_to_be64(ipl->start_addr);
    }
+15 −5
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "s390-pci-bus.h"
#include "hw/s390x/storage-keys.h"
#include "hw/s390x/storage-attributes.h"
#include "hw/s390x/event-facility.h"
#include "hw/compat.h"
#include "ipl.h"
#include "hw/s390x/s390-virtio-ccw.h"
@@ -254,8 +255,10 @@ static void s390_init_ipl_dev(const char *kernel_filename,
    }
    qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
    qdev_prop_set_string(dev, "firmware", firmware);
    qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
    qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
    if (!strlen(object_property_get_str(new, "netboot_fw", &error_abort))) {
        qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
    }
    object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
                              new, NULL);
    object_unref(new);
@@ -388,12 +391,14 @@ static void s390_machine_device_unplug_request(HotplugHandler *hotplug_dev,
    }
}

static CpuInstanceProperties s390_cpu_index_to_props(MachineState *machine,
static CpuInstanceProperties s390_cpu_index_to_props(MachineState *ms,
                                                     unsigned cpu_index)
{
    g_assert(machine->possible_cpus && cpu_index < machine->possible_cpus->len);
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);

    return machine->possible_cpus->cpus[cpu_index].props;
    assert(cpu_index < possible_cpus->len);
    return possible_cpus->cpus[cpu_index].props;
}

static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
@@ -664,7 +669,12 @@ bool css_migration_enabled(void)
    type_init(ccw_machine_register_##suffix)

#define CCW_COMPAT_2_11 \
        HW_COMPAT_2_11
        HW_COMPAT_2_11 \
        {\
            .driver   = TYPE_SCLP_EVENT_FACILITY,\
            .property = "allow_all_mask_sizes",\
            .value    = "off",\
        },

#define CCW_COMPAT_2_10 \
        HW_COMPAT_2_10
Loading