aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuzuki K Poulose <suzuki.poulose@arm.com>2019-03-12 05:52:51 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2019-03-19 14:01:57 -0400
commita80868f398554842b14d07060012c06efb57c456 (patch)
tree86a4c1704fc2d2b4287dd72cf6eca94ed8359f44
parent7494cec6cb3ba7385a6a223b81906384f15aae34 (diff)
KVM: arm/arm64: Enforce PTE mappings at stage2 when needed
commit 6794ad5443a2118 ("KVM: arm/arm64: Fix unintended stage 2 PMD mappings") made the checks to skip huge mappings, stricter. However it introduced a bug where we still use huge mappings, ignoring the flag to use PTE mappings, by not reseting the vma_pagesize to PAGE_SIZE. Also, the checks do not cover the PUD huge pages, that was under review during the same period. This patch fixes both the issues. Fixes : 6794ad5443a2118 ("KVM: arm/arm64: Fix unintended stage 2 PMD mappings") Reported-by: Zenghui Yu <yuzenghui@huawei.com> Cc: Zenghui Yu <yuzenghui@huawei.com> Cc: Christoffer Dall <christoffer.dall@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r--virt/kvm/arm/mmu.c43
1 files changed, 21 insertions, 22 deletions
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index ffd7acdceac7..bcdf978c0d1d 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1594,8 +1594,9 @@ static void kvm_send_hwpoison_signal(unsigned long address,
1594 send_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, lsb, current); 1594 send_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, lsb, current);
1595} 1595}
1596 1596
1597static bool fault_supports_stage2_pmd_mappings(struct kvm_memory_slot *memslot, 1597static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
1598 unsigned long hva) 1598 unsigned long hva,
1599 unsigned long map_size)
1599{ 1600{
1600 gpa_t gpa_start; 1601 gpa_t gpa_start;
1601 hva_t uaddr_start, uaddr_end; 1602 hva_t uaddr_start, uaddr_end;
@@ -1610,34 +1611,34 @@ static bool fault_supports_stage2_pmd_mappings(struct kvm_memory_slot *memslot,
1610 1611
1611 /* 1612 /*
1612 * Pages belonging to memslots that don't have the same alignment 1613 * Pages belonging to memslots that don't have the same alignment
1613 * within a PMD for userspace and IPA cannot be mapped with stage-2 1614 * within a PMD/PUD for userspace and IPA cannot be mapped with stage-2
1614 * PMD entries, because we'll end up mapping the wrong pages. 1615 * PMD/PUD entries, because we'll end up mapping the wrong pages.
1615 * 1616 *
1616 * Consider a layout like the following: 1617 * Consider a layout like the following:
1617 * 1618 *
1618 * memslot->userspace_addr: 1619 * memslot->userspace_addr:
1619 * +-----+--------------------+--------------------+---+ 1620 * +-----+--------------------+--------------------+---+
1620 * |abcde|fgh Stage-1 PMD | Stage-1 PMD tv|xyz| 1621 * |abcde|fgh Stage-1 block | Stage-1 block tv|xyz|
1621 * +-----+--------------------+--------------------+---+ 1622 * +-----+--------------------+--------------------+---+
1622 * 1623 *
1623 * memslot->base_gfn << PAGE_SIZE: 1624 * memslot->base_gfn << PAGE_SIZE:
1624 * +---+--------------------+--------------------+-----+ 1625 * +---+--------------------+--------------------+-----+
1625 * |abc|def Stage-2 PMD | Stage-2 PMD |tvxyz| 1626 * |abc|def Stage-2 block | Stage-2 block |tvxyz|
1626 * +---+--------------------+--------------------+-----+ 1627 * +---+--------------------+--------------------+-----+
1627 * 1628 *
1628 * If we create those stage-2 PMDs, we'll end up with this incorrect 1629 * If we create those stage-2 blocks, we'll end up with this incorrect
1629 * mapping: 1630 * mapping:
1630 * d -> f 1631 * d -> f
1631 * e -> g 1632 * e -> g
1632 * f -> h 1633 * f -> h
1633 */ 1634 */
1634 if ((gpa_start & ~S2_PMD_MASK) != (uaddr_start & ~S2_PMD_MASK)) 1635 if ((gpa_start & (map_size - 1)) != (uaddr_start & (map_size - 1)))
1635 return false; 1636 return false;
1636 1637
1637 /* 1638 /*
1638 * Next, let's make sure we're not trying to map anything not covered 1639 * Next, let's make sure we're not trying to map anything not covered
1639 * by the memslot. This means we have to prohibit PMD size mappings 1640 * by the memslot. This means we have to prohibit block size mappings
1640 * for the beginning and end of a non-PMD aligned and non-PMD sized 1641 * for the beginning and end of a non-block aligned and non-block sized
1641 * memory slot (illustrated by the head and tail parts of the 1642 * memory slot (illustrated by the head and tail parts of the
1642 * userspace view above containing pages 'abcde' and 'xyz', 1643 * userspace view above containing pages 'abcde' and 'xyz',
1643 * respectively). 1644 * respectively).
@@ -1646,8 +1647,8 @@ static bool fault_supports_stage2_pmd_mappings(struct kvm_memory_slot *memslot,
1646 * userspace_addr or the base_gfn, as both are equally aligned (per 1647 * userspace_addr or the base_gfn, as both are equally aligned (per
1647 * the check above) and equally sized. 1648 * the check above) and equally sized.
1648 */ 1649 */
1649 return (hva & S2_PMD_MASK) >= uaddr_start && 1650 return (hva & ~(map_size - 1)) >= uaddr_start &&
1650 (hva & S2_PMD_MASK) + S2_PMD_SIZE <= uaddr_end; 1651 (hva & ~(map_size - 1)) + map_size <= uaddr_end;
1651} 1652}
1652 1653
1653static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, 1654static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
@@ -1676,12 +1677,6 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
1676 return -EFAULT; 1677 return -EFAULT;
1677 } 1678 }
1678 1679
1679 if (!fault_supports_stage2_pmd_mappings(memslot, hva))
1680 force_pte = true;
1681
1682 if (logging_active)
1683 force_pte = true;
1684
1685 /* Let's check if we will get back a huge page backed by hugetlbfs */ 1680 /* Let's check if we will get back a huge page backed by hugetlbfs */
1686 down_read(&current->mm->mmap_sem); 1681 down_read(&current->mm->mmap_sem);
1687 vma = find_vma_intersection(current->mm, hva, hva + 1); 1682 vma = find_vma_intersection(current->mm, hva, hva + 1);
@@ -1692,6 +1687,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
1692 } 1687 }
1693 1688
1694 vma_pagesize = vma_kernel_pagesize(vma); 1689 vma_pagesize = vma_kernel_pagesize(vma);
1690 if (logging_active ||
1691 !fault_supports_stage2_huge_mapping(memslot, hva, vma_pagesize)) {
1692 force_pte = true;
1693 vma_pagesize = PAGE_SIZE;
1694 }
1695
1695 /* 1696 /*
1696 * The stage2 has a minimum of 2 level table (For arm64 see 1697 * The stage2 has a minimum of 2 level table (For arm64 see
1697 * kvm_arm_setup_stage2()). Hence, we are guaranteed that we can 1698 * kvm_arm_setup_stage2()). Hence, we are guaranteed that we can
@@ -1699,11 +1700,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
1699 * As for PUD huge maps, we must make sure that we have at least 1700 * As for PUD huge maps, we must make sure that we have at least
1700 * 3 levels, i.e, PMD is not folded. 1701 * 3 levels, i.e, PMD is not folded.
1701 */ 1702 */
1702 if ((vma_pagesize == PMD_SIZE || 1703 if (vma_pagesize == PMD_SIZE ||
1703 (vma_pagesize == PUD_SIZE && kvm_stage2_has_pmd(kvm))) && 1704 (vma_pagesize == PUD_SIZE && kvm_stage2_has_pmd(kvm)))
1704 !force_pte) {
1705 gfn = (fault_ipa & huge_page_mask(hstate_vma(vma))) >> PAGE_SHIFT; 1705 gfn = (fault_ipa & huge_page_mask(hstate_vma(vma))) >> PAGE_SHIFT;
1706 }
1707 up_read(&current->mm->mmap_sem); 1706 up_read(&current->mm->mmap_sem);
1708 1707
1709 /* We need minimum second+third level pages */ 1708 /* We need minimum second+third level pages */