Acked-by: Muhammad Usama Anjum <usama.anjum@xxxxxxxxxxxxx> > > Signed-off-by: Thomas WeiÃ?schuh <thomas.weissschuh@xxxxxxxxxxxxx> > Reviewed-by: David Gow <davidgow@xxxxxxxxxx> > --- > MAINTAINERS | 1 + > lib/kunit/Makefile | 6 +++++ > lib/kunit/kunit-uapi.c | 9 +++++-- > lib/kunit/uapi-preinit.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 77 insertions(+), 2 deletions(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index b1405f0a0e638d1654d9dc9e51d784ddc838cf5b..e81dfa180ab374ef91c7a45e546e6e9a8f454fa7 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -13546,6 +13546,7 @@ S: Maintained > F: include/kunit/uapi.h > F: lib/kunit/kunit-example-uapi.c > F: lib/kunit/kunit-uapi.c > +F: lib/kunit/uapi-preinit.c > > KVM PARAVIRT (KVM/paravirt) > M: Paolo Bonzini <pbonzini@xxxxxxxxxx> > diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile > index 1bba7965613e36e26939d6b31e1d65acf5bad0dc..b50f3bc8bc7f3ade03be4900d9163d7a0d96863c 100644 > --- a/lib/kunit/Makefile > +++ b/lib/kunit/Makefile > @@ -14,8 +14,14 @@ kunit-objs += test.o \ > device.o \ > platform.o > > +userprogs += uapi-preinit > +uapi-preinit-userccflags += -static $(NOLIBC_USERCFLAGS) \ > + -include include/generated/autoconf.h \ > + -include $(srctree)/tools/include/linux/kconfig.h > obj-$(CONFIG_KUNIT_UAPI) += kunit-uapi.o > > +$(obj)/kunit-uapi.o: $(obj)/uapi-preinit > + > ifeq ($(CONFIG_KUNIT_DEBUGFS),y) > kunit-objs += debugfs.o > endif > diff --git a/lib/kunit/kunit-uapi.c b/lib/kunit/kunit-uapi.c > index cfe8440e16fde942a5f0fa7ac9d8ab90a737215b..7c87605b9ded9dbeb3968af8a8f4650ab5938887 100644 > --- a/lib/kunit/kunit-uapi.c > +++ b/lib/kunit/kunit-uapi.c > @@ -25,6 +25,8 @@ > #define KSFT_XPASS 3 > #define KSFT_SKIP 4 > > +KUNIT_UAPI_EMBED_BLOB(kunit_uapi_preinit, "uapi-preinit"); > + > static struct vfsmount *kunit_uapi_mount_ramfs(void) > { > struct file_system_type *type; > @@ -146,7 +148,7 @@ static int kunit_uapi_user_mode_thread_init(void *data) > kernel_sigaction(SIGABRT, SIG_DFL); > > complete(&ctx->setup_done); > - ctx->exec_err = kernel_execve(ctx->executable, argv, NULL); > + ctx->exec_err = kernel_execve(kbasename(kunit_uapi_preinit.path), argv, NULL); > if (!ctx->exec_err) > return 0; > do_exit(0); > @@ -255,7 +257,10 @@ static int kunit_uapi_run_executable(struct kunit *test, > if (IS_ERR(mnt)) > return PTR_ERR(mnt); > > - err = kunit_uapi_write_executable(mnt, executable); > + err = kunit_uapi_write_executable(mnt, &kunit_uapi_preinit); > + > + if (!err) > + err = kunit_uapi_write_executable(mnt, executable); > > if (!err) > err = kunit_uapi_run_executable_in_mount(test, exe_name, mnt); > diff --git a/lib/kunit/uapi-preinit.c b/lib/kunit/uapi-preinit.c > new file mode 100644 > index 0000000000000000000000000000000000000000..81182039965a8c93aebb2d5d76f4113bfef277a6 > --- /dev/null > +++ b/lib/kunit/uapi-preinit.c > @@ -0,0 +1,63 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * KUnit Userspace environment setup. > + * > + * Copyright (C) 2025, Linutronix GmbH. > + * Author: Thomas WeiÃ?schuh <thomas.weissschuh@xxxxxxxxxxxxx> > + * > + * This is *userspace* code. > + */ > + > +#include <sys/mount.h> > +#include <sys/stat.h> > + > +#include "../../tools/testing/selftests/kselftest.h" > + > +static int setup_api_mount(const char *target, const char *fstype) > +{ > + int ret; > + > + ret = mkdir(target, 0755); > + if (ret && errno != EEXIST) > + return -errno; > + > + ret = mount("none", target, fstype, 0, NULL); > + if (ret && errno != EBUSY) > + return -errno; > + > + return 0; > +} > + > +static void exit_failure(const char *stage, int err) > +{ > + /* If preinit fails synthesize a failed test report. */ > + ksft_print_header(); > + ksft_set_plan(1); > + ksft_test_result_fail("Failed during test setup: %s: %s\n", stage, strerror(-err)); Positive error values are passed to strerror() without the - sign in userspace. Probably - needs to be removed from strerror() here. > + ksft_finished(); > +} > + > +int main(int argc, char **argv, char **envp) > +{ > + int ret; > + > + ret = setup_api_mount("/proc", "proc"); > + if (ret) > + exit_failure("mount /proc", ret); > + > + ret = setup_api_mount("/sys", "sysfs"); > + if (ret) > + exit_failure("mount /sys", ret); > + > + if (IS_ENABLED(CONFIG_DEVTMPFS)) { > + ret = setup_api_mount("/dev", "devtmpfs"); > + if (ret) > + exit_failure("mount /dev", ret); > + } > + > + ret = execve(argv[0], argv, envp); > + if (ret) > + exit_failure("execve", ret); > + > + return 0; > +} >