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

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



Hi Simon,

This patch looks good.

Reviewed-by: Felipe Huici <felipe.huici@xxxxxxxxx>

-- Felipe

On 09.05.19, 16:27, "Simon Kuenzer" <simon.kuenzer@xxxxxxxxx> wrote:

    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®.