Re: [libvirt PATCH 4/9] Jailhouse driver: Implementation of DomainCreate* callbacks

2020-09-23 Thread Daniel P . Berrangé
On Thu, Sep 17, 2020 at 04:23:54PM +0100, Daniel P. Berrangé wrote:
> From: Prakhar Bansal 
> 
> Implemented Jailhouse hypervisor APIs for cell
> load/start/shutdown/destroy.
> ---
>  src/jailhouse/jailhouse_api.c| 100 --
>  src/jailhouse/jailhouse_api.h|  29 +
>  src/jailhouse/jailhouse_driver.c | 217 +--
>  src/jailhouse/jailhouse_driver.h |   8 ++
>  4 files changed, 335 insertions(+), 19 deletions(-)
> 
> diff --git a/src/jailhouse/jailhouse_api.c b/src/jailhouse/jailhouse_api.c
> index cda00b50e7..783903e939 100644
> --- a/src/jailhouse/jailhouse_api.c
> +++ b/src/jailhouse/jailhouse_api.c
> @@ -43,11 +43,14 @@
>  #define JAILHOUSE_CELLS 
> "/sys/devices/jailhouse/cells"
>  #define MAX_JAILHOUSE_SYS_CONFIG_FILE_SIZE  1024*1024
>  #define MAX_JAILHOUSE_CELL_CONFIG_FILE_SIZE 1024
> +#define MAX_JAILHOUSE_CELL_IMAGE_FILE_SIZE  64*1024*1024
>  
>  
>  #define JAILHOUSE_ENABLE   _IOW(0, 0, void *)
>  #define JAILHOUSE_DISABLE  _IO(0, 1)
>  #define JAILHOUSE_CELL_CREATE  _IOW(0, 2, virJailhouseCellCreate)
> +#define JAILHOUSE_CELL_LOAD_IOW(0, 3, virJailhouseCellLoad)
> +#define JAILHOUSE_CELL_START   _IOW(0, 4, virJailhouseCellId)
>  #define JAILHOUSE_CELL_DESTROY _IOW(0, 5, virJailhouseCellId)
>  
>  #define VIR_FROM_THIS VIR_FROM_JAILHOUSE
> @@ -68,8 +71,6 @@ int cell_match(const struct dirent *dirent);
>  
>  int createCell(const char *conf_file);
>  
> -int destroyCell(virJailhouseCellId cell_id);
> -
>  int getCellInfo(const unsigned int id,
>  virJailhouseCellInfoPtr * cell_info);
>  
> @@ -254,7 +255,7 @@ readSysfsCellString(const unsigned int id, const char 
> *entry)
>  }
>  
>  int
> -getCellInfo(const unsigned int id, virJailhouseCellInfoPtr * cell_info_ptr)
> +getCellInfo(const unsigned int id, virJailhouseCellInfoPtr *cell_info_ptr)
>  {
>  char *tmp;
>  
> @@ -345,28 +346,105 @@ getJailhouseCellsInfo(void)
>  }
>  
>  int
> -destroyCell(virJailhouseCellId cell_id)
> +loadImagesInCell(virJailhouseCellId cell_id, char **images, int num_images)
> +{
> +   virJailhousePreloadImagePtr image;
> +   virJailhouseCellLoadPtr cell_load;
> +   g_autofree char *buffer = NULL;
> +   unsigned int n;
> +   int len = -1, err = -1;
> +   VIR_AUTOCLOSE fd = -1;
> +
> +
> +   if (VIR_ALLOC(cell_load) < 0) {
> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   "%s",
> +   _("Insufficient memory for cell load"));
> +return -1;
> +   }
> +
> +
> +   if (VIR_ALLOC_N(cell_load->image, num_images) < 0) {
> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   "%s",
> +   _("Insufficient memory for cell load images"));
> +return -1;
> +   }

No need to check failure - these abort on OOM.

> +
> +   cell_load->id = cell_id;
> +   cell_load->num_preload_images = num_images;
> +
> +   for (n = 0, image = cell_load->image; n < num_images; n++, image++) {
> +len = virFileReadAll(images[n], MAX_JAILHOUSE_CELL_IMAGE_FILE_SIZE, 
> &buffer);
> +if (len < 0 || !buffer) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +_("Failed to read the image file %s"),
> +images[n]);
> + return -1;
> +}
> +
> +image->source_address = (unsigned long)buffer;
> +image->size = len;
> +
> +// TODO(Prakhar): Add support for target address.
> +image->target_address = 0;
> +   }
> +
> +   fd = openDev();

Check error here.

> +
> +   err = ioctl(fd, JAILHOUSE_CELL_LOAD, cell_load);
> +   if (err) {
> +   virReportSystemError(errno,
> +_("Loading cell images for %d failed"),
> +cell_id.id);
> +   return -1;
> +   }
> +
> +   return 0;
> +}


> -destroyJailhouseCells(virJailhouseCellInfoPtr *cell_info_list G_GNUC_UNUSED)
> +destroyCell(virJailhouseCellId cell_id)
>  {
> +int err = -1;
> +VIR_AUTOCLOSE fd = -1;
> +
> +fd = openDev();

Check error

>  
> -/* Iterate over all cells in cell_info_list and destroy each cell */
> -// TODO: Not implemented yet.
> +err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell_id);
> +if (err) {
> +virReportSystemError(errno,
> + _("Destroying cell %d failed"),
> + cell_id.id);
> +
> +return -1;
> +}


> +typedef struct _virJailhousePreloadImage virJailhousePreloadImage;
> +typedef virJailhousePreloadImage *virJailhousePreloadImagePtr;
> +
> +struct _virJailhousePreloadImage {
> +__u64 source_address;

uint64_t, etc

> +__u64 size;
> +__u64 target_address;
> +__u64 padding;
> +};
> +
> +typedef struct _virJailhouseCellLoad virJailhouseCellLoad;
> +typedef virJailhouseCellLoad *virJailhouseCellLoadPtr;
> +
> +struct _virJailhouseCellLoad {
> +str

[libvirt PATCH 4/9] Jailhouse driver: Implementation of DomainCreate* callbacks

2020-09-17 Thread Daniel P . Berrangé
From: Prakhar Bansal 

Implemented Jailhouse hypervisor APIs for cell
load/start/shutdown/destroy.
---
 src/jailhouse/jailhouse_api.c| 100 --
 src/jailhouse/jailhouse_api.h|  29 +
 src/jailhouse/jailhouse_driver.c | 217 +--
 src/jailhouse/jailhouse_driver.h |   8 ++
 4 files changed, 335 insertions(+), 19 deletions(-)

diff --git a/src/jailhouse/jailhouse_api.c b/src/jailhouse/jailhouse_api.c
index cda00b50e7..783903e939 100644
--- a/src/jailhouse/jailhouse_api.c
+++ b/src/jailhouse/jailhouse_api.c
@@ -43,11 +43,14 @@
 #define JAILHOUSE_CELLS "/sys/devices/jailhouse/cells"
 #define MAX_JAILHOUSE_SYS_CONFIG_FILE_SIZE  1024*1024
 #define MAX_JAILHOUSE_CELL_CONFIG_FILE_SIZE 1024
+#define MAX_JAILHOUSE_CELL_IMAGE_FILE_SIZE  64*1024*1024
 
 
 #define JAILHOUSE_ENABLE   _IOW(0, 0, void *)
 #define JAILHOUSE_DISABLE  _IO(0, 1)
 #define JAILHOUSE_CELL_CREATE  _IOW(0, 2, virJailhouseCellCreate)
+#define JAILHOUSE_CELL_LOAD_IOW(0, 3, virJailhouseCellLoad)
+#define JAILHOUSE_CELL_START   _IOW(0, 4, virJailhouseCellId)
 #define JAILHOUSE_CELL_DESTROY _IOW(0, 5, virJailhouseCellId)
 
 #define VIR_FROM_THIS VIR_FROM_JAILHOUSE
@@ -68,8 +71,6 @@ int cell_match(const struct dirent *dirent);
 
 int createCell(const char *conf_file);
 
-int destroyCell(virJailhouseCellId cell_id);
-
 int getCellInfo(const unsigned int id,
 virJailhouseCellInfoPtr * cell_info);
 
@@ -254,7 +255,7 @@ readSysfsCellString(const unsigned int id, const char 
*entry)
 }
 
 int
-getCellInfo(const unsigned int id, virJailhouseCellInfoPtr * cell_info_ptr)
+getCellInfo(const unsigned int id, virJailhouseCellInfoPtr *cell_info_ptr)
 {
 char *tmp;
 
@@ -345,28 +346,105 @@ getJailhouseCellsInfo(void)
 }
 
 int
-destroyCell(virJailhouseCellId cell_id)
+loadImagesInCell(virJailhouseCellId cell_id, char **images, int num_images)
+{
+   virJailhousePreloadImagePtr image;
+   virJailhouseCellLoadPtr cell_load;
+   g_autofree char *buffer = NULL;
+   unsigned int n;
+   int len = -1, err = -1;
+   VIR_AUTOCLOSE fd = -1;
+
+
+   if (VIR_ALLOC(cell_load) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   "%s",
+   _("Insufficient memory for cell load"));
+return -1;
+   }
+
+
+   if (VIR_ALLOC_N(cell_load->image, num_images) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   "%s",
+   _("Insufficient memory for cell load images"));
+return -1;
+   }
+
+   cell_load->id = cell_id;
+   cell_load->num_preload_images = num_images;
+
+   for (n = 0, image = cell_load->image; n < num_images; n++, image++) {
+len = virFileReadAll(images[n], MAX_JAILHOUSE_CELL_IMAGE_FILE_SIZE, 
&buffer);
+if (len < 0 || !buffer) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+_("Failed to read the image file %s"),
+images[n]);
+ return -1;
+}
+
+image->source_address = (unsigned long)buffer;
+image->size = len;
+
+// TODO(Prakhar): Add support for target address.
+image->target_address = 0;
+   }
+
+   fd = openDev();
+
+   err = ioctl(fd, JAILHOUSE_CELL_LOAD, cell_load);
+   if (err) {
+   virReportSystemError(errno,
+_("Loading cell images for %d failed"),
+cell_id.id);
+   return -1;
+   }
+
+   return 0;
+}
+
+int
+shutdownCell(virJailhouseCellId cell_id)
+{
+// Loading 0 images in the cell causes cell to shutdown.
+return loadImagesInCell(cell_id, NULL, 0);
+}
+
+int
+startCell(virJailhouseCellId cell_id)
 {
 int err = -1;
 VIR_AUTOCLOSE fd = -1;
 
 fd = openDev();
 
-err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell_id);
-if (err)
+err = ioctl(fd, JAILHOUSE_CELL_START, &cell_id);
+if (err) {
 virReportSystemError(errno,
- _("Destroying cell %d failed"),
+ _("Start cell %d failed"),
  cell_id.id);
+return -1;
+}
 
-return err;
+return 0;
 }
 
 int
-destroyJailhouseCells(virJailhouseCellInfoPtr *cell_info_list G_GNUC_UNUSED)
+destroyCell(virJailhouseCellId cell_id)
 {
+int err = -1;
+VIR_AUTOCLOSE fd = -1;
+
+fd = openDev();
 
-/* Iterate over all cells in cell_info_list and destroy each cell */
-// TODO: Not implemented yet.
+err = ioctl(fd, JAILHOUSE_CELL_DESTROY, &cell_id);
+if (err) {
+virReportSystemError(errno,
+ _("Destroying cell %d failed"),
+ cell_id.id);
+
+return -1;
+}
 
 return 0;
 }
diff --git a/src/jailhouse/jailhouse_api.h b/src/jailhouse/jailhouse_api.h
index 8362cb3d0f..ba39a4c8b7 100644
--- a/src/jailhouse/jailhouse_api.h
+++ b/src/jailhouse/jail