From: Konstantin Khorenko <khorenko@virtuozzo.com>
To: OpenVZ devel list <devel@openvz.org>
Subject: Re: [Devel] [PATCH vz10 12/24] oracle/mm: enter COW seqcount/mmu-notifier section in copy_page_range_mt()
Date: Wed, 14 Oct 2026 22:06:50 +0200 [thread overview]
Message-ID: <dbf89080-c778-439f-b599-6d9580dbe975@virtuozzo.com> (raw)
In-Reply-To: <f1a6f877-a8f3-48ae-b435-9192fd846399@virtuozzo.com>
i'm dropping this patch.
The bug is fixed by another patch, taken from Oracle UEK8 kernel:
[PATCH hci-8.1 1/8] oracle/mm: fix VM_BUG_ON hit when preserving memory
--
Best regards,
Konstantin Khorenko,
Virtuozzo Linux Kernel Team
On 7/24/26 15:09, Pavel Tikhomirov wrote:
> Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
>
> This is really non-obvious, the logic behind "mirroring" is sound, also
> we should report this to oracle, I don't see full miroring there, they have
> raw_write_seqcount_begin(), but not mmu_notifier_...
>
> On 7/6/26 12:59, Konstantin Khorenko wrote:
>> copy_page_range_mt() is the padata-multithreaded copy used by vma_dup()
>> to preserve a VM_EXEC_KEEP (MADV_DOEXEC) VMA across exec. A MADV_DOEXEC
>> VMA is private anon, so is_cow_mapping() is true and the copy write
>> protects the source PTEs - a permission downgrade. Unlike the normal
>> fork path copy_page_range(), this helper jumped straight into
>> padata_do_multithreaded() without the COW prologue/epilogue, so it:
>>
>> - never entered src_mm->write_protect_seq (left it even), which trips
>> the DEBUG_VM invariant in folio_needs_cow_for_dma() reached from
>> folio_try_dup_anon_rmap_pte() during the copy:
>>
>> kernel BUG at include/linux/mm.h:2054!
>> copy_present_ptes <- copy_pte_range <- copy_page_range_chunk
>> <- padata_do_multithreaded <- copy_page_range_mt <- vma_dup
>> <- exec_mmap <- begin_new_exec <- load_elf_binary
>>
>> - never called mmu_notifier_invalidate_range_start/end(), a real latent
>> bug: a secondary MMU (KVM, IOMMU SVA, GPU) registered on the old mm
>> outlives de_thread() and could keep writable mappings of pages whose
>> PTEs the exec copy just wrprotected and shared into the new mm.
>>
>> Mirror copy_page_range(): for a COW mapping, invalidate secondary MMUs
>> and take the write_protect_seq write side around the padata job. The
>> exec'ing task is single-threaded by now and is the only user of src_mm,
>> so there is no concurrent seqcount writer (fork needs mmap_write_lock)
>> or GUP-fast reader; taking the raw write side while holding only
>> mmap_read_lock is safe, which is why vma_assert_write_locked() from
>> copy_page_range() is intentionally not carried over here.
>>
>> Fixes: 11e4b1dc50e3 ("oracle/mm: use padata for copying page ranges in vma_dup()")
>> Feature: oracle/mm: MADV_DOEXEC madvise() flag
>> https://virtuozzo.atlassian.net/browse/VSTOR-137234
>> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
>> ---
>> mm/memory.c | 35 ++++++++++++++++++++++++++++++++++-
>> 1 file changed, 34 insertions(+), 1 deletion(-)
>>
>> diff --git a/mm/memory.c b/mm/memory.c
>> index 837194e87664..4d04591f8f40 100644
>> --- a/mm/memory.c
>> +++ b/mm/memory.c
>> @@ -1478,6 +1478,10 @@ static int copy_page_range_chunk(unsigned long addr,
>> int copy_page_range_mt(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
>> {
>> struct copy_page_range_args args = { dst_vma, src_vma };
>> + struct mm_struct *src_mm = src_vma->vm_mm;
>> + struct mmu_notifier_range range;
>> + bool is_cow;
>> + int ret;
>> struct padata_mt_job job = {
>> .thread_fn = copy_page_range_chunk,
>> .fn_arg = &args,
>> @@ -1490,7 +1494,36 @@ int copy_page_range_mt(struct vm_area_struct *dst_vma, struct vm_area_struct *sr
>>
>> BUG_ON(!(src_vma->vm_flags & VM_EXEC_KEEP));
>>
>> - return padata_do_multithreaded(&job);
>> + /*
>> + * Mirror copy_page_range(): for a COW mapping the copy write
>> + * protects the source PTEs, which is a permission downgrade, so
>> + * secondary MMUs must be invalidated, and write_protect_seq must be
>> + * entered (odd) so GUP-fast cannot race with the wrprotect
>> + * (folio_needs_cow_for_dma() asserts this under CONFIG_DEBUG_VM).
>> + *
>> + * The exec'ing task is single-threaded by now and the only user of
>> + * src_mm, so no concurrent write_protect_seq writer (fork, which
>> + * needs mmap_write_lock) or GUP-fast reader can exist; taking the
>> + * raw write side while holding only mmap_read_lock is safe here, and
>> + * the padata helper threads only read the seqcount.
>> + */
>> + is_cow = is_cow_mapping(src_vma->vm_flags);
>> + if (is_cow) {
>> + mmu_notifier_range_init(&range, MMU_NOTIFY_PROTECTION_PAGE,
>> + 0, src_mm, src_vma->vm_start,
>> + src_vma->vm_end);
>> + mmu_notifier_invalidate_range_start(&range);
>> + raw_write_seqcount_begin(&src_mm->write_protect_seq);
>> + }
>> +
>> + ret = padata_do_multithreaded(&job);
>> +
>> + if (is_cow) {
>> + raw_write_seqcount_end(&src_mm->write_protect_seq);
>> + mmu_notifier_invalidate_range_end(&range);
>> + }
>> +
>> + return ret;
>> }
>> #endif /* CONFIG_PADATA */
>>
>
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
prev parent reply other threads:[~2026-10-14 20:08 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260706110002.1024515-1-khorenko@virtuozzo.com>
[not found] ` <20260706110002.1024515-8-khorenko@virtuozzo.com>
[not found] ` <970b9d91-59c9-4a6d-8494-2d58afcab4b8@virtuozzo.com>
2026-08-05 19:26 ` [Devel] [PATCH vz10 07/24] blk-cbt: don't WARN on a user-supplied ABI version mismatch Konstantin Khorenko
[not found] ` <20260706110002.1024515-13-khorenko@virtuozzo.com>
[not found] ` <f1a6f877-a8f3-48ae-b435-9192fd846399@virtuozzo.com>
2026-10-14 20:06 ` Konstantin Khorenko [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=dbf89080-c778-439f-b599-6d9580dbe975@virtuozzo.com \
--to=khorenko@virtuozzo.com \
--cc=devel@openvz.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox