2 * Jailhouse, a Linux-based partitioning hypervisor
4 * Copyright (c) Siemens AG, 2013-2015
5 * Copyright (c) Valentine Sinitsyn, 2014
8 * Jan Kiszka <jan.kiszka@siemens.com>
9 * Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
11 * This work is licensed under the terms of the GNU GPL, version 2. See
12 * the COPYING file in the top-level directory.
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/device.h>
19 #include <linux/miscdevice.h>
20 #include <linux/firmware.h>
22 #include <linux/smp.h>
23 #include <linux/uaccess.h>
24 #include <linux/reboot.h>
25 #include <linux/vmalloc.h>
28 #include <asm/cacheflush.h>
29 #include <asm/tlbflush.h>
32 #include "jailhouse.h"
37 #include <jailhouse/header.h>
38 #include <jailhouse/hypercall.h>
39 #include <generated/version.h>
42 #error 64-bit kernel required!
45 #if JAILHOUSE_CELL_ID_NAMELEN != JAILHOUSE_CELL_NAME_MAXLEN
46 # warning JAILHOUSE_CELL_ID_NAMELEN and JAILHOUSE_CELL_NAME_MAXLEN out of sync!
49 /* For compatibility with older kernel versions */
50 #include <linux/version.h>
53 #define JAILHOUSE_AMD_FW_NAME "jailhouse-amd.bin"
54 #define JAILHOUSE_INTEL_FW_NAME "jailhouse-intel.bin"
56 #define JAILHOUSE_FW_NAME "jailhouse.bin"
59 MODULE_DESCRIPTION("Management driver for Jailhouse partitioning hypervisor");
60 MODULE_LICENSE("GPL");
62 MODULE_FIRMWARE(JAILHOUSE_AMD_FW_NAME);
63 MODULE_FIRMWARE(JAILHOUSE_INTEL_FW_NAME);
65 MODULE_FIRMWARE(JAILHOUSE_FW_NAME);
67 MODULE_VERSION(JAILHOUSE_VERSION);
69 DEFINE_MUTEX(jailhouse_lock);
70 bool jailhouse_enabled;
72 static struct device *jailhouse_dev;
73 static void *hypervisor_mem;
74 static unsigned long hv_core_and_percpu_size;
75 static atomic_t call_done;
76 static int error_code;
79 bool jailhouse_use_vmcall;
81 static void init_hypercall(void)
83 jailhouse_use_vmcall = boot_cpu_has(X86_FEATURE_VMX);
85 #else /* !CONFIG_X86 */
86 static void init_hypercall(void)
91 static long get_max_cpus(u32 cpu_set_size,
92 const struct jailhouse_system __user *system_config)
95 (u8 __user *)jailhouse_cell_cpu_set(
96 (const struct jailhouse_cell_desc * __force)
97 &system_config->root_cell);
98 unsigned int pos = cpu_set_size;
103 if (get_user(bitmap, cpu_set + pos))
105 max_cpu_id = fls(bitmap);
107 return pos * 8 + max_cpu_id;
112 void *jailhouse_ioremap(phys_addr_t phys, unsigned long virt,
115 struct vm_struct *vma;
117 size = PAGE_ALIGN(size);
119 vma = __get_vm_area(size, VM_IOREMAP, virt,
120 virt + size + PAGE_SIZE);
122 vma = __get_vm_area(size, VM_IOREMAP, VMALLOC_START,
126 vma->phys_addr = phys;
128 if (ioremap_page_range((unsigned long)vma->addr,
129 (unsigned long)vma->addr + size, phys,
138 static void enter_hypervisor(void *info)
140 struct jailhouse_header *header = info;
141 unsigned int cpu = smp_processor_id();
144 if (cpu < header->max_cpus)
145 /* either returns 0 or the same error code across all CPUs */
146 err = header->entry(cpu);
153 #if defined(CONFIG_X86) && LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)
154 /* on Intel, VMXE is now on - update the shadow */
158 atomic_inc(&call_done);
161 static inline const char * jailhouse_fw_name(void)
164 if (boot_cpu_has(X86_FEATURE_SVM))
165 return JAILHOUSE_AMD_FW_NAME;
166 if (boot_cpu_has(X86_FEATURE_VMX))
167 return JAILHOUSE_INTEL_FW_NAME;
170 return JAILHOUSE_FW_NAME;
174 static int jailhouse_cmd_enable(struct jailhouse_system __user *arg)
176 const struct firmware *hypervisor;
177 struct jailhouse_system config_header;
178 struct jailhouse_system *config;
179 struct jailhouse_memory *hv_mem = &config_header.hypervisor_memory;
180 struct jailhouse_header *header;
181 void __iomem *console = NULL;
182 unsigned long config_size;
187 fw_name = jailhouse_fw_name();
189 pr_err("jailhouse: Missing or unsupported HVM technology\n");
193 if (copy_from_user(&config_header, arg, sizeof(config_header)))
196 if (memcmp(config_header.signature, JAILHOUSE_SYSTEM_SIGNATURE,
197 sizeof(config_header.signature)) != 0) {
198 pr_err("jailhouse: Not a system configuration\n");
202 config_header.root_cell.name[JAILHOUSE_CELL_NAME_MAXLEN] = 0;
204 max_cpus = get_max_cpus(config_header.root_cell.cpu_set_size, arg);
207 if (max_cpus > UINT_MAX)
210 if (mutex_lock_interruptible(&jailhouse_lock) != 0)
214 if (jailhouse_enabled || !try_module_get(THIS_MODULE))
217 err = request_firmware(&hypervisor, fw_name, jailhouse_dev);
219 pr_err("jailhouse: Missing hypervisor image %s\n", fw_name);
220 goto error_put_module;
223 header = (struct jailhouse_header *)hypervisor->data;
226 if (memcmp(header->signature, JAILHOUSE_SIGNATURE,
227 sizeof(header->signature)) != 0 ||
228 hypervisor->size >= hv_mem->size)
229 goto error_release_fw;
231 hv_core_and_percpu_size = header->core_size +
232 max_cpus * header->percpu_size;
233 config_size = jailhouse_system_config_size(&config_header);
234 if (hv_core_and_percpu_size >= hv_mem->size ||
235 config_size >= hv_mem->size - hv_core_and_percpu_size)
236 goto error_release_fw;
238 hypervisor_mem = jailhouse_ioremap(hv_mem->phys_start, JAILHOUSE_BASE,
240 if (!hypervisor_mem) {
241 pr_err("jailhouse: Unable to map RAM reserved for hypervisor "
242 "at %08lx\n", (unsigned long)hv_mem->phys_start);
243 goto error_release_fw;
246 memcpy(hypervisor_mem, hypervisor->data, hypervisor->size);
247 memset(hypervisor_mem + hypervisor->size, 0,
248 hv_mem->size - hypervisor->size);
250 header = (struct jailhouse_header *)hypervisor_mem;
251 header->max_cpus = max_cpus;
253 config = (struct jailhouse_system *)
254 (hypervisor_mem + hv_core_and_percpu_size);
255 if (copy_from_user(config, arg, config_size)) {
260 if (config->debug_console.flags & JAILHOUSE_MEM_IO) {
261 console = ioremap(config->debug_console.phys_start,
262 config->debug_console.size);
265 pr_err("jailhouse: Unable to map hypervisor debug "
266 "console at %08lx\n",
267 (unsigned long)config->debug_console.phys_start);
270 /* The hypervisor has no notion of address spaces, so we need
271 * to enforce conversion. */
272 header->debug_console_base = (void * __force)console;
275 err = jailhouse_cell_prepare_root(&config->root_cell);
283 header->online_cpus = num_online_cpus();
285 atomic_set(&call_done, 0);
286 on_each_cpu(enter_hypervisor, header, 0);
287 while (atomic_read(&call_done) != num_online_cpus())
294 goto error_free_cell;
300 release_firmware(hypervisor);
302 jailhouse_cell_register_root();
304 jailhouse_enabled = true;
306 mutex_unlock(&jailhouse_lock);
308 pr_info("The Jailhouse is opening.\n");
313 jailhouse_cell_delete_root();
316 vunmap(hypervisor_mem);
321 release_firmware(hypervisor);
324 module_put(THIS_MODULE);
327 mutex_unlock(&jailhouse_lock);
331 static void leave_hypervisor(void *info)
336 /* Touch each hypervisor page we may need during the switch so that
337 * the active mm definitely contains all mappings. At least x86 does
338 * not support taking any faults while switching worlds. */
339 for (page = hypervisor_mem;
340 page < hypervisor_mem + hv_core_and_percpu_size;
342 readl((void __iomem *)page);
344 /* either returns 0 or the same error code across all CPUs */
345 err = jailhouse_call(JAILHOUSE_HC_DISABLE);
349 #if defined(CONFIG_X86) && LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)
350 /* on Intel, VMXE is now off - update the shadow */
354 atomic_inc(&call_done);
357 static int jailhouse_cmd_disable(void)
361 if (mutex_lock_interruptible(&jailhouse_lock) != 0)
364 if (!jailhouse_enabled) {
373 if (num_online_cpus() != cpumask_weight(&root_cell->cpus_assigned)) {
375 * Not all assigned CPUs are currently online. If we disable
376 * now, we will loose the offlined ones.
385 atomic_set(&call_done, 0);
386 on_each_cpu(leave_hypervisor, NULL, 0);
387 while (atomic_read(&call_done) != num_online_cpus())
396 vunmap(hypervisor_mem);
398 jailhouse_cell_delete_all();
399 jailhouse_enabled = false;
400 module_put(THIS_MODULE);
402 pr_info("The Jailhouse was closed.\n");
405 mutex_unlock(&jailhouse_lock);
410 static long jailhouse_ioctl(struct file *file, unsigned int ioctl,
416 case JAILHOUSE_ENABLE:
417 err = jailhouse_cmd_enable(
418 (struct jailhouse_system __user *)arg);
420 case JAILHOUSE_DISABLE:
421 err = jailhouse_cmd_disable();
423 case JAILHOUSE_CELL_CREATE:
424 err = jailhouse_cmd_cell_create(
425 (struct jailhouse_cell_create __user *)arg);
427 case JAILHOUSE_CELL_LOAD:
428 err = jailhouse_cmd_cell_load(
429 (struct jailhouse_cell_load __user *)arg);
431 case JAILHOUSE_CELL_START:
432 err = jailhouse_cmd_cell_start((const char __user *)arg);
434 case JAILHOUSE_CELL_DESTROY:
435 err = jailhouse_cmd_cell_destroy((const char __user *)arg);
445 static const struct file_operations jailhouse_fops = {
446 .owner = THIS_MODULE,
447 .unlocked_ioctl = jailhouse_ioctl,
448 .compat_ioctl = jailhouse_ioctl,
449 .llseek = noop_llseek,
452 static struct miscdevice jailhouse_misc_dev = {
453 .minor = MISC_DYNAMIC_MINOR,
455 .fops = &jailhouse_fops,
458 static int jailhouse_shutdown_notify(struct notifier_block *unused1,
459 unsigned long unused2, void *unused3)
463 err = jailhouse_cmd_disable();
464 if (err && err != -EINVAL)
465 pr_emerg("jailhouse: ordered shutdown failed!\n");
470 static struct notifier_block jailhouse_shutdown_nb = {
471 .notifier_call = jailhouse_shutdown_notify,
474 static int __init jailhouse_init(void)
478 jailhouse_dev = root_device_register("jailhouse");
479 if (IS_ERR(jailhouse_dev))
480 return PTR_ERR(jailhouse_dev);
482 err = jailhouse_sysfs_init(jailhouse_dev);
486 err = misc_register(&jailhouse_misc_dev);
490 err = jailhouse_pci_register();
494 register_reboot_notifier(&jailhouse_shutdown_nb);
500 misc_deregister(&jailhouse_misc_dev);
503 jailhouse_sysfs_exit(jailhouse_dev);
506 root_device_unregister(jailhouse_dev);
510 static void __exit jailhouse_exit(void)
512 unregister_reboot_notifier(&jailhouse_shutdown_nb);
513 misc_deregister(&jailhouse_misc_dev);
514 jailhouse_sysfs_exit(jailhouse_dev);
515 jailhouse_pci_unregister();
516 root_device_unregister(jailhouse_dev);
519 module_init(jailhouse_init);
520 module_exit(jailhouse_exit);