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 <samitolvanen@google.com>
This commit is contained in:
Sami Tolvanen 2020-08-11 11:31:11 -07:00
parent 8152ef3a7a
commit 395ea775bf
2 changed files with 7 additions and 5 deletions

View File

@ -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; \
})

View File

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