aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-07-06 18:14:04 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-07-06 18:14:04 +0300
commit76517486919657ecadda9867125dc6730f29a5b7 (patch)
tree02d975db2b911ec7b92c4b1be7c5a2510b418ae1 /include
parent608f44306a6f0d5692f5c81bcbfe7a621ec254ba (diff)
downloadkmi-76517486919657ecadda9867125dc6730f29a5b7.tar.gz
kmi-76517486919657ecadda9867125dc6730f29a5b7.zip
pretty massive virtual memory rewrite
+ The system is now a bit simpler and hopefully easier to understand, while also extending the shared memory to be 1:N, where there is one owner who may become a zombie while waiting for the N to die.
Diffstat (limited to 'include')
-rw-r--r--include/arch/proc.h2
-rw-r--r--include/arch/vmem.h7
-rw-r--r--include/kmi/bkl.h12
-rw-r--r--include/kmi/caps.h3
-rw-r--r--include/kmi/mem.h7
-rw-r--r--include/kmi/mem_nodes.h42
-rw-r--r--include/kmi/orphanage.h2
-rw-r--r--include/kmi/regions.h (renamed from include/kmi/mem_regions.h)161
-rw-r--r--include/kmi/syscalls.h6
-rw-r--r--include/kmi/tcb.h22
-rw-r--r--include/kmi/uapi.h24
-rw-r--r--include/kmi/vmem.h189
12 files changed, 169 insertions, 308 deletions
diff --git a/include/arch/proc.h b/include/arch/proc.h
index 429f688..61a30c4 100644
--- a/include/arch/proc.h
+++ b/include/arch/proc.h
@@ -91,7 +91,7 @@ void load_regs(void *p, struct tcb *t);
* @param d Destination.
* @param s Source.
*/
-void clone_regs(struct tcb *d, struct tcb *s);
+void copy_regs(struct tcb *d, struct tcb *s);
/**
* Do modifications to \ref tcb state if necessary for ipis to work.
diff --git a/include/arch/vmem.h b/include/arch/vmem.h
index 8f94e07..6e761b6 100644
--- a/include/arch/vmem.h
+++ b/include/arch/vmem.h
@@ -17,6 +17,7 @@
#endif
#include <kmi/types.h>
+#include <kmi/attrs.h>
/**
* Map one virtual page to physical page.
@@ -161,17 +162,15 @@ struct vmem *create_vmem();
* Jump into virtual memory context.
*
* @param b Virtual memory to jump into.
- * @return \ref OK.
*/
-stat_t use_vmem(struct vmem *b);
+void use_vmem(struct vmem *b);
/**
* Destroy virtual memory space.
*
* @param b Virtual memory to destroy.
- * @return \ref OK.
*/
-stat_t destroy_vmem(struct vmem *b);
+void destroy_vmem(struct vmem *b);
/**
* Raw clone user virtual memory.
diff --git a/include/kmi/bkl.h b/include/kmi/bkl.h
index 26dfaa8..9ea6ccd 100644
--- a/include/kmi/bkl.h
+++ b/include/kmi/bkl.h
@@ -1,15 +1,27 @@
+/* SPDX-License-Identifier: copyleft-next-0.3.1 */
+/* Copyright 2024, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
+
#ifndef KMI_BKL_H
#define KMI_BKL_H
+/**
+ * @file bkl.h
+ *
+ * Stuff for handling the Big Kernel Lock.
+ */
+
#include <kmi/lock.h>
+/** Big Kenrel Lock. */
extern spinlock_t bkl;
+/** Lock the Big Kernel Lock. */
static inline void bkl_lock()
{
spin_lock(&bkl);
}
+/** Unlock the Big Kernel Lock. */
static inline void bkl_unlock()
{
spin_unlock(&bkl);
diff --git a/include/kmi/caps.h b/include/kmi/caps.h
index 158845d..02f6b3e 100644
--- a/include/kmi/caps.h
+++ b/include/kmi/caps.h
@@ -40,6 +40,9 @@ enum {
/** Thread is allowed to request notification handler. */
CAP_SIGNAL = (1 << 6),
+
+ /** Thread is allowed to request shared memory */
+ CAP_SHARED = (1 << 7)
};
/**
diff --git a/include/kmi/mem.h b/include/kmi/mem.h
index 97a85bf..f2b7b74 100644
--- a/include/kmi/mem.h
+++ b/include/kmi/mem.h
@@ -132,9 +132,12 @@
/** @{ */
/** Memory region is used. */
-#define MR_USED (1 << 8)
+#define MR_USED (1 << (ARCH_VP_FLAGS + 0))
/** Don't free memory on clear. */
-#define MR_KEEP (1 << 9)
+#define MR_KEEP (1 << (ARCH_VP_FLAGS + 1))
+/** Memory region in shared, but owned. Note: regions that are shared but no
+ * owned don't use this flag, they just set the tid field for the region. */
+#define MR_SHARED (1 << (ARCH_VP_FLAGS + 2))
/** @} */
diff --git a/include/kmi/mem_nodes.h b/include/kmi/mem_nodes.h
deleted file mode 100644
index 523c087..0000000
--- a/include/kmi/mem_nodes.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SPDX-License-Identifier: copyleft-next-0.3.1 */
-/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
-
-#ifndef KMI_MM_NODES_H
-#define KMI_MM_NODES_H
-
-/**
- * @file mem_nodes.h
- * Memory node subsystem. Used by the memory region subsystem.
- */
-
-#include <kmi/vmem.h>
-#include <kmi/nodes.h>
-
-/**
- * Initialize memory node subsystem.
- *
- * @pre Physical memory subsystem has been initialized.
- */
-void init_mem_nodes();
-
-/**
- * Destroy memory node subsystem.
- * Free all associated allocations.
- */
-void destroy_mem_nodes();
-
-/**
- * Fetch a new memory node.
- *
- * @return Pointer to \ref mem_region node on success, \c NULL otherwise.
- */
-struct mem_region *get_mem_node();
-
-/**
- * Free a memory node.
- *
- * @param m Pointer to \ref mem_region node to free.
- */
-void free_mem_node(struct mem_region *m);
-
-#endif /* KMI_MM_NODES_H */
diff --git a/include/kmi/orphanage.h b/include/kmi/orphanage.h
index 09e36b3..db5a617 100644
--- a/include/kmi/orphanage.h
+++ b/include/kmi/orphanage.h
@@ -14,6 +14,8 @@
* them whenever it gets a chance.
*/
+#include <kmi/attrs.h>
+#include <kmi/types.h>
#include <kmi/tcb.h>
/**
diff --git a/include/kmi/mem_regions.h b/include/kmi/regions.h
index 080a499..1d96f00 100644
--- a/include/kmi/mem_regions.h
+++ b/include/kmi/regions.h
@@ -1,20 +1,33 @@
/* SPDX-License-Identifier: copyleft-next-0.3.1 */
/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
-#ifndef KMI_MEM_REGIONS_H
-#define KMI_MEM_REGIONS_H
+#ifndef KMI_REGIONS_H
+#define KMI_REGIONS_H
/**
- * @file mem_regions.h
+ * @file regions.h
* Memory region subsytem. Mainly used by the virtual memory subsytems, i.e. device and
* user memory.
*/
#include <kmi/mem.h>
-#include <arch/vmem.h>
#include <kmi/types.h>
+#include <kmi/nodes.h>
#include <kmi/sp_tree.h>
+#include <arch/vmem.h>
+
+/**
+ * Initialize memory region nodes. Must be done after physical memory has been
+ * initialized.
+ */
+void init_mem_nodes();
+
+/**
+ * Destroy all nodes allocated by the memory region subsystem.
+ */
+void destroy_mem_nodes();
+
/**
* Get \ref mem_region container of \c ptr.
*
@@ -71,10 +84,6 @@ struct mem_region {
/** Start address of memory region. */
vm_t start;
- /** In shared regions, this is the address associated with region in the
- * other process. */
- vm_t alt_va;
-
/** In shared regions, mark the other pid that shared the region. */
id_t pid;
@@ -165,10 +174,8 @@ stat_t free_region(struct mem_region_root *r, vm_t start);
*
* @param r Memory region root.
* @param m Memory region to free.
- * @return \ref OK.
- * \todo Improve error checking.
*/
-stat_t free_known_region(struct mem_region_root *r, struct mem_region *m);
+void free_known_region(struct mem_region_root *r, struct mem_region *m);
/**
* Find the memory region with lowest starting address.
@@ -216,89 +223,89 @@ struct mem_region *find_free_region(struct mem_region_root *r, size_t size,
size_t *align);
/**
- * Helper functions for converting between memory regions and page
- * mappings. Called by \ref map_fill_region().
- * \see map_fill_region() for further explanation.
+ * Map a region starting at virtual address \p start, that is \p bytes bytes in size
+ * to physical memory. Will allocate pages itself. If it fails midway through,
+ * doesn't clean up after itself, so remember to call \ref unmap_region() in
+ * such a case.
*
- * @param vmem Virtual memory space in which the operation is to be done.
- * @param offset Offset from where to start looking for next physical page. \see
- * alloc_page().
- * @param vaddr Current virtual address.
- * @param flags Virtual memory allocation flags.
- * @param order Order of physical page.
- * @param data Custom data.
- * @return \ref OK if succesful, \c INFO_TRGN if page order should be decreased,
- * anything else means error.
+ * @param vmem Virtual memory to do allocation in.
+ * @param start Start of region.
+ * @param bytes How large the allocation is in bytes.
+ * @param order What is the maximum order of page the function is allowed to
+ * use. This is mainly useful for shared memory regions that may want to always
+ * use base pages to maximize the chance of a clone succeeding.
+ * @param flags What flags to assign the page.
+ * @return \ref OK on success, some other error code otherwise.
*/
-typedef stat_t region_callback_t(struct vmem *vmem, pm_t *offset, vm_t vaddr,
- vmflags_t flags, enum mm_order order,
- void *data);
+stat_t map_region(struct vmem *vmem, vm_t start, size_t bytes,
+ enum mm_order order, vmflags_t flags);
/**
- * Query flags of region that contains \c va.
+ * Map a virtual memory region starting at \p v to the physical memory region
+ * starting at \p start, \p bytes long. Same as \ref map_region(), clean up
+ * after this function if it fails.
*
- * @param r Memory region root.
- * @param va Address that is within memory region.
- * @param flags Memory region flags.
- * @return \ref OK when succesful.
- * \todo Implement.
+ * @param vmem Virtual memory to do mapping in.
+ * @param v Start of virtual region.
+ * @param start Start of physical region.
+ * @param bytes Size of region in bytes.
+ * @param flags Flags to use for mapping.
+ * @return \ref OK on success, some other error code otherwise.
*/
-stat_t stat_region(struct mem_region_root *r, vm_t va, vmflags_t *flags);
+stat_t map_fixed_region(struct vmem *vmem, vm_t v, pm_t start, size_t bytes,
+ vmflags_t flags);
/**
- * Modify flags of region that contains \c va.
+ * Clone a region starting at \p from in \p g of size \p bytes into \p to in \p
+ * b. Does not allocate new pages, just makes the virtual region point to the
+ * same physical pages. Used to implement shared memory, primarily.
*
- * @param r Memory region root.
- * @param va Address that is within memory region.
- * @param flags New flags of region.
- * @return \ref OK when succesful.
- * \todo Implement.
+ * @param b Where to create mapping.
+ * @param g Where current mapping exists.
+ * @param from Start of region in \p g.
+ * @param to Start of region in \p b.
+ * @param bytes Size of region. Must be identical for both \p b and \p g.
+ * @param flags Flags for the new mapping. The original mapping can be RW while
+ * the new one just R, for example.
+ *
+ * @return \ref OK on success, some other error code otherwise.
*/
-stat_t mod_region(struct mem_region_root *r, vm_t va, vmflags_t flags);
+stat_t clone_region(struct vmem *b, struct vmem *g, vm_t from, vm_t to,
+ size_t bytes, vmflags_t flags);
/**
- * Set alternate virtual address associated with shared memory region in other process.
+ * Copy region starting at \p from in \p g of size \p bytes to \p to in \p b.
+ * Allocates new pages, so the regions get copied as well. Used to implement
+ * \ref fork().
*
- * @param r Memory region root.
- * @param va Virtual address in \p r.
- * @param alt_va Virtual address in other process.
+ * @param b Where to create mapping.
+ * @param g Where current mapping exists.
+ * @param from Start of region in \p g.
+ * @param to Start of region in \p b.
+ * @param bytes Size of region. Must be identical for both \p b and \p g.
+ *
+ * @return \ref OK on success, some other error code otherwise.
*/
-void set_alt_region_addr(struct mem_region_root *r, vm_t va, vm_t alt_va);
+stat_t copy_region(struct vmem *b, struct vmem *g, vm_t from, vm_t to,
+ size_t bytes);
/**
- * Conversion function between abstract memory region and actual page mappings.
- * Assumes that pages of some order are mappable at multiples of their size, and
- * tries to fit as many and as high order pages as it can into the region.
- * Heavily utilizes \c mem_handler, to which it gives a suggestion for how to
- * map a page. If this suggestion is accepted and succesfully executed, \c mem_handler
- * returns \ref OK. If the suggestion is not possible, for example no higher
- * order pages are available, \c mem_handler returns \ref INFO_TRGN to tell \c
- * map_fill_region() to give it some other suggestion. Any error value stops the
- * conversion.
+ * Unmap a region, while at the same time freeing backing pages.
*
- * This 'algorithm' also works quite nicely for freeing a region, but in
- * reverse, i.e. it is given a suggestion and checks if that suggestion was
- * executed when the region was mapped. If the suggestion was executed, then the
- * same suggestion is freed, else \ref INFO_TRGN is returned and a new
- * suggestion is requested until all pages have been freed.
- *
- * There are some more technicalities, for example currently \c
- * map_fill_region() gives up trying to map higher order pages as soon as its
- * first suggestion is rejected, which gives us quick conversion times but
- * probably less than ideal mappings.
+ * @param b Where to unmap region.
+ * @param v Start of region to unmap.
+ * @param bytes Size of region to unmap.
+ */
+void unmap_region(struct vmem *b, vm_t v, size_t bytes);
+
+/**
+ * Unmap a region, without freeing any pages.
+ * Useful for freeing shared memory or mappings outside RAM.
*
- * @param vmem Virtual memory inside which to map the region.
- * @param mem_handler Worker handler callback.
- * @param offset Offset at which the physical memory availability map should
- * start searching.
- * @param start Start address of memory region.
- * @param bytes Size of memory region.
- * @param flags Memory flags.
- * @param data User-specified data.
- * @return \c start when succesful, \c 0 otherwise.
+ * @param b Where to unmap region.
+ * @param v Start of region to unmap.
+ * @param bytes Size of region to unmap.
*/
-vm_t map_fill_region(struct vmem *vmem, region_callback_t *mem_handler,
- pm_t offset, vm_t start, size_t bytes, vmflags_t flags,
- void *data);
+void unmap_fixed_region(struct vmem *b, vm_t v, size_t bytes);
-#endif /* KMI_MEM_REGIONS_H */
+#endif /* KMI_REGIONS_H */
diff --git a/include/kmi/syscalls.h b/include/kmi/syscalls.h
index 4ae0f0b..42cbcc0 100644
--- a/include/kmi/syscalls.h
+++ b/include/kmi/syscalls.h
@@ -11,9 +11,9 @@
/* pass VM_X etc. to userspace */
#if defined(riscv64)
-#include "../../arch/riscv64/include/vmem.h"
+#include "../../arch/riscv64/include/uapi.h"
#elif defined(riscv32)
-#include "../../arch/riscv32/include/vmem.h"
+#include "../../arch/riscv32/include/uapi.h"
#endif
/** enum for now, possibly macros in the future once I get an approximate idea of
@@ -46,7 +46,7 @@ enum sys_code {
SYS_REQ_MEM,
/** Request physical page from ram. */
- SYS_REQ_PAGE,
+ SYS_REF_SHAREDMEM,
/** Request memory with physical address. */
SYS_REQ_PMEM,
diff --git a/include/kmi/tcb.h b/include/kmi/tcb.h
index 54f6e82..b7fd3d6 100644
--- a/include/kmi/tcb.h
+++ b/include/kmi/tcb.h
@@ -12,14 +12,15 @@
/* forward declaration */
struct tcb;
-#include <kmi/mem_regions.h>
#include <kmi/orphanage.h>
#include <kmi/syscalls.h>
+#include <kmi/regions.h>
#include <kmi/atomic.h>
#include <kmi/queue.h>
#include <kmi/types.h>
#include <kmi/caps.h>
-#include <arch/tcb.h> /* arch-specific data */
+
+#include <arch/tcb.h>
/**
* Check if thread is process thread.
@@ -82,6 +83,21 @@ enum tcb_state {
TCB_ORPHAN = (1 << 1),
};
+/** Wrapper around data for managing userspace virtual memory, defined here to
+ * avoid loops */
+struct uvmem {
+ /** ID of owning thread. Zombie threads or orhaned threads may be moved
+ * to other virtual memories, but they still hold a 'backwards'
+ * reference to their original virtual memory. */
+ id_t owner;
+
+ /** Actual userspace virtual memory address space. */
+ struct vmem *vmem;
+
+ /** Region data for allocations within this address space. */
+ struct mem_region_root region;
+};
+
/** Thread control block. Main way to handle threads. */
struct tcb {
/** Execution continuation point. Important that it is first. */
@@ -97,7 +113,7 @@ struct tcb {
struct arch_tcbd arch;
/** Memory mapping data. Only relevant in root thread. */
- struct mem_region_root sp_r;
+ struct uvmem uvmem;
/** Address of callback function in servers. */
vm_t callback;
diff --git a/include/kmi/uapi.h b/include/kmi/uapi.h
index 42d6e5b..87b1895 100644
--- a/include/kmi/uapi.h
+++ b/include/kmi/uapi.h
@@ -292,30 +292,18 @@ SYSCALL_DECLARE1(putch, ch);
SYSCALL_DECLARE2(req_mem, size, flags);
/**
- * Request one page of memory. The nearest fitting size is chosen.
+ * Reference shared memory, i.e. create a mapping for it in \p tid.
*
- * This might be better implemented as some number of adjacent physical pages,
- * but the underlying physical page allocator doesn't really handle it very
- * well. This weird design decision is because I don't know if there are devices
- * whose drivers need multiple adjacent physical pages, only that at least
- * virtio devices need to be able to access the physical address of a single
- * page. Basic adjacent physical pages can be made from higher order pages,
- * just with a massive overhead. Still, probably good eough for now.
- *
- * For example, if you need two adjacent 4K pages, you pass size = 8K and you
- * get back a 2M page, if one is available.
- *
- * @param t Current tcb.
- * @param size Required size of region.
+ * @param t Current tcb, owner of \p addr.
+ * @param tid Thread to create mapping in.
+ * @param addr Address of shared region in \p t.
* @param flags Mapping flags to use.
- * @param c Unused.
* @param d Unused.
* @param e Unused.
*
- * Returns \ref ERR_OOMEM if no page is available, otherwise \c OK, virtual
- * address, actual size, physical size in that order.
+ * Returns \ref OK, virtual address, size, in that order.
*/
-SYSCALL_DECLARE2(req_page, size, flags);
+SYSCALL_DECLARE3(ref_sharedmem, tid, addr, flags);
/**
* Request physical memory syscall.
diff --git a/include/kmi/vmem.h b/include/kmi/vmem.h
index 6335959..3f7ab71 100644
--- a/include/kmi/vmem.h
+++ b/include/kmi/vmem.h
@@ -12,6 +12,7 @@
#include <kmi/tcb.h>
#include <kmi/mem.h>
#include <kmi/pmem.h>
+#include <kmi/regions.h>
#include <kmi/sp_tree.h>
/**
@@ -58,48 +59,30 @@ vm_t alloc_fixed_uvmem(struct tcb *r, vm_t start, size_t size, vmflags_t flags);
/**
* Allocate shared user virtual memory.
+ * Initially this region is only visible to whoever allocated it, but calling
+ * \ref ref_shared_uvmem() with the address of this allocation
+ * will add mappings to this region into other processes' address spaces.
*
* @param s First process to allocate memory in.
- * @param c Second process to allocate memory in.
* @param size Minimum size of allocation.
- * @param sflags Flags of allocation for \p s.
- * @param cflags Flags of allocation for \p c.
- * @param sstart Start of allocation for \p s.
- * @param cstart Start of allocation for \p c.
- * @return Status of allocation.
- */
-stat_t alloc_shared_uvmem(struct tcb *s, struct tcb *c, size_t size,
- vmflags_t sflags, vmflags_t cflags,
- vm_t *sstart, vm_t *cstart);
-
-/**
- * Reference shared user virtual memory.
- *
- * Only callable by clients.
- *
- * @param r1 Process in which shared memory resides.
- * @param r2 Process to reference shared memory in.
- * @param va Virtual address of shared memory in \c r1.
- * @param flags Flags of reference in \c r2.
- * @return Start of reference in \c r2 when succesful, \c NULL otherwise.
+ * @param flags Flags of allocation.
+ * @return Address of allocation.
*/
-vm_t ref_shared_uvmem(struct tcb *r1, struct tcb *r2, vm_t va, vmflags_t flags);
+vm_t alloc_shared_uvmem(struct tcb *s, size_t size, vmflags_t flags);
/**
* Free all user virtual memory allocations not marked with \ref MR_KEEP.
*
* @param r Process in which to clear user virtual memory.
- * @return \ref OK.
*/
-stat_t clear_uvmem(struct tcb *r);
+void clear_uvmem(struct tcb *r);
/**
* Free all user virtual memory allocations, even if marked with \ref MR_KEEP.
*
* @param r Process in which to clear user virtual memory.
- * @return \ref OK.
*/
-stat_t purge_uvmem(struct tcb *r);
+void purge_uvmem(struct tcb *r);
/**
* Free one user virtual memory allocation.
@@ -116,6 +99,8 @@ stat_t free_uvmem(struct tcb *r, vm_t va);
* This assumes the user virtual memory is contiguous, with no holes between \c
* base and \c top.
*
+ * Requires that \p t already has a vmem allocated.
+ *
* @param r Process in which to initialize user virtual memory.
* @param base Start of user virtual memory.
* @param top Top of user virtual memory.
@@ -127,9 +112,8 @@ stat_t init_uvmem(struct tcb *r, vm_t base, vm_t top);
* Destroy user virtual memory instance.
*
* @param r Process in which to destroy user virtual memory.
- * @return \see destroy_region().
*/
-stat_t destroy_uvmem(struct tcb *r);
+void destroy_uvmem(struct tcb *r);
/**
* Map a fixed physical region (within kernelspace) to somewhere in virtual
@@ -143,7 +127,7 @@ stat_t destroy_uvmem(struct tcb *r);
* the start of \p base, not necessarily the start of the allocation.
* If this should be freed, remember to align down to the base page size.
*/
-vm_t map_fixed_mem(struct tcb *r, pm_t base, size_t size, vmflags_t flags);
+vm_t map_fixed_uvmem(struct tcb *r, pm_t base, size_t size, vmflags_t flags);
/**
* Clone process memory.
@@ -158,144 +142,33 @@ vm_t map_fixed_mem(struct tcb *r, pm_t base, size_t size, vmflags_t flags);
stat_t clone_mem_regions(struct tcb *d, struct tcb *s);
/**
- * User virtual memory worker callback for \ref map_fill_region().
- *
- * \c data is a pointer to \ref stat_t, which is set to \ref INFO_SEFF if all
- * threads in process should sync their memory mappings. This occurs when the
- * top level page table is modified.
- *
- * @param b Virtual memory to work in.
- * @param offset Hint for \ref alloc_page().
- * @param vaddr Current virtual address.
- * @param flags Flags of region.
- * @param order Suggested page order.
- * @param data Pointer to \ref stat_t.
- * @return \c OK when suggested order if acceptable, \c INFO_TRGN if suggested
- * order not acceptable. Error otherwise.
- * again
- */
-stat_t alloc_uvmem_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr,
- vmflags_t flags, enum mm_order order, void *data);
-
-/**
- * Shared user virtual memory worker callback for \ref map_fill_region().
- *
- * @param b Virtual memory to work in.
- * @param offset Hint for \ref alloc_page().
- * @param vaddr Current virtual address.
- * @param flags Flags of region.
- * @param order Suggested page order.
- * @param data Pointer to \ref stat_t.
- * @return \see alloc_uvmem_wrapper().
- *
- * \see alloc_uvmem_wrapper().
- */
-stat_t alloc_shared_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr,
- vmflags_t flags, enum mm_order order, void *data);
-
-/**
- * User virtual memory copying worker callback for \ref map_fill_region().
- *
- * Currently unused, but intention is to set up copy of some other virtual
- * memory region, likely passed through \c data?
- *
- * @param b Virtual memory to work in.
- * @param offset Hint for \ref alloc_page().
- * @param vaddr Current virtual address.
- * @param flags Flags of region.
- * @param order Suggested page order.
- * @param data Pointer to \ref vmem to clone from.
- * @return \see alloc_uvmem_wrapper().
- *
- * \see alloc_uvmem_wraper().
- * \todo Implement.
- */
-stat_t copy_allocd_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr,
- vmflags_t flags, enum mm_order order, void *data);
-
-/**
- * User virtual memory freeing worker callback for \ref map_fill_region().
- *
- * @param b Virtual memory to work in.
- * @param offset Hint for \ref alloc_page().
- * @param vaddr Current virtual address.
- * @param flags Flags of region.
- * @param order Suggested page order.
- * @param data Pointer to \ref stat_t.
- * @return \see alloc_uvmem_wrapper().
- *
- * \see alloc_uvmem_wrapper().
- */
-stat_t free_uvmem_wrapper(struct vmem *b, pm_t *offset, vm_t vaddr,
- vmflags_t flags, enum mm_order order, void *data);
-
-/**
- * Convenience wrapper for \ref map_fill_region() when mapping an allocated
- * region.
- *
- * @param b Virtual memory to work in.
- * @param start Start of virtual memory region to map.
- * @param bytes Size of virtual memory region.
- * @param flags Flags of virtual memory region.
- * @param data Pointer to \c stat_t.
- * @return \see map_fill_region().
- */
-#define map_allocd_region(b, start, bytes, flags, data) \
- map_fill_region(b, &alloc_uvmem_wrapper, 0, start, bytes, flags, data)
-
-/**
- * Convenience wrapper for \ref map_fill_region() when mapping a shared region.
- *
- * @param b Virtual memory to work in.
- * @param start Start of virtual memory region to map.
- * @param bytes Size of virtual memory region.
- * @param flags Flags of virtual memory region.
- * @param data Pointer to \c stat_t.
- * @return \see map_fill_region().
- */
-#define map_shared_region(b, start, bytes, flags, data) \
- map_fill_region(b, &alloc_shared_wrapper, 0, start, bytes, flags, data)
-
-/**
- * Convenience wrapper for \ref map_fill_region() when copying a region.
- *
- * @param b Virtual memory to work in.
- * @param start Start of virtual memory region to map.
- * @param bytes Size of virtual memory region.
- * @param flags Flags of virtual memory region.
- * @param data Pointer to \c vmem to clone.
- * @return \see map_fill_region().
- */
-#define copy_allocd_region(b, start, bytes, flags, data) \
- map_fill_region(b, &copy_allocd_wrapper, 0, start, bytes, flags, data)
-
-/**
- * Convenience wrapper for \ref map_fill_region() when freeing region.
+ * Reference a shared memory region.
+ * Adds a mapping in \p d of region \p v in \p s.
*
- * @param b Virtual memory to work in.
- * @param start Start of virtual memory region to unmap.
- * @param bytes Size of virtual memory region.
- * @param flags Flags of virtual memory region. Technically unused?
- * @param data Pointer to \c stat_t.
- * @return \see map_fill_region().
+ * @param d For which thread to create a new mapping.
+ * @param s Owner of shared region.
+ * @param v Address of shared region in \p s.
+ * @param flags Flags for mapping in \p d.
+ * @return Address of mapping in \p d.
*/
-#define unmap_freed_region(b, start, bytes, flags, data) \
- map_fill_region(b, &free_uvmem_wrapper, 0, start, bytes, flags, data)
+vm_t ref_shared_uvmem(struct tcb *d, struct tcb *s, vm_t v, vmflags_t flags);
/**
- * Extract virtual memory flags (MR_XXX).
+ * Create a copy of \p s in \p d. Used for implementing \ref fork().
*
- * @param x Flags to extract virtual memory region flags from.
- * @return Virtual memory region flags.
+ * @param d Destination of copy.
+ * @param s Source of copy.
+ * @return \ref OK on success, some error otherwise.
*/
-#define vm_flags(x) ((x) & ~0xff)
+stat_t copy_uvmem(struct tcb *d, struct tcb *s);
/**
- * Extract physical memory page flags (VM_XXX).
+ * Clears out all other flags besides VM_W/VM_R/VM_X from user-provided flags
+ * and adds VM_U and VM_V to make mapping accessible from userspace.
*
- * @param x Flags to extract physical memory page flags from.
- * @return Physical memory page flags.
+ * @param flags Flags to sanitize.
+ * @return Sanitized flags.
*/
-#define vp_flags(x) ((x) & 0xff)
+vmflags_t sanitize_uvflags(vmflags_t flags);
#endif /* KMI_VMEM_H */