Hypercall "Cell Create" (code 1)
- - - - - - - - - - - - - - - - -
-Creates a new cell according to the provided configuration, then set all
-cell CPUs to an architecture-specific reset state. At least one CPU will then
-execute the bootstrap code that must have been loaded into the cell's memory
-at the reset address before invoking this hypercall. See [1] for details on the
-reset state of cell CPUs.
+Creates a new cell according to the provided configuration. The cell's memory
+content will not be initialized, and the cell will be put in suspended state,
+i.e. no code is executed on its CPUs after this hypercall completed.
This hypercall can only be issued on CPUs belonging to the Linux cell.
-EINVAL (-22) - incorrect or inconsistent configuration data
-Hypercall "Cell Destroy" (code 2)
+Hypercall "Cell Start" (code 2)
+- - - - - - - - - - - - - - - -
+
+Sets all cell CPUs to an architecture-specific start state and resumes
+execution of the cell if it was previously suspended. At least one CPU will
+then execute the bootstrap code that must have been loaded into the cell's
+memory at the reset address before invoking this hypercall. See [1] for details
+on the start state of cell CPUs.
+
+This hypercall can only be issued on CPUs belonging to the Linux cell.
+
+Argument: ID of target cell
+
+Return code: 0 on success or negative error code
+
+ Possible errors are:
+ -EPERM (-1) - hypercall was issued over a non-root cell or the target
+ cell rejected the reset request
+ -ENOENT (-2) - cell with provided ID does not exist
+ -EINVAL (-22) - root cell specified, which cannot be started
+
+
+Hypercall "Cell Destroy" (code 4)
- - - - - - - - - - - - - - - - -
Destroys the cell of the provided name, returning its resources to the root
Note: The root cell uses ID 0. Passing this ID to "Cell Destroy" is illegal.
-Hypercall "Hypervisor Get Info" (code 3)
+Hypercall "Hypervisor Get Info" (code 5)
- - - - - - - - - - - - - - - - - - - - -
Obtain information about specific hypervisor states.
-EINVAL (-22) - invalid information type
-Hypercall "Cell Get State" (code 4)
+Hypercall "Cell Get State" (code 6)
- - - - - - - - - - - - - - - - - -
Obtain information about the state of a specific cell.
-EINVAL (-22) - cell state is invalid
-Hypercall "CPU Get State" (code 5)
+Hypercall "CPU Get State" (code 7)
- - - - - - - - - - - - - - - - - -
Obtain information about the state of a specific CPU.
The cell state field provides the second logical channel. On cell startup, it
is initialized by the hypervisor to the state "Running". From then on, the
-field becomes conceptually read-only for the hypervisor and will just be
-updated by the cell itself. The following states are defined:
+field becomes conceptually read-only for the hypervisor and will only be
+updated by the cell until a terminal state is reached. The following states are
+defined:
- Running (code 0)
- Shut down (code 1), terminal state
- Failed (code 2), terminal state
-Terminal states are immutable, thus cannot be left anymore once reached until
-the cell is destroyed.
+Once a cell declared to have reached a terminal state, the hypervisor is free
+to destroy or restart that cell. On restart, it will also reset the state field
+to "Running".
References
if (err)
goto err_restore_root;
+ cell->comm_page.comm_region.cell_state = JAILHOUSE_CELL_SHUT_DOWN;
+
last = &root_cell;
while (last->next)
last = last->next;
last->next = cell;
num_cells++;
- /* update cell references and clean up before releasing the cpus of
- * the new cell */
- for_each_cpu(cpu, cell->cpu_set)
+ for_each_cpu(cpu, cell->cpu_set) {
per_cpu(cpu)->cell = cell;
+ arch_park_cpu(cpu);
+ }
printk("Created cell \"%s\"\n", cell->config->name);
page_map_dump_stats("after cell creation");
- for_each_cpu(cpu, cell->cpu_set) {
- per_cpu(cpu)->failed = false;
- arch_reset_cpu(cpu);
- }
-
cell_resume(cpu_data);
return cell->id;
return 0;
}
+static int cell_start(struct per_cpu *cpu_data, unsigned long id)
+{
+ struct cell *cell;
+ unsigned int cpu;
+ int err;
+
+ err = cell_management_prologue(cpu_data, id, &cell);
+ if (err)
+ return err;
+
+ /* present a consistent Communication Region state to the cell */
+ cell->comm_page.comm_region.cell_state = JAILHOUSE_CELL_RUNNING;
+ cell->comm_page.comm_region.msg_to_cell = JAILHOUSE_MSG_NONE;
+
+ for_each_cpu(cpu, cell->cpu_set) {
+ per_cpu(cpu)->failed = false;
+ arch_reset_cpu(cpu);
+ }
+
+ printk("Started cell \"%s\"\n", cell->config->name);
+
+ cell_resume(cpu_data);
+
+ return 0;
+}
+
static int cell_destroy(struct per_cpu *cpu_data, unsigned long id)
{
const struct jailhouse_memory *mem;
return shutdown(cpu_data);
case JAILHOUSE_HC_CELL_CREATE:
return cell_create(cpu_data, arg);
+ case JAILHOUSE_HC_CELL_START:
+ return cell_start(cpu_data, arg);
case JAILHOUSE_HC_CELL_DESTROY:
return cell_destroy(cpu_data, arg);
case JAILHOUSE_HC_HYPERVISOR_GET_INFO: