Commit b2df44ff authored by Suzuki K Poulose's avatar Suzuki K Poulose Committed by Marc Zyngier
Browse files

kvm: arm64: Clean up VTCR_EL2 initialisation



Use the new helper for converting the parange to the physical shift.
Also, add the missing definitions for the VTCR_EL2 register fields
and use them instead of hard coding numbers.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Christoffer Dall <cdall@kernel.org>
Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent ce00e3cb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@
#define VTCR_EL2_RES1		(1 << 31)
#define VTCR_EL2_HD		(1 << 22)
#define VTCR_EL2_HA		(1 << 21)
#define VTCR_EL2_PS_SHIFT	TCR_EL2_PS_SHIFT
#define VTCR_EL2_PS_MASK	TCR_EL2_PS_MASK
#define VTCR_EL2_TG0_MASK	TCR_TG0_MASK
#define VTCR_EL2_TG0_4K		TCR_TG0_4K
@@ -127,6 +128,8 @@
#define VTCR_EL2_VS_8BIT	(0 << VTCR_EL2_VS_SHIFT)
#define VTCR_EL2_VS_16BIT	(1 << VTCR_EL2_VS_SHIFT)

#define VTCR_EL2_T0SZ(x)	TCR_T0SZ(x)

/*
 * We configure the Stage-2 page tables to always restrict the IPA space to be
 * 40 bits wide (T0SZ = 24).  Systems with a PARange smaller than 40 bits are
+8 −26
Original line number Diff line number Diff line
@@ -19,45 +19,27 @@
#include <asm/kvm_arm.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_hyp.h>
#include <asm/cpufeature.h>

u32 __hyp_text __init_stage2_translation(void)
{
	u64 val = VTCR_EL2_FLAGS;
	u64 parange;
	u32 phys_shift;
	u64 tmp;

	/*
	 * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS
	 * bits in VTCR_EL2. Amusingly, the PARange is 4 bits, while
	 * PS is only 3. Fortunately, bit 19 is RES0 in VTCR_EL2...
	 * bits in VTCR_EL2. Amusingly, the PARange is 4 bits, but the
	 * allocated values are limited to 3bits.
	 */
	parange = read_sysreg(id_aa64mmfr0_el1) & 7;
	if (parange > ID_AA64MMFR0_PARANGE_MAX)
		parange = ID_AA64MMFR0_PARANGE_MAX;
	val |= parange << 16;
	val |= parange << VTCR_EL2_PS_SHIFT;

	/* Compute the actual PARange... */
	switch (parange) {
	case 0:
		parange = 32;
		break;
	case 1:
		parange = 36;
		break;
	case 2:
		parange = 40;
		break;
	case 3:
		parange = 42;
		break;
	case 4:
		parange = 44;
		break;
	case 5:
	default:
		parange = 48;
		break;
	}
	phys_shift = id_aa64mmfr0_parange_to_phys_shift(parange);

	/*
	 * ... and clamp it to 40 bits, unless we have some braindead
@@ -65,7 +47,7 @@ u32 __hyp_text __init_stage2_translation(void)
	 * return that value for the rest of the kernel to decide what
	 * to do.
	 */
	val |= 64 - (parange > 40 ? 40 : parange);
	val |= VTCR_EL2_T0SZ(phys_shift > 40 ? 40 : phys_shift);

	/*
	 * Check the availability of Hardware Access Flag / Dirty Bit
@@ -86,5 +68,5 @@ u32 __hyp_text __init_stage2_translation(void)

	write_sysreg(val, vtcr_el2);

	return parange;
	return phys_shift;
}