Kernel/x86_64 - Debugging GUI errors (and a wild goose chase)
authorJohn Hodge (sonata) <[email protected]>
Mon, 26 Nov 2012 08:05:26 +0000 (16:05 +0800)
committerJohn Hodge (sonata) <[email protected]>
Mon, 26 Nov 2012 08:05:26 +0000 (16:05 +0800)
KernelLand/Kernel/arch/x86_64/desctab.asm
KernelLand/Kernel/arch/x86_64/errors.c
KernelLand/Kernel/arch/x86_64/include/mm_virt.h
KernelLand/Kernel/arch/x86_64/mm_virt.c
KernelLand/Kernel/arch/x86_64/proc.asm
KernelLand/Kernel/arch/x86_64/proc.c
KernelLand/Kernel/libc.c
KernelLand/Kernel/syscalls.c
KernelLand/Kernel/threads.c
KernelLand/Modules/Display/BochsGA/bochsvbe.c

index 22b41be..e833173 100644 (file)
@@ -276,17 +276,23 @@ DEFIRQ    i
 %assign i i+1
 %endrep
 
+[extern Proc_int_SetIRQIP]
+
 [global IrqCommon]
 IrqCommon:
        PUSH_GPR
        push gs
        push fs
-
+       
+       mov rdi, [rsp+(16+2+2)*8]       ; 2SReg + GPRs + Int/Errcode = RIP
+       call Proc_int_SetIRQIP
+       push rax
+       
 ;      mov rdi, csIRQ_Fired
 ;      mov rsi, [rsp+(16+2)*8]
 ;      call Log
        
-       mov ebx, [rsp+(16+2)*8] ; Get interrupt number (16 GPRS + 2 SRs)
+       mov ebx, [rsp+(1+2+16)*8]       ; Get interrupt number (16 GPRS + 2 SRs)
        shl ebx, 2      ; *4
        mov rax, gaIRQ_Handlers
        lea rbx, [rax+rbx*8]
@@ -300,7 +306,7 @@ IrqCommon:
        test rax, rax   ; Check if it exists
        jz .skip.%[i]
        ; Set RDI to IRQ number
-       mov rdi, [rsp+(16+2+1)*8]       ; Get IRQ number
+       mov rdi, [rsp+(16+2+1+1)*8]     ; Get IRQ number
        mov rsi, [rbx-gaIRQ_Handlers+gaIRQ_DataPtrs]
        call rax        ; Call
 .skip.%[i]:
@@ -311,12 +317,15 @@ IrqCommon:
        
        ; ACK
        mov al, 0x20
-       mov rdi, [rsp+(16+2)*8] ; Get IRQ number
+       mov rdi, [rsp+(16+2+1)*8]       ; Get IRQ number
        cmp rdi, 8
        jb .skipAckSecondary
        out 0xA0, al
 .skipAckSecondary:
        out 0x20, al
+
+       pop rdi
+       call Proc_int_SetIRQIP
        
        pop fs
        pop gs
@@ -398,7 +407,10 @@ SyscallStub:
        mov [rsp+0x28], r10     ; Arg4
        mov [rsp+0x30], r8      ; Arg5
        mov [rsp+0x38], r9      ; Arg6
-       
+
+       mov rdi, rcx    
+       call Proc_int_SetIRQIP
+
        mov rdi, rsp
        sub rsp, 8
        call SyscallHandler
index e7812c3..fda3113 100644 (file)
@@ -13,6 +13,7 @@
 extern int     MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs);
 extern void    Error_Backtrace(Uint IP, Uint BP);
 extern void    Proc_EnableSSE(void);
+extern void    Threads_Dump(void);
 extern void    Proc_RestoreSSE(Uint32 Data);
 
 // === PROTOTYPES ===
@@ -98,6 +99,9 @@ void Error_Handler(tRegs *Regs)
                        *(Uint8*)(Regs->RIP+2), *(Uint8*)(Regs->RIP+3)
                        );
                break;
+       case 2: // NMI
+               Threads_Dump();
+               break;
        }
        
        __asm__ __volatile__ ("cli");
index 6cf25f0..120afb3 100644 (file)
@@ -84,7 +84,7 @@
 // === FUNCTIONS ===
 void   MM_FinishVirtualInit(void);
 tVAddr MM_NewKStack(void);
-tVAddr MM_Clone(void);
+tVAddr MM_Clone(int bCopyUser);
 tVAddr MM_NewWorkerStack(void *StackData, size_t StackSize);
 
 #endif
index e1e59c0..de7ae52 100644 (file)
@@ -722,43 +722,73 @@ int MM_IsValidBuffer(tVAddr Addr, size_t Size)
 
        Size += Addr & (PAGE_SIZE-1);
        Addr &= ~(PAGE_SIZE-1);
-       Addr &= ((1UL << 48)-1);        // Clap to address space
+       // NC addr
+       if( ((Addr >> 47) & 1) != ((Addr>>48) == 0xFFFF))
+               return 0;
+       Addr &= ((1UL << 48)-1);        // Clamp to address space
 
        pml4 = Addr >> 39;
        pdp = Addr >> 30;
        dir = Addr >> 21;
        tab = Addr >> 12;
 
-       if( !(PAGEMAPLVL4(pml4) & 1) )  return 0;
-       if( !(PAGEDIRPTR(pdp) & 1) )    return 0;
-       if( !(PAGEDIR(dir) & 1) )       return 0;
-       if( !(PAGETABLE(tab) & 1) )     return 0;
+       if( !(PAGEMAPLVL4(pml4) & 1) ) {
+               Log_Debug("MMVirt", "PML4E %i NP", pml4);
+               return 0;
+       }
+       if( !(PAGEDIRPTR(pdp) & 1) ) {
+               Log_Debug("MMVirt", "PDPE %i NP", pdp);
+               return 0;
+       }
+       if( !(PAGEDIR(dir) & 1) ) {
+               Log_Debug("MMVirt", "PDE %i NP", dir);
+               return 0;
+       }
+       if( !(PAGETABLE(tab) & 1) ) {
+               Log_Debug("MMVirt", "PTE %i NP", tab);
+               return 0;
+       }
        
        bIsUser = !!(PAGETABLE(tab) & PF_USER);
 
        while( Size >= PAGE_SIZE )
        {
+               tab ++;
+               Size -= PAGE_SIZE;
+               
                if( (tab & 511) == 0 )
                {
                        dir ++;
-                       if( ((dir >> 9) & 511) == 0 )
+                       if( (dir & 511) == 0 )
                        {
                                pdp ++;
-                               if( ((pdp >> 18) & 511) == 0 )
+                               if( (pdp & 511) == 0 )
                                {
                                        pml4 ++;
-                                       if( !(PAGEMAPLVL4(pml4) & 1) )  return 0;
+                                       if( !(PAGEMAPLVL4(pml4) & 1) ) {
+                                               Log_Debug("MMVirt", "IsValidBuffer - PML4E %x NP, Size=%x", pml4, Size);
+                                               return 0;
+                                       }
+                               }
+                               if( !(PAGEDIRPTR(pdp) & 1) ) {
+                                       Log_Debug("MMVirt", "IsValidBuffer - PDPE %x NP", pdp);
+                                       return 0;
                                }
-                               if( !(PAGEDIRPTR(pdp) & 1) )    return 0;
                        }
-                       if( !(PAGEDIR(dir) & 1) )       return 0;
+                       if( !(PAGEDIR(dir) & 1) ) {
+                               Log_Debug("MMVirt", "IsValidBuffer - PDE %x NP", dir);
+                               return 0;
+                       }
                }
                
-               if( !(PAGETABLE(tab) & 1) )   return 0;
-               if( bIsUser && !(PAGETABLE(tab) & PF_USER) )    return 0;
-
-               tab ++;
-               Size -= PAGE_SIZE;
+               if( !(PAGETABLE(tab) & 1) ) {
+                       Log_Debug("MMVirt", "IsValidBuffer - PTE %x NP", tab);
+                       return 0;
+               }
+               if( bIsUser && !(PAGETABLE(tab) & PF_USER) ) {
+                       Log_Debug("MMVirt", "IsValidBuffer - PTE %x Not user", tab);
+                       return 0;
+               }
        }
        return 1;
 }
@@ -894,7 +924,7 @@ void MM_FreeTemp(void *Ptr)
 
 
 // --- Address Space Clone --
-tPAddr MM_Clone(void)
+tPAddr MM_Clone(int bNoUserCopy)
 {
        tPAddr  ret;
         int    i;
@@ -910,7 +940,7 @@ tPAddr MM_Clone(void)
        INVLPG_ALL();
        
        // #3 Set Copy-On-Write to all user pages
-       if( Threads_GetPID() != 0 )
+       if( Threads_GetPID() != 0 && !bNoUserCopy )
        {
                for( i = 0; i < 256; i ++)
                {
index f44d65b..f3b3a28 100644 (file)
@@ -39,6 +39,8 @@ Proc_CloneInt:
        PUSH_GPR
        ; Save RSP
        mov [rdi], rsp
+       ; Call MM_Clone (with bNoUserCopy flag)
+       mov rdi, rdx
        call MM_Clone
        ; Save CR3
        mov rsi, [rsp+0x30]     ; Saved version of RSI
index 884babb..46e2b21 100644 (file)
@@ -37,7 +37,7 @@ extern void   APStartup(void);        // 16-bit AP startup code
 
 extern Uint    GetRIP(void);   // start.asm
 extern Uint    SaveState(Uint *RSP, Uint *Regs);
-extern Uint    Proc_CloneInt(Uint *RSP, Uint *CR3);
+extern Uint    Proc_CloneInt(Uint *RSP, Uint *CR3, int bCopyUserVM);
 extern void    NewTaskHeader(void);    // Actually takes cdecl args
 extern void    Proc_InitialiseSSE(void);
 extern void    Proc_SaveSSE(Uint DestPtr);
@@ -75,6 +75,7 @@ void  Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP) NO
 //void Proc_DumpThreadCPUState(tThread *Thread);
 //void Proc_Reschedule(void);
 void   Proc_Scheduler(int CPU, Uint RSP, Uint RIP);
+Uint   Proc_int_SetIRQIP(Uint RIP);
 
 // === GLOBALS ===
 //!\brief Used by desctab.asm in SyscallStub
@@ -507,7 +508,7 @@ tTID Proc_Clone(Uint Flags)
        if(!newThread)  return -1;
        
        // Save core machine state
-       rip = Proc_CloneInt(&newThread->SavedState.RSP, &newThread->Process->MemState.CR3);
+       rip = Proc_CloneInt(&newThread->SavedState.RSP, &newThread->Process->MemState.CR3, !!(Flags & CLONE_NOUSER));
        if(rip == 0)    return 0;       // Child
        newThread->KernelStack = cur->KernelStack;
        newThread->SavedState.RIP = rip;
@@ -725,7 +726,14 @@ void Proc_CallFaultHandler(tThread *Thread)
 
 void Proc_DumpThreadCPUState(tThread *Thread)
 {
-       Log("  At %04x:%016llx", Thread->SavedState.UserCS, Thread->SavedState.UserRIP);
+       if( Thread->CurCPU == GetCPUNum() ) {
+               // TODO: Backtrace to IRQ
+               Log("  IRQ %016llx", Thread->SavedState.UserRIP);
+       }
+       else {
+               Log("  At %016llx, SP=%016llx", Thread->SavedState.RIP, Thread->SavedState.RSP);
+               Log("  User %04x:%016llx", Thread->SavedState.UserCS, Thread->SavedState.UserRIP);
+       }
 }
 
 void Proc_Reschedule(void)
@@ -825,5 +833,14 @@ void Proc_Scheduler(int CPU, Uint RSP, Uint RIP)
 #endif
 }
 
+Uint Proc_int_SetIRQIP(Uint RIP)
+{
+        int    cpu = GetCPUNum();
+       tThread *thread = gaCPUs[cpu].Current;
+       Uint    rv = thread->SavedState.UserRIP;
+       thread->SavedState.UserRIP = RIP;
+       return rv;
+}
+
 // === EXPORTS ===
 EXPORT(Proc_SpawnWorker);
index 1b6f371..c6df2cd 100644 (file)
@@ -226,7 +226,9 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
                if(c == 'p') {
                        Uint    ptr = va_arg(args, Uint);
                        PUTCH('*');     PUTCH('0');     PUTCH('x');
-                       for( len = BITS/4; len --; )
+                       for( len = BITS/4; len -- && ((ptr>>(len*4))&15) == 0; )
+                               ;
+                       for( len ++; len --; )
                                PUTCH( cUCDIGITS[ (ptr>>(len*4))&15 ] );
                        continue ;
                }
@@ -738,7 +740,8 @@ void *memmove(void *__dest, const void *__src, size_t len)
        
 }
 
-// NOTE: Strictly not libc, but lib.c is used by userland code too
+// NOTE: Strictly not libc, but lib.c is used by userland code too and hence these two
+// can't be in it.
 /**
  * \name Memory Validation
  * \{
index 5a1d596..82389bb 100644 (file)
 #include <events.h>
 
 #define CHECK_NUM_NULLOK(v,size)       \
-       if((v)&&!Syscall_Valid((size),(v))){ret=-1;err=-EINVAL;break;}
+       if((v)&&!Syscall_Valid((size),(v))){LOG("CHECK_NUM_NULLOK: %p(%x) FAIL",v,size);ret=-1;err=-EINVAL;break;}
 #define CHECK_STR_NULLOK(v)    \
-       if((v)&&!Syscall_ValidString((v))){ret=-1;err=-EINVAL;break;}
+       if((v)&&!Syscall_ValidString((v))){LOG("CHECK_STR_NULLOK: %p FAIL",v);ret=-1;err=-EINVAL;break;}
 #define CHECK_NUM_NONULL(v,size)       \
-       if(!(v)||!Syscall_Valid((size),(v))){ret=-1;err=-EINVAL;break;}
+       if(!(v)||!Syscall_Valid((size),(v))){LOG("CHECK_NUM_NONULL: %p(%x) FAIL",v,size);ret=-1;err=-EINVAL;break;}
 #define CHECK_STR_NONULL(v)    \
-       if(!(v)||!Syscall_ValidString((v))){ret=-1;err=-EINVAL;break;}
+       if(!(v)||!Syscall_ValidString((v))){LOG("CHECK_STR_NONULL: %p FAIL",v);ret=-1;err=-EINVAL;break;}
 #define CHECK_STR_ARRAY(arr)   do {\
         int    i;\
        char    **tmp = (char**)arr; \
@@ -400,7 +400,10 @@ int Syscall_ValidString(const char *Addr)
  */
 int Syscall_Valid(int Size, const void *Addr)
 {
-       if(!MM_IsUser( (tVAddr)Addr ))  return 0;
+       if(!MM_IsUser( (tVAddr)Addr )) {
+               Log_Debug("Syscalls", "Syscall_Valid - %p not user", Addr);
+               return 0;
+       }
        
        return CheckMem( Addr, Size );
 }
index 17cccca..a21db4a 100644 (file)
@@ -1079,7 +1079,7 @@ void Threads_int_DumpThread(tThread *thread)
        default:        break;
        }
        Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
-       Log("  KStack 0x%x", thread->KernelStack);
+       Log("  KStack %p", thread->KernelStack);
        if( thread->bInstrTrace )
                Log("  Tracing Enabled");
        Proc_DumpThreadCPUState(thread);
index 70f0c91..84473df 100644 (file)
@@ -47,8 +47,6 @@ enum {
        VBE_DISPI_INDEX_Y_OFFSET\r
 };\r
 \r
-extern void MM_DumpTables(tVAddr Start, tVAddr End);\r
-\r
 // === PROTOTYPES ===\r
 // Driver\r
  int   BGA_Install(char **Arguments);\r

UCC git Repository :: git.ucc.asn.au