diff options
author | Tejun Heo <tj@kernel.org> | 2009-06-21 22:56:24 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2009-06-21 22:56:24 -0400 |
commit | 992f4c1c2c1583cef3296ec4bf5205843a9a5f3d (patch) | |
tree | 764e35b8492afdc73c771551d9b2b4a8c4f8820e /arch/x86/mm/pageattr.c | |
parent | 0ff2587fd54bd6f66bc6914ada4eb77a7e819a5b (diff) |
x86: reorganize cpa_process_alias()
Reorganize cpa_process_alias() so that new alias condition can be
added easily.
Jan Beulich spotted problem in the original cleanup thread which
incorrectly assumed the two existing conditions were mutially
exclusive.
[ Impact: code reorganization ]
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Jan Beulich <JBeulich@novell.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r-- | arch/x86/mm/pageattr.c | 50 |
1 files changed, 23 insertions, 27 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 3cfe9ced8a4c..2ab058b0947d 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -681,8 +681,9 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias); | |||
681 | static int cpa_process_alias(struct cpa_data *cpa) | 681 | static int cpa_process_alias(struct cpa_data *cpa) |
682 | { | 682 | { |
683 | struct cpa_data alias_cpa; | 683 | struct cpa_data alias_cpa; |
684 | int ret = 0; | 684 | unsigned long laddr = (unsigned long)__va(cpa->pfn << PAGE_SHIFT); |
685 | unsigned long temp_cpa_vaddr, vaddr; | 685 | unsigned long vaddr; |
686 | int ret; | ||
686 | 687 | ||
687 | if (cpa->pfn >= max_pfn_mapped) | 688 | if (cpa->pfn >= max_pfn_mapped) |
688 | return 0; | 689 | return 0; |
@@ -706,42 +707,37 @@ static int cpa_process_alias(struct cpa_data *cpa) | |||
706 | PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)))) { | 707 | PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)))) { |
707 | 708 | ||
708 | alias_cpa = *cpa; | 709 | alias_cpa = *cpa; |
709 | temp_cpa_vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); | 710 | alias_cpa.vaddr = &laddr; |
710 | alias_cpa.vaddr = &temp_cpa_vaddr; | ||
711 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | 711 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); |
712 | 712 | ||
713 | |||
714 | ret = __change_page_attr_set_clr(&alias_cpa, 0); | 713 | ret = __change_page_attr_set_clr(&alias_cpa, 0); |
714 | if (ret) | ||
715 | return ret; | ||
715 | } | 716 | } |
716 | 717 | ||
717 | #ifdef CONFIG_X86_64 | 718 | #ifdef CONFIG_X86_64 |
718 | if (ret) | ||
719 | return ret; | ||
720 | /* | 719 | /* |
721 | * No need to redo, when the primary call touched the high | 720 | * If the primary call didn't touch the high mapping already |
722 | * mapping already: | 721 | * and the physical address is inside the kernel map, we need |
723 | */ | ||
724 | if (within(vaddr, (unsigned long) _text, _brk_end)) | ||
725 | return 0; | ||
726 | |||
727 | /* | ||
728 | * If the physical address is inside the kernel map, we need | ||
729 | * to touch the high mapped kernel as well: | 722 | * to touch the high mapped kernel as well: |
730 | */ | 723 | */ |
731 | if (!within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) | 724 | if (!within(vaddr, (unsigned long)_text, _brk_end) && |
732 | return 0; | 725 | within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) { |
733 | 726 | unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + | |
734 | alias_cpa = *cpa; | 727 | __START_KERNEL_map - phys_base; |
735 | temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base; | 728 | alias_cpa = *cpa; |
736 | alias_cpa.vaddr = &temp_cpa_vaddr; | 729 | alias_cpa.vaddr = &temp_cpa_vaddr; |
737 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | 730 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); |
738 | 731 | ||
739 | /* | 732 | /* |
740 | * The high mapping range is imprecise, so ignore the return value. | 733 | * The high mapping range is imprecise, so ignore the |
741 | */ | 734 | * return value. |
742 | __change_page_attr_set_clr(&alias_cpa, 0); | 735 | */ |
736 | __change_page_attr_set_clr(&alias_cpa, 0); | ||
737 | } | ||
743 | #endif | 738 | #endif |
744 | return ret; | 739 | |
740 | return 0; | ||
745 | } | 741 | } |
746 | 742 | ||
747 | static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) | 743 | static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) |