aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/pageattr.c53
1 files changed, 46 insertions, 7 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index db8ace29514f..b3b19f46c016 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -453,7 +453,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
453 * Check for races, another CPU might have split this page 453 * Check for races, another CPU might have split this page
454 * up already: 454 * up already:
455 */ 455 */
456 tmp = lookup_address(address, &level); 456 tmp = _lookup_address_cpa(cpa, address, &level);
457 if (tmp != kpte) 457 if (tmp != kpte)
458 goto out_unlock; 458 goto out_unlock;
459 459
@@ -559,7 +559,8 @@ out_unlock:
559} 559}
560 560
561static int 561static int
562__split_large_page(pte_t *kpte, unsigned long address, struct page *base) 562__split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
563 struct page *base)
563{ 564{
564 pte_t *pbase = (pte_t *)page_address(base); 565 pte_t *pbase = (pte_t *)page_address(base);
565 unsigned long pfn, pfninc = 1; 566 unsigned long pfn, pfninc = 1;
@@ -572,7 +573,7 @@ __split_large_page(pte_t *kpte, unsigned long address, struct page *base)
572 * Check for races, another CPU might have split this page 573 * Check for races, another CPU might have split this page
573 * up for us already: 574 * up for us already:
574 */ 575 */
575 tmp = lookup_address(address, &level); 576 tmp = _lookup_address_cpa(cpa, address, &level);
576 if (tmp != kpte) { 577 if (tmp != kpte) {
577 spin_unlock(&pgd_lock); 578 spin_unlock(&pgd_lock);
578 return 1; 579 return 1;
@@ -648,7 +649,8 @@ __split_large_page(pte_t *kpte, unsigned long address, struct page *base)
648 return 0; 649 return 0;
649} 650}
650 651
651static int split_large_page(pte_t *kpte, unsigned long address) 652static int split_large_page(struct cpa_data *cpa, pte_t *kpte,
653 unsigned long address)
652{ 654{
653 struct page *base; 655 struct page *base;
654 656
@@ -660,7 +662,7 @@ static int split_large_page(pte_t *kpte, unsigned long address)
660 if (!base) 662 if (!base)
661 return -ENOMEM; 663 return -ENOMEM;
662 664
663 if (__split_large_page(kpte, address, base)) 665 if (__split_large_page(cpa, kpte, address, base))
664 __free_page(base); 666 __free_page(base);
665 667
666 return 0; 668 return 0;
@@ -1041,6 +1043,9 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr)
1041static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr, 1043static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
1042 int primary) 1044 int primary)
1043{ 1045{
1046 if (cpa->pgd)
1047 return populate_pgd(cpa, vaddr);
1048
1044 /* 1049 /*
1045 * Ignore all non primary paths. 1050 * Ignore all non primary paths.
1046 */ 1051 */
@@ -1085,7 +1090,7 @@ static int __change_page_attr(struct cpa_data *cpa, int primary)
1085 else 1090 else
1086 address = *cpa->vaddr; 1091 address = *cpa->vaddr;
1087repeat: 1092repeat:
1088 kpte = lookup_address(address, &level); 1093 kpte = _lookup_address_cpa(cpa, address, &level);
1089 if (!kpte) 1094 if (!kpte)
1090 return __cpa_process_fault(cpa, address, primary); 1095 return __cpa_process_fault(cpa, address, primary);
1091 1096
@@ -1149,7 +1154,7 @@ repeat:
1149 /* 1154 /*
1150 * We have to split the large page: 1155 * We have to split the large page:
1151 */ 1156 */
1152 err = split_large_page(kpte, address); 1157 err = split_large_page(cpa, kpte, address);
1153 if (!err) { 1158 if (!err) {
1154 /* 1159 /*
1155 * Do a global flush tlb after splitting the large page 1160 * Do a global flush tlb after splitting the large page
@@ -1298,6 +1303,8 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
1298 int ret, cache, checkalias; 1303 int ret, cache, checkalias;
1299 unsigned long baddr = 0; 1304 unsigned long baddr = 0;
1300 1305
1306 memset(&cpa, 0, sizeof(cpa));
1307
1301 /* 1308 /*
1302 * Check, if we are requested to change a not supported 1309 * Check, if we are requested to change a not supported
1303 * feature: 1310 * feature:
@@ -1744,6 +1751,7 @@ static int __set_pages_p(struct page *page, int numpages)
1744{ 1751{
1745 unsigned long tempaddr = (unsigned long) page_address(page); 1752 unsigned long tempaddr = (unsigned long) page_address(page);
1746 struct cpa_data cpa = { .vaddr = &tempaddr, 1753 struct cpa_data cpa = { .vaddr = &tempaddr,
1754 .pgd = NULL,
1747 .numpages = numpages, 1755 .numpages = numpages,
1748 .mask_set = __pgprot(_PAGE_PRESENT | _PAGE_RW), 1756 .mask_set = __pgprot(_PAGE_PRESENT | _PAGE_RW),
1749 .mask_clr = __pgprot(0), 1757 .mask_clr = __pgprot(0),
@@ -1762,6 +1770,7 @@ static int __set_pages_np(struct page *page, int numpages)
1762{ 1770{
1763 unsigned long tempaddr = (unsigned long) page_address(page); 1771 unsigned long tempaddr = (unsigned long) page_address(page);
1764 struct cpa_data cpa = { .vaddr = &tempaddr, 1772 struct cpa_data cpa = { .vaddr = &tempaddr,
1773 .pgd = NULL,
1765 .numpages = numpages, 1774 .numpages = numpages,
1766 .mask_set = __pgprot(0), 1775 .mask_set = __pgprot(0),
1767 .mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW), 1776 .mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW),
@@ -1822,6 +1831,36 @@ bool kernel_page_present(struct page *page)
1822 1831
1823#endif /* CONFIG_DEBUG_PAGEALLOC */ 1832#endif /* CONFIG_DEBUG_PAGEALLOC */
1824 1833
1834int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
1835 unsigned numpages, unsigned long page_flags)
1836{
1837 int retval = -EINVAL;
1838
1839 struct cpa_data cpa = {
1840 .vaddr = &address,
1841 .pfn = pfn,
1842 .pgd = pgd,
1843 .numpages = numpages,
1844 .mask_set = __pgprot(0),
1845 .mask_clr = __pgprot(0),
1846 .flags = 0,
1847 };
1848
1849 if (!(__supported_pte_mask & _PAGE_NX))
1850 goto out;
1851
1852 if (!(page_flags & _PAGE_NX))
1853 cpa.mask_clr = __pgprot(_PAGE_NX);
1854
1855 cpa.mask_set = __pgprot(_PAGE_PRESENT | page_flags);
1856
1857 retval = __change_page_attr_set_clr(&cpa, 0);
1858 __flush_tlb_all();
1859
1860out:
1861 return retval;
1862}
1863
1825/* 1864/*
1826 * The testcases use internal knowledge of the implementation that shouldn't 1865 * The testcases use internal knowledge of the implementation that shouldn't
1827 * be exposed to the rest of the kernel. Include these directly here. 1866 * be exposed to the rest of the kernel. Include these directly here.