#include <jailhouse/cell-config.h>
struct cell {
- char name[JAILHOUSE_CELL_NAME_MAXLEN+1];
unsigned int id;
+ unsigned int data_pages;
+ struct jailhouse_cell_desc *config;
struct cpu_set *cpu_set;
struct cpu_set small_cpu_set;
#include <jailhouse/entry.h>
-int arch_init_early(struct cell *linux_cell,
- struct jailhouse_cell_desc *config)
+int arch_init_early(struct cell *linux_cell)
{
return -ENOSYS;
}
return -ENOSYS;
}
-int arch_init_late(struct cell *linux_cell,
- struct jailhouse_cell_desc *config)
+int arch_init_late(struct cell *linux_cell)
{
return -ENOSYS;
}
void arch_resume_cpu(unsigned int cpu_id) {}
void arch_reset_cpu(unsigned int cpu_id) {}
void arch_shutdown_cpu(unsigned int cpu_id) {}
-int arch_cell_create(struct per_cpu *cpu_data, struct cell *new_cell,
- struct jailhouse_cell_desc *config) { return -ENOSYS; }
+int arch_cell_create(struct per_cpu *cpu_data, struct cell *new_cell)
+{ return -ENOSYS; }
void *memcpy(void *dest, const void *src, unsigned long n) { return NULL; }
void arch_dbg_write(const char *msg) {}
#include <jailhouse/control.h>
#include <asm/vmx.h>
-int arch_cell_create(struct per_cpu *cpu_data, struct cell *new_cell,
- struct jailhouse_cell_desc *config)
+int arch_cell_create(struct per_cpu *cpu_data, struct cell *new_cell)
{
unsigned int cpu;
- vmx_cell_shrink(cpu_data->cell, config);
+ vmx_cell_shrink(cpu_data->cell, new_cell->config);
for_each_cpu_except(cpu, cpu_data->cell->cpu_set, cpu_data->cpu_id)
per_cpu(cpu)->flush_caches = true;
- return vmx_cell_init(new_cell, config);
+ return vmx_cell_init(new_cell);
}
pgd_t *page_table;
} vtd;
- char name[JAILHOUSE_CELL_NAME_MAXLEN+1];
unsigned int id;
+ unsigned int data_pages;
+ struct jailhouse_cell_desc *config;
struct cpu_set *cpu_set;
struct cpu_set small_cpu_set;
void vmx_init(void);
-int vmx_cell_init(struct cell *cell, struct jailhouse_cell_desc *config);
+int vmx_cell_init(struct cell *cell);
void vmx_cell_shrink(struct cell *cell, struct jailhouse_cell_desc *config);
int vmx_cpu_init(struct per_cpu *cpu_data);
#define VTD_PHMLIMIT_REG 0x78
int vtd_init(void);
-int vtd_cell_init(struct cell *cell, struct jailhouse_cell_desc *config);
+int vtd_cell_init(struct cell *cell);
void vtd_shutdown(void);
static u32 idt[NUM_IDT_DESC * 4];
-int arch_init_early(struct cell *linux_cell,
- struct jailhouse_cell_desc *config)
+int arch_init_early(struct cell *linux_cell)
{
unsigned long entry;
unsigned int vector;
vmx_init();
- err = vmx_cell_init(linux_cell, config);
+ err = vmx_cell_init(linux_cell);
if (err)
return err;
return err;
}
-int arch_init_late(struct cell *linux_cell,
- struct jailhouse_cell_desc *config)
+int arch_init_late(struct cell *linux_cell)
{
int err;
if (err)
return err;
- err = vtd_cell_init(linux_cell, config);
+ err = vtd_cell_init(linux_cell);
if (err)
return err;
msr_bitmap[VMX_MSR_BITMAP_0000_WRITE][MSR_X2APIC_ICR/8] = 0x01;
}
-int vmx_cell_init(struct cell *cell, struct jailhouse_cell_desc *config)
+int vmx_cell_init(struct cell *cell)
{
+ struct jailhouse_cell_desc *config = cell->config;
struct jailhouse_memory *mem;
u32 page_flags, table_flags;
u32 pio_bitmap_size, size;
return true;
}
-int vtd_cell_init(struct cell *cell, struct jailhouse_cell_desc *config)
+int vtd_cell_init(struct cell *cell)
{
+ struct jailhouse_cell_desc *config = cell->config;
struct jailhouse_pci_device *dev;
void *reg_base = dmar_reg_base;
struct jailhouse_memory *mem;
for_each_cpu_except(cpu, cell->cpu_set, cpu_data->cpu_id)
arch_suspend_cpu(cpu);
- printk("Suspended cell \"%s\"\n", cell->name);
+ printk("Suspended cell \"%s\"\n", cell->config->name);
}
static void cell_resume(struct per_cpu *cpu_data)
return id;
}
-int cell_init(struct cell *cell, struct jailhouse_cell_desc *config,
- bool copy_cpu_set)
+int cell_init(struct cell *cell, bool copy_cpu_set)
{
unsigned long *config_cpu_set =
- (unsigned long *)(((void *)config) +
+ (unsigned long *)(((void *)cell->config) +
sizeof(struct jailhouse_cell_desc));
- unsigned long cpu_set_size = config->cpu_set_size;
+ unsigned long cpu_set_size = cell->config->cpu_set_size;
struct jailhouse_memory *config_ram =
(struct jailhouse_memory *)(((void *)config_cpu_set) +
cpu_set_size);
struct cpu_set *cpu_set;
- memcpy(cell->name, config->name, sizeof(cell->name));
cell->id = get_free_cell_id();
if (cpu_set_size > PAGE_SIZE)
struct cell *cell;
for (cell = &linux_cell; cell; cell = cell->next)
- if (strcmp(cell->name, name) == 0)
+ if (strcmp(cell->config->name, name) == 0)
break;
return cell;
}
{
unsigned long mapping_addr = FOREIGN_MAPPING_BASE +
cpu_data->cpu_id * PAGE_SIZE * NUM_FOREIGN_PAGES;
- unsigned long header_size, total_size;
+ unsigned long cfg_header_size, cfg_total_size;
struct jailhouse_cell_desc *cfg;
struct cpu_set *shrinking_set;
unsigned int cell_pages, cpu;
cell_suspend(cpu_data);
- header_size = (config_address & ~PAGE_MASK) +
+ cfg_header_size = (config_address & ~PAGE_MASK) +
sizeof(struct jailhouse_cell_desc);
err = page_map_create(hv_page_table, config_address & PAGE_MASK,
- header_size, mapping_addr, PAGE_READONLY_FLAGS,
- PAGE_DEFAULT_FLAGS, PAGE_DIR_LEVELS);
+ cfg_header_size, mapping_addr,
+ PAGE_READONLY_FLAGS, PAGE_DEFAULT_FLAGS,
+ PAGE_DIR_LEVELS);
if (err)
goto resume_out;
cfg = (struct jailhouse_cell_desc *)(mapping_addr +
(config_address & ~PAGE_MASK));
- total_size = jailhouse_cell_config_size(cfg);
- if (total_size > NUM_FOREIGN_PAGES * PAGE_SIZE) {
+ cfg_total_size = jailhouse_cell_config_size(cfg);
+ if (cfg_total_size > NUM_FOREIGN_PAGES * PAGE_SIZE) {
err = -E2BIG;
goto resume_out;
}
}
err = page_map_create(hv_page_table, config_address & PAGE_MASK,
- total_size, mapping_addr, PAGE_READONLY_FLAGS,
- PAGE_DEFAULT_FLAGS, PAGE_DIR_LEVELS);
+ cfg_total_size, mapping_addr,
+ PAGE_READONLY_FLAGS, PAGE_DEFAULT_FLAGS,
+ PAGE_DIR_LEVELS);
if (err)
goto resume_out;
if (err)
goto resume_out;
- cell_pages = PAGE_ALIGN(sizeof(*cell)) / PAGE_SIZE;
+ 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;
}
- err = cell_init(cell, cfg, true);
+ cell->data_pages = cell_pages;
+ cell->config = ((void *)cell) + sizeof(*cell);
+ memcpy(cell->config, cfg, cfg_total_size);
+
+ err = cell_init(cell, true);
if (err)
goto err_free_cell;
for_each_cpu(cpu, cell->cpu_set)
clear_bit(cpu, shrinking_set->bitmap);
- err = arch_cell_create(cpu_data, cell, cfg);
+ err = arch_cell_create(cpu_data, cell);
if (err)
goto err_restore_cpu_set;
for_each_cpu(cpu, cell->cpu_set)
per_cpu(cpu)->cell = cell;
- printk("Created cell \"%s\"\n", cell->name);
+ printk("Created cell \"%s\"\n", cell->config->name);
page_map_dump_stats("after cell creation");
printk("Shutting down hypervisor\n");
while (cell) {
- printk(" Closing cell \"%s\"\n", cell->name);
+ printk(" Closing cell \"%s\"\n", cell->config->name);
for_each_cpu(cpu, cell->cpu_set) {
printk(" Releasing CPU %d\n", cpu);
cell = cell->next;
}
- printk(" Closing Linux cell \"%s\"\n", linux_cell.name);
+ printk(" Closing Linux cell \"%s\"\n",
+ linux_cell.config->name);
}
printk(" Releasing CPU %d\n", this_cpu);
)
int check_mem_regions(struct jailhouse_cell_desc *config);
-int cell_init(struct cell *cell, struct jailhouse_cell_desc *config,
- bool copy_cpu_set);
+int cell_init(struct cell *cell, bool copy_cpu_set);
int cell_create(struct per_cpu *cpu_data, unsigned long config_address);
int cell_destroy(struct per_cpu *cpu_data, unsigned long name_address);
void arch_reset_cpu(unsigned int cpu_id);
void arch_shutdown_cpu(unsigned int cpu_id);
-int arch_cell_create(struct per_cpu *cpu_data, struct cell *new_cell,
- struct jailhouse_cell_desc *config);
+int arch_cell_create(struct per_cpu *cpu_data, struct cell *new_cell);
int entry(struct per_cpu *cpu_data);
-int arch_init_early(struct cell *linux_cell,
- struct jailhouse_cell_desc *config);
+int arch_init_early(struct cell *linux_cell);
int arch_cpu_init(struct per_cpu *cpu_data);
-int arch_init_late(struct cell *linux_cell,
- struct jailhouse_cell_desc *config);
+int arch_init_late(struct cell *linux_cell);
void __attribute__((noreturn)) arch_cpu_activate_vmm(struct per_cpu *cpu_data);
void arch_cpu_restore(struct per_cpu *cpu_data);
if (error)
return;
+ linux_cell.config = &system_config->system;
+
if (system_config->config_memory.size > 0) {
size = PAGE_ALIGN(system_config->config_memory.size);
if (error)
return;
- error = arch_init_early(&linux_cell, &system_config->system);
+ error = arch_init_early(&linux_cell);
if (error)
return;
- error = cell_init(&linux_cell, &system_config->system, false);
+ error = cell_init(&linux_cell, false);
if (error)
return;
static void init_late(void)
{
- error = arch_init_late(&linux_cell, &system_config->system);
+ error = arch_init_late(&linux_cell);
if (error)
return;