aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-06-20 09:51:30 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-06-20 09:51:30 +0100
commit46012db666990ff2eed1d3dc199ab8006439a93b (patch)
treef067d28651c66530c8ea9d24d23fda2da21f0532 /hw
parenteee4baef4ac273b99e06ef5b12ac74bbc94fab62 (diff)
parent49b67e9440892179c016a7afd33725a50d995ba6 (diff)
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20180619' into staging
- cleanup in virtio-ccw - accommodate guests using vfio-ccw without specifying unlimited prefetch, but actually working fine - add cpu model for the z14 Model ZR1 - add support for pxelinux.cfg-style network booting to the s390x firmware # gpg: Signature made Tue 19 Jun 2018 10:33:06 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-20180619: pc-bios/s390-ccw: Update the s390-netboot.img binary pc-bios/s390-ccw: Optimize the s390-netboot.img for size pc-bios/s390-ccw/net: Try to load pxelinux.cfg file accoring to the UUID pc-bios/s390-ccw/net: Add support for pxelinux-style config files pc-bios/s390-ccw/net: Update code for the latest changes in SLOF roms: Update SLOF submodule to current status pc-bios/s390-ccw: define loadparm length s390x/cpumodels: add z14 Model ZR1 s390x/ipl: Try to detect Linux vs non Linux for initial IPL PSW vfio-ccw: remove orb.c64 (64 bit data addresses) check vfio-ccw: add force unlimited prefetch property virtio-ccw: clean up notify Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/s390x/css.c12
-rw-r--r--hw/s390x/ipl.c27
-rw-r--r--hw/s390x/virtio-ccw.c13
-rw-r--r--hw/vfio/ccw.c35
4 files changed, 66 insertions, 21 deletions
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 56c3fa8c89..5424ea4562 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1199,18 +1199,6 @@ static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch)
assert(orb != NULL);
p->intparm = orb->intparm;
}
-
- /*
- * Only support prefetch enable mode.
- * Only support 64bit addressing idal.
- */
- if (!(orb->ctrl0 & ORB_CTRL0_MASK_PFCH) ||
- !(orb->ctrl0 & ORB_CTRL0_MASK_C64)) {
- warn_report("vfio-ccw requires PFCH and C64 flags set");
- sch_gen_unit_exception(sch);
- css_inject_io_interrupt(sch);
- return IOINST_CC_EXPECTED;
- }
return s390_ccw_cmd_request(sch);
}
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 04245b5258..0d67349004 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -29,6 +29,7 @@
#include "exec/exec-all.h"
#define KERN_IMAGE_START 0x010000UL
+#define LINUX_MAGIC_ADDR 0x010008UL
#define KERN_PARM_AREA 0x010480UL
#define INITRD_START 0x800000UL
#define INITRD_PARM_START 0x010408UL
@@ -105,7 +106,9 @@ static uint64_t bios_translate_addr(void *opaque, uint64_t srcaddr)
static void s390_ipl_realize(DeviceState *dev, Error **errp)
{
S390IPLState *ipl = S390_IPL(dev);
- uint64_t pentry = KERN_IMAGE_START;
+ uint32_t *ipl_psw;
+ uint64_t pentry;
+ char *magic;
int kernel_size;
Error *err = NULL;
@@ -157,10 +160,24 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp)
NULL, 1, EM_S390, 0, 0);
if (kernel_size < 0) {
kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
- }
- if (kernel_size < 0) {
- error_setg(&err, "could not load kernel '%s'", ipl->kernel);
- goto error;
+ if (kernel_size < 0) {
+ error_setg(&err, "could not load kernel '%s'", ipl->kernel);
+ goto error;
+ }
+ /* if this is Linux use KERN_IMAGE_START */
+ magic = rom_ptr(LINUX_MAGIC_ADDR);
+ if (magic && !memcmp(magic, "S390EP", 6)) {
+ pentry = KERN_IMAGE_START;
+ } else {
+ /* if not Linux load the address of the (short) IPL PSW */
+ ipl_psw = rom_ptr(4);
+ if (ipl_psw) {
+ pentry = be32_to_cpu(*ipl_psw) & 0x7fffffffUL;
+ } else {
+ error_setg(&err, "Could not get IPL PSW");
+ goto error;
+ }
+ }
}
/*
* Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 0a9bec484b..b92a85d0b0 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1001,10 +1001,15 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
SubchDev *sch = ccw_dev->sch;
uint64_t indicators;
- /* queue indicators + secondary indicators */
- if (vector >= VIRTIO_QUEUE_MAX + 64) {
+ if (vector == VIRTIO_NO_VECTOR) {
return;
}
+ /*
+ * vector < VIRTIO_QUEUE_MAX: notification for a virtqueue
+ * vector == VIRTIO_QUEUE_MAX: configuration change notification
+ * bits beyond that are unused and should never be notified for
+ */
+ assert(vector <= VIRTIO_QUEUE_MAX);
if (vector < VIRTIO_QUEUE_MAX) {
if (!dev->indicators) {
@@ -1027,6 +1032,7 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
css_adapter_interrupt(CSS_IO_ADAPTER_VIRTIO, dev->thinint_isc);
}
} else {
+ assert(vector < NR_CLASSIC_INDICATOR_BITS);
indicators = address_space_ldq(&address_space_memory,
dev->indicators->addr,
MEMTXATTRS_UNSPECIFIED,
@@ -1040,12 +1046,11 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
if (!dev->indicators2) {
return;
}
- vector = 0;
indicators = address_space_ldq(&address_space_memory,
dev->indicators2->addr,
MEMTXATTRS_UNSPECIFIED,
NULL);
- indicators |= 1ULL << vector;
+ indicators |= 1ULL;
address_space_stq(&address_space_memory, dev->indicators2->addr,
indicators, MEMTXATTRS_UNSPECIFIED, NULL);
css_conditional_io_interrupt(sch);
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 76e4e8c652..351b305e1a 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -33,8 +33,30 @@ typedef struct VFIOCCWDevice {
uint64_t io_region_offset;
struct ccw_io_region *io_region;
EventNotifier io_notifier;
+ bool force_orb_pfch;
+ bool warned_orb_pfch;
} VFIOCCWDevice;
+static inline void warn_once(bool *warned, const char *fmt, ...)
+{
+ va_list ap;
+
+ if (!warned || *warned) {
+ return;
+ }
+ *warned = true;
+ va_start(ap, fmt);
+ warn_vreport(fmt, ap);
+ va_end(ap);
+}
+
+static inline void warn_once_pfch(VFIOCCWDevice *vcdev, SubchDev *sch,
+ const char *msg)
+{
+ warn_once(&vcdev->warned_orb_pfch, "vfio-ccw (devno %x.%x.%04x): %s",
+ sch->cssid, sch->ssid, sch->devno, msg);
+}
+
static void vfio_ccw_compute_needs_reset(VFIODevice *vdev)
{
vdev->needs_reset = false;
@@ -55,6 +77,18 @@ static IOInstEnding vfio_ccw_handle_request(SubchDev *sch)
struct ccw_io_region *region = vcdev->io_region;
int ret;
+ if (!(sch->orb.ctrl0 & ORB_CTRL0_MASK_PFCH)) {
+ if (!(vcdev->force_orb_pfch)) {
+ warn_once_pfch(vcdev, sch, "requires PFCH flag set");
+ sch_gen_unit_exception(sch);
+ css_inject_io_interrupt(sch);
+ return IOINST_CC_EXPECTED;
+ } else {
+ sch->orb.ctrl0 |= ORB_CTRL0_MASK_PFCH;
+ warn_once_pfch(vcdev, sch, "PFCH flag forced");
+ }
+ }
+
QEMU_BUILD_BUG_ON(sizeof(region->orb_area) != sizeof(ORB));
QEMU_BUILD_BUG_ON(sizeof(region->scsw_area) != sizeof(SCSW));
QEMU_BUILD_BUG_ON(sizeof(region->irb_area) != sizeof(IRB));
@@ -430,6 +464,7 @@ static void vfio_ccw_unrealize(DeviceState *dev, Error **errp)
static Property vfio_ccw_properties[] = {
DEFINE_PROP_STRING("sysfsdev", VFIOCCWDevice, vdev.sysfsdev),
+ DEFINE_PROP_BOOL("force-orb-pfch", VFIOCCWDevice, force_orb_pfch, false),
DEFINE_PROP_END_OF_LIST(),
};