aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/mm/pageattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/mm/pageattr.c')
-rw-r--r--arch/x86_64/mm/pageattr.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index 081409aa3452..d653d0bf3df6 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -180,16 +180,24 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
180 */ 180 */
181int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) 181int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
182{ 182{
183 int err = 0; 183 int err = 0, kernel_map = 0;
184 int i; 184 int i;
185 185
186 if (address >= __START_KERNEL_map
187 && address < __START_KERNEL_map + KERNEL_TEXT_SIZE) {
188 address = (unsigned long)__va(__pa(address));
189 kernel_map = 1;
190 }
191
186 down_write(&init_mm.mmap_sem); 192 down_write(&init_mm.mmap_sem);
187 for (i = 0; i < numpages; i++, address += PAGE_SIZE) { 193 for (i = 0; i < numpages; i++, address += PAGE_SIZE) {
188 unsigned long pfn = __pa(address) >> PAGE_SHIFT; 194 unsigned long pfn = __pa(address) >> PAGE_SHIFT;
189 195
190 err = __change_page_attr(address, pfn, prot, PAGE_KERNEL); 196 if (!kernel_map || pte_present(pfn_pte(0, prot))) {
191 if (err) 197 err = __change_page_attr(address, pfn, prot, PAGE_KERNEL);
192 break; 198 if (err)
199 break;
200 }
193 /* Handle kernel mapping too which aliases part of the 201 /* Handle kernel mapping too which aliases part of the
194 * lowmem */ 202 * lowmem */
195 if (__pa(address) < KERNEL_TEXT_SIZE) { 203 if (__pa(address) < KERNEL_TEXT_SIZE) {