[to-be-updated] kexec-prevent-removal-of-memory-in-use-by-a-loaded-kexec-image.patch removed from -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     Subject: kexec: prevent removal of memory in use by a loaded kexec image
has been removed from the -mm tree.  Its filename was
     kexec-prevent-removal-of-memory-in-use-by-a-loaded-kexec-image.patch

This patch was dropped because an updated version will be merged

------------------------------------------------------
From: James Morse <james.morse@xxxxxxx>
Subject: kexec: prevent removal of memory in use by a loaded kexec image

Patch series "kexec/memory_hotplug: Prevent removal and accidental use".

arm64 recently queued support for memory hotremove, which led to some new
corner cases for kexec.

If the kexec segments are loaded for a removable region, that region may
be removed before kexec actually occurs.  This causes the first kernel to
lockup when applying the relocations.  (I've triggered this on x86 too).

The first patch adds a memory notifier for kexec so that it can refuse to
allow in-use regions to be taken offline.

This doesn't solve the problem for arm64, where the new kernel must
initially rely on the data structures from the first boot to describe
memory.  These don't describe hotpluggable memory.  If kexec places the
kernel in one of these regions, it must also provide a DT that describes
the region in which the kernel was mapped as memory.  (and somehow ensure
its always present in the future...)

To prevent this from happening accidentally with unaware user-space,
patches two and three allow arm64 to give these regions a different name.

This is a change in behaviour for arm64 as memory hotadd and hotremove
were added separately.

I haven't tried kdump.  Unaware kdump from user-space probably won't
describe the hotplug regions if the name is different, which saves us from
problems if the memory is no longer present at kdump time, but means the
vmcore is incomplete.


This patch (of 3):

An image loaded for kexec is not stored in place, instead its segments are
scattered through memory, and are re-assembled when needed.  In the
meantime, the target memory may have been removed.

Because mm is not aware that this memory is still in use, it allows it
to be removed.

Add a memory notifier to prevent the removal of memory regions that
overlap with a loaded kexec image segment.  e.g., when triggered from the
Qemu console:

| kexec_core: memory region in use
| memory memory32: Offline failed.

Kexec allows user-space to specify the address that the kexec image
should be loaded to.  Because this memory may be in use, an image
loaded for kexec is not stored in place, instead its segments are
scattered through memory, and are re-assembled when needed.  In the
meantime, the target memory may have been removed.

The target is described by user space during kexec_load() and that user
space - right now - parses /proc/iomem to find applicable system
memory.

Link: http://lkml.kernel.org/r/20200326180730.4754-1-james.morse@xxxxxxx
Link: http://lkml.kernel.org/r/20200326180730.4754-2-james.morse@xxxxxxx
Signed-off-by: James Morse <james.morse@xxxxxxx>
Cc: Eric Biederman <ebiederm@xxxxxxxxxxxx>
Cc: Catalin Marinas <catalin.marinas@xxxxxxx>
Cc: Will Deacon <will@xxxxxxxxxx>
Cc: Anshuman Khandual <anshuman.khandual@xxxxxxx>
Cc: Bhupesh Sharma <bhsharma@xxxxxxxxxx>
Cc: David Hildenbrand <david@xxxxxxxxxx>
Cc: Michal Hocko <mhocko@xxxxxxxxxx>
Cc: piliu <piliu@xxxxxxxxxx>
Cc: Dave Young <dyoung@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 kernel/kexec_core.c |   56 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

--- a/kernel/kexec_core.c~kexec-prevent-removal-of-memory-in-use-by-a-loaded-kexec-image
+++ a/kernel/kexec_core.c
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/kexec.h>
+#include <linux/memory.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/highmem.h>
@@ -22,10 +23,12 @@
 #include <linux/elf.h>
 #include <linux/elfcore.h>
 #include <linux/utsname.h>
+#include <linux/notifier.h>
 #include <linux/numa.h>
 #include <linux/suspend.h>
 #include <linux/device.h>
 #include <linux/freezer.h>
+#include <linux/pfn.h>
 #include <linux/pm.h>
 #include <linux/cpu.h>
 #include <linux/uaccess.h>
@@ -1219,3 +1222,56 @@ void __weak arch_kexec_protect_crashkres
 
 void __weak arch_kexec_unprotect_crashkres(void)
 {}
+
+/*
+ * If user-space wants to offline memory that is in use by a loaded kexec
+ * image, it should unload the image first.
+ */
+static int mem_remove_cb(struct notifier_block *nb, unsigned long action,
+			 void *data)
+{
+	int rv = NOTIFY_OK, i;
+	struct memory_notify *arg = data;
+	unsigned long pfn = arg->start_pfn;
+	unsigned long nr_segments, sstart, send;
+	unsigned long end_pfn = arg->start_pfn + arg->nr_pages;
+
+	might_sleep();
+
+	if (action != MEM_GOING_OFFLINE)
+		return NOTIFY_DONE;
+
+	mutex_lock(&kexec_mutex);
+	if (kexec_image) {
+		nr_segments = kexec_image->nr_segments;
+
+		for (i = 0; i < nr_segments; i++) {
+			sstart = PFN_DOWN(kexec_image->segment[i].mem);
+			send = PFN_UP(kexec_image->segment[i].mem +
+				      kexec_image->segment[i].memsz);
+
+			if ((pfn <= sstart && sstart < end_pfn) ||
+			    (pfn <= send && send < end_pfn)) {
+				pr_warn("Memory region in use\n");
+				rv = NOTIFY_BAD;
+				break;
+			}
+		}
+	}
+	mutex_unlock(&kexec_mutex);
+
+	return rv;
+}
+
+static struct notifier_block mem_remove_nb = {
+	.notifier_call = mem_remove_cb,
+};
+
+static int __init register_mem_remove_cb(void)
+{
+	if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG))
+		return register_memory_notifier(&mem_remove_nb);
+
+	return 0;
+}
+device_initcall(register_mem_remove_cb);
_

Patches currently in -mm which might be from james.morse@xxxxxxx are

mm-memory_hotplug-allow-arch-override-of-non-boot-memory-resource-names.patch
arm64-memory-give-hotplug-memory-a-different-resource-name.patch




[Index of Archives]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux