drivers/iommu/amd/iommu.c
Source file repositories/reference/linux-study-clean/drivers/iommu/amd/iommu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iommu/amd/iommu.c- Extension
.c- Size
- 110257 bytes
- Lines
- 4198
- Domain
- Driver Families
- Bucket
- drivers/iommu
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/ratelimit.hlinux/pci.hlinux/acpi.hlinux/pci-ats.hlinux/bitmap.hlinux/slab.hlinux/string_choices.hlinux/debugfs.hlinux/scatterlist.hlinux/dma-map-ops.hlinux/dma-direct.hlinux/idr.hlinux/iommu-helper.hlinux/delay.hlinux/amd-iommu.hlinux/notifier.hlinux/export.hlinux/irq.hlinux/irqchip/irq-msi-lib.hlinux/msi.hlinux/irqdomain.hlinux/percpu.hlinux/cc_platform.hasm/irq_remapping.hasm/io_apic.hasm/apic.hasm/hw_irq.hasm/proto.hasm/iommu.hasm/gart.hasm/dma.huapi/linux/iommufd.h
Detected Declarations
function amd_iommu_atomic128_setfunction write_dte_upper128function write_dte_lower128function update_dte256function FIELD_GETfunction amd_iommu_update_dtefunction get_dte256function pdom_is_v2_pgtbl_modefunction pdom_is_in_pt_modefunction pdom_is_sva_capablefunction get_acpihid_device_idfunction list_for_each_entryfunction get_device_sbdf_idfunction get_device_segmentfunction amd_iommu_set_rlookup_tablefunction for_each_pci_segmentfunction clone_aliasfunction clone_aliasesfunction setup_aliasesfunction list_for_each_entryfunction pdev_pasid_supportedfunction pdev_get_capsfunction pdev_enable_cap_atsfunction pdev_disable_cap_atsfunction pdev_enable_cap_prifunction pdev_disable_cap_prifunction pdev_enable_cap_pasidfunction pdev_disable_cap_pasidfunction pdev_enable_capsfunction pdev_disable_capsfunction check_devicefunction iommu_init_devicefunction dev_is_pcifunction iommu_ignore_devicefunction dump_dte_entryfunction dump_commandfunction amd_iommu_report_rmp_hw_errorfunction amd_iommu_report_rmp_faultfunction amd_iommu_report_page_faultfunction iommu_print_eventfunction iommu_poll_eventsfunction amd_iommu_register_ga_log_notifierfunction iommu_poll_ga_logfunction amd_iommu_set_pci_msi_domainfunction amd_iommu_set_pci_msi_domainfunction amd_iommu_int_thread_evtlogfunction amd_iommu_int_thread_pprlogfunction amd_iommu_int_thread_galog
Annotated Snippet
FIELD_GET(DTE_GPT_LEVEL_MASK, new->data[2])) {
/*
* Both DTEs are valid and have guest page table,
* but have different number of levels. So, we need
* to upadte both upper and lower 128-bit value, which
* require disabling and flushing.
*/
struct dev_table_entry clear = {};
/* First disable DTE */
write_dte_lower128(ptr, &clear);
iommu_flush_dte_sync(iommu, dev_data->devid);
/* Then update DTE */
write_dte_upper128(ptr, new);
write_dte_lower128(ptr, new);
iommu_flush_dte_sync(iommu, dev_data->devid);
} else {
/*
* Both DTEs are valid and have guest page table,
* and same number of levels. We just need to only
* update the lower 128-bit. So no need to disable DTE.
*/
write_dte_lower128(ptr, new);
}
spin_unlock_irqrestore(&dev_data->dte_lock, flags);
}
void amd_iommu_update_dte(struct amd_iommu *iommu,
struct iommu_dev_data *dev_data,
struct dev_table_entry *new)
{
update_dte256(iommu, dev_data, new);
clone_aliases(iommu, dev_data->dev);
device_flush_dte(dev_data);
iommu_completion_wait(iommu);
}
static void get_dte256(struct amd_iommu *iommu, struct iommu_dev_data *dev_data,
struct dev_table_entry *dte)
{
unsigned long flags;
struct dev_table_entry *ptr;
struct dev_table_entry *dev_table = get_dev_table(iommu);
ptr = &dev_table[dev_data->devid];
spin_lock_irqsave(&dev_data->dte_lock, flags);
dte->data128[0] = ptr->data128[0];
dte->data128[1] = ptr->data128[1];
spin_unlock_irqrestore(&dev_data->dte_lock, flags);
}
static inline bool pdom_is_v2_pgtbl_mode(struct protection_domain *pdom)
{
return (pdom && (pdom->pd_mode == PD_MODE_V2));
}
static inline bool pdom_is_in_pt_mode(struct protection_domain *pdom)
{
return (pdom->domain.type == IOMMU_DOMAIN_IDENTITY);
}
/*
* We cannot support PASID w/ existing v1 page table in the same domain
* since it will be nested. However, existing domain w/ v2 page table
* or passthrough mode can be used for PASID.
*/
static inline bool pdom_is_sva_capable(struct protection_domain *pdom)
{
return pdom_is_v2_pgtbl_mode(pdom) || pdom_is_in_pt_mode(pdom);
}
static inline int get_acpihid_device_id(struct device *dev,
struct acpihid_map_entry **entry)
{
struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpihid_map_entry *p, *p1 = NULL;
int hid_count = 0;
bool fw_bug;
if (!adev)
return -ENODEV;
list_for_each_entry(p, &acpihid_map, list) {
if (acpi_dev_hid_uid_match(adev, p->hid,
p->uid[0] ? p->uid : NULL)) {
p1 = p;
fw_bug = false;
Annotation
- Immediate include surface: `linux/ratelimit.h`, `linux/pci.h`, `linux/acpi.h`, `linux/pci-ats.h`, `linux/bitmap.h`, `linux/slab.h`, `linux/string_choices.h`, `linux/debugfs.h`.
- Detected declarations: `function amd_iommu_atomic128_set`, `function write_dte_upper128`, `function write_dte_lower128`, `function update_dte256`, `function FIELD_GET`, `function amd_iommu_update_dte`, `function get_dte256`, `function pdom_is_v2_pgtbl_mode`, `function pdom_is_in_pt_mode`, `function pdom_is_sva_capable`.
- Atlas domain: Driver Families / drivers/iommu.
- Implementation status: integration 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.