diff options
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r-- | arch/x86/mm/pageattr.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index afd40054d157..65c6e46bf059 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -141,7 +141,7 @@ static void cpa_flush_all(unsigned long cache) | |||
141 | { | 141 | { |
142 | BUG_ON(irqs_disabled()); | 142 | BUG_ON(irqs_disabled()); |
143 | 143 | ||
144 | on_each_cpu(__cpa_flush_all, (void *) cache, 1, 1); | 144 | on_each_cpu(__cpa_flush_all, (void *) cache, 1); |
145 | } | 145 | } |
146 | 146 | ||
147 | static void __cpa_flush_range(void *arg) | 147 | static void __cpa_flush_range(void *arg) |
@@ -162,7 +162,7 @@ static void cpa_flush_range(unsigned long start, int numpages, int cache) | |||
162 | BUG_ON(irqs_disabled()); | 162 | BUG_ON(irqs_disabled()); |
163 | WARN_ON(PAGE_ALIGN(start) != start); | 163 | WARN_ON(PAGE_ALIGN(start) != start); |
164 | 164 | ||
165 | on_each_cpu(__cpa_flush_range, NULL, 1, 1); | 165 | on_each_cpu(__cpa_flush_range, NULL, 1); |
166 | 166 | ||
167 | if (!cache) | 167 | if (!cache) |
168 | return; | 168 | return; |
@@ -262,6 +262,7 @@ pte_t *lookup_address(unsigned long address, unsigned int *level) | |||
262 | 262 | ||
263 | return pte_offset_kernel(pmd, address); | 263 | return pte_offset_kernel(pmd, address); |
264 | } | 264 | } |
265 | EXPORT_SYMBOL_GPL(lookup_address); | ||
265 | 266 | ||
266 | /* | 267 | /* |
267 | * Set the new pmd in all the pgds we know about: | 268 | * Set the new pmd in all the pgds we know about: |
@@ -536,8 +537,14 @@ static int split_large_page(pte_t *kpte, unsigned long address) | |||
536 | set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); | 537 | set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); |
537 | 538 | ||
538 | if (address >= (unsigned long)__va(0) && | 539 | if (address >= (unsigned long)__va(0) && |
540 | address < (unsigned long)__va(max_low_pfn_mapped << PAGE_SHIFT)) | ||
541 | split_page_count(level); | ||
542 | |||
543 | #ifdef CONFIG_X86_64 | ||
544 | if (address >= (unsigned long)__va(1UL<<32) && | ||
539 | address < (unsigned long)__va(max_pfn_mapped << PAGE_SHIFT)) | 545 | address < (unsigned long)__va(max_pfn_mapped << PAGE_SHIFT)) |
540 | split_page_count(level); | 546 | split_page_count(level); |
547 | #endif | ||
541 | 548 | ||
542 | /* | 549 | /* |
543 | * Install the new, split up pagetable. Important details here: | 550 | * Install the new, split up pagetable. Important details here: |
@@ -652,15 +659,24 @@ static int cpa_process_alias(struct cpa_data *cpa) | |||
652 | struct cpa_data alias_cpa; | 659 | struct cpa_data alias_cpa; |
653 | int ret = 0; | 660 | int ret = 0; |
654 | 661 | ||
655 | if (cpa->pfn > max_pfn_mapped) | 662 | if (cpa->pfn >= max_pfn_mapped) |
656 | return 0; | 663 | return 0; |
657 | 664 | ||
665 | #ifdef CONFIG_X86_64 | ||
666 | if (cpa->pfn >= max_low_pfn_mapped && cpa->pfn < (1UL<<(32-PAGE_SHIFT))) | ||
667 | return 0; | ||
668 | #endif | ||
658 | /* | 669 | /* |
659 | * No need to redo, when the primary call touched the direct | 670 | * No need to redo, when the primary call touched the direct |
660 | * mapping already: | 671 | * mapping already: |
661 | */ | 672 | */ |
662 | if (!within(cpa->vaddr, PAGE_OFFSET, | 673 | if (!(within(cpa->vaddr, PAGE_OFFSET, |
663 | PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) { | 674 | PAGE_OFFSET + (max_low_pfn_mapped << PAGE_SHIFT)) |
675 | #ifdef CONFIG_X86_64 | ||
676 | || within(cpa->vaddr, PAGE_OFFSET + (1UL<<32), | ||
677 | PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)) | ||
678 | #endif | ||
679 | )) { | ||
664 | 680 | ||
665 | alias_cpa = *cpa; | 681 | alias_cpa = *cpa; |
666 | alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); | 682 | alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); |