X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fmm_virt.c;h=4434a88040b94c9792abd44d85396c9b8ac90ccd;hb=30e2436921e53b149d65403430048e39a44cad4b;hp=af3daa34f53a750ddb6764ea06af782c3cab48e8;hpb=c575e49ea4543b45ccd2a47d57ec590ca995e707;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index af3daa34..4434a880 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -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)":"") @@ -247,6 +248,7 @@ void MM_DumpTables(tVAddr Start, tVAddr End) { tVAddr rangeStart = 0; tPAddr expected = 0; + void *expected_node = NULL, *tmpnode = NULL; tVAddr curPos; Uint page; const tPAddr MASK = ~0xF78; @@ -276,11 +278,12 @@ void MM_DumpTables(tVAddr Start, tVAddr End) { if( !(gaPageDir[curPos>>22] & PF_PRESENT) || !(gaPageTable[page] & PF_PRESENT) - || (gaPageTable[page] & MASK) != expected) + || (gaPageTable[page] & MASK) != expected + || (tmpnode=NULL,MM_GetPageNode(expected, &tmpnode), tmpnode != expected_node)) { if(expected) { tPAddr orig = gaPageTable[rangeStart>>12]; - Log(" 0x%08x => 0x%08x - 0x%08x (%s%s%s%s%s)", + Log(" 0x%08x => 0x%08x - 0x%08x (%s%s%s%s%s) %p", rangeStart, orig & ~0xFFF, curPos - rangeStart, @@ -288,7 +291,8 @@ void MM_DumpTables(tVAddr Start, tVAddr End) (orig & PF_COW ? "C" : "-"), (orig & PF_GLOBAL ? "G" : "-"), (orig & PF_USER ? "U" : "-"), - (orig & PF_WRITE ? "W" : "-") + (orig & PF_WRITE ? "W" : "-"), + expected_node ); expected = 0; } @@ -296,20 +300,24 @@ void MM_DumpTables(tVAddr Start, tVAddr End) if( !(gaPageTable[curPos>>12] & PF_PRESENT) ) continue; expected = (gaPageTable[page] & MASK); + MM_GetPageNode(expected, &expected_node); rangeStart = curPos; } if(expected) expected += 0x1000; } if(expected) { - Log("0x%08x => 0x%08x - 0x%08x (%s%s%s%s)", + tPAddr orig = gaPageTable[rangeStart>>12]; + Log("0x%08x => 0x%08x - 0x%08x (%s%s%s%s%s) %p", rangeStart, - gaPageTable[rangeStart>>12] & ~0xFFF, + orig & ~0xFFF, curPos - rangeStart, - (expected & PF_NOPAGE ? "p" : "-"), - (expected & PF_COW ? "C" : "-"), - (expected & PF_USER ? "U" : "-"), - (expected & PF_WRITE ? "W" : "-") + (orig & PF_NOPAGE ? "p" : "-"), + (orig & PF_COW ? "C" : "-"), + (orig & PF_GLOBAL ? "G" : "-"), + (orig & PF_USER ? "U" : "-"), + (orig & PF_WRITE ? "W" : "-"), + expected_node ); expected = 0; } @@ -672,18 +680,11 @@ tVAddr MM_NewKStack(void) * \fn tVAddr MM_NewWorkerStack() * \brief Creates a new worker stack */ -tVAddr MM_NewWorkerStack() +tVAddr MM_NewWorkerStack(Uint *StackContents, size_t ContentsSize) { - Uint esp, ebp; - Uint oldstack; Uint base, addr; - int i, j; - Uint *tmpPage; - tPAddr pages[WORKER_STACK_SIZE>>12]; - - // Get the old ESP and EBP - __asm__ __volatile__ ("mov %%esp, %0": "=r"(esp)); - __asm__ __volatile__ ("mov %%ebp, %0": "=r"(ebp)); + tVAddr tmpPage; + tPAddr page; // TODO: Thread safety // Find a free worker stack address @@ -733,44 +734,22 @@ tVAddr MM_NewWorkerStack() // Mapping Time! for( addr = 0; addr < WORKER_STACK_SIZE; addr += 0x1000 ) - //for( addr = WORKER_STACK_SIZE; addr; addr -= 0x1000 ) { - pages[ addr >> 12 ] = MM_AllocPhys(); - gaTmpTable[ (base + addr) >> 12 ] = pages[addr>>12] | 3; + page = MM_AllocPhys(); + gaTmpTable[ (base + addr) >> 12 ] = page | 3; } *gpTmpCR3 = 0; // Release the temp mapping lock Mutex_Release(&glTempFractal); - - // Copy the old stack - oldstack = (esp + KERNEL_STACK_SIZE-1) & ~(KERNEL_STACK_SIZE-1); - esp = oldstack - esp; // ESP as an offset in the stack - - // Make `base` be the top of the stack - base += WORKER_STACK_SIZE; - - i = (WORKER_STACK_SIZE>>12) - 1; - // Copy the contents of the old stack to the new one, altering the addresses - // `addr` is refering to bytes from the stack base (mem downwards) - for(addr = 0; addr < esp; addr += 0x1000) - { - Uint *stack = (Uint*)( oldstack-(addr+0x1000) ); - tmpPage = (void*)MM_MapTemp( pages[i] ); - // Copy old stack - for(j = 0; j < 1024; j++) - { - // Possible Stack address? - if(oldstack-esp < stack[j] && stack[j] < oldstack) - tmpPage[j] = base - (oldstack - stack[j]); - else // Seems not, best leave it alone - tmpPage[j] = stack[j]; - } - MM_FreeTemp((tVAddr)tmpPage); - i --; - } + + // NOTE: Max of 1 page + // `page` is the last allocated page from the previious for loop + tmpPage = MM_MapTemp( page ); + memcpy( (void*)( tmpPage + (0x1000 - ContentsSize) ), StackContents, ContentsSize); + MM_FreeTemp(tmpPage); //Log("MM_NewWorkerStack: RETURN 0x%x", base); - return base; + return base + WORKER_STACK_SIZE; } /**