diff options
| author | Mark Brown <broonie@kernel.org> | 2026-05-29 22:46:36 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-05-29 22:46:37 +0100 |
| commit | b3897f4d6b7c3d92f8bb098038327766da8ba06d (patch) | |
| tree | 095730507e9a2c7f22b291c91b7d1aa873967f5b /tools | |
| parent | e2bd485974b30605aaa2fd4b8b6551d9a1846a62 (diff) | |
| parent | 5428435567cbe06c19914592fc22ca23c9ca1de5 (diff) | |
| download | linux-next-history-b3897f4d6b7c3d92f8bb098038327766da8ba06d.tar.gz | |
Merge branch 'next' of https://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/testing/memblock/linux/mmzone.h | 4 | ||||
| -rwxr-xr-x | tools/testing/selftests/kho/vmtest.sh | 4 | ||||
| -rw-r--r-- | tools/testing/selftests/liveupdate/liveupdate.c | 113 |
3 files changed, 121 insertions, 0 deletions
diff --git a/tools/testing/memblock/linux/mmzone.h b/tools/testing/memblock/linux/mmzone.h index bb682659a12df..8d934ff5b0802 100644 --- a/tools/testing/memblock/linux/mmzone.h +++ b/tools/testing/memblock/linux/mmzone.h @@ -35,4 +35,8 @@ typedef struct pglist_data { } pg_data_t; +enum migratetype { + MIGRATE_CMA, +}; + #endif diff --git a/tools/testing/selftests/kho/vmtest.sh b/tools/testing/selftests/kho/vmtest.sh index 49fdac8e8b159..0014bd76e88de 100755 --- a/tools/testing/selftests/kho/vmtest.sh +++ b/tools/testing/selftests/kho/vmtest.sh @@ -59,10 +59,14 @@ function build_kernel() { tee "$kconfig" > "$kho_config" <<EOF CONFIG_BLK_DEV_INITRD=y CONFIG_KEXEC_HANDOVER=y +CONFIG_KEXEC_HANDOVER_DEBUG=y CONFIG_KEXEC_HANDOVER_DEBUGFS=y CONFIG_TEST_KEXEC_HANDOVER=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_VM=y +CONFIG_DEBUG_VM_PGFLAGS=y +CONFIG_SMP=y +CONFIG_DEFERRED_STRUCT_PAGE_INIT=y $arch_kconfig EOF diff --git a/tools/testing/selftests/liveupdate/liveupdate.c b/tools/testing/selftests/liveupdate/liveupdate.c index 37c808fbe1e92..c7d94b9181e12 100644 --- a/tools/testing/selftests/liveupdate/liveupdate.c +++ b/tools/testing/selftests/liveupdate/liveupdate.c @@ -102,6 +102,22 @@ static int create_session(int lu_fd, const char *name) return args.fd; } +/* Helper function to get a session name via ioctl. */ +static int get_session_name(int session_fd, char *name, size_t name_len) +{ + struct liveupdate_session_get_name args = {}; + + args.size = sizeof(args); + + if (ioctl(session_fd, LIVEUPDATE_SESSION_GET_NAME, &args)) + return -errno; + + strncpy(name, (char *)args.name, name_len - 1); + name[name_len - 1] = '\0'; + + return 0; +} + /* * Test Case: Create Duplicate Session * @@ -386,4 +402,101 @@ TEST_F(liveupdate_device, prevent_double_preservation) ASSERT_EQ(close(session_fd2), 0); } +/* + * Test Case: Create Session with No Null Termination + * + * Verifies that filling the entire 64-byte name field with non-null characters + * (no '\0' terminator) is rejected by the kernel with EINVAL. + */ +TEST_F(liveupdate_device, create_session_no_null_termination) +{ + struct liveupdate_ioctl_create_session args = {}; + + self->fd1 = open(LIVEUPDATE_DEV, O_RDWR); + if (self->fd1 < 0 && errno == ENOENT) + SKIP(return, "%s does not exist", LIVEUPDATE_DEV); + ASSERT_GE(self->fd1, 0); + + /* Fill entire name field with 'X', no null terminator */ + args.size = sizeof(args); + memset(args.name, 'X', sizeof(args.name)); + + EXPECT_LT(ioctl(self->fd1, LIVEUPDATE_IOCTL_CREATE_SESSION, &args), 0); + EXPECT_EQ(errno, EINVAL); +} + +/* + * Test Case: Create Session with Empty Name + * + * Verifies that creating a session with an empty string name fails + * with EINVAL. + */ +TEST_F(liveupdate_device, create_session_empty_name) +{ + int session_fd; + + self->fd1 = open(LIVEUPDATE_DEV, O_RDWR); + if (self->fd1 < 0 && errno == ENOENT) + SKIP(return, "%s does not exist", LIVEUPDATE_DEV); + ASSERT_GE(self->fd1, 0); + + session_fd = create_session(self->fd1, ""); + EXPECT_EQ(session_fd, -EINVAL); +} + +/* + * Test Case: Get Session Name + * + * Verifies that the full session name can be retrieved from a session file + * descriptor via ioctl. + */ +TEST_F(liveupdate_device, get_session_name) +{ + char name_buf[LIVEUPDATE_SESSION_NAME_LENGTH] = {}; + const char *session_name = "get-name-test-session"; + int session_fd; + + self->fd1 = open(LIVEUPDATE_DEV, O_RDWR); + if (self->fd1 < 0 && errno == ENOENT) + SKIP(return, "%s does not exist", LIVEUPDATE_DEV); + ASSERT_GE(self->fd1, 0); + + session_fd = create_session(self->fd1, session_name); + ASSERT_GE(session_fd, 0); + + ASSERT_EQ(get_session_name(session_fd, name_buf, sizeof(name_buf)), 0); + ASSERT_STREQ(name_buf, session_name); + + ASSERT_EQ(close(session_fd), 0); +} + +/* + * Test Case: Get Session Name at Maximum Length + * + * Verifies that a session name using the full LIVEUPDATE_SESSION_NAME_LENGTH + * (minus the null terminator) can be correctly retrieved. + */ +TEST_F(liveupdate_device, get_session_name_max_length) +{ + char name_buf[LIVEUPDATE_SESSION_NAME_LENGTH] = {}; + char long_name[LIVEUPDATE_SESSION_NAME_LENGTH]; + int session_fd; + + memset(long_name, 'A', sizeof(long_name) - 1); + long_name[sizeof(long_name) - 1] = '\0'; + + self->fd1 = open(LIVEUPDATE_DEV, O_RDWR); + if (self->fd1 < 0 && errno == ENOENT) + SKIP(return, "%s does not exist", LIVEUPDATE_DEV); + ASSERT_GE(self->fd1, 0); + + session_fd = create_session(self->fd1, long_name); + ASSERT_GE(session_fd, 0); + + ASSERT_EQ(get_session_name(session_fd, name_buf, sizeof(name_buf)), 0); + ASSERT_STREQ(name_buf, long_name); + + ASSERT_EQ(close(session_fd), 0); +} + TEST_HARNESS_MAIN |
