diff options
author | David Hildenbrand <david@redhat.com> | 2019-10-18 20:19:16 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-10-29 09:19:55 +0100 |
commit | 43a2a6c2f0fb0cf76fe8850cb054f63a8c8c7dbb (patch) | |
tree | cbea8967c95206966a483648936059e669305dc0 /drivers/base | |
parent | 4d5307c099afc9ce5fe89e8acf9b3c65104d0e08 (diff) | |
download | linux-stable-43a2a6c2f0fb0cf76fe8850cb054f63a8c8c7dbb.tar.gz linux-stable-43a2a6c2f0fb0cf76fe8850cb054f63a8c8c7dbb.tar.bz2 linux-stable-43a2a6c2f0fb0cf76fe8850cb054f63a8c8c7dbb.zip |
drivers/base/memory.c: don't access uninitialized memmaps in soft_offline_page_store()
commit 641fe2e9387a36f9ee01d7c69382d1fe147a5e98 upstream.
Uninitialized memmaps contain garbage and in the worst case trigger kernel
BUGs, especially with CONFIG_PAGE_POISONING. They should not get touched.
Right now, when trying to soft-offline a PFN that resides on a memory
block that was never onlined, one gets a misleading error with
CONFIG_PAGE_POISONING:
:/# echo 5637144576 > /sys/devices/system/memory/soft_offline_page
[ 23.097167] soft offline: 0x150000 page already poisoned
But the actual result depends on the garbage in the memmap.
soft_offline_page() can only work with online pages, it returns -EIO in
case of ZONE_DEVICE. Make sure to only forward pages that are online
(iow, managed by the buddy) and, therefore, have an initialized memmap.
Add a check against pfn_to_online_page() and similarly return -EIO.
Link: http://lkml.kernel.org/r/20191010141200.8985-1-david@redhat.com
Fixes: f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") [visible after d0dc12e86b319]
Signed-off-by: David Hildenbrand <david@redhat.com>
Acked-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: <stable@vger.kernel.org> [4.13+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/memory.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 817320c7c4c1..85ee64d0a44e 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -554,6 +554,9 @@ store_soft_offline_page(struct device *dev, pfn >>= PAGE_SHIFT; if (!pfn_valid(pfn)) return -ENXIO; + /* Only online pages can be soft-offlined (esp., not ZONE_DEVICE). */ + if (!pfn_to_online_page(pfn)) + return -EIO; ret = soft_offline_page(pfn_to_page(pfn), 0); return ret == 0 ? count : ret; } |