From 1b8793dc1e9364416460d969544b7663cf43eaff Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 9 Apr 2014 13:02:38 +0200 Subject: [PATCH] driver/tools: Break up cell creation Reduce the functionality of the cell create IOCTL to just assigning the cell resources, removing support for loading and starting the cell from this service. For those steps we now have separate IOCTLs. Extend the command line tool accordingly so that cell creation becomes three steps: jailhouse cell create CELLCONFIG jailhouse cell load ID_OR_NAME IMAGE jailhouse cell start ID_OR_NAME To reload a cell, the second and third step can now be invoked without having to destroy the cell first. Signed-off-by: Jan Kiszka --- driver.c | 25 ++----------- jailhouse.h | 15 ++++---- tools/jailhouse.c | 95 +++++++++++++++++++++++++++++++++-------------- 3 files changed, 79 insertions(+), 56 deletions(-) diff --git a/driver.c b/driver.c index c49ea4089..ef7f778d1 100644 --- a/driver.c +++ b/driver.c @@ -524,14 +524,13 @@ static int load_image(struct cell *cell, return err; } -static int jailhouse_cell_create(struct jailhouse_new_cell __user *arg) +static int jailhouse_cell_create(struct jailhouse_cell_create __user *arg) { - struct jailhouse_preload_image __user *image = arg->image; - struct jailhouse_new_cell cell_params; + struct jailhouse_cell_create cell_params; struct jailhouse_cell_desc *config; struct jailhouse_cell_id cell_id; - unsigned int cpu, n; struct cell *cell; + unsigned int cpu; int id, err; if (copy_from_user(&cell_params, arg, sizeof(cell_params))) @@ -572,12 +571,6 @@ static int jailhouse_cell_create(struct jailhouse_new_cell __user *arg) goto unlock_out; } - for (n = cell_params.num_preload_images; n > 0; n--, image++) { - err = load_image(cell, image); - if (err) - goto error_cell_put; - } - if (!cpumask_subset(&cell->cpus_assigned, &root_cell->cpus_assigned)) { err = -EBUSY; goto error_cell_put; @@ -599,10 +592,6 @@ static int jailhouse_cell_create(struct jailhouse_new_cell __user *arg) goto error_cpu_online; } - err = jailhouse_call_arg(JAILHOUSE_HC_CELL_START, id); - if (err) - goto error_cell_destroy; - cell->id = id; register_cell(cell); @@ -616,12 +605,6 @@ static int jailhouse_cell_create(struct jailhouse_new_cell __user *arg) return err; -error_cell_destroy: - if (jailhouse_call_arg(JAILHOUSE_HC_CELL_DESTROY, id) < 0) { - pr_crit("Cleanup after incomplete cell creation failed"); - goto error_cell_put; - } - error_cpu_online: for_each_cpu(cpu, &cell->cpus_assigned) { if (!cpu_online(cpu) && cpu_up(cpu) == 0) @@ -760,7 +743,7 @@ static long jailhouse_ioctl(struct file *file, unsigned int ioctl, break; case JAILHOUSE_CELL_CREATE: err = jailhouse_cell_create( - (struct jailhouse_new_cell __user *)arg); + (struct jailhouse_cell_create __user *)arg); break; case JAILHOUSE_CELL_LOAD: err = jailhouse_cell_load( diff --git a/jailhouse.h b/jailhouse.h index 6dc6fdc4c..c6bf15f62 100644 --- a/jailhouse.h +++ b/jailhouse.h @@ -14,6 +14,12 @@ #include #include +struct jailhouse_cell_create { + __u64 config_address; + __u32 config_size; + __u32 padding; +}; + struct jailhouse_preload_image { __u64 source_address; __u64 size; @@ -21,13 +27,6 @@ struct jailhouse_preload_image { __u64 padding; }; -struct jailhouse_new_cell { - __u64 config_address; - __u32 config_size; - __u32 num_preload_images; - struct jailhouse_preload_image image[]; -}; - struct jailhouse_cell_id { __s32 id; __u32 padding; @@ -45,7 +44,7 @@ struct jailhouse_cell_load { #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_CREATE _IOW(0, 2, struct jailhouse_cell_create) #define JAILHOUSE_CELL_LOAD _IOW(0, 3, struct jailhouse_cell_load) #define JAILHOUSE_CELL_START _IOW(0, 4, struct jailhouse_cell_id) #define JAILHOUSE_CELL_DESTROY _IOW(0, 5, struct jailhouse_cell_id) diff --git a/tools/jailhouse.c b/tools/jailhouse.c index c290e2fdb..70fab8446 100644 --- a/tools/jailhouse.c +++ b/tools/jailhouse.c @@ -28,10 +28,12 @@ help(const char *progname, int exit_status) { printf("%s { COMMAND | --help }\n" "\nAvailable commands:\n" - " enable CONFIGFILE\n" + " enable SYSCONFIG\n" " disable\n" - " cell create CONFIGFILE IMAGE [-l ADDRESS] " - "[IMAGE [-l ADDRESS] ...]\n" + " cell create CELLCONFIG\n" + " cell load { ID | [--name] NAME } IMAGE " + "[ -a | --address ADDRESS] ...\n" + " cell start { ID | [--name] NAME }\n" " cell destroy { ID | [--name] NAME }\n", progname); exit(exit_status); @@ -107,6 +109,29 @@ static int enable(int argc, char *argv[]) return err; } +static int cell_create(int argc, char *argv[]) +{ + struct jailhouse_cell_create cell_create; + size_t size; + int err, fd; + + if (argc != 4) + help(argv[0], 1); + + cell_create.config_address = (unsigned long)read_file(argv[3], &size); + cell_create.config_size = size; + + fd = open_dev(); + + err = ioctl(fd, JAILHOUSE_CELL_CREATE, &cell_create); + if (err) + perror("JAILHOUSE_CELL_CREATE"); + + close(fd); + + return err; +} + static int parse_cell_id(struct jailhouse_cell_id *cell_id, int argc, char *argv[]) { @@ -138,50 +163,59 @@ static int parse_cell_id(struct jailhouse_cell_id *cell_id, int argc, return arg_pos + 1; } -static int cell_create(int argc, char *argv[]) +static bool match_opt(const char *argv, const char *short_opt, + const char *long_opt) { + return strcmp(argv, short_opt) == 0 || + strcmp(argv, long_opt) == 0; +} + +static int cell_load(int argc, char *argv[]) +{ + unsigned int images, id_args, arg_num, n; struct jailhouse_preload_image *image; - struct jailhouse_new_cell *cell; - unsigned int images, arg_num, n; + struct jailhouse_cell_load *cell_load; + struct jailhouse_cell_id cell_id; size_t size; int err, fd; char *endp; - if (argc < 5) + id_args = parse_cell_id(&cell_id, argc - 3, &argv[3]); + arg_num = 3 + id_args; + if (id_args == 0 || arg_num == argc) help(argv[0], 1); - arg_num = 4; images = 0; while (arg_num < argc) { images++; arg_num++; - if (arg_num < argc && strcmp(argv[arg_num], "-l") == 0) { + if (arg_num < argc && + match_opt(argv[arg_num], "-a", "--address")) { if (arg_num + 1 >= argc) help(argv[0], 1); arg_num += 2; } } - cell = malloc(sizeof(*cell) + sizeof(*image) * images); - if (!cell) { + cell_load = malloc(sizeof(*cell_load) + sizeof(*image) * images); + if (!cell_load) { fprintf(stderr, "insufficient memory\n"); exit(1); } + cell_load->cell_id = cell_id; + cell_load->num_preload_images = images; - cell->config_address = (unsigned long)read_file(argv[3], &size); - cell->config_size = size; - cell->num_preload_images = images; - - arg_num = 4; + arg_num = 3 + id_args; - for (n = 0, image = cell->image; n < images; n++, image++) { + for (n = 0, image = cell_load->image; n < images; n++, image++) { image->source_address = (unsigned long)read_file(argv[arg_num++], &size); image->size = size; image->target_address = 0; - if (arg_num < argc && strcmp(argv[arg_num], "-l") == 0) { + if (arg_num < argc && + match_opt(argv[arg_num], "-a", "--address")) { errno = 0; image->target_address = strtoll(argv[arg_num + 1], &endp, 0); @@ -194,20 +228,19 @@ static int cell_create(int argc, char *argv[]) fd = open_dev(); - err = ioctl(fd, JAILHOUSE_CELL_CREATE, cell); + err = ioctl(fd, JAILHOUSE_CELL_LOAD, cell_load); if (err) - perror("JAILHOUSE_CELL_CREATE"); + perror("JAILHOUSE_CELL_LOAD"); close(fd); - free((void *)(unsigned long)cell->config_address); - for (n = 0, image = cell->image; n < images; n++, image++) + for (n = 0, image = cell_load->image; n < images; n++, image++) free((void *)(unsigned long)image->source_address); - free(cell); + free(cell_load); return err; } -static int cell_destroy(int argc, char *argv[]) +static int cell_simple_cmd(int argc, char *argv[], unsigned int command) { struct jailhouse_cell_id cell_id; int id_args, err, fd; @@ -218,9 +251,13 @@ static int cell_destroy(int argc, char *argv[]) fd = open_dev(); - err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell_id); + err = ioctl(fd, command, &cell_id); if (err) - perror("JAILHOUSE_CELL_DESTROY"); + perror(command == JAILHOUSE_CELL_START ? + "JAILHOUSE_CELL_START" : + command == JAILHOUSE_CELL_DESTROY ? + "JAILHOUSE_CELL_DESTROY" : + ""); close(fd); @@ -236,8 +273,12 @@ static int cell_management(int argc, char *argv[]) if (strcmp(argv[2], "create") == 0) err = cell_create(argc, argv); + else if (strcmp(argv[2], "load") == 0) + err = cell_load(argc, argv); + else if (strcmp(argv[2], "start") == 0) + err = cell_simple_cmd(argc, argv, JAILHOUSE_CELL_START); else if (strcmp(argv[2], "destroy") == 0) - err = cell_destroy(argc, argv); + err = cell_simple_cmd(argc, argv, JAILHOUSE_CELL_DESTROY); else help(argv[0], 1);