summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authordzwdz2024-07-22 20:49:58 +0200
committerdzwdz2024-07-22 20:49:58 +0200
commit2be2236e99e5aed779b820b540d72dffb47da406 (patch)
tree771913557b89e20c825bcc1fb29baa74c801e896 /src/kernel
parentacf0c1333d620821820b2246e1c7acc0aaf0bd44 (diff)
kernel: explicitly store process RIP and RFLAGS
Once again, needed for the interrupt return syscall. Seems to have made the kernel slower in timebench?
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/arch/amd64/registers.h2
-rw-r--r--src/kernel/arch/amd64/sysenter.s46
-rw-r--r--src/kernel/execbuf.c2
-rw-r--r--src/kernel/proc.c6
4 files changed, 31 insertions, 25 deletions
diff --git a/src/kernel/arch/amd64/registers.h b/src/kernel/arch/amd64/registers.h
index 5fd09c9..cfbfa54 100644
--- a/src/kernel/arch/amd64/registers.h
+++ b/src/kernel/arch/amd64/registers.h
@@ -7,7 +7,7 @@ struct CpuRegs {
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
uint64_t rdi, rsi;
userptr_t rbp, rsp;
- uint64_t rbx, rdx, rcx, rax;
+ uint64_t rbx, rdx, rcx, rax, rip, flags;
uint8_t _sse[512];
} __attribute__((__packed__));
diff --git a/src/kernel/arch/amd64/sysenter.s b/src/kernel/arch/amd64/sysenter.s
index 8d91c4a..8e07dbb 100644
--- a/src/kernel/arch/amd64/sysenter.s
+++ b/src/kernel/arch/amd64/sysenter.s
@@ -41,13 +41,19 @@ stored_rsp:
pagedir_current:
.skip 8
-// temporarily used for IRET
+/* fake stack used for IRET */
+.align 8
+iret_stack:
+iret_ip:
.skip 8
+iret_cs:
+ .quad SEG_r3code << 3 | 3
+iret_flags:
.skip 8
+iret_sp:
.skip 8
- .skip 8
- .skip 8
-dumb_stack:
+iret_ss:
+ .quad SEG_r3data << 3 | 3
.global _sysexit_real
.type _sysexit_real, @function
@@ -58,12 +64,6 @@ _sysexit_real:
mov %ax, %fs
mov %ax, %gs
- /* The state image referenced with an FXRSTOR instruction must have
- * been saved using an FXSAVE instruction or be in the same format
- * as required [...] will result in an incorrect state restoration. */
- // TODO will probably end up fucking something up in a hard to debug way
- // sorry, future me. hopefully you have learned something from this
- fxrstor (_sysexit_regs + 128)
mov $_sysexit_regs, %rsp
pop %r15
pop %r14
@@ -78,23 +78,25 @@ _sysexit_real:
pop %rdi
pop %rsi
pop %rbp
- pop (stored_rsp)
+ pop (iret_sp)
pop %rbx
pop %rdx
pop %rcx
pop %rax
- // enable paging
+ pop (iret_ip)
+ pop (iret_flags)
+
+ /* The state image referenced with an FXRSTOR instruction must have
+ * been saved using an FXSAVE instruction or be in the same format
+ * as required [...] will result in an incorrect state restoration. */
+ fxrstor (%rsp)
+
mov (pagedir_current), %rsp
mov %rsp, %cr3
- mov $dumb_stack, %rsp
- push $(SEG_r3data << 3 | 3) /* SS */
- push (stored_rsp) /* SP */
- push %r11 /* FLAGS */
- push $(SEG_r3code << 3 | 3) /* CS */
- push %rcx /* IP */
+ mov $iret_stack, %rsp
iretq
sysenter_stage1:
@@ -105,8 +107,12 @@ sysenter_stage1:
mov $pml4_identity, %rsp
mov %rsp, %cr3
- fxsave (_sysexit_regs + 128)
- mov $(_sysexit_regs + 128), %rsp
+ mov $(_sysexit_regs + 144), %rsp
+ fxsave (%rsp)
+
+ push %r11 /* flags */
+ push %rcx /* ip */
+
push %rax
push %rcx
push %rdx
diff --git a/src/kernel/execbuf.c b/src/kernel/execbuf.c
index fe9e159..71fc662 100644
--- a/src/kernel/execbuf.c
+++ b/src/kernel/execbuf.c
@@ -36,7 +36,7 @@ _Noreturn void execbuf_run(Proc *proc) {
case EXECBUF_JMP:
try_fetch(proc, buf, 1);
- proc->regs.rcx = buf[0];
+ proc->regs.rip = buf[0];
break;
default:
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 6cc1679..a22f632 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -40,7 +40,7 @@ Proc *proc_seed(void *data, size_t datalen) {
for (uintptr_t off = 0; off < datalen; off += PAGE_SIZE)
pagedir_map(proc_first->pages, init_base + off, data + off, true, true);
- proc_first->regs.rcx = (uintptr_t)init_base; // SYSRET jumps to %rcx
+ proc_first->regs.rip = (uintptr_t)init_base;
// proc_first->regs.r11 |= 1<<9; /* enable interrupts */
return proc_first;
@@ -372,12 +372,12 @@ void proc_intr(Proc *p, const char *buf, size_t len) {
/* save old rsp,rip */
struct intr_data d;
void __user *sp = p->regs.rsp - 128 - sizeof(d);
- d.ip = (void __user *)p->regs.rcx;
+ d.ip = (void __user *)p->regs.rip;
d.sp = p->regs.rsp;
pcpy_to(p, sp, &d, sizeof(d));
/* switch to intr handler */
- p->regs.rcx = (uint64_t)p->intr_fn;
+ p->regs.rip = (uint64_t)p->intr_fn;
p->regs.rsp = sp;
}