summaryrefslogtreecommitdiff
path: root/src/arch/x86/include
diff options
context:
space:
mode:
authorRobert Zieba <robertzieba@google.com>2022-04-14 10:36:15 -0600
committerNick Vaccaro <nvaccaro@google.com>2022-05-12 15:47:18 +0000
commit3f01cd14533f12f04a87a9cf1111dd948094bac4 (patch)
treee1ef98e60c0f91fd59fc14f3983525d21c62760a /src/arch/x86/include
parent4be0f4bf9943f5f6c84d1c13dee70b7442f99bd0 (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.h58
-rw-r--r--src/arch/x86/include/arch/null_breakpoint.h16
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_ */