summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2008-02-15 22:17:57 +0100
committerThomas Gleixner <tglx@linutronix.de>2008-02-18 20:54:14 +0100
commitf34b439f34c49d7de858234bab5e2dd03cfaf3c1 (patch)
tree9707b181f13361b86285524e009522aa43f47fea
parentaf96e4438a4b34a257f5318a296e0b9e182e7ab9 (diff)
x86: CPA: avoid double checking of alias ranges
When the CPA code is called with an virtual address in the range of the direct mapping or the high alias then we do not need to run through the alias check for this range. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-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 b8f53233151..3ee14996c82 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);
static int cpa_process_alias(struct cpa_data *cpa)
{
struct cpa_data alias_cpa;
- int ret;
+ int ret = 0;
if (cpa->pfn > max_pfn_mapped)
return 0;
- alias_cpa = *cpa;
- alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
+ /*
+ * No need to redo, when the primary call touched the direct
+ * mapping already:
+ */
+ if (!within(cpa->vaddr, PAGE_OFFSET,
+ PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) {
- ret = __change_page_attr_set_clr(&alias_cpa, 0);
+ alias_cpa = *cpa;
+ alias_cpa.vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
+
+ ret = __change_page_attr_set_clr(&alias_cpa, 0);
+ }
#ifdef CONFIG_X86_64
if (ret)
return ret;
/*
+ * No need to redo, when the primary call touched the high
+ * mapping already:
+ */
+ if (within(cpa->vaddr, (unsigned long) _text, (unsigned long) _end))
+ return 0;
+
+ /*
* If the physical address is inside the kernel map, we need
* to touch the high mapped kernel as well:
*/