xref: /aosp_15_r20/external/coreboot/src/arch/x86/null_breakpoint.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/breakpoint.h>
4 #include <arch/null_breakpoint.h>
5 #include <bootstate.h>
6 #include <console/console.h>
7 #include <types.h>
8 
9 static struct breakpoint_handle null_deref_bp;
10 static struct breakpoint_handle null_fetch_bp;
11 
handle_fetch_breakpoint(struct breakpoint_handle handle,struct eregs * regs)12 static int handle_fetch_breakpoint(struct breakpoint_handle handle, struct eregs *regs)
13 {
14 	printk(BIOS_ERR, "Instruction fetch from address zero\n");
15 	return CONFIG(DEBUG_NULL_DEREF_HALT);
16 }
17 
handle_deref_breakpoint(struct breakpoint_handle handle,struct eregs * regs)18 static int handle_deref_breakpoint(struct breakpoint_handle handle, struct eregs *regs)
19 {
20 #if ENV_X86_64
21 	printk(BIOS_ERR, "Null dereference at rip: 0x%llx\n", regs->rip);
22 #else
23 	printk(BIOS_ERR, "Null dereference at eip: 0x%x\n", regs->eip);
24 #endif
25 	return CONFIG(DEBUG_NULL_DEREF_HALT);
26 }
27 
create_deref_breakpoint(void)28 static void create_deref_breakpoint(void)
29 {
30 	enum breakpoint_result res =
31 		breakpoint_create_data(&null_deref_bp, NULL, sizeof(uintptr_t), false);
32 
33 	if (res != BREAKPOINT_RES_OK) {
34 		printk(BIOS_ERR, "Failed to create NULL dereference breakpoint\n");
35 		return;
36 	}
37 
38 	breakpoint_set_handler(null_deref_bp, &handle_deref_breakpoint);
39 	breakpoint_enable(null_deref_bp, true);
40 }
41 
create_instruction_breakpoint(void)42 static void create_instruction_breakpoint(void)
43 {
44 	enum breakpoint_result res = breakpoint_create_instruction(&null_fetch_bp, NULL);
45 
46 	if (res != BREAKPOINT_RES_OK) {
47 		printk(BIOS_ERR, "Failed to create address zero instruction fetch breakpoint\n");
48 		return;
49 	}
50 
51 	breakpoint_set_handler(null_fetch_bp, &handle_fetch_breakpoint);
52 	breakpoint_enable(null_fetch_bp, true);
53 }
54 
null_breakpoint_init(void)55 void null_breakpoint_init(void)
56 {
57 	create_deref_breakpoint();
58 	create_instruction_breakpoint();
59 }
60 
null_breakpoint_disable(void)61 void null_breakpoint_disable(void)
62 {
63 	breakpoint_remove(null_fetch_bp);
64 	breakpoint_remove(null_deref_bp);
65 }
66 
null_breakpoint_disable_hook(void * unused)67 static void null_breakpoint_disable_hook(void *unused)
68 {
69 	null_breakpoint_disable();
70 }
71 
72 BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, null_breakpoint_disable_hook, NULL);
73 BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, null_breakpoint_disable_hook, NULL);
74