summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/sys/include/sys/proc.h18
-rw-r--r--src/sys/include/vm/vm.h16
-rw-r--r--src/sys/os/os_proc.c54
-rw-r--r--src/sys/vm/vm_map.c9
4 files changed, 97 insertions, 0 deletions
diff --git a/src/sys/include/sys/proc.h b/src/sys/include/sys/proc.h
index 200d5ce..cf00850 100644
--- a/src/sys/include/sys/proc.h
+++ b/src/sys/include/sys/proc.h
@@ -35,6 +35,7 @@
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/queue.h>
+#include <vm/vm.h>
#include <machine/pcb.h> /* standard */
/*
@@ -52,6 +53,7 @@
* @flags: State flags (see PROC_*)
* @pcb: Process control block
* @scdom: Syscall domain
+ * @maplist: List of mapped regions
* @link: TAILQ link
*/
struct proc {
@@ -59,6 +61,7 @@ struct proc {
uint32_t flags;
struct md_pcb pcb;
struct syscall_domain scdom;
+ TAILQ_HEAD(, vm_range) maplist;
TAILQ_ENTRY(proc) link;
};
@@ -83,6 +86,21 @@ int proc_init(struct proc *procp, int flags);
struct proc *proc_self(void);
/*
+ * Allocate a range descriptor and add it to the
+ * process's range tracking list for cleanup upon
+ * exit.
+ *
+ * @procp: Process to initialize the range of
+ * @va: Virtual address to use
+ * @pa: Physical address to use
+ * @len: Length to use
+ *
+ * Returns zero on success, otherwise a less than
+ * zero value upon error.
+ */
+int proc_add_range(struct proc *procp, vaddr_t va, paddr_t pa, size_t len);
+
+/*
* Kill a process with a specific status code
*
* @procp: Process to kill
diff --git a/src/sys/include/vm/vm.h b/src/sys/include/vm/vm.h
index 790fe0b..f5f7b16 100644
--- a/src/sys/include/vm/vm.h
+++ b/src/sys/include/vm/vm.h
@@ -31,6 +31,7 @@
#define _VM_H_ 1
#include <sys/types.h>
+#include <sys/queue.h>
#include <sys/bootvars.h>
#define VM_HIGHER_HALF (get_kernel_base())
@@ -42,6 +43,21 @@
typedef uintptr_t vaddr_t;
typedef uintptr_t paddr_t;
+/*
+ * Describes a virtual memory range
+ *
+ * @pa_base: Physical memory base
+ * @va_base: Virtual memory base
+ * @len: Length of region
+ * @link: Queue link
+ */
+struct vm_range {
+ paddr_t pa_base;
+ vaddr_t va_base;
+ size_t len;
+ TAILQ_ENTRY(vm_range) link;
+};
+
void vm_init(void);
#endif /* !_VM_H_ */
diff --git a/src/sys/os/os_proc.c b/src/sys/os/os_proc.c
index 329a3ea..3a42496 100644
--- a/src/sys/os/os_proc.c
+++ b/src/sys/os/os_proc.c
@@ -30,12 +30,39 @@
#include <sys/types.h>
#include <sys/atomic.h>
#include <sys/errno.h>
+#include <sys/cdefs.h>
+#include <sys/queue.h>
#include <sys/proc.h>
+#include <vm/vm.h>
+#include <vm/physseg.h>
+#include <os/kalloc.h>
#include <string.h>
static pid_t next_pid = 0;
/*
+ * Deallocate saved memory ranges
+ *
+ * @proc: Process to target
+ */
+static void
+proc_clear_ranges(struct proc *proc)
+{
+ const size_t PSIZE = DEFAULT_PAGESIZE;
+ struct vm_range *range;
+ size_t n_pages;
+
+ TAILQ_FOREACH(range, &proc->maplist, link) {
+ if (range == NULL) {
+ continue;
+ }
+
+ n_pages = ALIGN_UP(range->len, PSIZE) / PSIZE;
+ vm_free_frame(range->pa_base, n_pages);
+ }
+}
+
+/*
* MI proc init code
*/
int
@@ -52,6 +79,7 @@ proc_init(struct proc *procp, int flags)
/* Put the process in a known state */
scdp = &procp->scdom;
memset(procp, 0, sizeof(*procp));
+ TAILQ_INIT(&procp->maplist);
/*
* Initialize each platform latch
@@ -73,6 +101,31 @@ proc_init(struct proc *procp, int flags)
}
/*
+ * Add range to process
+ */
+int
+proc_add_range(struct proc *procp, vaddr_t va, paddr_t pa, size_t len)
+{
+ const size_t PSIZE = DEFAULT_PAGESIZE;
+ struct vm_range *range;
+
+ if (procp == NULL) {
+ return -EINVAL;
+ }
+
+ range = kalloc(sizeof(*range));
+ if (range == NULL) {
+ return -ENOMEM;
+ }
+
+ range->pa_base = pa;
+ range->va_base = va;
+ range->len = ALIGN_UP(len, PSIZE);
+ TAILQ_INSERT_TAIL(&procp->maplist, range, link);
+ return 0;
+}
+
+/*
* Kill a specific process
*/
int
@@ -83,5 +136,6 @@ proc_kill(struct proc *procp, int status)
}
procp->flags |= PROC_EXITING;
+ proc_clear_ranges(procp);
return md_proc_kill(procp, 0);
}
diff --git a/src/sys/vm/vm_map.c b/src/sys/vm/vm_map.c
index d8cb4b7..27cdcce 100644
--- a/src/sys/vm/vm_map.c
+++ b/src/sys/vm/vm_map.c
@@ -103,15 +103,19 @@ __vm_map(struct vm_vas *vas, struct mmu_map *spec, size_t len, int prot)
int
vm_map(struct vm_vas *vas, struct mmu_map *spec, size_t len, int prot)
{
+ const size_t PSIZE = DEFAULT_PAGESIZE;
int retval;
size_t unmap_len;
struct mmu_map spec_cpy;
+ struct proc *self = proc_self();
if (spec != NULL) {
spec_cpy = *spec;
}
+
/* If this fails, unmap the partial region */
+ len = ALIGN_UP(len, PSIZE);
retval = __vm_map(vas, spec, len, prot);
if (retval != 0) {
printf("vm_map: could not map <%p>\n", spec_cpy.va);
@@ -121,6 +125,11 @@ vm_map(struct vm_vas *vas, struct mmu_map *spec, size_t len, int prot)
return -1;
}
+ /* Add the range if we can */
+ if (self != NULL) {
+ proc_add_range(self, spec->va, spec->pa, len);
+ }
+
/* Place a guard page at the end */
spec->va = spec_cpy.va + len;
__vm_map(vas, spec, DEFAULT_PAGESIZE, 0);