Skip to content

Commit

Permalink
fs/proc/task_mmu: move mmu notification mechanism inside mm lock
Browse files Browse the repository at this point in the history
Move mmu notification mechanism inside mm lock to prevent race condition
in other components which depend on it.  The notifier will invalidate
memory range.  Depending upon the number of iterations, different memory
ranges would be invalidated.

The following warning would be removed by this patch:
WARNING: CPU: 0 PID: 5067 at arch/x86/kvm/../../../virt/kvm/kvm_main.c:734 kvm_mmu_notifier_change_pte+0x860/0x960 arch/x86/kvm/../../../virt/kvm/kvm_main.c:734

There is no behavioural and performance change with this patch when
there is no component registered with the mmu notifier.

[[email protected]: narrow the scope of `range', per Sean]
Link: https://lkml.kernel.org/r/[email protected]
Fixes: 52526ca ("fs/proc/task_mmu: implement IOCTL to get and optionally clear info about PTEs")
Signed-off-by: Muhammad Usama Anjum <[email protected]>
Reported-by: [email protected]
Link: https://lore.kernel.org/all/[email protected]/
Reviewed-by: Sean Christopherson <[email protected]>
Cc: Andrei Vagin <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: David Hildenbrand <[email protected]>
Cc: Hugh Dickins <[email protected]>
Cc: Kefeng Wang <[email protected]>
Cc: Liam R. Howlett <[email protected]>
Cc: Michał Mirosław <[email protected]>
Cc: Peter Xu <[email protected]>
Cc: Ryan Roberts <[email protected]>
Cc: Stephen Rothwell <[email protected]>
Cc: Suren Baghdasaryan <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
musamaanjum authored and akpm00 committed Jan 12, 2024
1 parent ea52f71 commit 4cccb62
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions fs/proc/task_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2432,7 +2432,6 @@ static long pagemap_scan_flush_buffer(struct pagemap_scan_private *p)

static long do_pagemap_scan(struct mm_struct *mm, unsigned long uarg)
{
struct mmu_notifier_range range;
struct pagemap_scan_private p = {0};
unsigned long walk_start;
size_t n_ranges_out = 0;
Expand All @@ -2448,15 +2447,9 @@ static long do_pagemap_scan(struct mm_struct *mm, unsigned long uarg)
if (ret)
return ret;

/* Protection change for the range is going to happen. */
if (p.arg.flags & PM_SCAN_WP_MATCHING) {
mmu_notifier_range_init(&range, MMU_NOTIFY_PROTECTION_VMA, 0,
mm, p.arg.start, p.arg.end);
mmu_notifier_invalidate_range_start(&range);
}

for (walk_start = p.arg.start; walk_start < p.arg.end;
walk_start = p.arg.walk_end) {
struct mmu_notifier_range range;
long n_out;

if (fatal_signal_pending(current)) {
Expand All @@ -2467,8 +2460,20 @@ static long do_pagemap_scan(struct mm_struct *mm, unsigned long uarg)
ret = mmap_read_lock_killable(mm);
if (ret)
break;

/* Protection change for the range is going to happen. */
if (p.arg.flags & PM_SCAN_WP_MATCHING) {
mmu_notifier_range_init(&range, MMU_NOTIFY_PROTECTION_VMA, 0,
mm, walk_start, p.arg.end);
mmu_notifier_invalidate_range_start(&range);
}

ret = walk_page_range(mm, walk_start, p.arg.end,
&pagemap_scan_ops, &p);

if (p.arg.flags & PM_SCAN_WP_MATCHING)
mmu_notifier_invalidate_range_end(&range);

mmap_read_unlock(mm);

n_out = pagemap_scan_flush_buffer(&p);
Expand All @@ -2494,9 +2499,6 @@ static long do_pagemap_scan(struct mm_struct *mm, unsigned long uarg)
if (pagemap_scan_writeback_args(&p.arg, uarg))
ret = -EFAULT;

if (p.arg.flags & PM_SCAN_WP_MATCHING)
mmu_notifier_invalidate_range_end(&range);

kfree(p.vec_buf);
return ret;
}
Expand Down

0 comments on commit 4cccb62

Please sign in to comment.