Skip to content

Commit

Permalink
arch/x86: Add support for catching null dereferences through debug regs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
GRobertZieba authored and NickVaccaro committed May 12, 2022
1 parent 4be0f4b commit 3f01cd1
Show file tree
Hide file tree
Showing 7 changed files with 486 additions and 2 deletions.
32 changes: 32 additions & 0 deletions src/arch/x86/Kconfig
Expand Up @@ -320,6 +320,38 @@ config MEMLAYOUT_LD_FILE
string
default "src/arch/x86/memlayout.ld"

config DEBUG_HW_BREAKPOINTS
bool
default y
help
Enable support for hardware data and instruction breakpoints through
the x86 debug registers

config DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES
bool
default y
depends on DEBUG_HW_BREAKPOINTS && IDT_IN_EVERY_STAGE

config DEBUG_NULL_DEREF_BREAKPOINTS
bool
default y
depends on DEBUG_HW_BREAKPOINTS
help
Enable support for catching null dereferences and instruction execution

config DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES
bool
default y
depends on DEBUG_NULL_DEREF_BREAKPOINTS && DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES

config DEBUG_NULL_DEREF_HALT
bool
default n
depends on DEBUG_NULL_DEREF_BREAKPOINTS
help
When enabled null dereferences and instruction fetches will halt execution.
Otherwise an error will be printed.

# Some EC need an "EC firmware pointer" (a data structure hinting the address
# of its firmware blobs) being put at a fixed position. Its space
# (__section__(".ecfw_ptr")) should be reserved if it lies in the range of a
Expand Down
12 changes: 12 additions & 0 deletions src/arch/x86/Makefile.inc
Expand Up @@ -78,6 +78,7 @@ endef
ifeq ($(CONFIG_ARCH_BOOTBLOCK_X86_32)$(CONFIG_ARCH_BOOTBLOCK_X86_64),y)

bootblock-y += boot.c
bootblock-$(CONFIG_DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) += breakpoint.c
bootblock-y += post.c
bootblock-y += cpu_common.c
bootblock-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
Expand All @@ -87,6 +88,7 @@ bootblock-y += memset.c
bootblock-y += memmove.c
bootblock-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
bootblock-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
bootblock-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) += null_breakpoint.c
bootblock-$(CONFIG_BOOTBLOCK_NORMAL) += bootblock_normal.c
bootblock-y += gdt_init.S
bootblock-y += id.S
Expand Down Expand Up @@ -122,6 +124,7 @@ ifeq ($(CONFIG_ARCH_VERSTAGE_X86_32)$(CONFIG_ARCH_VERSTAGE_X86_64),y)

verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += assembly_entry.S
verstage-y += boot.c
verstage-$(CONFIG_DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) += breakpoint.c
verstage-y += post.c
verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += gdt_init.S
verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
Expand All @@ -133,6 +136,7 @@ verstage-y += memset.c
verstage-y += memcpy.c
verstage-y += memmove.c
verstage-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
verstage-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) += null_breakpoint.c
# If verstage is a separate stage it means there's no need
# for a chipset-specific car_stage_entry() so use the generic one
# which just calls verstage().
Expand All @@ -158,6 +162,7 @@ ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y)

romstage-y += assembly_entry.S
romstage-y += boot.c
romstage-$(CONFIG_DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) += breakpoint.c
romstage-y += post.c
romstage-y += gdt_init.S
romstage-y += cpu_common.c
Expand All @@ -167,6 +172,7 @@ romstage-y += memcpy.c
romstage-y += memmove.c
romstage-y += memset.c
romstage-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
romstage-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) += null_breakpoint.c
romstage-y += postcar_loader.c
romstage-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
romstage-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
Expand Down Expand Up @@ -199,6 +205,7 @@ endif
postcar-generic-ccopts += -D__POSTCAR__

postcar-y += boot.c
postcar-$(CONFIG_DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) += breakpoint.c
postcar-y += post.c
postcar-y += gdt_init.S
postcar-y += cpu_common.c
Expand All @@ -209,6 +216,7 @@ postcar-y += memcpy.c
postcar-y += memmove.c
postcar-y += memset.c
postcar-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
postcar-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) += null_breakpoint.c
postcar-y += postcar.c
postcar-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
postcar-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
Expand Down Expand Up @@ -243,6 +251,7 @@ ramstage-y += c_start.S
ramstage-y += c_exit.S
ramstage-y += cpu.c
ramstage-y += cpu_common.c
ramstage-$(CONFIG_DEBUG_HW_BREAKPOINTS) += breakpoint.c
ramstage-y += ebda.c
ramstage-y += exception.c
ramstage-y += idt.S
Expand All @@ -252,6 +261,7 @@ ramstage-y += memmove.c
ramstage-y += memset.c
ramstage-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
ramstage-$(CONFIG_GENERATE_MP_TABLE) += mpspec.c
ramstage-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS) += null_breakpoint.c
ramstage-$(CONFIG_GENERATE_PIRQ_TABLE) += pirq_routing.c
ramstage-y += rdrand.c
ramstage-$(CONFIG_GENERATE_SMBIOS_TABLES) += smbios.c
Expand Down Expand Up @@ -306,11 +316,13 @@ $(objgenerated)/ramstage.o: $$(ramstage-objs) $(COMPILER_RT_ramstage) $$(ramstag

endif # CONFIG_ARCH_RAMSTAGE_X86_32 / CONFIG_ARCH_RAMSTAGE_X86_64

smm-$(CONFIG_DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) += breakpoint.c
smm-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
smm-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
smm-y += memcpy.c
smm-y += memmove.c
smm-y += memset.c
smm-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
smm-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) += null_breakpoint.c

smm-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/smihandler.c)

0 comments on commit 3f01cd1

Please sign in to comment.