OSDN Git Service

KVM: arm64: Add usage of stage 2 fault lookup level in user_mem_abort()
authorYanan Wang <wangyanan55@huawei.com>
Tue, 1 Dec 2020 20:10:34 +0000 (04:10 +0800)
committerMarc Zyngier <maz@kernel.org>
Wed, 2 Dec 2020 09:53:29 +0000 (09:53 +0000)
commit7d894834a305568a0168c55d4729216f5f8cb4e6
treeb08b0bdcf2f27ff3e775be9dbfb827645d81e416
parent3a0b870e3448302ca2ba703bea1b79b61c3f33c6
KVM: arm64: Add usage of stage 2 fault lookup level in user_mem_abort()

If we get a FSC_PERM fault, just using (logging_active && writable) to
determine calling kvm_pgtable_stage2_map(). There will be two more cases
we should consider.

(1) After logging_active is configged back to false from true. When we
get a FSC_PERM fault with write_fault and adjustment of hugepage is needed,
we should merge tables back to a block entry. This case is ignored by still
calling kvm_pgtable_stage2_relax_perms(), which will lead to an endless
loop and guest panic due to soft lockup.

(2) We use (FSC_PERM && logging_active && writable) to determine
collapsing a block entry into a table by calling kvm_pgtable_stage2_map().
But sometimes we may only need to relax permissions when trying to write
to a page other than a block.
In this condition,using kvm_pgtable_stage2_relax_perms() will be fine.

The ISS filed bit[1:0] in ESR_EL2 regesiter indicates the stage2 lookup
level at which a D-abort or I-abort occurred. By comparing granule of
the fault lookup level with vma_pagesize, we can strictly distinguish
conditions of calling kvm_pgtable_stage2_relax_perms() or
kvm_pgtable_stage2_map(), and the above two cases will be well considered.

Suggested-by: Keqian Zhu <zhukeqian1@huawei.com>
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20201201201034.116760-4-wangyanan55@huawei.com
arch/arm64/include/asm/esr.h
arch/arm64/include/asm/kvm_emulate.h
arch/arm64/kvm/mmu.c