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)))
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;
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);
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)
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(
#include <linux/types.h>
#include <jailhouse/cell-config.h>
+struct jailhouse_cell_create {
+ __u64 config_address;
+ __u32 config_size;
+ __u32 padding;
+};
+
struct jailhouse_preload_image {
__u64 source_address;
__u64 size;
__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;
#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)
{
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);
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[])
{
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);
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;
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" :
+ "<unknown command>");
close(fd);
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);