From: David Hildenbrand <david@redhat.com>
To: stable@vger.kernel.org
Cc: Wupeng Ma <mawupeng1@huawei.com>, Ingo Molnar <mingo@kernel.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
Andy Lutomirski <luto@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Thomas Gleixner <tglx@linutronix.de>,
Borislav Petkov <bp@alien8.de>, "H. Peter Anvin" <hpa@zytor.com>
Subject: Re: [PATCH 5.10.y] x86/mm/pat: fix VM_PAT handling in COW mappings
Date: Wed, 10 Apr 2024 11:55:12 +0200 [thread overview]
Message-ID: <3469eb7f-96b5-4efa-b3de-82c956809038@redhat.com> (raw)
In-Reply-To: <20240410094355.182476-1-david@redhat.com>
On 10.04.24 11:43, David Hildenbrand wrote:
> PAT handling won't do the right thing in COW mappings: the first PTE (or,
> in fact, all PTEs) can be replaced during write faults to point at anon
> folios. Reliably recovering the correct PFN and cachemode using
> follow_phys() from PTEs will not work in COW mappings.
>
> Using follow_phys(), we might just get the address+protection of the anon
> folio (which is very wrong), or fail on swap/nonswap entries, failing
> follow_phys() and triggering a WARN_ON_ONCE() in untrack_pfn() and
> track_pfn_copy(), not properly calling free_pfn_range().
>
> In free_pfn_range(), we either wouldn't call memtype_free() or would call
> it with the wrong range, possibly leaking memory.
>
> To fix that, let's update follow_phys() to refuse returning anon folios,
> and fallback to using the stored PFN inside vma->vm_pgoff for COW mappings
> if we run into that.
>
> We will now properly handle untrack_pfn() with COW mappings, where we
> don't need the cachemode. We'll have to fail fork()->track_pfn_copy() if
> the first page was replaced by an anon folio, though: we'd have to store
> the cachemode in the VMA to make this work, likely growing the VMA size.
>
> For now, lets keep it simple and let track_pfn_copy() just fail in that
> case: it would have failed in the past with swap/nonswap entries already,
> and it would have done the wrong thing with anon folios.
>
> Simple reproducer to trigger the WARN_ON_ONCE() in untrack_pfn():
>
> <--- C reproducer --->
> #include <stdio.h>
> #include <sys/mman.h>
> #include <unistd.h>
> #include <liburing.h>
>
> int main(void)
> {
> struct io_uring_params p = {};
> int ring_fd;
> size_t size;
> char *map;
>
> ring_fd = io_uring_setup(1, &p);
> if (ring_fd < 0) {
> perror("io_uring_setup");
> return 1;
> }
> size = p.sq_off.array + p.sq_entries * sizeof(unsigned);
>
> /* Map the submission queue ring MAP_PRIVATE */
> map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
> ring_fd, IORING_OFF_SQ_RING);
> if (map == MAP_FAILED) {
> perror("mmap");
> return 1;
> }
>
> /* We have at least one page. Let's COW it. */
> *map = 0;
> pause();
> return 0;
> }
> <--- C reproducer --->
>
> On a system with 16 GiB RAM and swap configured:
> # ./iouring &
> # memhog 16G
> # killall iouring
> [ 301.552930] ------------[ cut here ]------------
> [ 301.553285] WARNING: CPU: 7 PID: 1402 at arch/x86/mm/pat/memtype.c:1060 untrack_pfn+0xf4/0x100
> [ 301.553989] Modules linked in: binfmt_misc nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_g
> [ 301.558232] CPU: 7 PID: 1402 Comm: iouring Not tainted 6.7.5-100.fc38.x86_64 #1
> [ 301.558772] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebu4
> [ 301.559569] RIP: 0010:untrack_pfn+0xf4/0x100
> [ 301.559893] Code: 75 c4 eb cf 48 8b 43 10 8b a8 e8 00 00 00 3b 6b 28 74 b8 48 8b 7b 30 e8 ea 1a f7 000
> [ 301.561189] RSP: 0018:ffffba2c0377fab8 EFLAGS: 00010282
> [ 301.561590] RAX: 00000000ffffffea RBX: ffff9208c8ce9cc0 RCX: 000000010455e047
> [ 301.562105] RDX: 07fffffff0eb1e0a RSI: 0000000000000000 RDI: ffff9208c391d200
> [ 301.562628] RBP: 0000000000000000 R08: ffffba2c0377fab8 R09: 0000000000000000
> [ 301.563145] R10: ffff9208d2292d50 R11: 0000000000000002 R12: 00007fea890e0000
> [ 301.563669] R13: 0000000000000000 R14: ffffba2c0377fc08 R15: 0000000000000000
> [ 301.564186] FS: 0000000000000000(0000) GS:ffff920c2fbc0000(0000) knlGS:0000000000000000
> [ 301.564773] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 301.565197] CR2: 00007fea88ee8a20 CR3: 00000001033a8000 CR4: 0000000000750ef0
> [ 301.565725] PKRU: 55555554
> [ 301.565944] Call Trace:
> [ 301.566148] <TASK>
> [ 301.566325] ? untrack_pfn+0xf4/0x100
> [ 301.566618] ? __warn+0x81/0x130
> [ 301.566876] ? untrack_pfn+0xf4/0x100
> [ 301.567163] ? report_bug+0x171/0x1a0
> [ 301.567466] ? handle_bug+0x3c/0x80
> [ 301.567743] ? exc_invalid_op+0x17/0x70
> [ 301.568038] ? asm_exc_invalid_op+0x1a/0x20
> [ 301.568363] ? untrack_pfn+0xf4/0x100
> [ 301.568660] ? untrack_pfn+0x65/0x100
> [ 301.568947] unmap_single_vma+0xa6/0xe0
> [ 301.569247] unmap_vmas+0xb5/0x190
> [ 301.569532] exit_mmap+0xec/0x340
> [ 301.569801] __mmput+0x3e/0x130
> [ 301.570051] do_exit+0x305/0xaf0
> ...
>
> Link: https://lkml.kernel.org/r/20240403212131.929421-3-david@redhat.com
> Signed-off-by: David Hildenbrand <david@redhat.com>
> Reported-by: Wupeng Ma <mawupeng1@huawei.com>
> Closes: https://lkml.kernel.org/r/20240227122814.3781907-1-mawupeng1@huawei.com
> Fixes: b1a86e15dc03 ("x86, pat: remove the dependency on 'vm_pgoff' in track/untrack pfn vma routines")
> Fixes: 5899329b1910 ("x86: PAT: implement track/untrack of pfnmap regions for x86 - v3")
> Acked-by: Ingo Molnar <mingo@kernel.org>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> (cherry picked from commit 04c35ab3bdae7fefbd7c7a7355f29fa03a035221)
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
Backport notes:
(1) #include "../....//mm/internal.h" to make it compile
(2) vm_normal_folio -> vm_normal_page
(3) follow_phys() is also used in generic_access_phys(), where we would
now also reject anon pages. I don't think we care.
--
Cheers,
David / dhildenb
prev parent reply other threads:[~2024-04-10 9:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-08 9:28 FAILED: patch "[PATCH] x86/mm/pat: fix VM_PAT handling in COW mappings" failed to apply to 5.10-stable tree gregkh
2024-04-10 9:43 ` [PATCH 5.10.y] x86/mm/pat: fix VM_PAT handling in COW mappings David Hildenbrand
2024-04-10 9:55 ` David Hildenbrand [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3469eb7f-96b5-4efa-b3de-82c956809038@redhat.com \
--to=david@redhat.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=luto@kernel.org \
--cc=mawupeng1@huawei.com \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=stable@vger.kernel.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.