drivers/iommu/iommufd/pages.c
Source file repositories/reference/linux-study-clean/drivers/iommu/iommufd/pages.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iommu/iommufd/pages.c- Extension
.c- Size
- 69880 bytes
- Lines
- 2531
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/dma-buf.hlinux/dma-resv.hlinux/file.hlinux/highmem.hlinux/iommu.hlinux/iommufd.hlinux/kthread.hlinux/overflow.hlinux/slab.hlinux/sched/mm.hlinux/vfio_pci_core.hdouble_span.hio_pagetable.h
Detected Declarations
struct pfn_batchstruct pfn_reader_userstruct pfn_reader_dmabufstruct pfn_readerenum batch_kindfunction iommu_iova_to_physfunction interval_tree_double_span_iter_updatefunction interval_tree_double_span_iter_firstfunction interval_tree_double_span_iter_nextfunction iopt_pages_add_npinnedfunction iopt_pages_sub_npinnedfunction iopt_pages_err_unpinfunction iopt_area_index_to_iovafunction iopt_area_index_to_iova_lastfunction iommu_unmap_nofailfunction iopt_area_unmap_domain_rangefunction batch_clearfunction batch_clear_carryfunction batch_skip_carryfunction __batch_initfunction batch_initfunction batch_init_backupfunction batch_destroyfunction batch_add_pfn_numfunction batch_remove_pfn_numfunction batch_add_pfnfunction batch_from_domainfunction batch_from_domain_continuefunction batch_iommu_map_smallfunction batch_to_domainfunction batch_from_xarrayfunction batch_from_xarray_clearfunction clear_xarrayfunction pages_to_xarrayfunction batch_from_pagesfunction batch_from_foliosfunction batch_unpinfunction copy_data_pagefunction batch_rwfunction pfn_reader_user_initfunction pfn_reader_user_destroyfunction pin_memfd_pagesfunction pfn_reader_user_pinfunction incr_user_locked_vmfunction decr_user_locked_vmfunction update_mm_locked_vmfunction iopt_pages_update_pinnedfunction update_unpinned
Annotated Snippet
struct pfn_batch {
unsigned long *pfns;
u32 *npfns;
unsigned int array_size;
unsigned int end;
unsigned int total_pfns;
enum batch_kind kind;
};
enum { MAX_NPFNS = type_max(typeof(((struct pfn_batch *)0)->npfns[0])) };
static void batch_clear(struct pfn_batch *batch)
{
batch->total_pfns = 0;
batch->end = 0;
batch->pfns[0] = 0;
batch->npfns[0] = 0;
batch->kind = 0;
}
/*
* Carry means we carry a portion of the final hugepage over to the front of the
* batch
*/
static void batch_clear_carry(struct pfn_batch *batch, unsigned int keep_pfns)
{
if (!keep_pfns)
return batch_clear(batch);
if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
WARN_ON(!batch->end ||
batch->npfns[batch->end - 1] < keep_pfns);
batch->total_pfns = keep_pfns;
batch->pfns[0] = batch->pfns[batch->end - 1] +
(batch->npfns[batch->end - 1] - keep_pfns);
batch->npfns[0] = keep_pfns;
batch->end = 1;
}
static void batch_skip_carry(struct pfn_batch *batch, unsigned int skip_pfns)
{
if (!batch->total_pfns)
return;
if (IS_ENABLED(CONFIG_IOMMUFD_TEST))
WARN_ON(batch->total_pfns != batch->npfns[0]);
skip_pfns = min(batch->total_pfns, skip_pfns);
batch->pfns[0] += skip_pfns;
batch->npfns[0] -= skip_pfns;
batch->total_pfns -= skip_pfns;
}
static int __batch_init(struct pfn_batch *batch, size_t max_pages, void *backup,
size_t backup_len)
{
const size_t elmsz = sizeof(*batch->pfns) + sizeof(*batch->npfns);
size_t size = max_pages * elmsz;
batch->pfns = temp_kmalloc(&size, backup, backup_len);
if (!batch->pfns)
return -ENOMEM;
if (IS_ENABLED(CONFIG_IOMMUFD_TEST) && WARN_ON(size < elmsz))
return -EINVAL;
batch->array_size = size / elmsz;
batch->npfns = (u32 *)(batch->pfns + batch->array_size);
batch_clear(batch);
return 0;
}
static int batch_init(struct pfn_batch *batch, size_t max_pages)
{
return __batch_init(batch, max_pages, NULL, 0);
}
static void batch_init_backup(struct pfn_batch *batch, size_t max_pages,
void *backup, size_t backup_len)
{
__batch_init(batch, max_pages, backup, backup_len);
}
static void batch_destroy(struct pfn_batch *batch, void *backup)
{
if (batch->pfns != backup)
kfree(batch->pfns);
}
static bool batch_add_pfn_num(struct pfn_batch *batch, unsigned long pfn,
u32 nr, enum batch_kind kind)
{
unsigned int end = batch->end;
Annotation
- Immediate include surface: `linux/dma-buf.h`, `linux/dma-resv.h`, `linux/file.h`, `linux/highmem.h`, `linux/iommu.h`, `linux/iommufd.h`, `linux/kthread.h`, `linux/overflow.h`.
- Detected declarations: `struct pfn_batch`, `struct pfn_reader_user`, `struct pfn_reader_dmabuf`, `struct pfn_reader`, `enum batch_kind`, `function iommu_iova_to_phys`, `function interval_tree_double_span_iter_update`, `function interval_tree_double_span_iter_first`, `function interval_tree_double_span_iter_next`, `function iopt_pages_add_npinned`.
- 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.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.