summaryrefslogtreecommitdiff
path: root/arch/arm64/kvm/reset.c
diff options
context:
space:
mode:
authorSuzuki K Poulose <suzuki.poulose@arm.com>2018-09-26 17:32:53 +0100
committerMarc Zyngier <marc.zyngier@arm.com>2018-10-03 11:45:14 +0100
commit58b3efc820acd3219e89ff014e93346a734229b8 (patch)
treefd7e6d712ea2f7f759e2d3ee4f2426727cabf1e3 /arch/arm64/kvm/reset.c
parent0f62f0e95be29200ab2ab98ca870e22c9b148dfa (diff)
downloadlinux-stable-58b3efc820acd3219e89ff014e93346a734229b8.tar.gz
kvm: arm64: Limit the minimum number of page table levels
Since we are about to remove the lower limit on the IPA size, make sure that we do not go to 1 level page table (e.g, with 32bit IPA on 64K host with concatenation) to avoid splitting the host PMD huge pages at stage2. 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>
Diffstat (limited to 'arch/arm64/kvm/reset.c')
-rw-r--r--arch/arm64/kvm/reset.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 96b3f50101bc..f156e45760bc 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -190,6 +190,7 @@ int kvm_arm_config_vm(struct kvm *kvm, unsigned long type)
{
u64 vtcr = VTCR_EL2_FLAGS;
u32 parange, phys_shift;
+ u8 lvls;
if (type)
return -EINVAL;
@@ -203,7 +204,14 @@ 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(stage2_pgtable_levels(phys_shift));
+ /*
+ * Use a minimum 2 level page table to prevent splitting
+ * host PMD huge pages at stage2.
+ */
+ lvls = stage2_pgtable_levels(phys_shift);
+ if (lvls < 2)
+ lvls = 2;
+ vtcr |= VTCR_EL2_LVLS_TO_SL0(lvls);
/*
* Enable the Hardware Access Flag management, unconditionally