arch/arm/mm/ioremap.c
Source file repositories/reference/linux-study-clean/arch/arm/mm/ioremap.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm/mm/ioremap.c- Extension
.c- Size
- 13310 bytes
- Lines
- 520
- Domain
- Architecture Layer
- Bucket
- arch/arm
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- 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.
- 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/module.hlinux/errno.hlinux/kasan.hlinux/mm.hlinux/vmalloc.hlinux/io.hlinux/sizes.hlinux/memblock.hasm/cp15.hasm/cputype.hasm/cacheflush.hasm/early_ioremap.hasm/mmu_context.hasm/pgalloc.hasm/tlbflush.hasm/set_memory.hasm/system_info.hasm/mach/map.hasm/mach/pci.hmm.h
Detected Declarations
function list_for_each_entryfunction list_for_each_entryfunction add_static_vm_earlyfunction list_for_each_entryfunction ioremap_pagefunction arm_kasan_mem_to_shadowfunction arm_kasan_mem_to_shadowfunction memcpy_pgdfunction __check_vmalloc_seqfunction get_vm_area_callerfunction remap_area_sectionsfunction remap_area_supersectionsfunction __arm_ioremap_pfn_callerfunction cpu_is_xsc3function __arm_ioremap_pfnfunction __arm_ioremap_execfunction __arm_iomem_set_rofunction iounmapfunction pci_ioremap_set_mem_typefunction pci_remap_iospacefunction early_ioremap_initfunction arch_memremap_can_ram_remapexport ioremap_pageexport __arm_ioremap_pfnexport ioremapexport ioremap_cacheexport ioremap_wcexport iounmapexport pci_remap_iospaceexport pci_remap_cfgspace
Annotated Snippet
if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) {
unsigned long start =
arm_kasan_mem_to_shadow(VMALLOC_START);
unsigned long end =
arm_kasan_mem_to_shadow(VMALLOC_END);
memcpy_pgd(mm, start, end);
}
/*
* Use a store-release so that other CPUs that observe the
* counter's new value are guaranteed to see the results of the
* memcpy as well.
*/
atomic_set_release(&mm->context.vmalloc_seq, seq);
} while (seq != atomic_read(&init_mm.context.vmalloc_seq));
}
#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
/*
* Section support is unsafe on SMP - If you iounmap and ioremap a region,
* the other CPUs will not see this change until their next context switch.
* Meanwhile, (eg) if an interrupt comes in on one of those other CPUs
* which requires the new ioremap'd region to be referenced, the CPU will
* reference the _old_ region.
*
* Note that get_vm_area_caller() allocates a guard 4K page, so we need to
* mask the size back to 1MB aligned or we will overflow in the loop below.
*/
static void unmap_area_sections(unsigned long virt, unsigned long size)
{
unsigned long addr = virt, end = virt + (size & ~(SZ_1M - 1));
pmd_t *pmdp = pmd_off_k(addr);
do {
pmd_t pmd = *pmdp;
if (!pmd_none(pmd)) {
/*
* Clear the PMD from the page table, and
* increment the vmalloc sequence so others
* notice this change.
*
* Note: this is still racy on SMP machines.
*/
pmd_clear(pmdp);
atomic_inc_return_release(&init_mm.context.vmalloc_seq);
/*
* Free the page table, if there was one.
*/
if ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_TABLE)
pte_free_kernel(&init_mm, pmd_page_vaddr(pmd));
}
addr += PMD_SIZE;
pmdp += 2;
} while (addr < end);
/*
* Ensure that the active_mm is up to date - we want to
* catch any use-after-iounmap cases.
*/
check_vmalloc_seq(current->active_mm);
flush_tlb_kernel_range(virt, end);
}
static int
remap_area_sections(unsigned long virt, unsigned long pfn,
size_t size, const struct mem_type *type)
{
unsigned long addr = virt, end = virt + size;
pmd_t *pmd = pmd_off_k(addr);
/*
* Remove and free any PTE-based mapping, and
* sync the current kernel mapping.
*/
unmap_area_sections(virt, size);
do {
pmd[0] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
pfn += SZ_1M >> PAGE_SHIFT;
pmd[1] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
pfn += SZ_1M >> PAGE_SHIFT;
flush_pmd_entry(pmd);
addr += PMD_SIZE;
pmd += 2;
} while (addr < end);
Annotation
- Immediate include surface: `linux/module.h`, `linux/errno.h`, `linux/kasan.h`, `linux/mm.h`, `linux/vmalloc.h`, `linux/io.h`, `linux/sizes.h`, `linux/memblock.h`.
- Detected declarations: `function list_for_each_entry`, `function list_for_each_entry`, `function add_static_vm_early`, `function list_for_each_entry`, `function ioremap_page`, `function arm_kasan_mem_to_shadow`, `function arm_kasan_mem_to_shadow`, `function memcpy_pgd`, `function __check_vmalloc_seq`, `function get_vm_area_caller`.
- Atlas domain: Architecture Layer / arch/arm.
- Implementation status: integration implementation candidate.
- 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.