mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
Add a test of the signal ABI for INT instructions in both 32-bit and 64-bit processes. Check the signal number, trap number, error code, si_code, si_addr, instruction pointer and RF/TF state against legacy IDT behavior. Include a 15-byte prefixed INT to check that IP uses the hardware instruction length. Exercise both INT3 encodings, INT4, UD2 and HLT to cover the unchanged trap and fault paths. Run each instruction with TF clear and set. Resume at a known NOP after handling the signal and check that single-stepping traps after the NOP. Also drive INT 0x2d under ptrace, which resumes through the fault frame rather than sigreturn and so exposes a stale FRED software event flag. Start from an INT3 stop, whose FRED frame has no software event flag, instead of the syscall frame of raise(SIGSTOP). Single-step into the INT and check that the fault reports its address. Then suppress SIGSEGV and resume at the NOP, once with PTRACE_SINGLESTEP and once with PTRACE_CONT and TF set. Section 6.2.3 of the Intel FRED specification [1] specifies the immediate single-step trap caused by returning with both that flag and TF set. Check that each trap occurs after the NOP, rather than at its address. Report whether the CPU supports FRED, since a pass looks the same on either entry path. INT 0x80 with IA32 emulation disabled and a 64-bit tracer of a 32-bit tracee are not covered. Both variants pass all 29 checks on a non-FRED AMD host and on Panther Lake with FRED enabled and the fix applied. With the same binaries on unpatched Panther Lake, 16 signal-context checks fail and the first ptrace check reports the IP after the INT. The two dependent ptrace resume checks are not reached. [1] Intel Flexible Return and Event Delivery (FRED) Specification, revision 9.0 (346446-009US), section 6.2.3. Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://cdrdv2.intel.com/v1/dl/getContent/678938 # [1] Link: https://patch.msgid.link/20260917230907.2080792-3-matthew.schwartz@linux.dev
141 lines
5.0 KiB
Makefile
141 lines
5.0 KiB
Makefile
# SPDX-License-Identifier: GPL-2.0
|
|
all:
|
|
|
|
include ../lib.mk
|
|
|
|
.PHONY: all all_32 all_64 warn_32bit_failure clean
|
|
|
|
UNAME_M := $(shell uname -m)
|
|
CAN_BUILD_I386 := $(shell ./check_cc.sh "$(CC)" trivial_32bit_program.c -m32)
|
|
CAN_BUILD_X86_64 := $(shell ./check_cc.sh "$(CC)" trivial_64bit_program.c)
|
|
CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh "$(CC)" trivial_program.c -no-pie)
|
|
|
|
TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \
|
|
check_initial_reg_state sigreturn iopl ioperm \
|
|
test_vsyscall mov_ss_trap sigtrap_loop \
|
|
syscall_arg_fault fsgsbase_restore sigaltstack int_signal
|
|
TARGETS_C_BOTHBITS += nx_stack
|
|
TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \
|
|
test_FCMOV test_FCOMI test_FISTTP \
|
|
vdso_restorer
|
|
TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip syscall_numbering \
|
|
corrupt_xstate_header amx lam test_shadow_stack avx apx
|
|
# Some selftests require 32bit support enabled also on 64bit systems
|
|
TARGETS_C_32BIT_NEEDED := ldt_gdt ptrace_syscall
|
|
|
|
TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) $(TARGETS_C_32BIT_NEEDED)
|
|
TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY)
|
|
ifeq ($(CAN_BUILD_I386)$(CAN_BUILD_X86_64),11)
|
|
TARGETS_C_64BIT_ALL += $(TARGETS_C_32BIT_NEEDED)
|
|
endif
|
|
|
|
BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32)
|
|
BINARIES_64 := $(TARGETS_C_64BIT_ALL:%=%_64)
|
|
|
|
BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32))
|
|
BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64))
|
|
|
|
CFLAGS := -O2 -g -std=gnu99 -pthread -Wall $(KHDR_INCLUDES)
|
|
CFLAGS += -I $(top_srcdir)/tools/testing/selftests/
|
|
|
|
# call32_from_64 in thunks.S uses absolute addresses.
|
|
ifeq ($(CAN_BUILD_WITH_NOPIE),1)
|
|
CFLAGS += -no-pie
|
|
|
|
ifneq ($(LLVM),)
|
|
# clang only wants to see -no-pie during linking. Here, we don't have a separate
|
|
# linking stage, so a compiler warning is unavoidable without (wastefully)
|
|
# restructuring the Makefile. Avoid this by simply disabling that warning.
|
|
CFLAGS += -Wno-unused-command-line-argument
|
|
endif
|
|
endif
|
|
|
|
define gen-target-rule-32
|
|
$(1) $(1)_32: $(OUTPUT)/$(1)_32
|
|
.PHONY: $(1) $(1)_32
|
|
endef
|
|
|
|
define gen-target-rule-64
|
|
$(1) $(1)_64: $(OUTPUT)/$(1)_64
|
|
.PHONY: $(1) $(1)_64
|
|
endef
|
|
|
|
ifeq ($(CAN_BUILD_I386),1)
|
|
all: all_32
|
|
TEST_PROGS += $(BINARIES_32)
|
|
EXTRA_CFLAGS += -DCAN_BUILD_32
|
|
$(foreach t,$(TARGETS_C_32BIT_ALL),$(eval $(call gen-target-rule-32,$(t))))
|
|
endif
|
|
|
|
ifeq ($(CAN_BUILD_X86_64),1)
|
|
all: all_64
|
|
TEST_PROGS += $(BINARIES_64)
|
|
EXTRA_CFLAGS += -DCAN_BUILD_64
|
|
$(foreach t,$(TARGETS_C_64BIT_ALL),$(eval $(call gen-target-rule-64,$(t))))
|
|
endif
|
|
|
|
all_32: $(BINARIES_32)
|
|
|
|
all_64: $(BINARIES_64)
|
|
|
|
EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64) srso
|
|
|
|
$(BINARIES_32): $(OUTPUT)/%_32: %.c helpers.h
|
|
$(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $< $(EXTRA_FILES) -lrt -ldl -lm
|
|
|
|
$(BINARIES_64): $(OUTPUT)/%_64: %.c helpers.h
|
|
$(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $< $(EXTRA_FILES) -lrt -ldl
|
|
|
|
# x86_64 users should be encouraged to install 32-bit libraries
|
|
ifeq ($(CAN_BUILD_I386)$(CAN_BUILD_X86_64),01)
|
|
all: warn_32bit_failure
|
|
|
|
warn_32bit_failure:
|
|
@echo "Warning: you seem to have a broken 32-bit build" 2>&1; \
|
|
echo "environment. This will reduce test coverage of 64-bit" 2>&1; \
|
|
echo "kernels. If you are using a Debian-like distribution," 2>&1; \
|
|
echo "try:"; 2>&1; \
|
|
echo ""; \
|
|
echo " apt-get install gcc-multilib libc6-i386 libc6-dev-i386"; \
|
|
echo ""; \
|
|
echo "If you are using a Fedora-like distribution, try:"; \
|
|
echo ""; \
|
|
echo " yum install glibc-devel.*i686"; \
|
|
echo ""; \
|
|
echo "If you are using a SUSE-like distribution, try:"; \
|
|
echo ""; \
|
|
echo " zypper install gcc-32bit glibc-devel-static-32bit"; \
|
|
exit 0;
|
|
endif
|
|
|
|
# Add an additional file to the source file list for a given target, and also
|
|
# add a Makefile dependency on that same file. However, do these separately, so
|
|
# that the compiler invocation ("$(CC) file1.c file2.S") is not combined with
|
|
# the dependencies ("header3.h"), because clang, unlike gcc, will not accept
|
|
# header files as an input to the compiler invocation.
|
|
define extra-files
|
|
$(OUTPUT)/$(1): EXTRA_FILES := $(2)
|
|
$(OUTPUT)/$(1): $(2)
|
|
endef
|
|
|
|
$(eval $(call extra-files,sysret_ss_attrs_64,thunks.S))
|
|
$(eval $(call extra-files,ptrace_syscall_32,raw_syscall_helper_32.S))
|
|
$(eval $(call extra-files,test_syscall_vdso_32,thunks_32.S))
|
|
$(eval $(call extra-files,fsgsbase_restore_64,clang_helpers_64.S))
|
|
$(eval $(call extra-files,fsgsbase_restore_32,clang_helpers_32.S))
|
|
$(eval $(call extra-files,sysret_rip_64,clang_helpers_64.S))
|
|
|
|
# check_initial_reg_state is special: it needs a custom entry, and it
|
|
# needs to be static so that its interpreter doesn't destroy its initial
|
|
# state.
|
|
$(OUTPUT)/check_initial_reg_state_32: CFLAGS += -Wl,-ereal_start -static
|
|
$(OUTPUT)/check_initial_reg_state_64: CFLAGS += -Wl,-ereal_start -static
|
|
|
|
$(OUTPUT)/nx_stack_32: CFLAGS += -Wl,-z,noexecstack
|
|
$(OUTPUT)/nx_stack_64: CFLAGS += -Wl,-z,noexecstack
|
|
|
|
$(OUTPUT)/avx_64: CFLAGS += -mno-avx -mno-avx512f
|
|
$(OUTPUT)/amx_64: EXTRA_FILES += xstate.c
|
|
$(OUTPUT)/avx_64: EXTRA_FILES += xstate.c
|
|
$(OUTPUT)/apx_64: EXTRA_FILES += xstate.c
|