android_kernel_samsung_univ.../arch/arm/kvm
Suzuki K Poulose 1f72c8b60e kvm-arm: Unmap shadow pagetables properly
commit 293f293637b55db4f9f522a5a72514e98a541076 upstream.

On arm/arm64, we depend on the kvm_unmap_hva* callbacks (via
mmu_notifiers::invalidate_*) to unmap the stage2 pagetables when
the userspace buffer gets unmapped. However, when the Hypervisor
process exits without explicit unmap of the guest buffers, the only
notifier we get is kvm_arch_flush_shadow_all() (via mmu_notifier::release
) which does nothing on arm. Later this causes us to access pages that
were already released [via exit_mmap() -> unmap_vmas()] when we actually
get to unmap the stage2 pagetable [via kvm_arch_destroy_vm() ->
kvm_free_stage2_pgd()]. This triggers crashes with CONFIG_DEBUG_PAGEALLOC,
which unmaps any free'd pages from the linear map.

 [  757.644120] Unable to handle kernel paging request at virtual address
  ffff800661e00000
 [  757.652046] pgd = ffff20000b1a2000
 [  757.655471] [ffff800661e00000] *pgd=00000047fffe3003, *pud=00000047fcd8c003,
  *pmd=00000047fcc7c003, *pte=00e8004661e00712
 [  757.666492] Internal error: Oops: 96000147 [#3] PREEMPT SMP
 [  757.672041] Modules linked in:
 [  757.675100] CPU: 7 PID: 3630 Comm: qemu-system-aar Tainted: G      D
 4.8.0-rc1 #3
 [  757.683240] Hardware name: AppliedMicro X-Gene Mustang Board/X-Gene Mustang Board,
  BIOS 3.06.15 Aug 19 2016
 [  757.692938] task: ffff80069cdd3580 task.stack: ffff8006adb7c000
 [  757.698840] PC is at __flush_dcache_area+0x1c/0x40
 [  757.703613] LR is at kvm_flush_dcache_pmd+0x60/0x70
 [  757.708469] pc : [<ffff20000809dbdc>] lr : [<ffff2000080b4a70>] pstate: 20000145
 ...
 [  758.357249] [<ffff20000809dbdc>] __flush_dcache_area+0x1c/0x40
 [  758.363059] [<ffff2000080b6748>] unmap_stage2_range+0x458/0x5f0
 [  758.368954] [<ffff2000080b708c>] kvm_free_stage2_pgd+0x34/0x60
 [  758.374761] [<ffff2000080b2280>] kvm_arch_destroy_vm+0x20/0x68
 [  758.380570] [<ffff2000080aa330>] kvm_put_kvm+0x210/0x358
 [  758.385860] [<ffff2000080aa524>] kvm_vm_release+0x2c/0x40
 [  758.391239] [<ffff2000082ad234>] __fput+0x114/0x2e8
 [  758.396096] [<ffff2000082ad46c>] ____fput+0xc/0x18
 [  758.400869] [<ffff200008104658>] task_work_run+0x108/0x138
 [  758.406332] [<ffff2000080dc8ec>] do_exit+0x48c/0x10e8
 [  758.411363] [<ffff2000080dd5fc>] do_group_exit+0x6c/0x130
 [  758.416739] [<ffff2000080ed924>] get_signal+0x284/0xa18
 [  758.421943] [<ffff20000808a098>] do_signal+0x158/0x860
 [  758.427060] [<ffff20000808aad4>] do_notify_resume+0x6c/0x88
 [  758.432608] [<ffff200008083624>] work_pending+0x10/0x14
 [  758.437812] Code: 9ac32042 8b010001 d1000443 8a230000 (d50b7e20)

This patch fixes the issue by moving the kvm_free_stage2_pgd() to
kvm_arch_flush_shadow_all().

Tested-by: Itaru Kitayama <itaru.kitayama@riken.jp>
Reported-by: Itaru Kitayama <itaru.kitayama@riken.jp>
Reported-by: James Morse <james.morse@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-09-24 10:07:37 +02:00
..
arm.c kvm-arm: Unmap shadow pagetables properly 2016-09-24 10:07:37 +02:00
coproc_a7.c arm/arm64: KVM: Use set/way op trapping to track the state of the caches 2015-01-29 23:24:56 +01:00
coproc_a15.c arm/arm64: KVM: Use set/way op trapping to track the state of the caches 2015-01-29 23:24:56 +01:00
coproc.c arm/arm64: KVM: Use set/way op trapping to track the state of the caches 2015-01-29 23:24:56 +01:00
coproc.h arm/arm64: KVM: Use set/way op trapping to track the state of the caches 2015-01-29 23:24:56 +01:00
emulate.c
guest.c arm/arm64: KVM: Fix ioctl error handling 2016-03-09 15:34:51 -08:00
handle_exit.c ARM: KVM: extend WFI tracepoint to differentiate between wfi and wfe 2015-01-15 13:12:27 +01:00
init.S ARM: kvm: round HYP section to page size instead of log2 upper bound 2015-03-27 12:21:27 +00:00
interrupts_head.S arm: KVM: Disable virtual timer even if the guest is not using it 2015-09-17 13:11:48 +01:00
interrupts.S arm: KVM: keep arm vfp/simd exit handling consistent with arm64 2015-08-19 22:27:58 +01:00
Kconfig arm/arm64: KVM : Enable vhost device selection under KVM config menu 2015-10-22 23:01:45 +02:00
Makefile KVM: arm/arm64: Enable the KVM-VFIO device 2015-06-17 09:46:29 +01:00
mmio.c arm64: KVM: Correctly handle zero register during MMIO 2015-12-04 16:29:37 +00:00
mmu.c kvm-arm: Unmap shadow pagetables properly 2016-09-24 10:07:37 +02:00
perf.c
psci.c arm64: KVM: Get rid of old vcpu_reg() 2015-12-04 16:30:03 +00:00
reset.c KVM: arm/arm64: timer: Allow the timer to control the active state 2015-08-12 11:28:26 +01:00
trace.h arm/arm64: KVM: Improve kvm_exit tracepoint 2015-10-22 23:01:47 +02:00