drivers/iommu/virtio-iommu.c
Source file repositories/reference/linux-study-clean/drivers/iommu/virtio-iommu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iommu/virtio-iommu.c- Extension
.c- Size
- 32795 bytes
- Lines
- 1302
- Domain
- Driver Families
- Bucket
- drivers/iommu
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/dma-map-ops.hlinux/freezer.hlinux/interval_tree.hlinux/iommu.hlinux/module.hlinux/of.hlinux/pci.hlinux/virtio.hlinux/virtio_config.hlinux/virtio_ids.hlinux/wait.huapi/linux/virtio_iommu.hdma-iommu.h
Detected Declarations
struct viommu_devstruct viommu_mappingstruct viommu_domainstruct viommu_endpointstruct viommu_requeststruct viommu_eventfunction viommu_get_req_errnofunction viommu_set_req_statusfunction viommu_get_write_desc_offsetfunction __viommu_sync_reqfunction viommu_sync_reqfunction sync_reqfunction viommu_add_reqfunction viommu_send_req_syncfunction viommu_send_attach_reqfunction viommu_add_mappingfunction viommu_del_mappingsfunction viommu_domain_map_identityfunction list_for_each_entryfunction viommu_replay_mappingsfunction viommu_add_resv_memfunction viommu_probe_endpointfunction viommu_fault_handlerfunction viommu_event_handlerfunction viommu_domain_freefunction viommu_attach_devfunction viommu_attach_identity_domainfunction viommu_detach_devfunction viommu_map_pagesfunction viommu_unmap_pagesfunction viommu_iova_to_physfunction viommu_iotlb_syncfunction viommu_iotlb_sync_mapfunction viommu_flush_iotlb_allfunction viommu_get_resv_regionsfunction list_for_each_entryfunction viommu_match_nodefunction viommu_release_devicefunction viommu_of_xlatefunction viommu_capablefunction viommu_init_vqsfunction viommu_fill_evtqfunction viommu_probefunction viommu_removefunction viommu_config_changed
Annotated Snippet
static const struct bus_type *virtio_bus_type;
static int viommu_match_node(struct device *dev, const void *data)
{
return device_match_fwnode(dev->parent, data);
}
static struct viommu_dev *viommu_get_by_fwnode(struct fwnode_handle *fwnode)
{
struct device *dev = bus_find_device(virtio_bus_type, NULL, fwnode,
viommu_match_node);
put_device(dev);
return dev ? dev_to_virtio(dev)->priv : NULL;
}
static struct iommu_device *viommu_probe_device(struct device *dev)
{
int ret;
struct viommu_endpoint *vdev;
struct viommu_dev *viommu = NULL;
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
viommu = viommu_get_by_fwnode(fwspec->iommu_fwnode);
if (!viommu)
return ERR_PTR(-ENODEV);
vdev = kzalloc_obj(*vdev);
if (!vdev)
return ERR_PTR(-ENOMEM);
vdev->dev = dev;
vdev->viommu = viommu;
INIT_LIST_HEAD(&vdev->resv_regions);
dev_iommu_priv_set(dev, vdev);
if (viommu->probe_size) {
/* Get additional information for this endpoint */
ret = viommu_probe_endpoint(viommu, dev);
if (ret)
goto err_free_dev;
}
return &viommu->iommu;
err_free_dev:
iommu_put_resv_regions(dev, &vdev->resv_regions);
kfree(vdev);
return ERR_PTR(ret);
}
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);
}
static struct iommu_group *viommu_device_group(struct device *dev)
{
if (dev_is_pci(dev))
return pci_device_group(dev);
else
return generic_device_group(dev);
}
static int viommu_of_xlate(struct device *dev,
const struct of_phandle_args *args)
{
return iommu_fwspec_add_ids(dev, args->args, 1);
}
static bool viommu_capable(struct device *dev, enum iommu_cap cap)
{
switch (cap) {
case IOMMU_CAP_CACHE_COHERENCY:
return true;
case IOMMU_CAP_DEFERRED_FLUSH:
return true;
default:
return false;
}
}
static const struct iommu_ops viommu_ops = {
.capable = viommu_capable,
Annotation
- Immediate include surface: `linux/delay.h`, `linux/dma-map-ops.h`, `linux/freezer.h`, `linux/interval_tree.h`, `linux/iommu.h`, `linux/module.h`, `linux/of.h`, `linux/pci.h`.
- Detected declarations: `struct viommu_dev`, `struct viommu_mapping`, `struct viommu_domain`, `struct viommu_endpoint`, `struct viommu_request`, `struct viommu_event`, `function viommu_get_req_errno`, `function viommu_set_req_status`, `function viommu_get_write_desc_offset`, `function __viommu_sync_req`.
- Atlas domain: Driver Families / drivers/iommu.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.