|
@@ -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;
|
|
|
}
|