Commit 1ba530a4 authored by Peter Maydell's avatar Peter Maydell
Browse files

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



s390x updates:
- tcg: support the floating-point extension facility
- vfio-ap: support hot(un)plug of vfio-ap device
- fixes + cleanups

# gpg: Signature made Mon 04 Mar 2019 11:55:39 GMT
# gpg:                using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF
# gpg:                issuer "cohuck@redhat.com"
# gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [unknown]
# gpg:                 aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full]
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full]
# gpg:                 aka "Cornelia Huck <cohuck@kernel.org>" [unknown]
# gpg:                 aka "Cornelia Huck <cohuck@redhat.com>" [unknown]
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0  18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20190304: (27 commits)
  s390x: Add floating-point extension facility to "qemu" cpu model
  s390x/tcg: Handle all rounding modes overwritten by BFP instructions
  s390x/tcg: Implement rounding mode and XxC for LOAD ROUNDED
  s390x/tcg: Implement XxC and checks for most FP instructions
  s390x/tcg: Prepare for IEEE-inexact-exception control (XxC)
  s390x/tcg: Refactor saving/restoring the bfp rounding mode
  s390x/tcg: Check for exceptions in SET BFP ROUNDING MODE
  s390x/tcg: Handle SET FPC AND LOAD FPC 3-bit BFP rounding modes
  s390x/tcg: Fix simulated-IEEE exceptions
  s390x/tcg: Refactor SET FPC AND SIGNAL handling
  s390x/tcg: Hide IEEE underflows in some scenarios
  s390x/tcg: Fix parts of IEEE exception handling
  s390x/tcg: Factor out conversion of softfloat exceptions
  s390x/tcg: Fix rounding from float128 to uint64_t/uint32_t
  s390x/tcg: Fix TEST DATA CLASS instructions
  s390x/tcg: Implement LOAD COUNT TO BLOCK BOUNDARY
  s390x/tcg: Implement LOAD LENGTHENED short HFP to long HFP
  s390x/tcg: Factor out gen_addi_and_wrap_i64() from get_address()
  s390x/tcg: Factor out vec_full_reg_offset()
  s390x/tcg: Clarify terminology in vec_reg_offset()
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 1d31f187 df192fbc
Loading
Loading
Loading
Loading
+56 −5
Original line number Diff line number Diff line
@@ -440,8 +440,7 @@ unassign_control_domain
   'unassign_domain' file. This may be done multiple times to unassign more than
   one control domain.

Notes: Hot plug/unplug is not currently supported for mediated AP matrix
devices, so no changes to the AP matrix will be allowed while a guest using
Notes: No changes to the AP matrix will be allowed while a guest using
the mediated matrix device is running. Attempts to assign an adapter,
domain or control domain will be rejected and an error (EBUSY) returned.

@@ -562,6 +561,54 @@ facilities:
                     for guest usage, no AP devices can be made accessible to a
                     guest started without APFT installed.

Hot plug a vfio-ap device into a running guest:
==============================================
Only one vfio-ap device can be attached to the virtual machine's ap-bus, so a
vfio-ap device can be hot plugged if and only if no vfio-ap device is attached
to the bus already, whether via the QEMU command line or a prior hot plug
action.

To hot plug a vfio-ap device, use the QEMU device_add command:

    (qemu) device_add vfio-ap,sysfsdev="$path-to-mdev"

    Where the '$path-to-mdev' value specifies the absolute path to a mediated
    device to which AP resources to be used by the guest have been assigned.

Note that on Linux guests, the AP devices will be created in the
/sys/bus/ap/devices directory when the AP bus subsequently performs its periodic
scan, so there may be a short delay before the AP devices are accessible on the
guest.

The command will fail if:

* A vfio-ap device has already been attached to the virtual machine's ap-bus.

* The CPU model features for controlling guest access to AP facilities are not
  enabled (see 'CPU model features' subsection in the previous section).

Hot unplug a vfio-ap device from a running guest:
================================================
A vfio-ap device can be unplugged from a running KVM guest if a vfio-ap device
has been attached to the virtual machine's ap-bus via the QEMU command line
or a prior hot plug action.

To hot unplug a vfio-ap device, use the QEMU device_del command:

    (qemu) device_del vfio-ap,sysfsdev="$path-to-mdev"

    Where $path-to-mdev is the same as the path specified when the vfio-ap
    device was attached to the virtual machine's ap-bus.

On a Linux guest, the AP devices will be removed from the /sys/bus/ap/devices
directory on the guest when the AP bus subsequently performs its periodic scan,
so there may be a short delay before the AP devices are no longer accessible by
the guest.

The command will fail if the $path-to-mdev specified on the device_del command
does not match the value specified when the vfio-ap device was attached to
the virtual machine's ap-bus.

Example: Configure AP Matrixes for Three Linux Guests:
=====================================================
Let's now provide an example to illustrate how KVM guests may be given
@@ -819,7 +866,11 @@ Limitations
  assigned lest the host be given access to the private data of the AP queue
  device, such as a private key configured specifically for the guest.

* Dynamically modifying the AP matrix for a running guest (which would amount to
  hot(un)plug of AP devices for the guest) is currently not supported
* Dynamically assigning AP resources to or unassigning AP resources from a
  mediated matrix device - see 'Configuring an AP matrix for a linux guest'
  section above - while a running guest is using it is currently not supported.

* Live guest migration is not supported for guests using AP devices.
* Live guest migration is not supported for guests using AP devices. If a guest
  is using AP devices, the vfio-ap device configured for the guest must be
  unplugged before migrating the guest (see 'Hot unplug a vfio-ap device from a
  running guest' section above.
+11 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ static const TypeInfo ap_bus_info = {
void s390_init_ap(void)
{
    DeviceState *dev;
    BusState *bus;

    /* If no AP instructions then no need for AP bridge */
    if (!s390_has_feat(S390_FEAT_AP)) {
@@ -52,13 +53,18 @@ void s390_init_ap(void)
    qdev_init_nofail(dev);

    /* Create bus on bridge device */
    qbus_create(TYPE_AP_BUS, dev, TYPE_AP_BUS);
    bus = qbus_create(TYPE_AP_BUS, dev, TYPE_AP_BUS);

    /* Enable hotplugging */
    qbus_set_hotplug_handler(bus, OBJECT(dev), &error_abort);
 }

static void ap_bridge_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);

    hc->unplug = qdev_simple_device_unplug_cb;
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}

@@ -67,6 +73,10 @@ static const TypeInfo ap_bridge_info = {
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = 0,
    .class_init    = ap_bridge_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_HOTPLUG_HANDLER },
        { }
    }
};

static void ap_register(void)
+1 −1
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ static void vfio_ap_class_init(ObjectClass *klass, void *data)
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    dc->realize = vfio_ap_realize;
    dc->unrealize = vfio_ap_unrealize;
    dc->hotpluggable = false;
    dc->hotpluggable = true;
    dc->reset = vfio_ap_reset;
    dc->bus_type = TYPE_AP_BUS;
}
+8 −0
Original line number Diff line number Diff line
@@ -397,6 +397,11 @@ static uint32_t cc_calc_flogr(uint64_t dst)
    return dst ? 2 : 0;
}

static uint32_t cc_calc_lcbb(uint64_t dst)
{
    return dst == 16 ? 0 : 3;
}

static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
                                  uint64_t src, uint64_t dst, uint64_t vr)
{
@@ -506,6 +511,9 @@ static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
    case CC_OP_FLOGR:
        r = cc_calc_flogr(dst);
        break;
    case CC_OP_LCBB:
        r = cc_calc_lcbb(dst);
        break;

    case CC_OP_NZ_F32:
        r = set_cc_nz_f32(dst);
+44 −2
Original line number Diff line number Diff line
@@ -347,10 +347,41 @@ static void do_io_interrupt(CPUS390XState *env)
    load_psw(env, mask, addr);
}

typedef struct MchkExtSaveArea {
    uint64_t    vregs[32][2];                     /* 0x0000 */
    uint8_t     pad_0x0200[0x0400 - 0x0200];      /* 0x0200 */
} MchkExtSaveArea;
QEMU_BUILD_BUG_ON(sizeof(MchkExtSaveArea) != 1024);

static int mchk_store_vregs(CPUS390XState *env, uint64_t mcesao)
{
    hwaddr len = sizeof(MchkExtSaveArea);
    MchkExtSaveArea *sa;
    int i;

    sa = cpu_physical_memory_map(mcesao, &len, 1);
    if (!sa) {
        return -EFAULT;
    }
    if (len != sizeof(MchkExtSaveArea)) {
        cpu_physical_memory_unmap(sa, len, 1, 0);
        return -EFAULT;
    }

    for (i = 0; i < 32; i++) {
        sa->vregs[i][0] = cpu_to_be64(env->vregs[i][0].ll);
        sa->vregs[i][1] = cpu_to_be64(env->vregs[i][1].ll);
    }

    cpu_physical_memory_unmap(sa, len, 1, len);
    return 0;
}

static void do_mchk_interrupt(CPUS390XState *env)
{
    QEMUS390FLICState *flic = QEMU_S390_FLIC(s390_get_flic());
    uint64_t mask, addr;
    uint64_t mcic = s390_build_validity_mcic() | MCIC_SC_CP;
    uint64_t mask, addr, mcesao = 0;
    LowCore *lowcore;
    int i;

@@ -362,6 +393,17 @@ static void do_mchk_interrupt(CPUS390XState *env)

    lowcore = cpu_map_lowcore(env);

    /* extended save area */
    if (mcic & MCIC_VB_VR) {
        /* length and alignment is 1024 bytes */
        mcesao = be64_to_cpu(lowcore->mcesad) & ~0x3ffull;
    }

    /* try to store vector registers */
    if (!mcesao || mchk_store_vregs(env, mcesao)) {
        mcic &= ~MCIC_VB_VR;
    }

    /* we are always in z/Architecture mode */
    lowcore->ar_access_id = 1;

@@ -377,7 +419,7 @@ static void do_mchk_interrupt(CPUS390XState *env)
    lowcore->cpu_timer_save_area = cpu_to_be64(env->cputm);
    lowcore->clock_comp_save_area = cpu_to_be64(env->ckc >> 8);

    lowcore->mcic = cpu_to_be64(s390_build_validity_mcic() | MCIC_SC_CP);
    lowcore->mcic = cpu_to_be64(mcic);
    lowcore->mcck_old_psw.mask = cpu_to_be64(get_psw_mask(env));
    lowcore->mcck_old_psw.addr = cpu_to_be64(env->psw.addr);
    mask = be64_to_cpu(lowcore->mcck_new_psw.mask);
Loading