Kernel/x86 - Misc fixes
authorJohn Hodge <[email protected]>
Sun, 28 Aug 2011 04:01:32 +0000 (12:01 +0800)
committerJohn Hodge <[email protected]>
Sun, 28 Aug 2011 04:01:32 +0000 (12:01 +0800)
- Fixed bugs in PMM
 > Reference counts were not being filled correctly
 > Nodes were not stored correctly
- Added some improved output to debug / MM_DumpTables
- Fixed VM8086 sometimes hard locking
- Improved bInstrTrace support

Kernel/arch/x86/desctab.asm
Kernel/arch/x86/errors.c
Kernel/arch/x86/mm_phys.c
Kernel/arch/x86/mm_virt.c
Kernel/arch/x86/proc.c
Kernel/arch/x86/vm8086.c

index dc064f5..ab7f8c2 100644 (file)
@@ -249,12 +249,18 @@ Isr240.jmp:
 [extern ErrorHandler]
 ErrorCommon:
        ;xchg bx, bx    ; MAGIC BREAK
+       
        pusha
        push ds
        push es
        push fs
        push gs
-       
+
+       ; Clear TF      
+;      pushf
+;      and WORD [esp], 0xFEFF
+;      popf
+
        mov ax, 0x10
        mov ds, ax
        mov es, ax
index 3821281..15fe22b 100644 (file)
@@ -20,6 +20,7 @@ extern void   MM_DumpTables(tVAddr, tVAddr);
 // === PROTOTYPES ===
 void   __stack_chk_fail(void);
 void   ErrorHandler(tRegs *Regs);
+void   Proc_PrintBacktrace(void);
 void   Error_Backtrace(Uint eip, Uint ebp);
 void   StartupPrint(char *Str);
 
@@ -160,6 +161,14 @@ void ErrorHandler(tRegs *Regs)
        
        for(;;) __asm__ __volatile__ ("hlt");
 }
+
+void Proc_PrintBacktrace(void)
+{
+       Uint32  ebp;
+       __asm__ __volatile__ ("mov %%ebp, %0" : "=r" (ebp));
+       Error_Backtrace( *(Uint32*)(ebp+4), *(Uint32*)ebp );
+}
+
 /**
  * \fn void Error_Backtrace(Uint eip, Uint ebp)
  * \brief Unrolls the stack to trace execution
index b84ceb6..cd4187e 100644 (file)
@@ -13,6 +13,7 @@
 
 // === IMPORTS ===
 extern void    gKernelEnd;
+extern void    Proc_PrintBacktrace(void);
 
 // === PROTOTYPES ===
 void   MM_Install(tMBoot_Info *MBoot);
@@ -256,7 +257,10 @@ tPAddr MM_AllocPhys(void)
        
        LEAVE('X', ret);
        #if TRACE_ALLOCS
-       Log_Debug("PMem", "MM_AllocPhys: RETURN 0x%llx (%i free)", ret, giPageCount-giPhysAlloc);
+       if( now() > 4000 ) {
+       Log_Debug("PMem", "MM_AllocPhys: RETURN %P (%i free)", ret, giPageCount-giPhysAlloc);
+       Proc_PrintBacktrace();
+       }
        #endif
        return ret;
 }
@@ -412,7 +416,9 @@ void MM_RefPhys(tPAddr PAddr)
        // Reference the page
        if( gaPageReferences )
        {
-               if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) == 0 ) {
+               if( MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) == 0 )
+               {
+                        int    i, base;
                        tVAddr  addr = ((tVAddr)&gaPageReferences[PAddr]) & ~0xFFF;
                        Log_Debug("PMem", "MM_RefPhys: Allocating info for %X", PAddr);
                        Mutex_Release( &glPhysAlloc );
@@ -420,7 +426,11 @@ void MM_RefPhys(tPAddr PAddr)
                                Log_KernelPanic("PMem", "MM_RefPhys: Out of physical memory");
                        }
                        Mutex_Acquire( &glPhysAlloc );
-                       memset( (void*)addr, 0, 0x1000 );
+                       
+                       base = PAddr & ~(1024-1);
+                       for( i = 0; i < 1024; i ++ ) {
+                               gaPageReferences[base + i] = (gaPageBitmap[(base+i)/32] & (1 << (base+i)%32)) ? 1 : 0;
+                       }
                }
                gaPageReferences[ PAddr ] ++;
        }
@@ -464,21 +474,22 @@ void MM_DerefPhys(tPAddr PAddr)
        if( !MM_GetPhysAddr( (tVAddr)&gaPageReferences[PAddr] ) || (-- gaPageReferences[PAddr]) == 0 )
        {
                #if TRACE_ALLOCS
-               Log_Debug("PMem", "MM_DerefPhys: Free'd 0x%x (%i free)", PAddr, giPageCount-giPhysAlloc);
+               Log_Debug("PMem", "MM_DerefPhys: Free'd %P (%i free)", PAddr<<12, giPageCount-giPhysAlloc);
+               Proc_PrintBacktrace();
                #endif
                //LOG("Freed 0x%x by %p\n", PAddr<<12, __builtin_return_address(0));
                giPhysAlloc --;
                gaPageBitmap[ PAddr / 32 ] &= ~(1 << (PAddr&31));
                if(gaPageBitmap[ PAddr / 32 ] == 0)
                        gaSuperBitmap[ PAddr >> 10 ] &= ~(1 << ((PAddr >> 5)&31));
-       }
 
-       if( MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) )
-       {
-               gaPageNodes[PAddr] = NULL;
-               // TODO: Free Node Page when fully unused
+               if( MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) )
+               {
+                       gaPageNodes[PAddr] = NULL;
+                       // TODO: Free Node Page when fully unused
+               }
        }
-       
+
        // Release spinlock
        Mutex_Release( &glPhysAlloc );
 }
@@ -522,14 +533,14 @@ int MM_SetPageNode(tPAddr PAddr, void *Node)
        }
 
        gaPageNodes[PAddr] = Node;
+//     Log("gaPageNodes[0x%x] = %p", PAddr, Node);
        return 0;
 }
 
 int MM_GetPageNode(tPAddr PAddr, void **Node)
 {
-       if( MM_GetRefCount(PAddr) == 0 ) {
-               return 1;
-       }
+       if( MM_GetRefCount(PAddr) == 0 )        return 1;
+       
        PAddr /= PAGE_SIZE;
        if( !MM_GetPhysAddr( (tVAddr) &gaPageNodes[PAddr] ) ) {
                *Node = NULL;
index b2f11c3..77ee4f6 100644 (file)
@@ -175,21 +175,23 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs)
                        gaPageTable[Addr>>12] |= paddr|PF_PRESENT|PF_WRITE;
                }
                
-               Log_Debug("MMVirt", "COW for %p", Addr);
+               Log_Debug("MMVirt", "COW for %p (%P)", Addr, gaPageTable[Addr>>12]);
                
                INVLPG( Addr & ~0xFFF );
                return;
        }
        
+       __asm__ __volatile__ ("pushf; andw $0xFEFF, 0(%esp); popf");
+       Proc_GetCurThread()->bInstrTrace = 0;
+
        // If it was a user, tell the thread handler
        if(ErrorCode & 4) {
-               Log_Warning("MMVirt", "%s %s %s memory%s",
-                       (ErrorCode&4?"User":"Kernel"),
+               Log_Warning("MMVirt", "User %s %s memory%s",
                        (ErrorCode&2?"write to":"read from"),
                        (ErrorCode&1?"bad/locked":"non-present"),
                        (ErrorCode&16?" (Instruction Fetch)":"")
                        );
-               Warning("User Pagefault: Instruction at %04x:%08x accessed %p", Regs->cs, Regs->eip, Addr);
+               Log_Warning("MMVirt", "Instruction %04x:%08x accessed %p", Regs->cs, Regs->eip, Addr);
                __asm__ __volatile__ ("sti");   // Restart IRQs
                #if 1
                Error_Backtrace(Regs->eip, Regs->ebp);
@@ -205,8 +207,7 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs)
                Warning("Reserved Bits Trashed!");
        else
        {
-               Warning("%s %s %s memory%s",
-                       (ErrorCode&4?"User":"Kernel"),
+               Warning("Kernel %s %s memory%s",
                        (ErrorCode&2?"write to":"read from"),
                        (ErrorCode&1?"bad/locked":"non-present"),
                        (ErrorCode&16?" (Instruction Fetch)":"")
@@ -278,7 +279,7 @@ void MM_DumpTables(tVAddr Start, tVAddr End)
                if( !(gaPageDir[curPos>>22] & PF_PRESENT)
                ||  !(gaPageTable[page] & PF_PRESENT)
                ||  (gaPageTable[page] & MASK) != expected
-               ||  (tmpnode=NULL,MM_GetPageNode(curPos, &tmpnode), tmpnode != expected_node))
+               ||  (tmpnode=NULL,MM_GetPageNode(expected, &tmpnode), tmpnode != expected_node))
                {
                        if(expected) {
                                tPAddr  orig = gaPageTable[rangeStart>>12];
@@ -299,7 +300,7 @@ void MM_DumpTables(tVAddr Start, tVAddr End)
                        if( !(gaPageTable[curPos>>12] & PF_PRESENT) )   continue;
                        
                        expected = (gaPageTable[page] & MASK);
-                       MM_GetPageNode(curPos, &expected_node);
+                       MM_GetPageNode(expected, &expected_node);
                        rangeStart = curPos;
                }
                if(expected)    expected += 0x1000;
index 8cff256..8598fa6 100644 (file)
@@ -950,10 +950,6 @@ void Proc_Scheduler(int CPU)
        thread = gCurrentThread;
        #endif
        
-       // NOTE:
-       // 2011-04-05
-       // Bug may be caused by DR0 not being maintained somewhere, hence 
-       // login is getting loaded with the idle state.
        if( thread )
        {
                tRegs   *regs;
@@ -967,7 +963,24 @@ void Proc_Scheduler(int CPU)
                __asm__ __volatile__ ( "mov %%esp, %0" : "=r" (esp) );
                __asm__ __volatile__ ( "mov %%ebp, %0" : "=r" (ebp) );
                eip = GetEIP();
-               if(eip == SWITCH_MAGIC) return; // Check if a switch happened
+               if(eip == SWITCH_MAGIC) {
+                       __asm__ __volatile__ ( "nop" : : : "eax","ebx","ecx","edx","edi","esi");
+                       regs = (tRegs*)(ebp+(2+2)*4);   // EBP,Ret + CPU,CurThread
+                       #if USE_MP
+                       thread = gaCPUs[CPU].Current;
+                       #else
+                       thread = gCurrentThread;
+                       #endif
+                       if(thread->bInstrTrace) {
+                               regs->eflags |= 0x100;  // Set TF
+//                             LogF("Tracing enabled\n");
+                               Log("%p Scheduled (EIP = %p)", thread, thread->SavedState.EIP);
+                       }
+                       else
+                               regs->eflags &= ~0x100;
+                       
+                       return; // Check if a switch happened
+               }
                
                // Save machine state
                thread->SavedState.ESP = esp;
@@ -1034,7 +1047,7 @@ void Proc_Scheduler(int CPU)
        #endif
        
        if( thread->bInstrTrace ) {
-               Log("%p Scheduled", thread);
+               Log("%p Scheduled (EIP = %p)", thread, thread->SavedState.EIP);
        }
        
        // Set thread pointer
index 46daeef..589d9a7 100644 (file)
@@ -7,6 +7,7 @@
 #include <vm8086.h>
 #include <modules.h>
 #include <hal_proc.h>
+#include <semaphore.h>
 
 // === CONSTANTS ===
 #define VM8086_MAGIC_CS        0xFFFF
@@ -47,6 +48,8 @@ void  VM8086_GPF(tRegs *Regs);
 // === GLOBALS ===
 MODULE_DEFINE(0, 0x100, VM8086, VM8086_Install, NULL, NULL);
 tMutex glVM8086_Process;
+tSemaphore     gVM8086_TaskComplete;
+tSemaphore     gVM8086_TasksToDo;
 tPID   gVM8086_WorkerPID;
 tTID   gVM8086_CallingThread;
 tVM8086        volatile * volatile gpVM8086_State = (void*)-1; // Set to -1 to avoid race conditions
@@ -181,16 +184,12 @@ void VM8086_GPF(tRegs *Regs)
                        gpVM8086_State->DS = Regs->ds;  gpVM8086_State->ES = Regs->es;
                        gpVM8086_State = NULL;
                        // Wake the caller
-                       Threads_WakeTID(gVM8086_CallingThread);
+                       Semaphore_Signal(&gVM8086_TaskComplete, 1);
                }
                
                //Log_Log("VM8086", "Waiting for something to do");
                __asm__ __volatile__ ("sti");
-               // Wait for a new task
-               while(!gpVM8086_State) {
-                       Threads_Sleep();
-                       //Log_Log("VM8086", "gpVM8086_State = %p", gpVM8086_State);
-               }
+               Semaphore_Wait(&gVM8086_TasksToDo, 1);
                
                //Log_Log("VM8086", "We have a task (%p)", gpVM8086_State);
                Regs->esp -= 2; *(Uint16*volatile)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = VM8086_MAGIC_CS;
@@ -428,9 +427,9 @@ void VM8086_Int(tVM8086 *State, Uint8 Interrupt)
        
        gpVM8086_State = State;
        gVM8086_CallingThread = Threads_GetTID();
-       Threads_WakeTID( gVM8086_WorkerPID );
-       Threads_Sleep();
-       while( gpVM8086_State != NULL ) Threads_Sleep();
+       Semaphore_Signal(&gVM8086_TasksToDo, 1);
+
+       Semaphore_Wait(&gVM8086_TaskComplete, 1);
        
        Mutex_Release( &glVM8086_Process );
 }

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