BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 73145c0e2b43a1cca5c2cd10a53a703d3ad013bf / memory

// Related

Nucleus

Barry Page functions + User memory functions 73145c0 (3 years, 3 months ago)
diff --git a/memory/fault.c b/memory/fault.c
index e8d66a7..dd7953f 100644
--- a/memory/fault.c
+++ b/memory/fault.c
@@ -16,8 +16,12 @@ early_page_fault_handler(struct InterruptFrame *frame, uint32_t err)
 {
 	uintptr_t addr;
 	asm volatile("mov %%cr2, %0" : "=r" (addr));
+	uint8_t present = err & (1 << 0);
+	uint8_t write   = err & (1 << 1);
+	uint8_t user    = err & (1 << 2);
 	if (!PAGE_ADDR(addr))
 		panic("Null dereference @ %#.8x", frame->eip);
+	ASSERT(!present);
 	/* Allocate a page */
 	set_page(addr, alloc_frame() | PTE_PRESENT | PTE_WRITE | PTE_GLOBAL);
 }
diff --git a/memory/frame.c b/memory/frame.c
index 8a868ea..c477121 100644
--- a/memory/frame.c
+++ b/memory/frame.c
@@ -100,7 +100,7 @@ find_frame(struct FrameRegion *region)
 uintptr_t
 alloc_frame(void)
 {
-	off_t idx;
+	int idx;
 	/* Walk the regions, first fit */
 	struct FrameRegion *region;
 	for (region = regions; region; region = region->next) {
diff --git a/memory/page.c b/memory/page.c
index 8dd07d8..6e1e67a 100644
--- a/memory/page.c
+++ b/memory/page.c
@@ -24,6 +24,7 @@ static void page_delete(Object *);
 
 /* Page object type */
 ObjectType pageType = {
+	.name = "PAGE",
 	.size = sizeof(Page),
 	.delete = page_delete,
 };
@@ -49,16 +50,41 @@ compare_page_offset(void *object, void *data)
 	return 0;
 }
 
+/* Create a new Page entry */
+Page *
+create_page(ObjectList *cache, page_t frame, off_t offset)
+{
+	Page *page = new(&pageType);
+	page->frame = frame;
+	page->offset = offset;
+	add(cache, page);
+	return page;
+}
+
 /* Find a Page by offset in a cache */
 Page *
 find_page(ObjectList *cache, off_t offset)
 {
-	lock(cache);
 	struct FindData data = {
 		.offset = offset,
 		.result = NULL,
 	};
 	iterate(cache, compare_page_offset, &data);
-	unlock(cache);
 	return data.result;
 }
+
+/* Get the virtual address for the mapping of a page */
+void *
+map_page(Page *page)
+{
+	/*
+	 * Since this x86 kernel doesn't keep all physical memory mapped into
+	 * the virtual address space, the page needs to be mapped into memory.
+	 * If more virtual memory was available (e.g. x86_64) all of physical
+	 * memory could be mapped to an offset, and this function would just
+	 * return (page->frame + offset);
+	 */
+	set_page(0x7FF000, page->frame | PTE_PRESENT | PTE_WRITE);
+	flush_tlb(0x7FF000);
+	return (void *) 0x7FF000;
+}
diff --git a/memory/user.c b/memory/user.c
new file mode 100644
index 0000000..cdf4bcd
--- /dev/null
+++ b/memory/user.c
@@ -0,0 +1,24 @@
+/*
+ * This file handles safely getting data from userspace for the kernel.  This is
+ * for security reasons to prevent the user from tricking a syscall into
+ * manipulating/leaking kernel data structures.  User memory is defined as any
+ * address range that completely sits in a Virtual Memory Region.
+ */
+
+#include <nucleus/memory.h>
+
+/* Check if user has access to a region of memory */
+int
+verify_access(const void *addr, size_t len, int prot)
+{
+	/*
+	 * This should iterate all memory regions to check if the address range
+	 * fits inside one, if not then access should be denied.  If a matching
+	 * region is found, the prot parameter should be checked against the
+	 * protection value for that region.  If this function is called from
+	 * the kernel directly, or the user did not pass an address or a length
+	 * (NULL and 0, respectively), then it should just grant access
+	 * immediately.  This can be implemented when userspace is implemented.
+	 */
+	return 1;
+}