Commit 9d4502fe authored by Tzung-Bi Shih's avatar Tzung-Bi Shih Committed by Greg Kroah-Hartman
Browse files

selftests: revocable: Add kselftest cases



Add kselftest cases for the revocable API.

The test consists of three parts:
- A kernel module (revocable_test.ko) that creates a debugfs interface
  with `/provider` and `/consumer` files.
- A user-space C program (revocable_test) that uses the kselftest
  harness to interact with the debugfs files.
- An orchestrating shell script (test-revocable.sh) that loads the
  module, runs the C program, and unloads the module.

The test cases cover the following scenarios:
- Basic: Verifies that a consumer can successfully access the resource
  provided via the provider.
- Revocation: Verifies that after the provider revokes the resource,
  the consumer correctly receives a NULL pointer on a subsequent access.
- Try Access Macro: Same as "Revocation" but uses the
  REVOCABLE_TRY_ACCESS_WITH() and REVOCABLE_TRY_ACCESS_SCOPED().

Signed-off-by: default avatarTzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260116080235.350305-4-tzungbi@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent cd769341
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22375,6 +22375,7 @@ S: Maintained
F:	drivers/base/revocable.c
F:	drivers/base/revocable_test.c
F:	include/linux/revocable.h
F:	tools/testing/selftests/drivers/base/revocable/
RFKILL
M:	Johannes Berg <johannes@sipsolutions.net>
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ TARGETS += damon
TARGETS += devices/error_logs
TARGETS += devices/probe
TARGETS += dmabuf-heaps
TARGETS += drivers/base/revocable
TARGETS += drivers/dma-buf
TARGETS += drivers/ntsync
TARGETS += drivers/s390x/uvdevice
+7 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

TEST_GEN_MODS_DIR := test_modules
TEST_GEN_PROGS_EXTENDED := revocable_test
TEST_PROGS := test-revocable.sh

include ../../../lib.mk
+136 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2026 Google LLC
 *
 * A selftest for the revocable API.
 *
 * The test cases cover the following scenarios:
 *
 * - Basic: Verifies that a consumer can successfully access the resource
 *   provided via the provider.
 *
 * - Revocation: Verifies that after the provider revokes the resource,
 *   the consumer correctly receives a NULL pointer on a subsequent access.
 *
 * - Try Access Macro: Same as "Revocation" but uses the
 *   REVOCABLE_TRY_ACCESS_WITH() and REVOCABLE_TRY_ACCESS_SCOPED().
 */

#include <fcntl.h>
#include <unistd.h>

#include "../../../kselftest_harness.h"

#define DEBUGFS_PATH "/sys/kernel/debug/revocable_test"
#define TEST_CMD_RESOURCE_GONE "resource_gone"
#define TEST_DATA "12345678"
#define TEST_MAGIC_OFFSET 0x1234
#define TEST_MAGIC_OFFSET2 0x5678

FIXTURE(revocable_fixture) {
	int pfd;
	int cfd;
};

FIXTURE_SETUP(revocable_fixture) {
	int ret;

	self->pfd = open(DEBUGFS_PATH "/provider", O_WRONLY);
	ASSERT_NE(-1, self->pfd)
		TH_LOG("failed to open provider fd");

	ret = write(self->pfd, TEST_DATA, strlen(TEST_DATA));
	ASSERT_NE(-1, ret) {
		close(self->pfd);
		TH_LOG("failed to write test data");
	}

	self->cfd = open(DEBUGFS_PATH "/consumer", O_RDONLY);
	ASSERT_NE(-1, self->cfd)
		TH_LOG("failed to open consumer fd");
}

FIXTURE_TEARDOWN(revocable_fixture) {
	close(self->cfd);
	close(self->pfd);
}

/*
 * ASSERT_* is only available in TEST or TEST_F block.  Use
 * macro for the helper.
 */
#define READ_TEST_DATA(_fd, _offset, _data, _msg)			\
	do {								\
		int ret;						\
									\
		ret = lseek(_fd, _offset, SEEK_SET);			\
		ASSERT_NE(-1, ret)					\
			TH_LOG("failed to lseek");			\
									\
		ret = read(_fd, _data, sizeof(_data) - 1);		\
		ASSERT_NE(-1, ret)					\
			TH_LOG(_msg);					\
		data[ret] = '\0';					\
	} while (0)

TEST_F(revocable_fixture, basic) {
	char data[16];

	READ_TEST_DATA(self->cfd, 0, data, "failed to read test data");
	EXPECT_STREQ(TEST_DATA, data);
}

TEST_F(revocable_fixture, revocation) {
	char data[16];
	int ret;

	READ_TEST_DATA(self->cfd, 0, data, "failed to read test data");
	EXPECT_STREQ(TEST_DATA, data);

	ret = write(self->pfd, TEST_CMD_RESOURCE_GONE,
		    strlen(TEST_CMD_RESOURCE_GONE));
	ASSERT_NE(-1, ret)
		TH_LOG("failed to write resource gone cmd");

	READ_TEST_DATA(self->cfd, 0, data,
		       "failed to read test data after resource gone");
	EXPECT_STREQ("(null)", data);
}

TEST_F(revocable_fixture, try_access_macro) {
	char data[16];
	int ret;

	READ_TEST_DATA(self->cfd, TEST_MAGIC_OFFSET, data,
		       "failed to read test data");
	EXPECT_STREQ(TEST_DATA, data);

	ret = write(self->pfd, TEST_CMD_RESOURCE_GONE,
		    strlen(TEST_CMD_RESOURCE_GONE));
	ASSERT_NE(-1, ret)
		TH_LOG("failed to write resource gone cmd");

	READ_TEST_DATA(self->cfd, TEST_MAGIC_OFFSET, data,
		       "failed to read test data after resource gone");
	EXPECT_STREQ("(null)", data);
}

TEST_F(revocable_fixture, try_access_macro2) {
	char data[16];
	int ret;

	READ_TEST_DATA(self->cfd, TEST_MAGIC_OFFSET2, data,
		       "failed to read test data");
	EXPECT_STREQ(TEST_DATA, data);

	ret = write(self->pfd, TEST_CMD_RESOURCE_GONE,
		    strlen(TEST_CMD_RESOURCE_GONE));
	ASSERT_NE(-1, ret)
		TH_LOG("failed to write resource gone cmd");

	READ_TEST_DATA(self->cfd, TEST_MAGIC_OFFSET2, data,
		       "failed to read test data after resource gone");
	EXPECT_STREQ("(null)", data);
}

TEST_HARNESS_MAIN
+39 −0
Original line number Diff line number Diff line
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0

mod_name="revocable_test"
ksft_fail=1
ksft_skip=4

if [ "$(id -u)" -ne 0 ]; then
	echo "$0: Must be run as root"
	exit "$ksft_skip"
fi

if ! which insmod > /dev/null 2>&1; then
	echo "$0: Need insmod"
	exit "$ksft_skip"
fi

if ! which rmmod > /dev/null 2>&1; then
	echo "$0: Need rmmod"
	exit "$ksft_skip"
fi

insmod test_modules/"${mod_name}".ko

if [ ! -d /sys/kernel/debug/revocable_test/ ]; then
	mount -t debugfs none /sys/kernel/debug/

	if [ ! -d /sys/kernel/debug/revocable_test/ ]; then
		echo "$0: Error mounting debugfs"
		exit "$ksft_fail"
	fi
fi

./revocable_test
ret=$?

rmmod "${mod_name}"

exit "${ret}"
Loading