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 <kevin.tian@intel.com> Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Reviewed-by: Eric Auger <eric.auger@redhat.com> Link: https://lore.kernel.org/r/20211201173323.1045819-3-jean-philippe@linaro.org Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
Родитель
063ebb19d9
Коммит
f0f07a8462
|
@ -71,6 +71,7 @@ struct viommu_domain {
|
|||
struct rb_root_cached mappings;
|
||||
|
||||
unsigned long nr_endpoints;
|
||||
bool bypass;
|
||||
};
|
||||
|
||||
struct viommu_endpoint {
|
||||
|
@ -587,7 +588,9 @@ static struct iommu_domain *viommu_domain_alloc(unsigned type)
|
|||
{
|
||||
struct viommu_domain *vdomain;
|
||||
|
||||
if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
|
||||
if (type != IOMMU_DOMAIN_UNMANAGED &&
|
||||
type != IOMMU_DOMAIN_DMA &&
|
||||
type != IOMMU_DOMAIN_IDENTITY)
|
||||
return NULL;
|
||||
|
||||
vdomain = kzalloc(sizeof(*vdomain), GFP_KERNEL);
|
||||
|
@ -630,6 +633,17 @@ static int viommu_domain_finalise(struct viommu_endpoint *vdev,
|
|||
vdomain->map_flags = viommu->map_flags;
|
||||
vdomain->viommu = viommu;
|
||||
|
||||
if (domain->type == IOMMU_DOMAIN_IDENTITY) {
|
||||
if (!virtio_has_feature(viommu->vdev,
|
||||
VIRTIO_IOMMU_F_BYPASS_CONFIG)) {
|
||||
ida_free(&viommu->domain_ids, vdomain->id);
|
||||
vdomain->viommu = NULL;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
vdomain->bypass = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -691,6 +705,9 @@ static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
|
|||
.domain = cpu_to_le32(vdomain->id),
|
||||
};
|
||||
|
||||
if (vdomain->bypass)
|
||||
req.flags |= cpu_to_le32(VIRTIO_IOMMU_ATTACH_F_BYPASS);
|
||||
|
||||
for (i = 0; i < fwspec->num_ids; i++) {
|
||||
req.endpoint = cpu_to_le32(fwspec->ids[i]);
|
||||
|
||||
|
@ -1132,6 +1149,7 @@ static unsigned int features[] = {
|
|||
VIRTIO_IOMMU_F_DOMAIN_RANGE,
|
||||
VIRTIO_IOMMU_F_PROBE,
|
||||
VIRTIO_IOMMU_F_MMIO,
|
||||
VIRTIO_IOMMU_F_BYPASS_CONFIG,
|
||||
};
|
||||
|
||||
static struct virtio_device_id id_table[] = {
|
||||
|
|
Загрузка…
Ссылка в новой задаче