[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH v2 6/8] plat/kvm: Introduce platform configuration struct



Instead of having individual platform-global variables that hold
configuration found during setup (e.g., _libkvmplat_heap_start,
_libkvmplat_stack_top, _libkvmplat_mem_end), we introduce a
configuration struct. We do this for readability reasons.

Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
---
 plat/common/arm/pl011.c       | 15 ++++----
 plat/common/arm/time.c        | 13 ++++---
 plat/kvm/arm/setup.c          | 67 ++++++++++++++++++++++-------------
 plat/kvm/include/kvm/config.h | 63 ++++++++++++++++++++++++++++++++
 plat/kvm/memory.c             | 18 +++-------
 plat/kvm/x86/setup.c          | 39 ++++++++++++--------
 6 files changed, 153 insertions(+), 62 deletions(-)
 create mode 100644 plat/kvm/include/kvm/config.h

diff --git a/plat/common/arm/pl011.c b/plat/common/arm/pl011.c
index 206c0bf4..0b0d672b 100644
--- a/plat/common/arm/pl011.c
+++ b/plat/common/arm/pl011.c
@@ -23,6 +23,11 @@
 #include <uk/assert.h>
 #include <arm/cpu.h>
 
+/* TODO: For now this file is KVM dependent. As soon as we have more
+ * Arm platforms that are using this file, we need to introduce a
+ * portable way to handover the DTB entry point to common platform code */
+#include <kvm/config.h>
+
 /* PL011 UART registers and masks*/
 /* Data register */
 #define REG_UARTDR_OFFSET      0x00
@@ -83,8 +88,6 @@ static uint64_t pl011_uart_bas = 0;
 #define PL011_REG_READ(r)      ioreg_read16(PL011_REG(r))
 #define PL011_REG_WRITE(r, v)  ioreg_write16(PL011_REG(r), v)
 
-extern void *_libkvmplat_dtb;
-
 static void init_pl011(uint64_t bas)
 {
        pl011_uart_bas = bas;
@@ -115,20 +118,20 @@ void _libkvmplat_init_console(void)
 
        uk_pr_info("Serial initializing\n");
 
-       offset = fdt_node_offset_by_compatible(_libkvmplat_dtb, \
+       offset = fdt_node_offset_by_compatible(_libkvmplat_cfg.dtb, \
                                        -1, "arm,pl011");
        if (offset < 0)
                UK_CRASH("No console UART found!\n");
 
-       naddr = fdt_address_cells(_libkvmplat_dtb, offset);
+       naddr = fdt_address_cells(_libkvmplat_cfg.dtb, offset);
        if (naddr < 0 || naddr >= FDT_MAX_NCELLS)
                UK_CRASH("Could not find proper address cells!\n");
 
-       nsize = fdt_size_cells(_libkvmplat_dtb, offset);
+       nsize = fdt_size_cells(_libkvmplat_cfg.dtb, offset);
        if (nsize < 0 || nsize >= FDT_MAX_NCELLS)
                UK_CRASH("Could not find proper size cells!\n");
 
-       regs = fdt_getprop(_libkvmplat_dtb, offset, "reg", &len);
+       regs = fdt_getprop(_libkvmplat_cfg.dtb, offset, "reg", &len);
        if (regs == NULL || (len < (int)sizeof(fdt32_t) * (naddr + nsize)))
                UK_CRASH("Bad 'reg' property: %p %d\n", regs, len);
 
diff --git a/plat/common/arm/time.c b/plat/common/arm/time.c
index 57a62354..1b30903b 100644
--- a/plat/common/arm/time.c
+++ b/plat/common/arm/time.c
@@ -39,9 +39,13 @@
 #include <uk/bitops.h>
 #include <cpu.h>
 
+/* TODO: For now this file is KVM dependent. As soon as we have more
+ * Arm platforms that are using this file, we need to introduce a
+ * portable way to handover the DTB entry point to common platform code */
+#include <kvm/config.h>
+
 static uint64_t boot_ticks;
 static uint32_t counter_freq;
-extern void *_libkvmplat_dtb;
 
 /*
  * Shift factor for counter scaling multiplier; referred to as S in the
@@ -73,17 +77,18 @@ static uint32_t get_counter_frequency(void)
        const uint64_t *fdt_freq;
 
        /* Try to find arm,armv8-timer first */
-       fdt_archtimer = fdt_node_offset_by_compatible(_libkvmplat_dtb,
+       fdt_archtimer = fdt_node_offset_by_compatible(_libkvmplat_cfg.dtb,
                                                -1, "arm,armv8-timer");
        /* If failed, try to find arm,armv7-timer */
        if (fdt_archtimer < 0)
-               fdt_archtimer = fdt_node_offset_by_compatible(_libkvmplat_dtb,
+               fdt_archtimer = fdt_node_offset_by_compatible(
+                                                       _libkvmplat_cfg.dtb,
                                                        -1, "arm,armv7-timer");
        /* DT doesn't provide arch timer information */
        if (fdt_archtimer < 0)
                goto endnofreq;
 
-       fdt_freq = fdt_getprop(_libkvmplat_dtb,
+       fdt_freq = fdt_getprop(_libkvmplat_cfg.dtb,
                        fdt_archtimer, "clock-frequency", &len);
        if (!fdt_freq || (len <= 0)) {
                uk_pr_info("No clock-frequency found, reading from register 
directly.\n");
diff --git a/plat/kvm/arm/setup.c b/plat/kvm/arm/setup.c
index 15a884a2..301b5a14 100644
--- a/plat/kvm/arm/setup.c
+++ b/plat/kvm/arm/setup.c
@@ -21,16 +21,13 @@
 #include <libfdt.h>
 #include <sections.h>
 #include <kvm/console.h>
+#include <kvm/config.h>
 #include <uk/assert.h>
 #include <kvm-arm/mm.h>
 #include <arm/cpu.h>
 #include <uk/arch/limits.h>
 
-void *_libkvmplat_pagetable;
-void *_libkvmplat_heap_start;
-void *_libkvmplat_stack_top;
-void *_libkvmplat_mem_end;
-void *_libkvmplat_dtb;
+struct kvmplat_config _libkvmplat_cfg = { 0 };
 
 #define MAX_CMDLINE_SIZE 1024
 static char cmdline[MAX_CMDLINE_SIZE];
@@ -47,7 +44,7 @@ static void _init_dtb(void *dtb_pointer)
        if ((ret = fdt_check_header(dtb_pointer)))
                UK_CRASH("Invalid DTB: %s\n", fdt_strerror(ret));
 
-       _libkvmplat_dtb = dtb_pointer;
+       _libkvmplat_cfg.dtb = dtb_pointer;
        uk_pr_info("Found device tree on: %p\n", dtb_pointer);
 }
 
@@ -60,17 +57,17 @@ static void _dtb_get_psci_method(void)
         * We just support PSCI-0.2 and PSCI-1.0, the PSCI-0.1 would not
         * be supported.
         */
-       fdtpsci = fdt_node_offset_by_compatible(_libkvmplat_dtb,
+       fdtpsci = fdt_node_offset_by_compatible(_libkvmplat_cfg.dtb,
                                                -1, "arm,psci-1.0");
        if (fdtpsci < 0)
-               fdtpsci = fdt_node_offset_by_compatible(_libkvmplat_dtb,
+               fdtpsci = fdt_node_offset_by_compatible(_libkvmplat_cfg.dtb,
                                                        -1, "arm,psci-0.2");
        if (fdtpsci < 0) {
                uk_pr_info("No PSCI conduit found in DTB\n");
                goto enomethod;
        }
 
-       fdtmethod = fdt_getprop(_libkvmplat_dtb, fdtpsci, "method", &len);
+       fdtmethod = fdt_getprop(_libkvmplat_cfg.dtb, fdtpsci, "method", &len);
        if (!fdtmethod || (len <= 0)) {
                uk_pr_info("No PSCI method found\n");
                goto enomethod;
@@ -102,10 +99,10 @@ static void _init_dtb_mem(void)
        uint64_t mem_base, mem_size, max_addr;
 
        /* search for assigned VM memory in DTB */
-       if (fdt_num_mem_rsv(_libkvmplat_dtb) != 0)
+       if (fdt_num_mem_rsv(_libkvmplat_cfg.dtb) != 0)
                uk_pr_warn("Reserved memory is not supported\n");
 
-       fdt_mem = fdt_node_offset_by_prop_value(_libkvmplat_dtb, -1,
+       fdt_mem = fdt_node_offset_by_prop_value(_libkvmplat_cfg.dtb, -1,
                                                "device_type",
                                                "memory", sizeof("memory"));
        if (fdt_mem < 0) {
@@ -113,11 +110,11 @@ static void _init_dtb_mem(void)
                return;
        }
 
-       naddr = fdt_address_cells(_libkvmplat_dtb, fdt_mem);
+       naddr = fdt_address_cells(_libkvmplat_cfg.dtb, fdt_mem);
        if (naddr < 0 || naddr >= FDT_MAX_NCELLS)
                UK_CRASH("Could not find proper address cells!\n");
 
-       nsize = fdt_size_cells(_libkvmplat_dtb, fdt_mem);
+       nsize = fdt_size_cells(_libkvmplat_cfg.dtb, fdt_mem);
        if (nsize < 0 || nsize >= FDT_MAX_NCELLS)
                UK_CRASH("Could not find proper size cells!\n");
 
@@ -125,7 +122,7 @@ static void _init_dtb_mem(void)
         * QEMU will always provide us at least one bank of memory.
         * unikraft will use the first bank for the time-being.
         */
-       regs = fdt_getprop(_libkvmplat_dtb, fdt_mem, "reg", &prop_len);
+       regs = fdt_getprop(_libkvmplat_cfg.dtb, fdt_mem, "reg", &prop_len);
 
        /*
         * The property must contain at least the start address
@@ -145,12 +142,28 @@ static void _init_dtb_mem(void)
                UK_CRASH("Fatal: Image outside of RAM\n");
 
        max_addr = mem_base + mem_size;
-       _libkvmplat_pagetable = (void *) ALIGN_DOWN((size_t)__END, __PAGE_SIZE);
-       _libkvmplat_heap_start = _libkvmplat_pagetable + page_table_size;
-       _libkvmplat_mem_end = (void *) max_addr;
+       _libkvmplat_cfg.pagetable.start = ALIGN_DOWN((uintptr_t)__END,
+                                                    __PAGE_SIZE);
+       _libkvmplat_cfg.pagetable.len   = ALIGN_UP(page_table_size,
+                                                  __PAGE_SIZE);
+       _libkvmplat_cfg.pagetable.end   = _libkvmplat_cfg.pagetable.start
+                                         + _libkvmplat_cfg.pagetable.len;
 
        /* AArch64 require stack be 16-bytes alignment by default */
-       _libkvmplat_stack_top = (void *) ALIGN_UP(max_addr, __STACK_ALIGN_SIZE);
+       _libkvmplat_cfg.bstack.end   = ALIGN_DOWN(max_addr,
+                                                 __STACK_ALIGN_SIZE);
+       _libkvmplat_cfg.bstack.len   = ALIGN_UP(__STACK_SIZE,
+                                               __STACK_ALIGN_SIZE);
+       _libkvmplat_cfg.bstack.start = _libkvmplat_cfg.bstack.end
+                                      - _libkvmplat_cfg.bstack.len;
+
+       _libkvmplat_cfg.heap.start = _libkvmplat_cfg.pagetable.end;
+       _libkvmplat_cfg.heap.end   = _libkvmplat_cfg.bstack.start;
+       _libkvmplat_cfg.heap.len   = _libkvmplat_cfg.heap.end
+                                    - _libkvmplat_cfg.heap.start;
+
+       if (_libkvmplat_cfg.heap.start > _libkvmplat_cfg.heap.end)
+               UK_CRASH("Not enough memory, giving up...\n");
 }
 
 static void _dtb_get_cmdline(char *cmdline, size_t maxlen)
@@ -159,10 +172,11 @@ static void _dtb_get_cmdline(char *cmdline, size_t maxlen)
        const char *fdtcmdline;
 
        /* TODO: Proper error handling */
-       fdtchosen = fdt_path_offset(_libkvmplat_dtb, "/chosen");
+       fdtchosen = fdt_path_offset(_libkvmplat_cfg.dtb, "/chosen");
        if (!fdtchosen)
                goto enocmdl;
-       fdtcmdline = fdt_getprop(_libkvmplat_dtb, fdtchosen, "bootargs", &len);
+       fdtcmdline = fdt_getprop(_libkvmplat_cfg.dtb, fdtchosen, "bootargs",
+                                &len);
        if (!fdtcmdline || (len <= 0))
                goto enocmdl;
 
@@ -200,16 +214,19 @@ void _libkvmplat_start(void *dtb_pointer)
        /* Initialize memory from DTB */
        _init_dtb_mem();
 
-       uk_pr_info("pagetable start: %p\n", _libkvmplat_pagetable);
-       uk_pr_info("     heap start: %p\n", _libkvmplat_heap_start);
-       uk_pr_info("      stack top: %p\n", _libkvmplat_stack_top);
+       uk_pr_info("pagetable start: %p\n",
+                  (void *) _libkvmplat_cfg.pagetable.start);
+       uk_pr_info("     heap start: %p\n",
+                  (void *) _libkvmplat_cfg.heap.start);
+       uk_pr_info("      stack top: %p\n",
+                  (void *) _libkvmplat_cfg.bstack.start);
 
        /*
         * Switch away from the bootstrap stack as early as possible.
         */
        uk_pr_info("Switch from bootstrap stack to stack @%p\n",
-                  _libkvmplat_stack_top);
+                  (void *) _libkvmplat_cfg.bstack.end);
 
-       _libkvmplat_newstack((uint64_t) _libkvmplat_stack_top,
+       _libkvmplat_newstack((uint64_t) _libkvmplat_cfg.bstack.end,
                                _libkvmplat_entry2, NULL);
 }
diff --git a/plat/kvm/include/kvm/config.h b/plat/kvm/include/kvm/config.h
new file mode 100644
index 00000000..ee82731b
--- /dev/null
+++ b/plat/kvm/include/kvm/config.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
+ *          Wei Chen <Wei.Chen@xxxxxxx>
+ *
+ * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation,
+ *                     All rights reserved.
+ * Copyright (c) 2018, Arm Ltd., All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+
+#ifndef __KVM_CONFIG_H__
+#define __KVM_CONFIG_H__
+
+#include <inttypes.h>
+#include <sys/types.h>
+
+struct kvmplat_config_memregion {
+       uintptr_t start;
+       uintptr_t end;
+       size_t len;
+};
+
+struct kvmplat_config {
+       struct kvmplat_config_memregion heap;
+       struct kvmplat_config_memregion bstack;
+
+#ifdef CONFIG_ARCH_ARM_64
+       struct kvmplat_config_memregion pagetable;
+       void *dtb;
+#endif
+};
+
+/* Initialized and defined in setup.c */
+extern struct kvmplat_config _libkvmplat_cfg;
+
+#endif /* __KVM_CONFIG_H__ */
diff --git a/plat/kvm/memory.c b/plat/kvm/memory.c
index e45b88c5..d8293293 100644
--- a/plat/kvm/memory.c
+++ b/plat/kvm/memory.c
@@ -23,13 +23,7 @@
 #include <sys/types.h>
 #include <uk/plat/memory.h>
 #include <uk/assert.h>
-
-/*
- * Provided by setup.c
- */
-extern void *_libkvmplat_heap_start;
-extern void *_libkvmplat_stack_top;
-extern void *_libkvmplat_mem_end;
+#include <kvm/config.h>
 
 int ukplat_memregion_count(void)
 {
@@ -118,9 +112,8 @@ int ukplat_memregion_get(int i, struct 
ukplat_memregion_desc *m)
                ret = 0;
                break;
        case 7: /* heap */
-               m->base  = _libkvmplat_heap_start;
-               m->len   = (size_t) _libkvmplat_stack_top
-                          - (size_t) _libkvmplat_heap_start;
+               m->base  = (void *) _libkvmplat_cfg.heap.start;
+               m->len   = _libkvmplat_cfg.heap.len;
                m->flags = UKPLAT_MEMRF_ALLOCATABLE;
 #if CONFIG_UKPLAT_MEMRNAME
                m->name  = "heap";
@@ -128,9 +121,8 @@ int ukplat_memregion_get(int i, struct 
ukplat_memregion_desc *m)
                ret = 0;
                break;
        case 8: /* stack */
-               m->base  = _libkvmplat_stack_top;
-               m->len   = (size_t) _libkvmplat_mem_end
-                          - (size_t) _libkvmplat_stack_top;
+               m->base  = (void *) _libkvmplat_cfg.bstack.start;
+               m->len   = _libkvmplat_cfg.bstack.len;
                m->flags = (UKPLAT_MEMRF_RESERVED
                            | UKPLAT_MEMRF_READABLE
                            | UKPLAT_MEMRF_WRITABLE);
diff --git a/plat/kvm/x86/setup.c b/plat/kvm/x86/setup.c
index df25592f..c3959c40 100644
--- a/plat/kvm/x86/setup.c
+++ b/plat/kvm/x86/setup.c
@@ -30,6 +30,7 @@
 #include <sections.h>
 #include <x86/cpu.h>
 #include <x86/traps.h>
+#include <kvm/config.h>
 #include <kvm/console.h>
 #include <kvm/intctrl.h>
 #include <kvm-x86/multiboot.h>
@@ -46,12 +47,10 @@
 #define MAX_CMDLINE_SIZE 8192
 static char cmdline[MAX_CMDLINE_SIZE];
 
-void *_libkvmplat_heap_start;
-void *_libkvmplat_stack_top;
-void *_libkvmplat_mem_end;
+struct kvmplat_config _libkvmplat_cfg = { 0 };
 
-extern void _libkvmplat_newstack(__u64 stack_start, void (*tramp)(void *),
-                               void *arg);
+extern void _libkvmplat_newstack(uintptr_t stack_start, void (*tramp)(void *),
+                                void *arg);
 
 static inline void _mb_get_cmdline(struct multiboot_info *mi)
 {
@@ -99,11 +98,21 @@ static inline void _mb_init_mem(struct multiboot_info *mi)
        max_addr = m->addr + m->len;
        if (max_addr > PLATFORM_MAX_MEM_ADDR)
                max_addr = PLATFORM_MAX_MEM_ADDR;
-       UK_ASSERT((size_t)__END <= max_addr);
+       UK_ASSERT((size_t) __END <= max_addr);
 
-       _libkvmplat_heap_start = (void *) ALIGN_UP((size_t)__END, __PAGE_SIZE);
-       _libkvmplat_mem_end    = (void *) max_addr;
-       _libkvmplat_stack_top  = (void *) (max_addr - __STACK_SIZE);
+       /*
+        * Reserve space for boot stack at the end of found memory
+        */
+       if ((max_addr - m->addr) < __STACK_SIZE)
+               UK_CRASH("Not enough memory to allocate boot stack\n");
+
+       _libkvmplat_cfg.heap.start = ALIGN_UP((uintptr_t) __END, __PAGE_SIZE);
+       _libkvmplat_cfg.heap.end   = (uintptr_t) max_addr - __STACK_SIZE;
+       _libkvmplat_cfg.heap.len   = _libkvmplat_cfg.heap.end
+                                    - _libkvmplat_cfg.heap.start;
+       _libkvmplat_cfg.bstack.start = _libkvmplat_cfg.heap.end;
+       _libkvmplat_cfg.bstack.end   = max_addr;
+       _libkvmplat_cfg.bstack.len   = __STACK_SIZE;
 }
 
 static void _libkvmplat_entry2(void *arg __attribute__((unused)))
@@ -130,14 +139,16 @@ void _libkvmplat_entry(void *arg)
        _mb_get_cmdline(mi);
        _mb_init_mem(mi);
 
-       uk_pr_info("    heap start: %p\n", _libkvmplat_heap_start);
-       uk_pr_info("     stack top: %p\n", _libkvmplat_stack_top);
+       uk_pr_info("    heap start: %p\n",
+                  (void *) _libkvmplat_cfg.heap.start);
+       uk_pr_info("     stack top: %p\n",
+                  (void *) _libkvmplat_cfg.bstack.start);
 
        /*
         * Switch away from the bootstrap stack as early as possible.
         */
        uk_pr_info("Switch from bootstrap stack to stack @%p\n",
-                  _libkvmplat_mem_end);
-       _libkvmplat_newstack((__u64) _libkvmplat_mem_end,
-                               _libkvmplat_entry2, 0);
+                  (void *) _libkvmplat_cfg.bstack.end);
+       _libkvmplat_newstack(_libkvmplat_cfg.bstack.end,
+                            _libkvmplat_entry2, 0);
 }
-- 
2.20.1


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.