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 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.