KVM: arm64: Fix sleeping while atomic BUG() on OOM
Subsystems (10)
Will Deacon
maintainercover KVM: arm64: Fix sleeping while atomic BUG() on OOM
Hi all,
While stress-testing my arm64 stage-2 page-table rewrite [1], I ran into a sleeping while atomic BUG() during OOM that I can reproduce with mainline.
The problem is that the arm64 page-table code periodically calls cond_resched_lock() when unmapping the stage-2 page-tables, but in the case of OOM, this occurs in atomic context.
These couple of patches (based on 5.8) propagate the flags from the MMU notifier range structure, which in turn indicate whether or not blocking is permitted.
Cheers,
Will
[1] https://android-kvm.googlesource.com/linux/+/refs/heads/topic/pgtable
--->8
Will Deacon (2):
KVM: Pass MMU notifier range flags to kvm_unmap_hva_range()
KVM: arm64: Only reschedule if MMU_NOTIFIER_RANGE_BLOCKABLE is not set
arch/arm64/include/asm/kvm_host.h | 2 +- arch/arm64/kvm/mmu.c | 19 ++++++++++++++----- arch/mips/include/asm/kvm_host.h | 2 +- arch/mips/kvm/mmu.c | 3 ++- arch/powerpc/include/asm/kvm_host.h | 3 ++- arch/powerpc/kvm/book3s.c | 3 ++- arch/powerpc/kvm/e500_mmu_host.c | 3 ++- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/kvm/mmu/mmu.c | 3 ++- virt/kvm/kvm_main.c | 3 ++- 10 files changed, 30 insertions(+), 14 deletions(-)
Signature · 1 line
2.28.0.236.gb10cc79966-goog
Will Deacon
maintainerPATCH 1/2 KVM: Pass MMU notifier range flags to kvm_unmap_hva_range()
The 'flags' field of 'struct mmu_notifier_range' is used to indicate whether invalidate_range_{start,end}() are permitted to block. In the case of kvm_mmu_notifier_invalidate_range_start(), this field is not forwarded on to the architecture-specific implementation of kvm_unmap_hva_range() and therefore the backend cannot sensibly decide whether or not to block.
Add an extra 'flags' parameter to kvm_unmap_hva_range() so that architectures are aware as to whether or not they are permitted to block.
--- arch/arm64/include/asm/kvm_host.h | 2 +- arch/arm64/kvm/mmu.c | 2 +- arch/mips/include/asm/kvm_host.h | 2 +- arch/mips/kvm/mmu.c | 3 ++- arch/powerpc/include/asm/kvm_host.h | 3 ++- arch/powerpc/kvm/book3s.c | 3 ++- arch/powerpc/kvm/e500_mmu_host.c | 3 ++- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/kvm/mmu/mmu.c | 3 ++- virt/kvm/kvm_main.c | 3 ++- 10 files changed, 17 insertions(+), 10 deletions(-)
arch/arm64/include/asm/kvm_host.h +1 -1
@@ -443,7 +443,7 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,#define KVM_ARCH_WANT_MMU_NOTIFIER int kvm_unmap_hva_range (struct kvm *kvm, -unsigned long start,unsigned long end); +unsigned long start,unsigned long end,unsigned flags);int kvm_set_spte_hva (struct kvm *kvm,unsigned long hva,pte_t pte);int kvm_age_hva (struct kvm *kvm,unsigned long start,unsigned long end);int kvm_test_age_hva (struct kvm *kvm,unsigned long hva);
arch/arm64/kvm/mmu.c +1 -1
@@ -2203,7 +2203,7 @@ static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *dat }int kvm_unmap_hva_range (struct kvm *kvm, -unsigned long start,unsigned long end) +unsigned long start,unsigned long end,unsigned flags) {if (!kvm->arch.pgd)return 0 ;
arch/mips/include/asm/kvm_host.h +1 -1
@@ -981,7 +981,7 @@ enum kvm_mips_fault_result kvm_trap_emul_gva_fault(struct kvm_vcpu *vcpu,#define KVM_ARCH_WANT_MMU_NOTIFIER int kvm_unmap_hva_range (struct kvm *kvm, -unsigned long start,unsigned long end); +unsigned long start,unsigned long end,unsigned flags);int kvm_set_spte_hva (struct kvm *kvm,unsigned long hva,pte_t pte);int kvm_age_hva (struct kvm *kvm,unsigned long start,unsigned long end);int kvm_test_age_hva (struct kvm *kvm,unsigned long hva);
arch/mips/kvm/mmu.c +2 -1
@@ -518,7 +518,8 @@ static int kvm_unmap_hva_handler(struct kvm *kvm, gfn_t gfn, gfn_t gfn_end,return 1 ; } -int kvm_unmap_hva_range (struct kvm *kvm,unsigned long start,unsigned long end) +int kvm_unmap_hva_range (struct kvm *kvm,unsigned long start,unsigned long end, +unsigned flags) {handle_hva_to_gpa (kvm, start, end, &kvm_unmap_hva_handler,NULL );
arch/powerpc/include/asm/kvm_host.h +2 -1
@@ -58,7 +58,8 @@#define KVM_ARCH_WANT_MMU_NOTIFIER extern int kvm_unmap_hva_range (struct kvm *kvm, -unsigned long start,unsigned long end); +unsigned long start,unsigned long end, +unsigned flags);extern int kvm_age_hva (struct kvm *kvm,unsigned long start,unsigned long end);extern int kvm_test_age_hva (struct kvm *kvm,unsigned long hva);extern int kvm_set_spte_hva (struct kvm *kvm,unsigned long hva,pte_t pte);
arch/powerpc/kvm/book3s.c +2 -1
@@ -834,7 +834,8 @@ void kvmppc_core_commit_memory_region(struct kvm *kvm, kvm->arch.kvm_ops->commit_memory_region (kvm, mem, old, new, change); } -int kvm_unmap_hva_range (struct kvm *kvm,unsigned long start,unsigned long end) +int kvm_unmap_hva_range (struct kvm *kvm,unsigned long start,unsigned long end, +unsigned flags) {return kvm->arch.kvm_ops->unmap_hva_range (kvm, start, end); }
arch/powerpc/kvm/e500_mmu_host.c +2 -1
@@ -734,7 +734,8 @@ static int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)return 0 ; } -int kvm_unmap_hva_range (struct kvm *kvm,unsigned long start,unsigned long end) +int kvm_unmap_hva_range (struct kvm *kvm,unsigned long start,unsigned long end, +unsigned flags) {/* kvm_unmap_hva flushes everything anyways */ kvm_unmap_hva (kvm, start);
arch/x86/include/asm/kvm_host.h +2 -1
@@ -1641,7 +1641,8 @@ asmlinkage void kvm_spurious_fault(void); _ASM_EXTABLE(666b, 667b)#define KVM_ARCH_WANT_MMU_NOTIFIER -int kvm_unmap_hva_range (struct kvm *kvm,unsigned long start,unsigned long end); +int kvm_unmap_hva_range (struct kvm *kvm,unsigned long start,unsigned long end, +unsigned flags);int kvm_age_hva (struct kvm *kvm,unsigned long start,unsigned long end);int kvm_test_age_hva (struct kvm *kvm,unsigned long hva);int kvm_set_spte_hva (struct kvm *kvm,unsigned long hva,pte_t pte);
arch/x86/kvm/mmu/mmu.c +2 -1
@@ -1971,7 +1971,8 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,return kvm_handle_hva_range (kvm, hva, hva +1 , data, handler); } -int kvm_unmap_hva_range (struct kvm *kvm,unsigned long start,unsigned long end) +int kvm_unmap_hva_range (struct kvm *kvm,unsigned long start,unsigned long end, +unsigned flags) {return kvm_handle_hva_range (kvm, start, end,0 , kvm_unmap_rmapp); }
virt/kvm/kvm_main.c +2 -1
@@ -427,7 +427,8 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,* count is also read inside the mmu_lock critical section. */ kvm->mmu_notifier_count++; - need_tlb_flush =kvm_unmap_hva_range (kvm, range->start, range->end); + need_tlb_flush =kvm_unmap_hva_range (kvm, range->start, range->end, + range->flags); need_tlb_flush |= kvm->tlbs_dirty;/* we've to flush the tlb before the pages can be freed */ if (need_tlb_flush)
Signature · 1 line
2.28.0.236.gb10cc79966-goog
Sasha Levin
maintainerRe: [PATCH 1/2] KVM: Pass MMU notifier range flags to kvm_unmap_hva_range()
Hi
[This is an automated email]
This commit has been processed because it contains a -stable tag. The stable tag indicates that it's relevant for the following trees: all
The bot has tested the following trees: v5.8.1, v5.7.15, v5.4.58, v4.19.139, v4.14.193, v4.9.232, v4.4.232.
v5.8.1: Build OK!
v5.7.15: Build OK!
v5.4.58: Build OK!
v4.19.139: Failed to apply! Possible dependencies:
18fc7bf8e041 ("arm64: KVM: Allow for direct call of HYP functions when using VHE")
208243c752a7 ("KVM: arm64: Move hyp-init.S to nVHE")
25357de01b95 ("KVM: arm64: Clean up kvm makefiles")
33e45234987e ("arm64: initialize and switch ptrauth kernel keys")
396244692232 ("arm64: preempt: Provide our own implementation of asm/preempt.h")
3f58bf634555 ("KVM: arm/arm64: Share common code in user_mem_abort()")
6396b852e46e ("KVM: arm/arm64: Re-factor setting the Stage 2 entry to exec on fault")
748c0e312fce ("KVM: Make kvm_set_spte_hva() return int")
750319756256 ("arm64: add basic pointer authentication support")
7621712918ad ("KVM: arm64: Add build rules for separate VHE/nVHE object files")
7aa8d1464165 ("arm/arm64: KVM: Introduce kvm_call_hyp_ret()")
86d0dd34eaff ("arm64: cpufeature: add feature for CRC32 instructions")
90776dd1c427 ("arm64/efi: Move variable assignments after SECTIONS")
95b861a4a6d9 ("arm64: arch_timer: Add workaround for ARM erratum 1188873")
a0e50aa3f4a8 ("KVM: arm64: Factor out stage 2 page table data from struct kvm")
b877e9849d41 ("KVM: arm64: Build hyp-entry.S separately for VHE/nVHE")
bd4fb6d270bc ("arm64: Add support for SB barrier and patch in over DSB; ISB sequences")
be1298425665 ("arm64: install user ptrauth keys at kernel exit time")
d82755b2e781 ("KVM: arm64: Kill off CONFIG_KVM_ARM_HOST")
f50b6f6ae131 ("KVM: arm64: Handle calls to prefixed hyp functions")
f56063c51f9f ("arm64: add image head flag definitions")
f8df73388ee2 ("KVM: arm/arm64: Introduce helpers to manipulate page table entries")v4.14.193: Failed to apply! Possible dependencies:
0db9dd8a0fbd ("KVM: arm/arm64: Stop using the kernel's {pmd,pud,pgd}_populate helpers") 17ab9d57deba ("KVM: arm/arm64: Drop vcpu parameter from guest cache maintenance operartions") 3f58bf634555 ("KVM: arm/arm64: Share common code in user_mem_abort()") 6396b852e46e ("KVM: arm/arm64: Re-factor setting the Stage 2 entry to exec on fault") 694556d54f35 ("KVM: arm/arm64: Clean dcache to PoC when changing PTE due to CoW") 748c0e312fce ("KVM: Make kvm_set_spte_hva() return int")
88dc25e8ea7c ("KVM: arm/arm64: Consolidate page-table accessors") 91c703e0382a ("arm: KVM: Add optimized PIPT icache flushing")
a15f693935a9 ("KVM: arm/arm64: Split dcache/icache flushing")
a9c0e12ebee5 ("KVM: arm/arm64: Only clean the dcache on translation fault") d0e22b4ac3ba ("KVM: arm/arm64: Limit icache invalidation to prefetch aborts") f8df73388ee2 ("KVM: arm/arm64: Introduce helpers to manipulate page table entries")
v4.9.232: Failed to apply! Possible dependencies:
1534b3964901 ("KVM: MIPS/MMU: Simplify ASID restoration") 1581ff3dbf69 ("KVM: MIPS/MMU: Move preempt/ASID handling to implementation") 1880afd6057f ("KVM: MIPS/T&E: Add lockless GVA access helpers") 411740f5422a ("KVM: MIPS/MMU: Implement KVM_CAP_SYNC_MMU") 748c0e312fce ("KVM: Make kvm_set_spte_hva() return int") 91cdee5710d5 ("KVM: MIPS/T&E: Restore host asid on return to host") a2c046e40ff1 ("KVM: MIPS: Add vcpu_run() & vcpu_reenter() callbacks") a31b50d741bd ("KVM: MIPS/MMU: Invalidate GVA PTs on ASID changes") a60b8438bdba ("KVM: MIPS: Convert get/set_regs -> vcpu_load/put") a7ebb2e410f8 ("KVM: MIPS/T&E: active_mm = init_mm in guest context") aba8592950f1 ("KVM: MIPS/MMU: Invalidate stale GVA PTEs on TLBW") c550d53934d8 ("KVM: MIPS: Remove duplicated ASIDs from vcpu")
v4.4.232: Failed to apply! Possible dependencies:
16d100db245a ("MIPS: Move Cause.ExcCode trap codes to mipsregs.h")
1880afd6057f ("KVM: MIPS/T&E: Add lockless GVA access helpers")
19d194c62b25 ("MIPS: KVM: Simplify TLB_* macros")
411740f5422a ("KVM: MIPS/MMU: Implement KVM_CAP_SYNC_MMU")
748c0e312fce ("KVM: Make kvm_set_spte_hva() return int")
8cffd1974851 ("MIPS: KVM: Convert code to kernel sized types")
9fbfb06a4065 ("MIPS: KVM: Arrayify struct kvm_mips_tlb::tlb_lo*")
ba049e93aef7 ("kvm: rename pfn_t to kvm_pfn_t")
bdb7ed8608f8 ("MIPS: KVM: Convert headers to kernel sized types")
ca64c2beecd4 ("MIPS: KVM: Abstract guest ASID mask")
caa1faa7aba6 ("MIPS: KVM: Trivial whitespace and style fixes")NOTE: The patch will not be queued to stable trees until it is upstream.
How should we proceed with this patch?
Signature · 6 lines
Thanks Sasha _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Sasha Levin
maintainerRe: [PATCH 1/2] KVM: Pass MMU notifier range flags to kvm_unmap_hva_range()
In reply to Will DeaconHi
[This is an automated email]
This commit has been processed because it contains a -stable tag. The stable tag indicates that it's relevant for the following trees: all
The bot has tested the following trees: v5.8.2, v5.7.16, v5.4.59, v4.19.140, v4.14.193, v4.9.232, v4.4.232.
v5.8.2: Build OK!
v5.7.16: Build OK!
v5.4.59: Build OK!
v4.19.140: Failed to apply! Possible dependencies:
18fc7bf8e041 ("arm64: KVM: Allow for direct call of HYP functions when using VHE")
208243c752a7 ("KVM: arm64: Move hyp-init.S to nVHE")
25357de01b95 ("KVM: arm64: Clean up kvm makefiles")
33e45234987e ("arm64: initialize and switch ptrauth kernel keys")
396244692232 ("arm64: preempt: Provide our own implementation of asm/preempt.h")
3f58bf634555 ("KVM: arm/arm64: Share common code in user_mem_abort()")
6396b852e46e ("KVM: arm/arm64: Re-factor setting the Stage 2 entry to exec on fault")
748c0e312fce ("KVM: Make kvm_set_spte_hva() return int")
750319756256 ("arm64: add basic pointer authentication support")
7621712918ad ("KVM: arm64: Add build rules for separate VHE/nVHE object files")
7aa8d1464165 ("arm/arm64: KVM: Introduce kvm_call_hyp_ret()")
86d0dd34eaff ("arm64: cpufeature: add feature for CRC32 instructions")
90776dd1c427 ("arm64/efi: Move variable assignments after SECTIONS")
95b861a4a6d9 ("arm64: arch_timer: Add workaround for ARM erratum 1188873")
a0e50aa3f4a8 ("KVM: arm64: Factor out stage 2 page table data from struct kvm")
b877e9849d41 ("KVM: arm64: Build hyp-entry.S separately for VHE/nVHE")
bd4fb6d270bc ("arm64: Add support for SB barrier and patch in over DSB; ISB sequences")
be1298425665 ("arm64: install user ptrauth keys at kernel exit time")
d82755b2e781 ("KVM: arm64: Kill off CONFIG_KVM_ARM_HOST")
f50b6f6ae131 ("KVM: arm64: Handle calls to prefixed hyp functions")
f56063c51f9f ("arm64: add image head flag definitions")
f8df73388ee2 ("KVM: arm/arm64: Introduce helpers to manipulate page table entries")v4.14.193: Failed to apply! Possible dependencies:
0db9dd8a0fbd ("KVM: arm/arm64: Stop using the kernel's {pmd,pud,pgd}_populate helpers") 17ab9d57deba ("KVM: arm/arm64: Drop vcpu parameter from guest cache maintenance operartions") 3f58bf634555 ("KVM: arm/arm64: Share common code in user_mem_abort()") 6396b852e46e ("KVM: arm/arm64: Re-factor setting the Stage 2 entry to exec on fault") 694556d54f35 ("KVM: arm/arm64: Clean dcache to PoC when changing PTE due to CoW") 748c0e312fce ("KVM: Make kvm_set_spte_hva() return int")
88dc25e8ea7c ("KVM: arm/arm64: Consolidate page-table accessors") 91c703e0382a ("arm: KVM: Add optimized PIPT icache flushing")
a15f693935a9 ("KVM: arm/arm64: Split dcache/icache flushing")
a9c0e12ebee5 ("KVM: arm/arm64: Only clean the dcache on translation fault") d0e22b4ac3ba ("KVM: arm/arm64: Limit icache invalidation to prefetch aborts") f8df73388ee2 ("KVM: arm/arm64: Introduce helpers to manipulate page table entries")
v4.9.232: Failed to apply! Possible dependencies:
1534b3964901 ("KVM: MIPS/MMU: Simplify ASID restoration") 1581ff3dbf69 ("KVM: MIPS/MMU: Move preempt/ASID handling to implementation") 1880afd6057f ("KVM: MIPS/T&E: Add lockless GVA access helpers") 411740f5422a ("KVM: MIPS/MMU: Implement KVM_CAP_SYNC_MMU") 748c0e312fce ("KVM: Make kvm_set_spte_hva() return int") 91cdee5710d5 ("KVM: MIPS/T&E: Restore host asid on return to host") a2c046e40ff1 ("KVM: MIPS: Add vcpu_run() & vcpu_reenter() callbacks") a31b50d741bd ("KVM: MIPS/MMU: Invalidate GVA PTs on ASID changes") a60b8438bdba ("KVM: MIPS: Convert get/set_regs -> vcpu_load/put") a7ebb2e410f8 ("KVM: MIPS/T&E: active_mm = init_mm in guest context") aba8592950f1 ("KVM: MIPS/MMU: Invalidate stale GVA PTEs on TLBW") c550d53934d8 ("KVM: MIPS: Remove duplicated ASIDs from vcpu")
v4.4.232: Failed to apply! Possible dependencies:
16d100db245a ("MIPS: Move Cause.ExcCode trap codes to mipsregs.h")
1880afd6057f ("KVM: MIPS/T&E: Add lockless GVA access helpers")
19d194c62b25 ("MIPS: KVM: Simplify TLB_* macros")
411740f5422a ("KVM: MIPS/MMU: Implement KVM_CAP_SYNC_MMU")
748c0e312fce ("KVM: Make kvm_set_spte_hva() return int")
8cffd1974851 ("MIPS: KVM: Convert code to kernel sized types")
9fbfb06a4065 ("MIPS: KVM: Arrayify struct kvm_mips_tlb::tlb_lo*")
ba049e93aef7 ("kvm: rename pfn_t to kvm_pfn_t")
bdb7ed8608f8 ("MIPS: KVM: Convert headers to kernel sized types")
ca64c2beecd4 ("MIPS: KVM: Abstract guest ASID mask")
caa1faa7aba6 ("MIPS: KVM: Trivial whitespace and style fixes")NOTE: The patch will not be queued to stable trees until it is upstream.
How should we proceed with this patch?
Signature · 6 lines
Thanks Sasha _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Will Deacon
maintainerPATCH 2/2 KVM: arm64: Only reschedule if MMU_NOTIFIER_RANGE_BLOCKABLE is not set
In reply to Will DeaconWhen 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.
--- arch/arm64/kvm/mmu.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
arch/arm64/kvm/mmu.c +13 -4
@@ -365,7 +365,8 @@ static void unmap_stage2_p4ds(struct kvm *kvm, pgd_t *pgd,* destroying the VM), otherwise another faulting VCPU may come in and mess * with things behind our backs. */ -static void unmap_stage2_range (struct kvm *kvm,phys_addr_t start,u64 size) +static void __unmap_stage2_range (struct kvm *kvm,phys_addr_t start,u64 size, +bool may_block) {pgd_t *pgd;phys_addr_t addr = start, end = start + size;
@@ -390,11 +391,16 @@ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size)* If the range is too large, release the kvm->mmu_lock * to prevent starvation and lockup detector warnings. */ -if (next != end) +if (may_block && next != end)cond_resched_lock (&kvm->mmu_lock); }while (pgd++, addr = next, addr != end); } +static void unmap_stage2_range (struct kvm *kvm,phys_addr_t start,u64 size) +{ +__unmap_stage2_range (kvm, start, size, true); +} +static void stage2_flush_ptes (struct kvm *kvm,pmd_t *pmd,phys_addr_t addr,phys_addr_t end) {
@@ -2198,7 +2204,10 @@ static int handle_hva_to_gpa(struct kvm *kvm,static int kvm_unmap_hva_handler (struct kvm *kvm,gpa_t gpa,u64 size,void *data) { -unmap_stage2_range (kvm, gpa, size); +unsigned flags = *(unsigned *)data; +bool may_block = flags &MMU_NOTIFIER_RANGE_BLOCKABLE ; + +__unmap_stage2_range (kvm, gpa, size, may_block);return 0 ; }
@@ -2209,7 +2218,7 @@ int kvm_unmap_hva_range(struct kvm *kvm,return 0 ;trace_kvm_unmap_hva_range (start, end); -handle_hva_to_gpa (kvm, start, end, &kvm_unmap_hva_handler,NULL ); +handle_hva_to_gpa (kvm, start, end, &kvm_unmap_hva_handler, &flags);return 0 ; }
Signature · 1 line
2.28.0.236.gb10cc79966-goog
Re: [PATCH 2/2] KVM: arm64: Only reschedule if MMU_NOTIFIER_RANGE_BLOCKABLE is not set
Quoted 31 lines · 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 followingBUG():| 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/0x30Use the new 'flags' argument to
kvm_unmap_hva_range()to ensure that we only reschedule ifMMU_NOTIFIER_RANGE_BLOCKABLEis set in the notifier flags.
Quoted 7 lines
Cc <[email protected]>Fixes 8b3405e345b5 ("kvm: arm/arm64: Fix locking for kvm_free_stage2_pgd")Cc Marc Zyngier <[email protected]>Cc Suzuki K Poulose <[email protected]>Cc James Morse <[email protected]>Signed-off-by Will Deacon <[email protected]>---
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Paolo Bonzini
maintainerQuoted 34 lines · Will Deacon
Hi all,
While stress-testing my arm64 stage-2 page-table rewrite [1], I ran into a sleeping while atomic
BUG()during OOM that I can reproduce with mainline.The problem is that the arm64 page-table code periodically calls
cond_resched_lock()when unmapping the stage-2 page-tables, but in the case of OOM, this occurs in atomic context.These couple of patches (based on 5.8) propagate the flags from the MMU notifier range structure, which in turn indicate whether or not blocking is permitted.
Cheers,
Will
[1] https://android-kvm.googlesource.com/linux/+/refs/heads/topic/pgtable
Cc Marc Zyngier <[email protected]>Cc Suzuki K Poulose <[email protected]>Cc James Morse <[email protected]>Cc Thomas Bogendoerfer <[email protected]>Cc Paul Mackerras <[email protected]>Cc Paolo Bonzini <[email protected]>Cc Sean Christopherson <[email protected]>--->8
Will Deacon (2):
KVM: Pass MMU notifier range flags tokvm_unmap_hva_range()
KVM: arm64: Only reschedule ifMMU_NOTIFIER_RANGE_BLOCKABLEis not set
Quoted 12 lines
arch/arm64/include/asm/kvm_host.h | 2 +- arch/arm64/kvm/mmu.c | 19 ++++++++++++++----- arch/mips/include/asm/kvm_host.h | 2 +- arch/mips/kvm/mmu.c | 3 ++- arch/powerpc/include/asm/kvm_host.h | 3 ++- arch/powerpc/kvm/book3s.c | 3 ++- arch/powerpc/kvm/e500_mmu_host.c | 3 ++- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/kvm/mmu/mmu.c | 3 ++- virt/kvm/kvm_main.c | 3 ++- 10 files changed, 30 insertions(+), 14 deletions(-)
These would be okay for 5.9 too, so I plan to queue them myself before we fork for 5.10.
Paolo
Will Deacon
maintainerQuoted 18 lines · Paolo Bonzini
Quoted 4 lines · Will Deacon
Will Deacon (2):
KVM: Pass MMU notifier range flags tokvm_unmap_hva_range()
KVM: arm64: Only reschedule ifMMU_NOTIFIER_RANGE_BLOCKABLEis not setQuoted 12 lines
arch/arm64/include/asm/kvm_host.h | 2 +- arch/arm64/kvm/mmu.c | 19 ++++++++++++++----- arch/mips/include/asm/kvm_host.h | 2 +- arch/mips/kvm/mmu.c | 3 ++- arch/powerpc/include/asm/kvm_host.h | 3 ++- arch/powerpc/kvm/book3s.c | 3 ++- arch/powerpc/kvm/e500_mmu_host.c | 3 ++- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/kvm/mmu/mmu.c | 3 ++- virt/kvm/kvm_main.c | 3 ++- 10 files changed, 30 insertions(+), 14 deletions(-)
Quoted 2 lines
These would be okay for 5.9 too, so I plan to queue them myself before we fork for 5.10.
Thanks, Paolo. Let me know if you want me to rebase/repost.
Please note that I'm planning on rewriting most of the arm64 KVM page-table code for 5.10, so if you can get this series in early (e.g. for -rc2), then it would _really_ help with managing the kvm/arm64 queue for the next merge window.
Otherwise, could you and Marc please set up a shared branch with just these, so I can use it as a base?
Please let me know.
Will
Marc Zyngier
maintainerQuoted 29 lines · Will Deacon
Quoted 18 lines · Paolo Bonzini
Quoted 4 lines · Will Deacon
Will Deacon (2):
KVM: Pass MMU notifier range flags tokvm_unmap_hva_range()
KVM: arm64: Only reschedule ifMMU_NOTIFIER_RANGE_BLOCKABLEis not setQuoted 12 lines
arch/arm64/include/asm/kvm_host.h | 2 +- arch/arm64/kvm/mmu.c | 19 ++++++++++++++----- arch/mips/include/asm/kvm_host.h | 2 +- arch/mips/kvm/mmu.c | 3 ++- arch/powerpc/include/asm/kvm_host.h | 3 ++- arch/powerpc/kvm/book3s.c | 3 ++- arch/powerpc/kvm/e500_mmu_host.c | 3 ++- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/kvm/mmu/mmu.c | 3 ++- virt/kvm/kvm_main.c | 3 ++- 10 files changed, 30 insertions(+), 14 deletions(-)Quoted 2 lines
These would be okay for 5.9 too, so I plan to queue them myself before we fork for 5.10.
Thanks, Paolo. Let me know if you want me to rebase/repost.
Please note that I'm planning on rewriting most of the arm64 KVM page-table code for 5.10, so if you can get this series in early (e.g. for -rc2), then it would _really_ help with managing the kvm/arm64 queue for the next merge window.
Quoted 4 lines
Otherwise, could you and Marc please set up a shared branch with just these, so I can use it as a base?
Please let me know.
Given that this doesn't directly applies to -rc1, I'll push out a branch shortly with the conflicts resolved.
Thanks,
M.
Signature · 1 line
Jazz is not dead. It just smells funny...
Paolo Bonzini
maintainerQuoted 4 lines · Will Deacon
Please note that I'm planning on rewriting most of the arm64 KVM page-table code for 5.10, so if you can get this series in early (e.g. for -rc2), then it would _really_ help with managing the kvm/arm64 queue for the next merge window.
Yes, I plan to send it tomorrow.
Paolo
Quoted 9 lines · Will Deacon
While stress-testing my arm64 stage-2 page-table rewrite [1], I ran into a sleeping while atomic
BUG()during OOM that I can reproduce with mainline.The problem is that the arm64 page-table code periodically calls
cond_resched_lock()when unmapping the stage-2 page-tables, but in the case of OOM, this occurs in atomic context.[...]
Applied to kvm-arm64/pt-rework-base, thanks!
[1/2] KVM: Pass MMU notifier range flags to kvm_unmap_hva_range()
commit: 462a296d8a2004063ab3c6b4df07d6f165786734
[2/2] KVM: arm64: Only reschedule if MMU_NOTIFIER_RANGE_BLOCKABLE is not set
commit: 78dcf128f9bb3a6a3950a21cf097cdc48cf3f505Cheers,
M.
Signature · 1 line
Without deviation from the norm, progress is not possible.