Jean-Philippe Brucker
2023-Apr-14 15:07 UTC
[PATCH] iommu/virtio: Detach domain on endpoint release
When an endpoint is released, for example a PCIe VF is disabled or a
function hot-unplugged, it should be detached from its domain. Send a
DETACH request.
Fixes: edcd69ab9a32 ("iommu: Add virtio-iommu driver")
Reported-by: Akihiko Odaki <akihiko.odaki at daynix.com>
Link: https://lore.kernel.org/all/15bf1b00-3aa0-973a-3a86-3fa5c4d41d2c at
daynix.com/
Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
---
drivers/iommu/virtio-iommu.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 5b8fe9bfa9a5..3d3d4462359e 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -788,6 +788,28 @@ static int viommu_attach_dev(struct iommu_domain *domain,
struct device *dev)
return 0;
}
+static void viommu_detach_dev(struct viommu_endpoint *vdev)
+{
+ int i;
+ struct virtio_iommu_req_detach req;
+ struct viommu_domain *vdomain = vdev->vdomain;
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(vdev->dev);
+
+ if (!vdomain)
+ return;
+
+ req = (struct virtio_iommu_req_detach) {
+ .head.type = VIRTIO_IOMMU_T_DETACH,
+ .domain = cpu_to_le32(vdomain->id),
+ };
+
+ for (i = 0; i < fwspec->num_ids; i++) {
+ req.endpoint = cpu_to_le32(fwspec->ids[i]);
+ WARN_ON(viommu_send_req_sync(vdev->viommu, &req, sizeof(req)));
+ }
+ vdev->vdomain = NULL;
+}
+
static int viommu_map_pages(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t pgsize, size_t pgcount,
int prot, gfp_t gfp, size_t *mapped)
@@ -990,6 +1012,7 @@ static void viommu_release_device(struct device *dev)
{
struct viommu_endpoint *vdev = dev_iommu_priv_get(dev);
+ viommu_detach_dev(vdev);
iommu_put_resv_regions(dev, &vdev->resv_regions);
kfree(vdev);
}
--
2.40.0
Jean-Philippe Brucker
2023-May-10 08:11 UTC
[PATCH] iommu/virtio: Detach domain on endpoint release
Hi Joerg, On Fri, Apr 14, 2023 at 04:07:45PM +0100, Jean-Philippe Brucker wrote:> When an endpoint is released, for example a PCIe VF is disabled or a > function hot-unplugged, it should be detached from its domain. Send a > DETACH request. > > Fixes: edcd69ab9a32 ("iommu: Add virtio-iommu driver") > Reported-by: Akihiko Odaki <akihiko.odaki at daynix.com> > Link: https://lore.kernel.org/all/15bf1b00-3aa0-973a-3a86-3fa5c4d41d2c at daynix.com/ > Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org>This patch fixes device unregistration in the virtio-iommu driver, could you please pick it up for the next batch of fixes? It applies cleanly on v6.4-rc1 Thanks, Jean> --- > drivers/iommu/virtio-iommu.c | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > > diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c > index 5b8fe9bfa9a5..3d3d4462359e 100644 > --- a/drivers/iommu/virtio-iommu.c > +++ b/drivers/iommu/virtio-iommu.c > @@ -788,6 +788,28 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev) > return 0; > } > > +static void viommu_detach_dev(struct viommu_endpoint *vdev) > +{ > + int i; > + struct virtio_iommu_req_detach req; > + struct viommu_domain *vdomain = vdev->vdomain; > + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(vdev->dev); > + > + if (!vdomain) > + return; > + > + req = (struct virtio_iommu_req_detach) { > + .head.type = VIRTIO_IOMMU_T_DETACH, > + .domain = cpu_to_le32(vdomain->id), > + }; > + > + for (i = 0; i < fwspec->num_ids; i++) { > + req.endpoint = cpu_to_le32(fwspec->ids[i]); > + WARN_ON(viommu_send_req_sync(vdev->viommu, &req, sizeof(req))); > + } > + vdev->vdomain = NULL; > +} > + > static int viommu_map_pages(struct iommu_domain *domain, unsigned long iova, > phys_addr_t paddr, size_t pgsize, size_t pgcount, > int prot, gfp_t gfp, size_t *mapped) > @@ -990,6 +1012,7 @@ static void viommu_release_device(struct device *dev) > { > struct viommu_endpoint *vdev = dev_iommu_priv_get(dev); > > + viommu_detach_dev(vdev); > iommu_put_resv_regions(dev, &vdev->resv_regions); > kfree(vdev); > } > -- > 2.40.0 >
Hi Jean, On 4/14/23 17:07, Jean-Philippe Brucker wrote:> When an endpoint is released, for example a PCIe VF is disabled or a > function hot-unplugged, it should be detached from its domain. Send a > DETACH request. > > Fixes: edcd69ab9a32 ("iommu: Add virtio-iommu driver") > Reported-by: Akihiko Odaki <akihiko.odaki at daynix.com> > Link: https://lore.kernel.org/all/15bf1b00-3aa0-973a-3a86-3fa5c4d41d2c at daynix.com/ > Signed-off-by: Jean-Philippe Brucker <jean-philippe at linaro.org> > --- > drivers/iommu/virtio-iommu.c | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > > diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c > index 5b8fe9bfa9a5..3d3d4462359e 100644 > --- a/drivers/iommu/virtio-iommu.c > +++ b/drivers/iommu/virtio-iommu.c > @@ -788,6 +788,28 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev) > return 0; > } > > +static void viommu_detach_dev(struct viommu_endpoint *vdev) > +{ > + int i; > + struct virtio_iommu_req_detach req; > + struct viommu_domain *vdomain = vdev->vdomain; > + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(vdev->dev); > + > + if (!vdomain) > + return; > + > + req = (struct virtio_iommu_req_detach) { > + .head.type = VIRTIO_IOMMU_T_DETACH, > + .domain = cpu_to_le32(vdomain->id), > + }; > + > + for (i = 0; i < fwspec->num_ids; i++) { > + req.endpoint = cpu_to_le32(fwspec->ids[i]); > + WARN_ON(viommu_send_req_sync(vdev->viommu, &req, sizeof(req))); > + }just a late question: don't you need to decrement vdomain's nr_endpoints? Thanks Eric> + vdev->vdomain = NULL; > +} > + > static int viommu_map_pages(struct iommu_domain *domain, unsigned long iova, > phys_addr_t paddr, size_t pgsize, size_t pgcount, > int prot, gfp_t gfp, size_t *mapped) > @@ -990,6 +1012,7 @@ static void viommu_release_device(struct device *dev) > { > struct viommu_endpoint *vdev = dev_iommu_priv_get(dev); > > + viommu_detach_dev(vdev); > iommu_put_resv_regions(dev, &vdev->resv_regions); > kfree(vdev); > }