From cc248cf2b37b96f8f86d652e0121be105b23d192 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Sun, 8 Jul 2012 11:56:06 +0100 Subject: [PATCH] A couple of bug fixes. * mmu_get_virtual_mapping() should check that the page directory entry is present rather than assuming there's a page table there. This was resulting in some invalid mappings being created in the 64-bit virtual address space. * arch_vm_init_end() should clear from KERNEL_LOAD_BASE to virtual_end, not from KERNEL_BASE. On x86_64 this was causing it to loop through ~512GB of address space, which obviously was taking quite a while. --- src/system/boot/platform/bios_ia32/mmu.cpp | 17 +++++++++-------- src/system/kernel/arch/x86/arch_cpu.cpp | 3 --- src/system/kernel/arch/x86/arch_vm.cpp | 4 ++-- .../paging/64bit/X86VMTranslationMap64Bit.cpp | 3 ++- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/system/boot/platform/bios_ia32/mmu.cpp b/src/system/boot/platform/bios_ia32/mmu.cpp index 1046b70116..05167e7c3c 100644 --- a/src/system/boot/platform/bios_ia32/mmu.cpp +++ b/src/system/boot/platform/bios_ia32/mmu.cpp @@ -512,17 +512,18 @@ mmu_get_virtual_mapping(addr_t virtualAddress, addr_t *_physicalAddress) (void *)virtualAddress); } - uint32 *pageTable = (uint32 *)(sPageDirectory[virtualAddress - / (B_PAGE_SIZE * 1024)] & 0xfffff000); + uint32 dirEntry = sPageDirectory[virtualAddress / (B_PAGE_SIZE * 1024)]; + if ((dirEntry & (1 << 0)) == 0) + return false; + + uint32 *pageTable = (uint32 *)(dirEntry & 0xfffff000); uint32 tableEntry = pageTable[(virtualAddress % (B_PAGE_SIZE * 1024)) / B_PAGE_SIZE]; - - if ((tableEntry & (1<<0)) != 0) { - *_physicalAddress = tableEntry & 0xFFFFF000; - return true; - } else { + if ((tableEntry & (1 << 0)) == 0) return false; - } + + *_physicalAddress = tableEntry & 0xFFFFF000; + return true; } diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 6a7a2069b1..2edd3c392d 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -897,10 +897,7 @@ arch_cpu_init_post_vm(kernel_args* args) } #endif - // TODO x86_64 -#ifndef __x86_64 if (!apic_available()) -#endif x86_init_fpu(); // else fpu gets set up in smp code diff --git a/src/system/kernel/arch/x86/arch_vm.cpp b/src/system/kernel/arch/x86/arch_vm.cpp index 8fe04923de..f5948e13a2 100644 --- a/src/system/kernel/arch/x86/arch_vm.cpp +++ b/src/system/kernel/arch/x86/arch_vm.cpp @@ -672,8 +672,8 @@ arch_vm_init_end(kernel_args *args) TRACE(("arch_vm_init_endvm: entry\n")); // throw away anything in the kernel_args.pgtable[] that's not yet mapped - vm_free_unused_boot_loader_range(KERNEL_BASE, - args->arch_args.virtual_end - KERNEL_BASE); + vm_free_unused_boot_loader_range(KERNEL_LOAD_BASE, + args->arch_args.virtual_end - KERNEL_LOAD_BASE); return B_OK; } diff --git a/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp index 24e85c2cde..2217bfe16b 100644 --- a/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp +++ b/src/system/kernel/arch/x86/paging/64bit/X86VMTranslationMap64Bit.cpp @@ -539,7 +539,8 @@ X86VMTranslationMap64Bit::Query(addr_t virtualAddress, | ((entry & X86_64_PTE_PRESENT) != 0 ? PAGE_PRESENT : 0); TRACE("X86VMTranslationMap64Bit::Query(%#" B_PRIxADDR ") -> %#" - B_PRIxPHYSADDR ":\n", virtualAddress, *_physicalAddress); + B_PRIxPHYSADDR " %#" B_PRIx32 " (pte: %p %#" B_PRIx64 ")\n", + virtualAddress, *_physicalAddress, *_flags, pte, entry); return B_OK; }