All of lore.kernel.org
 help / color / mirror / Atom feed
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
To: Ian Campbell <Ian.Campbell@citrix.com>,
	Keir Fraser <Keir.Fraser@eu.citrix.com>,
	"xen-devel@lists.xensource.com" <xen-devel@lists.xensource.com>
Subject: Re: [PATCH2] multiboot module support
Date: Sat, 12 Dec 2009 00:18:54 +0100	[thread overview]
Message-ID: <20091211231854.GD6590@const> (raw)
In-Reply-To: <20091211102923.GF5096@const.bordeaux.inria.fr>

Samuel Thibault, le Fri 11 Dec 2009 11:29:23 +0100, a écrit :
> Yes, it didn't go as badly as I thought. The addition of mods_count
> could perhaps be avoided by saying that the multiboot module table
> always ends with a NULL entry.  That is still compliant with multiboot,
> it just makes the PV guest have to count the modules itself (but not
> have to rebase all the pointers).

i.e. the patch below

Samuel

This defines how multiple modules can be passed to a domain by packing them
together into a "multiboot module" the same way as the multiboot standard.  An
SIF_ flag is added to announce such package. xc_dom_multiboot_mem is added to
libxc to load such list of modules, used by PV-GRUB.

Signed-Off-By: Samuel Thibault <samuel.thibault@ens-lyon.org>

diff -r 8f304c003af4 stubdom/grub.patches/99minios
--- a/stubdom/grub.patches/99minios	Wed Dec 09 10:59:31 2009 +0000
+++ b/stubdom/grub.patches/99minios	Sat Dec 12 00:18:05 2009 +0100
@@ -151,6 +151,14 @@
  
  /* print */
  static int
+@@ -2910,6 +2910,7 @@
+   switch (kernel_type)
+     {
+     case KERNEL_TYPE_MULTIBOOT:
++    case KERNEL_TYPE_PV:
+       if (mb_cmdline + len + 1 > (char *) MB_CMDLINE_BUF + MB_CMDLINE_BUFLEN)
+ 	{
+ 	  errnum = ERR_WONT_FIT;
 @@ -3776,6 +3802,7 @@
  };
  
diff -r 8f304c003af4 stubdom/grub/config.h
--- a/stubdom/grub/config.h	Wed Dec 09 10:59:31 2009 +0000
+++ b/stubdom/grub/config.h	Sat Dec 12 00:18:05 2009 +0100
@@ -5,7 +5,7 @@
 #define debug _debug
 #define grub_halt(a) do_exit()
 #define printf grub_printf
-void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline);
+void kexec(void *kernel, long kernel_size, char *cmdline, void *module, long module_size, int multiboot_number, void **multiboot_blobs, size_t *multiboot_sizes, char **multiboot_cmdlines);
 struct fbfront_dev *fb_open(void *fb, int width, int height, int depth);
 void fb_close(void);
 void pv_boot (void);
diff -r 8f304c003af4 stubdom/grub/kexec.c
--- a/stubdom/grub/kexec.c	Wed Dec 09 10:59:31 2009 +0000
+++ b/stubdom/grub/kexec.c	Sat Dec 12 00:18:05 2009 +0100
@@ -103,7 +103,7 @@
     return 0;
 }
 
-void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline)
+void kexec(void *kernel, long kernel_size, char *cmdline, void *module, long module_size, int multiboot_number, void **multiboot_blobs, size_t *multiboot_sizes, char **multiboot_cmdlines)
 {
     struct xc_dom_image *dom;
     int rc;
@@ -123,11 +123,11 @@
     dom = xc_dom_allocate(cmdline, features);
     dom->allocate = kexec_allocate;
 
-    dom->kernel_blob = kernel;
-    dom->kernel_size = kernel_size;
-
-    dom->ramdisk_blob = module;
-    dom->ramdisk_size = module_size;
+    xc_dom_kernel_mem(dom, kernel, kernel_size);
+    if (module)
+      xc_dom_ramdisk_mem(dom, module, module_size);
+    else if (multiboot_blobs)
+      xc_dom_multiboot_mem(dom, multiboot_number, multiboot_blobs, multiboot_sizes, multiboot_cmdlines);
 
     dom->flags = 0;
     dom->console_evtchn = start_info.console.domU.evtchn;
diff -r 8f304c003af4 stubdom/grub/mini-os.c
--- a/stubdom/grub/mini-os.c	Wed Dec 09 10:59:31 2009 +0000
+++ b/stubdom/grub/mini-os.c	Sat Dec 12 00:18:05 2009 +0100
@@ -172,7 +172,11 @@
 
 void *kernel_image, *module_image;
 long  kernel_size, module_size;
-char *kernel_arg, *module_arg;
+char *kernel_arg;
+void **multiboot_blobs;
+size_t *multiboot_sizes;
+char **multiboot_cmdlines;
+int multiboot_number;
 
 kernel_t
 load_image (char *kernel, char *arg, kernel_t suggested_type,
@@ -196,6 +200,13 @@
     if (module_image)
         free(module_image);
     module_image = NULL;
+    multiboot_number = 0;
+    free(multiboot_blobs);
+    multiboot_blobs = NULL;
+    free(multiboot_sizes);
+    multiboot_sizes = NULL;
+    free(multiboot_cmdlines);
+    multiboot_cmdlines = NULL;
     load_file (initrd, &module_image, &module_size);
     return ! errnum;
 }
@@ -203,20 +214,28 @@
 int
 load_module (char *module, char *arg)
 {
-    if (module_image)
-        free(module_image);
-    module_image = NULL;
-    load_file (module, &module_image, &module_size);
-    if (module_arg)
-        free(module_arg);
-    module_arg = strdup(arg);
-    return ! errnum;
+    void *module_blob;
+    long module_size;
+
+    if (load_file (module, &module_blob, &module_size))
+        return 0;
+
+    multiboot_number++;
+    multiboot_blobs = realloc(multiboot_blobs, multiboot_number * sizeof(*multiboot_blobs));
+    multiboot_sizes = realloc(multiboot_sizes, multiboot_number * sizeof(*multiboot_sizes));
+    multiboot_cmdlines = realloc(multiboot_cmdlines, multiboot_number * sizeof(*multiboot_cmdlines));
+
+    multiboot_blobs[multiboot_number-1] = module_blob;
+    multiboot_sizes[multiboot_number-1] = module_size;
+    multiboot_cmdlines[multiboot_number-1] = arg;
+
+    return 1;
 }
 
 void
 pv_boot (void)
 {
-    kexec(kernel_image, kernel_size, module_image, module_size, kernel_arg);
+    kexec(kernel_image, kernel_size, kernel_arg, module_image, module_size, multiboot_number, multiboot_blobs, multiboot_sizes, multiboot_cmdlines);
 }
 
 /*
diff -r 8f304c003af4 tools/libxc/xc_dom.h
--- a/tools/libxc/xc_dom.h	Wed Dec 09 10:59:31 2009 +0000
+++ b/tools/libxc/xc_dom.h	Sat Dec 12 00:18:05 2009 +0100
@@ -35,6 +35,10 @@
     size_t kernel_size;
     void *ramdisk_blob;
     size_t ramdisk_size;
+    int multiboot_number;
+    void **multiboot_blobs;
+    char **multiboot_cmdlines;
+    size_t *multiboot_sizes;
 
     /* arguments and parameters */
     char *cmdline;
@@ -47,6 +51,7 @@
     /* memory layout */
     struct xc_dom_seg kernel_seg;
     struct xc_dom_seg ramdisk_seg;
+    struct xc_dom_seg multiboot_seg;
     struct xc_dom_seg p2m_seg;
     struct xc_dom_seg pgtables_seg;
     struct xc_dom_seg devicetree_seg;
@@ -168,6 +173,10 @@
                       size_t memsize);
 int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem,
                        size_t memsize);
+int xc_dom_multiboot_mem(struct xc_dom_image *dom, int multiboot_number,
+                         void **multiboot_blobs,
+                         size_t *multiboot_sizes,
+                         char **multiboot_cmdlines);
 
 int xc_dom_parse_image(struct xc_dom_image *dom);
 struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type);
diff -r 8f304c003af4 tools/libxc/xc_dom_core.c
--- a/tools/libxc/xc_dom_core.c	Wed Dec 09 10:59:31 2009 +0000
+++ b/tools/libxc/xc_dom_core.c	Sat Dec 12 00:18:05 2009 +0100
@@ -607,6 +607,17 @@
     return 0;
 }
 
+int xc_dom_multiboot_mem(struct xc_dom_image *dom, int number,
+                         void **mems, size_t *memsizes, char **cmdlines)
+{
+    xc_dom_printf("%s: called\n", __FUNCTION__);
+    dom->multiboot_number = number;
+    dom->multiboot_blobs = mems;
+    dom->multiboot_sizes = memsizes;
+    dom->multiboot_cmdlines = cmdlines;
+    return 0;
+}
+
 int xc_dom_parse_image(struct xc_dom_image *dom)
 {
     int i;
@@ -757,6 +768,56 @@
             memcpy(ramdiskmap, dom->ramdisk_blob, dom->ramdisk_size);
     }
 
+    /* load multiboot modules */
+    if ( dom->multiboot_blobs )
+    {
+        void *multibootmap;
+        int i;
+        struct xen_multiboot_mod_list *module;
+        char *module_cmdline;
+        void *module_blob;
+        size_t totsize = 0;
+        size_t headers_size = 0;
+        size_t cmdlines_size = 0;
+
+        for (i = 0; i < dom->multiboot_number; i++) {
+            totsize += ROUNDUP(dom->multiboot_sizes[i], page_size);
+            headers_size += sizeof(*module);
+            cmdlines_size += strlen(dom->multiboot_cmdlines[i]) + 1;
+        }
+        headers_size += sizeof(*module);
+
+        totsize += ROUNDUP(headers_size + cmdlines_size, page_size);
+
+        if (xc_dom_alloc_segment(dom, &dom->multiboot_seg, "multiboot", 0, totsize))
+            goto err;
+        multibootmap = xc_dom_seg_to_ptr(dom, &dom->multiboot_seg);
+
+        module = multibootmap;
+        module_cmdline = multibootmap + headers_size;
+        module_blob = multibootmap + headers_size + cmdlines_size;
+
+        for (i = 0; i < dom->multiboot_number; i++) {
+            int len = strlen(dom->multiboot_cmdlines[i]) + 1;
+            memcpy(module_cmdline, dom->multiboot_cmdlines[i], len);
+            module->cmdline = (void*) module_cmdline - multibootmap
+                            + dom->multiboot_seg.vstart - dom->parms.virt_base;
+            module_cmdline += len;
+
+            memcpy(module_blob, dom->multiboot_blobs[i],
+                   dom->multiboot_sizes[i]);
+            module->mod_start = (void*) module_blob - multibootmap
+                            + dom->multiboot_seg.vstart - dom->parms.virt_base;
+            module->mod_end = module->mod_start + dom->multiboot_sizes[i] - 1;
+            module_blob += ROUNDUP(dom->multiboot_sizes[i], page_size);
+
+            module->pad = 0;
+
+            module++;
+        }
+        module->mod_start = 0;
+    }
+
     /* allocate other pages */
     if ( dom->arch_hooks->alloc_magic_pages(dom) != 0 )
         goto err;
diff -r 8f304c003af4 tools/libxc/xc_dom_ia64.c
--- a/tools/libxc/xc_dom_ia64.c	Wed Dec 09 10:59:31 2009 +0000
+++ b/tools/libxc/xc_dom_ia64.c	Sat Dec 12 00:18:05 2009 +0100
@@ -69,6 +69,16 @@
         bp->initrd_start = start_info->mod_start;
         bp->initrd_size = start_info->mod_len;
     }
+
+    if ( dom->multiboot_blobs )
+    {
+        start_info->mod_start = dom->multiboot_seg.vstart;
+        start_info->mod_len = dom->multiboot_seg.vend - dom->multiboot_seg.vstart;
+        bp->initrd_start = start_info->mod_start;
+        bp->initrd_size = start_info->mod_len;
+        dom->flags |= SIF_MULTIBOOT_MOD;
+    }
+
     bp->command_line = (dom->start_info_pfn << PAGE_SHIFT_IA64)
         + offsetof(start_info_t, cmd_line);
     if ( dom->cmdline )
diff -r 8f304c003af4 tools/libxc/xc_dom_x86.c
--- a/tools/libxc/xc_dom_x86.c	Wed Dec 09 10:59:31 2009 +0000
+++ b/tools/libxc/xc_dom_x86.c	Sat Dec 12 00:18:05 2009 +0100
@@ -441,6 +441,13 @@
         start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
     }
 
+    if ( dom->multiboot_blobs )
+    {
+        start_info->mod_start = dom->multiboot_seg.vstart;
+        start_info->mod_len = dom->multiboot_seg.vend - dom->multiboot_seg.vstart;
+        dom->flags |= SIF_MULTIBOOT_MOD;
+    }
+
     if ( dom->cmdline )
     {
         strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE);
@@ -481,6 +488,13 @@
         start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
     }
 
+    if ( dom->multiboot_blobs )
+    {
+        start_info->mod_start = dom->multiboot_seg.vstart;
+        start_info->mod_len = dom->multiboot_seg.vend - dom->multiboot_seg.vstart;
+        dom->flags |= SIF_MULTIBOOT_MOD;
+    }
+
     if ( dom->cmdline )
     {
         strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE);
diff -r 8f304c003af4 xen/include/public/xen.h
--- a/xen/include/public/xen.h	Wed Dec 09 10:59:31 2009 +0000
+++ b/xen/include/public/xen.h	Sat Dec 12 00:18:05 2009 +0100
@@ -584,8 +584,27 @@
 /* These flags are passed in the 'flags' field of start_info_t. */
 #define SIF_PRIVILEGED    (1<<0)  /* Is the domain privileged? */
 #define SIF_INITDOMAIN    (1<<1)  /* Is this the initial control domain? */
+#define SIF_MULTIBOOT_MOD (1<<2)  /* Is mod_start a multiboot module? */
 #define SIF_PM_MASK       (0xFF<<8) /* reserve 1 byte for xen-pm options */
 
+/*
+ * A multiboot module is a package containing modules like a multiboot module
+ * array. The only difference is that the module list always ends with an entry
+ * with mod_start set to zero, to let the guest know how many modules are
+ * provided.
+ */
+struct xen_multiboot_mod_list
+{
+    /* PHYSICAL address of first byte of the module */
+    unsigned long mod_start;
+    /* PHYSICAL address of last byte of the module (inclusive) */
+    unsigned long mod_end;
+    /* PHYSICAL address of zero-terminated command line */
+    unsigned long cmdline;
+    /* Unused, must be zero */
+    unsigned long pad;
+};
+
 typedef struct dom0_vga_console_info {
     uint8_t video_type; /* DOM0_VGA_CONSOLE_??? */
 #define XEN_VGATYPE_TEXT_MODE_3 0x03

  reply	other threads:[~2009-12-11 23:18 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-09 14:01 [PATCH] multiboot-like module support Samuel Thibault
2009-12-09 14:29 ` Ian Campbell
2009-12-09 14:59   ` Samuel Thibault
2009-12-11  2:44     ` [PATCH2] multiboot " Samuel Thibault
2009-12-11  8:09       ` Keir Fraser
2009-12-11  9:59         ` Ian Campbell
2009-12-11 10:29           ` Samuel Thibault
2009-12-11 23:18             ` Samuel Thibault [this message]
2009-12-15 20:42               ` Samuel Thibault
2009-12-15 22:18                 ` Keir Fraser
2009-12-15 22:42                   ` Samuel Thibault

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091211231854.GD6590@const \
    --to=samuel.thibault@ens-lyon.org \
    --cc=Ian.Campbell@citrix.com \
    --cc=Keir.Fraser@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.