[PATCH v22 13/23] KVM: arm64: Abstract out memory abort handling
Gavin Shan
gshan at redhat.com
Mon Oct 5 20:07:37 PDT 2026
On 10/5/26 7:07 PM, Suzuki K Poulose wrote:
> Move the memory abort handling under VM specific s2 operation.
>
> Tested-by: Gavin Shan <gshan at redhat.com>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> ---
> Changes since v21:
> - Rename protected_vm_mem_abort => protected_pkvm_mem_abort for consistency
> with the other callbacks.
> ---
> arch/arm64/include/asm/kvm_host.h | 2 ++
> arch/arm64/kvm/mmu.c | 33 ++++++++++++++++++-------------
> 2 files changed, 21 insertions(+), 14 deletions(-)
>
One nitpick below. In either way:
Reviewed-by: Gavin Shan <gshan at redhat.com>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 0778c308ce597..7cb343583953d 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -156,6 +156,7 @@ struct kvm_vcpu_ops {
> };
>
> struct kvm_gfn_range;
> +struct kvm_s2_fault_desc;
>
> struct kvm_vm_s2_ops {
> bool (*vm_age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range);
> @@ -166,6 +167,7 @@ struct kvm_vm_s2_ops {
> void (*vm_stage2_unmap_range)(struct kvm_s2_mmu *mmu,
> phys_addr_t start, u64 size,
> bool may_block);
> + int (*vm_mem_abort)(const struct kvm_s2_fault_desc *s2fd);
> };
>
> struct kvm_s2_mmu {
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 9cc7fcde4dd0a..ccbe2ffeda40b 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1740,7 +1740,7 @@ struct kvm_s2_fault_vma_info {
> bool map_non_cacheable;
> };
>
> -static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> +static int protected_pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> {
> unsigned int flags = FOLL_HWPOISON | FOLL_LONGTERM | FOLL_WRITE;
> struct kvm_vcpu *vcpu = s2fd->vcpu;
> @@ -2178,6 +2178,20 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> return kvm_s2_fault_map(s2fd, &s2vi, prot, memcache);
> }
>
> +static int kvm_vm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> +{
> + struct kvm_vcpu *vcpu = s2fd->vcpu;
> +
> + VM_WARN_ON_ONCE(kvm_vcpu_trap_is_permission_fault(vcpu) &&
> + !kvm_is_write_fault(vcpu) &&
> + !kvm_vcpu_trap_is_exec_fault(vcpu));
> +
> + if (kvm_slot_has_gmem(s2fd->memslot))
> + return gmem_abort(s2fd);
> + else
> + return user_mem_abort(s2fd);
> +}
The "if...else" block is moved from kvm_handle_guest_abort(), but it might be
clearer if we have:
if (kvm_slot_has_gmem(s2fd->memslot))
return gmem_abort(s2fd);
return user_mem_abort(s2fd);
> +
> /* Resolve the access fault by making the page young again. */
> static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
> {
> @@ -2447,19 +2461,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
> .hva = hva,
> };
>
> - if (kvm_vm_is_protected(kvm)) {
> - ret = pkvm_mem_abort(&s2fd);
> - } else {
> - VM_WARN_ON_ONCE(kvm_vcpu_trap_is_permission_fault(vcpu) &&
> - !write_fault &&
> - !kvm_vcpu_trap_is_exec_fault(vcpu));
> -
> - if (kvm_slot_has_gmem(memslot))
> - ret = gmem_abort(&s2fd);
> - else
> - ret = user_mem_abort(&s2fd);
> - }
> -
> + ret = kvm->arch.vm_s2_ops->vm_mem_abort(&s2fd);
> if (ret == 0)
> ret = 1;
> out:
> @@ -2873,6 +2875,7 @@ static const struct kvm_vm_s2_ops protected_pkvm_vm_s2_ops = {
> .vm_age_gfn = no_age_gfn,
> .vm_test_age_gfn = no_age_gfn,
> .vm_stage2_unmap_range = no_stage2_unmap_range,
> + .vm_mem_abort = protected_pkvm_mem_abort,
> };
>
> static const struct kvm_vm_s2_ops pkvm_vm_s2_ops = {
> @@ -2881,6 +2884,7 @@ static const struct kvm_vm_s2_ops pkvm_vm_s2_ops = {
> .vm_age_gfn = pkvm_age_gfn,
> .vm_test_age_gfn = pkvm_test_age_gfn,
> .vm_stage2_unmap_range = pkvm_stage2_unmap_range,
> + .vm_mem_abort = kvm_vm_mem_abort,
> };
>
> static const struct kvm_vm_s2_ops kvm_default_vm_s2_ops = {
> @@ -2889,6 +2893,7 @@ static const struct kvm_vm_s2_ops kvm_default_vm_s2_ops = {
> .vm_age_gfn = kvm_vm_age_gfn,
> .vm_test_age_gfn = kvm_vm_test_age_gfn,
> .vm_stage2_unmap_range = kvm_vm_stage2_unmap_range,
> + .vm_mem_abort = kvm_vm_mem_abort,
> };
>
> #define KVM_VM_S2_OPS(flavor, ops) \
Thanks,
Gavin
More information about the linux-arm-kernel
mailing list