diff options
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r-- | arch/x86/mm/pageattr.c | 29 |
1 files changed, 9 insertions, 20 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 7e600c1962db..24952fdc7e40 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
13 | #include <linux/debugfs.h> | 13 | #include <linux/debugfs.h> |
14 | #include <linux/pfn.h> | 14 | #include <linux/pfn.h> |
15 | #include <linux/percpu.h> | ||
15 | 16 | ||
16 | #include <asm/e820.h> | 17 | #include <asm/e820.h> |
17 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
@@ -686,7 +687,7 @@ static int cpa_process_alias(struct cpa_data *cpa) | |||
686 | { | 687 | { |
687 | struct cpa_data alias_cpa; | 688 | struct cpa_data alias_cpa; |
688 | unsigned long laddr = (unsigned long)__va(cpa->pfn << PAGE_SHIFT); | 689 | unsigned long laddr = (unsigned long)__va(cpa->pfn << PAGE_SHIFT); |
689 | unsigned long vaddr, remapped; | 690 | unsigned long vaddr; |
690 | int ret; | 691 | int ret; |
691 | 692 | ||
692 | if (cpa->pfn >= max_pfn_mapped) | 693 | if (cpa->pfn >= max_pfn_mapped) |
@@ -744,24 +745,6 @@ static int cpa_process_alias(struct cpa_data *cpa) | |||
744 | } | 745 | } |
745 | #endif | 746 | #endif |
746 | 747 | ||
747 | /* | ||
748 | * If the PMD page was partially used for per-cpu remapping, | ||
749 | * the recycled area needs to be split and modified. Because | ||
750 | * the area is always proper subset of a PMD page | ||
751 | * cpa->numpages is guaranteed to be 1 for these areas, so | ||
752 | * there's no need to loop over and check for further remaps. | ||
753 | */ | ||
754 | remapped = (unsigned long)pcpu_lpage_remapped((void *)laddr); | ||
755 | if (remapped) { | ||
756 | WARN_ON(cpa->numpages > 1); | ||
757 | alias_cpa = *cpa; | ||
758 | alias_cpa.vaddr = &remapped; | ||
759 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | ||
760 | ret = __change_page_attr_set_clr(&alias_cpa, 0); | ||
761 | if (ret) | ||
762 | return ret; | ||
763 | } | ||
764 | |||
765 | return 0; | 748 | return 0; |
766 | } | 749 | } |
767 | 750 | ||
@@ -822,6 +805,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, | |||
822 | { | 805 | { |
823 | struct cpa_data cpa; | 806 | struct cpa_data cpa; |
824 | int ret, cache, checkalias; | 807 | int ret, cache, checkalias; |
808 | unsigned long baddr = 0; | ||
825 | 809 | ||
826 | /* | 810 | /* |
827 | * Check, if we are requested to change a not supported | 811 | * Check, if we are requested to change a not supported |
@@ -853,6 +837,11 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, | |||
853 | */ | 837 | */ |
854 | WARN_ON_ONCE(1); | 838 | WARN_ON_ONCE(1); |
855 | } | 839 | } |
840 | /* | ||
841 | * Save address for cache flush. *addr is modified in the call | ||
842 | * to __change_page_attr_set_clr() below. | ||
843 | */ | ||
844 | baddr = *addr; | ||
856 | } | 845 | } |
857 | 846 | ||
858 | /* Must avoid aliasing mappings in the highmem code */ | 847 | /* Must avoid aliasing mappings in the highmem code */ |
@@ -900,7 +889,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, | |||
900 | cpa_flush_array(addr, numpages, cache, | 889 | cpa_flush_array(addr, numpages, cache, |
901 | cpa.flags, pages); | 890 | cpa.flags, pages); |
902 | } else | 891 | } else |
903 | cpa_flush_range(*addr, numpages, cache); | 892 | cpa_flush_range(baddr, numpages, cache); |
904 | } else | 893 | } else |
905 | cpa_flush_all(cache); | 894 | cpa_flush_all(cache); |
906 | 895 | ||