locked paging for thread safety? hope this suffices

This commit is contained in:
Sparchatus 2022-04-06 12:35:00 +00:00
parent c96e6bcf66
commit 3c8987f5f3
2 changed files with 92 additions and 39 deletions

View File

@ -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;
};

View File

@ -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,18 +628,30 @@ 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[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,
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;
@ -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;
}