summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-11-08 11:37:01 +0100
committerAndreas Kling <awesomekling@gmail.com>2018-11-08 11:40:58 +0100
commitfdbd9f1e272b97d7d28f9f610be8fbf0bdbd98d9 (patch)
tree5caafbf80252f8116a6921d7498d5d56a21481fb /Kernel
parent41a751c90c9d39db764308aeba476db593b9b6e1 (diff)
downloadserenity-fdbd9f1e272b97d7d28f9f610be8fbf0bdbd98d9.zip
Start working on memory-mapped files.
First of all, change sys$mmap to take a struct SC_mmap_params since our sycsall calling convention can't handle more than 3 arguments. This exposed a bug in Syscall::invoke() needing to use clobber lists. It was a bit confusing to debug. :^)
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/MemoryManager.h4
-rw-r--r--Kernel/Process.cpp18
-rw-r--r--Kernel/Process.h3
-rw-r--r--Kernel/Syscall.cpp4
-rw-r--r--Kernel/Syscall.h17
-rw-r--r--Kernel/i386.cpp5
6 files changed, 39 insertions, 12 deletions
diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h
index 9477e420d2..ca30f9d6db 100644
--- a/Kernel/MemoryManager.h
+++ b/Kernel/MemoryManager.h
@@ -9,6 +9,7 @@
#include <AK/Vector.h>
#include <AK/HashTable.h>
#include <AK/String.h>
+#include <VirtualFileSystem/VirtualFileSystem.h>
class Process;
extern Process* current;
@@ -71,6 +72,9 @@ struct Region : public Retainable<Region> {
return (laddr - linearAddress).get() / PAGE_SIZE;
}
+ RetainPtr<VirtualFileSystem::Node> m_file;
+ Unix::off_t m_file_offset { 0 };
+
LinearAddress linearAddress;
size_t size { 0 };
Vector<RetainPtr<PhysicalPage>> physical_pages;
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index 19aec8c7bf..48fc568437 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -26,15 +26,17 @@
// FIXME: Only do a single validation for accesses that don't span multiple pages.
// FIXME: Some places pass strlen(arg1) as arg2. This doesn't seem entirely perfect..
-#define VALIDATE_USER_READ(b, s) \
+#define VALIDATE_USER_READ_WITH_RETURN_TYPE(b, s, ret_type) \
do { \
LinearAddress laddr((dword)(b)); \
if (!validate_user_read(laddr) || !validate_user_read(laddr.offset((s) - 1))) { \
dbgprintf("Bad read address passed to syscall: %p +%u\n", laddr.get(), (s)); \
- return -EFAULT; \
+ return (ret_type)-EFAULT; \
} \
} while(0)
+#define VALIDATE_USER_READ(b, s) VALIDATE_USER_READ_WITH_RETURN_TYPE(b, s, int)
+
#define VALIDATE_USER_WRITE(b, s) \
do { \
LinearAddress laddr((dword)(b)); \
@@ -136,15 +138,21 @@ int Process::sys$set_mmap_name(void* addr, size_t size, const char* name)
return 0;
}
-void* Process::sys$mmap(void* addr, size_t size)
+void* Process::sys$mmap(const Syscall::SC_mmap_params* params)
{
+ VALIDATE_USER_READ_WITH_RETURN_TYPE(params, sizeof(Syscall::SC_mmap_params), void*);
InterruptDisabler disabler;
- // FIXME: Implement mapping at a client-preferred address.
+ void* addr = (void*)params->addr;
+ size_t size = params->size;
+ int prot = params->prot;
+ int flags = params->flags;
+ int fd = params->fd;
+ Unix::off_t offset = params->offset;
+ // FIXME: Implement mapping at a client-preferred address. Most of the support is already in plcae.
ASSERT(addr == nullptr);
auto* region = allocate_region(LinearAddress(), size, "mmap");
if (!region)
return (void*)-1;
- MM.mapRegion(*this, *region);
return (void*)region->linearAddress.get();
}
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 13661def26..4a136b3b84 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -9,6 +9,7 @@
#include <VirtualFileSystem/VirtualFileSystem.h>
#include <VirtualFileSystem/UnixTypes.h>
#include "TTY.h"
+#include "Syscall.h"
class FileDescriptor;
class PageDirectory;
@@ -132,7 +133,7 @@ public:
void sys$sigreturn() NORETURN;
pid_t sys$spawn(const char* path, const char** args, const char** envp);
pid_t sys$waitpid(pid_t, int* wstatus, int options);
- void* sys$mmap(void*, size_t size);
+ void* sys$mmap(const Syscall::SC_mmap_params*);
int sys$munmap(void*, size_t size);
int sys$set_mmap_name(void*, size_t, const char*);
int sys$get_dir_entries(int fd, void*, size_t);
diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp
index 57c574e3e5..fbf41acba2 100644
--- a/Kernel/Syscall.cpp
+++ b/Kernel/Syscall.cpp
@@ -8,7 +8,7 @@ extern "C" void syscall_entry(RegisterDump&);
extern "C" void syscall_ISR();
extern volatile RegisterDump* syscallRegDump;
-asm(
+asm volatile(
".globl syscall_ISR \n"
"syscall_ISR:\n"
" pusha\n"
@@ -93,7 +93,7 @@ static DWORD handle(RegisterDump& regs, DWORD function, DWORD arg1, DWORD arg2,
case Syscall::SC_waitpid:
return current->sys$waitpid((pid_t)arg1, (int*)arg2, (int)arg3);
case Syscall::SC_mmap:
- return (dword)current->sys$mmap((void*)arg1, (size_t)arg2);
+ return (dword)current->sys$mmap((const SC_mmap_params*)arg1);
case Syscall::SC_munmap:
return current->sys$munmap((void*)arg1, (size_t)arg2);
case Syscall::SC_gethostname:
diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h
index a9f8187769..40f952bdbd 100644
--- a/Kernel/Syscall.h
+++ b/Kernel/Syscall.h
@@ -82,33 +82,42 @@ inline constexpr const char* toString(Function function)
return "Unknown";
}
+struct SC_mmap_params {
+ uint32_t addr;
+ uint32_t size;
+ int32_t prot;
+ int32_t flags;
+ int32_t fd;
+ uint32_t offset; // FIXME: 64-bit off_t?
+};
+
void initialize();
inline dword invoke(dword function)
{
dword result;
- asm volatile("int $0x80":"=a"(result):"a"(function));
+ asm volatile("int $0x80":"=a"(result):"a"(function):"memory");
return result;
}
inline dword invoke(dword function, dword arg1)
{
dword result;
- asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1));
+ asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1):"memory");
return result;
}
inline dword invoke(dword function, dword arg1, dword arg2)
{
dword result;
- asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2));
+ asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2):"memory");
return result;
}
inline dword invoke(dword function, dword arg1, dword arg2, dword arg3)
{
dword result;
- asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2),"b"(arg3));
+ asm volatile("int $0x80":"=a"(result):"a"(function),"d"(arg1),"c"(arg2),"b"(arg3):"memory");
return result;
}
diff --git a/Kernel/i386.cpp b/Kernel/i386.cpp
index f7b21b504f..f6e46f7345 100644
--- a/Kernel/i386.cpp
+++ b/Kernel/i386.cpp
@@ -232,6 +232,11 @@ void exception_14_handler(RegisterDumpWithExceptionCode& regs)
if (response == PageFaultResponse::ShouldCrash) {
kprintf("Crashing after unresolved page fault\n");
+ kprintf("exception code: %w\n", regs.exception_code);
+ kprintf("pc=%w:%x ds=%w es=%w fs=%w gs=%w\n", regs.cs, regs.eip, regs.ds, regs.es, regs.fs, regs.gs);
+ kprintf("stk=%w:%x\n", ss, esp);
+ kprintf("eax=%x ebx=%x ecx=%x edx=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx);
+ kprintf("ebp=%x esp=%x esi=%x edi=%x\n", regs.ebp, esp, regs.esi, regs.edi);
current->crash();
} else if (response == PageFaultResponse::Continue) {
#ifdef PAGE_FAULT_DEBUG