mmap #8

Merged
mathieu merged 22 commits from mmap into master 2024-02-11 15:29:59 +01:00
8 changed files with 84 additions and 19 deletions
Showing only changes of commit d9051ea59c - Show all commits

View File

@ -45,9 +45,9 @@ int exceptionSetRoutine(int exception, exception_handler handler)
void print_handler(struct cpu_state *frame, ulong intr) void print_handler(struct cpu_state *frame, ulong intr)
{ {
int intNbInt = intr; VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "EXCEPTION %lu", intr);
VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "EXCEPTION %d", intNbInt);
printf("Exception %lu at 0x%p\n", intr, (void *)cpu_context_get_PC(frame)); printf("Exception %lu at 0x%p\n", intr, (void *)cpu_context_get_PC(frame));
asm("hlt"); asm("hlt");
} }
@ -55,17 +55,26 @@ void pagefault_handler(struct cpu_state *frame, ulong intr)
{ {
struct thread *current = getCurrentThread(); struct thread *current = getCurrentThread();
struct uAddrSpace *as = processGetAddrSpace(current->process); assert(frame == current->cpuState);
vaddr_t faultAddr = cpu_context_get_EX_faulting_vaddr(frame); if (cpu_context_is_in_user_mode(current->cpuState)) {
struct uAddrSpace *as = processGetAddrSpace(current->process);
vaddr_t faultAddr = cpu_context_get_EX_faulting_vaddr(frame);
if(!uAddrSpaceCheckNAlloc(as, faultAddr)) if (!uAddrSpaceHeapCheckNAlloc(as, faultAddr))
return; return;
printf("page fault while in thread [%s] at 0x%p when trying to access 0x%p err_code 0x%x\n", current->name, // PAGE_FAULT is a interrupt with an error code (see exception_wrapper.S)
(void *)cpu_context_get_PC(frame), (void *)faultAddr, cpu_context_get_EX_err(frame)); uint32_t error_code = cpu_context_get_EX_err(frame);
if (cpu_context_is_in_user_mode(frame)) {
if (!uAddrSpaceSolvePageFault(as, faultAddr, error_code & 0x2))
return;
printf(
"page fault while in thread [%s] at 0x%p when trying to access 0x%p err_code 0x%x\n",
current->name, (void *)cpu_context_get_PC(frame), (void *)faultAddr, error_code);
printf("Killing User Thread\n"); printf("Killing User Thread\n");
threadExit(); threadExit();
return;
} }
VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "PAGE FAULT %d", intr); VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "PAGE FAULT %d", intr);
(void)intr; (void)intr;
@ -79,5 +88,6 @@ int exceptionSetup()
exceptionSetRoutine(i, print_handler); exceptionSetRoutine(i, print_handler);
} }
exceptionSetRoutine(EXCEPTION_PAGE_FAULT, pagefault_handler); exceptionSetRoutine(EXCEPTION_PAGE_FAULT, pagefault_handler);
return 0; return 0;
} }

View File

@ -165,7 +165,7 @@
iret iret
.endm .endm
/*List of exception w or w/o err codehttps://wiki.osdev.org/Exceptions*/ /* List of exception w or w/o err code https://wiki.osdev.org/Exceptions */
.irp exception_id, 8, 10, 11, 12, 13, 14, 17, 30 .irp exception_id, 8, 10, 11, 12, 13, 14, 17, 30
exception_mac_with_errcode exception_id exception_mac_with_errcode exception_id
.endr .endr

View File

@ -61,6 +61,7 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
case SYSCALL_ID_MMAP: { case SYSCALL_ID_MMAP: {
struct uAddrSpace *as; struct uAddrSpace *as;
uaddr_t uaddr; uaddr_t uaddr;
uaddr_t uaddr_ptr;
size_t size; size_t size;
uint32_t rights; uint32_t rights;
uint32_t flags; uint32_t flags;
@ -69,15 +70,26 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
char path[256]; char path[256];
as = processGetAddrSpace(getCurrentThread()->process); as = processGetAddrSpace(getCurrentThread()->process);
ret = syscallGet5args(userCtx, (unsigned int *)&uaddr, (unsigned int *)&size, (unsigned int *)&rights, ret = syscallGet5args(userCtx, (unsigned int *)&uaddr_ptr, (unsigned int *)&size, (unsigned int *)&rights,
(unsigned int *)&flags, (unsigned int *)&userPath); (unsigned int *)&flags, (unsigned int *)&userPath);
if (memcpyFromUser((vaddr_t)&uaddr, uaddr_ptr, sizeof(uaddr)) != sizeof(uaddr)) {
ret = -EFAULT;
break;
}
strzcpyFromUser((vaddr_t *)path, (uaddr_t *)userPath, sizeof(path)); strzcpyFromUser((vaddr_t *)path, (uaddr_t *)userPath, sizeof(path));
printf("Trying mmap for device %s\n", path);
printf("Trying mmap for device %s at %lu\n", path, (vaddr_t)uaddr);
if(strcmp(path, "/dev/zero") == 0){ if(strcmp(path, "/dev/zero") == 0){
ret = zeroMmap(as, &uaddr, size, rights,flags); ret = zeroMmap(as, &uaddr, size, rights,flags);
} }
printf("ret %d\n", ret); if(!ret){
(void)as; if(memcpyToUser(uaddr_ptr, (vaddr_t)&uaddr, sizeof(uaddr)) != sizeof(uaddr)){
ret = -EFAULT;
break;
}
}
break; break;
} }
default: default:

View File

@ -44,6 +44,17 @@ static int memcpyUserMemNoCheck(vaddr_t dest, vaddr_t src, size_t size)
return size; return size;
} }
int memcpyToUser(uaddr_t to, vaddr_t from, size_t size)
{
if ((uint)to < PAGING_BASE_USER_ADDRESS)
return -EPERM;
if ((uint)to > PAGING_TOP_USER_ADDRESS - size)
return -EPERM;
return memcpyUserMemNoCheck(to, from, size);
}
int memcpyFromUser(vaddr_t to, uaddr_t from, size_t size) int memcpyFromUser(vaddr_t to, uaddr_t from, size_t size)
{ {

View File

@ -4,4 +4,5 @@
#include "stdarg.h" #include "stdarg.h"
int memcpyFromUser(vaddr_t to, uaddr_t from, size_t size); int memcpyFromUser(vaddr_t to, uaddr_t from, size_t size);
int memcpyToUser(uaddr_t to, vaddr_t from, size_t size);
int strzcpyFromUser(vaddr_t *to, uaddr_t *from, size_t size); int strzcpyFromUser(vaddr_t *to, uaddr_t *from, size_t size);

View File

@ -250,7 +250,7 @@ uaddr_t sysBrk(struct uAddrSpace *as, uaddr_t newHeapTop)
incSize = ALIGN(newHeapTop - (as->heapStart + as->heapSize), PAGE_SIZE); incSize = ALIGN(newHeapTop - (as->heapStart + as->heapSize), PAGE_SIZE);
if (incSize < 0){ if (incSize < 0){
//TODO how to free allocated page by uAddrSpaceCheckNAlloc //TODO how to free allocated page by uAddrSpaceHeapCheckNAlloc
return as->heapStart + as->heapSize; return as->heapStart + as->heapSize;
} }
@ -259,7 +259,7 @@ uaddr_t sysBrk(struct uAddrSpace *as, uaddr_t newHeapTop)
return as->heapStart + as->heapSize; return as->heapStart + as->heapSize;
} }
int uAddrSpaceCheckNAlloc(struct uAddrSpace *as, vaddr_t addr) int uAddrSpaceHeapCheckNAlloc(struct uAddrSpace *as, vaddr_t addr)
{ {
struct uAddrVirtualReg *newReg; struct uAddrVirtualReg *newReg;
int right = PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ; int right = PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ;
@ -372,3 +372,28 @@ free_reg:
free(reg); free(reg);
return ret; return ret;
} }
/**
* Check if @param faultAddr could be managed by the uAddrVirtualReg from @param as
**/
int uAddrSpaceSolvePageFault(struct uAddrSpace *as, vaddr_t faultAddr, int isWriteAccess)
{
struct uAddrVirtualReg *reg;
int rights = PAGING_MEM_READ;
reg = findVirtualRegionFromAddr(as, faultAddr, 1);
if (reg == NULL)
return -EFAULT;
if (isWriteAccess && !(reg->right & PAGING_MEM_WRITE))
return -EFAULT;
if (isWriteAccess)
rights |= PAGING_MEM_WRITE;
if (reg->res->ops->nopage(reg, faultAddr, rights))
return -EFAULT;
return 0;
}

View File

@ -43,9 +43,10 @@ struct uAddrSpace * uAddrSpaceCreate(struct process *proc);
int uAddrSpaceDelete(struct uAddrSpace *addr); int uAddrSpaceDelete(struct uAddrSpace *addr);
struct mmu_context * uAddrSpaceGetMMUContext(struct uAddrSpace *addr); struct mmu_context * uAddrSpaceGetMMUContext(struct uAddrSpace *addr);
int uAddrSpaceSetHeap(struct uAddrSpace *as, uaddr_t addr, size_t size); int uAddrSpaceSetHeap(struct uAddrSpace *as, uaddr_t addr, size_t size);
int uAddrSpaceCheckNAlloc(struct uAddrSpace *as, vaddr_t addr); int uAddrSpaceHeapCheckNAlloc(struct uAddrSpace *as, vaddr_t addr);
uaddr_t sysBrk(struct uAddrSpace *as, uaddr_t newHeapTop); uaddr_t sysBrk(struct uAddrSpace *as, uaddr_t newHeapTop);
int uAddrSpaceMmap(struct uAddrSpace *as, uaddr_t *uaddr, size_t size, uint32_t rights, int uAddrSpaceMmap(struct uAddrSpace *as, uaddr_t *uaddr, size_t size, uint32_t rights,
uint32_t flags, struct mappedRessource *res, uint32_t offset); uint32_t flags, struct mappedRessource *res, uint32_t offset);
int uAddrSpaceUnmap(struct uAddrSpace *as, uaddr_t uaddr, size_t size); int uAddrSpaceUnmap(struct uAddrSpace *as, uaddr_t uaddr, size_t size);
int uAddrSpaceSolvePageFault(struct uAddrSpace *as, vaddr_t faultAddr, int isWriteAccess);

View File

@ -4,6 +4,7 @@
#include "swintr.h" #include "swintr.h"
#include "syscall.h" #include "syscall.h"
int errno = 0;
int memcmp(const void *aptr, const void *bptr, size_t size) int memcmp(const void *aptr, const void *bptr, size_t size)
{ {
const unsigned char *a = (const unsigned char *)aptr; const unsigned char *a = (const unsigned char *)aptr;
@ -725,7 +726,11 @@ void *realloc(void *ptr, size_t size)
return new_ptr; return new_ptr;
} }
void *mmap(void *addr, size_t len, int prot, int flags, char *path){ void *mmap(void *addr, size_t len, int prot, int flags, char *path) {
return (void *)syscall5(SYSCALL_ID_MMAP, (unsigned int)addr, len, prot, flags, (unsigned int)path); int ret = syscall5(SYSCALL_ID_MMAP, (unsigned int)&addr, len, prot, flags, (unsigned int)path);
if(!ret)
return addr;
errno = ret;
return (void *)-1;
} }