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 | |
| 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>
| -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) |
