]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
driver/tools: Rework cell destruction API
authorJan Kiszka <jan.kiszka@siemens.com>
Mon, 2 Dec 2013 16:58:09 +0000 (17:58 +0100)
committerJan Kiszka <jan.kiszka@siemens.com>
Thu, 12 Dec 2013 16:36:48 +0000 (17:36 +0100)
Reference a cell to be destructed via its config file. The API to the
hypervisor is still based on names, but the driver IOCTL now takes a
reference to a fully loaded config.

This allows the driver to bring the CPUs that were used by the
destructed cell online again. It is also more handy for the user as
creation and destruction now both use the same token to reference a
cell.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
jailhouse.h
main.c
tools/jailhouse.c

index e318ec43a46b6edbca83ca2436fefd6f467addd4..dc6e550e04da41392aec7830005c6409fa6de50a 100644 (file)
@@ -28,7 +28,12 @@ struct jailhouse_new_cell {
        struct jailhouse_preload_image image[];
 };
 
+struct jailhouse_cell {
+       __u64 config_address;
+       __u32 config_size;
+};
+
 #define JAILHOUSE_ENABLE               _IOW(0, 0, struct jailhouse_system)
 #define JAILHOUSE_DISABLE              _IO(0, 1)
 #define JAILHOUSE_CELL_CREATE          _IOW(0, 2, struct jailhouse_new_cell)
-#define JAILHOUSE_CELL_DESTROY         _IOW(0, 3, const char *)
+#define JAILHOUSE_CELL_DESTROY         _IOW(0, 3, struct jailhouse_cell)
diff --git a/main.c b/main.c
index ab0c42b192742f2df998434751180718361495b4..1316e846f3dbf537a1c2d7b60a8fb3e3019ef972 100644 (file)
--- a/main.c
+++ b/main.c
@@ -363,12 +363,25 @@ kfree_config_out:
 
 static int jailhouse_cell_destroy(const char __user *arg)
 {
-       char name[JAILHOUSE_CELL_NAME_MAXLEN];
+       struct jailhouse_cell_desc *config;
+       struct jailhouse_cell cell;
+       unsigned int cpu;
        int err;
 
-       if (strncpy_from_user(name, arg, sizeof(name) - 1) < 0)
+       if (copy_from_user(&cell, arg, sizeof(cell)))
                return -EFAULT;
-       name[sizeof(name) - 1] = 0;
+
+       config = kmalloc(cell.config_size, GFP_KERNEL | GFP_DMA);
+       if (!config)
+               return -ENOMEM;
+
+       if (copy_from_user(config, (void *)(unsigned long)cell.config_address,
+                          cell.config_size)) {
+               err = -EFAULT;
+               goto kfree_config_out;
+       }
+       config->name[JAILHOUSE_CELL_NAME_MAXLEN] = 0;
+
 
        if (mutex_lock_interruptible(&lock) != 0)
                return -EINTR;
@@ -378,15 +391,26 @@ static int jailhouse_cell_destroy(const char __user *arg)
                goto unlock_out;
        }
 
-       err = jailhouse_call1(JAILHOUSE_HC_CELL_DESTROY, __pa(name));
+       err = jailhouse_call1(JAILHOUSE_HC_CELL_DESTROY, __pa(config->name));
        if (err)
                goto unlock_out;
 
-       pr_info("Destroyed Jailhouse cell \"%s\"\n", name);
+       for_each_cell_cpu(cpu, config)
+               if (cpu_isset(cpu, offlined_cpus)) {
+                       if (cpu_up(cpu) != 0)
+                               pr_err("Jailhouse: failed to bring CPU %d "
+                                      "back online\n", cpu);
+                       cpu_clear(cpu, offlined_cpus);
+               }
+
+       pr_info("Destroyed Jailhouse cell \"%s\"\n", config->name);
 
 unlock_out:
        mutex_unlock(&lock);
 
+kfree_config_out:
+       kfree(config);
+
        return err;
 }
 
index 3cc869a21f46a0dee0af50b27c186e61a1e891cb..2fad3eda6a81712778e5e6828dff88dc385a4ee8 100644 (file)
@@ -29,7 +29,7 @@ static void help(const char *progname)
               "   enable CONFIGFILE\n"
               "   disable\n"
               "   cell create CONFIGFILE PRELOADIMAGE [-l ADDRESS]\n"
-              "   cell destroy NAME\n",
+              "   cell destroy CONFIGFILE\n",
               progname);
 }
 
@@ -154,6 +154,8 @@ static int cell_create(int argc, char *argv[])
 
 static int cell_destroy(int argc, char *argv[])
 {
+       struct jailhouse_cell cell;
+       size_t size;
        int err, fd;
 
        if (argc != 4) {
@@ -161,13 +163,17 @@ static int cell_destroy(int argc, char *argv[])
                exit(1);
        }
 
+       cell.config_address = (unsigned long)read_file(argv[3], &size);
+       cell.config_size = size;
+
        fd = open_dev();
 
-       err = ioctl(fd, JAILHOUSE_CELL_DESTROY, argv[3]);
+       err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell);
        if (err)
                perror("JAILHOUSE_CELL_DESTROY");
 
        close(fd);
+       free((void *)(unsigned long)cell.config_address);
 
        return err;
 }