fix: To mitigate race condition, make the system call mask interrupt by default, and unmask when and only when needed.
improve: better debugging experience when GP happened due to the buggy iret!
DefaultAsmLines = 512
DumpWSIndex = 2
DockOrder = 0x123
DefaultAsmLines = 512
DumpWSIndex = 2
DockOrder = 0x123
-ListWidthPix[0] = 485
-ListWidthPix[1] = 667
-ListWidthPix[2] = 764
-MainWindow = 0, 0, 1283, 500
+ListWidthPix[0] = 257
+ListWidthPix[1] = 318
+ListWidthPix[2] = 367
+MainWindow = 0, 0, 743, 500
/**
* @file llist.h
* @author Lunaixsky
/**
* @file llist.h
* @author Lunaixsky
- * @brief This doubly linked cyclic list is adopted from Linux kernel <linux/list.h>
+ * @brief This doubly linked cyclic list is adopted from Linux kernel
+ * <linux/list.h>
* @version 0.1
* @date 2022-03-12
* @version 0.1
* @date 2022-03-12
* @copyright Copyright (c) 2022
* @copyright Copyright (c) 2022
*/
#ifndef __LUNAIX_LLIST_H
#define __LUNAIX_LLIST_H
*/
#ifndef __LUNAIX_LLIST_H
#define __LUNAIX_LLIST_H
-llist_init_head(struct llist_header* head) {
+llist_init_head(struct llist_header* head)
+{
head->next = head;
head->prev = head;
}
head->next = head;
head->prev = head;
}
-llist_delete(struct llist_header* elem) {
+llist_delete(struct llist_header* elem)
+{
elem->prev->next = elem->next;
elem->prev->next = elem->next;
- elem->next->prev = elem->next;
-
+ elem->next->prev = elem->prev;
+
- elem->prev = elem;
- elem->next = elem;
+ // elem->prev = elem;
+ // elem->next = elem;
-static inline int llist_empty(struct llist_header* elem) {
+static inline int
+llist_empty(struct llist_header* elem)
+{
return elem->next == elem;
}
return elem->next == elem;
}
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
-#define list_entry(ptr, type, member) \
- container_of(ptr, type, member)
+#define list_entry(ptr, type, member) container_of(ptr, type, member)
/**
* list_for_each_entry - iterate over list of given type
/**
* list_for_each_entry - iterate over list of given type
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
-#define llist_for_each(pos, n, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member), \
- n = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#define llist_for_each(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
#endif /* __LUNAIX_LLIST_H */
#endif /* __LUNAIX_LLIST_H */
uint64_t _idt[IDT_ENTRY];
uint16_t _idt_limit = sizeof(_idt) - 1;
uint64_t _idt[IDT_ENTRY];
uint16_t _idt_limit = sizeof(_idt) - 1;
-static inline void _set_idt_entry(uint32_t vector, uint16_t seg_selector, void (*isr)(), uint8_t dpl, uint8_t type) {
+static inline void
+_set_idt_entry(uint32_t vector,
+ uint16_t seg_selector,
+ void (*isr)(),
+ uint8_t dpl,
+ uint8_t type)
+{
uintptr_t offset = (uintptr_t)isr;
_idt[vector] = (offset & 0xffff0000) | IDT_ATTR(dpl, type);
_idt[vector] <<= 32;
_idt[vector] |= (seg_selector << 16) | (offset & 0x0000ffff);
}
uintptr_t offset = (uintptr_t)isr;
_idt[vector] = (offset & 0xffff0000) | IDT_ATTR(dpl, type);
_idt[vector] <<= 32;
_idt[vector] |= (seg_selector << 16) | (offset & 0x0000ffff);
}
-void _set_idt_intr_entry(uint32_t vector, uint16_t seg_selector, void (*isr)(), uint8_t dpl) {
+void
+_set_idt_intr_entry(uint32_t vector,
+ uint16_t seg_selector,
+ void (*isr)(),
+ uint8_t dpl)
+{
_set_idt_entry(vector, seg_selector, isr, dpl, IDT_INTERRUPT);
}
_set_idt_entry(vector, seg_selector, isr, dpl, IDT_INTERRUPT);
}
-void _set_idt_trap_entry(uint32_t vector, uint16_t seg_selector, void (*isr)(), uint8_t dpl) {
+void
+_set_idt_trap_entry(uint32_t vector,
+ uint16_t seg_selector,
+ void (*isr)(),
+ uint8_t dpl)
+{
_set_idt_entry(vector, seg_selector, isr, dpl, IDT_TRAP);
}
_set_idt_entry(vector, seg_selector, isr, dpl, IDT_TRAP);
}
// CPU defined interrupts
_set_idt_intr_entry(FAULT_DIVISION_ERROR, 0x08, _asm_isr0, 0);
_set_idt_intr_entry(FAULT_GENERAL_PROTECTION, 0x08, _asm_isr13, 0);
// CPU defined interrupts
_set_idt_intr_entry(FAULT_DIVISION_ERROR, 0x08, _asm_isr0, 0);
_set_idt_intr_entry(FAULT_GENERAL_PROTECTION, 0x08, _asm_isr13, 0);
_set_idt_intr_entry(APIC_ERROR_IV, 0x08, _asm_isr250, 0);
_set_idt_intr_entry(APIC_LINT0_IV, 0x08, _asm_isr251, 0);
_set_idt_intr_entry(APIC_ERROR_IV, 0x08, _asm_isr250, 0);
_set_idt_intr_entry(APIC_LINT0_IV, 0x08, _asm_isr251, 0);
- _set_idt_intr_entry(APIC_SPIV_IV, 0x08, _asm_isr252, 0);
+ _set_idt_intr_entry(APIC_SPIV_IV, 0x08, _asm_isr252, 0);
_set_idt_intr_entry(APIC_TIMER_IV, 0x08, _asm_isr253, 0);
_set_idt_intr_entry(APIC_TIMER_IV, 0x08, _asm_isr253, 0);
- _set_idt_intr_entry(PC_KBD_IV, 0x08, _asm_isr201, 0);
+ _set_idt_intr_entry(PC_KBD_IV, 0x08, _asm_isr201, 0);
- _set_idt_intr_entry(RTC_TIMER_IV, 0x08, _asm_isr210, 0);
+ _set_idt_intr_entry(RTC_TIMER_IV, 0x08, _asm_isr210, 0);
// system defined interrupts
_set_idt_intr_entry(LUNAIX_SYS_PANIC, 0x08, _asm_isr32, 0);
// system defined interrupts
_set_idt_intr_entry(LUNAIX_SYS_PANIC, 0x08, _asm_isr32, 0);
- // syscall is a trap gate (recall: trap does NOT clear IF flag upon interruption)
- // XXX: this should be fine, as our design of context switch support interruptible syscall
- // FIXME: This may cause nasty concurrency bug! We should 'lockify' our code!
- _set_idt_trap_entry(LUNAIX_SYS_CALL, 0x08, _asm_isr33, 3);
+ // syscall is a trap gate (recall: trap does NOT clear IF flag upon
+ // interruption)
+ // // XXX: this should be fine, as our design of context switch support
+ // interruptible syscall We make this a non-trap entry, and enable interrupt
+ // only when needed!
+ // FIXME: This may cause nasty concurrency bug! We should 'lockify' our
+ // code!
+ _set_idt_intr_entry(LUNAIX_SYS_CALL, 0x08, _asm_isr33, 3);
}
\ No newline at end of file
}
\ No newline at end of file
#define __ASM__
#include <arch/x86/interrupts.h>
#include <lunaix/common.h>
#define __ASM__
#include <arch/x86/interrupts.h>
#include <lunaix/common.h>
-// #define __ASM_INTR_DIAGNOSIS
+#define __ASM_INTR_DIAGNOSIS
.macro isr_template vector, no_error_code=1
.global _asm_isr\vector
.macro isr_template vector, no_error_code=1
.global _asm_isr\vector
addl $8, %esp
#ifdef __ASM_INTR_DIAGNOSIS
addl $8, %esp
#ifdef __ASM_INTR_DIAGNOSIS
- cmpl $0, (%esp)
- jz 1f
- iret
-1:
- movl $__current, %eax
- movl (%esp), %ebx
- movl $debug_resv, %ecx
- ud2
-#else
- iret
+ pushl %eax
+ movl 4(%esp), %eax
+ movl %eax, debug_resv
+ popl %eax
#include <arch/x86/interrupts.h>
#include <arch/x86/interrupts.h>
-#include <lunaix/tty/tty.h>
+#include <lunaix/process.h>
#include <lunaix/spike.h>
#include <lunaix/syslog.h>
#include <lunaix/spike.h>
#include <lunaix/syslog.h>
+#include <lunaix/tty/tty.h>
LOG_MODULE("INTR")
extern void
LOG_MODULE("INTR")
extern void
-intr_routine_page_fault (const isr_param* param);
+intr_routine_page_fault(const isr_param* param);
+
+extern uint32_t debug_resv;
-void
-__print_panic_msg(const char* msg, const isr_param* param)
+void
+__print_panic_msg(const char* msg, const isr_param* param)
{
kprint_panic(" INT %u: (%x) [%p: %p] %s",
{
kprint_panic(" INT %u: (%x) [%p: %p] %s",
- param->vector,
- param->err_code,
- param->cs,
- param->eip,
- msg);
+ param->vector,
+ param->err_code,
+ param->cs,
+ param->eip,
+ msg);
-intr_routine_divide_zero (const isr_param* param)
+intr_routine_divide_zero(const isr_param* param)
{
__print_panic_msg("Divide by zero!", param);
spin();
}
void
{
__print_panic_msg("Divide by zero!", param);
spin();
}
void
-intr_routine_general_protection (const isr_param* param)
+intr_routine_general_protection(const isr_param* param)
+ kprintf(KERROR "Addr: %p\n", (&debug_resv)[0]);
+ kprintf(KERROR "Expected: %p\n", __current->intr_ctx.eip);
__print_panic_msg("General Protection", param);
spin();
}
void
__print_panic_msg("General Protection", param);
spin();
}
void
-intr_routine_sys_panic (const isr_param* param)
+intr_routine_sys_panic(const isr_param* param)
{
__print_panic_msg((char*)(param->registers.edi), param);
spin();
}
void
{
__print_panic_msg((char*)(param->registers.edi), param);
spin();
}
void
-intr_routine_fallback (const isr_param* param)
+intr_routine_fallback(const isr_param* param)
{
__print_panic_msg("Unknown Interrupt", param);
spin();
{
__print_panic_msg("Unknown Interrupt", param);
spin();
/**
* @brief ISR for Spurious interrupt
/**
* @brief ISR for Spurious interrupt
* @param isr_param passed by CPU
*/
void
* @param isr_param passed by CPU
*/
void
-intr_routine_apic_spi (const isr_param* param)
+intr_routine_apic_spi(const isr_param* param)
{
// FUTURE: do nothing for now
}
{
// FUTURE: do nothing for now
}
-void
-intr_routine_apic_error (const isr_param* param)
+void
+intr_routine_apic_error(const isr_param* param)
{
uint32_t error_reg = apic_read_reg(APIC_ESR);
char buf[32];
{
uint32_t error_reg = apic_read_reg(APIC_ESR);
char buf[32];
- intr_subscribe(FAULT_DIVISION_ERROR, intr_routine_divide_zero);
+ intr_subscribe(FAULT_DIVISION_ERROR, intr_routine_divide_zero);
intr_subscribe(FAULT_GENERAL_PROTECTION, intr_routine_general_protection);
intr_subscribe(FAULT_GENERAL_PROTECTION, intr_routine_general_protection);
- intr_subscribe(FAULT_PAGE_FAULT, intr_routine_page_fault);
- intr_subscribe(LUNAIX_SYS_PANIC, intr_routine_sys_panic);
- intr_subscribe(APIC_SPIV_IV, intr_routine_apic_spi);
- intr_subscribe(APIC_ERROR_IV, intr_routine_apic_error);
+ intr_subscribe(FAULT_PAGE_FAULT, intr_routine_page_fault);
+ intr_subscribe(LUNAIX_SYS_PANIC, intr_routine_sys_panic);
+ intr_subscribe(APIC_SPIV_IV, intr_routine_apic_spi);
+ intr_subscribe(APIC_ERROR_IV, intr_routine_apic_error);
intr_set_fallback_handler(intr_set_fallback_handler);
}
\ No newline at end of file
intr_set_fallback_handler(intr_set_fallback_handler);
}
\ No newline at end of file
LOG_MODULE("INIT")
// #define FORK_BOMB_DEMO
LOG_MODULE("INIT")
// #define FORK_BOMB_DEMO
kprintf("Test no hang!");
kprintf("Test no hang!");
- waitpid(-1, &status, 0);
- // FIXME: WNOHANG还有点问题……
- // waitpid(-1, &status, WNOHANG);
-
- sleep(2);
+ waitpid(-1, &status, WNOHANG);
- for (size_t i = 0; i < 10; i++) {
+ for (size_t i = 0; i < 5; i++) {
pid_t pid = 0;
if (!(pid = fork())) {
sleep(i);
pid_t pid = 0;
if (!(pid = fork())) {
sleep(i);
+ // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序……
+ cpu_disable_interrupt();
struct proc_info* next;
int prev_ptr = sched_ctx.procs_index;
int ptr = prev_ptr;
struct proc_info* next;
int prev_ptr = sched_ctx.procs_index;
int ptr = prev_ptr;
sched_ctx.procs_index = ptr;
sched_ctx.procs_index = ptr;
- // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序……
- cpu_disable_interrupt();
if (!seconds) {
return 0;
}
if (!seconds) {
return 0;
}
if (__current->timer) {
return __current->timer->counter / timer_context()->running_frequency;
}
if (__current->timer) {
return __current->timer->counter / timer_context()->running_frequency;
}
__DEFINE_LXSYSCALL(void, yield)
{
__DEFINE_LXSYSCALL(void, yield)
{
if (llist_empty(&__current->children)) {
return -1;
}
if (llist_empty(&__current->children)) {
return -1;
}
+
+ cpu_enable_interrupt();
repeat:
llist_for_each(proc, n, &__current->children, siblings)
{
repeat:
llist_for_each(proc, n, &__current->children, siblings)
{
+ cpu_disable_interrupt();
*status = (proc->exit_code & 0xffff) | status_flags;
return destroy_process(proc->pid);
}
*status = (proc->exit_code & 0xffff) | status_flags;
return destroy_process(proc->pid);
}