Skip to content

Commit b1366d2

Browse files
ryanhrobMarc Zyngier
authored andcommitted
arm64: Add ARM64_HAS_LPA2 CPU capability
Expose FEAT_LPA2 as a capability so that we can take advantage of alternatives patching in the hypervisor. Although FEAT_LPA2 presence is advertised separately for stage1 and stage2, the expectation is that in practice both stages will either support or not support it. Therefore, we combine both into a single capability, allowing us to simplify the implementation. KVM requires support in both stages in order to use LPA2 since the same library is used for hyp stage 1 and guest stage 2 pgtables. Reviewed-by: Oliver Upton <oliver.upton@linux.dev> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20231127111737.1897081-6-ryan.roberts@arm.com
1 parent e477c8c commit b1366d2

3 files changed

Lines changed: 45 additions & 0 deletions

File tree

arch/arm64/include/asm/cpufeature.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,11 @@ static inline bool system_supports_tlb_range(void)
819819
return alternative_has_cap_unlikely(ARM64_HAS_TLB_RANGE);
820820
}
821821

822+
static inline bool system_supports_lpa2(void)
823+
{
824+
return cpus_have_final_cap(ARM64_HAS_LPA2);
825+
}
826+
822827
int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
823828
bool try_emulate_mrs(struct pt_regs *regs, u32 isn);
824829

arch/arm64/kernel/cpufeature.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,39 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
17681768
return !meltdown_safe;
17691769
}
17701770

1771+
#if defined(ID_AA64MMFR0_EL1_TGRAN_LPA2) && defined(ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2)
1772+
static bool has_lpa2_at_stage1(u64 mmfr0)
1773+
{
1774+
unsigned int tgran;
1775+
1776+
tgran = cpuid_feature_extract_unsigned_field(mmfr0,
1777+
ID_AA64MMFR0_EL1_TGRAN_SHIFT);
1778+
return tgran == ID_AA64MMFR0_EL1_TGRAN_LPA2;
1779+
}
1780+
1781+
static bool has_lpa2_at_stage2(u64 mmfr0)
1782+
{
1783+
unsigned int tgran;
1784+
1785+
tgran = cpuid_feature_extract_unsigned_field(mmfr0,
1786+
ID_AA64MMFR0_EL1_TGRAN_2_SHIFT);
1787+
return tgran == ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2;
1788+
}
1789+
1790+
static bool has_lpa2(const struct arm64_cpu_capabilities *entry, int scope)
1791+
{
1792+
u64 mmfr0;
1793+
1794+
mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
1795+
return has_lpa2_at_stage1(mmfr0) && has_lpa2_at_stage2(mmfr0);
1796+
}
1797+
#else
1798+
static bool has_lpa2(const struct arm64_cpu_capabilities *entry, int scope)
1799+
{
1800+
return false;
1801+
}
1802+
#endif
1803+
17711804
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
17721805
#define KPTI_NG_TEMP_VA (-(1UL << PMD_SHIFT))
17731806

@@ -2731,6 +2764,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
27312764
.matches = has_cpuid_feature,
27322765
ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, EVT, IMP)
27332766
},
2767+
{
2768+
.desc = "52-bit Virtual Addressing for KVM (LPA2)",
2769+
.capability = ARM64_HAS_LPA2,
2770+
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
2771+
.matches = has_lpa2,
2772+
},
27342773
{},
27352774
};
27362775

arch/arm64/tools/cpucaps

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ HAS_GIC_PRIO_MASKING
3737
HAS_GIC_PRIO_RELAXED_SYNC
3838
HAS_HCX
3939
HAS_LDAPR
40+
HAS_LPA2
4041
HAS_LSE_ATOMICS
4142
HAS_MOPS
4243
HAS_NESTED_VIRT

0 commit comments

Comments
 (0)