diff --git a/arch/amd64/hw/exc_s.S b/arch/amd64/hw/exc_s.S index de22394..33e59b5 100644 --- a/arch/amd64/hw/exc_s.S +++ b/arch/amd64/hw/exc_s.S @@ -18,6 +18,15 @@ amd64_exc_isr_\n: .section .text amd64_exc_generic: + // 0x18: cs + // 0x10: rip + // 0x08: error code + // 0x00: error number + cmpq $0x08, 0x18(%rip) + jnz 1f + swapgs +1: + // Push full CPU context for dump pushq %rax pushq %rcx @@ -37,9 +46,6 @@ amd64_exc_generic: pushq %r14 pushq %r15 - pushq %fs - pushq %gs - movq $AMD64_STACK_CTX_CANARY, %rax pushq %rax @@ -53,9 +59,6 @@ amd64_exc_generic: 1: addq $8, %rsp - popq %gs - popq %fs - popq %r15 popq %r14 popq %r13 diff --git a/arch/amd64/sys/spin_s.S b/arch/amd64/sys/spin_s.S index bcbd2fe..9ed4b5c 100644 --- a/arch/amd64/sys/spin_s.S +++ b/arch/amd64/sys/spin_s.S @@ -1,3 +1,5 @@ +#include "arch/amd64/asm/asm_cpu.h" + .section .text .global spin_lock .global spin_release @@ -13,9 +15,12 @@ spin_lock_irqsave: cli spin_lock: + movq get_cpu(CPU_ID), %rax + shlq $1, %rax // %rdi - spinlock - lock bts $0, (%rdi) + lock btsq $0, (%rdi) jc 1f + orq %rax, (%rdi) retq // Failed to obtain lock immediately, wait diff --git a/include/arch/amd64/asm/asm_cpu.h b/include/arch/amd64/asm/asm_cpu.h index 531a403..761cf9e 100644 --- a/include/arch/amd64/asm/asm_cpu.h +++ b/include/arch/amd64/asm/asm_cpu.h @@ -24,6 +24,7 @@ #define CPU_THREAD 0x08 #define CPU_TSS 0x10 #define CPU_SYSCALL_RSP 0x18 +#define CPU_ID 0x28 #define TSS_RSP0 0x04 @@ -37,9 +38,9 @@ struct cpu { struct thread *thread; // 0x08 amd64_tss_t *tss; // 0x10 uint64_t syscall_rsp; // 0x18 - uint64_t ticks; + uint64_t ticks; // 0x20 - uint64_t processor_id; + uint64_t processor_id; // 0x28 // No need to define offsets for these: ther're not accessed // from assembly diff --git a/include/arch/amd64/cpu.h b/include/arch/amd64/cpu.h index 4a35f2f..b074706 100644 --- a/include/arch/amd64/cpu.h +++ b/include/arch/amd64/cpu.h @@ -34,7 +34,6 @@ extern struct cpu cpus[AMD64_MAX_SMP]; static inline struct cpu *get_cpu(void) { struct cpu *cpu; - _assert(rdmsr(MSR_IA32_KERNEL_GS_BASE)); asm volatile ("movq %%gs:0, %0":"=r"(cpu)); return cpu; } diff --git a/sys/char/ring.c b/sys/char/ring.c index 61192eb..e4083d3 100644 --- a/sys/char/ring.c +++ b/sys/char/ring.c @@ -78,7 +78,11 @@ int ring_getc(struct thread *ctx, struct ring *ring, char *c, int err) { ctx->wait_next = ctx; ring->reader_head = ctx; + _assert(ctx->cpu >= 0); sched_unqueue(ctx, THREAD_WAITING_IO); + + thread_check_signal(ctx, 0); + _assert(ctx->cpu >= 0); } else { break; } diff --git a/sys/sched.c b/sys/sched.c index 3e1f88a..05ff186 100644 --- a/sys/sched.c +++ b/sys/sched.c @@ -91,7 +91,7 @@ void sched_unqueue(struct thread *thr, enum thread_state new_state) { struct cpu *cpu = get_cpu(); #if defined(AMD64_SMP) - _assert(thr->cpu >= 0); + assert(thr->cpu >= 0, "Tried to unqueue non-queued thread\n"); if ((int) cpu->processor_id != thr->cpu) { // Need to ask another CPU to unqueue the task panic("TODO: implement cross-CPU unqueue\n"); diff --git a/sys/thread.c b/sys/thread.c index d219878..4eba3ca 100644 --- a/sys/thread.c +++ b/sys/thread.c @@ -662,28 +662,28 @@ void thread_signal(struct thread *thr, int signum) { if (thr->cpu == (int) get_cpu()->processor_id) { if (thr == thread_self) { kdebug("Signal will be handled now\n"); - thread_sigenter(signum); + //thread_sigenter(signum); } else { kdebug("Signal will be handled later\n"); thread_signal_set(thr, signum); - if (thr->state == THREAD_WAITING) { - timer_remove_sleep(thr); - } + //if (thr->state == THREAD_WAITING) { + // timer_remove_sleep(thr); + //} - sched_queue(thr); + //sched_queue(thr); } } else if (thr->cpu >= 0) { kdebug("Signal will be handled later (other cpu%d)\n", thr->cpu); thread_signal_set(thr, signum); - if (thr->state == THREAD_WAITING) { - timer_remove_sleep(thr); - } + //if (thr->state == THREAD_WAITING) { + // timer_remove_sleep(thr); + //} - sched_queue(thr); + //sched_queue(thr); } else { - kdebug("Signal will be handled later\n"); + kdebug("Signal will be handled later (not running)\n"); thread_signal_set(thr, signum); if (thr->state == THREAD_WAITING) {