]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
core: Introduce cell shutdown control interface
authorJan Kiszka <jan.kiszka@siemens.com>
Tue, 14 Jan 2014 19:26:13 +0000 (20:26 +0100)
committerJan Kiszka <jan.kiszka@siemens.com>
Thu, 16 Jan 2014 16:06:37 +0000 (17:06 +0100)
Using the messaging feature of the comm region, this introduces an
interface for cell to control their shutdown. The hypervisor sends a
shutdown request to a cell before destroying it. The cell can either
reject or accept the request in its reply message.

Cells can be excluded from this procedure and will continue to be
destructed immediately by setting the flag JAILHOUSE_CELL_UNMANAGED_EXIT
in their configuration file. For now we mark both demo cells as
unmanaged.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
configs/apic-demo.c
configs/tiny-demo.c
hypervisor/control.c
hypervisor/include/jailhouse/cell-config.h
hypervisor/include/jailhouse/hypercall.h

index 2e49a000b39e44d336ac574782efc0f6780aa24a..65c6cb412b2961052f5a3fee9effc6f05803e81e 100644 (file)
@@ -26,6 +26,7 @@ struct {
 } ALIGN config = {
        .cell = {
                .name = "APIC Demo",
+               .flags = JAILHOUSE_CELL_UNMANAGED_EXIT,
 
                .cpu_set_size = sizeof(config.cpus),
                .num_memory_regions = ARRAY_SIZE(config.mem_regions),
index 69929873517c235753aae29cf9b02981eba58c70..97d8b17dfc2476ab965436fe81aac6a48751558e 100644 (file)
@@ -26,6 +26,7 @@ struct {
 } ALIGN config = {
        .cell = {
                .name = "Tiny Demo",
+               .flags = JAILHOUSE_CELL_UNMANAGED_EXIT,
 
                .cpu_set_size = sizeof(config.cpus),
                .num_memory_regions = ARRAY_SIZE(config.mem_regions),
index dc962f741df48cb22f13ae65b583b24ec4e58939..cd6173a78ad7279c1a3e8bc3f85b6cbb746ef712 100644 (file)
@@ -257,6 +257,23 @@ err_free_cell:
        goto resume_out;
 }
 
+static bool cell_shutdown_ok(struct cell *cell)
+{
+       volatile u32 *reply = &cell->comm_page.comm_region.reply_from_cell;
+
+       if (cell->config->flags & JAILHOUSE_CELL_UNMANAGED_EXIT)
+               return true;
+
+       jailhouse_send_msg_to_cell(&cell->comm_page.comm_region,
+                                  JAILHOUSE_MSG_SHUTDOWN_REQUESTED);
+
+       while (*reply != JAILHOUSE_MSG_SHUTDOWN_DENIED &&
+              *reply != JAILHOUSE_MSG_SHUTDOWN_OK)
+               cpu_relax();
+
+       return *reply == JAILHOUSE_MSG_SHUTDOWN_OK;
+}
+
 static bool address_in_region(unsigned long addr,
                              const struct jailhouse_memory *region)
 {
@@ -309,8 +326,6 @@ int cell_destroy(struct per_cpu *cpu_data, unsigned long name_address)
        const char *name;
        int err = 0;
 
-       // TODO: access control
-
        /* We do not support destruction over non-Linux cells so far. */
        if (cpu_data->cell != &linux_cell)
                return -EPERM;
@@ -340,6 +355,11 @@ int cell_destroy(struct per_cpu *cpu_data, unsigned long name_address)
                goto resume_out;
        }
 
+       if (!cell_shutdown_ok(cell)) {
+               err = -EPERM;
+               goto resume_out;
+       }
+
        cell_suspend(cell, cpu_data);
 
        printk("Closing cell \"%s\"\n", name);
@@ -377,12 +397,10 @@ resume_out:
 
 int shutdown(struct per_cpu *cpu_data)
 {
-       struct cell *cell = linux_cell.next;
        unsigned int this_cpu = cpu_data->cpu_id;
+       struct cell *cell;
        unsigned int cpu;
-       int ret;
-
-       // TODO: access control
+       int state, ret;
 
        /* We do not support shutdown over non-Linux cells so far. */
        if (cpu_data->cell != &linux_cell)
@@ -391,26 +409,33 @@ int shutdown(struct per_cpu *cpu_data)
        spin_lock(&shutdown_lock);
 
        if (cpu_data->shutdown_state == SHUTDOWN_NONE) {
-               printk("Shutting down hypervisor\n");
+               state = SHUTDOWN_STARTED;
+               for (cell = linux_cell.next; cell; cell = cell->next)
+                       if (!cell_shutdown_ok(cell))
+                               state = -EPERM;
+
+               if (state == SHUTDOWN_STARTED) {
+                       printk("Shutting down hypervisor\n");
 
-               while (cell) {
-                       cell_suspend(cell, cpu_data);
+                       for (cell = linux_cell.next; cell; cell = cell->next) {
+                               cell_suspend(cell, cpu_data);
 
-                       printk("Closing cell \"%s\"\n", cell->config->name);
+                               printk("Closing cell \"%s\"\n",
+                                      cell->config->name);
 
-                       for_each_cpu(cpu, cell->cpu_set) {
-                               printk(" Releasing CPU %d\n", cpu);
-                               arch_shutdown_cpu(cpu);
+                               for_each_cpu(cpu, cell->cpu_set) {
+                                       printk(" Releasing CPU %d\n", cpu);
+                                       arch_shutdown_cpu(cpu);
+                               }
                        }
-                       cell = cell->next;
-               }
 
-               printk("Closing Linux cell \"%s\"\n",
-                      linux_cell.config->name);
-               arch_shutdown();
+                       printk("Closing Linux cell \"%s\"\n",
+                              linux_cell.config->name);
+                       arch_shutdown();
+               }
 
                for_each_cpu(cpu, linux_cell.cpu_set)
-                       per_cpu(cpu)->shutdown_state = SHUTDOWN_STARTED;
+                       per_cpu(cpu)->shutdown_state = state;
        }
 
        if (cpu_data->shutdown_state == SHUTDOWN_STARTED) {
index cdab94e3d1b7101808fcd05b43043558422fc927..3cc9d6fbb110a765fadf14196536eb85a666e96a 100644 (file)
 
 #define JAILHOUSE_CELL_NAME_MAXLEN     31
 
+#define JAILHOUSE_CELL_UNMANAGED_EXIT  0x00000001
+
 struct jailhouse_cell_desc {
        char name[JAILHOUSE_CELL_NAME_MAXLEN+1];
+       __u32 flags;
 
        __u32 cpu_set_size;
        __u32 num_memory_regions;
@@ -24,7 +27,7 @@ struct jailhouse_cell_desc {
        __u32 pio_bitmap_size;
        __u32 num_pci_devices;
 
-       __u32 padding[3];
+       __u32 padding[2];
 };
 
 #define JAILHOUSE_MEM_READ             0x0001
index 43d12409fb11d2fb33232b46c96dd74a84dc817b..acdc65b0b97ee94d415a09b46c5e7f5a2994ef31 100644 (file)
 
 #define JAILHOUSE_MSG_NONE                     0
 
+/* messages to cell */
+#define JAILHOUSE_MSG_SHUTDOWN_REQUESTED       1
+
+/* replies from cell */
+#define JAILHOUSE_MSG_SHUTDOWN_DENIED          1
+#define JAILHOUSE_MSG_SHUTDOWN_OK              2
+
 struct jailhouse_comm_region {
        volatile __u32 msg_to_cell;
        volatile __u32 reply_from_cell;