drivers/iommu/amd/ppr.c
Source file repositories/reference/linux-study-clean/drivers/iommu/amd/ppr.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iommu/amd/ppr.c- Extension
.c- Size
- 7052 bytes
- Lines
- 276
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/amd-iommu.hlinux/delay.hlinux/mmu_notifier.hasm/iommu.hamd_iommu.hamd_iommu_types.h../iommu-pages.h
Detected Declarations
function Copyrightfunction amd_iommu_enable_ppr_logfunction amd_iommu_free_ppr_logfunction amd_iommu_restart_ppr_logfunction ppr_flag_to_fault_permfunction ppr_is_validfunction iommu_call_iopf_notifierfunction amd_iommu_poll_ppr_logfunction amd_iommu_iopf_initfunction amd_iommu_iopf_uninitfunction amd_iommu_page_responsefunction amd_iommu_iopf_add_devicefunction amd_iommu_iopf_remove_device
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2023 Advanced Micro Devices, Inc.
*/
#define pr_fmt(fmt) "AMD-Vi: " fmt
#define dev_fmt(fmt) pr_fmt(fmt)
#include <linux/amd-iommu.h>
#include <linux/delay.h>
#include <linux/mmu_notifier.h>
#include <asm/iommu.h>
#include "amd_iommu.h"
#include "amd_iommu_types.h"
#include "../iommu-pages.h"
int __init amd_iommu_alloc_ppr_log(struct amd_iommu *iommu)
{
iommu->ppr_log = iommu_alloc_4k_pages(iommu, GFP_KERNEL | __GFP_ZERO,
amd_iommu_pprlog_size);
return iommu->ppr_log ? 0 : -ENOMEM;
}
void amd_iommu_enable_ppr_log(struct amd_iommu *iommu)
{
u64 entry;
if (iommu->ppr_log == NULL)
return;
iommu_feature_enable(iommu, CONTROL_PPR_EN);
entry = iommu_virt_to_phys(iommu->ppr_log);
entry |= (amd_iommu_pprlog_size == PPRLOG_SIZE_DEF) ?
PPRLOG_LEN_MASK_DEF : PPRLOG_LEN_MASK_MAX;
memcpy_toio(iommu->mmio_base + MMIO_PPR_LOG_OFFSET,
&entry, sizeof(entry));
/* set head and tail to zero manually */
writel(0x00, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
writel(0x00, iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);
iommu_feature_enable(iommu, CONTROL_PPRINT_EN);
iommu_feature_enable(iommu, CONTROL_PPRLOG_EN);
}
void __init amd_iommu_free_ppr_log(struct amd_iommu *iommu)
{
iommu_free_pages(iommu->ppr_log);
}
/*
* This function restarts ppr logging in case the IOMMU experienced
* PPR log overflow.
*/
void amd_iommu_restart_ppr_log(struct amd_iommu *iommu)
{
amd_iommu_restart_log(iommu, "PPR", CONTROL_PPRINT_EN,
CONTROL_PPRLOG_EN, MMIO_STATUS_PPR_RUN_MASK,
MMIO_STATUS_PPR_OVERFLOW_MASK);
}
static inline u32 ppr_flag_to_fault_perm(u16 flag)
{
int perm = 0;
if (flag & PPR_FLAG_READ)
perm |= IOMMU_FAULT_PERM_READ;
if (flag & PPR_FLAG_WRITE)
perm |= IOMMU_FAULT_PERM_WRITE;
if (flag & PPR_FLAG_EXEC)
perm |= IOMMU_FAULT_PERM_EXEC;
if (!(flag & PPR_FLAG_US))
perm |= IOMMU_FAULT_PERM_PRIV;
return perm;
}
static bool ppr_is_valid(struct amd_iommu *iommu, u64 *raw)
{
struct device *dev = iommu->iommu.dev;
u16 devid = PPR_DEVID(raw[0]);
if (!(PPR_FLAGS(raw[0]) & PPR_FLAG_GN)) {
dev_dbg(dev, "PPR logged [Request ignored due to GN=0 (device=%04x:%02x:%02x.%x "
"pasid=0x%05llx address=0x%llx flags=0x%04llx tag=0x%03llx]\n",
Annotation
- Immediate include surface: `linux/amd-iommu.h`, `linux/delay.h`, `linux/mmu_notifier.h`, `asm/iommu.h`, `amd_iommu.h`, `amd_iommu_types.h`, `../iommu-pages.h`.
- Detected declarations: `function Copyright`, `function amd_iommu_enable_ppr_log`, `function amd_iommu_free_ppr_log`, `function amd_iommu_restart_ppr_log`, `function ppr_flag_to_fault_perm`, `function ppr_is_valid`, `function iommu_call_iopf_notifier`, `function amd_iommu_poll_ppr_log`, `function amd_iommu_iopf_init`, `function amd_iommu_iopf_uninit`.
- Atlas domain: Driver Families / drivers/iommu.
- Implementation status: source implementation candidate.
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.