X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Farch%2Fx86_64%2Fmm_virt.c;h=e2e779db1a87716a7b41c64b59b28566bb0dd39c;hb=e2744a459d1c63435d7348d0bfd0e4b92b0ec9f9;hp=89aeaa15be9072ae6a3851f827248c9be74aaecb;hpb=51ab5f489bc356940c95cc936fd0508e8f07ea97;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/arch/x86_64/mm_virt.c b/KernelLand/Kernel/arch/x86_64/mm_virt.c index 89aeaa15..e2e779db 100644 --- a/KernelLand/Kernel/arch/x86_64/mm_virt.c +++ b/KernelLand/Kernel/arch/x86_64/mm_virt.c @@ -128,9 +128,9 @@ void MM_int_ClonePageEnt( Uint64 *Ent, void *NextLevel, tVAddr Addr, int bTable ASSERT(paddr != curpage); - tmp = (void*)MM_MapTemp(paddr); + tmp = MM_MapTemp(paddr); memcpy( tmp, NextLevel, 0x1000 ); - MM_FreeTemp( (tVAddr)tmp ); + MM_FreeTemp( tmp ); #if TRACE_COW Log_Debug("MMVirt", "COW ent at %p (%p) from %P to %P", Ent, NextLevel, curpage, paddr); @@ -269,9 +269,9 @@ void MM_int_DumpTablesEnt(tVAddr RangeStart, size_t Length, tPAddr Expected) #define CANOICAL(addr) ((addr)&0x800000000000?(addr)|0xFFFF000000000000:(addr)) LogF("%016llx => ", CANOICAL(RangeStart)); // LogF("%6llx %6llx %6llx %016llx => ", -// MM_GetPhysAddr( (tVAddr)&PAGEDIRPTR(RangeStart>>30) ), -// MM_GetPhysAddr( (tVAddr)&PAGEDIR(RangeStart>>21) ), -// MM_GetPhysAddr( (tVAddr)&PAGETABLE(RangeStart>>12) ), +// MM_GetPhysAddr( &PAGEDIRPTR(RangeStart>>30) ), +// MM_GetPhysAddr( &PAGEDIR(RangeStart>>21) ), +// MM_GetPhysAddr( &PAGETABLE(RangeStart>>12) ), // CANOICAL(RangeStart) // ); if( gMM_ZeroPage && (PAGETABLE(RangeStart>>12) & PADDR_MASK) == gMM_ZeroPage ) @@ -340,8 +340,8 @@ void MM_DumpTables(tVAddr Start, tVAddr End) expected |= expected_pml4 & PF_NX; expected |= expected_pdp & PF_NX; expected |= expected_pd & PF_NX; - Log("expected (pml4 = %x, pdp = %x, pd = %x)", - expected_pml4, expected_pdp, expected_pd); +// Log("expected (pml4 = %x, pdp = %x, pd = %x)", +// expected_pml4, expected_pdp, expected_pd); // Dump MM_int_DumpTablesEnt( rangeStart, curPos - rangeStart, expected ); expected = CHANGEABLE_BITS; @@ -576,7 +576,7 @@ void MM_Deallocate(tVAddr VAddr) { tPAddr phys; - phys = MM_GetPhysAddr(VAddr); + phys = MM_GetPhysAddr( (void*)VAddr ); if(!phys) return ; MM_Unmap(VAddr); @@ -609,8 +609,9 @@ int MM_GetPageEntry(tVAddr Addr, tPAddr *Phys, Uint *Flags) /** * \brief Get the physical address of a virtual location */ -tPAddr MM_GetPhysAddr(tVAddr Addr) +tPAddr MM_GetPhysAddr(volatile const void *Ptr) { + tVAddr Addr = (tVAddr)Ptr; tPAddr *ptr; int ret; @@ -721,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; } @@ -766,7 +797,7 @@ int MM_IsValidBuffer(tVAddr Addr, size_t Size) /** * \brief Map a range of hardware pages */ -tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number) +void *MM_MapHWPages(tPAddr PAddr, Uint Number) { tVAddr ret; int num; @@ -776,7 +807,8 @@ tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number) { for( num = Number; num -- && ret < MM_HWMAP_TOP; ret += 0x1000 ) { - if( MM_GetPhysAddr(ret) != 0 ) break; + if( MM_GetPhysAddr( (void*)ret ) != 0 ) + break; } if( num >= 0 ) continue; @@ -792,7 +824,7 @@ tVAddr MM_MapHWPages(tPAddr PAddr, Uint Number) MM_RefPhys(PAddr); } - return ret; + return (void*)ret; } Log_Error("MM", "MM_MapHWPages - No space for %i pages", Number); @@ -807,7 +839,7 @@ void MM_UnmapHWPages(tVAddr VAddr, Uint Number) // Log_KernelPanic("MM", "TODO: Implement MM_UnmapHWPages"); while( Number -- ) { - MM_DerefPhys( MM_GetPhysAddr(VAddr) ); + MM_DerefPhys( MM_GetPhysAddr((void*)VAddr) ); MM_Unmap(VAddr); VAddr += 0x1000; } @@ -822,10 +854,10 @@ void MM_UnmapHWPages(tVAddr VAddr, Uint Number) * \param PhysAddr Pointer to the location to place the physical address allocated * \return Virtual address allocate */ -tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr) +void *MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr) { tPAddr phys; - tVAddr ret; + void *ret; // Sanity Check if(MaxBits < 12 || !PhysAddr) return 0; @@ -847,6 +879,7 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr) // Allocated successfully, now map ret = MM_MapHWPages(phys, Pages); + *PhysAddr = phys; // MapHWPages references the pages, so deref them back down to 1 for(;Pages--;phys+=0x1000) MM_DerefPhys(phys); @@ -855,12 +888,11 @@ tVAddr MM_AllocDMA(int Pages, int MaxBits, tPAddr *PhysAddr) return 0; } - *PhysAddr = phys; return ret; } // --- Tempory Mappings --- -tVAddr MM_MapTemp(tPAddr PAddr) +void *MM_MapTemp(tPAddr PAddr) { const int max_slots = (MM_TMPMAP_END - MM_TMPMAP_BASE) / PAGE_SIZE; tVAddr ret = MM_TMPMAP_BASE; @@ -879,20 +911,20 @@ tVAddr MM_MapTemp(tPAddr PAddr) *ent = PAddr | 3; MM_RefPhys(PAddr); INVLPG(ret); - return ret; + return (void*)ret; } return 0; } -void MM_FreeTemp(tVAddr VAddr) +void MM_FreeTemp(void *Ptr) { - MM_Deallocate(VAddr); + MM_Deallocate((tVAddr)Ptr); return ; } // --- Address Space Clone -- -tPAddr MM_Clone(void) +tPAddr MM_Clone(int bNoUserCopy) { tPAddr ret; int i; @@ -908,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 ++) { @@ -966,14 +998,14 @@ tPAddr MM_Clone(void) for( i = 1; i < KERNEL_STACK_SIZE/0x1000; i ++ ) { tPAddr phys = MM_AllocPhys(); - tVAddr tmpmapping; + void *tmpmapping; MM_MapEx(kstackbase+i*0x1000, phys, 1, 0); tmpmapping = MM_MapTemp(phys); - if( MM_GetPhysAddr( kstackbase+i*0x1000 ) ) - memcpy((void*)tmpmapping, (void*)(kstackbase+i*0x1000), 0x1000); + if( MM_GetPhysAddr( (void*)(kstackbase+i*0x1000) ) ) + memcpy(tmpmapping, (void*)(kstackbase+i*0x1000), 0x1000); else - memset((void*)tmpmapping, 0, 0x1000); + memset(tmpmapping, 0, 0x1000); // if( i == 0xF ) // Debug_HexDump("MM_Clone: *tmpmapping = ", (void*)tmpmapping, 0x1000); MM_FreeTemp(tmpmapping); @@ -1018,7 +1050,7 @@ void MM_int_ClearTableLevel(tVAddr VAddr, int LevelBits, int MaxEnts) void MM_ClearUser(void) { - MM_int_ClearTableLevel(0, 39, 256); + MM_int_ClearTableLevel(0, 39, 256); } tVAddr MM_NewWorkerStack(void *StackData, size_t StackSize) @@ -1064,12 +1096,10 @@ tVAddr MM_NewWorkerStack(void *StackData, size_t StackSize) Log_Error("MM", "MM_NewWorkerStack: StackSize(0x%x) > 0x1000, cbf handling", StackSize); } else { - tVAddr tmp_addr, dest; + void *tmp_addr, *dest; tmp_addr = MM_MapTemp(phys); - dest = tmp_addr + (0x1000 - StackSize); - memcpy( (void*)dest, StackData, StackSize ); - Log_Debug("MM", "MM_NewWorkerStack: %p->%p %i bytes (i=%i)", StackData, dest, StackSize, i); - Log_Debug("MM", "MM_NewWorkerStack: ret = %p", ret); + dest = (char*)tmp_addr + (0x1000 - StackSize); + memcpy( dest, StackData, StackSize ); MM_FreeTemp(tmp_addr); } @@ -1088,7 +1118,7 @@ tVAddr MM_NewKStack(void) Uint i; for( ; base < MM_KSTACK_TOP; base += KERNEL_STACK_SIZE ) { - if(MM_GetPhysAddr(base+KERNEL_STACK_SIZE-0x1000) != 0) + if(MM_GetPhysAddr( (void*)(base+KERNEL_STACK_SIZE-0x1000) ) != 0) continue; //Log("MM_NewKStack: Found one at %p", base + KERNEL_STACK_SIZE);