aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kiszka2018-01-21 10:32:32 -0600
committerJan Kiszka2018-01-26 10:46:16 -0600
commita88684048228fc15bc979abcd533e433f038b370 (patch)
tree001b76863d316f93b8cd4153f938c8ebef63e9ad
parent74ed7fecb6d3f6c3f944c3c2e154ec55b6f679f7 (diff)
downloadjailhouse-a88684048228fc15bc979abcd533e433f038b370.tar.gz
jailhouse-a88684048228fc15bc979abcd533e433f038b370.tar.xz
jailhouse-a88684048228fc15bc979abcd533e433f038b370.zip
driver: Avoid dependency on additional kernel symbol exports
If CONFIG_KALLSYMS_ALL is enabled, we can get symbol addresses that the upstream kernel does not export via kallsyms_lookup_name. We can use this to avoid a number of kernel patches. Specifically, x86 can become patch-free once all guest-side support is merged and ivshmem-net is built as external module (or merged as well). Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
-rw-r--r--driver/main.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/driver/main.c b/driver/main.c
index af4930f3..ee585848 100644
--- a/driver/main.c
+++ b/driver/main.c
@@ -22,6 +22,7 @@
22#include <linux/miscdevice.h> 22#include <linux/miscdevice.h>
23#include <linux/firmware.h> 23#include <linux/firmware.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/kallsyms.h>
25#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0) 26#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0)
26#include <linux/sched/signal.h> 27#include <linux/sched/signal.h>
27#endif 28#endif
@@ -75,9 +76,7 @@ MODULE_FIRMWARE(JAILHOUSE_FW_NAME);
75#endif 76#endif
76MODULE_VERSION(JAILHOUSE_VERSION); 77MODULE_VERSION(JAILHOUSE_VERSION);
77 78
78#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
79extern unsigned int __hyp_stub_vectors[]; 79extern unsigned int __hyp_stub_vectors[];
80#endif
81 80
82struct console_state { 81struct console_state {
83 unsigned int head; 82 unsigned int head;
@@ -96,6 +95,17 @@ static struct jailhouse_console* volatile console_page;
96static bool console_available; 95static bool console_available;
97static struct resource *hypervisor_mem_res; 96static struct resource *hypervisor_mem_res;
98 97
98static typeof(ioremap_page_range) *ioremap_page_range_sym;
99#ifdef CONFIG_X86
100static typeof(lapic_timer_frequency) *lapic_timer_frequency_sym;
101#endif
102#ifdef CONFIG_ARM
103static typeof(__boot_cpu_mode) *__boot_cpu_mode_sym;
104#endif
105#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
106static typeof(__hyp_stub_vectors) *__hyp_stub_vectors_sym;
107#endif
108
99/* last_console contains three members: 109/* last_console contains three members:
100 * - valid: indicates if content in the page member is present 110 * - valid: indicates if content in the page member is present
101 * - id: hint for the consumer if it already consumed the content 111 * - id: hint for the consumer if it already consumed the content
@@ -191,9 +201,9 @@ void *jailhouse_ioremap(phys_addr_t phys, unsigned long virt,
191 return NULL; 201 return NULL;
192 vma->phys_addr = phys; 202 vma->phys_addr = phys;
193 203
194 if (ioremap_page_range((unsigned long)vma->addr, 204 if (ioremap_page_range_sym((unsigned long)vma->addr,
195 (unsigned long)vma->addr + size, phys, 205 (unsigned long)vma->addr + size, phys,
196 PAGE_KERNEL_EXEC)) { 206 PAGE_KERNEL_EXEC)) {
197 vunmap(vma->addr); 207 vunmap(vma->addr);
198 return NULL; 208 return NULL;
199 } 209 }
@@ -374,7 +384,9 @@ static int jailhouse_cmd_enable(struct jailhouse_system __user *arg)
374 goto error_unlock; 384 goto error_unlock;
375 385
376#ifdef CONFIG_ARM 386#ifdef CONFIG_ARM
377 if (!is_hyp_mode_available()) { 387 /* open-coded is_hyp_mode_available to use __boot_cpu_mode_sym */
388 if ((*__boot_cpu_mode_sym & MODE_MASK) != HYP_MODE ||
389 (*__boot_cpu_mode_sym) & BOOT_CPU_MODE_MISMATCH) {
378 pr_err("jailhouse: HYP mode not available\n"); 390 pr_err("jailhouse: HYP mode not available\n");
379 err = -ENODEV; 391 err = -ENODEV;
380 goto error_put_module; 392 goto error_put_module;
@@ -444,7 +456,7 @@ static int jailhouse_cmd_enable(struct jailhouse_system __user *arg)
444 header->max_cpus = max_cpus; 456 header->max_cpus = max_cpus;
445 457
446#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) 458#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
447 header->arm_linux_hyp_vectors = virt_to_phys(__hyp_stub_vectors); 459 header->arm_linux_hyp_vectors = virt_to_phys(*__hyp_stub_vectors_sym);
448#if LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0) 460#if LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0)
449 header->arm_linux_hyp_abi = HYP_STUB_ABI_LEGACY; 461 header->arm_linux_hyp_abi = HYP_STUB_ABI_LEGACY;
450#else 462#else
@@ -511,7 +523,7 @@ static int jailhouse_cmd_enable(struct jailhouse_system __user *arg)
511 config->platform_info.x86.tsc_khz = tsc_khz; 523 config->platform_info.x86.tsc_khz = tsc_khz;
512 if (config->platform_info.x86.apic_khz == 0) 524 if (config->platform_info.x86.apic_khz == 0)
513 config->platform_info.x86.apic_khz = 525 config->platform_info.x86.apic_khz =
514 lapic_timer_frequency / (1000 / HZ); 526 *lapic_timer_frequency_sym / (1000 / HZ);
515#endif 527#endif
516 528
517 err = jailhouse_cell_prepare_root(&config->root_cell); 529 err = jailhouse_cell_prepare_root(&config->root_cell);
@@ -649,7 +661,7 @@ static int jailhouse_cmd_disable(void)
649 * This flag has been set when onlining a CPU under Jailhouse 661 * This flag has been set when onlining a CPU under Jailhouse
650 * supervision into SVC instead of HYP mode. 662 * supervision into SVC instead of HYP mode.
651 */ 663 */
652 __boot_cpu_mode &= ~BOOT_CPU_MODE_MISMATCH; 664 *__boot_cpu_mode_sym &= ~BOOT_CPU_MODE_MISMATCH;
653#endif 665#endif
654 666
655 atomic_set(&call_done, 0); 667 atomic_set(&call_done, 0);
@@ -850,6 +862,27 @@ static int __init jailhouse_init(void)
850{ 862{
851 int err; 863 int err;
852 864
865#ifdef CONFIG_KALLSYMS_ALL
866#define RESOLVE_EXTERNAL_SYMBOL(symbol) \
867 symbol##_sym = (void *)kallsyms_lookup_name(#symbol); \
868 if (!symbol##_sym) \
869 return -EINVAL
870#else
871#define RESOLVE_EXTERNAL_SYMBOL(symbol) \
872 symbol##_sym = &symbol
873#endif
874
875 RESOLVE_EXTERNAL_SYMBOL(ioremap_page_range);
876#ifdef CONFIG_X86
877 RESOLVE_EXTERNAL_SYMBOL(lapic_timer_frequency);
878#endif
879#ifdef CONFIG_ARM
880 RESOLVE_EXTERNAL_SYMBOL(__boot_cpu_mode);
881#endif
882#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
883 RESOLVE_EXTERNAL_SYMBOL(__hyp_stub_vectors);
884#endif
885
853 jailhouse_dev = root_device_register("jailhouse"); 886 jailhouse_dev = root_device_register("jailhouse");
854 if (IS_ERR(jailhouse_dev)) 887 if (IS_ERR(jailhouse_dev))
855 return PTR_ERR(jailhouse_dev); 888 return PTR_ERR(jailhouse_dev);