From 9461d582084ab8c0d85e8dca1df276945366a84b Mon Sep 17 00:00:00 2001 From: Minep Date: Fri, 12 Aug 2022 13:17:22 +0100 Subject: [PATCH 1/1] refactor: kernel space yield() for controllable, flexible task switching fix: incorrect control flow in getcwd(2) syscall --- lunaix-os/includes/arch/x86/interrupts.h | 1 + lunaix-os/includes/arch/x86/vectors.h | 1 + lunaix-os/includes/hal/cpu.h | 6 ++++++ lunaix-os/includes/lunaix/sched.h | 2 +- lunaix-os/kernel/asm/x86/idt.c | 2 ++ lunaix-os/kernel/asm/x86/interrupt.S | 1 + lunaix-os/kernel/asm/x86/intr_routines.c | 10 +++++++++ lunaix-os/kernel/fs/vfs.c | 26 ++++++++++++------------ lunaix-os/kernel/lxconsole.c | 2 +- lunaix-os/kernel/sched.c | 12 +++++++---- lunaix-os/kernel/signal.c | 9 ++++---- lunaix-os/kernel/time/timer.c | 6 ------ 12 files changed, 48 insertions(+), 30 deletions(-) diff --git a/lunaix-os/includes/arch/x86/interrupts.h b/lunaix-os/includes/arch/x86/interrupts.h index 862ef05..94c15e1 100644 --- a/lunaix-os/includes/arch/x86/interrupts.h +++ b/lunaix-os/includes/arch/x86/interrupts.h @@ -63,6 +63,7 @@ ISR(21) ISR(32) ISR(33) +ISR(34) ISR(201) ISR(202) diff --git a/lunaix-os/includes/arch/x86/vectors.h b/lunaix-os/includes/arch/x86/vectors.h index e4a1968..9873db6 100644 --- a/lunaix-os/includes/arch/x86/vectors.h +++ b/lunaix-os/includes/arch/x86/vectors.h @@ -29,6 +29,7 @@ // LunaixOS related #define LUNAIX_SYS_PANIC 32 #define LUNAIX_SYS_CALL 33 +#define LUNAIX_SCHED 34 #define EX_INTERRUPT_BEGIN 200 diff --git a/lunaix-os/includes/hal/cpu.h b/lunaix-os/includes/hal/cpu.h index af56120..5789d4a 100644 --- a/lunaix-os/includes/hal/cpu.h +++ b/lunaix-os/includes/hal/cpu.h @@ -117,6 +117,12 @@ cpu_invtlb() : "r"(interm)); } +static inline void +cpu_int(int vect) +{ + asm("int %0" ::"i"(vect)); +} + void cpu_rdmsr(uint32_t msr_idx, uint32_t* reg_high, uint32_t* reg_low); diff --git a/lunaix-os/includes/lunaix/sched.h b/lunaix-os/includes/lunaix/sched.h index 69019f3..021b55e 100644 --- a/lunaix-os/includes/lunaix/sched.h +++ b/lunaix-os/includes/lunaix/sched.h @@ -17,6 +17,6 @@ void schedule(); void -sched_yield(); +sched_yieldk(); #endif /* __LUNAIX_SCHEDULER_H */ diff --git a/lunaix-os/kernel/asm/x86/idt.c b/lunaix-os/kernel/asm/x86/idt.c index d2578f7..e8b9524 100644 --- a/lunaix-os/kernel/asm/x86/idt.c +++ b/lunaix-os/kernel/asm/x86/idt.c @@ -63,4 +63,6 @@ _init_idt() // We make this a non-trap entry, and enable interrupt // only when needed! _set_idt_intr_entry(LUNAIX_SYS_CALL, 0x08, _asm_isr33, 3); + + _set_idt_intr_entry(LUNAIX_SCHED, 0x08, _asm_isr34, 0); } \ No newline at end of file diff --git a/lunaix-os/kernel/asm/x86/interrupt.S b/lunaix-os/kernel/asm/x86/interrupt.S index 7382142..b4ce936 100644 --- a/lunaix-os/kernel/asm/x86/interrupt.S +++ b/lunaix-os/kernel/asm/x86/interrupt.S @@ -36,6 +36,7 @@ isr_template LUNAIX_SYS_PANIC isr_template LUNAIX_SYS_CALL + isr_template LUNAIX_SCHED isr_template APIC_ERROR_IV isr_template APIC_LINT0_IV diff --git a/lunaix-os/kernel/asm/x86/intr_routines.c b/lunaix-os/kernel/asm/x86/intr_routines.c index 807dbe4..813490c 100644 --- a/lunaix-os/kernel/asm/x86/intr_routines.c +++ b/lunaix-os/kernel/asm/x86/intr_routines.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,12 @@ intr_routine_apic_error(const isr_param* param) spin(); } +void +intr_routine_sched(const isr_param* param) +{ + schedule(); +} + void intr_routine_init() { @@ -91,7 +98,10 @@ intr_routine_init() intr_subscribe(FAULT_GENERAL_PROTECTION, intr_routine_general_protection); intr_subscribe(FAULT_PAGE_FAULT, intr_routine_page_fault); intr_subscribe(FAULT_STACK_SEG_FAULT, intr_routine_page_fault); + intr_subscribe(LUNAIX_SYS_PANIC, intr_routine_sys_panic); + intr_subscribe(LUNAIX_SCHED, intr_routine_sched); + intr_subscribe(APIC_SPIV_IV, intr_routine_apic_spi); intr_subscribe(APIC_ERROR_IV, intr_routine_apic_error); diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index e13b489..ad9fd70 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -663,9 +663,8 @@ __DEFINE_LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count) goto done; } - cpu_enable_interrupt(); - errno = file->ops.read(file, buf, count, file->f_pos); - cpu_disable_interrupt(); + __SYSCALL_INTERRUPTIBLE( + { errno = file->ops.read(file, buf, count, file->f_pos); }) if (errno > 0) { file->f_pos += errno; @@ -690,9 +689,8 @@ __DEFINE_LXSYSCALL3(int, write, int, fd, void*, buf, size_t, count) goto done; } - cpu_enable_interrupt(); - errno = file->ops.write(file, buf, count, file->f_pos); - cpu_disable_interrupt(); + __SYSCALL_INTERRUPTIBLE( + { errno = file->ops.write(file, buf, count, file->f_pos); }) if (errno > 0) { file->f_pos += errno; @@ -1103,15 +1101,17 @@ __DEFINE_LXSYSCALL2(char*, getcwd, char*, buf, size_t, size) goto done; } + size_t len = 0; + if (!__current->cwd) { *buf = PATH_DELIM; - goto done; - } - - size_t len = vfs_get_path(__current->cwd, buf, size, 0); - if (len == size) { - errno = ERANGE; - goto done; + len = 1; + } else { + len = vfs_get_path(__current->cwd, buf, size, 0); + if (len == size) { + errno = ERANGE; + goto done; + } } buf[len + 1] = '\0'; diff --git a/lunaix-os/kernel/lxconsole.c b/lunaix-os/kernel/lxconsole.c index e58e3f1..785330a 100644 --- a/lunaix-os/kernel/lxconsole.c +++ b/lunaix-os/kernel/lxconsole.c @@ -69,7 +69,7 @@ __tty_read(struct device* dev, void* buf, size_t offset, size_t len) // When a key is arrived, one of the processes will win the race and // swallow it (advancing the key buffer pointer) if (!kbd_recv_key(&keyevent)) { - sched_yield(); + sched_yieldk(); continue; } if (!(keyevent.state & KBD_KEY_FPRESSED)) { diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index be99525..4a0e254 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -145,6 +145,12 @@ redo: run(next); } +void +sched_yieldk() +{ + cpu_int(LUNAIX_SCHED); +} + __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds) { if (!seconds) { @@ -219,7 +225,6 @@ _wait(pid_t wpid, int* status, int options) } wpid = wpid ? wpid : -__current->pgid; - cpu_enable_interrupt(); repeat: llist_for_each(proc, n, &__current->children, siblings) { @@ -238,11 +243,10 @@ repeat: return 0; } // 放弃当前的运行机会 - sched_yield(); + sched_yieldk(); goto repeat; done: - cpu_disable_interrupt(); status_flags |= PEXITSIG * (proc->sig_inprogress != 0); if (status) { *status = proc->exit_code | status_flags; @@ -330,7 +334,7 @@ destroy_process(pid_t pid) struct mm_region *pos, *n; llist_for_each(pos, n, &proc->mm.regions.head, head) { - lxfree(pos); + vfree(pos); } vmm_mount_pd(PD_MOUNT_1, proc->page_table); diff --git a/lunaix-os/kernel/signal.c b/lunaix-os/kernel/signal.c index db1d4ff..5f0c868 100644 --- a/lunaix-os/kernel/signal.c +++ b/lunaix-os/kernel/signal.c @@ -188,11 +188,10 @@ __do_pause() { __current->flags |= PROC_FINPAUSE; - __SYSCALL_INTERRUPTIBLE({ - while ((__current->flags & PROC_FINPAUSE)) { - sched_yield(); - } - }) + while ((__current->flags & PROC_FINPAUSE)) { + sched_yieldk(); + } + __current->k_status = EINTR; } diff --git a/lunaix-os/kernel/time/timer.c b/lunaix-os/kernel/time/timer.c index f479f58..51c2c7f 100644 --- a/lunaix-os/kernel/time/timer.c +++ b/lunaix-os/kernel/time/timer.c @@ -213,12 +213,6 @@ timer_update(const isr_param* param) } } -void -sched_yield() -{ - sched_ticks_counter = sched_ticks; -} - static void temp_intr_routine_rtc_tick(const isr_param* param) { -- 2.27.0