diff options
author | Robert Zieba <robertzieba@google.com> | 2022-04-14 10:36:15 -0600 |
---|---|---|
committer | Nick Vaccaro <nvaccaro@google.com> | 2022-05-12 15:47:18 +0000 |
commit | 3f01cd14533f12f04a87a9cf1111dd948094bac4 (patch) | |
tree | e1ef98e60c0f91fd59fc14f3983525d21c62760a /src/arch/x86/include | |
parent | 4be0f4bf9943f5f6c84d1c13dee70b7442f99bd0 (diff) |
arch/x86: Add support for catching null dereferences through debug regs
This commit adds support for catching null dereferences and execution
through x86's debug registers. This is particularly useful when running
32-bit coreboot as paging is not enabled to catch these through page
faults. This commit adds three new configs to support this feature:
DEBUG_HW_BREAKPOINTS, DEBUG_NULL_DEREF_BREAKPOINTS and
DEBUG_NULL_DEREF_HALT.
BUG=b:223902046
TEST=Ran on nipperkin device, verifying that HW breakpoints work as
expected.
Change-Id: I113590689046a13c2a552741bbfe7668a834354a
Signed-off-by: Robert Zieba <robertzieba@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/63657
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Diffstat (limited to 'src/arch/x86/include')
-rw-r--r-- | src/arch/x86/include/arch/breakpoint.h | 58 | ||||
-rw-r--r-- | src/arch/x86/include/arch/null_breakpoint.h | 16 |
2 files changed, 74 insertions, 0 deletions
diff --git a/src/arch/x86/include/arch/breakpoint.h b/src/arch/x86/include/arch/breakpoint.h new file mode 100644 index 0000000000..32e9f48d09 --- /dev/null +++ b/src/arch/x86/include/arch/breakpoint.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _BREAKPOINT_H_ +#define _BREAKPOINT_H_ + +#include <arch/registers.h> +#include <types.h> + +#if CONFIG(DEBUG_HW_BREAKPOINTS) && \ + (CONFIG(DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) || ENV_RAMSTAGE) +struct breakpoint_handle { + int bp; +}; + +typedef int (*breakpoint_handler)(struct breakpoint_handle, struct eregs *info); + +enum breakpoint_result { + BREAKPOINT_RES_OK = 0, + BREAKPOINT_RES_NONE_AVAILABLE = -1, + BREAKPOINT_RES_INVALID_HANDLE = -2, + BREAKPOINT_RES_INVALID_LENGTH = -3 +}; + +enum breakpoint_type { + BREAKPOINT_TYPE_INSTRUCTION = 0x0, + BREAKPOINT_TYPE_DATA_WRITE = 0x1, + BREAKPOINT_TYPE_IO = 0x2, + BREAKPOINT_TYPE_DATA_RW = 0x3, +}; + +/* Creates an instruction breakpoint at the given address. */ +enum breakpoint_result breakpoint_create_instruction(struct breakpoint_handle *out_handle, + void *virt_addr); +/* Creates a data breakpoint at the given address for len bytes. */ +enum breakpoint_result breakpoint_create_data(struct breakpoint_handle *out_handle, + void *virt_addr, size_t len, bool write_only); +/* Removes a given breakpoint. */ +enum breakpoint_result breakpoint_remove(struct breakpoint_handle handle); +/* Enables or disables a given breakpoint. */ +enum breakpoint_result breakpoint_enable(struct breakpoint_handle handle, bool enabled); +/* Returns the type of a breakpoint. */ +enum breakpoint_result breakpoint_get_type(struct breakpoint_handle handle, + enum breakpoint_type *type); +/* + * Sets a handler function to be called when the breakpoint is hit. The handler should return 0 + * to continue or any other value to halt execution as a fatal error. + */ +enum breakpoint_result breakpoint_set_handler(struct breakpoint_handle handle, + breakpoint_handler handler); +/* Called by x86_exception to dispatch breakpoint exceptions to the correct handler. */ +int breakpoint_dispatch_handler(struct eregs *info); +#else +static inline int breakpoint_dispatch_handler(struct eregs *info) +{ + /* Not implemented */ + return 0; +} +#endif +#endif /* _BREAKPOINT_H_ */ diff --git a/src/arch/x86/include/arch/null_breakpoint.h b/src/arch/x86/include/arch/null_breakpoint.h new file mode 100644 index 0000000000..bc86dc03e4 --- /dev/null +++ b/src/arch/x86/include/arch/null_breakpoint.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _NULL_BREAKPOINT_H_ +#define _NULL_BREAKPOINT_H_ + +#if CONFIG(DEBUG_NULL_DEREF_BREAKPOINTS) && \ + (CONFIG(DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) || ENV_RAMSTAGE) + +/* Places data and instructions breakpoints at address zero. */ +void null_breakpoint_init(void); +#else +static inline void null_breakpoint_init(void) +{ + /* Not implemented */ +} +#endif +#endif /* _NULL_BREAKPOINT_H_ */ |