From 395ea775bf4368fc455e3b8de86fac579b332363 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Tue, 11 Aug 2020 11:31:11 -0700 Subject: [PATCH] ANDROID: arm64: add __va_function With CFI, the compiler replaces function references with pointers to the CFI jump table. This breaks passing these addresses to code running at EL2, where the jump tables are not valid. Add a __va_function macro similarly to the earlier __pa_function to take address of the actual function in inline assembly and use that in kvm_ksym_ref instead. Bug: 163385976 Change-Id: I097b99409995512c00786300e7d18fe42c720a1b (cherry picked from commit 2f4d6c9fd77c88ad0500aad4bf1f64aaf2654c49) Signed-off-by: Sami Tolvanen --- arch/arm64/include/asm/kvm_asm.h | 4 ++-- arch/arm64/include/asm/memory.h | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 44a243754c1b..e695eddc9ece 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -43,9 +43,9 @@ /* Translate a kernel address of @sym into its equivalent linear mapping */ #define kvm_ksym_ref(sym) \ ({ \ - void *val = &sym; \ + void *val = __va_function(sym); \ if (!is_kernel_in_hyp_mode()) \ - val = lm_alias(&sym); \ + val = lm_alias(val); \ val; \ }) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index b6e4013dfc25..c49bf247040b 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -318,13 +318,15 @@ static inline void *phys_to_virt(phys_addr_t x) * virtual address. Therefore, use inline assembly to ensure we are * always taking the address of the actual function. */ -#define __pa_function(x) ({ \ - unsigned long addr; \ +#define __va_function(x) ({ \ + void *addr; \ asm("adrp %0, " __stringify(x) "\n\t" \ "add %0, %0, :lo12:" __stringify(x) : "=r" (addr)); \ - __pa_symbol(addr); \ + addr; \ }) +#define __pa_function(x) __pa_symbol(__va_function(x)) + /* * virt_to_page(x) convert a _valid_ virtual address to struct page * * virt_addr_valid(x) indicates whether a virtual address is valid