X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fmm_virt.c;h=e2442ae10be60667897bb74ab726bbe527539712;hb=c5de7b08d4a82908a5acf6454fd7836bdab68715;hp=77ee4f6f559e468c80c9dcced7cc1217d4e5d25d;hpb=95d6bcfbf5ff9d9921ca70997a64f2580d1f91a7;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index 77ee4f6f..e2442ae1 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -15,6 +15,7 @@ #include #include #include +#include #define TAB 22 @@ -59,7 +60,7 @@ typedef Uint32 tTabEnt; // === IMPORTS === -extern void _UsertextEnd, _UsertextBase; +extern char _UsertextEnd[], _UsertextBase[]; extern Uint32 gaInitPageDir[1024]; extern Uint32 gaInitPageTable[1024]; extern void Threads_SegFault(tVAddr Addr); @@ -69,8 +70,8 @@ extern void Error_Backtrace(Uint eip, Uint ebp); void MM_PreinitVirtual(void); void MM_InstallVirtual(void); void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs); -void MM_DumpTables(tVAddr Start, tVAddr End); -tVAddr MM_ClearUser(void); +//void MM_DumpTables(tVAddr Start, tVAddr End); +//void MM_ClearUser(void); tPAddr MM_DuplicatePage(tVAddr VAddr); // === GLOBALS === @@ -175,7 +176,7 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs) gaPageTable[Addr>>12] |= paddr|PF_PRESENT|PF_WRITE; } - Log_Debug("MMVirt", "COW for %p (%P)", Addr, gaPageTable[Addr>>12]); +// Log_Debug("MMVirt", "COW for %p (%P)", Addr, gaPageTable[Addr>>12]); INVLPG( Addr & ~0xFFF ); return; @@ -475,10 +476,9 @@ int MM_Map(tVAddr VAddr, tPAddr PAddr) } /** - * \fn tVAddr MM_ClearUser() * \brief Clear user's address space */ -tVAddr MM_ClearUser(void) +void MM_ClearUser(void) { Uint i, j; @@ -504,8 +504,6 @@ tVAddr MM_ClearUser(void) INVLPG( &gaPageTable[i*1024] ); } INVLPG( gaPageDir ); - - return *gpPageCR3; } /** @@ -680,18 +678,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 @@ -741,44 +732,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; } /** @@ -858,6 +827,45 @@ Uint MM_GetFlags(tVAddr VAddr) return ret; } +/** + * \brief Check if the provided buffer is valid + * \return Boolean valid + */ +int MM_IsValidBuffer(tVAddr Addr, size_t Size) +{ + int bIsUser; + int dir, tab; + + Size += Addr & (PAGE_SIZE-1); + Addr &= ~(PAGE_SIZE-1); + + dir = Addr >> 22; + tab = Addr >> 12; + +// Debug("Addr = %p, Size = 0x%x, dir = %i, tab = %i", Addr, Size, dir, tab); + + if( !(gaPageDir[dir] & 1) ) return 0; + if( !(gaPageTable[tab] & 1) ) return 0; + + bIsUser = !!(gaPageTable[tab] & PF_USER); + + while( Size >= PAGE_SIZE ) + { + if( (tab & 1023) == 0 ) + { + dir ++; + if( !(gaPageDir[dir] & 1) ) return 0; + } + + if( !(gaPageTable[tab] & 1) ) return 0; + if( bIsUser && !(gaPageTable[tab] & PF_USER) ) return 0; + + tab ++; + Size -= PAGE_SIZE; + } + return 1; +} + /** * \fn tPAddr MM_DuplicatePage(tVAddr VAddr) * \brief Duplicates a virtual page to a physical one