OSDN Git Service

kvm: arm64: Clean up VTCR_EL2 initialisation
authorSuzuki K Poulose <suzuki.poulose@arm.com>
Wed, 26 Sep 2018 16:32:41 +0000 (17:32 +0100)
committerMarc Zyngier <marc.zyngier@arm.com>
Mon, 1 Oct 2018 12:50:29 +0000 (13:50 +0100)
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: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
arch/arm64/include/asm/kvm_arm.h
arch/arm64/kvm/hyp/s2-setup.c

index aa45df7..5f807b6 100644 (file)
 #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
 #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
index 603e1ee..e1ca672 100644 (file)
 #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;
 }