[PATCH v2] KVM: arm64: Don't split hugepages outside of MMU write lock

Reiji Watanabe reijiw at google.com
Fri Apr 1 18:06:30 PDT 2022


On 4/1/22 12:46 PM, Oliver Upton wrote:
> It is possible to take a stage-2 permission fault on a page larger than
> PAGE_SIZE. For example, when running a guest backed by 2M HugeTLB, KVM
> eagerly maps at the largest possible block size. When dirty logging is
> enabled on a memslot, KVM does *not* eagerly split these 2M stage-2
> mappings and instead clears the write bit on the pte.
> 
> Since dirty logging is always performed at PAGE_SIZE granularity, KVM
> lazily splits these 2M block mappings down to PAGE_SIZE in the stage-2
> fault handler. This operation must be done under the write lock. Since
> commit f783ef1c0e82 ("KVM: arm64: Add fast path to handle permission
> relaxation during dirty logging"), the stage-2 fault handler
> conditionally takes the read lock on permission faults with dirty
> logging enabled. To that end, it is possible to split a 2M block mapping
> while only holding the read lock.
> 
> The problem is demonstrated by running kvm_page_table_test with 2M
> anonymous HugeTLB, which splats like so:
> 
>    WARNING: CPU: 5 PID: 15276 at arch/arm64/kvm/hyp/pgtable.c:153 stage2_map_walk_leaf+0x124/0x158
> 
>    [...]
> 
>    Call trace:
>    stage2_map_walk_leaf+0x124/0x158
>    stage2_map_walker+0x5c/0xf0
>    __kvm_pgtable_walk+0x100/0x1d4
>    __kvm_pgtable_walk+0x140/0x1d4
>    __kvm_pgtable_walk+0x140/0x1d4
>    kvm_pgtable_walk+0xa0/0xf8
>    kvm_pgtable_stage2_map+0x15c/0x198
>    user_mem_abort+0x56c/0x838
>    kvm_handle_guest_abort+0x1fc/0x2a4
>    handle_exit+0xa4/0x120
>    kvm_arch_vcpu_ioctl_run+0x200/0x448
>    kvm_vcpu_ioctl+0x588/0x664
>    __arm64_sys_ioctl+0x9c/0xd4
>    invoke_syscall+0x4c/0x144
>    el0_svc_common+0xc4/0x190
>    do_el0_svc+0x30/0x8c
>    el0_svc+0x28/0xcc
>    el0t_64_sync_handler+0x84/0xe4
>    el0t_64_sync+0x1a4/0x1a8
> 
> Fix the issue by only acquiring the read lock if the guest faulted on a
> PAGE_SIZE granule w/ dirty logging enabled. Add a WARN to catch locking
> bugs in future changes.
> 
> Fixes: f783ef1c0e82 ("KVM: arm64: Add fast path to handle permission relaxation during dirty logging")
> Cc: Jing Zhang <jingzhangos at google.com>
> Signed-off-by: Oliver Upton <oupton at google.com>

Reviewed-by: Reiji Watanabe <reijiw at google.com>



More information about the linux-arm-kernel mailing list