arch/powerpc/mm/fault.c
Source file repositories/reference/linux-study-clean/arch/powerpc/mm/fault.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/mm/fault.c- Extension
.c- Size
- 20044 bytes
- Lines
- 698
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- Inferred role
- Architecture Layer: implementation source
- Status
- source 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/signal.hlinux/sched.hlinux/sched/task_stack.hlinux/kernel.hlinux/errno.hlinux/string.hlinux/string_choices.hlinux/types.hlinux/pagemap.hlinux/ptrace.hlinux/mman.hlinux/mm.hlinux/interrupt.hlinux/highmem.hlinux/extable.hlinux/kprobes.hlinux/kdebug.hlinux/perf_event.hlinux/ratelimit.hlinux/context_tracking.hlinux/hugetlb.hlinux/uaccess.hlinux/kfence.hlinux/pkeys.hasm/firmware.hasm/interrupt.hasm/page.hasm/mmu.hasm/mmu_context.hasm/siginfo.hasm/debug.hasm/kup.h
Detected Declarations
function Copyrightfunction bad_area_nosemaphorefunction __bad_areafunction bad_access_pkeyfunction bad_accessfunction do_sigbusfunction mm_fault_errorfunction bad_kernel_faultfunction access_pkey_errorfunction access_errorfunction cmo_account_page_faultfunction cmo_account_page_faultfunction page_fault_is_badfunction ___do_page_faultfunction copy_from_kernel_nofaultfunction __do_page_faultfunction hash__do_page_faultfunction __bad_page_faultfunction bad_page_fault
Annotated Snippet
* fault path, handle_mm_fault() also does the same check. To avoid
* these multiple checks, we skip it here and handle access error due
* to pkeys later.
*/
return false;
}
#ifdef CONFIG_PPC_SMLPAR
static inline void cmo_account_page_fault(void)
{
if (firmware_has_feature(FW_FEATURE_CMO)) {
u32 page_ins;
preempt_disable();
page_ins = be32_to_cpu(get_lppaca()->page_ins);
page_ins += 1 << PAGE_FACTOR;
get_lppaca()->page_ins = cpu_to_be32(page_ins);
preempt_enable();
}
}
#else
static inline void cmo_account_page_fault(void) { }
#endif /* CONFIG_PPC_SMLPAR */
static void sanity_check_fault(bool is_write, bool is_user,
unsigned long error_code, unsigned long address)
{
/*
* Userspace trying to access kernel address, we get PROTFAULT for that.
*/
if (is_user && address >= TASK_SIZE) {
if ((long)address == -1)
return;
pr_crit_ratelimited("%s[%d]: User access of kernel address (%lx) - exploit attempt? (uid: %d)\n",
current->comm, current->pid, address,
from_kuid(&init_user_ns, current_uid()));
return;
}
if (!IS_ENABLED(CONFIG_PPC_BOOK3S))
return;
/*
* For hash translation mode, we should never get a
* PROTFAULT. Any update to pte to reduce access will result in us
* removing the hash page table entry, thus resulting in a DSISR_NOHPTE
* fault instead of DSISR_PROTFAULT.
*
* A pte update to relax the access will not result in a hash page table
* entry invalidate and hence can result in DSISR_PROTFAULT.
* ptep_set_access_flags() doesn't do a hpte flush. This is why we have
* the special !is_write in the below conditional.
*
* For platforms that doesn't supports coherent icache and do support
* per page noexec bit, we do setup things such that we do the
* sync between D/I cache via fault. But that is handled via low level
* hash fault code (hash_page_do_lazy_icache()) and we should not reach
* here in such case.
*
* For wrong access that can result in PROTFAULT, the above vma->vm_flags
* check should handle those and hence we should fall to the bad_area
* handling correctly.
*
* For embedded with per page exec support that doesn't support coherent
* icache we do get PROTFAULT and we handle that D/I cache sync in
* set_pte_at while taking the noexec/prot fault. Hence this is WARN_ON
* is conditional for server MMU.
*
* For radix, we can get prot fault for autonuma case, because radix
* page table will have them marked noaccess for user.
*/
if (radix_enabled() || is_write)
return;
WARN_ON_ONCE(error_code & DSISR_PROTFAULT);
}
/*
* Define the correct "is_write" bit in error_code based
* on the processor family
*/
#ifdef CONFIG_BOOKE
#define page_fault_is_write(__err) ((__err) & ESR_DST)
#else
#define page_fault_is_write(__err) ((__err) & DSISR_ISSTORE)
#endif
#ifdef CONFIG_BOOKE
#define page_fault_is_bad(__err) (0)
Annotation
- Immediate include surface: `linux/signal.h`, `linux/sched.h`, `linux/sched/task_stack.h`, `linux/kernel.h`, `linux/errno.h`, `linux/string.h`, `linux/string_choices.h`, `linux/types.h`.
- Detected declarations: `function Copyright`, `function bad_area_nosemaphore`, `function __bad_area`, `function bad_access_pkey`, `function bad_access`, `function do_sigbus`, `function mm_fault_error`, `function bad_kernel_fault`, `function access_pkey_error`, `function access_error`.
- Atlas domain: Architecture Layer / arch/powerpc.
- 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.