Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

proc/vmcore: don't fake reading zeroes on surprise vmcore_cb unregistration

In commit cc5f2704c934 ("proc/vmcore: convert oldmem_pfn_is_ram callback
to more generic vmcore callbacks"), we added detection of surprise
vmcore_cb unregistration after the vmcore was already opened. Once
detected, we warn the user and simulate reading zeroes from that point
on when accessing the vmcore.

The basic reason was that unexpected unregistration, for example, by
manually unbinding a driver from a device after opening the vmcore, is
not supported and could result in reading oldmem the vmcore_cb would
have actually prohibited while registered. However, something like that
can similarly be trigger by a user that's really looking for trouble
simply by unbinding the relevant driver before opening the vmcore -- or
by disallowing loading the driver in the first place. So it's actually
of limited help.

Currently, unregistration can only be triggered via virtio-mem when
manually unbinding the driver from the device inside the VM; there is no
way to trigger it from the hypervisor, as hypervisors don't allow for
unplugging virtio-mem devices -- ripping out system RAM from a VM
without coordination with the guest is usually not a good idea.

The important part is that unbinding the driver and unregistering the
vmcore_cb while concurrently reading the vmcore won't crash the system,
and that is handled by the rwsem.

To make the mechanism more future proof, let's remove the "read zero"
part, but leave the warning in place. For example, we could have a
future driver (like virtio-balloon) that will contact the hypervisor to
figure out if we already populated a page for a given PFN.
Hotunplugging such a device and consequently unregistering the vmcore_cb
could be triggered from the hypervisor without harming the system even
while kdump is running. In that case, we don't want to silently end up
with a vmcore that contains wrong data, because the user inside the VM
might be unaware of the hypervisor action and might easily miss the
warning in the log.

Link: https://lkml.kernel.org/r/20211111192243.22002-1-david@redhat.com
Signed-off-by: David Hildenbrand <david@redhat.com>
Acked-by: Baoquan He <bhe@redhat.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

David Hildenbrand and committed by
Linus Torvalds
25bc5b0d 20c03576

+2 -8
+2 -8
fs/proc/vmcore.c
··· 65 65 static DECLARE_RWSEM(vmcore_cb_rwsem); 66 66 /* List of registered vmcore callbacks. */ 67 67 static LIST_HEAD(vmcore_cb_list); 68 - /* Whether we had a surprise unregistration of a callback. */ 69 - static bool vmcore_cb_unstable; 70 68 /* Whether the vmcore has been opened once. */ 71 69 static bool vmcore_opened; 72 70 ··· 92 94 * very unusual (e.g., forced driver removal), but we cannot stop 93 95 * unregistering. 94 96 */ 95 - if (vmcore_opened) { 97 + if (vmcore_opened) 96 98 pr_warn_once("Unexpected vmcore callback unregistration\n"); 97 - vmcore_cb_unstable = true; 98 - } 99 99 up_write(&vmcore_cb_rwsem); 100 100 } 101 101 EXPORT_SYMBOL_GPL(unregister_vmcore_cb); ··· 104 108 bool ret = true; 105 109 106 110 lockdep_assert_held_read(&vmcore_cb_rwsem); 107 - if (unlikely(vmcore_cb_unstable)) 108 - return false; 109 111 110 112 list_for_each_entry(cb, &vmcore_cb_list, next) { 111 113 if (unlikely(!cb->pfn_is_ram)) ··· 575 581 * looping over all pages without a reason. 576 582 */ 577 583 down_read(&vmcore_cb_rwsem); 578 - if (!list_empty(&vmcore_cb_list) || vmcore_cb_unstable) 584 + if (!list_empty(&vmcore_cb_list)) 579 585 ret = remap_oldmem_pfn_checked(vma, from, pfn, size, prot); 580 586 else 581 587 ret = remap_oldmem_pfn_range(vma, from, pfn, size, prot);