Commit graph

50 commits

Author SHA1 Message Date
Andreas Kling a3db0ab14f Kernel: Remove MemoryManager::region_tree() accessor
Let's not have a way to grab at the RegionTree from outside of MM.
2022-04-05 13:45:10 +02:00
Andreas Kling f8d798b667 Kernel: Move allocate_unbacked_region_anywhere() to MemoryManager
This didn't need to be in RegionTree, and since it's specific to kernel
VM anyway, let's move it to MemoryManager.
2022-04-05 13:45:10 +02:00
Andreas Kling e0da8da657 Kernel: Move create_identity_mapped_region() to MemoryManager
This had no business being in RegionTree, since RegionTree doesn't track
identity-mapped regions anyway. (We allow *any* address to be identity
mapped, not just the ones that are part of the RegionTree's range.)
2022-04-05 13:45:10 +02:00
Andreas Kling e852a69a06 LibWeb: Make VM allocation atomic for kernel regions
Instead of first allocating the VM range, and then inserting a region
with that range into the MM region tree, we now do both things in a
single atomic operation:

    - RegionTree::place_anywhere(Region&, size, alignment)
    - RegionTree::place_specifically(Region&, address, size)

To reduce the number of things we do while locking the region tree,
we also require callers to provide a constructed Region object.
2022-04-03 21:51:58 +02:00
Andreas Kling e8f543c390 Kernel: Use intrusive RegionTree solution for kernel regions as well
This patch ports MemoryManager to RegionTree as well. The biggest
difference between this and the userspace code is that kernel regions
are owned by extant OwnPtr<Region> objects spread around the kernel,
while userspace regions are owned by the AddressSpace itself.

For kernelspace, there are a couple of situations where we need to make
large VM reservations that never get backed by regular VMObjects
(for example the kernel image reservation, or the big kmalloc range.)
Since we can't make a VM reservation without a Region object anymore,
this patch adds a way to create unbacked Region objects that can be
used for this exact purpose. They have no internal VMObject.)
2022-04-03 21:51:58 +02:00
James Mintram d79c772c87 Kernel: Make MemoryManager compile on aarch64 2022-04-02 19:34:20 -07:00
Andreas Kling 2ff9db0245 Kernel: Make contiguous VM objects use "user physical pages" by default
If someone specifically wants contiguous memory in the low-physical-
address-for-DMA range ("super pages"), they can use the
allocate_dma_buffer_pages() helper.
2022-02-11 12:45:38 +01:00
Idan Horowitz 5146315a15 Kernel: Convert MemoryManager::allocate_user_physical_page to ErrorOr
This allows is to use the TRY macro at the call sites, instead of using
clunky null checks.
2022-01-28 19:05:52 +02:00
Idan Horowitz bd5b56cab0 Kernel: Make allocate_supervisor_physical_page OOM-fallible 2022-01-28 19:05:52 +02:00
Idan Horowitz 4d2f1a05ec Kernel: Make allocate_contiguous_supervisor_physical_pages OOM-fallible 2022-01-28 19:05:52 +02:00
Marco Cutecchia a7ce0c2297 Kernel: Add missing #include <AK/Badge.h> to MemoryManager.h
This missing header broke the aarch64 build
2022-01-23 14:31:50 +01:00
Andreas Kling df34f7b90b Kernel: Use an IntrusiveRedBlackTree for kernel regions
We were already using a non-intrusive RedBlackTree, and since the kernel
regions tree is non-owning, this is a trivial conversion that makes a
bunch of the tree operations infallible (by being allocation-free.) :^)
2022-01-16 23:31:01 +01:00
Andreas Kling 8e0387e674 Kernel: Only register kernel regions with MemoryManager
We were already only tracking kernel regions, this patch just makes it
more clear by having it reflected in the name of the registration
helpers.

We also stop calling them for userspace regions, avoiding some spinlock
action in such cases.
2022-01-15 19:51:15 +01:00
Andreas Kling 24ecf1d021 Kernel: Remove redundant hash map of page tables in PageDirectory
The purpose of the PageDirectory::m_page_tables map was really just
to act as ref-counting storage for PhysicalPage objects that were
being used for the directory's page tables.

However, this was basically redundant, since we can find the physical
address of each page table from the page directory, and we can find the
PhysicalPage object from MemoryManager::get_physical_page_entry().
So if we just manually ref() and unref() the pages when they go in and
out of the directory, we no longer need PageDirectory::m_page_tables!

Not only does this remove a bunch of kmalloc() traffic, it also solves
a race condition that would occur when lazily adding a new page table
to a directory:

Previously, when MemoryManager::ensure_pte() would call HashMap::set()
to insert the new page table into m_page_tables, if the HashMap had to
grow its internal storage, it would call kmalloc(). If that kmalloc()
would need to perform heap expansion, it would end up calling
ensure_pte() again, which would clobber the page directory mapping used
by the outer invocation of ensure_pte().

The net result of the above bug would be that any invocation of
MemoryManager::ensure_pte() could erroneously return a pointer into
a kernel page table instead of the correct one!

This whole problem goes away when we remove the HashMap, as ensure_pte()
no longer does anything that allocates from the heap.
2022-01-10 16:22:37 +01:00
Pankaj Raghav 59da9bd0bd Kernel: Overload DMA helper without Physical Page output parameter
Not all drivers need the PhysicalPage output parameter while creating
a DMA buffer. This overload will avoid creating a temporary variable
for the caller
2022-01-09 00:45:38 +01:00
Liav A ca254699ec Kernel: Implement read functionality for MemoryDevice
So far we only had mmap(2) functionality on the /dev/mem device, but now
we can also do read(2) on it.

The test unit was updated to check we are doing it safely.
2022-01-08 13:21:16 +02:00
Liav A 876559d283 Kernel: Change method name to clarify physical memory mmap validation 2022-01-08 13:21:16 +02:00
Tom 10efbfb09e Kernel: Scan ACPI memory ranges for the RSDP table
On some systems the ACPI RSDP table may be located in ACPI reserved
memory ranges rather than in the EBDA or BIOS areas.
2022-01-04 17:46:36 +00:00
Pankaj Raghav 602b35aa62 Kernel: Add DMA allocate functions that are TRY-able
Add DMA allocate buffer helper functions in MemoryManager.
2022-01-01 14:55:58 +01:00
Guilherme Goncalves 33b78915d3 Kernel: Propagate overflow errors from Memory::page_round_up
Fixes #11402.
2021-12-28 23:08:50 +01:00
Andreas Kling ac7ce12123 Kernel: Remove the kmalloc_eternal heap :^)
This was a premature optimization from the early days of SerenityOS.
The eternal heap was a simple bump pointer allocator over a static
byte array. My original idea was to avoid heap fragmentation and improve
data locality, but both ideas were rooted in cargo culting, not data.

We would reserve 4 MiB at boot and only ended up using ~256 KiB, wasting
the rest.

This patch replaces all kmalloc_eternal() usage by regular kmalloc().
2021-12-28 21:02:38 +01:00
Andreas Kling f7a4c34929 Kernel: Make kmalloc heap expansion kmalloc-free
Previously, the heap expansion logic could end up calling kmalloc
recursively, which was quite messy and hard to reason about.

This patch redesigns heap expansion so that it's kmalloc-free:

- We make a single large virtual range allocation at startup
- When expanding, we bump allocate VM from that region
- When expanding, we populate page tables directly ourselves,
  instead of going via MemoryManager.

This makes heap expansion a great deal simpler. However, do note that it
introduces two new flaws that we'll need to deal with eventually:

- The single virtual range allocation is limited to 64 MiB and once
  exhausted, kmalloc() will fail. (Actually, it will PANIC for now..)

- The kmalloc heap can no longer shrink once expanded. Subheaps stay
  in place once constructed.
2021-12-25 22:07:59 +01:00
Guilherme Gonçalves da6aef9fff Kernel: Make msync return EINVAL when regions are too large
As a small cleanup, this also makes `page_round_up` verify its
precondition with `page_round_up_would_wrap` (which callers are expected
to call), rather than having its own logic.

Fixes #11297.
2021-12-23 17:43:12 -08:00
Daniel Bertalan 4fc28bfe02 Kernel: Unmap Prekernel pages after they are no longer needed
The Prekernel's memory is only accessed until MemoryManager has been
initialized. Keeping them around afterwards is both unnecessary and bad,
as it prevents the userland from using the 0x100000-0x155000 virtual
address range.

Co-authored-by: Idan Horowitz <idan.horowitz@gmail.com>
2021-12-22 00:02:36 -08:00
Andreas Kling 1f2d0d0ad4 Kernel: Use ksyms in-place instead of duplicating them into eternal heap
We can leave the .ksyms section mapped-but-read-only and then have the
symbols index simply point into it.

Note that we manually insert null-terminators into the symbols section
while parsing it.

This gets rid of ~950 KiB of kmalloc_eternal() at startup. :^)
2021-12-18 11:30:10 +01:00
Hendiadyoin1 e34eb3e36d Kernel: Remove unused String.h includes
This makes searching for not yet OOM safe interfaces a bit easier.
2021-12-11 13:15:26 -08:00
Andreas Kling a23edd42b8 Kernel: Store kernel memory regions in a RedBlackTree
We were already doing this for userspace memory regions (in the
Memory::AddressSpace class), so let's do it for kernel regions as well.

This gives a nice speed-up on test-js and probably basically everything
else as well. :^)
2021-12-11 20:13:20 +01:00
Idan Horowitz 4ca39c7110 Kernel: Move the expand_range_to_page_boundaries helper to MemoryManager
This helper can (and will) be used in more parts of the kernel besides
the mmap-family of syscalls.
2021-12-01 21:44:11 +02:00
James Mintram b08eb37b11 Kernel: Add an x86 include check+error in x86/TrapFrame.h 2021-12-01 11:22:04 -08:00
James Mintram eb33df0c30 Kernel: Add an x86 include check+error in x86/PageFault.h 2021-12-01 11:22:04 -08:00
James Mintram 17fb2adf61 Kernel: Add an x86 include check+error in x86/PageDirectory.h 2021-12-01 11:22:04 -08:00
Andreas Kling f2d5548d7a Kernel: Add MemoryManager::copy_physical_page()
This is a handy helper that copies out the full contents of a physical
page into a caller-provided buffer. It uses quickmapping internally
(and takes the MM lock for the duration.)
2021-11-17 19:32:07 +01:00
Andrew Kaster fff265a9a9 Kernel: Suppress clang-tidy warning on declaration of s_mm_lock
Seems we are declaring this guy as extern RecursiveSpinLock s_mm_lock;
in both Thread.h and MemoryManager.h. Smells funny for sure.
2021-11-14 22:52:35 +01:00
Andreas Kling 79fa9765ca Kernel: Replace KResult and KResultOr<T> with Error and ErrorOr<T>
We now use AK::Error and AK::ErrorOr<T> in both kernel and userspace!
This was a slightly tedious refactoring that took a long time, so it's
not unlikely that some bugs crept in.

Nevertheless, it does pass basic functionality testing, and it's just
real nice to finally see the same pattern in all contexts. :^)
2021-11-08 01:10:53 +01:00
Andreas Kling 890c647e0f Kernel: Fix off-by-one in Memory::is_user_range() check
This function was checking 1 byte after the provided range, which caused
it to reject valid userspace ranges that happened to end exactly at the
top of the user address space.

This fixes a long-standing issue with mysterious Optional errors in
Coredump::write_regions(). (It happened when trying to add a memory
region at the very top of the address space to a coredump.)
2021-09-11 02:34:55 +02:00
Andreas Kling cd8d52e6ae Kernel: Improve API names for switching address spaces
- enter_space => enter_address_space
- enter_process_paging_scope => enter_process_address_space
2021-09-06 18:56:51 +02:00
Andreas Kling 75564b4a5f Kernel: Make kernel region allocators return KResultOr<NOP<Region>>
This expands the reach of error propagation greatly throughout the
kernel. Sadly, it also exposes the fact that we're allocating (and
doing other fallible things) in constructors all over the place.

This patch doesn't attempt to address that of course. That's work for
our future selves.
2021-09-06 01:55:27 +02:00
Andreas Kling 2f790cf78f Kernel: Make MM.commit_user_physical_pages() return KResultOr
..and use TRY() at call sites. :^)
2021-09-06 01:55:27 +02:00
Brian Gianforcaro bb58a4d943 Kernel: Make all Spinlocks use u8 for storage, remove template
The default template argument is only used in one place, and it
looks like it was probably just an oversight. The rest of the Kernel
code all uses u8 as the type. So lets make that the default and remove
the unused template argument, as there doesn't seem to be a reason to
allow the size to be customizable.
2021-09-05 20:46:02 +02:00
Andreas Kling c922a7da09 Kernel: Rename ScopedSpinlock => SpinlockLocker
This matches MutexLocker, and doesn't sound like it's a lock itself.
2021-08-22 03:34:10 +02:00
Andreas Kling 55adace359 Kernel: Rename SpinLock => Spinlock 2021-08-22 03:34:10 +02:00
Andreas Kling 7979b5a8bb Kernel: Port VMObject to ListedRefCounted
The VMObject class now manages its own instance list (it was previously
a member of MemoryManager.) Removal from the list is done safely on the
last unref(), closing a race window in the previous implementation.

Note that VMObject::all_instances() now has its own lock instead of
using the global MM lock.
2021-08-17 01:21:47 +02:00
Andreas Kling 96c7b70de3 Kernel: Remove unused list of user regions in MemoryManager
We were putting all the user Region objects on an intrusive list
but not using it for anything.
2021-08-09 11:46:31 +02:00
Jean-Baptiste Boric 2c3b0baf76 Kernel: Move SpinLock.h into Locking/ 2021-08-07 11:48:00 +02:00
Andreas Kling f770b9d430 Kernel: Fix bad search-and-replace renames
Oops, I didn't mean to change every *Range* to *VirtualRange*!
2021-08-07 00:39:06 +02:00
Andreas Kling cdab5b2091 Kernel: Make identity mapping mechanism used during AP boot non-generic
When booting AP's, we identity map a region at 0x8000 while doing the
initial bringup sequence. This is the only thing in the kernel that
requires an identity mapping, yet we had a bunch of generic API's and a
dedicated VirtualRangeAllocator in every PageDirectory for this purpose.

This patch simplifies the situation by moving the identity mapping logic
to the AP boot code and removing the generic API's.
2021-08-06 21:35:56 +02:00
Andreas Kling b7476d7a1b Kernel: Rename Memory::Space => Memory::AddressSpace 2021-08-06 14:05:58 +02:00
Andreas Kling cd5faf4e42 Kernel: Rename Range => VirtualRange
...and also RangeAllocator => VirtualRangeAllocator.

This clarifies that the ranges we're dealing with are *virtual* memory
ranges and not anything else.
2021-08-06 14:05:58 +02:00
Andreas Kling 93d98d4976 Kernel: Move Kernel/Memory/ code into Kernel::Memory namespace 2021-08-06 14:05:58 +02:00
Andreas Kling a1d7ebf85a Kernel: Rename Kernel/VM/ to Kernel/Memory/
This directory isn't just about virtual memory, it's about all kinds
of memory management.
2021-08-06 14:05:58 +02:00
Renamed from Kernel/VM/MemoryManager.h (Browse further)