From patchwork Fri Nov 2 10:30:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre Morel X-Patchwork-Id: 992254 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42mdk95mQ5z9sWM for ; Fri, 2 Nov 2018 21:34:57 +1100 (AEDT) Received: from localhost ([::1]:50660 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gIWn1-0005fo-6e for incoming@patchwork.ozlabs.org; Fri, 02 Nov 2018 06:34:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39674) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gIWj5-0001sJ-JG for qemu-devel@nongnu.org; Fri, 02 Nov 2018 06:30:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gIWj2-0004HB-EL for qemu-devel@nongnu.org; Fri, 02 Nov 2018 06:30:51 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:42018 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gIWj2-0004By-3n for qemu-devel@nongnu.org; Fri, 02 Nov 2018 06:30:48 -0400 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id wA2ATFhE019043 for ; Fri, 2 Nov 2018 06:30:37 -0400 Received: from e06smtp03.uk.ibm.com (e06smtp03.uk.ibm.com [195.75.94.99]) by mx0b-001b2d01.pphosted.com with ESMTP id 2ngm26j1sy-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 02 Nov 2018 06:30:37 -0400 Received: from localhost by e06smtp03.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 2 Nov 2018 10:30:35 -0000 Received: from b06cxnps4074.portsmouth.uk.ibm.com (9.149.109.196) by e06smtp03.uk.ibm.com (192.168.101.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Fri, 2 Nov 2018 10:30:30 -0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id wA2AUT8g57278482 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 2 Nov 2018 10:30:29 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1E52711C054; Fri, 2 Nov 2018 10:30:29 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B725E11C052; Fri, 2 Nov 2018 10:30:28 +0000 (GMT) Received: from morel-ThinkPad-W530.boeblingen.de.ibm.com (unknown [9.152.224.73]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Fri, 2 Nov 2018 10:30:28 +0000 (GMT) From: Pierre Morel To: borntraeger@de.ibm.com Date: Fri, 2 Nov 2018 11:30:21 +0100 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541154621-22423-1-git-send-email-pmorel@linux.ibm.com> References: <1541154621-22423-1-git-send-email-pmorel@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18110210-0012-0000-0000-000002C2268C X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18110210-0013-0000-0000-000020F65BCE Message-Id: <1541154621-22423-6-git-send-email-pmorel@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-11-02_06:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=860 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1807170000 definitions=main-1811020099 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH v1 5/5] s390x/vfio: ap: Implementing AP Queue Interrupt Control X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: akrowiak@linux.ibm.com, peter.maydell@linaro.org, david@redhat.com, cohuck@redhat.com, qemu-devel@nongnu.org, agraf@suse.de, pasic@linux.ibm.com, eric.auger@redhat.com, qemu-s390x@nongnu.org, mst@redhat.com, pbonzini@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 --- 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 */