kobject_uevent(&cell->kobj, KOBJ_ADD);
}
-static struct cell *find_cell(struct jailhouse_cell_desc *cell_desc)
+static struct cell *find_cell(struct jailhouse_cell_id *cell_id)
{
struct cell *cell;
list_for_each_entry(cell, &cells, entry)
- if (strcmp(kobject_name(&cell->kobj), cell_desc->name) == 0)
+ if (cell_id->id == cell->id ||
+ (cell_id->id == JAILHOUSE_CELL_ID_UNUSED &&
+ strcmp(kobject_name(&cell->kobj), cell_id->name) == 0))
return cell;
return NULL;
}
struct jailhouse_preload_image __user *image = arg->image;
struct jailhouse_new_cell cell_params;
struct jailhouse_cell_desc *config;
+ struct jailhouse_cell_id cell_id;
unsigned int cpu, n;
struct cell *cell;
int id, err;
goto unlock_out;
}
- if (find_cell(config) != NULL) {
+ cell_id.id = JAILHOUSE_CELL_ID_UNUSED;
+ memcpy(cell_id.name, config->name, sizeof(cell_id.name));
+ if (find_cell(&cell_id) != NULL) {
err = -EEXIST;
goto unlock_out;
}
static int jailhouse_cell_destroy(const char __user *arg)
{
- struct jailhouse_cell_desc *config;
- struct jailhouse_cell cell_params;
+ struct jailhouse_cell_id cell_id;
struct cell *cell;
unsigned int cpu;
int err;
- if (copy_from_user(&cell_params, arg, sizeof(cell_params)))
+ if (copy_from_user(&cell_id, arg, sizeof(cell_id)))
return -EFAULT;
- config = kmalloc(cell_params.config_size, GFP_KERNEL | GFP_DMA);
- if (!config)
- return -ENOMEM;
-
- if (copy_from_user(config,
- (void *)(unsigned long)cell_params.config_address,
- cell_params.config_size)) {
- err = -EFAULT;
- goto kfree_config_out;
- }
- config->name[JAILHOUSE_CELL_NAME_MAXLEN] = 0;
+ cell_id.name[JAILHOUSE_CELL_NAME_MAXLEN] = 0;
- if (mutex_lock_interruptible(&lock) != 0) {
- err = -EINTR;
- goto kfree_config_out;
- }
+ if (mutex_lock_interruptible(&lock) != 0)
+ return -EINTR;
if (!enabled) {
err = -EINVAL;
goto unlock_out;
}
- cell = find_cell(config);
+ cell = find_cell(&cell_id);
if (!cell) {
err = -ENOENT;
goto unlock_out;
cpu_set(cpu, root_cell->cpus_assigned);
}
- delete_cell(cell);
+ pr_info("Destroyed Jailhouse cell \"%s\"\n",
+ kobject_name(&cell->kobj));
- pr_info("Destroyed Jailhouse cell \"%s\"\n", config->name);
+ delete_cell(cell);
unlock_out:
mutex_unlock(&lock);
-kfree_config_out:
- kfree(config);
-
return err;
}
struct jailhouse_preload_image image[];
};
-struct jailhouse_cell {
- __u64 config_address;
- __u32 config_size;
+struct jailhouse_cell_id {
+ __s32 id;
+ __u32 padding;
+ char name[JAILHOUSE_CELL_NAME_MAXLEN+1];
};
+#define JAILHOUSE_CELL_ID_UNUSED (-1)
+
#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, struct jailhouse_cell)
+#define JAILHOUSE_CELL_DESTROY _IOW(0, 3, struct jailhouse_cell_id)
* the COPYING file in the top-level directory.
*/
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
" disable\n"
" cell create CONFIGFILE IMAGE [-l ADDRESS] "
"[IMAGE [-l ADDRESS] ...]\n"
- " cell destroy CONFIGFILE\n",
+ " cell destroy { ID | [--name] NAME }\n",
progname);
exit(exit_status);
}
return err;
}
+static int parse_cell_id(struct jailhouse_cell_id *cell_id, int argc,
+ char *argv[])
+{
+ bool use_name = false;
+ int arg_pos = 0;
+ char *endp;
+
+ if (argc < 1)
+ return 0;
+
+ if (strcmp(argv[0], "--name") == 0) {
+ if (argc < 2)
+ return 0;
+ arg_pos++;
+ use_name = true;
+ } else {
+ errno = 0;
+ cell_id->id = strtoll(argv[0], &endp, 0);
+ if (errno != 0 || *endp != 0 || cell_id->id < 0)
+ use_name = true;
+ }
+
+ if (use_name) {
+ cell_id->id = JAILHOUSE_CELL_ID_UNUSED;
+ strncpy(cell_id->name, argv[arg_pos], sizeof(cell_id->name));
+ cell_id->name[sizeof(cell_id->name) - 1] = 0;
+ }
+
+ return arg_pos + 1;
+}
+
static int cell_create(int argc, char *argv[])
{
struct jailhouse_preload_image *image;
static int cell_destroy(int argc, char *argv[])
{
- struct jailhouse_cell cell;
- size_t size;
- int err, fd;
+ struct jailhouse_cell_id cell_id;
+ int id_args, err, fd;
- if (argc != 4)
+ id_args = parse_cell_id(&cell_id, argc - 3, &argv[3]);
+ if (id_args == 0 || 3 + id_args != argc)
help(argv[0], 1);
- cell.config_address = (unsigned long)read_file(argv[3], &size);
- cell.config_size = size;
-
fd = open_dev();
- err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell);
+ err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell_id);
if (err)
perror("JAILHOUSE_CELL_DESTROY");
close(fd);
- free((void *)(unsigned long)cell.config_address);
return err;
}