aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/mm/pageattr.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index b8f53233151d..3ee14996c829 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -594,20 +594,35 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias);
594static int cpa_process_alias(struct cpa_data *cpa) 594static int cpa_process_alias(struct cpa_data *cpa)
595{ 595{
596 struct cpa_data alias_cpa; 596 struct cpa_data alias_cpa;
597 int ret; 597 int ret = 0;
598 598
599 if (cpa->pfn > max_pfn_mapped) 599 if (cpa->pfn > max_pfn_mapped)
600 return 0; 600 return 0;
601 601
602 alias_cpa = *cpa; 602 /*
603 alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); 603 * No need to redo, when the primary call touched the direct
604 * mapping already:
605 */
606 if (!within(cpa->vaddr, PAGE_OFFSET,
607 PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) {
604 608
605 ret = __change_page_attr_set_clr(&alias_cpa, 0); 609 alias_cpa = *cpa;
610 alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
611
612 ret = __change_page_attr_set_clr(&alias_cpa, 0);
613 }
606 614
607#ifdef CONFIG_X86_64 615#ifdef CONFIG_X86_64
608 if (ret) 616 if (ret)
609 return ret; 617 return ret;
610 /* 618 /*
619 * No need to redo, when the primary call touched the high
620 * mapping already:
621 */
622 if (within(cpa->vaddr, (unsigned long) _text, (unsigned long) _end))
623 return 0;
624
625 /*
611 * If the physical address is inside the kernel map, we need 626 * If the physical address is inside the kernel map, we need
612 * to touch the high mapped kernel as well: 627 * to touch the high mapped kernel as well:
613 */ 628 */