mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 10:27:35 +00:00
Kernel: More gracefully handle out-of-memory when creating PageDirectory
This commit is contained in:
parent
ae956edf6e
commit
bf9be3ec01
3 changed files with 23 additions and 5 deletions
|
@ -284,11 +284,15 @@ KResultOr<Process::LoadResult> Process::load(NonnullRefPtr<FileDescription> main
|
|||
NonnullOwnPtrVector<Region> old_regions;
|
||||
|
||||
{
|
||||
auto page_directory = PageDirectory::create_for_userspace(*this);
|
||||
if (!page_directory)
|
||||
return KResult(-ENOMEM);
|
||||
|
||||
// Need to make sure we don't swap contexts in the middle
|
||||
ScopedCritical critical;
|
||||
old_page_directory = move(m_page_directory);
|
||||
old_regions = move(m_regions);
|
||||
m_page_directory = PageDirectory::create_for_userspace(*this);
|
||||
m_page_directory = page_directory.release_nonnull();
|
||||
}
|
||||
|
||||
ArmedScopeGuard rollback_regions_guard([&]() {
|
||||
|
|
|
@ -74,7 +74,6 @@ PageDirectory::PageDirectory()
|
|||
}
|
||||
|
||||
PageDirectory::PageDirectory(Process& process, const RangeAllocator* parent_range_allocator)
|
||||
: m_process(&process)
|
||||
{
|
||||
ScopedSpinLock lock(s_mm_lock);
|
||||
if (parent_range_allocator) {
|
||||
|
@ -87,9 +86,17 @@ PageDirectory::PageDirectory(Process& process, const RangeAllocator* parent_rang
|
|||
|
||||
// Set up a userspace page directory
|
||||
m_directory_table = MM.allocate_user_physical_page();
|
||||
if (!m_directory_table)
|
||||
return;
|
||||
m_directory_pages[0] = MM.allocate_user_physical_page();
|
||||
if (!m_directory_pages[0])
|
||||
return;
|
||||
m_directory_pages[1] = MM.allocate_user_physical_page();
|
||||
if (!m_directory_pages[1])
|
||||
return;
|
||||
m_directory_pages[2] = MM.allocate_user_physical_page();
|
||||
if (!m_directory_pages[2])
|
||||
return;
|
||||
// Share the top 1 GiB of kernel-only mappings (>=3GiB or >=0xc0000000)
|
||||
m_directory_pages[3] = MM.kernel_page_directory().m_directory_pages[3];
|
||||
|
||||
|
@ -135,6 +142,9 @@ PageDirectory::PageDirectory(Process& process, const RangeAllocator* parent_rang
|
|||
auto* new_pd = MM.quickmap_pd(*this, 0);
|
||||
memcpy(new_pd, &buffer, sizeof(PageDirectoryEntry));
|
||||
|
||||
// If we got here, we successfully created it. Set m_process now
|
||||
m_process = &process;
|
||||
|
||||
cr3_map().set(cr3(), this);
|
||||
}
|
||||
|
||||
|
@ -144,6 +154,7 @@ PageDirectory::~PageDirectory()
|
|||
dbg() << "MM: ~PageDirectory K" << this;
|
||||
#endif
|
||||
ScopedSpinLock lock(s_mm_lock);
|
||||
if (m_process)
|
||||
cr3_map().remove(cr3());
|
||||
}
|
||||
|
||||
|
|
|
@ -40,9 +40,12 @@ class PageDirectory : public RefCounted<PageDirectory> {
|
|||
friend class MemoryManager;
|
||||
|
||||
public:
|
||||
static NonnullRefPtr<PageDirectory> create_for_userspace(Process& process, const RangeAllocator* parent_range_allocator = nullptr)
|
||||
static RefPtr<PageDirectory> create_for_userspace(Process& process, const RangeAllocator* parent_range_allocator = nullptr)
|
||||
{
|
||||
return adopt(*new PageDirectory(process, parent_range_allocator));
|
||||
auto page_directory = adopt(*new PageDirectory(process, parent_range_allocator));
|
||||
if (!page_directory->process())
|
||||
return {};
|
||||
return page_directory;
|
||||
}
|
||||
static NonnullRefPtr<PageDirectory> create_kernel_page_directory() { return adopt(*new PageDirectory); }
|
||||
static RefPtr<PageDirectory> find_by_cr3(u32);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue