mirror of https://github.com/dynup/kpatch
test/integration: Updated module.patch for Linux 6.2
Yulia reported a bug with module.patch which can be seen with CONFIG_PROVE_RCU: BUG: sleeping function called from invalid context at include/linux/percpu-rwsem.h:49 in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 1053, name: grep preempt_count: 0, expected: 0 RCU nest depth: 1, expected: 0 2 locks held by grep/1053: #0: ffff8881079bf1a0 (&p->lock){+.+.}-{3:3}, at: seq_read_iter+0x55/0x460 #1: ffffffff8275d620 (rcu_read_lock){....}-{1:2}, at: cache_seq_start_rcu+0x5/0x140 [sunrpc] CPU: 3 PID: 1053 Comm: grep Tainted: G OE K 6.2.0 #57 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.1-2.fc37 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x5b/0x77 __might_resched.cold+0xff/0x13a cpus_read_lock+0x16/0xd0 static_key_disable+0xe/0x20 e_show+0x5b/0xd70 [livepatch_module] seq_read_iter+0x127/0x460 seq_read+0xa3/0xd0 proc_reg_read+0x52/0xa0 vfs_read+0xc9/0x2f0 ? __do_sys_newfstat+0x57/0x60 ? lock_is_held_type+0xe8/0x140 ksys_read+0x6c/0xf0 do_syscall_64+0x37/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc RIP: 0033:0x7fbd314f7af0 Code: b6 fe ff ff 48 8d 3d 2f 78 09 00 48 83 ec 08 e8 96 25 02 00 66 0f 1f 44 00 00 83 3d d9 db 2c 00 00 75 10 b8 00 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 7e e3 01 00 48 89 04 24 RSP: 002b:00007ffcd6f1c708 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 RAX: ffffffffffffffda RBX: 0000000000008000 RCX: 00007fbd314f7af0 RDX: 0000000000008000 RSI: 0000563c751ea000 RDI: 0000000000000003 RBP: 0000000000008000 R08: 0000000000009008 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000563c751ea000 R13: 0000000000000003 R14: 0000000000000003 R15: 0000563c751ea000 The problem is that the patched module's seq_operations take an RCU read lock before calling e_show(), which is patched to call static_key_disable(), which can sleep. Fix the issue by moving all the module test code to a different module (xfs) which doesn't take an RCU lock. Also enable the pr_debug() test and make the static branch test unconditional since they're supported by newer kernels and this test is for 6.2. Reported-by: Yulia Kopkova <ykopkova@redhat.com> Debugged-by: Joe Lawrence <joe.lawrence@redhat.com> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
This commit is contained in:
parent
4df1528cd9
commit
f499fc25e0
|
@ -2,12 +2,8 @@
|
|||
|
||||
set -o errexit
|
||||
|
||||
sudo modprobe nfsd
|
||||
sudo modprobe xfs
|
||||
sleep 5
|
||||
grep -q kpatch /proc/fs/nfs/exports
|
||||
|
||||
# TODO: This will trigger a printk on newer kernels which have the .klp.arch
|
||||
# removal. Don't actually do the grep until running on a newer kernel.
|
||||
echo "file fs/nfsd/export.c +p" > /sys/kernel/debug/dynamic_debug/control
|
||||
cat /proc/fs/nfs/exports > /dev/null
|
||||
# dmesg | grep -q "kpatch: pr_debug"
|
||||
echo "file fs/xfs/xfs_stats.c +p" > /sys/kernel/debug/dynamic_debug/control
|
||||
grep -q kpatch /sys/fs/xfs/stats/stats
|
||||
dmesg | grep -q "kpatch: pr_debug"
|
||||
|
|
|
@ -13,38 +13,43 @@ This tests several things related to the patching of modules:
|
|||
|
||||
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
|
||||
diff -Nupr src.orig/fs/nfsd/export.c src/fs/nfsd/export.c
|
||||
--- src.orig/fs/nfsd/export.c 2023-01-12 11:20:07.174710504 -0500
|
||||
+++ src/fs/nfsd/export.c 2023-01-12 11:20:46.075941153 -0500
|
||||
@@ -1294,6 +1294,10 @@ static void exp_flags(struct seq_file *m
|
||||
}
|
||||
diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c
|
||||
index 90a77cd3ebad..f65df90ae8e1 100644
|
||||
--- a/fs/xfs/xfs_stats.c
|
||||
+++ b/fs/xfs/xfs_stats.c
|
||||
@@ -16,6 +16,8 @@ static int counter_val(struct xfsstats __percpu *stats, int idx)
|
||||
return val;
|
||||
}
|
||||
|
||||
+#include <linux/version.h>
|
||||
+extern char *kpatch_string(void);
|
||||
+
|
||||
+__attribute__((optimize("-fno-optimize-sibling-calls")))
|
||||
static int e_show(struct seq_file *m, void *p)
|
||||
int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
|
||||
{
|
||||
struct cache_head *cp = p;
|
||||
@@ -1301,12 +1305,36 @@ static int e_show(struct seq_file *m, vo
|
||||
struct cache_detail *cd = m->private;
|
||||
bool export_stats = is_export_stats_file(m);
|
||||
int i, j;
|
||||
@@ -85,6 +87,34 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
|
||||
0);
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_X86_64
|
||||
+ alternative("ud2", "call single_task_running", X86_FEATURE_ALWAYS);
|
||||
+ alternative("call single_task_running", "ud2", X86_FEATURE_IA64);
|
||||
+ /* Reference a symbol outside the .o yet inside the patch module: */
|
||||
+ len += scnprintf(buf + len, PATH_MAX-len, "%s\n", kpatch_string());
|
||||
+
|
||||
+#ifdef CONFIG_X86_64
|
||||
+ /* Test alternatives patching: */
|
||||
+ alternative("ud2", "nop", X86_FEATURE_ALWAYS);
|
||||
+ alternative("nop", "ud2", X86_FEATURE_IA64);
|
||||
+
|
||||
+ /* Test paravirt patching: */
|
||||
+ slow_down_io(); /* paravirt call */
|
||||
+#endif
|
||||
+
|
||||
+ /* Test pr_debug: */
|
||||
+ pr_debug("kpatch: pr_debug() test\n");
|
||||
+
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
+{
|
||||
+ /* Test static branches: */
|
||||
+ static DEFINE_STATIC_KEY_TRUE(kpatch_key);
|
||||
+
|
||||
+ if (static_branch_unlikely(&memcg_kmem_enabled_key))
|
||||
+ if (static_branch_unlikely(&memcg_kmem_enabled_key))
|
||||
+ printk("kpatch: memcg_kmem_enabled_key\n");
|
||||
+
|
||||
+ BUG_ON(!static_branch_likely(&kpatch_key));
|
||||
|
@ -52,28 +57,21 @@ diff -Nupr src.orig/fs/nfsd/export.c src/fs/nfsd/export.c
|
|||
+ BUG_ON(static_branch_likely(&kpatch_key));
|
||||
+ static_branch_enable(&kpatch_key);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
if (p == SEQ_START_TOKEN) {
|
||||
seq_puts(m, "# Version 1.1\n");
|
||||
if (export_stats)
|
||||
seq_puts(m, "# Path Client Start-time\n#\tStats\n");
|
||||
else
|
||||
seq_puts(m, "# Path Client(Flags) # IPs\n");
|
||||
+ seq_puts(m, kpatch_string());
|
||||
return 0;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
diff -Nupr src.orig/net/netlink/af_netlink.c src/net/netlink/af_netlink.c
|
||||
--- src.orig/net/netlink/af_netlink.c 2023-01-12 11:20:07.603713047 -0500
|
||||
+++ src/net/netlink/af_netlink.c 2023-01-12 11:20:46.076941159 -0500
|
||||
@@ -2970,4 +2970,9 @@ panic:
|
||||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
|
||||
index c64277659753..05b753c2ec84 100644
|
||||
--- a/net/netlink/af_netlink.c
|
||||
+++ b/net/netlink/af_netlink.c
|
||||
@@ -2980,4 +2980,9 @@ static int __init netlink_proto_init(void)
|
||||
panic("netlink_init: Cannot allocate nl_table\n");
|
||||
}
|
||||
|
||||
+char *kpatch_string(void)
|
||||
+{
|
||||
+ return "# kpatch\n";
|
||||
+ return "kpatch";
|
||||
+}
|
||||
+
|
||||
core_initcall(netlink_proto_init);
|
||||
|
|
Loading…
Reference in New Issue