Skip to content

Commit

Permalink
driver/tools: Break up cell creation
Browse files Browse the repository at this point in the history
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 <jan.kiszka@siemens.com>
  • Loading branch information
jan-kiszka committed May 3, 2014
1 parent 92812e4 commit 1b8793d
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 56 deletions.
25 changes: 4 additions & 21 deletions driver.c
Expand Up @@ -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)))
Expand Down Expand Up @@ -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;
Expand All @@ -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);

Expand All @@ -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)
Expand Down Expand Up @@ -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(
Expand Down
15 changes: 7 additions & 8 deletions jailhouse.h
Expand Up @@ -14,20 +14,19 @@
#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 target_address;
__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;
Expand All @@ -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)
95 changes: 68 additions & 27 deletions tools/jailhouse.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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[])
{
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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" :
"<unknown command>");

close(fd);

Expand All @@ -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);

Expand Down

0 comments on commit 1b8793d

Please sign in to comment.