From: Pierre Morel <pmorel@linux.ibm.com>
To: borntraeger@de.ibm.com
Cc: cohuck@redhat.com, agraf@suse.de, rth@twiddle.net,
david@redhat.com, qemu-s390x@nongnu.org, qemu-devel@nongnu.org,
peter.maydell@linaro.org, pbonzini@redhat.com, mst@redhat.com,
eric.auger@redhat.com, akrowiak@linux.ibm.com,
pasic@linux.ibm.com
Subject: [Qemu-devel] [PATCH v1 5/5] s390x/vfio: ap: Implementing AP Queue Interrupt Control
Date: Fri, 2 Nov 2018 11:30:21 +0100 [thread overview]
Message-ID: <1541154621-22423-6-git-send-email-pmorel@linux.ibm.com> (raw)
In-Reply-To: <1541154621-22423-1-git-send-email-pmorel@linux.ibm.com>
We intercept the PQAP(AQIC) instruction and transform
the guest's AQIC command parameters for the host AQIC
parameters.
Doing this we use the standard adapter interface to provide
the adapter NIB, indicator and ISC.
We define a new structure, APQueue to keep track of
the route and indicator address and we add an array of
AP Queues in the VFIOAPDevice.
We call the VFIO ioctl to set or clear the interruption
according to the "i" bit of the parameter.
Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
---
hw/vfio/ap.c | 92 +++++++++++++++++++++++++++++++++++-
include/hw/s390x/ap-device.h | 46 ++++++++++++++++++
2 files changed, 137 insertions(+), 1 deletion(-)
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index d8d9cadc46..67a46e163e 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -27,17 +27,90 @@
#include "sysemu/sysemu.h"
#include "hw/s390x/ap-bridge.h"
#include "exec/address-spaces.h"
+#include "hw/s390x/s390_flic.h"
+#include "hw/s390x/css.h"
#define VFIO_AP_DEVICE_TYPE "vfio-ap"
typedef struct VFIOAPDevice {
APDevice apdev;
VFIODevice vdev;
+ QTAILQ_ENTRY(VFIOAPDevice) sibling;
+ APQueue apq[MAX_AP][MAX_DOMAIN];
} VFIOAPDevice;
#define VFIO_AP_DEVICE(obj) \
OBJECT_CHECK(VFIOAPDevice, (obj), VFIO_AP_DEVICE_TYPE)
+VFIOAPDevice *vfio_apdev;
+static APDevice *matrix;
+
+static int ap_aqic(CPUS390XState *env)
+{
+ struct pqap_cmd cmd = reg2cmd(env->regs[0]);
+ struct ap_status status = reg2status(env->regs[1]);
+ uint64_t guest_nib = env->regs[2];
+ struct vfio_ap_aqic param = {};
+ int retval;
+ VFIODevice *vdev;
+ VFIOAPDevice *ap_vdev;
+ APQueue *apq;
+
+ ap_vdev = DO_UPCAST(VFIOAPDevice, apdev, matrix);
+ apq = &ap_vdev->apq[cmd.apid][cmd.apqi];
+ vdev = &ap_vdev->vdev;
+
+ if (status.irq) {
+ if (apq->nib) {
+ status.rc = AP_RC_BAD_STATE;
+ goto error;
+ }
+ } else {
+ if (!apq->nib) {
+ status.rc = AP_RC_BAD_STATE;
+ goto error;
+ }
+ }
+ if (!guest_nib) {
+ status.rc = AP_RC_INVALID_ADDR;
+ goto error;
+ }
+
+ apq->routes.adapter.adapter_id = css_get_adapter_id(
+ CSS_IO_ADAPTER_AP, status.isc);
+
+ apq->nib = get_indicator(ldq_p(&guest_nib), 8);
+
+ retval = map_indicator(&apq->routes.adapter, apq->nib);
+ if (retval) {
+ status.rc = AP_RC_INVALID_ADDR;
+ env->regs[1] = status2reg(status);
+ goto error;
+ }
+
+ param.cmd = env->regs[0];
+ param.status = env->regs[1];
+ param.nib = env->regs[2];
+ param.adapter_id = apq->routes.adapter.adapter_id;
+ param.argsz = sizeof(param);
+
+ retval = ioctl(vdev->fd, VFIO_AP_SET_IRQ, ¶m);
+ status = reg2status(param.status);
+ if (retval) {
+ goto err_ioctl;
+ }
+
+ env->regs[1] = param.status;
+
+ return 0;
+err_ioctl:
+ release_indicator(&apq->routes.adapter, apq->nib);
+ apq->nib = NULL;
+error:
+ env->regs[1] = status2reg(status);
+ return 0;
+}
+
/*
* ap_pqap
* @env: environment pointing to registers
@@ -45,7 +118,20 @@ typedef struct VFIOAPDevice {
*/
int ap_pqap(CPUS390XState *env)
{
- return -PGM_OPERATION;
+ struct pqap_cmd cmd = reg2cmd(env->regs[0]);
+ int cc = 0;
+
+ switch (cmd.fc) {
+ case AQIC:
+ if (!s390_has_feat(S390_FEAT_AP_QUEUE_INTERRUPT_CONTROL)) {
+ return -PGM_OPERATION;
+ }
+ cc = ap_aqic(env);
+ break;
+ default:
+ return -PGM_OPERATION;
+ }
+ return cc;
}
static void vfio_ap_compute_needs_reset(VFIODevice *vdev)
@@ -119,6 +205,9 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
goto out_get_dev_err;
}
+ matrix = apdev;
+ css_register_io_adapters(CSS_IO_ADAPTER_AP, true, false,
+ 0, &error_abort);
return;
out_get_dev_err:
@@ -135,6 +224,7 @@ static void vfio_ap_unrealize(DeviceState *dev, Error **errp)
VFIOGroup *group = vapdev->vdev.group;
vfio_ap_put_device(vapdev);
+ matrix = NULL;
vfio_put_group(group);
}
diff --git a/include/hw/s390x/ap-device.h b/include/hw/s390x/ap-device.h
index a83ea096c7..bc2b7bcd8e 100644
--- a/include/hw/s390x/ap-device.h
+++ b/include/hw/s390x/ap-device.h
@@ -28,4 +28,50 @@ typedef struct APDevice {
#include "cpu.h"
int ap_pqap(CPUS390XState *env);
+#define MAX_AP 256
+#define MAX_DOMAIN 256
+
+#include "hw/s390x/s390_flic.h"
+#include "hw/s390x/css.h"
+typedef struct APQueue {
+ uint32_t apid;
+ uint32_t apqi;
+ AdapterRoutes routes;
+ IndAddr *nib;
+} APQueue;
+
+/* AP PQAP commands definitions */
+#define AQIC 0x03
+
+struct pqap_cmd {
+ uint32_t unused;
+ uint8_t fc;
+ unsigned t:1;
+ unsigned reserved:7;
+ uint8_t apid;
+ uint8_t apqi;
+};
+/* AP status returned by the AP PQAP commands */
+#define AP_RC_APQN_INVALID 0x01
+#define AP_RC_INVALID_ADDR 0x06
+#define AP_RC_BAD_STATE 0x07
+
+struct ap_status {
+ uint16_t pad;
+ unsigned irq:1;
+ unsigned pad2:15;
+ unsigned e:1;
+ unsigned r:1;
+ unsigned f:1;
+ unsigned unused:4;
+ unsigned i:1;
+ unsigned char rc;
+ unsigned reserved:13;
+ unsigned isc:3;
+};
+
+#define reg2cmd(reg) (*(struct pqap_cmd *)&(reg))
+#define status2reg(status) (*((uint64_t *)&status))
+#define reg2status(reg) (*(struct ap_status *)&(reg))
+
#endif /* HW_S390X_AP_DEVICE_H */
--
2.17.0
next prev parent reply other threads:[~2018-11-02 10:30 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-02 10:30 [Qemu-devel] [PATCH v1 0/5] s390x/vfio: VFIO-AP interrupt control interception Pierre Morel
2018-11-02 10:30 ` [Qemu-devel] [PATCH v1 1/5] s390x/vfio: ap: Linux uapi VFIO place holder Pierre Morel
2018-11-02 10:30 ` [Qemu-devel] [PATCH v1 2/5] s390x/cpumodel: Set up CPU model for AQIC interception Pierre Morel
2018-11-02 10:30 ` [Qemu-devel] [PATCH v1 3/5] s390x/vfio: ap: Definition for AP Adapter type Pierre Morel
2018-11-02 10:30 ` [Qemu-devel] [PATCH v1 4/5] s390x/vfio: ap: Intercepting AP Queue Interrupt Control Pierre Morel
2018-11-07 12:40 ` Cornelia Huck
2018-11-07 22:44 ` Pierre Morel
2018-11-02 10:30 ` Pierre Morel [this message]
2018-11-07 13:39 ` [Qemu-devel] [PATCH v1 5/5] s390x/vfio: ap: Implementing " Cornelia Huck
2018-11-07 23:02 ` Pierre Morel
2018-11-02 12:53 ` [Qemu-devel] [PATCH v1 0/5] s390x/vfio: VFIO-AP interrupt control interception David Hildenbrand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1541154621-22423-6-git-send-email-pmorel@linux.ibm.com \
--to=pmorel@linux.ibm.com \
--cc=agraf@suse.de \
--cc=akrowiak@linux.ibm.com \
--cc=borntraeger@de.ibm.com \
--cc=cohuck@redhat.com \
--cc=david@redhat.com \
--cc=eric.auger@redhat.com \
--cc=mst@redhat.com \
--cc=pasic@linux.ibm.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).