• Mark Rutland's avatar
    arm64: kvm: Use cpus_have_final_cap() explicitly · d8569fba
    Mark Rutland authored
    Much of the arm64 KVM code uses cpus_have_const_cap() to check for
    cpucaps, but this is unnecessary and it would be preferable to use
    cpus_have_final_cap().
    
    For historical reasons, cpus_have_const_cap() is more complicated than
    it needs to be. Before cpucaps are finalized, it will perform a bitmap
    test of the system_cpucaps bitmap, and once cpucaps are finalized it
    will use an alternative branch. This used to be necessary to handle some
    race conditions in the window between cpucap detection and the
    subsequent patching of alternatives and static branches, where different
    branches could be out-of-sync with one another (or w.r.t. alternative
    sequences). Now that we use alternative branches instead of static
    branches, these are all patched atomically w.r.t. one another, and there
    are only a handful of cases that need special care in the window between
    cpucap detection and alternative patching.
    
    Due to the above, it would be nice to remove cpus_have_const_cap(), and
    migrate callers over to alternative_has_cap_*(), cpus_have_final_cap(),
    or cpus_have_cap() depending on when their requirements. This will
    remove redundant instructions and improve code generation, and will make
    it easier to determine how each callsite will behave before, during, and
    after alternative patching.
    
    KVM is initialized after cpucaps have been finalized and alternatives
    have been patched. Since commit:
    
      d86de40d ("arm64: cpufeature: upgrade hyp caps to final")
    
    ... use of cpus_have_const_cap() in hyp code is automatically converted
    to use cpus_have_final_cap():
    
    | static __always_inline bool cpus_have_const_cap(int num)
    | {
    | 	if (is_hyp_code())
    | 		return cpus_have_final_cap(num);
    | 	else if (system_capabilities_finalized())
    | 		return __cpus_have_const_cap(num);
    | 	else
    | 		return cpus_have_cap(num);
    | }
    
    Thus, converting hyp code to use cpus_have_final_cap() directly will not
    result in any functional change.
    
    Non-hyp KVM code is also not executed until cpucaps have been finalized,
    and it would be preferable to extent the same treatment to this code and
    use cpus_have_final_cap() directly.
    
    This patch converts instances of cpus_have_const_cap() in KVM-only code
    over to cpus_have_final_cap(). As all of this code runs after cpucaps
    have been finalized, there should be no functional change as a result of
    this patch, but the redundant instructions generated by
    cpus_have_const_cap() will be removed from the non-hyp KVM code.
    Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
    Reviewed-by: default avatarMarc Zyngier <maz@kernel.org>
    Cc: Oliver Upton <oliver.upton@linux.dev>
    Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
    Cc: Will Deacon <will@kernel.org>
    Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    d8569fba
kvm_mmu.h 9.47 KB