2 * Jailhouse, a Linux-based partitioning hypervisor
4 * Copyright (c) Siemens AG, 2013
7 * Jan Kiszka <jan.kiszka@siemens.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
13 #include <jailhouse/entry.h>
14 #include <jailhouse/control.h>
15 #include <jailhouse/printk.h>
16 #include <jailhouse/paging.h>
17 #include <jailhouse/processor.h>
18 #include <jailhouse/string.h>
19 #include <jailhouse/utils.h>
20 #include <asm/bitops.h>
21 #include <asm/spinlock.h>
23 enum msg_type {MSG_REQUEST, MSG_INFORMATION};
24 enum failure_mode {ABORT_ON_ERROR, WARN_ON_ERROR};
25 enum management_task {CELL_START, CELL_SET_LOADABLE, CELL_DESTROY};
27 struct jailhouse_system *system_config;
29 static DEFINE_SPINLOCK(shutdown_lock);
30 static unsigned int num_cells = 1;
32 #define for_each_cell(c) for ((c) = &root_cell; (c); (c) = (c)->next)
33 #define for_each_non_root_cell(c) \
34 for ((c) = root_cell.next; (c); (c) = (c)->next)
36 unsigned int next_cpu(unsigned int cpu, struct cpu_set *cpu_set, int exception)
40 while (cpu <= cpu_set->max_cpu_id &&
41 (cpu == exception || !test_bit(cpu, cpu_set->bitmap)));
45 bool cpu_id_valid(unsigned long cpu_id)
47 const unsigned long *system_cpu_set =
48 jailhouse_cell_cpu_set(&system_config->root_cell);
50 return (cpu_id < system_config->root_cell.cpu_set_size * 8 &&
51 test_bit(cpu_id, system_cpu_set));
54 static void cell_suspend(struct cell *cell, struct per_cpu *cpu_data)
58 for_each_cpu_except(cpu, cell->cpu_set, cpu_data->cpu_id)
59 arch_suspend_cpu(cpu);
62 static void cell_resume(struct per_cpu *cpu_data)
66 for_each_cpu_except(cpu, cpu_data->cell->cpu_set, cpu_data->cpu_id)
71 * cell_send_message - Deliver a message to cell and wait for the reply
73 * @message: message code to be sent (JAILHOUSE_MSG_*)
74 * @type: message type, defines the valid replies
76 * Returns true if a request message was approved or reception of an
77 * information message was acknowledged by the target cell. It also return true
78 * of the target cell does not support a communication region, is shut down or
79 * in failed state. Return false on request denial or invalid replies.
81 static bool cell_send_message(struct cell *cell, u32 message,
84 if (cell->config->flags & JAILHOUSE_CELL_PASSIVE_COMMREG)
87 jailhouse_send_msg_to_cell(&cell->comm_page.comm_region, message);
90 u32 reply = cell->comm_page.comm_region.reply_from_cell;
91 u32 cell_state = cell->comm_page.comm_region.cell_state;
93 if (cell_state == JAILHOUSE_CELL_SHUT_DOWN ||
94 cell_state == JAILHOUSE_CELL_FAILED)
97 if ((type == MSG_REQUEST &&
98 reply == JAILHOUSE_MSG_REQUEST_APPROVED) ||
99 (type == MSG_INFORMATION &&
100 reply == JAILHOUSE_MSG_RECEIVED))
103 if (reply != JAILHOUSE_MSG_NONE)
110 static bool cell_reconfig_ok(struct cell *excluded_cell)
114 for_each_non_root_cell(cell)
115 if (cell != excluded_cell &&
116 cell->comm_page.comm_region.cell_state ==
117 JAILHOUSE_CELL_RUNNING_LOCKED)
122 static void cell_reconfig_completed(void)
126 for_each_non_root_cell(cell)
127 cell_send_message(cell, JAILHOUSE_MSG_RECONFIG_COMPLETED,
131 static unsigned int get_free_cell_id(void)
138 if (cell->id == id) {
146 /* cell must be zero-initialized */
147 int cell_init(struct cell *cell, bool copy_cpu_set)
149 const unsigned long *config_cpu_set =
150 jailhouse_cell_cpu_set(cell->config);
151 unsigned long cpu_set_size = cell->config->cpu_set_size;
152 struct cpu_set *cpu_set;
154 cell->id = get_free_cell_id();
156 if (cpu_set_size > PAGE_SIZE)
158 else if (cpu_set_size > sizeof(cell->small_cpu_set.bitmap)) {
159 cpu_set = page_alloc(&mem_pool, 1);
162 cpu_set->max_cpu_id =
163 ((PAGE_SIZE - sizeof(unsigned long)) * 8) - 1;
165 cpu_set = &cell->small_cpu_set;
166 cpu_set->max_cpu_id =
167 (sizeof(cell->small_cpu_set.bitmap) * 8) - 1;
169 cell->cpu_set = cpu_set;
171 memcpy(cell->cpu_set->bitmap, config_cpu_set, cpu_set_size);
176 static void destroy_cpu_set(struct cell *cell)
178 if (cell->cpu_set != &cell->small_cpu_set)
179 page_free(&mem_pool, cell->cpu_set, 1);
182 int check_mem_regions(const struct jailhouse_cell_desc *config)
184 const struct jailhouse_memory *mem =
185 jailhouse_cell_mem_regions(config);
188 for (n = 0; n < config->num_memory_regions; n++, mem++) {
189 if (mem->phys_start & ~PAGE_MASK ||
190 mem->virt_start & ~PAGE_MASK ||
191 mem->size & ~PAGE_MASK ||
192 mem->flags & ~JAILHOUSE_MEM_VALID_FLAGS) {
193 printk("FATAL: Invalid memory bar (%p, %p, %p, %x)\n",
194 mem->phys_start, mem->virt_start, mem->size,
202 static bool address_in_region(unsigned long addr,
203 const struct jailhouse_memory *region)
205 return addr >= region->phys_start &&
206 addr < (region->phys_start + region->size);
209 static int unmap_from_root_cell(const struct jailhouse_memory *mem)
212 * arch_unmap_memory_region uses the virtual address of the memory
213 * region. As only the root cell has a guaranteed 1:1 mapping, make a
214 * copy where we ensure this.
216 struct jailhouse_memory tmp = *mem;
218 tmp.virt_start = tmp.phys_start;
219 return arch_unmap_memory_region(&root_cell, &tmp);
222 static int remap_to_root_cell(const struct jailhouse_memory *mem,
223 enum failure_mode mode)
225 const struct jailhouse_memory *root_mem =
226 jailhouse_cell_mem_regions(root_cell.config);
227 struct jailhouse_memory overlap;
231 for (n = 0; n < root_cell.config->num_memory_regions;
233 if (address_in_region(mem->phys_start, root_mem)) {
234 overlap.phys_start = mem->phys_start;
235 overlap.size = root_mem->size -
236 (overlap.phys_start - root_mem->phys_start);
237 if (overlap.size > mem->size)
238 overlap.size = mem->size;
239 } else if (address_in_region(root_mem->phys_start, mem)) {
240 overlap.phys_start = root_mem->phys_start;
241 overlap.size = mem->size -
242 (overlap.phys_start - mem->phys_start);
243 if (overlap.size > root_mem->size)
244 overlap.size = root_mem->size;
248 overlap.virt_start = root_mem->virt_start +
249 overlap.phys_start - root_mem->phys_start;
250 overlap.flags = root_mem->flags;
252 err = arch_map_memory_region(&root_cell, &overlap);
254 if (mode == ABORT_ON_ERROR)
256 printk("WARNING: Failed to re-assign memory region "
263 static void cell_destroy_internal(struct per_cpu *cpu_data, struct cell *cell)
265 const struct jailhouse_memory *mem =
266 jailhouse_cell_mem_regions(cell->config);
269 for_each_cpu(cpu, cell->cpu_set) {
272 set_bit(cpu, root_cell.cpu_set->bitmap);
273 per_cpu(cpu)->cell = &root_cell;
274 per_cpu(cpu)->failed = false;
275 memset(per_cpu(cpu)->stats, 0, sizeof(per_cpu(cpu)->stats));
278 for (n = 0; n < cell->config->num_memory_regions; n++, mem++) {
280 * This cannot fail. The region was mapped as a whole before,
281 * thus no hugepages need to be broken up to unmap it.
283 arch_unmap_memory_region(cell, mem);
284 if (!(mem->flags & JAILHOUSE_MEM_COMM_REGION))
285 remap_to_root_cell(mem, WARN_ON_ERROR);
288 arch_cell_destroy(cpu_data, cell);
290 arch_config_commit(cpu_data, cell);
293 static int cell_create(struct per_cpu *cpu_data, unsigned long config_address)
295 unsigned long mapping_addr = TEMPORARY_MAPPING_CPU_BASE(cpu_data);
296 unsigned long cfg_page_offs = config_address & ~PAGE_MASK;
297 unsigned long cfg_header_size, cfg_total_size;
298 const struct jailhouse_memory *mem;
299 struct jailhouse_cell_desc *cfg;
300 unsigned int cell_pages, cpu, n;
301 struct cell *cell, *last;
304 /* We do not support creation over non-root cells. */
305 if (cpu_data->cell != &root_cell)
308 cell_suspend(&root_cell, cpu_data);
310 if (!cell_reconfig_ok(NULL)) {
315 cfg_header_size = (config_address & ~PAGE_MASK) +
316 sizeof(struct jailhouse_cell_desc);
318 err = page_map_create(&hv_paging_structs, config_address & PAGE_MASK,
319 cfg_header_size, mapping_addr,
320 PAGE_READONLY_FLAGS, PAGE_MAP_NON_COHERENT);
324 cfg = (struct jailhouse_cell_desc *)(mapping_addr + cfg_page_offs);
325 cfg_total_size = jailhouse_cell_config_size(cfg);
326 if (cfg_total_size + cfg_page_offs > NUM_TEMPORARY_PAGES * PAGE_SIZE) {
332 if (strcmp(cell->config->name, cfg->name) == 0) {
337 err = page_map_create(&hv_paging_structs, config_address & PAGE_MASK,
338 cfg_total_size + cfg_page_offs, mapping_addr,
339 PAGE_READONLY_FLAGS, PAGE_MAP_NON_COHERENT);
343 err = check_mem_regions(cfg);
347 cell_pages = PAGE_ALIGN(sizeof(*cell) + cfg_total_size) / PAGE_SIZE;
348 cell = page_alloc(&mem_pool, cell_pages);
354 cell->data_pages = cell_pages;
355 cell->config = ((void *)cell) + sizeof(*cell);
356 memcpy(cell->config, cfg, cfg_total_size);
358 err = cell_init(cell, true);
362 /* don't assign the CPU we are currently running on */
363 if (cpu_data->cpu_id <= cell->cpu_set->max_cpu_id &&
364 test_bit(cpu_data->cpu_id, cell->cpu_set->bitmap)) {
366 goto err_free_cpu_set;
369 /* the root cell's cpu set must be super-set of new cell's set */
370 if (root_cell.cpu_set->max_cpu_id < cell->cpu_set->max_cpu_id) {
372 goto err_free_cpu_set;
374 for_each_cpu(cpu, cell->cpu_set)
375 if (!test_bit(cpu, root_cell.cpu_set->bitmap)) {
377 goto err_free_cpu_set;
380 err = arch_cell_create(cpu_data, cell);
382 goto err_free_cpu_set;
384 for_each_cpu(cpu, cell->cpu_set) {
387 clear_bit(cpu, root_cell.cpu_set->bitmap);
388 per_cpu(cpu)->cell = cell;
389 memset(per_cpu(cpu)->stats, 0, sizeof(per_cpu(cpu)->stats));
393 * Unmap the cell's memory regions from the root cell and map them to
394 * the new cell instead.
396 mem = jailhouse_cell_mem_regions(cell->config);
397 for (n = 0; n < cell->config->num_memory_regions; n++, mem++) {
400 * - the communication region is not backed by root memory
402 if (!(mem->flags & JAILHOUSE_MEM_COMM_REGION)) {
403 err = unmap_from_root_cell(mem);
405 goto err_destroy_cell;
408 err = arch_map_memory_region(cell, mem);
410 goto err_destroy_cell;
413 arch_config_commit(cpu_data, cell);
415 cell->comm_page.comm_region.cell_state = JAILHOUSE_CELL_SHUT_DOWN;
423 cell_reconfig_completed();
425 printk("Created cell \"%s\"\n", cell->config->name);
427 page_map_dump_stats("after cell creation");
429 cell_resume(cpu_data);
434 cell_destroy_internal(cpu_data, cell);
436 destroy_cpu_set(cell);
438 page_free(&mem_pool, cell, cell_pages);
441 cell_resume(cpu_data);
446 static bool cell_shutdown_ok(struct cell *cell)
448 return cell_send_message(cell, JAILHOUSE_MSG_SHUTDOWN_REQUEST,
452 static int cell_management_prologue(enum management_task task,
453 struct per_cpu *cpu_data, unsigned long id,
454 struct cell **cell_ptr)
456 /* We do not support management commands over non-root cells. */
457 if (cpu_data->cell != &root_cell)
460 cell_suspend(&root_cell, cpu_data);
462 for_each_cell(*cell_ptr)
463 if ((*cell_ptr)->id == id)
467 cell_resume(cpu_data);
471 /* root cell cannot be managed */
472 if (*cell_ptr == &root_cell) {
473 cell_resume(cpu_data);
477 if ((task == CELL_DESTROY && !cell_reconfig_ok(*cell_ptr)) ||
478 !cell_shutdown_ok(*cell_ptr)) {
479 cell_resume(cpu_data);
483 cell_suspend(*cell_ptr, cpu_data);
488 static int cell_start(struct per_cpu *cpu_data, unsigned long id)
490 const struct jailhouse_memory *mem;
495 err = cell_management_prologue(CELL_START, cpu_data, id, &cell);
499 if (cell->loadable) {
500 /* unmap all loadable memory regions from the root cell */
501 mem = jailhouse_cell_mem_regions(cell->config);
502 for (n = 0; n < cell->config->num_memory_regions; n++, mem++)
503 if (mem->flags & JAILHOUSE_MEM_LOADABLE) {
504 err = unmap_from_root_cell(mem);
509 arch_config_commit(cpu_data, NULL);
511 cell->loadable = false;
514 /* present a consistent Communication Region state to the cell */
515 cell->comm_page.comm_region.cell_state = JAILHOUSE_CELL_RUNNING;
516 cell->comm_page.comm_region.msg_to_cell = JAILHOUSE_MSG_NONE;
518 for_each_cpu(cpu, cell->cpu_set) {
519 per_cpu(cpu)->failed = false;
523 printk("Started cell \"%s\"\n", cell->config->name);
526 cell_resume(cpu_data);
531 static int cell_set_loadable(struct per_cpu *cpu_data, unsigned long id)
533 const struct jailhouse_memory *mem;
538 err = cell_management_prologue(CELL_SET_LOADABLE, cpu_data, id, &cell);
542 for_each_cpu(cpu, cell->cpu_set) {
543 per_cpu(cpu)->failed = false;
550 cell->comm_page.comm_region.cell_state = JAILHOUSE_CELL_SHUT_DOWN;
551 cell->loadable = true;
553 /* map all loadable memory regions into the root cell */
554 mem = jailhouse_cell_mem_regions(cell->config);
555 for (n = 0; n < cell->config->num_memory_regions; n++, mem++)
556 if (mem->flags & JAILHOUSE_MEM_LOADABLE) {
557 err = remap_to_root_cell(mem, ABORT_ON_ERROR);
562 arch_config_commit(cpu_data, NULL);
564 printk("Cell \"%s\" can be loaded\n", cell->config->name);
567 cell_resume(cpu_data);
572 static int cell_destroy(struct per_cpu *cpu_data, unsigned long id)
574 struct cell *cell, *previous;
577 err = cell_management_prologue(CELL_DESTROY, cpu_data, id, &cell);
581 printk("Closing cell \"%s\"\n", cell->config->name);
583 cell_destroy_internal(cpu_data, cell);
585 previous = &root_cell;
586 while (previous->next != cell)
587 previous = previous->next;
588 previous->next = cell->next;
591 page_free(&mem_pool, cell, cell->data_pages);
592 page_map_dump_stats("after cell destruction");
594 cell_reconfig_completed();
596 cell_resume(cpu_data);
601 static int cell_get_state(struct per_cpu *cpu_data, unsigned long id)
605 if (cpu_data->cell != &root_cell)
609 * We do not need explicit synchronization with cell_create/destroy
610 * because their cell_suspend(root_cell) will not return before we left
614 if (cell->id == id) {
615 u32 state = cell->comm_page.comm_region.cell_state;
618 case JAILHOUSE_CELL_RUNNING:
619 case JAILHOUSE_CELL_RUNNING_LOCKED:
620 case JAILHOUSE_CELL_SHUT_DOWN:
621 case JAILHOUSE_CELL_FAILED:
630 static int shutdown(struct per_cpu *cpu_data)
632 unsigned int this_cpu = cpu_data->cpu_id;
637 /* We do not support shutdown over non-root cells. */
638 if (cpu_data->cell != &root_cell)
641 spin_lock(&shutdown_lock);
643 if (cpu_data->shutdown_state == SHUTDOWN_NONE) {
644 state = SHUTDOWN_STARTED;
645 for_each_non_root_cell(cell)
646 if (!cell_shutdown_ok(cell))
649 if (state == SHUTDOWN_STARTED) {
650 printk("Shutting down hypervisor\n");
652 for_each_non_root_cell(cell) {
653 cell_suspend(cell, cpu_data);
655 printk("Closing cell \"%s\"\n",
658 for_each_cpu(cpu, cell->cpu_set) {
659 printk(" Releasing CPU %d\n", cpu);
660 arch_shutdown_cpu(cpu);
664 printk("Closing root cell \"%s\"\n",
665 root_cell.config->name);
669 for_each_cpu(cpu, root_cell.cpu_set)
670 per_cpu(cpu)->shutdown_state = state;
673 if (cpu_data->shutdown_state == SHUTDOWN_STARTED) {
674 printk(" Releasing CPU %d\n", this_cpu);
677 ret = cpu_data->shutdown_state;
678 cpu_data->shutdown_state = SHUTDOWN_NONE;
680 spin_unlock(&shutdown_lock);
685 static long hypervisor_get_info(struct per_cpu *cpu_data, unsigned long type)
688 case JAILHOUSE_INFO_MEM_POOL_SIZE:
689 return mem_pool.pages;
690 case JAILHOUSE_INFO_MEM_POOL_USED:
691 return mem_pool.used_pages;
692 case JAILHOUSE_INFO_REMAP_POOL_SIZE:
693 return remap_pool.pages;
694 case JAILHOUSE_INFO_REMAP_POOL_USED:
695 return remap_pool.used_pages;
696 case JAILHOUSE_INFO_NUM_CELLS:
703 static int cpu_get_info(struct per_cpu *cpu_data, unsigned long cpu_id,
706 if (!cpu_id_valid(cpu_id))
710 * We do not need explicit synchronization with cell_destroy because
711 * its cell_suspend(root_cell + this_cell) will not return before we
712 * left this hypercall.
714 if (cpu_data->cell != &root_cell &&
715 (cpu_id > cpu_data->cell->cpu_set->max_cpu_id ||
716 !test_bit(cpu_id, cpu_data->cell->cpu_set->bitmap)))
719 if (type == JAILHOUSE_CPU_INFO_STATE) {
720 return per_cpu(cpu_id)->failed ? JAILHOUSE_CPU_FAILED :
721 JAILHOUSE_CPU_RUNNING;
722 } else if (type >= JAILHOUSE_CPU_INFO_STAT_BASE &&
723 type - JAILHOUSE_CPU_INFO_STAT_BASE < JAILHOUSE_NUM_CPU_STATS) {
724 type -= JAILHOUSE_CPU_INFO_STAT_BASE;
725 return per_cpu(cpu_id)->stats[type] & BIT_MASK(30, 0);
730 long hypercall(struct per_cpu *cpu_data, unsigned long code,
731 unsigned long arg1, unsigned long arg2)
733 cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_HYPERCALL]++;
736 case JAILHOUSE_HC_DISABLE:
737 return shutdown(cpu_data);
738 case JAILHOUSE_HC_CELL_CREATE:
739 return cell_create(cpu_data, arg1);
740 case JAILHOUSE_HC_CELL_START:
741 return cell_start(cpu_data, arg1);
742 case JAILHOUSE_HC_CELL_SET_LOADABLE:
743 return cell_set_loadable(cpu_data, arg1);
744 case JAILHOUSE_HC_CELL_DESTROY:
745 return cell_destroy(cpu_data, arg1);
746 case JAILHOUSE_HC_HYPERVISOR_GET_INFO:
747 return hypervisor_get_info(cpu_data, arg1);
748 case JAILHOUSE_HC_CELL_GET_STATE:
749 return cell_get_state(cpu_data, arg1);
750 case JAILHOUSE_HC_CPU_GET_INFO:
751 return cpu_get_info(cpu_data, arg1, arg2);
757 void panic_stop(struct per_cpu *cpu_data)
759 panic_printk("Stopping CPU");
761 panic_printk(" %d", cpu_data->cpu_id);
762 cpu_data->cpu_stopped = true;
766 if (phys_processor_id() == panic_cpu)
767 panic_in_progress = 0;
769 arch_panic_stop(cpu_data);
772 void panic_halt(struct per_cpu *cpu_data)
774 struct cell *cell = cpu_data->cell;
775 bool cell_failed = true;
778 panic_printk("Parking CPU %d\n", cpu_data->cpu_id);
780 cpu_data->failed = true;
781 for_each_cpu(cpu, cell->cpu_set)
782 if (!per_cpu(cpu)->failed) {
787 cell->comm_page.comm_region.cell_state = JAILHOUSE_CELL_FAILED;
789 arch_panic_halt(cpu_data);
791 if (phys_processor_id() == panic_cpu)
792 panic_in_progress = 0;