summaryrefslogtreecommitdiff
path: root/src/kernel/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/arch')
-rw-r--r--src/kernel/arch/generic.h4
-rw-r--r--src/kernel/arch/i386/pagedir.c16
-rw-r--r--src/kernel/arch/i386/registers.h7
-rw-r--r--src/kernel/arch/i386/sysenter.c8
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);