Skip to contentSkip to conversation

FAILED: patch "[PATCH] powerpc/powernv/memtrace: Fix crashing the kernel when" failed to apply to 4.14-stable tree

PATCH [email protected] 1 participant 1 message Dec 28, 2020

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From d6718941a2767fb383e105d257d2105fe4f15f0e Mon Sep 17 00:00:00 2001
From: David Hildenbrand <[email protected]>
Date: Wed, 11 Nov 2020 15:53:16 +0100
Subject: [PATCH] powerpc/powernv/memtrace: Fix crashing the kernel when
enabling concurrently

It's very easy to crash the kernel right now by simply trying to enable memtrace concurrently, hammering on the "enable" interface

loop.sh:
#!/bin/bash

  dmesg --console-off

while true; do

          echo 0x40000000 > /sys/kernel/debug/powerpc/memtrace/enable

done

[root@localhost ~]# loop.sh &
[root@localhost ~]# loop.sh &

Resulting quickly in a kernel crash. Let's properly protect using a mutex.

Fixes 9d5171a8f248 ("powerpc/powernv: Enable removal of memory for in memory tracing")
arch/powerpc/platforms/powernv/memtrace.c +15 -7
index eea1f94482ff..0e42fe2d7b6a 100644
@@ -30,6 +30,7 @@ struct memtrace_entry {
 	char name[16];
 };
 
+static DEFINE_MUTEX(memtrace_mutex);
 static u64 memtrace_size;
 
 static struct memtrace_entry *memtrace_array;
@@ -279,6 +280,7 @@ static int memtrace_online(void)
 
 static int memtrace_enable_set(void *data, u64 val)
 {
+	int rc = -EAGAIN;
 	u64 bytes;
 
 	/*
@@ -291,25 +293,31 @@ static int memtrace_enable_set(void *data, u64 val)
 		return -EINVAL;
 	}
 
+	mutex_lock(&memtrace_mutex);
+
 	/* Re-add/online previously removed/offlined memory */
 	if (memtrace_size) {
 		if (memtrace_online())
-			return -EAGAIN;
+			goto out_unlock;
 	}
 
-	if (!val)
-		return 0;
+	if (!val) {
+		rc = 0;
+		goto out_unlock;
+	}
 
 	/* Offline and remove memory */
 	if (memtrace_init_regions_runtime(val))
-		return -EINVAL;
+		goto out_unlock;
 
 	if (memtrace_init_debugfs())
-		return -EINVAL;
+		goto out_unlock;
 
 	memtrace_size = val;
-
-	return 0;
+	rc = 0;
+out_unlock:
+	mutex_unlock(&memtrace_mutex);
+	return rc;
 }
 
 static int memtrace_enable_get(void *data, u64 *val)