mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 21:47:43 +00:00
Kernel: Make ProcessPagingScope restore CR3 properly
Instead of restoring CR3 to the current process's paging scope when a ProcessPagingScope goes out of scope, we now restore exactly whatever the CR3 value was when we created the ProcessPagingScope. This fixes breakage in situations where a process ends up with nested ProcessPagingScopes. This was making profiling very fragile, and with this change it's now possible to profile g++! :^)
This commit is contained in:
parent
ad3f931707
commit
6eab7b398d
3 changed files with 16 additions and 7 deletions
|
@ -734,7 +734,8 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
|
||||||
#ifdef MM_DEBUG
|
#ifdef MM_DEBUG
|
||||||
dbgprintf("Process %u exec: PD=%x created\n", pid(), m_page_directory.ptr());
|
dbgprintf("Process %u exec: PD=%x created\n", pid(), m_page_directory.ptr());
|
||||||
#endif
|
#endif
|
||||||
ProcessPagingScope paging_scope(*this);
|
|
||||||
|
MM.enter_process_paging_scope(*this);
|
||||||
|
|
||||||
Region* region { nullptr };
|
Region* region { nullptr };
|
||||||
|
|
||||||
|
@ -775,11 +776,10 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
|
||||||
m_regions.append(move(executable_region));
|
m_regions.append(move(executable_region));
|
||||||
|
|
||||||
ArmedScopeGuard rollback_regions_guard([&]() {
|
ArmedScopeGuard rollback_regions_guard([&]() {
|
||||||
m_page_directory = move(old_page_directory);
|
|
||||||
ASSERT(¤t->process() == this);
|
ASSERT(¤t->process() == this);
|
||||||
MM.enter_process_paging_scope(*this);
|
m_page_directory = move(old_page_directory);
|
||||||
executable_region = m_regions.take_first();
|
|
||||||
m_regions = move(old_regions);
|
m_regions = move(old_regions);
|
||||||
|
MM.enter_process_paging_scope(*this);
|
||||||
});
|
});
|
||||||
|
|
||||||
loader = make<ELFLoader>(region->vaddr().as_ptr(), loader_metadata.size);
|
loader = make<ELFLoader>(region->vaddr().as_ptr(), loader_metadata.size);
|
||||||
|
|
|
@ -682,10 +682,15 @@ void MemoryManager::dump_kernel_regions()
|
||||||
ProcessPagingScope::ProcessPagingScope(Process& process)
|
ProcessPagingScope::ProcessPagingScope(Process& process)
|
||||||
{
|
{
|
||||||
ASSERT(current);
|
ASSERT(current);
|
||||||
|
asm("movl %%cr3, %%eax"
|
||||||
|
: "=a"(m_previous_cr3));
|
||||||
MM.enter_process_paging_scope(process);
|
MM.enter_process_paging_scope(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessPagingScope::~ProcessPagingScope()
|
ProcessPagingScope::~ProcessPagingScope()
|
||||||
{
|
{
|
||||||
MM.enter_process_paging_scope(current->process());
|
InterruptDisabler disabler;
|
||||||
|
current->tss().cr3 = m_previous_cr3;
|
||||||
|
asm volatile("movl %%eax, %%cr3" ::"a"(m_previous_cr3)
|
||||||
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,9 +190,13 @@ private:
|
||||||
bool m_quickmap_in_use { false };
|
bool m_quickmap_in_use { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProcessPagingScope {
|
class ProcessPagingScope {
|
||||||
ProcessPagingScope(Process&);
|
public:
|
||||||
|
explicit ProcessPagingScope(Process&);
|
||||||
~ProcessPagingScope();
|
~ProcessPagingScope();
|
||||||
|
|
||||||
|
private:
|
||||||
|
u32 m_previous_cr3 { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue