summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-11-03 23:40:10 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-11-03 23:51:55 +0100
commit5b7f8634e3f62643fdfdb879f9fb3dc9163d40fe (patch)
treef5c8dac18d34aa747e89c2af6621c455f1b4d08f /Kernel
parent4bf1a72d2158f7a1531f643444cb896558094973 (diff)
downloadserenity-5b7f8634e3f62643fdfdb879f9fb3dc9163d40fe.zip
Kernel: Set the G (global) bit for kernel page tables
Since the kernel page tables are shared between all processes, there's no need to (implicitly) flush the TLB for them on every context switch. Setting the G bit on kernel page tables allows the CPU to keep the translation caches around.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Arch/i386/CPU.h12
-rw-r--r--Kernel/VM/MemoryManager.cpp9
2 files changed, 19 insertions, 2 deletions
diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h
index 5cdcfa4467..2af084c7a3 100644
--- a/Kernel/Arch/i386/CPU.h
+++ b/Kernel/Arch/i386/CPU.h
@@ -104,6 +104,7 @@ public:
UserSupervisor = 1 << 2,
WriteThrough = 1 << 3,
CacheDisabled = 1 << 4,
+ Global = 1 << 8,
};
bool is_present() const { return raw() & Present; }
@@ -121,7 +122,10 @@ public:
bool is_cache_disabled() const { return raw() & CacheDisabled; }
void set_cache_disabled(bool b) { set_bit(CacheDisabled, b); }
- void set_bit(u8 bit, bool value)
+ bool is_global() const { return raw() & Global; }
+ void set_global(bool b) { set_bit(Global, b); }
+
+ void set_bit(u32 bit, bool value)
{
if (value)
m_raw |= bit;
@@ -152,6 +156,7 @@ public:
UserSupervisor = 1 << 2,
WriteThrough = 1 << 3,
CacheDisabled = 1 << 4,
+ Global = 1 << 8,
};
bool is_present() const { return raw() & Present; }
@@ -169,7 +174,10 @@ public:
bool is_cache_disabled() const { return raw() & CacheDisabled; }
void set_cache_disabled(bool b) { set_bit(CacheDisabled, b); }
- void set_bit(u8 bit, bool value)
+ bool is_global() const { return raw() & Global; }
+ void set_global(bool b) { set_bit(Global, b); }
+
+ void set_bit(u32 bit, bool value)
{
if (value)
m_raw |= bit;
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp
index 67cddbf144..1d7f87e8c3 100644
--- a/Kernel/VM/MemoryManager.cpp
+++ b/Kernel/VM/MemoryManager.cpp
@@ -158,6 +158,12 @@ void MemoryManager::initialize_paging()
dbgprintf("MM: Installing page directory\n");
#endif
+ // Turn on CR4.PGE so the CPU will respect the G bit in page tables.
+ asm volatile(
+ "mov %cr4, %eax\n"
+ "orl $0x10, %eax\n"
+ "mov %eax, %cr4\n");
+
asm volatile("movl %%eax, %%cr3" ::"a"(kernel_page_directory().cr3()));
asm volatile(
"movl %%cr0, %%eax\n"
@@ -187,12 +193,14 @@ PageTableEntry& MemoryManager::ensure_pte(PageDirectory& page_directory, Virtual
pde.set_user_allowed(false);
pde.set_present(true);
pde.set_writable(true);
+ pde.set_global(true);
} else if (page_directory_index == 1) {
ASSERT(&page_directory == m_kernel_page_directory);
pde.set_page_table_base((u32)m_page_table_one);
pde.set_user_allowed(false);
pde.set_present(true);
pde.set_writable(true);
+ pde.set_global(true);
} else {
//ASSERT(&page_directory != m_kernel_page_directory.ptr());
auto page_table = allocate_supervisor_physical_page();
@@ -210,6 +218,7 @@ PageTableEntry& MemoryManager::ensure_pte(PageDirectory& page_directory, Virtual
pde.set_user_allowed(true);
pde.set_present(true);
pde.set_writable(true);
+ pde.set_global(&page_directory == m_kernel_page_directory.ptr());
page_directory.m_physical_pages.set(page_directory_index, move(page_table));
}
}