解决了在用户态下进行系统调用会禁用中断的问题

This commit is contained in:
fslongjin 2022-04-12 15:25:21 +08:00
parent 2d7b2b7048
commit fb4ddc56ff
9 changed files with 54 additions and 126 deletions

View File

@ -475,18 +475,16 @@ void do_IRQ(struct pt_regs *rsp, ul number)
}
}
else if (number >= 0x80 && number != 250)
else if (number == 0x80) // 系统调用
{
do_syscall_int(rsp, 0);
}
else if (number > 0x80)
{
printk_color(RED, BLACK, "SMP IPI [ %d ]\n", number);
apic_local_apic_edge_ack(number);
}
else if (number == 250) // 系统调用
{
kdebug("receive syscall");
kdebug("rflags=%#010lx", rsp->rflags);
}
else
{

View File

@ -50,7 +50,7 @@ hardware_intr_controller HPET_intr_controller =
void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
{
printk("(HPET)");
//printk("(HPET)");
switch (param)
{
case 0: // 定时器0中断
@ -76,7 +76,6 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0)
{
current_pcb->flags |= PROC_NEED_SCHED;
kdebug("need_sched. proc_jiffies=%ld", sched_cfs_ready_queue.cpu_exec_proc_jiffies);
}
break;

View File

@ -145,31 +145,32 @@ ENTRY(system_call)
//
ENTRY(ret_from_system_call)
movq %rax, 0x80(%rsp) // raxrax
popq %r15
popq %r14
popq %r13
popq %r12
popq %r11
popq %r10
popq %r9
popq %r8
popq %rbx
popq %rcx
popq %rdx
popq %rsi
popq %rdi
popq %rbp
popq %rax // popds
movq %rax, %ds
popq %rax
movq %rax, %es
popq %rax
addq $0x10, %rsp // FUNCerrcode
iretq
popq %r15
popq %r14
popq %r13
popq %r12
popq %r11
popq %r10
popq %r9
popq %r8
popq %rbx
popq %rcx
popq %rdx
popq %rsi
popq %rdi
popq %rbp
popq %rax
movq %rax, %ds
popq %rax
movq %rax, %es
popq %rax
addq $0x38, %rsp
.byte 0x48
sysexit
@ -337,6 +338,8 @@ ENTRY(virtualization_exception)
xchgq %rax, (%rsp) // FUNC
jmp Err_Code
/*
// 0x80
ENTRY(syscall_int)

View File

@ -129,8 +129,9 @@ Build_IRQ(0xcf);
Build_IRQ(0xd0);
Build_IRQ(0xd1);
Build_IRQ(0xfa); // 系统调用入口
void (*syscall_intr_table[1])(void) = {IRQ0xfainterrupt};
Build_IRQ(0x80); // 系统调用入口
void (*syscall_intr_table[1])(void) = {IRQ0x80interrupt};
// 初始化IPI中断服务程序数组
void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) =
{

View File

@ -169,6 +169,7 @@ void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code)
void do_general_protection(struct pt_regs *regs, unsigned long error_code)
{
hlt();
kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\n", error_code, regs->rsp, regs->rip);
if (error_code & 0x01)
printk_color(RED, BLACK, "The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n");
@ -311,27 +312,4 @@ void sys_vector_init()
// 32-255为用户自定义中断内部
/*
set_trap_gate(0, 1, divide_error);
set_trap_gate(1, 1, debug);
set_intr_gate(2, 1, nmi);
set_system_trap_gate(3, 1, int3);
set_system_trap_gate(4, 1, overflow);
set_system_trap_gate(5, 1, bounds);
set_trap_gate(6, 1, undefined_opcode);
set_trap_gate(7, 1, dev_not_avaliable);
set_trap_gate(8, 1, double_fault);
set_trap_gate(9, 1, coprocessor_segment_overrun);
set_trap_gate(10, 1, invalid_TSS);
set_trap_gate(11, 1, segment_not_exists);
set_trap_gate(12, 1, stack_segment_fault);
set_trap_gate(13, 1, general_protection);
set_trap_gate(14, 1, page_fault);
// 中断号15由Intel保留不能使用
set_trap_gate(16, 1, x87_FPU_error);
set_trap_gate(17, 1, alignment_check);
set_trap_gate(18, 1, machine_check);
set_trap_gate(19, 1, SIMD_exception);
set_trap_gate(20, 1, virtualization_exception);
*/
}

View File

@ -9,6 +9,7 @@
#include <sched/sched.h>
extern void system_call(void);
/**
* @brief
*
@ -31,7 +32,7 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
__asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs));
__asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs));
wrmsr(0x175, next->thread->rbp);
//wrmsr(0x175, next->thread->rbp);
// kdebug("next=%#018lx", next);
// kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1);
@ -56,7 +57,6 @@ void user_level_function()
// color_printk(RED,BLACK,"user_level_function task is running\n");
char string[] = "Hello World!\n";
/*
__asm__ __volatile__("leaq sysexit_return_address(%%rip), %%rdx \n\t"
"movq %%rsp, %%rcx \n\t"
@ -67,13 +67,13 @@ void user_level_function()
: "memory");
*/
for (int i = 0; i < 10; ++i)
for (int i = 0;; ++i)
{
long err_code;
ul addr = (ul)string;
__asm__ __volatile__(
"movq %2, %%r8 \n\t"
"int $250 \n\t"
"int $0x80 \n\t"
: "=a"(err_code)
: "a"(SYS_PRINTF), "m"(addr)
: "memory", "r8");
@ -93,11 +93,13 @@ void user_level_function()
ul do_execve(struct pt_regs *regs)
{
// 选择这两个寄存器是对应了sysexit指令的需要
regs->rdx = 0x800000; // rip 应用层程序的入口地址 这里的地址选择没有特殊要求,只要是未使用的内存区域即可。
regs->rcx = 0xa00000; // rsp 应用层程序的栈顶地址
regs->rip = 0x800000; // rip 应用层程序的入口地址 这里的地址选择没有特殊要求,只要是未使用的内存区域即可。
regs->rsp = 0xa00000; // rsp 应用层程序的栈顶地址
regs->cs = USER_CS|3;
regs->ds = USER_DS|3;
regs->ss = USER_DS |0x3;
regs->rflags = 0x200246;
regs->rax = 1;
regs->ds = 0;
regs->es = 0;
// kdebug("do_execve is running...");
@ -359,7 +361,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
kdebug("is kernel proc.");
kdebug("ret_from_system_call=%#018lx", (ul)ret_from_system_call);
tsk->state = PROC_RUNNING;
sched_cfs_enqueue(tsk);

View File

@ -18,7 +18,6 @@ struct process_control_block *sched_cfs_dequeue()
list_del(&proc->list);
--sched_cfs_ready_queue.count;
kdebug("dequeued");
return proc;
}
@ -41,7 +40,6 @@ void sched_cfs_enqueue(struct process_control_block *pcb)
}
list_append(&proc->list, &pcb->list);
++sched_cfs_ready_queue.count;
kdebug("enqueued");
}
/**
@ -111,6 +109,6 @@ void sched_init()
memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t));
list_init(&sched_cfs_ready_queue.proc_queue.list);
sched_cfs_ready_queue.count = 1; // 因为存在IDLE进程因此为1
sched_cfs_ready_queue.cpu_exec_proc_jiffies = 15;
sched_cfs_ready_queue.cpu_exec_proc_jiffies = 8;
sched_cfs_ready_queue.proc_queue.virtual_runtime = 0x7fffffffffffffff;
}

View File

@ -25,58 +25,8 @@ ul system_call_function(struct pt_regs *regs)
void syscall_init()
{
kinfo("Initializing syscall...");
/*
// 向MSR寄存器组中的 IA32_SYSENTER_CS寄存器写入内核的代码段的地址
wrmsr(0x174, KERNEL_CS);
// 向MSR寄存器组中的 IA32_SYSENTER_ESP寄存器写入内核进程的rbp在syscall入口中会将rsp减去相应的数值
wrmsr(0x175, current_pcb->thread->rbp);
// 向MSR寄存器组中的 IA32_SYSENTER_EIP寄存器写入系统调用入口的地址。
wrmsr(0x176, (ul)system_call);
*/
set_system_trap_gate(250, 0, syscall_intr_table[0]); // 系统调用门
}
/*
long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
{
long err_code;
__asm__ __volatile__("leaq sysexit_return_address(%%rip), %%rdx \n\t"
"movq %%rsp, %%rcx \n\t"
"movq %2, %%r8 \n\t"
"movq %3, %%r9 \n\t"
"movq %4, %%r10 \n\t"
"movq %5, %%r11 \n\t"
"movq %6, %%r12 \n\t"
"movq %7, %%r13 \n\t"
"movq %8, %%r14 \n\t"
"movq %9, %%r15 \n\t"
"sysenter \n\t"
"sysexit_return_address: \n\t"
: "=a"(err_code)
: "0"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5), "m"(arg6), "m"(arg7)
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
return err_code;
}
*/
ul enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
{
long err_code;
__asm__ __volatile__(
"movq %2, %%r8 \n\t"
"movq %3, %%r9 \n\t"
"movq %4, %%r10 \n\t"
"movq %5, %%r11 \n\t"
"movq %6, %%r12 \n\t"
"movq %7, %%r13 \n\t"
"movq %8, %%r14 \n\t"
"movq %9, %%r15 \n\t"
"int $0x80 \n\t"
: "=a"(err_code)
: "a"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5), "m"(arg6), "m"(arg7)
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
return err_code;
set_system_trap_gate(0x80, 0, syscall_intr_table[0]); // 系统调用门
}
/**
@ -93,7 +43,7 @@ ul enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4,
* @param arg7
* @return long
*/
/*
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7)
{
long err_code;
@ -112,7 +62,7 @@ long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
return err_code;
}
*/
/**
* @brief
*
@ -140,6 +90,5 @@ void do_syscall_int(struct pt_regs *regs, unsigned long error_code)
{
ul ret = system_call_table[regs->rax](regs);
__asm__ __volatile__("movq %0, %%rax \n\t" ::"r"(ret)
: "memory");
regs->rax = ret; // 返回码
}

View File

@ -26,7 +26,7 @@ void syscall_init();
* @return long
*/
long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7);
ul enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7);
long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7);
/**
* @brief