diff --git a/src/jailhouse/driver/main.c b/src/jailhouse/driver/main.c index 64e2b9a468acfa25eabd6239cebf7a261fe96eca..def7842e5f6bd66f4ecf190cd0cccd80d04957d6 100644 --- a/src/jailhouse/driver/main.c +++ b/src/jailhouse/driver/main.c @@ -55,6 +55,10 @@ #include #include +#ifdef KPROBE_LOOKUP +#include +#endif + #ifdef CONFIG_X86_32 #error 64-bit kernel required! #endif @@ -200,9 +204,11 @@ static long get_max_cpus(u32 cpu_set_size, return -EINVAL; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0) +static typeof(__get_vm_area_caller) *__get_vm_area_caller_sym; + #define __get_vm_area(size, flags, start, end) \ - __get_vm_area_caller(size, flags, start, end, \ + __get_vm_area_caller_sym(size, flags, start, end, \ __builtin_return_address(0)) #endif @@ -924,6 +930,34 @@ static int __init jailhouse_init(void) symbol##_sym = (void *)kallsyms_lookup_name(#symbol); \ if (!symbol##_sym) \ return -EINVAL +#elif defined(CONFIG_KALLSYMS_ALL) && LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0) + +#if !defined(CONFIG_KPROBES) +#error Kprobe is required! please confirm 'CONFIG_KPROBES' option when compiling kernel. +#else +#define KPROBE_LOOKUP 1 + + struct kprobe kp = { + .symbol_name = "kallsyms_lookup_name", + }; + + /* typedef for kallsyms_lookup_name() so we can easily cast kp.addr */ + typedef unsigned long (*kallsyms_lookup_name_t)(const char *name); + kallsyms_lookup_name_t kallsyms_lookup_name; + + /* register the kprobe */ + register_kprobe(&kp); + /* assign kallsyms_lookup_name symbol to kp.addr */ + kallsyms_lookup_name = (kallsyms_lookup_name_t)kp.addr; + /* done with the kprobe, so unregister it */ + unregister_kprobe(&kp); + +#define __RESOLVE_EXTERNAL_SYMBOL(symbol) \ + symbol##_sym = (void *)kallsyms_lookup_name(#symbol); \ + if (!symbol##_sym) \ + return -EINVAL +#endif + #else #define __RESOLVE_EXTERNAL_SYMBOL(symbol) \ symbol##_sym = &symbol @@ -931,6 +965,9 @@ static int __init jailhouse_init(void) #define RESOLVE_EXTERNAL_SYMBOL(symbol...) __RESOLVE_EXTERNAL_SYMBOL(symbol) RESOLVE_EXTERNAL_SYMBOL(ioremap_page_range); +#ifdef KPROBE_LOOKUP + RESOLVE_EXTERNAL_SYMBOL(__get_vm_area_caller); +#endif #ifdef CONFIG_X86 RESOLVE_EXTERNAL_SYMBOL(lapic_timer_period); #endif