[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1348242975-19184-6-git-send-email-cyril@ti.com>
Date: Fri, 21 Sep 2012 11:56:03 -0400
From: Cyril Chemparathy <cyril@...com>
To: <linux@....linux.org.uk>
CC: <linux-arm-kernel@...ts.infradead.org>,
<linux-kernel@...r.kernel.org>, <arnd@...db.de>,
<catalin.marinas@....com>, <davidb@...eaurora.org>,
<frank.rowand@...sony.com>, <hsweeten@...ionengravers.com>,
<linus.walleij@...aro.org>, <marc.zyngier@....com>,
<nico@...aro.org>, <paul.gortmaker@...driver.com>,
<plagnioj@...osoft.com>, <rabin@....in>, <rmallon@...il.com>,
<rob.herring@...xeda.com>, <sboyd@...eaurora.org>,
<sjg@...omium.org>, <tglx@...utronix.de>, <tj@...nel.org>,
<vincent.guittot@...aro.org>, <vitalya@...com>,
<will.deacon@....com>, <grant.likely@...retlab.ca>,
Cyril Chemparathy <cyril@...com>
Subject: [PATCH v3 RESEND 05/17] ARM: LPAE: support 64-bit virt_to_phys patching
This patch adds support for 64-bit physical addresses in virt_to_phys()
patching. This does not do real 64-bit add/sub, but instead patches in the
upper 32-bits of the phys_offset directly into the output of virt_to_phys.
There is no corresponding change on the phys_to_virt() side, because
computations on the upper 32-bits would be discarded anyway.
Signed-off-by: Cyril Chemparathy <cyril@...com>
---
arch/arm/include/asm/memory.h | 38 ++++++++++++++++++++++++++++++++++++--
arch/arm/kernel/head.S | 4 ++++
arch/arm/kernel/setup.c | 2 +-
3 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 88ca206..f3e8f88 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -154,13 +154,47 @@
#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
extern unsigned long __pv_offset;
-extern unsigned long __pv_phys_offset;
+extern phys_addr_t __pv_phys_offset;
#define PHYS_OFFSET __virt_to_phys(PAGE_OFFSET)
static inline phys_addr_t __virt_to_phys(unsigned long x)
{
- unsigned long t;
+ phys_addr_t t;
+
+#ifndef CONFIG_ARM_LPAE
early_patch_imm8("add", t, x, __pv_offset, 0);
+#else
+ unsigned long __tmp;
+
+#ifndef __ARMEB__
+#define PV_PHYS_HIGH "(__pv_phys_offset + 4)"
+#else
+#define PV_PHYS_HIGH "__pv_phys_offset"
+#endif
+
+ early_patch_stub(
+ /* type */ PATCH_IMM8,
+ /* code */
+ "ldr %[tmp], =__pv_offset\n"
+ "ldr %[tmp], [%[tmp]]\n"
+ "add %Q[to], %[from], %[tmp]\n"
+ "ldr %[tmp], =" PV_PHYS_HIGH "\n"
+ "ldr %[tmp], [%[tmp]]\n"
+ "mov %R[to], %[tmp]\n",
+ /* pad */ 4,
+ /* patch_data */
+ ".long __pv_offset\n"
+ "add %Q[to], %[from], %[imm]\n"
+ ".long " PV_PHYS_HIGH "\n"
+ "mov %R[to], %[imm]\n",
+ /* operands */
+ : [to] "=r" (t),
+ [tmp] "=&r" (__tmp)
+ : [from] "r" (x),
+ [imm] "I" (__IMM8),
+ "i" (&__pv_offset),
+ "i" (&__pv_phys_offset));
+#endif
return t;
}
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 69a3c09..61fb8df 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -530,7 +530,11 @@ ENDPROC(__fixup_pv_offsets)
.align
1: .long .
+#if defined(CONFIG_ARM_LPAE) && defined(__ARMEB__)
+ .long __pv_phys_offset + 4
+#else
.long __pv_phys_offset
+#endif
.long __pv_offset
.long PAGE_OFFSET
#endif
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 59e0f57..edb4f42 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -159,7 +159,7 @@ DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
* The initializers here prevent these from landing in the BSS section.
*/
unsigned long __pv_offset = 0xdeadbeef;
-unsigned long __pv_phys_offset = 0xdeadbeef;
+phys_addr_t __pv_phys_offset = 0xdeadbeef;
EXPORT_SYMBOL(__pv_phys_offset);
#endif
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists