arch/parisc/kernel/unwind.c
Source file repositories/reference/linux-study-clean/arch/parisc/kernel/unwind.c
File Facts
- System
- Linux kernel
- Corpus path
arch/parisc/kernel/unwind.c- Extension
.c- Size
- 12953 bytes
- Lines
- 497
- Domain
- Architecture Layer
- Bucket
- arch/parisc
- 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.
- 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/kernel.hlinux/init.hlinux/sched.hlinux/slab.hlinux/sort.hlinux/sched/task_stack.hlinux/uaccess.hasm/assembly.hasm/asm-offsets.hasm/ptrace.hasm/unwind.hasm/switch_to.hasm/sections.hasm/ftrace.h
Detected Declarations
function find_unwind_entry_in_tablefunction find_unwind_entryfunction list_for_each_entryfunction unwind_table_initfunction cmp_unwind_table_entryfunction unwind_table_sortfunction unwind_table_addfunction unwind_table_removefunction unwind_initfunction pc_is_kernel_fnfunction unwind_specialfunction unwind_frame_regsfunction unwind_frame_initfunction unwind_frame_init_from_blocked_taskfunction unwind_frame_init_taskfunction unwind_oncefunction unwind_to_userfunction return_address
Annotated Snippet
list_for_each_entry(table, &unwind_tables, list) {
if (addr >= table->start &&
addr <= table->end)
e = find_unwind_entry_in_table(table, addr);
if (e) {
/* Move-to-front to exploit common traces */
list_move(&table->list, &unwind_tables);
break;
}
}
spin_unlock_irqrestore(&unwind_lock, flags);
}
return e;
}
static void
unwind_table_init(struct unwind_table *table, const char *name,
unsigned long base_addr, unsigned long gp,
void *table_start, void *table_end)
{
struct unwind_table_entry *start = table_start;
struct unwind_table_entry *end =
(struct unwind_table_entry *)table_end - 1;
table->name = name;
table->base_addr = base_addr;
table->gp = gp;
table->start = base_addr + start->region_start;
table->end = base_addr + end->region_end;
table->table = (struct unwind_table_entry *)table_start;
table->length = end - start + 1;
INIT_LIST_HEAD(&table->list);
for (; start <= end; start++) {
if (start < end &&
start->region_end > (start+1)->region_start) {
pr_warn("Out of order unwind entry! %px and %px\n",
start, start+1);
}
start->region_start += base_addr;
start->region_end += base_addr;
}
}
static int cmp_unwind_table_entry(const void *a, const void *b)
{
return ((const struct unwind_table_entry *)a)->region_start
- ((const struct unwind_table_entry *)b)->region_start;
}
static void
unwind_table_sort(struct unwind_table_entry *start,
struct unwind_table_entry *finish)
{
sort(start, finish - start, sizeof(struct unwind_table_entry),
cmp_unwind_table_entry, NULL);
}
struct unwind_table *
unwind_table_add(const char *name, unsigned long base_addr,
unsigned long gp,
void *start, void *end)
{
struct unwind_table *table;
unsigned long flags;
struct unwind_table_entry *s = (struct unwind_table_entry *)start;
struct unwind_table_entry *e = (struct unwind_table_entry *)end;
unwind_table_sort(s, e);
table = kmalloc_obj(struct unwind_table, GFP_USER);
if (table == NULL)
return NULL;
unwind_table_init(table, name, base_addr, gp, start, end);
spin_lock_irqsave(&unwind_lock, flags);
list_add_tail(&table->list, &unwind_tables);
spin_unlock_irqrestore(&unwind_lock, flags);
return table;
}
void unwind_table_remove(struct unwind_table *table)
{
unsigned long flags;
spin_lock_irqsave(&unwind_lock, flags);
list_del(&table->list);
spin_unlock_irqrestore(&unwind_lock, flags);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/init.h`, `linux/sched.h`, `linux/slab.h`, `linux/sort.h`, `linux/sched/task_stack.h`, `linux/uaccess.h`, `asm/assembly.h`.
- Detected declarations: `function find_unwind_entry_in_table`, `function find_unwind_entry`, `function list_for_each_entry`, `function unwind_table_init`, `function cmp_unwind_table_entry`, `function unwind_table_sort`, `function unwind_table_add`, `function unwind_table_remove`, `function unwind_init`, `function pc_is_kernel_fn`.
- Atlas domain: Architecture Layer / arch/parisc.
- Implementation status: source 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.