Re: [PATCH V2 1/2] efi/unaccepted: Do not let /proc/vmcore try to access unaccepted memory
On 12/09/23 10:19, David Hildenbrand wrote: > On 11.09.23 13:21, Adrian Hunter wrote: >> Support for unaccepted memory was added recently, refer commit dcdfdd40fa82 >> ("mm: Add support for unaccepted memory"), whereby a virtual machine may >> need to accept memory before it can be used. >> >> Do not let /proc/vmcore try to access unaccepted memory because it can >> cause the guest to fail. > > Oh, hold on. What are the actual side effects of this? > > Once we're in the kdump kernel, any guest is already dead. So failing a guest > doesn't apply, no? > Unaccepted Memory is used by virtual machines. In this case the guest has kexec'ed to a dump-capture kernel, so the virtual machine is still alive and running the dump-capture kernel. ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH V2 2/2] proc/kcore: Do not try to access unaccepted memory
Support for unaccepted memory was added recently, refer commit dcdfdd40fa82 ("mm: Add support for unaccepted memory"), whereby a virtual machine may need to accept memory before it can be used. Do not try to access unaccepted memory because it can cause the guest to fail. For /proc/kcore, which is read-only and does not support mmap, this means a read of unaccepted memory will return zeros. Signed-off-by: Adrian Hunter --- fs/proc/kcore.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) Changes in V2: Change patch subject and commit message Do not open code pfn_is_unaccepted_memory() diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 23fc24d16b31..6422e569b080 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -546,7 +546,8 @@ static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter) * and explicitly excluded physical ranges. */ if (!page || PageOffline(page) || - is_page_hwpoison(page) || !pfn_is_ram(pfn)) { + is_page_hwpoison(page) || !pfn_is_ram(pfn) || + pfn_is_unaccepted_memory(pfn)) { if (iov_iter_zero(tsz, iter) != tsz) { ret = -EFAULT; goto out; -- 2.34.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH V2 0/2] Do not try to access unaccepted memory
Hi Support for unaccepted memory was added recently, refer commit dcdfdd40fa82 ("mm: Add support for unaccepted memory"), whereby a virtual machine may need to accept memory before it can be used. Plug a few gaps where RAM is exposed without checking if it is unaccepted memory. Changes in V2: efi/unaccepted: Do not let /proc/vmcore try to access unaccepted memory Change patch subject and commit message Use vmcore_cb->.pfn_is_ram() instead of changing vmcore.c proc/kcore: Do not try to access unaccepted memory Change patch subject and commit message Do not open code pfn_is_unaccepted_memory() /dev/mem: Do not map unaccepted memory Patch dropped because it is not required Adrian Hunter (2): efi/unaccepted: Do not let /proc/vmcore try to access unaccepted memory proc/kcore: Do not try to access unaccepted memory drivers/firmware/efi/unaccepted_memory.c | 20 fs/proc/kcore.c | 3 ++- include/linux/mm.h | 7 +++ 3 files changed, 29 insertions(+), 1 deletion(-) Regards Adrian ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH V2 1/2] efi/unaccepted: Do not let /proc/vmcore try to access unaccepted memory
Support for unaccepted memory was added recently, refer commit dcdfdd40fa82 ("mm: Add support for unaccepted memory"), whereby a virtual machine may need to accept memory before it can be used. Do not let /proc/vmcore try to access unaccepted memory because it can cause the guest to fail. For /proc/vmcore, which is read-only, this means a read or mmap of unaccepted memory will return zeros. Signed-off-by: Adrian Hunter --- drivers/firmware/efi/unaccepted_memory.c | 20 include/linux/mm.h | 7 +++ 2 files changed, 27 insertions(+) Changes in V2: Change patch subject and commit message Use vmcore_cb->.pfn_is_ram() instead of changing vmcore.c diff --git a/drivers/firmware/efi/unaccepted_memory.c b/drivers/firmware/efi/unaccepted_memory.c index 853f7dc3c21d..79ba576b22e3 100644 --- a/drivers/firmware/efi/unaccepted_memory.c +++ b/drivers/firmware/efi/unaccepted_memory.c @@ -3,6 +3,7 @@ #include #include #include +#include #include /* Protects unaccepted memory bitmap */ @@ -145,3 +146,22 @@ bool range_contains_unaccepted_memory(phys_addr_t start, phys_addr_t end) return ret; } + +#ifdef CONFIG_PROC_VMCORE +static bool unaccepted_memory_vmcore_pfn_is_ram(struct vmcore_cb *cb, + unsigned long pfn) +{ + return !pfn_is_unaccepted_memory(pfn); +} + +static struct vmcore_cb vmcore_cb = { + .pfn_is_ram = unaccepted_memory_vmcore_pfn_is_ram, +}; + +static int __init unaccepted_memory_init_kdump(void) +{ + register_vmcore_cb(&vmcore_cb); + return 0; +} +core_initcall(unaccepted_memory_init_kdump); +#endif /* CONFIG_PROC_VMCORE */ diff --git a/include/linux/mm.h b/include/linux/mm.h index bf5d0b1b16f4..86511150f1d4 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -4062,4 +4062,11 @@ static inline void accept_memory(phys_addr_t start, phys_addr_t end) #endif +static inline bool pfn_is_unaccepted_memory(unsigned long pfn) +{ + phys_addr_t paddr = pfn << PAGE_SHIFT; + + return range_contains_unaccepted_memory(paddr, paddr + PAGE_SIZE); +} + #endif /* _LINUX_MM_H */ -- 2.34.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH 1/3] proc/vmcore: Do not map unaccepted memory
On 7/09/23 18:39, Dave Hansen wrote: > On 9/6/23 00:39, Adrian Hunter wrote: >> @@ -559,7 +567,8 @@ static int vmcore_remap_oldmem_pfn(struct vm_area_struct >> *vma, >> * pages without a reason. >> */ >> idx = srcu_read_lock(&vmcore_cb_srcu); >> -if (!list_empty(&vmcore_cb_list)) >> +if (!list_empty(&vmcore_cb_list) || >> +range_contains_unaccepted_memory(paddr, paddr + size)) >> ret = remap_oldmem_pfn_checked(vma, from, pfn, size, prot); >> else >> ret = remap_oldmem_pfn_range(vma, from, pfn, size, prot); > > The whole callback mechanism which fs/proc/vmcore.c::pfn_is_ram() > implements seems to be in place to ensure that there aren't a billion > different "ram" checks in here. > > Is there a reason you can't register_vmcore_cb() a callback to check for > unaccepted memory? Someone asked for the change to be in arch-independent code... ;-) ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH 1/3] proc/vmcore: Do not map unaccepted memory
Support for unaccepted memory was added recently, refer commit dcdfdd40fa82 ("mm: Add support for unaccepted memory"), whereby a virtual machine may need to accept memory before it can be used. Do not map unaccepted memory because it can cause the guest to fail. For /proc/vmcore, which is read-only, this means a read or mmap of unaccepted memory will return zeros. Fixes: dcdfdd40fa82 ("mm: Add support for unaccepted memory") Signed-off-by: Adrian Hunter --- fs/proc/vmcore.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 1fb213f379a5..a28da2033ce8 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -118,6 +118,13 @@ static bool pfn_is_ram(unsigned long pfn) return ret; } +static bool pfn_is_unaccepted_memory(unsigned long pfn) +{ + phys_addr_t paddr = pfn << PAGE_SHIFT; + + return range_contains_unaccepted_memory(paddr, paddr + PAGE_SIZE); +} + static int open_vmcore(struct inode *inode, struct file *file) { spin_lock(&vmcore_cb_lock); @@ -150,7 +157,7 @@ ssize_t read_from_oldmem(struct iov_iter *iter, size_t count, nr_bytes = count; /* If pfn is not ram, return zeros for sparse dump files */ - if (!pfn_is_ram(pfn)) { + if (!pfn_is_ram(pfn) || pfn_is_unaccepted_memory(pfn)) { tmp = iov_iter_zero(nr_bytes, iter); } else { if (encrypted) @@ -511,7 +518,7 @@ static int remap_oldmem_pfn_checked(struct vm_area_struct *vma, pos_end = pfn + (size >> PAGE_SHIFT); for (pos = pos_start; pos < pos_end; ++pos) { - if (!pfn_is_ram(pos)) { + if (!pfn_is_ram(pos) || pfn_is_unaccepted_memory(pos)) { /* * We hit a page which is not ram. Remap the continuous * region between pos_start and pos-1 and replace @@ -552,6 +559,7 @@ static int vmcore_remap_oldmem_pfn(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot) { + phys_addr_t paddr = pfn << PAGE_SHIFT; int ret, idx; /* @@ -559,7 +567,8 @@ static int vmcore_remap_oldmem_pfn(struct vm_area_struct *vma, * pages without a reason. */ idx = srcu_read_lock(&vmcore_cb_srcu); - if (!list_empty(&vmcore_cb_list)) + if (!list_empty(&vmcore_cb_list) || + range_contains_unaccepted_memory(paddr, paddr + size)) ret = remap_oldmem_pfn_checked(vma, from, pfn, size, prot); else ret = remap_oldmem_pfn_range(vma, from, pfn, size, prot); -- 2.34.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH 3/3] /dev/mem: Do not map unaccepted memory
Support for unaccepted memory was added recently, refer commit dcdfdd40fa82 ("mm: Add support for unaccepted memory"), whereby a virtual machine may need to accept memory before it can be used. Do not map unaccepted memory because it can cause the guest to fail. For /dev/mem, this means a read of unaccepted memory will return zeros, a write to unaccepted memory will be ignored, but an mmap of unaccepted memory will return an error. Fixes: dcdfdd40fa82 ("mm: Add support for unaccepted memory") Signed-off-by: Adrian Hunter --- drivers/char/mem.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 1052b0f2d4cf..1a7c5728783c 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -147,7 +147,8 @@ static ssize_t read_mem(struct file *file, char __user *buf, goto failed; err = -EFAULT; - if (allowed == 2) { + if (allowed == 2 || + range_contains_unaccepted_memory(p, p + sz)) { /* Show zeros for restricted memory. */ remaining = clear_user(buf, sz); } else { @@ -226,7 +227,8 @@ static ssize_t write_mem(struct file *file, const char __user *buf, return -EPERM; /* Skip actual writing when a page is marked as restricted. */ - if (allowed == 1) { + if (allowed == 1 && + !range_contains_unaccepted_memory(p, p + sz)) { /* * On ia64 if a page has been mapped somewhere as * uncached, then it must also be accessed uncached @@ -378,6 +380,9 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma) &vma->vm_page_prot)) return -EINVAL; + if (range_contains_unaccepted_memory(offset, offset + size)) + return -EINVAL; + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, size, vma->vm_page_prot); -- 2.34.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH 0/3] Do not map unaccepted memory
Hi Support for unaccepted memory was added recently, refer commit dcdfdd40fa82 ("mm: Add support for unaccepted memory"), whereby a virtual machine may need to accept memory before it can be used. Plug a few gaps where RAM is exposed without checking if it is unaccepted memory. Adrian Hunter (3): proc/vmcore: Do not map unaccepted memory proc/kcore: Do not map unaccepted memory /dev/mem: Do not map unaccepted memory drivers/char/mem.c | 9 +++-- fs/proc/kcore.c| 10 +- fs/proc/vmcore.c | 15 --- 3 files changed, 28 insertions(+), 6 deletions(-) Regards Adrian ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[PATCH 2/3] proc/kcore: Do not map unaccepted memory
Support for unaccepted memory was added recently, refer commit dcdfdd40fa82 ("mm: Add support for unaccepted memory"), whereby a virtual machine may need to accept memory before it can be used. Do not map unaccepted memory because it can cause the guest to fail. For /proc/kcore, which is read-only and does not support mmap, this means a read of unaccepted memory will return zeros. Fixes: dcdfdd40fa82 ("mm: Add support for unaccepted memory") Signed-off-by: Adrian Hunter --- fs/proc/kcore.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 23fc24d16b31..a3091c5ed871 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -76,6 +76,13 @@ static int pfn_is_ram(unsigned long pfn) return 1; } +static bool pfn_is_unaccepted_memory(unsigned long pfn) +{ + phys_addr_t paddr = pfn << PAGE_SHIFT; + + return range_contains_unaccepted_memory(paddr, paddr + PAGE_SIZE); +} + /* This doesn't grab kclist_lock, so it should only be used at init time. */ void __init kclist_add(struct kcore_list *new, void *addr, size_t size, int type) @@ -546,7 +553,8 @@ static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter) * and explicitly excluded physical ranges. */ if (!page || PageOffline(page) || - is_page_hwpoison(page) || !pfn_is_ram(pfn)) { + is_page_hwpoison(page) || !pfn_is_ram(pfn) || + pfn_is_unaccepted_memory(pfn)) { if (iov_iter_zero(tsz, iter) != tsz) { ret = -EFAULT; goto out; -- 2.34.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec