1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 01:58:12 +00:00

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.
This commit is contained in:
Andreas Kling 2019-11-03 23:40:10 +01:00
parent 4bf1a72d21
commit 5b7f8634e3
2 changed files with 19 additions and 2 deletions

View file

@ -104,6 +104,7 @@ public:
UserSupervisor = 1 << 2, UserSupervisor = 1 << 2,
WriteThrough = 1 << 3, WriteThrough = 1 << 3,
CacheDisabled = 1 << 4, CacheDisabled = 1 << 4,
Global = 1 << 8,
}; };
bool is_present() const { return raw() & Present; } bool is_present() const { return raw() & Present; }
@ -121,7 +122,10 @@ public:
bool is_cache_disabled() const { return raw() & CacheDisabled; } bool is_cache_disabled() const { return raw() & CacheDisabled; }
void set_cache_disabled(bool b) { set_bit(CacheDisabled, b); } 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) if (value)
m_raw |= bit; m_raw |= bit;
@ -152,6 +156,7 @@ public:
UserSupervisor = 1 << 2, UserSupervisor = 1 << 2,
WriteThrough = 1 << 3, WriteThrough = 1 << 3,
CacheDisabled = 1 << 4, CacheDisabled = 1 << 4,
Global = 1 << 8,
}; };
bool is_present() const { return raw() & Present; } bool is_present() const { return raw() & Present; }
@ -169,7 +174,10 @@ public:
bool is_cache_disabled() const { return raw() & CacheDisabled; } bool is_cache_disabled() const { return raw() & CacheDisabled; }
void set_cache_disabled(bool b) { set_bit(CacheDisabled, b); } 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) if (value)
m_raw |= bit; m_raw |= bit;

View file

@ -158,6 +158,12 @@ void MemoryManager::initialize_paging()
dbgprintf("MM: Installing page directory\n"); dbgprintf("MM: Installing page directory\n");
#endif #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 %%eax, %%cr3" ::"a"(kernel_page_directory().cr3()));
asm volatile( asm volatile(
"movl %%cr0, %%eax\n" "movl %%cr0, %%eax\n"
@ -187,12 +193,14 @@ PageTableEntry& MemoryManager::ensure_pte(PageDirectory& page_directory, Virtual
pde.set_user_allowed(false); pde.set_user_allowed(false);
pde.set_present(true); pde.set_present(true);
pde.set_writable(true); pde.set_writable(true);
pde.set_global(true);
} else if (page_directory_index == 1) { } else if (page_directory_index == 1) {
ASSERT(&page_directory == m_kernel_page_directory); ASSERT(&page_directory == m_kernel_page_directory);
pde.set_page_table_base((u32)m_page_table_one); pde.set_page_table_base((u32)m_page_table_one);
pde.set_user_allowed(false); pde.set_user_allowed(false);
pde.set_present(true); pde.set_present(true);
pde.set_writable(true); pde.set_writable(true);
pde.set_global(true);
} else { } else {
//ASSERT(&page_directory != m_kernel_page_directory.ptr()); //ASSERT(&page_directory != m_kernel_page_directory.ptr());
auto page_table = allocate_supervisor_physical_page(); 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_user_allowed(true);
pde.set_present(true); pde.set_present(true);
pde.set_writable(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)); page_directory.m_physical_pages.set(page_directory_index, move(page_table));
} }
} }