blob: 43e37274485300c561e3a98b6b74c5c653a69810 [file] [log] [blame]
Robert Zieba3f01cd12022-04-14 10:36:15 -06001/* SPDX-License-Identifier: GPL-2.0-only */
Elyes Haouasae1ca822022-10-07 10:02:38 +02002
Robert Zieba3f01cd12022-04-14 10:36:15 -06003#include <arch/breakpoint.h>
4#include <arch/null_breakpoint.h>
Arthur Heymans6fc12542022-05-14 10:40:24 +02005#include <bootstate.h>
Robert Zieba3f01cd12022-04-14 10:36:15 -06006#include <console/console.h>
Elyes Haouasae1ca822022-10-07 10:02:38 +02007#include <types.h>
Robert Zieba3f01cd12022-04-14 10:36:15 -06008
9static struct breakpoint_handle null_deref_bp;
10static struct breakpoint_handle null_fetch_bp;
11
12static 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
18static int handle_deref_breakpoint(struct breakpoint_handle handle, struct eregs *regs)
19{
20#if ENV_X86_64
Paul Menzel7151e0e2022-05-30 12:08:31 +020021 printk(BIOS_ERR, "Null dereference at rip: 0x%llx\n", regs->rip);
Robert Zieba3f01cd12022-04-14 10:36:15 -060022#else
Paul Menzel7151e0e2022-05-30 12:08:31 +020023 printk(BIOS_ERR, "Null dereference at eip: 0x%x\n", regs->eip);
Robert Zieba3f01cd12022-04-14 10:36:15 -060024#endif
25 return CONFIG(DEBUG_NULL_DEREF_HALT);
26}
27
28static 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
42static 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
55void null_breakpoint_init(void)
56{
57 create_deref_breakpoint();
58 create_instruction_breakpoint();
59}
Arthur Heymans6fc12542022-05-14 10:40:24 +020060
Arthur Heymansfdf6d122022-05-17 13:07:30 +020061void null_breakpoint_disable(void)
Arthur Heymans6fc12542022-05-14 10:40:24 +020062{
63 breakpoint_remove(null_fetch_bp);
64 breakpoint_remove(null_deref_bp);
65}
66
Arthur Heymansfdf6d122022-05-17 13:07:30 +020067static void null_breakpoint_disable_hook(void *unused)
68{
69 null_breakpoint_disable();
70}
71
72BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, null_breakpoint_disable_hook, NULL);
73BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, null_breakpoint_disable_hook, NULL);