diff options
Diffstat (limited to 'src/kernel/arch')
-rw-r--r-- | src/kernel/arch/generic.h | 4 | ||||
-rw-r--r-- | src/kernel/arch/i386/pagedir.c | 16 | ||||
-rw-r--r-- | src/kernel/arch/i386/registers.h | 7 | ||||
-rw-r--r-- | src/kernel/arch/i386/sysenter.c | 8 |
4 files changed, 20 insertions, 15 deletions
diff --git a/src/kernel/arch/generic.h b/src/kernel/arch/generic.h index e7afeff..547109f 100644 --- a/src/kernel/arch/generic.h +++ b/src/kernel/arch/generic.h @@ -23,11 +23,11 @@ int syscall_handler(int, int, int, int); // all of those can allocate memory struct pagedir *pagedir_new(void); struct pagedir *pagedir_copy(const struct pagedir *orig); -void pagedir_map(struct pagedir *dir, user_ptr virt, void *phys, +void pagedir_map(struct pagedir *dir, void __user *virt, void *phys, bool user, bool writeable); void pagedir_switch(struct pagedir *); // return 0 on failure -void *pagedir_virt2phys(struct pagedir *dir, const user_ptr virt, +void *pagedir_virt2phys(struct pagedir *dir, const void __user *virt, bool user, bool writeable); diff --git a/src/kernel/arch/i386/pagedir.c b/src/kernel/arch/i386/pagedir.c index 2fc96f4..770ff4e 100644 --- a/src/kernel/arch/i386/pagedir.c +++ b/src/kernel/arch/i386/pagedir.c @@ -46,11 +46,12 @@ struct pagedir *pagedir_new(void) { return dir; } -void pagedir_map(struct pagedir *dir, user_ptr virt, void *phys, +void pagedir_map(struct pagedir *dir, void __user *virt, void *phys, bool user, bool writeable) { - uint32_t pd_idx = virt >> 22; - uint32_t pt_idx = virt >> 12 & 0x03FF; + uintptr_t virt_cast = (uintptr_t) virt; + uint32_t pd_idx = virt_cast >> 22; + uint32_t pt_idx = virt_cast >> 12 & 0x03FF; struct pagetable_entry *pagetable; if (dir->e[pd_idx].present) { @@ -124,12 +125,13 @@ struct pagedir *pagedir_copy(const struct pagedir *orig) { return clone; } -void *pagedir_virt2phys(struct pagedir *dir, const user_ptr virt, +void *pagedir_virt2phys(struct pagedir *dir, const void __user *virt, bool user, bool writeable) { + uintptr_t virt_cast = (uintptr_t) virt; uintptr_t phys; - uint32_t pd_idx = virt >> 22; - uint32_t pt_idx = virt >> 12 & 0x03FF; + uint32_t pd_idx = virt_cast >> 22; + uint32_t pt_idx = virt_cast >> 12 & 0x03FF; struct pagetable_entry *pagetable, page; /* DOESN'T CHECK PERMISSIONS ON PAGE DIRS, TODO @@ -146,6 +148,6 @@ void *pagedir_virt2phys(struct pagedir *dir, const user_ptr virt, if (writeable && !page.writeable) return 0; phys = page.address << 11; - phys |= virt & 0xFFF; + phys |= virt_cast & 0xFFF; return (void*)phys; } diff --git a/src/kernel/arch/i386/registers.h b/src/kernel/arch/i386/registers.h index cca374d..fb369b7 100644 --- a/src/kernel/arch/i386/registers.h +++ b/src/kernel/arch/i386/registers.h @@ -1,13 +1,16 @@ #pragma once +#include <kernel/types.h> #include <stdint.h> struct registers { /* those are in the order of pushad/popad - so you can load/save this * struct in (almost) one instruction */ - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; + uint32_t edi, esi; + userptr_t ebp, esp; + uint32_t ebx, edx, ecx, eax; // not part of pushad/popad, but still useful - uint32_t eip; + userptr_t eip; } __attribute__((__packed__)); // saves a return value according to the SysV ABI diff --git a/src/kernel/arch/i386/sysenter.c b/src/kernel/arch/i386/sysenter.c index 2470979..231aba5 100644 --- a/src/kernel/arch/i386/sysenter.c +++ b/src/kernel/arch/i386/sysenter.c @@ -7,8 +7,8 @@ extern void _sysexit_real(void); void sysexit(struct registers regs) { _sysexit_regs = regs; - _sysexit_regs.ecx = regs.esp; - _sysexit_regs.edx = regs.eip; + _sysexit_regs.ecx = (uintptr_t) regs.esp; + _sysexit_regs.edx = (uintptr_t) regs.eip; _sysexit_real(); __builtin_unreachable(); } @@ -18,8 +18,8 @@ _Noreturn void sysenter_stage2(void) { struct registers *regs = &process_current->regs; *regs = _sysexit_regs; // save the registers - regs->esp = regs->ecx; // fix them up - regs->eip = regs->edx; + regs->esp = (userptr_t) regs->ecx; // fix them up + regs->eip = (userptr_t) regs->edx; val = syscall_handler(regs->eax, regs->ebx, regs->esi, regs->edi); |