kvm: arm64: Switch to per VM IPA limit
authorSuzuki K Poulose <suzuki.poulose@arm.com>
Wed, 26 Sep 2018 16:32:49 +0000 (17:32 +0100)
committerMarc Zyngier <marc.zyngier@arm.com>
Mon, 1 Oct 2018 12:50:32 +0000 (13:50 +0100)
Now that we can manage the stage2 page table per VM, switch the
configuration details to per VM instance. The VTCR is updated
with the values specific to the VM based on the configuration.
We store the IPA size and the number of stage2 page table levels
for the guest already in VTCR. Decode it back from the vtcr
field wherever we need it.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Christoffer Dall <cdall@kernel.org>
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/include/asm/kvm_mmu.h
arch/arm64/include/asm/stage2_pgtable.h
arch/arm64/kvm/reset.c

index f913adb44f933d6ca3e50c05ff359e395ca8d99f..e4240568cc18504efaef2d4ad27e4c94bab01cc2 100644 (file)
        VTCR_EL2_SL0_TO_LVLS(((vtcr) & VTCR_EL2_SL0_MASK) >> VTCR_EL2_SL0_SHIFT)
 
 #define VTCR_EL2_FLAGS                 (VTCR_EL2_COMMON_BITS | VTCR_EL2_TGRAN)
+#define VTCR_EL2_IPA(vtcr)             (64 - ((vtcr) & VTCR_EL2_T0SZ_MASK))
+
 /*
  * ARM VMSAv8-64 defines an algorithm for finding the translation table
  * descriptors in section D4.2.8 in ARM DDI 0487C.a.
index ac3ca9690bade6794bb26ddcd37f8a4c8d084359..77b1af9e64db1436a5d35ee026bed5f554c27fd0 100644 (file)
@@ -142,7 +142,7 @@ static inline unsigned long __kern_hyp_va(unsigned long v)
  */
 #define KVM_PHYS_SHIFT (40)
 
-#define kvm_phys_shift(kvm)            KVM_PHYS_SHIFT
+#define kvm_phys_shift(kvm)            VTCR_EL2_IPA(kvm->arch.vtcr)
 #define kvm_phys_size(kvm)             (_AC(1, ULL) << kvm_phys_shift(kvm))
 #define kvm_phys_mask(kvm)             (kvm_phys_size(kvm) - _AC(1, ULL))
 
index 36a0a11650038eb808cc94f2f90f1a8598f323e0..c62fe118a898ef045dd7835629be69d80b6abb36 100644 (file)
@@ -43,7 +43,7 @@
  */
 #define stage2_pgtable_levels(ipa)     ARM64_HW_PGTABLE_LEVELS((ipa) - 4)
 #define STAGE2_PGTABLE_LEVELS          stage2_pgtable_levels(KVM_PHYS_SHIFT)
-#define kvm_stage2_levels(kvm)         stage2_pgtable_levels(kvm_phys_shift(kvm))
+#define kvm_stage2_levels(kvm)         VTCR_EL2_LVLS(kvm->arch.vtcr)
 
 /*
  * With all the supported VA_BITs and 40bit guest IPA, the following condition
index 1ced1e37374e7fdf158595d99178261541a69b9e..2bf41e00739090515ce6a55e9efdbeb83c64946e 100644 (file)
@@ -160,7 +160,7 @@ int kvm_arm_config_vm(struct kvm *kvm, unsigned long type)
        if (phys_shift > KVM_PHYS_SHIFT)
                phys_shift = KVM_PHYS_SHIFT;
        vtcr |= VTCR_EL2_T0SZ(phys_shift);
-       vtcr |= VTCR_EL2_LVLS_TO_SL0(kvm_stage2_levels(kvm));
+       vtcr |= VTCR_EL2_LVLS_TO_SL0(stage2_pgtable_levels(phys_shift));
 
        /*
         * Enable the Hardware Access Flag management, unconditionally