sched: add kernel-mode context switching

This commit is contained in:
2023-04-30 14:27:57 +01:00
parent 2cb2d9100a
commit 085c3d2a89
12 changed files with 340 additions and 27 deletions

View File

@@ -36,32 +36,32 @@ struct irq_hook {
};
struct cpu_context {
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
uint64_t rdi, rsi, rbp, unused_rsp, rbx, rdx, rcx, rax;
uint64_t int_no, err_no;
uint64_t rip, cs, rflags, rsp, ss;
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
uint64_t rdi, rsi, rbp, unused_rsp, rbx, rdx, rcx, rax;
uint64_t int_no, err_no;
uint64_t rip, cs, rflags, rsp, ss;
} __packed;
struct idt_entry {
uint16_t base_low;
uint16_t selector;
uint8_t always0;
uint8_t type : 4;
uint8_t zero : 1;
uint8_t dpl : 2;
uint8_t present : 1;
uint16_t base_middle;
uint32_t base_high;
uint32_t reserved;
uint16_t base_low;
uint16_t selector;
uint8_t always0;
uint8_t type : 4;
uint8_t zero : 1;
uint8_t dpl : 2;
uint8_t present : 1;
uint16_t base_middle;
uint32_t base_high;
uint32_t reserved;
} __packed;
struct idt {
struct idt_entry i_entries[NR_IDT_ENTRIES];
struct idt_entry i_entries[NR_IDT_ENTRIES];
};
struct idt_ptr {
uint16_t i_limit;
uintptr_t i_base;
uint16_t i_limit;
uintptr_t i_base;
} __packed;
typedef void (*int_hook)(struct cpu_context *);

View File

@@ -0,0 +1,10 @@
#ifndef SOCKS_X86_64_THREAD_H_
#define SOCKS_X86_64_THREAD_H_
#include <socks/sched.h>
extern void switch_to(struct thread *from, struct thread *to);
extern void prepare_stack(uintptr_t ip, uintptr_t *sp);
extern void user_jump(uintptr_t ip, uintptr_t sp);
#endif

View File

@@ -96,7 +96,7 @@ static void gpf_handler(struct cpu_context *regs)
static void pf_handler(struct cpu_context *regs)
{
printk("page fault (%016llx %016llx)", pf_faultptr(), regs->rip);
printk("page fault (%016llx %016llx %016llx)", pf_faultptr(), regs->rip, regs->err_no);
ml_halt_cpu();
}
@@ -241,6 +241,10 @@ void irq_dispatch(struct cpu_context *regs)
hook->irq_callback();
}
if (need_resched()) {
schedule();
}
start_charge_period();
}

20
arch/x86_64/thread.c Normal file
View File

@@ -0,0 +1,20 @@
#include <socks/machine/thread.h>
struct thread_ctx {
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
uint64_t rdi, rsi, rbp, unused_rsp, rbx, rdx, rcx, rax;
uint64_t rfl;
} __packed;
void prepare_stack(uintptr_t ip, uintptr_t *sp)
{
(*sp) -= sizeof(uintptr_t);
uintptr_t *dest_ip = (uintptr_t *)(*sp);
*dest_ip = ip;
(*sp) -= sizeof(struct thread_ctx);
struct thread_ctx *ctx = (struct thread_ctx *)(*sp);
memset(ctx, 0x0, sizeof *ctx);
ctx->rfl = 0x202;
}

View File

@@ -0,0 +1,54 @@
.code64
.extern THREAD_sp
//TASK_threadsp:
//.long 32
.global switch_to
.type switch_to, @function
// %rdi = (struct thread *) current thread.
// %rsi = (struct thread *) next thread.
switch_to:
pushfq
push %rax
push %rcx
push %rdx
push %rbx
pushq $0
push %rbp
push %rsi
push %rdi
push %r8
push %r9
push %r10
push %r11
push %r12
push %r13
push %r14
push %r15
movq %rsp, THREAD_sp(%rdi)
movq THREAD_sp(%rsi), %rsp
pop %r15
pop %r14
pop %r13
pop %r12
pop %r11
pop %r10
pop %r9
pop %r8
pop %rdi
pop %rsi
pop %rbp
add $8, %rsp
pop %rbx
pop %rdx
pop %rcx
pop %rax
popfq
ret