arm: common: Use label to identify cpaccess dummy instruction
Use a label instead of using function start address. It's not
guaranteed that the compiler will make the mrc instruction
the first instruction in the function.
Self-modifying code replaces the dummy instruction with a new
instruction during runtime according to user inputs.
Change-Id: I8c37f4e414ce5983f0317a51a3cf790b45763bfc
Acked-by: Suren Eda Naarayana Kulothungan <sedanaar@qualcomm.com>
Signed-off-by: Neil Leeder <nleeder@codeaurora.org>
diff --git a/arch/arm/common/cpaccess.c b/arch/arm/common/cpaccess.c
index e71e318..12e2c38 100644
--- a/arch/arm/common/cpaccess.c
+++ b/arch/arm/common/cpaccess.c
@@ -63,6 +63,8 @@
.name = "cpaccess",
};
+void cpaccess_dummy_inst(void);
+
#ifdef CONFIG_ARCH_MSM_KRAIT
/*
* do_read_il2 - Read indirect L2 registers
@@ -143,9 +145,12 @@
*/
static noinline unsigned long cpaccess_dummy(unsigned long write_val)
{
- asm("mrc p15, 0, r0, c0, c0, 0\n\t");
- asm("bx lr\n\t");
- return 0xBEEF;
+ unsigned long ret = 0xBEEF;
+
+ asm volatile (".globl cpaccess_dummy_inst\n"
+ "cpaccess_dummy_inst:\n\t"
+ "mrc p15, 0, %0, c0, c0, 0\n\t" : "=r" (ret));
+ return ret;
} __attribute__((aligned(32)))
/*
@@ -195,7 +200,7 @@
* Grab address of the Dummy function, write the MRC/MCR
* instruction, ensuring cache coherency.
*/
- p_opcode = (unsigned long *)&cpaccess_dummy;
+ p_opcode = (unsigned long *)&cpaccess_dummy_inst;
mem_text_write_kernel_word(p_opcode, opcode);
#ifdef CONFIG_SMP