Propagate page fault to ressource handler
Fix mmap arguments handling
This commit is contained in:
parent
b9d741060f
commit
d9051ea59c
@ -45,9 +45,9 @@ int exceptionSetRoutine(int exception, exception_handler handler)
|
||||
|
||||
void print_handler(struct cpu_state *frame, ulong intr)
|
||||
{
|
||||
int intNbInt = intr;
|
||||
VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "EXCEPTION %d", intNbInt);
|
||||
VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "EXCEPTION %lu", intr);
|
||||
printf("Exception %lu at 0x%p\n", intr, (void *)cpu_context_get_PC(frame));
|
||||
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
@ -55,17 +55,26 @@ void pagefault_handler(struct cpu_state *frame, ulong intr)
|
||||
{
|
||||
|
||||
struct thread *current = getCurrentThread();
|
||||
struct uAddrSpace *as = processGetAddrSpace(current->process);
|
||||
vaddr_t faultAddr = cpu_context_get_EX_faulting_vaddr(frame);
|
||||
assert(frame == current->cpuState);
|
||||
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))
|
||||
return;
|
||||
if (!uAddrSpaceHeapCheckNAlloc(as, faultAddr))
|
||||
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, cpu_context_get_EX_err(frame));
|
||||
if (cpu_context_is_in_user_mode(frame)) {
|
||||
// PAGE_FAULT is a interrupt with an error code (see exception_wrapper.S)
|
||||
uint32_t error_code = cpu_context_get_EX_err(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");
|
||||
threadExit();
|
||||
return;
|
||||
}
|
||||
VGAPrintf(RED, BLACK, 0, VGA_HEIGHT - 1, "PAGE FAULT %d", intr);
|
||||
(void)intr;
|
||||
@ -79,5 +88,6 @@ int exceptionSetup()
|
||||
exceptionSetRoutine(i, print_handler);
|
||||
}
|
||||
exceptionSetRoutine(EXCEPTION_PAGE_FAULT, pagefault_handler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -165,7 +165,7 @@
|
||||
iret
|
||||
.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
|
||||
exception_mac_with_errcode exception_id
|
||||
.endr
|
||||
|
@ -61,6 +61,7 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
|
||||
case SYSCALL_ID_MMAP: {
|
||||
struct uAddrSpace *as;
|
||||
uaddr_t uaddr;
|
||||
uaddr_t uaddr_ptr;
|
||||
size_t size;
|
||||
uint32_t rights;
|
||||
uint32_t flags;
|
||||
@ -69,15 +70,26 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
|
||||
char path[256];
|
||||
|
||||
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);
|
||||
|
||||
if (memcpyFromUser((vaddr_t)&uaddr, uaddr_ptr, sizeof(uaddr)) != sizeof(uaddr)) {
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
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){
|
||||
ret = zeroMmap(as, &uaddr, size, rights,flags);
|
||||
}
|
||||
printf("ret %d\n", ret);
|
||||
(void)as;
|
||||
if(!ret){
|
||||
if(memcpyToUser(uaddr_ptr, (vaddr_t)&uaddr, sizeof(uaddr)) != sizeof(uaddr)){
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -44,6 +44,17 @@ static int memcpyUserMemNoCheck(vaddr_t dest, vaddr_t src, size_t 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)
|
||||
{
|
||||
|
||||
|
@ -4,4 +4,5 @@
|
||||
#include "stdarg.h"
|
||||
|
||||
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);
|
||||
|
@ -250,7 +250,7 @@ uaddr_t sysBrk(struct uAddrSpace *as, uaddr_t newHeapTop)
|
||||
incSize = ALIGN(newHeapTop - (as->heapStart + as->heapSize), PAGE_SIZE);
|
||||
|
||||
if (incSize < 0){
|
||||
//TODO how to free allocated page by uAddrSpaceCheckNAlloc
|
||||
//TODO how to free allocated page by uAddrSpaceHeapCheckNAlloc
|
||||
return as->heapStart + as->heapSize;
|
||||
}
|
||||
|
||||
@ -259,7 +259,7 @@ uaddr_t sysBrk(struct uAddrSpace *as, uaddr_t newHeapTop)
|
||||
return as->heapStart + as->heapSize;
|
||||
}
|
||||
|
||||
int uAddrSpaceCheckNAlloc(struct uAddrSpace *as, vaddr_t addr)
|
||||
int uAddrSpaceHeapCheckNAlloc(struct uAddrSpace *as, vaddr_t addr)
|
||||
{
|
||||
struct uAddrVirtualReg *newReg;
|
||||
int right = PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ;
|
||||
@ -372,3 +372,28 @@ free_reg:
|
||||
free(reg);
|
||||
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;
|
||||
}
|
||||
|
@ -43,9 +43,10 @@ struct uAddrSpace * uAddrSpaceCreate(struct process *proc);
|
||||
int uAddrSpaceDelete(struct uAddrSpace *addr);
|
||||
struct mmu_context * uAddrSpaceGetMMUContext(struct uAddrSpace *addr);
|
||||
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);
|
||||
|
||||
int uAddrSpaceMmap(struct uAddrSpace *as, uaddr_t *uaddr, size_t size, uint32_t rights,
|
||||
uint32_t flags, struct mappedRessource *res, uint32_t offset);
|
||||
int uAddrSpaceUnmap(struct uAddrSpace *as, uaddr_t uaddr, size_t size);
|
||||
int uAddrSpaceSolvePageFault(struct uAddrSpace *as, vaddr_t faultAddr, int isWriteAccess);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "swintr.h"
|
||||
#include "syscall.h"
|
||||
|
||||
int errno = 0;
|
||||
int memcmp(const void *aptr, const void *bptr, size_t size)
|
||||
{
|
||||
const unsigned char *a = (const unsigned char *)aptr;
|
||||
@ -725,7 +726,11 @@ void *realloc(void *ptr, size_t size)
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user