Commit graph

575 commits

Author SHA1 Message Date
Gunnar Beutner f2be1f9326 Kernel: Fix the variable declaration for some linker script symbols
Despite what the declaration would have us believe these are not "u8*".
If they were we wouldn't have to use the & operator to get the address
of them and then cast them to "u8*"/FlatPtr afterwards.
2021-07-22 22:27:11 +02:00
Andreas Kling 0642f8f2c6 Kernel: Make committed physical page allocation return NonnullRefPtr
Since we're taking from the committed set of pages, there should never
be a reason for this call to fail.

Also add a Badge to disallow taking committed pages from anywhere but
the Region class.
2021-07-22 14:20:05 +02:00
Andreas Kling 5217875f6a Kernel: Consolidate API for creating AnonymousVMObject with given pages
We don't need to have a dedicated API for creating a VMObject with a
single page, the multi-page API option works in all cases.

Also make the API take a Span<NonnullRefPtr<PhysicalPage>> instead of
a NonnullRefPtrVector<PhysicalPage>.
2021-07-22 09:17:02 +02:00
Andreas Kling 9e15708aa0 Kernel: Convert VMObject & subclasses to east-const style 2021-07-22 09:17:02 +02:00
Gunnar Beutner b4272d731f Kernel: Make sure crash dumps are properly aligned on x86_64 2021-07-22 08:57:01 +02:00
Gunnar Beutner 36e36507d5 Everywhere: Prefer using {:#x} over 0x{:x}
We have a dedicated format specifier which adds the "0x" prefix, so
let's use that instead of adding it manually.
2021-07-22 08:57:01 +02:00
Gunnar Beutner 31f30e732a Everywhere: Prefix hexadecimal numbers with 0x
Depending on the values it might be difficult to figure out whether a
value is decimal or hexadecimal. So let's make this more obvious. Also
this allows copying and pasting those numbers into GNOME calculator and
probably also other apps which auto-detect the base.
2021-07-22 08:57:01 +02:00
Gunnar Beutner be795d5812 Prekernel: Use physical addresses for some of the BootInfo parameters
The kernel would just turn those virtual addresses into physical
addresses later on, so let's just use physical addresses right from the
start.
2021-07-20 15:12:19 +02:00
Gunnar Beutner dd42093b93 Kernel: Move boot info declarations to a header file
Instead of manually redeclaring those variables in various files this
now adds a header file for them.
2021-07-20 15:12:19 +02:00
Brian Gianforcaro 85e95105c6 Kernel: Mark read only RegisterState function parameters as const 2021-07-20 03:21:14 +02:00
Brian Gianforcaro 27e1120dff Kernel: Move syscall precondition validates to MM
Move these to MM to simplify the flow of the syscall handler.

While here, also make sure we hold the process space lock for
the duration of the validation to avoid potential issues where
another thread attempts to modify the process space during the
validation. This will allow us to move the validation out of the
big process lock scope in a future change.

Additionally utilize the new no_lock variants of functions to avoid
unnecessary recursive process space spinlock acquisitions.
2021-07-20 03:21:14 +02:00
Brian Gianforcaro 308396bca1 Kernel: No lock validate_user_stack variant, switch to Space as argument
The entire process is not needed, just require the user to pass in the
Space. Also provide no_lock variant to use when you already have the
VM/Space lock acquired, to avoid unnecessary recursive spinlock
acquisitions.
2021-07-20 03:21:14 +02:00
Gunnar Beutner a364f5c7b7 Kernel: Make sure super pages are in the first 16MiB of physical memory
This was broken by recent changes.
2021-07-19 11:29:09 +02:00
Gunnar Beutner 5ff1416076 Kernel: Rename bootloader to prekernel
There are a few occurrences of the old name that slipped through.
2021-07-18 22:08:03 +02:00
Gunnar Beutner f56ee10a13 Kernel: Hand out 64-bit addresses to userspace 2021-07-18 17:31:13 +02:00
Gunnar Beutner 7e94b090fe Kernel: Introduce basic pre-kernel environment
This implements a simple bootloader that is capable of loading ELF64
kernel images. It does this by using QEMU/GRUB to load the kernel image
from disk and pass it to our bootloader as a Multiboot module.

The bootloader then parses the ELF image and sets it up appropriately.
The kernel's entry point is a C++ function with architecture-native
code.

Co-authored-by: Liav A <liavalb@gmail.com>
2021-07-18 17:31:13 +02:00
Gunnar Beutner 357ddd393e Kernel: Make allocate_randomized() work for 64-bit addresses
The odds of finding a suitable address in 1000 attempts were not in our
favor given the size of the 64-bit address space.
2021-07-18 17:31:13 +02:00
Gunnar Beutner f0c4941beb Kernel: Fix 64-bit address truncation in MemoryManager::ensure_pte() 2021-07-18 17:31:13 +02:00
Gunnar Beutner b708b23b13 Kernel: Add support for kernel addresses other than 3-4GB 2021-07-18 17:31:13 +02:00
Andreas Kling 9457d83986 Kernel: Rename Locker => MutexLocker 2021-07-18 01:53:04 +02:00
Andreas Kling cee9528168 Kernel: Rename Lock to Mutex
Let's be explicit about what kind of lock this is meant to be.
2021-07-17 21:10:32 +02:00
Brian Gianforcaro c0987453e6 Kernel: Remove double RedBlackTree lookup in VM/Space region removal
We should never request a regions removal that we don't currently
own. We currently assert this everywhere else by all callers.

Instead lets just push the assert down into the RedBlackTree removal
and assume that we will always successfully remove the region.
2021-07-17 16:22:59 +02:00
Brian Gianforcaro d879709ec7 Kernel: Convert the PhysicalPage bool parameter to an enum 2021-07-17 18:38:28 +04:30
Brian Gianforcaro eb282ad410 Kernel: Declare VM/RangeAllocator trivial destructor as default
This is a clang tidy recommendation.
2021-07-17 13:02:09 +02:00
Brian Gianforcaro 24bd664980 Kernel: Remove stale include from VM/RangeAllocator.cpp
This was left over after the latest big refactor of the VM subsystem.
2021-07-17 13:02:09 +02:00
Brian Gianforcaro dbc77148c9 Kernel: Convert RangeAllocator VERIFY to proper error handling
If a user allocates above 0x0 and below the allowable usermode
virtual address space, we need to return error instead of asserting.

Fixes: #8484
2021-07-17 13:00:21 +02:00
Gunnar Beutner cbdb488578 Kernel: Move end_of_kernel_image after the .ksyms section
Without this we won't be able to detect whether .ksyms overlaps the end
of the page table we set up for the kernel image.
2021-07-16 18:50:59 +02:00
Andreas Kling 15ad4a8fd6 Kernel: Convert RangeAllocator to using a RedBlackTree internally
This data structure is a much better fit for what is essentially a
sorted list of non-overlapping ranges.

Not using Vector means we no longer have to worry about Vector buffers
getting huge. Only nice & small allocations from now on.
2021-07-15 02:03:57 +02:00
Andreas Kling b0d9b88c49 Kernel: Hoist VERIFY from a loop in RangeAllocator::allocate_specific() 2021-07-15 01:48:09 +02:00
Andreas Kling 7ff14fecba Kernel: Remove unnecessary locking in RangeAllocator::contains()
The total range managed by a RangeAllocator doesn't change, so there's
no need to take a spinlock while comparing against it.
2021-07-15 01:48:09 +02:00
Andreas Kling d4c73daacb Kernel: Convert RangeAllocator to east-const style 2021-07-15 01:48:09 +02:00
Idan Horowitz be475cd6a8 Kernel: Handle OOM when adding memory regions to Spaces :^) 2021-07-15 00:49:41 +02:00
Andreas Kling dc26c02379 Kernel: Convert MemoryManager to east-const style 2021-07-14 13:31:21 +02:00
Andreas Kling c42807e3dc Kernel: Remove debug spam when PhysicalRegion::take_free_page() fails
We can have multiple PhysicalRegions (often the case when there is a
huge amount of RAM) so we really shouldn't print a debug message any
time someone tries to allocate from one. They will move on to another
region anyway.
2021-07-14 01:37:31 +02:00
Andreas Kling 5c24d18923 Kernel: Fix logic error in PhysicalRegion::contains()
This was incorrectly returning true for the address one byte past the
end of the region.
2021-07-14 01:37:19 +02:00
Andreas Kling 6cc1247395 Kernel: Cut allocation size for physical buddy bitmaps in half
We were allocating twice as much memory as we needed for these bitmaps
due to a silly typo. Found by tomuta trying to boot with 24 GiB of RAM.
2021-07-13 23:47:49 +02:00
Andreas Kling d8ff46594a Kernel: Re-add accidentally removed friendship
PageDirectory and MemoryManager need to remain friends, for now..
2021-07-13 23:21:22 +02:00
Andreas Kling de4ba1f39b Kernel: Remove some friendships and make some classes non-copy/moveable 2021-07-13 23:19:00 +02:00
Andreas Kling 424afdd72b Kernel: Remove some unnecessary includes in VM/Physical* 2021-07-13 23:11:06 +02:00
Andreas Kling 0a21d421d9 Kernel: Print a summary of physical zones during boot
Let's not print out every single zone, since that gets very noisy on
machines with a lot of RAM. :^)
2021-07-13 23:08:45 +02:00
Andreas Kling bf5e4326ac Kernel: Fix bogus address calculation in initialize_physical_pages()
We were incorrectly using sizeof(PhysicalPageEntry) for some address
calculations instead of sizeof(PageTableEntry).

It still worked correctly because they happen to be the same size.
2021-07-13 23:08:45 +02:00
Andreas Kling e323942623 Kernel: Only loop through usable zones when allocating >1 physical page
We still have to loop here, since a zone can be "usable" while not
being able to satisfy a multi-page allocation request.
2021-07-13 23:08:45 +02:00
Andreas Kling 379bcd26e4 Kernel: Avoid O(n) loop over zones when allocating from PhysicalRegion
We now keep all the PhysicalZones on one of two intrusive lists within
the PhysicalRegion.

The "usable" list contains all zones that can be allocated from,
and the "full" list contains all zones with no free pages.
2021-07-13 23:08:45 +02:00
Andreas Kling 9ae067aa7f Kernel: Make PhysicalRegion eternally allocated 2021-07-13 22:40:25 +02:00
Andreas Kling 959ceb4424 Kernel: Remove PhysicalRegion::finalize_capacity()
There's no reason to delay calculating the capacity (total page count)
of each PhysicalRegion. Just do it in the constructor.
2021-07-13 22:40:25 +02:00
Andreas Kling 5171249540 Kernel: Simplify the way PhysicalRegions are constructed
Instead of creating a PhysicalRegion and then expanding it over and
over as we traverse the memory map on boot, we now compute the final
size of the contiguous physical range up front, and *then* create a
PhysicalRegion object.
2021-07-13 22:40:25 +02:00
Andreas Kling 479df315d2 Kernel: Make PhysicalZone an eternally allocated object
Until we start supporting hot-pluggable RAM, these will not be freed
or reallocated during the kernel's lifetime. :^)
2021-07-13 22:40:25 +02:00
Andreas Kling 6ea5db20ff Kernel: Remove unused used/free pages API's from PhysicalRegion 2021-07-13 22:40:25 +02:00
Andreas Kling be90e51355 Kernel: Remove API for requesting physical allocation alignment
Nobody was using this API to request anythign about `PAGE_SIZE`
alignment, so let's get rid of it for now. We can reimplement it if
we end up needing it.

Also note that it wasn't actually used anywhere.
2021-07-13 22:40:25 +02:00
Andreas Kling ba87571366 Kernel: Implement zone-based buddy allocator for physical memory
The previous allocator was very naive and kept the state of all pages
in one big bitmap. When allocating, we had to scan through the bitmap
until we found an unset bit.

This patch introduces a new binary buddy allocator that manages the
physical memory pages.

Each PhysicalRegion is divided into zones (PhysicalZone) of 16MB each.
Any extra pages at the end of physical RAM that don't fit into a 16MB
zone are turned into 15 or fewer 1MB zones.

Each zone starts out with one full-sized block, which is then
recursively subdivided into halves upon allocation, until a block of
the request size can be returned.

There are more opportunities for improvement here: the way zone objects
are allocated and stored is non-optimal. Same goes for the allocation
of buddy block state bitmaps.
2021-07-13 22:40:25 +02:00