diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp index bbb04a39c8..325a824270 100644 --- a/Kernel/Arch/i386/CPU.cpp +++ b/Kernel/Arch/i386/CPU.cpp @@ -215,7 +215,7 @@ void page_fault_handler(TrapFrame* trap) #ifdef PAGE_FAULT_DEBUG u32 fault_page_directory = read_cr3(); - dbg() << "Ring " << (regs.cs & 3) + dbg() << "CPU #" << (Processor::is_initialized() ? Processor::current().id() : 0) << " ring " << (regs.cs & 3) << " " << (regs.exception_code & 1 ? "PV" : "NP") << " page fault in PD=" << String::format("%x", fault_page_directory) << ", " << (regs.exception_code & 8 ? "reserved-bit " : "") @@ -831,6 +831,7 @@ void Processor::initialize(u32 cpu) m_idle_thread = nullptr; m_current_thread = nullptr; + m_mm_data = nullptr; gdt_init(); if (cpu == 0) @@ -859,7 +860,7 @@ void Processor::initialize(u32 cpu) (*s_processors)[cpu] = this; } - klog() << "CPU #" << cpu << " using Processor at " << VirtualAddress(FlatPtr(this)); + klog() << "CPU[" << cpu << "]: initialized Processor at " << VirtualAddress(FlatPtr(this)); } void Processor::write_raw_gdt_entry(u16 selector, u32 low, u32 high) diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h index e1840e1a0c..0e2df7c357 100644 --- a/Kernel/Arch/i386/CPU.h +++ b/Kernel/Arch/i386/CPU.h @@ -611,6 +611,7 @@ struct TrapFrame; #define GDT_SELECTOR_TSS 0x38 class ProcessorInfo; +struct MemoryManagerData; class Processor { Processor* m_self; // must be first field (%fs offset 0x0) @@ -626,6 +627,7 @@ class Processor { static FPUState s_clean_fpu_state; ProcessorInfo* m_info; + MemoryManagerData* m_mm_data; Thread* m_current_thread; Thread* m_idle_thread; @@ -668,6 +670,16 @@ public: return get_fs() == GDT_SELECTOR_PROC && read_fs_u32(0) != 0; } + ALWAYS_INLINE void set_mm_data(MemoryManagerData& mm_data) + { + m_mm_data = &mm_data; + } + + ALWAYS_INLINE MemoryManagerData& get_mm_data() const + { + return *m_mm_data; + } + ALWAYS_INLINE Thread* idle_thread() const { return m_idle_thread; diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index 5be14ff06b..b43bd9c0f5 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -207,9 +207,16 @@ PageTableEntry& MemoryManager::ensure_pte(PageDirectory& page_directory, Virtual return quickmap_pt(PhysicalAddress((FlatPtr)pde.page_table_base()))[page_table_index]; } -void MemoryManager::initialize() +void MemoryManager::initialize(u32 cpu) { - s_the = new MemoryManager; + auto mm_data = new MemoryManagerData; +#ifdef MM_DEBUG + dbg() << "MM: Processor #" << cpu << " specific data at " << VirtualAddress(mm_data); +#endif + Processor::current().set_mm_data(*mm_data); + + if (cpu == 0) + s_the = new MemoryManager; } Region* MemoryManager::kernel_region_from_vaddr(VirtualAddress vaddr) @@ -566,50 +573,56 @@ PageDirectoryEntry* MemoryManager::quickmap_pd(PageDirectory& directory, size_t PageTableEntry* MemoryManager::quickmap_pt(PhysicalAddress pt_paddr) { ScopedSpinLock lock(s_lock); - auto& pte = boot_pd3_pt1023[8]; + auto& pte = boot_pd3_pt1023[0]; if (pte.physical_page_base() != pt_paddr.as_ptr()) { #ifdef MM_DEBUG - dbg() << "quickmap_pt: Mapping P" << (void*)pt_paddr.as_ptr() << " at 0xffe08000 in pte @ " << &pte; + dbg() << "quickmap_pt: Mapping P" << (void*)pt_paddr.as_ptr() << " at 0xffe00000 in pte @ " << &pte; #endif pte.set_physical_page_base(pt_paddr.get()); pte.set_present(true); pte.set_writable(true); pte.set_user_allowed(false); - flush_tlb(VirtualAddress(0xffe08000)); + flush_tlb(VirtualAddress(0xffe00000)); } - return (PageTableEntry*)0xffe08000; + return (PageTableEntry*)0xffe00000; } u8* MemoryManager::quickmap_page(PhysicalPage& physical_page) { ASSERT_INTERRUPTS_DISABLED(); + auto& mm_data = get_data(); + mm_data.m_quickmap_in_use.lock(); ScopedSpinLock lock(s_lock); - ASSERT(!m_quickmap_in_use); - m_quickmap_in_use = true; - auto& pte = boot_pd3_pt1023[0]; + u32 pte_idx = 8 + Processor::current().id(); + VirtualAddress vaddr(0xffe00000 + pte_idx * PAGE_SIZE); + + auto& pte = boot_pd3_pt1023[pte_idx]; if (pte.physical_page_base() != physical_page.paddr().as_ptr()) { #ifdef MM_DEBUG - dbg() << "quickmap_page: Mapping P" << (void*)physical_page.paddr().as_ptr() << " at 0xffe00000 in pte @ " << &pte; + dbg() << "quickmap_page: Mapping P" << (void*)physical_page.paddr().as_ptr() << " at 0xffe08000 in pte @ " << &pte; #endif pte.set_physical_page_base(physical_page.paddr().get()); pte.set_present(true); pte.set_writable(true); pte.set_user_allowed(false); - flush_tlb(VirtualAddress(0xffe00000)); + flush_tlb(vaddr); } - return (u8*)0xffe00000; + return vaddr.as_ptr(); } void MemoryManager::unquickmap_page() { ASSERT_INTERRUPTS_DISABLED(); ScopedSpinLock lock(s_lock); - ASSERT(m_quickmap_in_use); - auto& pte = boot_pd3_pt1023[0]; + auto& mm_data = get_data(); + ASSERT(mm_data.m_quickmap_in_use.is_locked()); + u32 pte_idx = 8 + Processor::current().id(); + VirtualAddress vaddr(0xffe00000 + pte_idx * PAGE_SIZE); + auto& pte = boot_pd3_pt1023[pte_idx]; pte.clear(); - flush_tlb(VirtualAddress(0xffe00000)); - m_quickmap_in_use = false; + flush_tlb(vaddr); + mm_data.m_quickmap_in_use.unlock(); } template diff --git a/Kernel/VM/MemoryManager.h b/Kernel/VM/MemoryManager.h index 6c27ca766e..c9e72fd1bc 100644 --- a/Kernel/VM/MemoryManager.h +++ b/Kernel/VM/MemoryManager.h @@ -67,6 +67,10 @@ class SynthFSInode; #define MM Kernel::MemoryManager::the() +struct MemoryManagerData { + SpinLock m_quickmap_in_use; +}; + class MemoryManager { AK_MAKE_ETERNAL friend class PageDirectory; @@ -80,7 +84,12 @@ class MemoryManager { public: static MemoryManager& the(); - static void initialize(); + static void initialize(u32 cpu); + + static inline MemoryManagerData& get_data() + { + return Processor::current().get_mm_data(); + } PageFaultResponse handle_page_fault(const PageFault&); @@ -204,8 +213,6 @@ private: static RecursiveSpinLock s_lock; - bool m_quickmap_in_use { false }; - RefPtr m_low_pseudo_identity_mapping_pages[4]; }; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 9f90528c19..c85c980197 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -114,7 +114,7 @@ extern "C" [[noreturn]] void init() } CommandLine::initialize(reinterpret_cast(low_physical_to_virtual(multiboot_info_ptr->cmdline))); - MemoryManager::initialize(); + MemoryManager::initialize(0); // Invoke all static global constructors in the kernel. // Note that we want to do this as early as possible. @@ -168,6 +168,7 @@ extern "C" [[noreturn]] void init_ap(u32 cpu, Processor* processor_info) klog() << "CPU #" << cpu << " processor_info at " << VirtualAddress(FlatPtr(processor_info)); cpu_setup(cpu); processor_info->initialize(cpu); + MemoryManager::initialize(cpu); APIC::the().enable(cpu);