arch/arm64/kernel/debug-monitors.c

Source file repositories/reference/linux-study-clean/arch/arm64/kernel/debug-monitors.c

File Facts

System
Linux kernel
Corpus path
arch/arm64/kernel/debug-monitors.c
Extension
.c
Size
9631 bytes
Lines
396
Domain
Architecture Layer
Bucket
arch/arm64
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (thumb_instr == AARCH32_BREAK_THUMB2_LO) {
			/* get second half of 32-bit Thumb-2 instruction */
			get_user(instr, (__le16 __user *)(pc + 2));
			thumb_instr = le16_to_cpu(instr);
			bp = thumb_instr == AARCH32_BREAK_THUMB2_HI;
		} else {
			bp = thumb_instr == AARCH32_BREAK_THUMB;
		}
	} else {
		/* 32-bit ARM instruction */
		__le32 instr;
		get_user(instr, (__le32 __user *)pc);
		arm_instr = le32_to_cpu(instr);
		bp = (arm_instr & ~0xf0000000) == AARCH32_BREAK_ARM;
	}

	if (!bp)
		return false;

	send_user_sigtrap(TRAP_BRKPT);
	return true;
}
NOKPROBE_SYMBOL(try_handle_aarch32_break);

/* Re-enable single step for syscall restarting. */
void user_rewind_single_step(struct task_struct *task)
{
	/*
	 * If single step is active for this thread, then set SPSR.SS
	 * to 1 to avoid returning to the active-pending state.
	 */
	if (test_tsk_thread_flag(task, TIF_SINGLESTEP))
		set_regs_spsr_ss(task_pt_regs(task));
}
NOKPROBE_SYMBOL(user_rewind_single_step);

void user_fastforward_single_step(struct task_struct *task)
{
	if (test_tsk_thread_flag(task, TIF_SINGLESTEP))
		clear_regs_spsr_ss(task_pt_regs(task));
}

void user_regs_reset_single_step(struct user_pt_regs *regs,
				 struct task_struct *task)
{
	if (test_tsk_thread_flag(task, TIF_SINGLESTEP))
		set_user_regs_spsr_ss(regs);
	else
		clear_user_regs_spsr_ss(regs);
}

/* Kernel API */
void kernel_enable_single_step(struct pt_regs *regs)
{
	WARN_ON(!irqs_disabled());
	set_regs_spsr_ss(regs);
	mdscr_write(mdscr_read() | MDSCR_EL1_SS);
	enable_debug_monitors(DBG_ACTIVE_EL1);
}
NOKPROBE_SYMBOL(kernel_enable_single_step);

void kernel_disable_single_step(void)
{
	WARN_ON(!irqs_disabled());
	mdscr_write(mdscr_read() & ~MDSCR_EL1_SS);
	disable_debug_monitors(DBG_ACTIVE_EL1);
}
NOKPROBE_SYMBOL(kernel_disable_single_step);

int kernel_active_single_step(void)
{
	WARN_ON(!irqs_disabled());
	return mdscr_read() & MDSCR_EL1_SS;
}
NOKPROBE_SYMBOL(kernel_active_single_step);

void kernel_rewind_single_step(struct pt_regs *regs)
{
	set_regs_spsr_ss(regs);
}

void kernel_fastforward_single_step(struct pt_regs *regs)
{
	clear_regs_spsr_ss(regs);
}

/* ptrace API */
void user_enable_single_step(struct task_struct *task)
{
	struct thread_info *ti = task_thread_info(task);

Annotation

Implementation Notes