• W
    KVM: arm64: Only reschedule if MMU_NOTIFIER_RANGE_BLOCKABLE is not set · b5331379
    Will Deacon 提交于
    When an MMU notifier call results in unmapping a range that spans multiple
    PGDs, we end up calling into cond_resched_lock() when crossing a PGD boundary,
    since this avoids running into RCU stalls during VM teardown. Unfortunately,
    if the VM is destroyed as a result of OOM, then blocking is not permitted
    and the call to the scheduler triggers the following BUG():
    
     | BUG: sleeping function called from invalid context at arch/arm64/kvm/mmu.c:394
     | in_atomic(): 1, irqs_disabled(): 0, non_block: 1, pid: 36, name: oom_reaper
     | INFO: lockdep is turned off.
     | CPU: 3 PID: 36 Comm: oom_reaper Not tainted 5.8.0 #1
     | Hardware name: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015
     | Call trace:
     |  dump_backtrace+0x0/0x284
     |  show_stack+0x1c/0x28
     |  dump_stack+0xf0/0x1a4
     |  ___might_sleep+0x2bc/0x2cc
     |  unmap_stage2_range+0x160/0x1ac
     |  kvm_unmap_hva_range+0x1a0/0x1c8
     |  kvm_mmu_notifier_invalidate_range_start+0x8c/0xf8
     |  __mmu_notifier_invalidate_range_start+0x218/0x31c
     |  mmu_notifier_invalidate_range_start_nonblock+0x78/0xb0
     |  __oom_reap_task_mm+0x128/0x268
     |  oom_reap_task+0xac/0x298
     |  oom_reaper+0x178/0x17c
     |  kthread+0x1e4/0x1fc
     |  ret_from_fork+0x10/0x30
    
    Use the new 'flags' argument to kvm_unmap_hva_range() to ensure that we
    only reschedule if MMU_NOTIFIER_RANGE_BLOCKABLE is set in the notifier
    flags.
    
    Cc: <stable@vger.kernel.org>
    Fixes: 8b3405e3 ("kvm: arm/arm64: Fix locking for kvm_free_stage2_pgd")
    Cc: Marc Zyngier <maz@kernel.org>
    Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
    Cc: James Morse <james.morse@arm.com>
    Signed-off-by: NWill Deacon <will@kernel.org>
    Message-Id: <20200811102725.7121-3-will@kernel.org>
    Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
    b5331379
mmu.c 68.2 KB