Commit graph

230 commits

Author SHA1 Message Date
Idan Horowitz
618f123463 Kernel: Use StringView instead of String in RingBuffer's constructor
This String was being copied into a KString internally anyways.
2022-01-13 00:20:08 -08:00
Andreas Kling
5f71925aa4 Kernel: Actually clear page slots in Region::clear_to_zero()
We were copying the RefPtr<PhysicalPage> and zeroing the copy instead
of zeroing the slot itself.
2022-01-12 14:52:47 +01:00
Andreas Kling
d8206c1059 Kernel: Don't release/relock spinlocks repeatedly during space teardown
Grab the page directory and MM locks once at the start of address space
teardown, then hold onto them across all the region unmapping work.
2022-01-12 14:52:47 +01:00
Andreas Kling
2323cdd914 Kernel: Do less unnecessary work when tearing down process address space
When deleting an entire AddressSpace, we don't need to do TLB flushes
at all (since the entire page directory is going away anyway).

We also don't need to deallocate VM ranges one by one, since the entire
VM range allocator will be deleted anyway.
2022-01-12 14:52:47 +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
Andreas Kling
bdbff9df24 Kernel: Don't relock MM lock for every page when remapping region
Make sure that callers already hold the MM lock, and we don't have to
worry about reacquiring it every time.
2022-01-10 16:22:37 +01:00
Hendiadyoin1
1cdace7898 Kernel: Add implied auto qualifiers in Memory 2022-01-09 23:29:57 -08: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
Pankaj Raghav
e79f94f998 Kernel: Set Cacheable parameter to NO explicitly in DMA helpers
The cacheable parameter to allocate_kernel_region should be explicitly
set to No as this region is used to do physical memory transfers. Even
though most architectures ignore this even if it is set, it is better
to make this explicit.
2022-01-09 00:45:38 +01:00
creator1creeper1
3c05261611 AK+Everywhere: Make FixedArray OOM-safe
FixedArray now doesn't expose any infallible constructors anymore.
Rather, it exposes fallible methods. Therefore, it can be used for
OOM-safe code.
This commit also converts the rest of the system to use the new API.
However, as an example, VMObject can't take advantage of this yet,
as we would have to endow VMObject with a fallible static
construction method, which would require a very fundamental change
to VMObject's whole inheritance hierarchy.
2022-01-08 22:54:05 +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
Liav A
3e066d380d Kernel/Memory: Remove needless VERIFY in /dev/mem mmap validation method
As it was pointed by Idan Horowitz, the rest of the method doesn't
assume we have any reserved ranges to allow mmap(2) to work on them, so
the VERIFY is not needed at all.
2022-01-07 19:13:27 +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
Tom
190572b714 Kernel: Fix possible buffer overrun when scanning a MappedROM
If the length of the prefix was less than the chunk_size argument
we were potentionally reading past the mapped memory region.
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
Idan Horowitz
be91b4fe3e Kernel: Support Mutex Protected lists in ListedRefCounted
This will allow us to support Mutex Protected lists like the custodies
list as well.
2021-12-29 12:04:15 +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
3399b6c57f Kernel: Remove old SlabAllocator :^)
This is no longer useful since kmalloc() does automatic slab allocation
without any of the limitations of the old SlabAllocator. :^)
2021-12-26 21:22:59 +01:00
Andreas Kling
43099fb387 Kernel: Remove all uses of MAKE_SLAB_ALLOCATED()
Objects that were previously allocated via slab_alloc()/slab_dealloc()
now go through kmalloc()/kfree_sized() instead.
2021-12-26 21:22:59 +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
Brian Gianforcaro
1c950773fb Kernel: Make MemoryManager::protect_ksyms_after_init UNMAP_AFTER_INIT
The function to protect ksyms after initialization, is only used during
boot of the system, so it can be UNMAP_AFTER_INIT as well.

This requires we switch the order of the init sequence, so we now call
`MM.protect_ksyms_after_init()` before `MM.unmap_text_after_init()`.
2021-12-24 14:28:59 -08: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
4195a7ef4b Kernel: Return EEXIST in VirtualRangeAllocator::try_allocate_specific()
This error only ever gets propagated to the userspace if
MAP_FIXED_NOREPLACE is requested, as MAP_FIXED unmaps intersecting
ranges beforehand, and non-fixed mmap() calls will just fall back to
allocating anywhere.

Linux specifies MAP_FIXED_NOREPLACE to return EEXIST when it can't
allocate, we now match that behavior.
2021-12-23 23:08:10 +01:00
Brian Gianforcaro
b8e210deea Kernel: Initialize PhysicalRegion::m_large_zones, remove m_small_zones
Found by PVS Studio Static Analysis.
2021-12-22 13:29:31 -08:00
Idan Horowitz
5f4a67434c Kernel: Move userspace virtual address range base to 0x10000
Now that the shared bottom 2 MiB virtual address mappings are gone
userspace can use lower virtual addresses.
2021-12-22 00:02:36 -08:00
Idan Horowitz
fccd0432a1 Kernel: Don't share the bottom 2 MiB of kernel mappings with processes
Now that the last 2 users of these mappings (the Prekernel and the APIC
ap boot environment) were removed, these are no longer used.
2021-12-22 00:02:36 -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
Nick Johnson
08e4a1a4dc AK+Everywhere: Replace __builtin bit functions
In order to reduce our reliance on __builtin_{ffs, clz, ctz, popcount},
this commit removes all calls to these functions and replaces them with
the equivalent functions in AK/BuiltinWrappers.h.
2021-12-21 22:13:51 +01: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
Clay Freeman
e3e40cca65 Kernel: Replace final loop in PhysicalRegion::return_page() with math
Since it's possible to determine where the small zones will start to
occur for each PhysicalRegion, we can use arithmetic so that the call
time for both large and small zones is identical.
2021-12-13 00:13:43 +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
813593a485 Kernel: Fix overly loose MemoryManager::kernel_region_from_vaddr()
It's not enough to just find the largest-address-not-above the argument,
we must also check that the found region actually contains the argument.

Regressed in a23edd42b8, thanks to Idan
for pointing this out.
2021-12-11 21:18:42 +01:00
Andreas Kling
259cca456f Kernel: Make PhysicalRegion::return_page() do arithmetic instead of loop
Most of the time, we will be freeing physical pages within the
full-sized zones. We can do some simple math to find the right zone
immediately instead of looping through the zones, checking each one.

We still do loop through the slack/remainder zones at the end.
There's probably an even nicer way to solve this, but this is already a
nice improvement. :^)
2021-12-11 20:13:32 +01: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
Sam Atkins
907feb84a0 Kernel: Cast unused smart-pointer return value to void 2021-12-05 15:31:03 +01:00
Idan Horowitz
40f64d7379 Kernel: Dispatch handle-able signals instead of crashing if possible
This matches the behaviour of the other *nixs and allows processes to
try and recover from such signals in userland.
2021-12-01 21:44:11 +02:00
Idan Horowitz
f415218afe Kernel+LibC: Implement sigaltstack()
This is required for compiling wine for serenity
2021-12-01 21:44:11 +02:00
Idan Horowitz
a9e436c4a3 Kernel: Replace usages of SIGSTKFLT with SIGSEGV
SIGSTKFLT is a signal that signifies a stack fault in a x87 coprocessor,
this signal is not POSIX and also unused by Linux and the BSDs, so let's
use SIGSEGV so programs that setup signal handlers for the common
signals could still handle them in serenity.
2021-12-01 21:44:11 +02: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
Idan Horowitz
ff6b43734c Kernel: Add Region::clear_to_zero
This helper method can be used to quickly and efficiently zero out a
region.
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
Hendiadyoin1
c7b90fa7d3 Kernel: Don't rewrite the whole file on sys$msync 2021-12-01 09:47:46 +01:00
Andreas Kling
578a576a98 Kernel: Make VirtualRangeAllocator setup functions propagate errors
If an internal allocation failure occurs while setting up a new VRA,
we'll now propagate the error to our caller instead of panicking.
2021-11-18 21:11:30 +01:00
Andreas Kling
0f22ba5bf2 AK: Make RedBlackTree::try_insert() return ErrorOr<void> instead of bool 2021-11-18 21:11:30 +01:00
Andreas Kling
1f894cee59 Kernel: Automatically sync shared file mappings when unmapped
To make sure we don't lose changes, shared file mappings will now be
fully synced when they are unmapped, whether explicitly or implicitly
(by the program exiting/crashing/etc.)

This can incur a lot of work, since we don't keep track of dirty pages,
but that's something we can optimize down the road. :^)
2021-11-17 19:35:53 +01:00
Andreas Kling
32aa37d5dc Kernel+LibC: Add msync() system call
This allows userspace to trigger a full (FIXME) flush of a shared file
mapping to disk. We iterate over all the mapped pages in the VMObject
and write them out to the underlying inode, one by one. This is rather
naive, and there's lots of room for improvement.

Note that shared file mappings are currently not possible since mmap()
returns ENOTSUP for PROT_WRITE+MAP_SHARED. That restriction will be
removed in a subsequent commit. :^)
2021-11-17 19:34:15 +01:00