aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/pageattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r--arch/x86/mm/pageattr.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 4fadfd2b7017..3bded76e8d5c 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file *m)
93static inline void split_page_count(int level) { } 93static inline void split_page_count(int level) { }
94#endif 94#endif
95 95
96static inline int
97within(unsigned long addr, unsigned long start, unsigned long end)
98{
99 return addr >= start && addr < end;
100}
101
102static inline int
103within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
104{
105 return addr >= start && addr <= end;
106}
107
96#ifdef CONFIG_X86_64 108#ifdef CONFIG_X86_64
97 109
98static inline unsigned long highmap_start_pfn(void) 110static inline unsigned long highmap_start_pfn(void)
@@ -106,20 +118,25 @@ static inline unsigned long highmap_end_pfn(void)
106 return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT; 118 return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT;
107} 119}
108 120
109#endif 121static bool __cpa_pfn_in_highmap(unsigned long pfn)
110
111static inline int
112within(unsigned long addr, unsigned long start, unsigned long end)
113{ 122{
114 return addr >= start && addr < end; 123 /*
124 * Kernel text has an alias mapping at a high address, known
125 * here as "highmap".
126 */
127 return within_inclusive(pfn, highmap_start_pfn(), highmap_end_pfn());
115} 128}
116 129
117static inline int 130#else
118within_inclusive(unsigned long addr, unsigned long start, unsigned long end) 131
132static bool __cpa_pfn_in_highmap(unsigned long pfn)
119{ 133{
120 return addr >= start && addr <= end; 134 /* There is no highmap on 32-bit */
135 return false;
121} 136}
122 137
138#endif
139
123/* 140/*
124 * Flushing functions 141 * Flushing functions
125 */ 142 */
@@ -1183,6 +1200,10 @@ static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
1183 cpa->numpages = 1; 1200 cpa->numpages = 1;
1184 cpa->pfn = __pa(vaddr) >> PAGE_SHIFT; 1201 cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
1185 return 0; 1202 return 0;
1203
1204 } else if (__cpa_pfn_in_highmap(cpa->pfn)) {
1205 /* Faults in the highmap are OK, so do not warn: */
1206 return -EFAULT;
1186 } else { 1207 } else {
1187 WARN(1, KERN_WARNING "CPA: called for zero pte. " 1208 WARN(1, KERN_WARNING "CPA: called for zero pte. "
1188 "vaddr = %lx cpa->vaddr = %lx\n", vaddr, 1209 "vaddr = %lx cpa->vaddr = %lx\n", vaddr,
@@ -1335,8 +1356,7 @@ static int cpa_process_alias(struct cpa_data *cpa)
1335 * to touch the high mapped kernel as well: 1356 * to touch the high mapped kernel as well:
1336 */ 1357 */
1337 if (!within(vaddr, (unsigned long)_text, _brk_end) && 1358 if (!within(vaddr, (unsigned long)_text, _brk_end) &&
1338 within_inclusive(cpa->pfn, highmap_start_pfn(), 1359 __cpa_pfn_in_highmap(cpa->pfn)) {
1339 highmap_end_pfn())) {
1340 unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + 1360 unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) +
1341 __START_KERNEL_map - phys_base; 1361 __START_KERNEL_map - phys_base;
1342 alias_cpa = *cpa; 1362 alias_cpa = *cpa;