From: John Hodge Date: Thu, 28 Jul 2011 13:11:36 +0000 (+0800) Subject: Kernel/x86_64 - Implemented UserRIP/CS X-Git-Tag: rel0.10~26 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=19930d5a055b1804fbdc8188973b52092392bf8f;p=tpg%2Facess2.git Kernel/x86_64 - Implemented UserRIP/CS --- diff --git a/Kernel/arch/x86_64/desctab.asm b/Kernel/arch/x86_64/desctab.asm index c575dd61..7ad93eb7 100644 --- a/Kernel/arch/x86_64/desctab.asm +++ b/Kernel/arch/x86_64/desctab.asm @@ -289,8 +289,10 @@ DEFIRQ i [global IrqCommon] IrqCommon: PUSH_GPR + push gs + push fs - mov rbx, [rsp+16*8] ; Calculate address + mov rbx, [rsp+(16+2)*8] ; Calculate address shr rbx, 3+2 ; *8*4 mov rax, gaIRQ_Handlers add rbx, rax @@ -321,6 +323,8 @@ IrqCommon: mov dx, 0x0020 out dx, al + pop fs + pop gs POP_GPR add rsp, 8*2 ;xchg bx, bx @@ -328,8 +332,15 @@ IrqCommon: [extern Proc_Scheduler] [global SchedulerIRQ] +; +; NOTE: Proc_Scheduler makes assumptions about the stack state when called +; SchedulerIRQ: + push 0 ; Error code + push 0 ; IRQNum PUSH_GPR + push gs + push fs ;PUSH_FPU ;PUSH_XMM @@ -365,7 +376,10 @@ SchedulerIRQ: ;POP_XMM ;POP_FPU + pop fs + pop gs POP_GPR + add rsp, 2*8 ; Dummy error code and IRQ num iretq [section .data] diff --git a/Kernel/arch/x86_64/include/mm_virt.h b/Kernel/arch/x86_64/include/mm_virt.h index dd520a22..ebb69232 100644 --- a/Kernel/arch/x86_64/include/mm_virt.h +++ b/Kernel/arch/x86_64/include/mm_virt.h @@ -61,7 +61,7 @@ #define MM_HWMAP_TOP (MM_KERNEL_RANGE|(0xD000##00000000)) #define MM_PPD_BASE (MM_KERNEL_RANGE|(0xD000##00000000)) #define MM_PPD_CFG MM_PPD_BASE -#define MM_PPD_VFS (MM_KERNEL_RANGE|(0xD008##00000000)) +#define MM_PPD_HANDLES (MM_KERNEL_RANGE|(0xD008##00000000)) #define MM_USER_CODE (MM_KERNEL_RANGE|(0xD080##00000000)) #define MM_PAGE_COUNTS (MM_KERNEL_RANGE|(0xE000##00000000)) diff --git a/Kernel/arch/x86_64/include/proc.h b/Kernel/arch/x86_64/include/proc.h index 94d21272..93926f7c 100644 --- a/Kernel/arch/x86_64/include/proc.h +++ b/Kernel/arch/x86_64/include/proc.h @@ -16,12 +16,12 @@ typedef struct { Uint FS, GS; Uint RAX, RCX, RDX, RBX; - Uint KernelRSP, RBP, RSI, RDI; + Uint KernelRSP, RBP, RSI, RDI; Uint R8, R9, R10, R11; Uint R12, R13, R14, R15; - Uint IntNum, ErrorCode; - Uint RIP, CS; + Uint IntNum, ErrorCode; + Uint RIP, CS; Uint RFlags, RSP, SS; } tRegs; @@ -39,6 +39,7 @@ typedef struct sMemoryState typedef struct sTaskState { Uint RIP, RSP, RBP; + Uint64 UserRIP, UserCS; } tTaskState; // === CONSTANTS === diff --git a/Kernel/arch/x86_64/proc.c b/Kernel/arch/x86_64/proc.c index 99fa7e60..f2abb289 100644 --- a/Kernel/arch/x86_64/proc.c +++ b/Kernel/arch/x86_64/proc.c @@ -742,6 +742,7 @@ void Proc_CallFaultHandler(tThread *Thread) void Proc_DumpThreadCPUState(tThread *Thread) { + Log(" At %04x:%016llx", Thread->SavedState.UserCS, Thread->SavedState.UserRIP); } /** @@ -758,22 +759,31 @@ void Proc_Scheduler(int CPU) // Get current thread thread = gaCPUs[CPU].Current; - - // Reduce remaining quantum and continue timeslice if non-zero - if(thread->Remaining--) return; - // Reset quantum for next call - thread->Remaining = thread->Quantum; - - // Get machine state - __asm__ __volatile__ ("mov %%rsp, %0":"=r"(rsp)); - __asm__ __volatile__ ("mov %%rbp, %0":"=r"(rbp)); - rip = GetRIP(); - if(rip == SWITCH_MAGIC) return; // Check if a switch happened - - // Save machine state - thread->SavedState.RSP = rsp; - thread->SavedState.RBP = rbp; - thread->SavedState.RIP = rip; + + if( thread ) + { + tRegs *regs; + // Reduce remaining quantum and continue timeslice if non-zero + if(thread->Remaining--) return; + // Reset quantum for next call + thread->Remaining = thread->Quantum; + + // Get machine state + __asm__ __volatile__ ("mov %%rsp, %0":"=r"(rsp)); + __asm__ __volatile__ ("mov %%rbp, %0":"=r"(rbp)); + rip = GetRIP(); + if(rip == SWITCH_MAGIC) return; // Check if a switch happened + + // Save machine state + thread->SavedState.RSP = rsp; + thread->SavedState.RBP = rbp; + thread->SavedState.RIP = rip; + + // TODO: Make this more stable somehow + regs = (tRegs*)(rbp+(2+1)*8); // RBP,Ret + CurThread + thread->SavedState.UserCS = regs->CS; + thread->SavedState.UserRIP = regs->RIP; + } // Get next thread thread = Threads_GetNextToRun(CPU, thread);