mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-10 20:36:48 +00:00
解决了在用户态下进行系统调用会禁用中断的问题
This commit is contained in:
parent
2d7b2b7048
commit
fb4ddc56ff
@ -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
|
||||
{
|
||||
|
||||
|
@ -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;
|
||||
|
@ -145,31 +145,32 @@ ENTRY(system_call)
|
||||
// 从系统调用中返回
|
||||
ENTRY(ret_from_system_call)
|
||||
|
||||
movq %rax, 0x80(%rsp) // 将当前rax的值先存到栈中rax的位置
|
||||
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 // 不允许直接pop到ds
|
||||
movq %rax, %ds
|
||||
|
||||
popq %rax
|
||||
movq %rax, %es
|
||||
|
||||
popq %rax
|
||||
addq $0x10, %rsp // 弹出变量FUNC和errcode
|
||||
|
||||
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)
|
||||
|
@ -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) =
|
||||
{
|
||||
|
@ -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);
|
||||
*/
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
@ -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; // 返回码
|
||||
}
|
@ -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 系统调用不存在时的处理函数
|
||||
|
Loading…
x
Reference in New Issue
Block a user