Kernel: Make on-demand paging thread safe
This commit is contained in:
parent
d25a5034db
commit
927fbda1e8
|
@ -220,7 +220,7 @@ namespace Kernel
|
|||
// Returns error if page could not be allocated
|
||||
// Returns true if the page was allocated successfully
|
||||
// Return false if access was page violation (segfault)
|
||||
BAN::ErrorOr<bool> allocate_page_for_demand_paging(vaddr_t addr, bool wants_write);
|
||||
BAN::ErrorOr<bool> allocate_page_for_demand_paging(vaddr_t addr, bool wants_write, bool wants_exec);
|
||||
|
||||
// FIXME: remove this API
|
||||
BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const;
|
||||
|
|
|
@ -214,7 +214,7 @@ namespace Kernel
|
|||
page_fault_error.raw = error;
|
||||
|
||||
Processor::set_interrupt_state(InterruptState::Enabled);
|
||||
auto result = Process::current().allocate_page_for_demand_paging(regs->cr2, page_fault_error.write);
|
||||
auto result = Process::current().allocate_page_for_demand_paging(regs->cr2, page_fault_error.write, page_fault_error.instruction);
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
if (!result.is_error() && result.value())
|
||||
|
|
|
@ -981,24 +981,32 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<bool> Process::allocate_page_for_demand_paging(vaddr_t address, bool wants_write)
|
||||
BAN::ErrorOr<bool> Process::allocate_page_for_demand_paging(vaddr_t address, bool wants_write, bool wants_exec)
|
||||
{
|
||||
ASSERT(&Process::current() == this);
|
||||
|
||||
LockGuard _(m_process_lock);
|
||||
|
||||
if (Thread::current().userspace_stack().contains(address))
|
||||
{
|
||||
TRY(Thread::current().userspace_stack().allocate_page_for_demand_paging(address));
|
||||
// NOTE: page can be already allocated by another thread!
|
||||
|
||||
PageTable::flags_t wanted_flags = PageTable::Flags::UserSupervisor | PageTable::Flags::Present;
|
||||
if (wants_write)
|
||||
wanted_flags |= PageTable::Flags::ReadWrite;
|
||||
if (wants_exec)
|
||||
wanted_flags |= PageTable::Flags::Execute;
|
||||
if ((m_page_table->get_page_flags(address & PAGE_ADDR_MASK) & wanted_flags) == wanted_flags)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Thread::current().userspace_stack().contains(address))
|
||||
return Thread::current().userspace_stack().allocate_page_for_demand_paging(address);
|
||||
|
||||
for (auto& region : m_mapped_regions)
|
||||
{
|
||||
if (!region->contains(address))
|
||||
continue;
|
||||
TRY(region->allocate_page_containing(address, wants_write));
|
||||
return true;
|
||||
return region->allocate_page_containing(address, wants_write);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -3112,7 +3120,7 @@ unauthorized_access:
|
|||
const vaddr_t current = page_start + i * PAGE_SIZE;
|
||||
if (page_table().get_page_flags(current) & PageTable::Flags::Present)
|
||||
continue;
|
||||
TRY(Process::allocate_page_for_demand_paging(current, needs_write));
|
||||
TRY(Process::allocate_page_for_demand_paging(current, needs_write, false));
|
||||
}
|
||||
|
||||
return {};
|
||||
|
|
Loading…
Reference in New Issue