drivers/iommu/iommufd/ioas.c
Source file repositories/reference/linux-study-clean/drivers/iommu/iommufd/ioas.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iommu/iommufd/ioas.c- Extension
.c- Size
- 16402 bytes
- Lines
- 664
- Domain
- Driver Families
- Bucket
- drivers/iommu
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/file.hlinux/interval_tree.hlinux/iommu.hlinux/iommufd.huapi/linux/iommufd.hio_pagetable.h
Detected Declarations
function Copyrightfunction iommufd_ioas_alloc_ioctlfunction iommufd_ioas_iova_rangesfunction iommufd_ioas_load_iovasfunction iommufd_ioas_allow_iovasfunction conv_iommu_protfunction iommufd_ioas_map_filefunction iommufd_ioas_mapfunction iommufd_ioas_copyfunction iommufd_ioas_unmapfunction iommufd_release_all_iova_rwsemfunction xa_for_eachfunction iommufd_take_all_iova_rwsemfunction need_charge_updatefunction charge_currentfunction change_mmfunction iommufd_ioas_change_processfunction for_each_ioas_areafunction for_each_ioas_areafunction iommufd_option_rlimit_modefunction iommufd_ioas_option_huge_pagesfunction iommufd_ioas_option
Annotated Snippet
if (cmd->num_iovas < max_iovas) {
struct iommu_iova_range elm = {
.start = span.start_hole,
.last = span.last_hole,
};
if (copy_to_user(&ranges[cmd->num_iovas], &elm,
sizeof(elm))) {
rc = -EFAULT;
goto out_put;
}
}
cmd->num_iovas++;
}
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
if (rc)
goto out_put;
if (cmd->num_iovas > max_iovas)
rc = -EMSGSIZE;
out_put:
up_read(&ioas->iopt.iova_rwsem);
iommufd_put_object(ucmd->ictx, &ioas->obj);
return rc;
}
static int iommufd_ioas_load_iovas(struct rb_root_cached *itree,
struct iommu_iova_range __user *ranges,
u32 num)
{
u32 i;
for (i = 0; i != num; i++) {
struct iommu_iova_range range;
struct iopt_allowed *allowed;
if (copy_from_user(&range, ranges + i, sizeof(range)))
return -EFAULT;
if (range.start >= range.last)
return -EINVAL;
if (interval_tree_iter_first(itree, range.start, range.last))
return -EINVAL;
allowed = kzalloc_obj(*allowed, GFP_KERNEL_ACCOUNT);
if (!allowed)
return -ENOMEM;
allowed->node.start = range.start;
allowed->node.last = range.last;
interval_tree_insert(&allowed->node, itree);
}
return 0;
}
int iommufd_ioas_allow_iovas(struct iommufd_ucmd *ucmd)
{
struct iommu_ioas_allow_iovas *cmd = ucmd->cmd;
struct rb_root_cached allowed_iova = RB_ROOT_CACHED;
struct interval_tree_node *node;
struct iommufd_ioas *ioas;
struct io_pagetable *iopt;
int rc = 0;
if (cmd->__reserved)
return -EOPNOTSUPP;
ioas = iommufd_get_ioas(ucmd->ictx, cmd->ioas_id);
if (IS_ERR(ioas))
return PTR_ERR(ioas);
iopt = &ioas->iopt;
rc = iommufd_ioas_load_iovas(&allowed_iova,
u64_to_user_ptr(cmd->allowed_iovas),
cmd->num_iovas);
if (rc)
goto out_free;
/*
* We want the allowed tree update to be atomic, so we have to keep the
* original nodes around, and keep track of the new nodes as we allocate
* memory for them. The simplest solution is to have a new/old tree and
* then swap new for old. On success we free the old tree, on failure we
* free the new tree.
*/
rc = iopt_set_allow_iova(iopt, &allowed_iova);
out_free:
while ((node = interval_tree_iter_first(&allowed_iova, 0, ULONG_MAX))) {
interval_tree_remove(node, &allowed_iova);
kfree(container_of(node, struct iopt_allowed, node));
Annotation
- Immediate include surface: `linux/file.h`, `linux/interval_tree.h`, `linux/iommu.h`, `linux/iommufd.h`, `uapi/linux/iommufd.h`, `io_pagetable.h`.
- Detected declarations: `function Copyright`, `function iommufd_ioas_alloc_ioctl`, `function iommufd_ioas_iova_ranges`, `function iommufd_ioas_load_iovas`, `function iommufd_ioas_allow_iovas`, `function conv_iommu_prot`, `function iommufd_ioas_map_file`, `function iommufd_ioas_map`, `function iommufd_ioas_copy`, `function iommufd_ioas_unmap`.
- Atlas domain: Driver Families / drivers/iommu.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
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.