@@ -1375,47 +1375,6 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
1375
1375
return ret ;
1376
1376
}
1377
1377
1378
- static bool transparent_hugepage_adjust (kvm_pfn_t * pfnp , phys_addr_t * ipap )
1379
- {
1380
- kvm_pfn_t pfn = * pfnp ;
1381
- gfn_t gfn = * ipap >> PAGE_SHIFT ;
1382
-
1383
- if (kvm_is_transparent_hugepage (pfn )) {
1384
- unsigned long mask ;
1385
- /*
1386
- * The address we faulted on is backed by a transparent huge
1387
- * page. However, because we map the compound huge page and
1388
- * not the individual tail page, we need to transfer the
1389
- * refcount to the head page. We have to be careful that the
1390
- * THP doesn't start to split while we are adjusting the
1391
- * refcounts.
1392
- *
1393
- * We are sure this doesn't happen, because mmu_notifier_retry
1394
- * was successful and we are holding the mmu_lock, so if this
1395
- * THP is trying to split, it will be blocked in the mmu
1396
- * notifier before touching any of the pages, specifically
1397
- * before being able to call __split_huge_page_refcount().
1398
- *
1399
- * We can therefore safely transfer the refcount from PG_tail
1400
- * to PG_head and switch the pfn from a tail page to the head
1401
- * page accordingly.
1402
- */
1403
- mask = PTRS_PER_PMD - 1 ;
1404
- VM_BUG_ON ((gfn & mask ) != (pfn & mask ));
1405
- if (pfn & mask ) {
1406
- * ipap &= PMD_MASK ;
1407
- kvm_release_pfn_clean (pfn );
1408
- pfn &= ~mask ;
1409
- kvm_get_pfn (pfn );
1410
- * pfnp = pfn ;
1411
- }
1412
-
1413
- return true;
1414
- }
1415
-
1416
- return false;
1417
- }
1418
-
1419
1378
/**
1420
1379
* stage2_wp_ptes - write protect PMD range
1421
1380
* @pmd: pointer to pmd entry
@@ -1663,6 +1622,59 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
1663
1622
(hva & ~(map_size - 1 )) + map_size <= uaddr_end ;
1664
1623
}
1665
1624
1625
+ /*
1626
+ * Check if the given hva is backed by a transparent huge page (THP) and
1627
+ * whether it can be mapped using block mapping in stage2. If so, adjust
1628
+ * the stage2 PFN and IPA accordingly. Only PMD_SIZE THPs are currently
1629
+ * supported. This will need to be updated to support other THP sizes.
1630
+ *
1631
+ * Returns the size of the mapping.
1632
+ */
1633
+ static unsigned long
1634
+ transparent_hugepage_adjust (struct kvm_memory_slot * memslot ,
1635
+ unsigned long hva , kvm_pfn_t * pfnp ,
1636
+ phys_addr_t * ipap )
1637
+ {
1638
+ kvm_pfn_t pfn = * pfnp ;
1639
+
1640
+ /*
1641
+ * Make sure the adjustment is done only for THP pages. Also make
1642
+ * sure that the HVA and IPA are sufficiently aligned and that the
1643
+ * block map is contained within the memslot.
1644
+ */
1645
+ if (kvm_is_transparent_hugepage (pfn ) &&
1646
+ fault_supports_stage2_huge_mapping (memslot , hva , PMD_SIZE )) {
1647
+ /*
1648
+ * The address we faulted on is backed by a transparent huge
1649
+ * page. However, because we map the compound huge page and
1650
+ * not the individual tail page, we need to transfer the
1651
+ * refcount to the head page. We have to be careful that the
1652
+ * THP doesn't start to split while we are adjusting the
1653
+ * refcounts.
1654
+ *
1655
+ * We are sure this doesn't happen, because mmu_notifier_retry
1656
+ * was successful and we are holding the mmu_lock, so if this
1657
+ * THP is trying to split, it will be blocked in the mmu
1658
+ * notifier before touching any of the pages, specifically
1659
+ * before being able to call __split_huge_page_refcount().
1660
+ *
1661
+ * We can therefore safely transfer the refcount from PG_tail
1662
+ * to PG_head and switch the pfn from a tail page to the head
1663
+ * page accordingly.
1664
+ */
1665
+ * ipap &= PMD_MASK ;
1666
+ kvm_release_pfn_clean (pfn );
1667
+ pfn &= ~(PTRS_PER_PMD - 1 );
1668
+ kvm_get_pfn (pfn );
1669
+ * pfnp = pfn ;
1670
+
1671
+ return PMD_SIZE ;
1672
+ }
1673
+
1674
+ /* Use page mapping if we cannot use block mapping. */
1675
+ return PAGE_SIZE ;
1676
+ }
1677
+
1666
1678
static int user_mem_abort (struct kvm_vcpu * vcpu , phys_addr_t fault_ipa ,
1667
1679
struct kvm_memory_slot * memslot , unsigned long hva ,
1668
1680
unsigned long fault_status )
@@ -1776,20 +1788,13 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
1776
1788
if (mmu_notifier_retry (kvm , mmu_seq ))
1777
1789
goto out_unlock ;
1778
1790
1779
- if (vma_pagesize == PAGE_SIZE && !force_pte ) {
1780
- /*
1781
- * Only PMD_SIZE transparent hugepages(THP) are
1782
- * currently supported. This code will need to be
1783
- * updated to support other THP sizes.
1784
- *
1785
- * Make sure the host VA and the guest IPA are sufficiently
1786
- * aligned and that the block is contained within the memslot.
1787
- */
1788
- if (fault_supports_stage2_huge_mapping (memslot , hva , PMD_SIZE ) &&
1789
- transparent_hugepage_adjust (& pfn , & fault_ipa ))
1790
- vma_pagesize = PMD_SIZE ;
1791
- }
1792
-
1791
+ /*
1792
+ * If we are not forced to use page mapping, check if we are
1793
+ * backed by a THP and thus use block mapping if possible.
1794
+ */
1795
+ if (vma_pagesize == PAGE_SIZE && !force_pte )
1796
+ vma_pagesize = transparent_hugepage_adjust (memslot , hva ,
1797
+ & pfn , & fault_ipa );
1793
1798
if (writable )
1794
1799
kvm_set_pfn_dirty (pfn );
1795
1800
0 commit comments