Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions scripts/tests
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,8 @@ class Tests:
log = logger(test_type, scheme_str, self.args.cross_prefix, opt)

args = ["make", test_type.make_run_target(scheme)]
if test_type.is_example() is False:
args += [f"OPT={int(opt)}", f"AUTO={int(self.args.auto)}"]
if test_type.is_benchmark() is False and test_type.is_example() is False:
args += self.make_j()
if test_type.make_dir() != "":
Expand Down
10 changes: 9 additions & 1 deletion test/abicheck/abicheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,20 @@ static const abicheck_entry_t all_checks[] = {{NULL, NULL}};
/* Return-code convention: see abicheck_common.h. SKIPPED means the kernel
* built but the host lacks the runtime capability; the generated check
* decides this via mld_sys_check_capability. */
int main(void)
/* Prototype for a re-#define'd main, to satisfy -Wmissing-prototypes. */
#if defined(main)
int main(int argc, char *argv[]);
#endif

int main(int argc, char *argv[])
{
int failed_tests = 0;
int selftest_failures;
const abicheck_entry_t *entry;

(void)argc;
(void)argv;

/* Meta-test the ABI checker before trusting kernel verdicts (see selftest.h).
*/
selftest_failures = abicheck_selftest();
Expand Down
25 changes: 15 additions & 10 deletions test/mk/components.mk
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,10 @@ endif
# ABI checker
ABICHECK_DIR = $(BUILD_DIR)/abicheck

# Map $(ARCH) to the abicheck per-arch subdir name. For most architectures
# the subdir matches $(ARCH); one exception:
# - arm-none-eabi- targets: $(ARCH) = arm (a generic label for the
# bare-metal Cortex-M family). The abicheck subdir is the more specific
# armv81m.
ifeq ($(ARCH),arm)
ABICHECK_ARCH := armv81m
else
ABICHECK_ARCH := $(ARCH)
endif
# A platform can select the ABI independently of make's host/cross ARCH (for
# example, Zephyr owns its target toolchain). Otherwise, use the architecture
# inferred from the compiler prefix.
ABICHECK_ARCH ?= $(ARCH)

ABICHECK_SOURCES = test/abicheck/abicheck.c test/abicheck/selftest.c
ABICHECK_SOURCES += $(wildcard test/abicheck/$(ABICHECK_ARCH)/abicheck_$(ABICHECK_ARCH).c)
Expand Down Expand Up @@ -268,4 +262,15 @@ ifneq ($(EXTRA_SOURCES),)
$(ABICHECK_EXTRA_OBJS): CFLAGS += $(EXTRA_SOURCES_CFLAGS)
endif

ifndef CUSTOM_BUILD
$(ABICHECK_DIR)/bin/abicheck: $(ABICHECK_OBJS) $(ABICHECK_EXTRA_OBJS)
else
# Custom builds compile sources through their own build system. Pass the ABI
# checker inputs and flags through the same interface as the other tests, and
# mark this as a standalone checker so the platform does not add libmldsa.
$(ABICHECK_DIR)/bin/abicheck: CUSTOM_BUILD_ABICHECK := 1
$(ABICHECK_DIR)/bin/abicheck: TEST_SRCS += $(ABICHECK_ALL_SOURCES)
$(ABICHECK_DIR)/bin/abicheck: CFLAGS += \
$(ABICHECK_ASM_CFLAGS) $(ABICHECK_FULL_API_CFLAGS)
$(ABICHECK_DIR)/bin/abicheck: $(ABICHECK_ALL_SOURCES) $(CUSTOM_BUILD_DEPS)
endif
4 changes: 1 addition & 3 deletions test/mk/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,8 @@ $(BUILD_DIR)/mldsa87/sign_hook/%.S.o: %.S $(CONFIG)
$(Q)$(CC) -c -o $@ $(CFLAGS) $<

$(BUILD_DIR)/abicheck/bin/%: $(CONFIG)
$(Q)echo " LD $@"
$(Q)[ -d $(@D) ] || mkdir -p $(@D)
$(Q)$(LD) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LDLIBS)
$(Q)$(LINK)

$(BUILD_DIR)/abicheck/%.c.o: %.c $(CONFIG)
$(Q)echo " CC $@"
Expand All @@ -161,4 +160,3 @@ $(BUILD_DIR)/abicheck/%.S.o: %.S $(CONFIG)
$(Q)echo " AS $@"
$(Q)[ -d $(@D) ] || mkdir -p $(@D)
$(Q)$(CC) -c -o $@ $(CFLAGS) $<

14 changes: 8 additions & 6 deletions test/zephyr/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ project(mldsa_native_zephyr)
# ZEPHYR_NATIVE_ROOT, space separated
# ZEPHYR_TEST_CFLAGS - the test binary's CFLAGS (see below); includes the
# parameter set (-DMLD_CONFIG_PARAMETER_SET=...)
# ZEPHYR_ABICHECK - build the standalone ABI checker sources without the
# normal mldsa amalgamation
set(R ${ZEPHYR_NATIVE_ROOT})

separate_arguments(_test_srcs UNIX_COMMAND "${ZEPHYR_TEST_SRCS}")
list(TRANSFORM _test_srcs PREPEND ${R}/)

target_sources(app PRIVATE
${R}/mldsa/mldsa_native.c
${_test_srcs}
)
target_sources(app PRIVATE ${_test_srcs})
if(NOT ZEPHYR_ABICHECK)
target_sources(app PRIVATE ${R}/mldsa/mldsa_native.c)
endif()

target_include_directories(app PRIVATE
${R}/mldsa
Expand Down Expand Up @@ -85,14 +87,14 @@ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/shim_nucleo_n657x0_q.c
# Optional native FIPS202 backend (e.g. Armv8.1-M MVE on Cortex-M55). The
# monolithic mldsa_native.c already includes the backend C sources; its
# assembly counterpart comes from mldsa_native_asm.S.
if(ZEPHYR_FIPS202_BACKEND)
if(ZEPHYR_FIPS202_BACKEND AND NOT ZEPHYR_ABICHECK)
target_sources(app PRIVATE ${R}/mldsa/mldsa_native_asm.S)
target_compile_definitions(app PRIVATE
MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202
"MLD_CONFIG_FIPS202_BACKEND_FILE=\"${ZEPHYR_FIPS202_BACKEND}\"")
endif()

# Each test brings its own int main(void); rename it so the selected Zephyr
# Each test brings its own main(); rename it so the selected Zephyr
# shim owns main() and can return the test's exit code through the target's
# runner. Only the test entrypoint in ZEPHYR_TEST_SRCS defines main(); the
# support sources (notrandombytes, hal) don't, so applying the define to all is
Expand Down
5 changes: 4 additions & 1 deletion test/zephyr/exec_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
binpath = sys.argv[1]
args = sys.argv[2:]
machine = os.environ.get("QEMU_MACHINE", "mps3-an547")
timeout = float(os.environ.get("QEMU_TIMEOUT", "300"))

semihosting_args = [binpath] + args
semihosting_config = "enable=on," + ",".join(f"arg={a}" for a in semihosting_args)
Expand All @@ -32,7 +33,9 @@
binpath,
]

result = subprocess.run(qemu_cmd, encoding="utf-8", capture_output=True, timeout=300)
result = subprocess.run(
qemu_cmd, encoding="utf-8", capture_output=True, timeout=timeout
)
sys.stdout.write(result.stdout)
if result.returncode != 0:
sys.stderr.write(result.stderr)
Expand Down
53 changes: 41 additions & 12 deletions test/zephyr/platform.mk
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ ZEPHYR_BOARD_nucleo-n657x0-q := nucleo_n657x0_q # Cortex-M55 (hardware)
ZEPHYR_FIPS202_BACKEND_mps3-an547 := fips202/native/armv81m/mve.h
ZEPHYR_FIPS202_BACKEND_nucleo-n657x0-q := fips202/native/armv81m/mve.h

# Zephyr owns target selection, so do not infer its ABI from make's host ARCH.
ZEPHYR_ABICHECK_ARCH_mps3-an547 := armv81m
ABICHECK_ARCH := $(strip $(ZEPHYR_ABICHECK_ARCH_$(ZEPHYR_TARGET)))

ZEPHYR_TARGETS := mps2-an385 mps2-an386 mps2-an500 mps2-an521 mps3-an547 nucleo-n657x0-q

ZEPHYR_BOARD := $(ZEPHYR_BOARD_$(ZEPHYR_TARGET))
Expand All @@ -55,12 +59,27 @@ endif
# file to source prerequisites (it is: the top-level Makefile includes us first).
OPT ?= 0

# Shrink the test iteration counts (the sources default them higher, sized for
# native hardware): QEMU is far slower. Keep these defaults ahead of the build
# key so command-line overrides invalidate binaries built with different counts.
NTESTS ?= 3
NUM_RANDOM_TESTS ?= 100

# Forward the QEMU execution deadline to exec_wrapper.py. Direct wrapper
# invocations use the same default when the variable is absent.
QEMU_TIMEOUT ?= 300
export QEMU_TIMEOUT

# Native backends are an OPT=1 feature (an547 builds the Armv8.1-M MVE backend).
ZEPHYR_FIPS202_BACKEND := $(if $(filter 1,$(OPT)),$(strip $(ZEPHYR_FIPS202_BACKEND_$(ZEPHYR_TARGET))))

ZEPHYR_APP := $(PLATFORM_PATH)/app
ZEPHYR_BUILD_DIR := $(BUILD_DIR)/zephyr/$(ZEPHYR_TARGET)
ZEPHYR_ACTIVE_TARGET := $(BUILD_DIR)/zephyr/.active-target
ZEPHYR_BUILD_KEY := $(ZEPHYR_TARGET)|OPT=$(OPT)
ZEPHYR_BUILD_KEY := $(ZEPHYR_BUILD_KEY)|FIPS202=$(ZEPHYR_FIPS202_BACKEND)
ZEPHYR_BUILD_KEY := $(ZEPHYR_BUILD_KEY)|NTESTS=$(NTESTS)
ZEPHYR_BUILD_KEY := $(ZEPHYR_BUILD_KEY)|NUM_RANDOM_TESTS=$(NUM_RANDOM_TESTS)
ZEPHYR_APP_INPUTS := \
$(ZEPHYR_APP)/CMakeLists.txt \
$(ZEPHYR_APP)/Kconfig \
Expand All @@ -79,14 +98,15 @@ ZEPHYR_TARGET_CMAKE_ARGS := $(if $(ZEPHYR_IS_NUCLEO_N657X0_Q),\

# Test binary output paths are shared across ZEPHYR_TARGET values, while the
# CMake build directory is target-specific. Keep a lightweight marker containing
# the last requested target, and only touch it when the target changes. Binaries
# depending on this marker are then rebuilt after a target switch without
# forcing a clean rebuild when the target is unchanged.
# the last requested build configuration, and only touch it when that
# configuration changes. Binaries depending on this marker are then rebuilt
# after a target, backend, or test-count switch without forcing a clean rebuild
# when the configuration is unchanged.
.PHONY: zephyr_target_marker_force
$(ZEPHYR_ACTIVE_TARGET): zephyr_target_marker_force
$(Q)[ -d $(@D) ] || mkdir -p $(@D)
$(Q)if [ ! -f $@ ] || [ "$$(cat $@)" != "$(ZEPHYR_TARGET)" ]; then \
echo "$(ZEPHYR_TARGET)" > $@; \
$(Q)if [ ! -f $@ ] || [ "$$(cat $@)" != "$(ZEPHYR_BUILD_KEY)" ]; then \
echo "$(ZEPHYR_BUILD_KEY)" > $@; \
fi

# Per-binary CMake build dir, keyed on $(notdir $@) so binaries build in
Expand All @@ -97,11 +117,10 @@ ZEPHYR_OUT = $(ZEPHYR_BUILD_DIR)/$(notdir $@)
# fit comfortably within the Zephyr main-thread stack (see app/prj.conf).
CFLAGS += -DMLD_CONFIG_REDUCE_RAM

# Shrink the test iteration counts (the sources default them higher, sized for
# native hardware): QEMU is far slower. On CFLAGS so they forward below.
CFLAGS += -DNTESTS=3 \
# Put the configurable test counts on CFLAGS so they forward below.
CFLAGS += -DNTESTS=$(NTESTS) \
-DMLD_BENCHMARK_NTESTS=10 -DMLD_BENCHMARK_NITERATIONS=10 -DMLD_BENCHMARK_NWARMUP=10 \
-DNUM_RANDOM_TESTS=100
-DNUM_RANDOM_TESTS=$(NUM_RANDOM_TESTS)

# The binary's CFLAGS, forwarded to the CMake build (which applies them to the
# mldsa amalgamation and test sources alike). '=' not ':=', so the recipe-time
Expand All @@ -120,26 +139,36 @@ ZEPHYR_TEST_CFLAGS = $(subst \",\\\",$(patsubst -Imldsa,-I$(abspath mldsa),$(CFL
ZEPHYR_CMAKE_ENV := env -u CFLAGS -u CXXFLAGS -u CPPFLAGS -u LDFLAGS

CUSTOM_BUILD = \
$(if $(CUSTOM_BUILD_ABICHECK),$(if $(ABICHECK_ARCH),,$(error ABI checking is not supported for ZEPHYR_TARGET=$(ZEPHYR_TARGET)))) \
echo " ZEPHYR $(ZEPHYR_TARGET): $(notdir $@)" && \
$(ZEPHYR_CMAKE_ENV) cmake -GNinja -S $(ZEPHYR_APP) -B $(ZEPHYR_OUT) \
-DBOARD=$(ZEPHYR_BOARD) \
-DZEPHYR_NATIVE_ROOT=$(CURDIR) \
-DZEPHYR_TEST_SRCS="$(strip $(TEST_SRCS))" \
-DZEPHYR_TEST_CFLAGS="$(ZEPHYR_TEST_CFLAGS)" \
-DZEPHYR_FIPS202_BACKEND=$(ZEPHYR_FIPS202_BACKEND) \
-DZEPHYR_ABICHECK=$(if $(CUSTOM_BUILD_ABICHECK),ON,OFF) \
$(if $(ZEPHYR_FIPS202_BACKEND),-DCONFIG_FIPS202_MVE_BACKEND=y) \
$(ZEPHYR_TARGET_CMAKE_ARGS) \
-DUSER_CACHE_DIR=$(abspath $(ZEPHYR_OUT)/.cache) \
>/dev/null && \
$(ZEPHYR_CMAKE_ENV) cmake --build $(ZEPHYR_OUT) >/dev/null && \
cp $(ZEPHYR_OUT)/zephyr/zephyr.elf $@

# A native assembly amalgamation can directly include development sources that
# do not appear in LIB_SRCS. The wildcard is empty before the Armv8.1-M x1
# backend lands and becomes an explicit dependency when that source is present.
ZEPHYR_NATIVE_ASM_INPUTS := mldsa/mldsa_native_asm.S \
$(wildcard dev/fips202/armv81m_clean/src/keccak_f1600_x1_armv7m.S)

# A custom build links the test sources directly rather than from objects, so
# nothing otherwise makes the bins depend on the Zephyr app inputs or the
# active-target marker. components.mk attaches CUSTOM_BUILD_DEPS to every test
# binary (in its CUSTOM_BUILD branch), so a CMakeLists/shim/overlay edit or a
# target switch forces a rebuild. Set here (before components.mk is included).
CUSTOM_BUILD_DEPS := $(ZEPHYR_ACTIVE_TARGET) $(ZEPHYR_APP_INPUTS)
# binary (in its CUSTOM_BUILD branch), so an application input, native assembly
# input, target, backend, or test-count change forces a rebuild. Set here before
# components.mk is included.
CUSTOM_BUILD_DEPS := $(ZEPHYR_ACTIVE_TARGET) $(ZEPHYR_APP_INPUTS) \
$(if $(ZEPHYR_FIPS202_BACKEND),$(ZEPHYR_NATIVE_ASM_INPUTS))

ifeq ($(ZEPHYR_IS_NUCLEO_N657X0_Q),)
EXEC_WRAPPER := $(abspath $(PLATFORM_PATH)/exec_wrapper.py)
Expand Down
Loading