diff options
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/pageattr.c | 23 |
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); | |||
594 | static int cpa_process_alias(struct cpa_data *cpa) | 594 | static 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 | */ |