struct cell {
struct kobject kobj;
struct list_head entry;
+ unsigned int id;
};
MODULE_DESCRIPTION("Loader for Jailhouse partitioning hypervisor");
release_firmware(hypervisor);
enabled = true;
+ root_cell->id = 0;
register_cell(root_cell);
mutex_unlock(&lock);
struct jailhouse_cell_desc *config;
unsigned int cpu, n;
struct cell *cell;
- int err;
+ int id, err;
if (copy_from_user(&cell_params, arg, sizeof(cell_params)))
return -EFAULT;
cpu_set(cpu, offlined_cpus);
}
- err = jailhouse_call1(JAILHOUSE_HC_CELL_CREATE, __pa(config));
- if (err)
+ id = jailhouse_call1(JAILHOUSE_HC_CELL_CREATE, __pa(config));
+ if (id < 0) {
+ err = id;
goto error_cpu_online;
+ }
+ cell->id = id;
register_cell(cell);
pr_info("Created Jailhouse cell \"%s\"\n", config->name);
goto unlock_out;
}
- err = jailhouse_call1(JAILHOUSE_HC_CELL_DESTROY, __pa(config->name));
+ err = jailhouse_call1(JAILHOUSE_HC_CELL_DESTROY, cell->id);
if (err)
goto unlock_out;
cfg_header_size, mapping_addr,
PAGE_READONLY_FLAGS, PAGE_MAP_NON_COHERENT);
if (err)
- goto resume_out;
+ goto err_resume;
cfg = (struct jailhouse_cell_desc *)(mapping_addr +
(config_address & ~PAGE_MASK));
cfg_total_size = jailhouse_cell_config_size(cfg);
if (cfg_total_size > NUM_TEMPORARY_PAGES * PAGE_SIZE) {
err = -E2BIG;
- goto resume_out;
+ goto err_resume;
}
if (cell_find(cfg->name)) {
err = -EEXIST;
- goto resume_out;
+ goto err_resume;
}
err = page_map_create(&hv_paging_structs, config_address & PAGE_MASK,
cfg_total_size, mapping_addr,
PAGE_READONLY_FLAGS, PAGE_MAP_NON_COHERENT);
if (err)
- goto resume_out;
+ goto err_resume;
err = check_mem_regions(cfg);
if (err)
- goto resume_out;
+ goto err_resume;
cell_pages = PAGE_ALIGN(sizeof(*cell) + cfg_total_size) / PAGE_SIZE;
cell = page_alloc(&mem_pool, cell_pages);
if (!cell) {
err = -ENOMEM;
- goto resume_out;
+ goto err_resume;
}
cell->data_pages = cell_pages;
for_each_cpu(cpu, cell->cpu_set)
arch_reset_cpu(cpu);
-resume_out:
cell_resume(cpu_data);
- return err;
+ return cell->id;
err_restore_cpu_set:
for_each_cpu(cpu, cell->cpu_set)
destroy_cpu_set(cell);
err_free_cell:
page_free(&mem_pool, cell, cell_pages);
- goto resume_out;
+
+err_resume:
+ cell_resume(cpu_data);
+
+ return err;
}
static bool cell_shutdown_ok(struct cell *cell)
}
}
-int cell_destroy(struct per_cpu *cpu_data, unsigned long name_address)
+int cell_destroy(struct per_cpu *cpu_data, unsigned long id)
{
- unsigned long mapping_addr = TEMPORARY_MAPPING_CPU_BASE(cpu_data);
const struct jailhouse_memory *mem;
struct cell *cell, *previous;
- unsigned long name_size;
unsigned int cpu, n;
- const char *name;
int err = 0;
/* We do not support destruction over non-Linux cells so far. */
cell_suspend(&linux_cell, cpu_data);
- name_size = (name_address & ~PAGE_MASK) + JAILHOUSE_CELL_NAME_MAXLEN;
-
- err = page_map_create(&hv_paging_structs, name_address & PAGE_MASK,
- name_size, mapping_addr, PAGE_READONLY_FLAGS,
- PAGE_MAP_NON_COHERENT);
- if (err)
- goto resume_out;
-
- name = (const char *)(mapping_addr + (name_address & ~PAGE_MASK));
-
- cell = cell_find(name);
+ for_each_cell(cell)
+ if (cell->id == id)
+ break;
if (!cell) {
err = -ENOENT;
goto resume_out;
cell_suspend(cell, cpu_data);
- printk("Closing cell \"%s\"\n", name);
+ printk("Closing cell \"%s\"\n", cell->config->name);
for_each_cpu(cpu, cell->cpu_set) {
printk(" Parking CPU %d\n", cpu);