Skip to content

Commit f0f07a8

Browse files
jpbruckerjoergroedel
authored andcommitted
iommu/virtio: Support bypass domains
The VIRTIO_IOMMU_F_BYPASS_CONFIG feature adds a new flag to the ATTACH request, that creates a bypass domain. Use it to enable identity domains. When VIRTIO_IOMMU_F_BYPASS_CONFIG is not supported by the device, we currently fail attaching to an identity domain. Future patches will instead create identity mappings in this case. Reviewed-by: Kevin Tian <[email protected]> Signed-off-by: Jean-Philippe Brucker <[email protected]> Reviewed-by: Eric Auger <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 063ebb1 commit f0f07a8

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

drivers/iommu/virtio-iommu.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ struct viommu_domain {
7171
struct rb_root_cached mappings;
7272

7373
unsigned long nr_endpoints;
74+
bool bypass;
7475
};
7576

7677
struct viommu_endpoint {
@@ -587,7 +588,9 @@ static struct iommu_domain *viommu_domain_alloc(unsigned type)
587588
{
588589
struct viommu_domain *vdomain;
589590

590-
if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
591+
if (type != IOMMU_DOMAIN_UNMANAGED &&
592+
type != IOMMU_DOMAIN_DMA &&
593+
type != IOMMU_DOMAIN_IDENTITY)
591594
return NULL;
592595

593596
vdomain = kzalloc(sizeof(*vdomain), GFP_KERNEL);
@@ -630,6 +633,17 @@ static int viommu_domain_finalise(struct viommu_endpoint *vdev,
630633
vdomain->map_flags = viommu->map_flags;
631634
vdomain->viommu = viommu;
632635

636+
if (domain->type == IOMMU_DOMAIN_IDENTITY) {
637+
if (!virtio_has_feature(viommu->vdev,
638+
VIRTIO_IOMMU_F_BYPASS_CONFIG)) {
639+
ida_free(&viommu->domain_ids, vdomain->id);
640+
vdomain->viommu = NULL;
641+
return -EOPNOTSUPP;
642+
}
643+
644+
vdomain->bypass = true;
645+
}
646+
633647
return 0;
634648
}
635649

@@ -691,6 +705,9 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
691705
.domain = cpu_to_le32(vdomain->id),
692706
};
693707

708+
if (vdomain->bypass)
709+
req.flags |= cpu_to_le32(VIRTIO_IOMMU_ATTACH_F_BYPASS);
710+
694711
for (i = 0; i < fwspec->num_ids; i++) {
695712
req.endpoint = cpu_to_le32(fwspec->ids[i]);
696713

@@ -1132,6 +1149,7 @@ static unsigned int features[] = {
11321149
VIRTIO_IOMMU_F_DOMAIN_RANGE,
11331150
VIRTIO_IOMMU_F_PROBE,
11341151
VIRTIO_IOMMU_F_MMIO,
1152+
VIRTIO_IOMMU_F_BYPASS_CONFIG,
11351153
};
11361154

11371155
static struct virtio_device_id id_table[] = {

0 commit comments

Comments
 (0)