]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
plat/xen: Manage memory regions through `ukplat_memregion` API's
authorSergiu Moga <sergiu.moga@protonmail.com>
Thu, 6 Apr 2023 14:52:34 +0000 (17:52 +0300)
committerUnikraft <monkey@unikraft.io>
Fri, 11 Aug 2023 10:18:44 +0000 (10:18 +0000)
Switch to using the generic `ukplat_memregion` API's since they are
more dynamic and flexible.

Thus, remove conflicting definitions of `ukplat_memregion` from
`memory.c`, in favor of those from `platform/common`.

Signed-off-by: Sergiu Moga <sergiu.moga@protonmail.com>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #848

plat/xen/include/xen-x86/setup.h
plat/xen/memory.c
plat/xen/x86/setup.c

index 0d9eecb0703e9b5e68839f077a516374a50440f4..b7bb0c683bb57c5066d310214a53d133ec1e645c 100644 (file)
@@ -40,8 +40,6 @@
 #include <xen/arch-x86/hvm/start_info.h>
 #include <uk/plat/memory.h>
 
-extern unsigned int _libxenplat_mrd_num;
-extern struct ukplat_memregion_desc _libxenplat_mrd[];
 extern char _libxenplat_bootstack[];
 
 extern start_info_t *HYPERVISOR_start_info;
index a2718ecf3601ca162be08e19628007857b31ff10..fa1af9e04cc58e2501ad32a10850bec11224d3a2 100644 (file)
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <string.h>
 #include <stdint.h>
-#include <stddef.h>
-#include <uk/plat/common/sections.h>
-#include <uk/plat/memory.h>
 
 #include <common/gnttab.h>
 #if (defined __X86_32__) || (defined __X86_64__)
 #include <xen-arm/mm.h>
 #endif
 
-#include <uk/assert.h>
-
-/* TODO: Replace with proper initialization of bootinfo */
-
-int ukplat_memregion_count(void)
-{
-       return (int) _libxenplat_mrd_num + 7;
-}
-
-int ukplat_memregion_get(int i, struct ukplat_memregion_desc **m)
-{
-       static struct ukplat_memregion_desc mrd[7];
-
-       UK_ASSERT(m);
-
-       switch (i) {
-       case 0: /* text */
-               mrd[i].pbase = __TEXT;
-               mrd[i].vbase = __TEXT;
-               mrd[i].len   = __ETEXT - __TEXT;
-               mrd[i].type  = UKPLAT_MEMRT_KERNEL;
-               mrd[i].flags = UKPLAT_MEMRF_READ | UKPLAT_MEMRF_EXECUTE;
-#if CONFIG_UKPLAT_MEMRNAME
-               strncpy(mrd[i].name, "text", sizeof(mrd[i].name) - 1);
-#endif
-               *m = &mrd[i];
-               break;
-       case 1: /* eh_frame */
-               mrd[i].pbase = __EH_FRAME_START;
-               mrd[i].vbase = __EH_FRAME_START;
-               mrd[i].len   = __EH_FRAME_END - __EH_FRAME_START;
-               mrd[i].type  = UKPLAT_MEMRT_KERNEL;
-               mrd[i].flags = UKPLAT_MEMRF_READ;
-#if CONFIG_UKPLAT_MEMRNAME
-               strncpy(mrd[i].name, "eh_frame", sizeof(mrd[i].name) - 1);
-#endif
-               *m = &mrd[i];
-               break;
-       case 2: /* eh_frame_hdr */
-               mrd[i].pbase = __EH_FRAME_HDR_START;
-               mrd[i].vbase = __EH_FRAME_HDR_START;
-               mrd[i].len   = __EH_FRAME_HDR_END - __EH_FRAME_HDR_START;
-               mrd[i].type  = UKPLAT_MEMRT_KERNEL;
-               mrd[i].flags = UKPLAT_MEMRF_READ;
-#if CONFIG_UKPLAT_MEMRNAME
-               strncpy(mrd[i].name, "eh_frame_hdr", sizeof(mrd[i].name) - 1);
-#endif
-               *m = &mrd[i];
-               break;
-       case 3: /* ro data */
-               mrd[i].pbase = __RODATA;
-               mrd[i].vbase = __RODATA;
-               mrd[i].len   = __ERODATA - __RODATA;
-               mrd[i].type  = UKPLAT_MEMRT_KERNEL;
-               mrd[i].flags = UKPLAT_MEMRF_READ;
-#if CONFIG_UKPLAT_MEMRNAME
-               strncpy(mrd[i].name, "rodata", sizeof(mrd[i].name) - 1);
-#endif
-               *m = &mrd[i];
-               break;
-       case 4: /* ctors */
-               mrd[i].pbase = __CTORS;
-               mrd[i].vbase = __CTORS;
-               mrd[i].len   = __ECTORS - __CTORS;
-               mrd[i].type  = UKPLAT_MEMRT_KERNEL;
-               mrd[i].flags = UKPLAT_MEMRF_READ;
-#if CONFIG_UKPLAT_MEMRNAME
-               strncpy(mrd[i].name, "ctors", sizeof(mrd[i].name) - 1);
-#endif
-               *m = &mrd[i];
-               break;
-       case 5: /* data */
-               mrd[i].pbase = __DATA;
-               mrd[i].vbase = __DATA;
-               mrd[i].len   = __EDATA - __DATA;
-               mrd[i].type  = UKPLAT_MEMRT_KERNEL;
-               mrd[i].flags = UKPLAT_MEMRF_READ | UKPLAT_MEMRF_WRITE;
-#if CONFIG_UKPLAT_MEMRNAME
-               strncpy(mrd[i].name, "data", sizeof(mrd[i].name) - 1);
-#endif
-               *m = &mrd[i];
-               break;
-       case 6: /* bss */
-               mrd[i].pbase = __BSS_START;
-               mrd[i].vbase = __BSS_START;
-               mrd[i].len   = __END - __BSS_START;
-               mrd[i].type  = UKPLAT_MEMRT_KERNEL;
-               mrd[i].flags = UKPLAT_MEMRF_READ | UKPLAT_MEMRF_WRITE;
-#if CONFIG_UKPLAT_MEMRNAME
-               strncpy(mrd[i].name, "bss", sizeof(mrd[i].name) - 1);
-#endif
-               *m = &mrd[i];
-               break;
-       default:
-               if (i < 0 || i >= ukplat_memregion_count())
-                       return -1;
-
-               *m = &_libxenplat_mrd[i - 7];
-               break;
-       }
-
-       return 0;
-}
-
 void mm_init(void)
 {
        arch_mm_init(ukplat_memallocator_get());
index 2ba8aeee5c95abdf9f6c0d0d3e13bdebd5197887..15986e81e6b33c92e8c5e4a03f19fb07bff1c2d1 100644 (file)
@@ -74,6 +74,7 @@
 #include <uk/plat/config.h>
 #include <uk/plat/console.h>
 #include <uk/plat/bootstrap.h>
+#include <uk/plat/common/bootinfo.h>
 #include <x86/cpu.h>
 #include <x86/traps.h>
 
@@ -91,8 +92,6 @@
 #include <xen/arch-x86/cpuid.h>
 #include <xen/arch-x86/hvm/start_info.h>
 
-static char cmdline[MAX_GUEST_CMDLINE];
-
 start_info_t *HYPERVISOR_start_info;
 shared_info_t *HYPERVISOR_shared_info;
 
@@ -102,13 +101,6 @@ shared_info_t *HYPERVISOR_shared_info;
  */
 char _libxenplat_bootstack[2*__STACK_SIZE];
 
-/*
- * Memory region description
- */
-#define UKPLAT_MEMRD_MAX_ENTRIES 3
-unsigned int _libxenplat_mrd_num;
-struct ukplat_memregion_desc _libxenplat_mrd[UKPLAT_MEMRD_MAX_ENTRIES];
-
 static inline void _init_traps(void)
 {
        traps_lcpu_init(NULL);
@@ -127,9 +119,11 @@ static inline void _init_shared_info(void)
        HYPERVISOR_shared_info = (shared_info_t *)_libxenplat_shared_info;
 }
 
-static inline void _init_mem(void)
+static int _init_mem(struct ukplat_bootinfo *const bi)
 {
        unsigned long start_pfn, max_pfn;
+       struct ukplat_memregion_desc mrd;
+       int rc;
 
        _init_mem_prepare(&start_pfn, &max_pfn);
 
@@ -145,59 +139,115 @@ static inline void _init_mem(void)
 
        /* Fill out mrd array */
        /* heap */
-       _libxenplat_mrd[0].pbase = start_pfn << PAGE_SHIFT;
-       _libxenplat_mrd[0].vbase = (__vaddr_t)to_virt(_libxenplat_mrd[0].pbase);
-       _libxenplat_mrd[0].len   = (max_pfn - start_pfn) << PAGE_SHIFT;
-       _libxenplat_mrd[0].type  = UKPLAT_MEMRT_FREE;
-       _libxenplat_mrd[0].flags = 0;
+       mrd = (struct ukplat_memregion_desc) {
+               .vbase = (__vaddr_t)to_virt(start_pfn << PAGE_SHIFT),
+               .pbase = start_pfn << PAGE_SHIFT,
+               .len   = (max_pfn - start_pfn) << PAGE_SHIFT,
+               .type  = UKPLAT_MEMRT_FREE,
+               .flags = UKPLAT_MEMRF_READ | UKPLAT_MEMRF_WRITE |
+                        UKPLAT_MEMRF_MAP,
+       };
 #if CONFIG_UKPLAT_MEMRNAME
-       strncpy(_libxenplat_mrd[0].name, "heap",
-               sizeof(_libxenplat_mrd[0].name) - 1);
+       strncpy(mrd.name, "heap", sizeof(mrd.name) - 1);
 #endif
+       rc = ukplat_memregion_list_insert(&bi->mrds, &mrd);
+       if (unlikely(rc < 0))
+               return rc;
 
-       /* demand area */
-       _libxenplat_mrd[1].pbase = __PADDR_MAX;
-       _libxenplat_mrd[1].vbase = VIRT_DEMAND_AREA;
-       _libxenplat_mrd[1].len   = DEMAND_MAP_PAGES * PAGE_SIZE;
-       _libxenplat_mrd[1].type  = UKPLAT_MEMRT_RESERVED;
-       _libxenplat_mrd[1].flags = 0;
+       mrd = (struct ukplat_memregion_desc) {
+               .vbase = VIRT_DEMAND_AREA,
+               .pbase = __PADDR_MAX,
+               .len   = DEMAND_MAP_PAGES * PAGE_SIZE,
+               .type  = UKPLAT_MEMRT_RESERVED,
+               .flags = UKPLAT_MEMRF_READ | UKPLAT_MEMRF_MAP,
+       };
 #if CONFIG_UKPLAT_MEMRNAME
-       strncpy(_libxenplat_mrd[1].name, "demand",
-               sizeof(_libxenplat_mrd[1].name) - 1);
+       strncpy(mrd.name, "demand", sizeof(mrd.name) - 1);
 #endif
-       _init_mem_demand_area((unsigned long) _libxenplat_mrd[1].vbase,
-                       DEMAND_MAP_PAGES);
+       rc = ukplat_memregion_list_insert(&bi->mrds, &mrd);
+       if (unlikely(rc < 0))
+               return rc;
 
-       _libxenplat_mrd_num = 2;
+       _init_mem_demand_area((unsigned long)mrd.vbase, DEMAND_MAP_PAGES);
 
        /* initrd */
+       mrd = (struct ukplat_memregion_desc){0};
        if (HYPERVISOR_start_info->mod_len) {
                if (HYPERVISOR_start_info->flags & SIF_MOD_START_PFN) {
-                       _libxenplat_mrd[2].pbase =
-                               HYPERVISOR_start_info->mod_start;
-                       _libxenplat_mrd[2].vbase =
-                               (__vaddr_t)to_virt(_libxenplat_mrd[2].pbase);
+                       mrd.pbase = HYPERVISOR_start_info->mod_start;
+                       mrd.vbase = (__vaddr_t)to_virt(mrd.pbase);
                } else {
-                       _libxenplat_mrd[2].pbase =
-                               HYPERVISOR_start_info->mod_start;
-                       _libxenplat_mrd[2].vbase =
-                               _libxenplat_mrd[2].pbase;
+                       mrd.pbase = HYPERVISOR_start_info->mod_start;
+                       mrd.vbase = mrd.pbase;
                }
-               _libxenplat_mrd[2].len   =
-                       (size_t) HYPERVISOR_start_info->mod_len;
-               _libxenplat_mrd[2].type  = UKPLAT_MEMRT_INITRD;
-               _libxenplat_mrd[2].flags = (UKPLAT_MEMRF_WRITE
-                                           | UKPLAT_MEMRF_MAP);
+               mrd.len = (size_t)HYPERVISOR_start_info->mod_len;
+               mrd.type = UKPLAT_MEMRT_INITRD;
+               mrd.flags = UKPLAT_MEMRF_READ | UKPLAT_MEMRF_WRITE |
+                           UKPLAT_MEMRF_MAP;
 #if CONFIG_UKPLAT_MEMRNAME
-               strncpy(_libxenplat_mrd[2].name, "initrd",
-                       sizeof(_libxenplat_mrd[2].name) - 1);
+               strncpy(mrd.name, "initrd", sizeof(mrd.name) - 1);
 #endif
-               _libxenplat_mrd_num++;
+               rc = ukplat_memregion_list_insert(&bi->mrds, &mrd);
+               if (unlikely(rc < 0))
+                       return rc;
        }
+
+       return ukplat_memregion_list_coalesce(&bi->mrds);
 }
 
-void _libxenplat_x86entry(void *start_info) __noreturn;
+static char *cmdline;
+static __sz cmdline_len;
+
+static void _libxenplat_x86bootinfo_setup_cmdl(struct ukplat_bootinfo *bi)
+{
+       cmdline_len = strlen((char *)HYPERVISOR_start_info->cmd_line);
+       if (!cmdline_len)
+               cmdline_len = sizeof(CONFIG_UK_NAME) - 1;
+
+       cmdline = ukplat_memregion_alloc(cmdline_len, UKPLAT_MEMRT_CMDLINE);
+       if (unlikely(!cmdline))
+               UK_CRASH("Could not allocate command-line memory");
+
+       strncpy(cmdline, (const char *)HYPERVISOR_start_info->cmd_line,
+               cmdline_len);
+       cmdline[cmdline_len] = '\0';
+
+       bi->cmdline = (__u64)cmdline;
+       bi->cmdline_len = cmdline_len;
+
+       /* Tag this scratch cmdline as a kernel resource, to distinguish it
+        * from the original cmdline obtained above
+        */
+       cmdline = ukplat_memregion_alloc(cmdline_len, UKPLAT_MEMRT_KERNEL);
+       if (unlikely(!cmdline))
+               UK_CRASH("Could not allocate scratch command-line memory");
+
+       strncpy(cmdline, (const char *)HYPERVISOR_start_info->cmd_line,
+               cmdline_len);
+       cmdline[cmdline_len] = '\0';
+}
+
+static void _libxenplat_x86bootinfo_setup(void)
+{
+       const char bl[] = "Xen";
+       const char bp[] = "PVH";
+       struct ukplat_bootinfo *bi;
+
+       bi = ukplat_bootinfo_get();
+       if (unlikely(!bi))
+               UK_CRASH("Failed to get bootinfo\n");
+
+       memcpy(bi->bootloader, bl, sizeof(bl));
+
+       memcpy(bi->bootprotocol, bp, sizeof(bp));
+
+       if (_init_mem(bi) < 0)
+               UK_CRASH("Failed to initialize memory\n");
 
+       _libxenplat_x86bootinfo_setup_cmdl(bi);
+}
+
+void _libxenplat_x86entry(void *start_info) __noreturn;
 void _libxenplat_x86entry(void *start_info)
 {
        _init_traps();
@@ -208,9 +258,6 @@ void _libxenplat_x86entry(void *start_info)
 
        _init_shared_info(); /* remaps shared info */
 
-       strncpy(cmdline, (char *)HYPERVISOR_start_info->cmd_line,
-               MAX_GUEST_CMDLINE);
-
        /* Set up events. */
        init_events();
 
@@ -218,13 +265,13 @@ void _libxenplat_x86entry(void *start_info)
        uk_pr_info("   shared_info: %p\n", HYPERVISOR_shared_info);
        uk_pr_info("hypercall_page: %p\n", hypercall_page);
 
-       _init_mem();
-
        init_console();
 
+       _libxenplat_x86bootinfo_setup();
+
 #if CONFIG_HAVE_X86PKU
        _check_ospke();
 #endif /* CONFIG_HAVE_X86PKU */
 
-       ukplat_entry_argp(CONFIG_UK_NAME, cmdline, MAX_GUEST_CMDLINE);
+       ukplat_entry_argp(CONFIG_UK_NAME, cmdline, cmdline_len);
 }