[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v4 4/4] lib/ukmmap: mmap trick for Go
Signed-off-by: Charalampos Mainas <Charalampos.Mainas@xxxxxxxxx> --- lib/ukmmap/Makefile.uk | 2 + lib/ukmmap/exportsyms.uk | 3 +- lib/ukmmap/mmap.c | 166 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 lib/ukmmap/mmap.c diff --git a/lib/ukmmap/Makefile.uk b/lib/ukmmap/Makefile.uk index 8ac3ab3c..71ff432f 100644 --- a/lib/ukmmap/Makefile.uk +++ b/lib/ukmmap/Makefile.uk @@ -1 +1,3 @@ $(eval $(call addlib_s,libukmmap,$(CONFIG_LIBUKMMAP))) + +LIBUKMMAP_SRCS-y += $(LIBUKMMAP_BASE)/mmap.c diff --git a/lib/ukmmap/exportsyms.uk b/lib/ukmmap/exportsyms.uk index 621e94f0..a31c636b 100644 --- a/lib/ukmmap/exportsyms.uk +++ b/lib/ukmmap/exportsyms.uk @@ -1 +1,2 @@ -none +mmap +munmap diff --git a/lib/ukmmap/mmap.c b/lib/ukmmap/mmap.c new file mode 100644 index 00000000..4e24f379 --- /dev/null +++ b/lib/ukmmap/mmap.c @@ -0,0 +1,166 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * + * Authors: Charalampos Mainas <charalampos.mainas@xxxxxxxxx> + * + * + * Copyright (c) 2019, NEC Europe Ltd., NEC Corporation. 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. + */ + +#include <sys/mman.h> +#include <uk/alloc.h> +#include <string.h> + +struct mmap_addr { + void *begin; + void *end; + struct mmap_addr *next; +}; + +static struct mmap_addr *mmap_addr; + +/** + * This is not a correct implementation of mmap. It is just a trick that works + * for Go but it needs to be revisited. Instead of mapping, it allocates len + * bytes of memory and stores the beginninig and the end of that memory chunk + * in struct mmap_addr. At first it checks if addr belongs to one of the memory + * chunks that have been allocated in a previous call of mmap. If that is the + * case addr is the return value. Otherwise a new memory block is allocated and + * the return value is a pointer to the beginninig of that block. + * + * Go uses mmap always with: + * @prot = either PROT_NONE or PROT_READ|PROT_WRITE, + * @flags = as MAP_ANON|MAP_PRIVATE, or MAP_FIXED|MAP_ANON|MAP_PRIVATE + * or MAP_NORESERVE|MAP_ANON|MAP_PRIVATE + * @fildes = -1 + * @off = 0 + * + */ + +void *mmap(void *addr, size_t len, int prot, + int flags, int fildes, off_t off) +{ + struct mmap_addr *tmp = mmap_addr, *last = NULL, *new = NULL; + + if (!len) { + errno = EINVAL; + return (void *) -1; + } + + /* Check if parameters match the ones that go use + * Otherwise return 0 (unimplemented mmap) + */ + if (fildes != -1 || off) + return 0; + if (!(prot & (PROT_READ|PROT_WRITE)) && (prot != 0)) + return 0; + if (!(flags & (MAP_ANON|MAP_PRIVATE)) && + !(flags & (MAP_FIXED|MAP_ANON|MAP_PRIVATE)) && + !(flags & (MAP_NORESERVE|MAP_ANON|MAP_PRIVATE))) + return 0; + + while (tmp) { + if (addr) { + if (addr >= tmp->begin && addr < tmp->end) + return addr; + } + last = tmp; + tmp = tmp->next; + } + void *mem = uk_malloc(uk_alloc_get_default(), len); + + if (!mem) { + errno = ENOMEM; + return (void *) -1; + } + new = uk_malloc(uk_alloc_get_default(), sizeof(struct mmap_addr)); + new->begin = mem; + new->end = mem + len; + new->next = NULL; + if (!mmap_addr) + mmap_addr = new; + else + last->next = new; + return mem; +} + +/* + * munmap frees len bytes os memory starting from addr. + * addr needs to be a pointer to a memory block that has been allocated from + * mmap. If len has the same value with the size of the memory block that has + * been allocated from mmap the struct mmap_addr counterpart is destroyed. + * Otherwise the initial memory block is replaced by a smaller one. + */ + +int munmap(void *addr, size_t len) +{ + struct mmap_addr *tmp = mmap_addr, *prev = NULL; + size_t remain_mem; + + if (!len) { + errno = EINVAL; + return -1; + } + if (!addr) + return 0; + while (tmp) { + if (addr != tmp->begin) { + if (tmp->end > addr + len) { + errno = EINVAL; + return -1; + } + remain_mem = tmp->end - addr - len; + if (remain_mem) { + + void *mem = uk_malloc(uk_alloc_get_default(), + remain_mem); + if (!mem) { + errno = ENOMEM; + return -1; + } + memcpy(mem, addr+len, remain_mem); + tmp->begin = mem; + } else { + + if (!prev) + mmap_addr = tmp->next; + else + prev->next = tmp->next; + uk_free(uk_alloc_get_default(), tmp); + } + uk_free(uk_alloc_get_default(), addr); + return 0; + } + prev = tmp; + tmp = tmp->next; + } + /* unimplemented munmap */ + return 0; +} -- 2.17.1 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |