From 75b139ff9b51040615599b12a162dab865b3faac Mon Sep 17 00:00:00 2001 From: Jakub Jermar Date: Sun, 28 Aug 2016 15:42:19 +0200 Subject: [PATCH] Add skeleton of the user backend --- kernel/Makefile | 1 + kernel/generic/include/mm/as.h | 11 +++ kernel/generic/src/mm/as.c | 11 ++- kernel/generic/src/mm/backend_user.c | 145 +++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 kernel/generic/src/mm/backend_user.c diff --git a/kernel/Makefile b/kernel/Makefile index 0d6c837bd..bd88aabd1 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -236,6 +236,7 @@ GENERIC_SOURCES = \ generic/src/mm/backend_anon.c \ generic/src/mm/backend_elf.c \ generic/src/mm/backend_phys.c \ + generic/src/mm/backend_user.c \ generic/src/mm/slab.c \ generic/src/lib/func.c \ generic/src/lib/memstr.c \ diff --git a/kernel/generic/include/mm/as.h b/kernel/generic/include/mm/as.h index 7c9dfea6e..052c90f90 100644 --- a/kernel/generic/include/mm/as.h +++ b/kernel/generic/include/mm/as.h @@ -168,6 +168,10 @@ struct mem_backend; /** Backend data stored in address space area. */ typedef union mem_backend_data { + /* anon_backend members */ + struct { + }; + /** elf_backend members */ struct { elf_header_t *elf; @@ -180,6 +184,12 @@ typedef union mem_backend_data { size_t frames; bool anonymous; }; + + /** user_backend members */ + struct { + int pager; /**< Phone to the pager. */ + }; + } mem_backend_data_t; /** Address space area structure. @@ -295,6 +305,7 @@ extern void as_deinstall_arch(as_t *); extern mem_backend_t anon_backend; extern mem_backend_t elf_backend; extern mem_backend_t phys_backend; +extern mem_backend_t user_backend; /* Address space area related syscalls. */ extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int, uintptr_t, diff --git a/kernel/generic/src/mm/as.c b/kernel/generic/src/mm/as.c index f91a86239..d6436e55b 100644 --- a/kernel/generic/src/mm/as.c +++ b/kernel/generic/src/mm/as.c @@ -2185,8 +2185,17 @@ sysarg_t sys_as_area_create(uintptr_t base, size_t size, unsigned int flags, uintptr_t bound, int pager) { uintptr_t virt = base; + mem_backend_t *backend; + mem_backend_data_t backend_data; + + if (pager == AS_AREA_UNPAGED) + backend = &anon_backend; + else { + backend = &user_backend; + backend_data.pager = pager; + } as_area_t *area = as_area_create(AS, flags, size, - AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, bound); + AS_AREA_ATTR_NONE, backend, &backend_data, &virt, bound); if (area == NULL) return (sysarg_t) AS_MAP_FAILED; diff --git a/kernel/generic/src/mm/backend_user.c b/kernel/generic/src/mm/backend_user.c new file mode 100644 index 000000000..8afb98d88 --- /dev/null +++ b/kernel/generic/src/mm/backend_user.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2016 Jakub Jermar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - 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. + * - The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/** @addtogroup genericmm + * @{ + */ + +/** + * @file + * @brief Backend for address space areas backed by the user pager. + * + */ + +#include +#include +#include +#include +#include +#include + +static bool user_create(as_area_t *); +static bool user_resize(as_area_t *, size_t); +static void user_share(as_area_t *); +static void user_destroy(as_area_t *); + +static bool user_is_resizable(as_area_t *); +static bool user_is_shareable(as_area_t *); + +static int user_page_fault(as_area_t *, uintptr_t, pf_access_t); +static void user_frame_free(as_area_t *, uintptr_t, uintptr_t); + +mem_backend_t user_backend = { + .create = user_create, + .resize = user_resize, + .share = user_share, + .destroy = user_destroy, + + .is_resizable = user_is_resizable, + .is_shareable = user_is_shareable, + + .page_fault = user_page_fault, + .frame_free = user_frame_free, + + .create_shared_data = NULL, + .destroy_shared_data = NULL +}; + +bool user_create(as_area_t *area) +{ + return true; +} + +bool user_resize(as_area_t *area, size_t new_pages) +{ + return true; +} + +/** Share the user-paged address space area. + * + * The address space and address space area must be already locked. + * + * @param area Address space area to be shared. + */ +void user_share(as_area_t *area) +{ + ASSERT(mutex_locked(&area->as->lock)); + ASSERT(mutex_locked(&area->lock)); +} + +void user_destroy(as_area_t *area) +{ + return; +} + +bool user_is_resizable(as_area_t *area) +{ + return true; +} + +bool user_is_shareable(as_area_t *area) +{ + return true; +} + +/** Service a page fault in the user-paged address space area. + * + * The address space area and page tables must be already locked. + * + * @param area Pointer to the address space area. + * @param upage Faulting virtual page. + * @param access Access mode that caused the fault (i.e. read/write/exec). + * + * @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. + * serviced). + */ +int user_page_fault(as_area_t *area, uintptr_t upage, pf_access_t access) +{ + ASSERT(page_table_locked(AS)); + ASSERT(mutex_locked(&area->lock)); + ASSERT(IS_ALIGNED(upage, PAGE_SIZE)); + + return AS_PF_FAULT; +} + +/** Free a frame that is backed by the user memory backend. + * + * The address space area and page tables must be already locked. + * + * @param area Ignored. + * @param page Virtual address of the page corresponding to the frame. + * @param frame Frame to be released. + */ +void user_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame) +{ + ASSERT(page_table_locked(area->as)); + ASSERT(mutex_locked(&area->lock)); +} + +/** @} + */ -- 2.11.4.GIT