[PATCH v22 11/23] KVM: arm64: Add VM specific callback for S2 MMU operations

Suzuki K Poulose suzuki.poulose at arm.com
Mon Oct 5 22:22:35 PDT 2026


On 06/10/2026 04:00, Gavin Shan wrote:
> On 10/5/26 7:07 PM, Suzuki K Poulose wrote:
>> Add VM type specific S2 MMU operation backends which can be 
>> initialized per
>> VM flavor, to keep the handling cleaner.
>>
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
>> ---
>> Change since v21:
>>   - Define all vm_s2_ops call back. All calls are mandatory.
>>   - Define callback for each flavor, disjointing the non-protetcted 
>> pKVM and
>>     normal KVM (VHE & nVHE) and remove the KVM_PGT_FN() hacks.
>>   - Dropped Reviews due to the changes.
>>   - Add "no_age_gfn" and "no_stage2_unmap_range" for pKVM callbacks, 
>> no_age_*
>>     to be also reused by Realms later.
>>   - Move kvm_vm_s2_ops field to keep the structure packed

...

>>    */
>>   int kvm_arch_flush_remote_tlbs(struct kvm *kvm)
>>   {
>> -    if (is_protected_kvm_enabled())
>> -        kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);
>> -    else
>> -        kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
>> -    return 0;
>> +    return kvm->arch.vm_s2_ops->vm_flush_remote_tlbs(kvm);
>>   }
>> -int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm,
>> -                      gfn_t gfn, u64 nr_pages)
>> +static int pkvm_flush_remote_tlbs_range(struct kvm *kvm,
>> +                    gfn_t gfn, u64 nr_pages)
>> +{
>> +    return pkvm_flush_remote_tlbs(kvm);
> 
> No need to have another function call, which causes unnecessary overhead?
> 
>      kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);

Maybe, but that is in another way, telling the reader that pKVM can only
do full VM TLB flush, no range TLB flush.

>      return 0;
> 
>> +}
>> +
>> +static int kvm_vm_flush_remote_tlbs_range(struct kvm *kvm,
>> +                     gfn_t gfn, u64 nr_pages)
>>   {
>>       u64 size = nr_pages << PAGE_SHIFT;
>>       u64 addr = gfn << PAGE_SHIFT;
>> -    if (is_protected_kvm_enabled())
>> -        kvm_call_hyp_nvhe(__pkvm_tlb_flush_vmid, kvm->arch.pkvm.handle);
>> -    else
>> -        kvm_tlb_flush_vmid_range(&kvm->arch.mmu, addr, size);
>> +    kvm_tlb_flush_vmid_range(&kvm->arch.mmu, addr, size);
>>       return 0;
>>   }
>>
> 
> Since we're here, the local variable 'addr' and 'size' can be dropped by:
> 
>      kvm_tlb_flush_vmid_range(&kvm->arch.mmu,
>                                   gfn << PAGE_SHIFT,
>                                   nr_pages << PAGE_SHIFT);
> 

Does it really matter, the compiler can optimise this anyways and looks
more readable ?

> 
>> +int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm,
>> +                     gfn_t gfn, u64 nr_pages)
>> +{
>> +    return kvm->arch.vm_s2_ops->vm_flush_remote_tlbs_range(kvm, gfn, 
>> nr_pages);
>> +}
>> +

...

>> +static const struct kvm_vm_s2_ops kvm_default_vm_s2_ops = {
>> +    .vm_flush_remote_tlbs        = kvm_vm_flush_remote_tlbs,
>> +    .vm_flush_remote_tlbs_range    = kvm_vm_flush_remote_tlbs_range,
>> +    .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,
>> +};
>> +
>> +#define KVM_VM_S2_OPS(flavor, ops)        \
>> +        [flavor] = &(ops)
> 
> s/[flavor]/[(flavor)]

Ack


Thanks !
Suzuki



More information about the linux-arm-kernel mailing list