Skip to content

Commit f0da169

Browse files
ardbiesheuvelwilldeacon
authored andcommitted
arm64/kvm: Configure HYP TCR.PS/DS based on host stage1
When the host stage1 is configured for LPA2, the value currently being programmed into TCR_EL2.T0SZ may be invalid unless LPA2 is configured at HYP as well. This means kvm_lpa2_is_enabled() is not the right condition to test when setting TCR_EL2.DS, as it will return false if LPA2 is only available for stage 1 but not for stage 2. Similary, programming TCR_EL2.PS based on a limited IPA range due to lack of stage2 LPA2 support could potentially result in problems. So use lpa2_is_enabled() instead, and set the PS field according to the host's IPS, which is capped at 48 bits if LPA2 support is absent or disabled. Whether or not we can make meaningful use of such a configuration is a different question. Cc: stable@vger.kernel.org Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Acked-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20241212081841.2168124-11-ardb+git@google.com Signed-off-by: Will Deacon <will@kernel.org>
1 parent 62cffa4 commit f0da169

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

arch/arm64/kvm/arm.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,8 +1990,7 @@ static int kvm_init_vector_slots(void)
19901990
static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
19911991
{
19921992
struct kvm_nvhe_init_params *params = per_cpu_ptr_nvhe_sym(kvm_init_params, cpu);
1993-
u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
1994-
unsigned long tcr;
1993+
unsigned long tcr, ips;
19951994

19961995
/*
19971996
* Calculate the raw per-cpu offset without a translation from the
@@ -2005,6 +2004,7 @@ static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
20052004
params->mair_el2 = read_sysreg(mair_el1);
20062005

20072006
tcr = read_sysreg(tcr_el1);
2007+
ips = FIELD_GET(TCR_IPS_MASK, tcr);
20082008
if (cpus_have_final_cap(ARM64_KVM_HVHE)) {
20092009
tcr |= TCR_EPD1_MASK;
20102010
} else {
@@ -2014,8 +2014,8 @@ static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
20142014
tcr &= ~TCR_T0SZ_MASK;
20152015
tcr |= TCR_T0SZ(hyp_va_bits);
20162016
tcr &= ~TCR_EL2_PS_MASK;
2017-
tcr |= FIELD_PREP(TCR_EL2_PS_MASK, kvm_get_parange(mmfr0));
2018-
if (kvm_lpa2_is_enabled())
2017+
tcr |= FIELD_PREP(TCR_EL2_PS_MASK, ips);
2018+
if (lpa2_is_enabled())
20192019
tcr |= TCR_EL2_DS;
20202020
params->tcr_el2 = tcr;
20212021

0 commit comments

Comments
 (0)