diff --git a/include/aos/paging_types.h b/include/aos/paging_types.h index a7ed8b0..c18a81e 100644 --- a/include/aos/paging_types.h +++ b/include/aos/paging_types.h @@ -80,6 +80,9 @@ struct paging_state { uint8_t refilling; struct pt_vaddr_reg_t vaddr_head; + + // mutex to protect operations + struct thread_mutex lock; }; diff --git a/lib/aos/paging.c b/lib/aos/paging.c index 324920c..5a9e286 100644 --- a/lib/aos/paging.c +++ b/lib/aos/paging.c @@ -134,6 +134,8 @@ static errval_t pt_alloc_level(struct paging_state *st, struct capref *pt_cap, u } void pt_print_state(struct paging_state *st) { + thread_mutex_lock_nested(&st->lock); + // iterates over all the page table entries and prints them debug_printf("L0\n"); if(st->l0_pt.children == NULL) return; @@ -167,6 +169,8 @@ void pt_print_state(struct paging_state *st) { debug_printf("- base=%lu, size=%lu, %s\n", reg->base, reg->size, reg->free ? "free" : "in use"); reg = reg->next; } + + thread_mutex_unlock(&st->lock); } // NOTE rueegges: each paging fixed call can use up to 4 pt slabs, up to 3 children slabs and up to 7 slots @@ -344,6 +348,9 @@ errval_t paging_init_state(struct paging_state *st, lvaddr_t start_vaddr, st->slot_alloc = ca; st->refilling = 0; + // initialize paging lock + thread_mutex_init(&st->lock); + return SYS_ERR_OK; } @@ -526,19 +533,7 @@ static errval_t paging_insert_vaddr_reg(struct paging_state *st, struct pt_vaddr return SYS_ERR_OK; } - -/** - * @brief Find a free region of virtual address space that is large enough to accomodate a - * buffer of size 'bytes'. - * - * @param[in] st A pointer to the paging state to allocate from - * @param[out] buf Returns the free virtual address that was found. - * @param[in] bytes The requested (minimum) size of the region to allocate - * @param[in] alignment The address needs to be a multiple of 'alignment'. - * - * @return Either SYS_ERR_OK if no error occured or an error indicating what went wrong otherwise. - */ -errval_t paging_alloc(struct paging_state *st, void **buf, size_t bytes, size_t alignment) +static errval_t _paging_alloc(struct paging_state *st, void **buf, size_t bytes, size_t alignment) { errval_t err; @@ -585,20 +580,29 @@ errval_t paging_alloc(struct paging_state *st, void **buf, size_t bytes, size_t return LIB_ERR_OUT_OF_VIRTUAL_ADDR; } - /** - * \brief Finds a free virtual address and maps `bytes` of the supplied frame at that address + * @brief Find a free region of virtual address space that is large enough to accomodate a + * buffer of size 'bytes'. * - * @param[in] st the paging state to create the mapping in - * @param[out] buf returns the virtual address at which this frame has been mapped. - * @param[in] bytes the number of bytes to map. - * @param[in] frame the frame capability to be mapped - * @param[in] flags The flags that are to be set for the newly mapped region, - * see 'paging_flags_t' in paging_types.h . + * @param[in] st A pointer to the paging state to allocate from + * @param[out] buf Returns the free virtual address that was found. + * @param[in] bytes The requested (minimum) size of the region to allocate + * @param[in] alignment The address needs to be a multiple of 'alignment'. * * @return Either SYS_ERR_OK if no error occured or an error indicating what went wrong otherwise. */ -errval_t paging_map_frame_attr(struct paging_state *st, void **buf, size_t bytes, +errval_t paging_alloc(struct paging_state *st, void **buf, size_t bytes, size_t alignment) +{ + errval_t err; + + thread_mutex_lock_nested(&st->lock); + err = _paging_alloc(st, buf, bytes, alignment); + thread_mutex_unlock(&st->lock); + + return err; +} + +static errval_t _paging_map_frame_attr(struct paging_state *st, void **buf, size_t bytes, struct capref frame, int flags) { errval_t err; @@ -624,21 +628,33 @@ errval_t paging_map_frame_attr(struct paging_state *st, void **buf, size_t bytes } /** - * @brief mapps the provided frame at the supplied address in the paging state + * \brief Finds a free virtual address and maps `bytes` of the supplied frame at that address * - * @param[in] st the paging state to create the mapping in - * @param[in] vaddr the virtual address to create the mapping at - * @param[in] frame the frame to map in - * @param[in] bytes the number of bytes that will be mapped. - * @param[in] flags The flags that are to be set for the newly mapped region, - * see 'paging_flags_t' in paging_types.h . + * @param[in] st the paging state to create the mapping in + * @param[out] buf returns the virtual address at which this frame has been mapped. + * @param[in] bytes the number of bytes to map. + * @param[in] frame the frame capability to be mapped + * @param[in] flags The flags that are to be set for the newly mapped region, + * see 'paging_flags_t' in paging_types.h . * - * @return SYS_ERR_OK on success. + * @return Either SYS_ERR_OK if no error occured or an error indicating what went wrong otherwise. */ -errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr, - struct capref frame, size_t bytes, int flags) +errval_t paging_map_frame_attr(struct paging_state *st, void **buf, size_t bytes, + struct capref frame, int flags) { errval_t err; + + thread_mutex_lock_nested(&st->lock); + err = _paging_map_frame_attr(st, buf, bytes, frame, flags); + thread_mutex_unlock(&st->lock); + + return err; +} + +static errval_t _paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr, + struct capref frame, size_t bytes, int flags) +{ + errval_t err; /* * (M1): * - Map a frame assuming all mappings will fit into one leaf page table (L3) @@ -783,18 +799,31 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr, return SYS_ERR_OK; } - /** - * @brief Unmaps the region starting at the supplied pointer. + * @brief mapps the provided frame at the supplied address in the paging state * * @param[in] st the paging state to create the mapping in - * @param[in] region starting address of the region to unmap + * @param[in] vaddr the virtual address to create the mapping at + * @param[in] frame the frame to map in + * @param[in] bytes the number of bytes that will be mapped. + * @param[in] flags The flags that are to be set for the newly mapped region, + * see 'paging_flags_t' in paging_types.h . * - * @return SYS_ERR_OK on success, or error code indicating the kind of failure - * - * The supplied `region` must be the start of a previously mapped frame. + * @return SYS_ERR_OK on success. */ -errval_t paging_unmap(struct paging_state *st, const void *region) +errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr, + struct capref frame, size_t bytes, int flags) +{ + errval_t err; + + thread_mutex_lock_nested(&st->lock); + err = _paging_map_fixed_attr(st, vaddr, frame, bytes, flags); + thread_mutex_unlock(&st->lock); + + return err; +} + +static errval_t _paging_unmap(struct paging_state *st, const void *region) { errval_t err; lvaddr_t vaddr = (lvaddr_t)region; @@ -866,3 +895,24 @@ errval_t paging_unmap(struct paging_state *st, const void *region) return SYS_ERR_OK; } + +/** + * @brief Unmaps the region starting at the supplied pointer. + * + * @param[in] st the paging state to create the mapping in + * @param[in] region starting address of the region to unmap + * + * @return SYS_ERR_OK on success, or error code indicating the kind of failure + * + * The supplied `region` must be the start of a previously mapped frame. + */ +errval_t paging_unmap(struct paging_state *st, const void *region) +{ + errval_t err; + + thread_mutex_lock_nested(&st->lock); + err = _paging_unmap(st, region); + thread_mutex_unlock(&st->lock); + + return err; +}