From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77205C43387 for ; Tue, 8 Jan 2019 10:29:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4DC052173C for ; Tue, 8 Jan 2019 10:29:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728967AbfAHK3A (ORCPT ); Tue, 8 Jan 2019 05:29:00 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46602 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728920AbfAHK26 (ORCPT ); Tue, 8 Jan 2019 05:28:58 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 96B86637EF; Tue, 8 Jan 2019 10:28:57 +0000 (UTC) Received: from laptop.redhat.com (ovpn-116-249.ams2.redhat.com [10.36.116.249]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3670B601A4; Tue, 8 Jan 2019 10:28:52 +0000 (UTC) From: Eric Auger To: eric.auger.pro@gmail.com, eric.auger@redhat.com, iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu, joro@8bytes.org, alex.williamson@redhat.com, jacob.jun.pan@linux.intel.com, yi.l.liu@linux.intel.com, jean-philippe.brucker@arm.com, will.deacon@arm.com, robin.murphy@arm.com Cc: kevin.tian@intel.com, ashok.raj@intel.com, marc.zyngier@arm.com, christoffer.dall@arm.com, peter.maydell@linaro.org Subject: [RFC v3 19/21] vfio-pci: Register an iommu fault handler Date: Tue, 8 Jan 2019 11:26:31 +0100 Message-Id: <20190108102633.17482-20-eric.auger@redhat.com> In-Reply-To: <20190108102633.17482-1-eric.auger@redhat.com> References: <20190108102633.17482-1-eric.auger@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 08 Jan 2019 10:28:57 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch registers a fault handler which records faults in a circular buffer and then signals an eventfd. This buffer is exposed within the fault region. Signed-off-by: Eric Auger --- drivers/vfio/pci/vfio_pci.c | 44 ++++++++++++++++++++++++++++- drivers/vfio/pci/vfio_pci_private.h | 1 + 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 2ba181ab2edd..f9e2c8292e60 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "vfio_pci_private.h" @@ -1296,6 +1297,44 @@ static const struct vfio_pci_regops vfio_pci_dma_fault_regops = { .release = vfio_pci_dma_fault_release, }; +int vfio_pci_iommu_dev_fault_handler(struct iommu_fault_event *evt, void *data) +{ + struct vfio_pci_device *vdev = (struct vfio_pci_device *) data; + int prod, cons, size; + unsigned long flags; + + spin_lock_irqsave(&vdev->fault_queue_lock, flags); + prod = vdev->fault_region->header.prod; + cons = vdev->fault_region->header.cons; + size = vdev->fault_region->header.size; + + if (cons > VFIO_FAULT_QUEUE_SIZE - 1) + goto unlock; + if (prod > VFIO_FAULT_QUEUE_SIZE - 1) + goto unlock; + if (size != VFIO_FAULT_QUEUE_SIZE) + goto unlock; + if (vdev->fault_region->header.reserved) + goto unlock; + if (CIRC_SPACE(prod, cons, size) < 1) + goto unlock; + + vdev->fault_region->queue[prod] = evt->fault; + prod = (prod + 1) % size; + vdev->fault_region->header.prod = prod; + spin_unlock_irqrestore(&vdev->fault_queue_lock, flags); + + mutex_lock(&vdev->igate); + if (vdev->dma_fault_trigger) + eventfd_signal(vdev->dma_fault_trigger, 1); + mutex_unlock(&vdev->igate); + return 0; + +unlock: + spin_unlock_irqrestore(&vdev->fault_queue_lock, flags); + return -EINVAL; +} + static int vfio_pci_init_dma_fault_region(struct vfio_pci_device *vdev) { u32 flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE | @@ -1322,7 +1361,9 @@ static int vfio_pci_init_dma_fault_region(struct vfio_pci_device *vdev) vdev->fault_region->header.cons = 0; vdev->fault_region->header.reserved = 0; vdev->fault_region->header.size = VFIO_FAULT_QUEUE_SIZE; - return 0; + return iommu_register_device_fault_handler(&vdev->pdev->dev, + vfio_pci_iommu_dev_fault_handler, + vdev); } static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -1414,6 +1455,7 @@ static void vfio_pci_remove(struct pci_dev *pdev) vfio_iommu_group_put(pdev->dev.iommu_group, &pdev->dev); kfree(vdev->region); + iommu_unregister_device_fault_handler(&pdev->dev); kfree(vdev->fault_region); mutex_destroy(&vdev->ioeventfds_lock); kfree(vdev); diff --git a/drivers/vfio/pci/vfio_pci_private.h b/drivers/vfio/pci/vfio_pci_private.h index 38b5d1764a26..5936802cbbd0 100644 --- a/drivers/vfio/pci/vfio_pci_private.h +++ b/drivers/vfio/pci/vfio_pci_private.h @@ -120,6 +120,7 @@ struct vfio_pci_device { int ioeventfds_nr; struct eventfd_ctx *err_trigger; struct eventfd_ctx *req_trigger; + struct eventfd_ctx *dma_fault_trigger; spinlock_t fault_queue_lock; struct vfio_fault_region *fault_region; struct list_head dummy_resources_list; -- 2.17.2