From: raschupkin.ri@gmail.com
To: live-patching@vger.kernel.org, joe.lawrence@redhat.com,
pmladek@suse.com, mbenes@suse.cz, jikos@kernel.org,
jpoimboe@kernel.org
Cc: Roman Rashchupkin <raschupkin.ri@gmail.com>
Subject: [PATCH 2/2] selftests/livepatch: Add tests for kprefcount_t support
Date: Sun, 14 Jul 2024 21:59:34 +0200 [thread overview]
Message-ID: <20240714195958.692313-3-raschupkin.ri@gmail.com> (raw)
In-Reply-To: <20240714195958.692313-1-raschupkin.ri@gmail.com>
From: Roman Rashchupkin <raschupkin.ri@gmail.com>
Signed-off-by: Roman Rashchupkin <raschupkin.ri@gmail.com>
---
tools/testing/selftests/livepatch/Makefile | 3 +-
.../selftests/livepatch/test-kprefcount.sh | 16 +++
.../selftests/livepatch/test_modules/Makefile | 4 +-
.../test_modules/test_klp_kprefcount.c | 120 ++++++++++++++++++
.../test_modules/test_klp_refcount.c | 65 ++++++++++
5 files changed, 206 insertions(+), 2 deletions(-)
create mode 100755 tools/testing/selftests/livepatch/test-kprefcount.sh
create mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_kprefcount.c
create mode 100644 tools/testing/selftests/livepatch/test_modules/test_klp_refcount.c
diff --git a/tools/testing/selftests/livepatch/Makefile b/tools/testing/selftests/livepatch/Makefile
index 35418a4790be..48926ebc77f2 100644
--- a/tools/testing/selftests/livepatch/Makefile
+++ b/tools/testing/selftests/livepatch/Makefile
@@ -10,7 +10,8 @@ TEST_PROGS := \
test-state.sh \
test-ftrace.sh \
test-sysfs.sh \
- test-syscall.sh
+ test-syscall.sh \
+ test-kprefcount.sh
TEST_FILES := settings
diff --git a/tools/testing/selftests/livepatch/test-kprefcount.sh b/tools/testing/selftests/livepatch/test-kprefcount.sh
new file mode 100755
index 000000000000..8ea6c18f59dd
--- /dev/null
+++ b/tools/testing/selftests/livepatch/test-kprefcount.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+insmod test_modules/test_klp_refcount.ko
+insmod test_modules/test_klp_kprefcount.ko
+livepatch_enabled=/sys/kernel/livepatch/test_klp_kprefcount/enabled
+while [ ! -e $livepatch_enabled -o $(cat $livepatch_enabled) -eq 0 ]; do
+ sleep 0.01;
+done
+echo 0 > $livepatch_enabled
+while [ $(cat $livepatch_enabled) -eq 1 ]; do
+ sleep 0.01;
+done
+while [ -e $livepatch_enabled ]; do
+ sleep 0.01;
+done
+rmmod test_klp_kprefcount
+rmmod test_klp_refcount
diff --git a/tools/testing/selftests/livepatch/test_modules/Makefile b/tools/testing/selftests/livepatch/test_modules/Makefile
index e6e638c4bcba..c26797372e0d 100644
--- a/tools/testing/selftests/livepatch/test_modules/Makefile
+++ b/tools/testing/selftests/livepatch/test_modules/Makefile
@@ -11,7 +11,9 @@ obj-m += test_klp_atomic_replace.o \
test_klp_state2.o \
test_klp_state3.o \
test_klp_shadow_vars.o \
- test_klp_syscall.o
+ test_klp_syscall.o \
+ test_klp_refcount.o \
+ test_klp_kprefcount.o
# Ensure that KDIR exists, otherwise skip the compilation
modules:
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_kprefcount.c b/tools/testing/selftests/livepatch/test_modules/test_klp_kprefcount.c
new file mode 100644
index 000000000000..063f286ebcec
--- /dev/null
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_kprefcount.c
@@ -0,0 +1,120 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/livepatch.h>
+#include <linux/livepatch_refcount.h>
+
+extern refcount_t test_refcount;
+extern int TEST_LIVEPATCH_KPREFCOUNT;
+
+#define ITER 100
+#define NREF 10
+#define KP_NREF 10
+static struct ref_holder {
+ unsigned char v;
+} kp_ref_holders[KP_NREF] = { 0 };
+kprefcount_t *kp_test_ref = 0;
+
+static int livepatch_refcount_test_iter(void)
+{
+ int k, i;
+ for (k=0; k<ITER; k++) {
+ for (i=0; i<KP_NREF; i++)
+ refcount_inc(&test_refcount);
+ for (i=0; i<KP_NREF; i++)
+ if (kprefcount_dec_and_test(kp_test_ref, 0, 1)) {
+ pr_alert("livepatch refcount underflow\n");
+ return -1;
+ }
+ }
+ TEST_LIVEPATCH_KPREFCOUNT = 0;
+ return 0;
+}
+
+struct delayed_work kp_work_refcount;
+static void kp_test_refcount(struct work_struct *work)
+{
+ int i, k;
+ for (k=0; k<ITER; k++) {
+ for (i=0; i<KP_NREF; i++)
+ kprefcount_dec(kp_test_ref, &kp_ref_holders[i].v, 1);
+ // Intentional refcounter underflow for additional testing
+ for (i=0; i<KP_NREF-1; i++)
+ kprefcount_inc(kp_test_ref, &kp_ref_holders[i].v, 1);
+ }
+}
+
+static void kp_post_patch_callback(struct klp_object *klp_obj)
+{
+ schedule_delayed_work(&kp_work_refcount, 0);
+}
+
+static void kp_pre_unpatch_callback(struct klp_object *klp_obj)
+{
+ cancel_delayed_work_sync(&kp_work_refcount);
+}
+
+static struct klp_func funcs[] = {
+ {
+ .old_name = "refcount_test_iter",
+ .new_func = livepatch_refcount_test_iter,
+ }, { }
+};
+
+static struct klp_object objs[] = {
+ {
+ .name = "test_klp_refcount",
+ .funcs = funcs,
+ .callbacks = {
+ .post_patch = kp_post_patch_callback,
+ .pre_unpatch = kp_pre_unpatch_callback,
+ },
+ }, { }
+};
+
+static struct klp_patch patch = {
+ .mod = THIS_MODULE,
+ .objs = objs,
+};
+
+struct delayed_work work_refcount;
+
+static void do_test_refcount(struct work_struct *work)
+{
+ int i;
+ for (i=0; i<NREF; i++) {
+ if (refcount_read(&test_refcount) <= 1)
+ pr_info("LIVEPATCH refcount test done.\n");
+ return;
+ refcount_dec(&test_refcount);
+ if (refcount_read(&test_refcount) < 0)
+ pr_alert("post-livepatch refcount underflow\n");
+ }
+ for (i=0; i<NREF; i++)
+ refcount_inc(&test_refcount);
+}
+
+static int refcount_test_init(void)
+{
+ int ret;
+ kp_test_ref = kprefcount_alloc(&test_refcount, GFP_KERNEL);
+ if (!kp_test_ref) {
+ pr_alert("kprefcount_livepatch: memory allocation_failed");
+ return -1;
+ }
+ ret = klp_enable_patch(&patch);
+ INIT_DELAYED_WORK(&kp_work_refcount, kp_test_refcount);
+ return 0;
+}
+
+static void refcount_test_exit(void)
+{
+}
+
+module_init(refcount_test_init);
+module_exit(refcount_test_exit);
+MODULE_INFO(livepatch, "Y");
+MODULE_AUTHOR("Roman Rashchupkin <raschupkin.ri@gmail.com>");
+MODULE_DESCRIPTION("Livepatch test: kprefcount");
+MODULE_LICENSE("GPL");
diff --git a/tools/testing/selftests/livepatch/test_modules/test_klp_refcount.c b/tools/testing/selftests/livepatch/test_modules/test_klp_refcount.c
new file mode 100644
index 000000000000..bd9c57e63476
--- /dev/null
+++ b/tools/testing/selftests/livepatch/test_modules/test_klp_refcount.c
@@ -0,0 +1,65 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/livepatch.h>
+#include <linux/livepatch_refcount.h>
+
+#define ITER 100
+#define NREF 10
+int TEST_LIVEPATCH_KPREFCOUNT = 1;
+EXPORT_SYMBOL(TEST_LIVEPATCH_KPREFCOUNT);
+refcount_t test_refcount = REFCOUNT_INIT(1);
+EXPORT_SYMBOL(test_refcount);
+
+int refcount_test_iter(void)
+{
+ int i;
+ for (i=0; i<NREF; i++)
+ refcount_inc(&test_refcount);
+ for (i=0; i<NREF; i++)
+ if (refcount_dec_and_test(&test_refcount))
+ return -1;
+ return 0;
+}
+
+int refcount_test(void)
+{
+ int i;
+ for (i=0; i<ITER; i++) {
+ if (refcount_test_iter())
+ return -1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(refcount_test);
+
+struct delayed_work kp_test_work;
+void start_refcount_test(struct work_struct *work)
+{
+ if (!TEST_LIVEPATCH_KPREFCOUNT)
+ return;
+ if (refcount_test()) {
+ pr_alert(KERN_ERR "refcount_test: error.\n");
+ return;
+ }
+ schedule_delayed_work(&kp_test_work, msecs_to_jiffies(50));
+}
+
+static int refcount_test_init(void)
+{
+ INIT_DELAYED_WORK(&kp_test_work, start_refcount_test);
+ schedule_delayed_work(&kp_test_work, msecs_to_jiffies(50));
+ return 0;
+}
+
+static void refcount_test_exit(void)
+{
+ cancel_delayed_work_sync(&kp_test_work);
+}
+
+module_init(refcount_test_init);
+module_exit(refcount_test_exit);
+MODULE_AUTHOR("Roman Rashchupkin <raschupkin.ri@gmail.com>");
+MODULE_DESCRIPTION("Livepatch test: refcount");
+MODULE_LICENSE("GPL");
--
2.43.0
next prev parent reply other threads:[~2024-07-14 20:00 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-14 19:59 raschupkin.ri
2024-07-14 19:59 ` [PATCH 1/2] [PATCH] livepatch: support of modifying refcount_t without underflow after unpatch raschupkin.ri
2024-07-14 22:07 ` Jeff Johnson
2024-07-14 19:59 ` raschupkin.ri [this message]
2024-07-15 20:20 ` Joe Lawrence
2024-07-15 22:45 ` Re: Roman Rashchupkin
2024-07-16 9:28 ` Re: Nicolai Stange
[not found] ` <66963d60.170a0220.70a9a.8866SMTPIN_ADDED_BROKEN@mx.google.com>
2024-07-16 9:53 ` Re: Roman Rashchupkin
2024-07-25 14:52 ` Re: Joe Lawrence
2024-07-16 17:33 ` Re: Song Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240714195958.692313-3-raschupkin.ri@gmail.com \
--to=raschupkin.ri@gmail.com \
--cc=jikos@kernel.org \
--cc=joe.lawrence@redhat.com \
--cc=jpoimboe@kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=pmladek@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox