summaryrefslogtreecommitdiff
path: root/Kernel/VM/Region.cpp
AgeCommit message (Collapse)Author
2021-06-24Everywhere: Use nothrow new with `adopt_{ref,own}_if_nonnull`Daniel Bertalan
This commit converts naked `new`s to `AK::try_make` and `AK::try_create` wherever possible. If the called constructor is private, this can not be done, so we instead now use the standard-defined and compiler-agnostic `new (nothrow)`.
2021-06-16Kernel: Remove various other uses of ssize_tGunnar Beutner
2021-05-29Kernel: Make Region creation API OOM safeBrian Gianforcaro
- Make Region::create_kernel_only OOM safe. - Make Region::create_user_accessible mostly OOM safe, there are still some tendrils to untangle before it and be completely fixed.
2021-05-28Kernel: Use KString for Region namesAndreas Kling
Replace the AK::String used for Region::m_name with a KString. This seems beneficial across the board, but as a specific data point, it reduces time spent in sys$set_mmap_name() by ~50% on test-js. :^)
2021-05-25Kernel: Release the paging lock while reading from the diskTom
Because reading from the disk may preempt, we need to release the paging lock.
2021-05-02Kernel: Change Inode::{read/write}_bytes interface to KResultOr<ssize_t>Brian Gianforcaro
The error handling in all these cases was still using the old style negative values to indicate errors. We have a nicer solution for this now with KResultOr<T>. This change switches the interface and then all implementers to use the new style.
2021-05-01Everywhere: Turn #if *_DEBUG into dbgln_if/if constexprGunnar Beutner
2021-04-25Kernel: Remove the now defunct `LOCKER(..)` macro.Brian Gianforcaro
2021-04-22Everything: Move to SPDX license identifiers in all files.Brian Gianforcaro
SPDX License Identifiers are a more compact / standardized way of representing file license information. See: https://spdx.dev/resources/use/#identifiers This was done with the `ambr` search and replace tool. ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
2021-03-09Kernel: Convert klog() to dmesgln() in RegionAndreas Kling
2021-03-08Kernel: Make MemoryManager API type-safe for Region::Access enumBrian Gianforcaro
Increase type-safety moving the MemoryManager APIs which take a Region::Access to actually use that type instead of a `u8`. Eventually the actually m_access can be moved there as well, but I hit some weird bug where it wasn't using the correct operators in `set_access_bit(..)` even though it's declared (and tested). Something to fix-up later.
2021-03-03Kernel: Skip TLB flushes while cloning regions in sys$fork()Andreas Kling
Since we know for sure that the virtual memory regions in the new process being created are not being used on any CPU, there's no need to do TLB flushes for every mapped page.
2021-02-23Everywhere: Rename ASSERT => VERIFYAndreas Kling
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED) Since all of these checks are done in release builds as well, let's rename them to VERIFY to prevent confusion, as everyone is used to assertions being compiled out in release. We can introduce a new ASSERT macro that is specifically for debug checks, but I'm doing this wholesale conversion first since we've accumulated thousands of these already, and it's not immediately obvious which ones are suitable for ASSERT.
2021-02-14Kernel: Assert if rounding-up-to-page-size would wrap around to 0Andreas Kling
If we try to align a number above 0xfffff000 to the next multiple of the page size (4 KiB), it would wrap around to 0. This is most likely never what we want, so let's assert if that happens.
2021-02-14Kernel: Panic on attempt to map mmap'ed page at a kernel addressAndreas Kling
If we somehow get tricked into mapping user-controlled mmap memory at a kernel address, let's just panic the kernel.
2021-02-14Kernel: Make the Region constructor privateAndreas Kling
We can use adopt_own(*new T) instead of make<T>().
2021-02-14Kernel: Remove user/kernel flags from RegionAndreas Kling
Now that we no longer need to support the signal trampolines being user-accessible inside the kernel memory range, we can get rid of the "kernel" and "user-accessible" flags on Region and simply use the address of the region to determine whether it's kernel or user. This also tightens the page table mapping code, since it can now set user-accessibility based solely on the virtual address of a page.
2021-02-13Kernel: Sanity check the VM range when constructing a RegionAndreas Kling
This should help us catch bogus VM ranges ending up in a process's address space sooner.
2021-02-08Everywhere: Replace dbgln<flag>(...) with dbgln_if(flag, ...)AnotherTest
Replacement made by `find Kernel Userland -name '*.h' -o -name '*.cpp' | sed -i -Ee 's/dbgln\b<(\w+)>\(/dbgln_if(\1, /g'`
2021-02-02Kernel: Add a way to specify which memory regions can make syscallsAndreas Kling
This patch adds sys$msyscall() which is loosely based on an OpenBSD mechanism for preventing syscalls from non-blessed memory regions. It works similarly to pledge and unveil, you can call it as many times as you like, and when you're finished, you call it with a null pointer and it will stop accepting new regions from then on. If a syscall later happens and doesn't originate from one of the previously blessed regions, the kernel will simply crash the process.
2021-01-29Kernel: Enforce W^X more strictly (like PaX MPROTECT)Andreas Kling
This patch adds enforcement of two new rules: - Memory that was previously writable cannot become executable - Memory that was previously executable cannot become writable Unfortunately we have to make an exception for text relocations in the dynamic loader. Since those necessitate writing into a private copy of library code, we allow programs to transition from RW to RX under very specific conditions. See the implementation of sys$mprotect()'s should_make_executable_exception_for_dynamic_loader() for details.
2021-01-27Kernel: Release MM lock while yielding from inode page fault handlerTom
We need to make sure other processors can grab the MM lock while we wait, so release it when we might block. Reading the page from disk may also block, so release it during that time as well.
2021-01-26Meta: Split debug defines into multiple headers.asynts
The following script was used to make these changes: #!/bin/bash set -e tmp=$(mktemp -d) echo "tmp=$tmp" find Kernel \( -name '*.cpp' -o -name '*.h' \) | sort > $tmp/Kernel.files find . \( -path ./Toolchain -prune -o -path ./Build -prune -o -path ./Kernel -prune \) -o \( -name '*.cpp' -o -name '*.h' \) -print | sort > $tmp/EverythingExceptKernel.files cat $tmp/Kernel.files | xargs grep -Eho '[A-Z0-9_]+_DEBUG' | sort | uniq > $tmp/Kernel.macros cat $tmp/EverythingExceptKernel.files | xargs grep -Eho '[A-Z0-9_]+_DEBUG' | sort | uniq > $tmp/EverythingExceptKernel.macros comm -23 $tmp/Kernel.macros $tmp/EverythingExceptKernel.macros > $tmp/Kernel.unique comm -1 $tmp/Kernel.macros $tmp/EverythingExceptKernel.macros > $tmp/EverythingExceptKernel.unique cat $tmp/Kernel.unique | awk '{ print "#cmakedefine01 "$1 }' > $tmp/Kernel.header cat $tmp/EverythingExceptKernel.unique | awk '{ print "#cmakedefine01 "$1 }' > $tmp/EverythingExceptKernel.header for macro in $(cat $tmp/Kernel.unique) do cat $tmp/Kernel.files | xargs grep -l $macro >> $tmp/Kernel.new-includes ||: done cat $tmp/Kernel.new-includes | sort > $tmp/Kernel.new-includes.sorted for macro in $(cat $tmp/EverythingExceptKernel.unique) do cat $tmp/Kernel.files | xargs grep -l $macro >> $tmp/Kernel.old-includes ||: done cat $tmp/Kernel.old-includes | sort > $tmp/Kernel.old-includes.sorted comm -23 $tmp/Kernel.new-includes.sorted $tmp/Kernel.old-includes.sorted > $tmp/Kernel.includes.new comm -13 $tmp/Kernel.new-includes.sorted $tmp/Kernel.old-includes.sorted > $tmp/Kernel.includes.old comm -12 $tmp/Kernel.new-includes.sorted $tmp/Kernel.old-includes.sorted > $tmp/Kernel.includes.mixed for file in $(cat $tmp/Kernel.includes.new) do sed -i -E 's/#include <AK\/Debug\.h>/#include <Kernel\/Debug\.h>/' $file done for file in $(cat $tmp/Kernel.includes.mixed) do echo "mixed include in $file, requires manual editing." done
2021-01-26Kernel: Assert on attempt to map private region backed by shared inodeAndreas Kling
If we find ourselves with a user-accessible, non-shared Region backed by a SharedInodeVMObject, that's pretty bad news, so let's just panic the kernel instead of getting abused. There might be a better place for this kind of check, so I've added a FIXME about putting more thought into that.
2021-01-26Kernel: sys$munmap() region splitting did not preserve "shared" flagAndreas Kling
This was exploitable since the shared flag determines whether inode permission checks are applied in sys$mprotect(). The bug was pretty hard to spot due to default arguments being used instead. This patch removes the default arguments to make explicit at each call site what's being done.
2021-01-25Everywhere: Debug macros instead of constexpr.asynts
This was done with the following script: find . \( -name '*.cpp' -o -name '*.h' -o -name '*.in' \) -not -path './Toolchain/*' -not -path './Build/*' -exec sed -i -E 's/dbgln<debug_([a-z_]+)>/dbgln<\U\1_DEBUG>/' {} \; find . \( -name '*.cpp' -o -name '*.h' -o -name '*.in' \) -not -path './Toolchain/*' -not -path './Build/*' -exec sed -i -E 's/if constexpr \(debug_([a-z0-9_]+)/if constexpr \(\U\1_DEBUG/' {} \;
2021-01-25Everywhere: Use CMake to generate AK/Debug.h.asynts
This was done with the help of several scripts, I dump them here to easily find them later: awk '/#ifdef/ { print "#cmakedefine01 "$2 }' AK/Debug.h.in for debug_macro in $(awk '/#ifdef/ { print $2 }' AK/Debug.h.in) do find . \( -name '*.cpp' -o -name '*.h' -o -name '*.in' \) -not -path './Toolchain/*' -not -path './Build/*' -exec sed -i -E 's/#ifdef '$debug_macro'/#if '$debug_macro'/' {} \; done # Remember to remove WRAPPER_GERNERATOR_DEBUG from the list. awk '/#cmake/ { print "set("$2" ON)" }' AK/Debug.h.in
2021-01-22Everywhere: Replace a bundle of dbg with dbgln.asynts
These changes are arbitrarily divided into multiple commits to make it easier to find potentially introduced bugs with git bisect.
2021-01-16Kernel: Remove unused syscall sys$minherit()Andreas Kling
This is no longer used. We can bring it back the day we need it.
2021-01-11Kernel: Remove MM_DEBUG debug spam codeAndreas Kling
This was too spammy to ever actually be used anyway.
2021-01-11Kernel: Convert a bunch of String::format() => String::formatted()Andreas Kling
2021-01-11Everywhere: Fix incorrect uses of String::format and StringBuilder::appendfSahan Fernando
These changes are arbitrarily divided into multiple commits to make it easier to find potentially introduced bugs with git bisect.
2021-01-11Everywhere: Replace a bundle of dbg with dbgln.asynts
These changes are arbitrarily divided into multiple commits to make it easier to find potentially introduced bugs with git bisect.Everything:
2021-01-09Everywhere: Replace a bundle of dbg with dbgln.asynts
These changes are arbitrarily divided into multiple commits to make it easier to find potentially introduced bugs with git bisect.Everything: The modifications in this commit were automatically made using the following command: find . -name '*.cpp' -exec sed -i -E 's/dbg\(\) << ("[^"{]*");/dbgln\(\1\);/' {} \;
2021-01-02Kernel: Ignore TLB flush requests for user addresses of other processesTom
If a TLB flush request is broadcast to other processors and the addresses to flush are user mode addresses, we can ignore such a request on the target processor if the page directory currently in use doesn't match the addresses to be flushed. We still need to broadcast to all processors in that case because the other processors may switch to that same page directory at any time.
2021-01-02Kernel: If a VMObject is shared, broadcast page remappingsTom
If we remap pages (e.g. lazy allocation) inside a VMObject that is shared among more than one region, broadcast it to any other region that may be mapping the same page.
2021-01-02Revert "Kernel: Allocate shared memory regions immediately"Tom
This reverts commit fe6b3f99d1f544715098182ce5bed71d67f266cf.
2021-01-02Kernel: Allocate shared memory regions immediatelyAndreas Kling
Lazily committed shared memory was not working in situations where one process would write to the memory and another would only read from it. Since the reading process would never cause a write fault in the shared region, we'd never notice that the writing process had added real physical pages to the VMObject. This happened because the lazily committed pages were marked "present" in the page table. This patch solves the issue by always allocating shared memory up front and not trying to be clever about it.
2021-01-02Kernel: Pass "shared" flag to Region constructorAndreas Kling
Before this change, we would sometimes map a region into the address space with !is_shared(), and then moments later call set_shared(true). I found this very confusing while debugging, so this patch makes us pass the initial shared flag to the Region constructor, ensuring that it's in the correct state by the time we first map the region.
2021-01-02Kernel: Make Region::amount_shared() and amount_resident() lazy-awareAndreas Kling
Don't count the lazy-committed page towards shared/resident amounts.
2021-01-01Kernel: Pass new region owner to Region::cloneTom
2021-01-01Kernel: Merge PurgeableVMObject into AnonymousVMObjectTom
This implements memory commitments and lazy-allocation of committed memory.
2021-01-01Kernel: Implement lazy committed page allocationTom
By designating a committed page pool we can guarantee to have physical pages available for lazy allocation in mappings. However, when forking we will overcommit. The assumption is that worst-case it's better for the fork to die due to insufficient physical memory on COW access than the parent that created the region. If a fork wants to ensure that all memory is available (trigger a commit) then it can use madvise. This also means that fork now can gracefully fail if we don't have enough physical pages available.
2021-01-01Kernel: Add MAP_NORESERVE support to mmapTom
Rather than lazily committing regions by default, we now commit the entire region unless MAP_NORESERVE is specified. This solves random crashes in low-memory situations where e.g. the malloc heap allocated memory, but using pages that haven't been used before triggers a crash when no more physical memory is available. Use this flag to create large regions without actually committing the backing memory. madvise() can be used to commit arbitrary areas of such regions after creating them.
2021-01-01Kernel: Memory purging improvementsTom
This adds the ability for a Region to define volatile/nonvolatile areas within mapped memory using madvise(). This also means that memory purging takes into account all views of the PurgeableVMObject and only purges memory that is not needed by all of them. When calling madvise() to change an area to nonvolatile memory, return whether memory from that area was purged. At that time also try to remap all memory that is requested to be nonvolatile, and if insufficient pages are available notify the caller of that fact.
2020-12-12Kernel: Fix some issues related to fixes and block conditionsTom
Fix some problems with join blocks where the joining thread block condition was added twice, which lead to a crash when trying to unblock that condition a second time. Deferred block condition evaluation by File objects were also not properly keeping the File object alive, which lead to some random crashes and corruption problems. Other problems were caused by the fact that the Queued state didn't handle signals/interruptions consistently. To solve these issues we remove this state entirely, along with Thread::wait_on and change the WaitQueue into a BlockCondition instead. Also, deliver signals even if there isn't going to be a context switch to another thread. Fixes #4336 and #4330
2020-12-01Kernel: Fix some problems with Thread::wait_on and LockTom
This changes the Thread::wait_on function to not enable interrupts upon leaving, which caused some problems with page fault handlers and in other situations. It may now be called from critical sections, with interrupts enabled or disabled, and returns to the same state. This also requires some fixes to Lock. To aid debugging, a new define LOCK_DEBUG is added that enables checking for Lock leaks upon finalization of a Thread.
2020-11-11Kernel: Protect the PageDirectory from concurrent accessTom
2020-09-13Kernel: Make copy_to/from_user safe and remove unnecessary checksTom
Since the CPU already does almost all necessary validation steps for us, we don't really need to attempt to do this. Doing it ourselves doesn't really work very reliably, because we'd have to account for other processors modifying virtual memory, and we'd have to account for e.g. pages not being able to be allocated due to insufficient resources. So change the copy_to/from_user (and associated helper functions) to use the new safe_memcpy, which will return whether it succeeded or not. The only manual validation step needed (which the CPU can't perform for us) is making sure the pointers provided by user mode aren't pointing to kernel mappings. To make it easier to read/write from/to either kernel or user mode data add the UserOrKernelBuffer helper class, which will internally either use copy_from/to_user or directly memcpy, or pass the data through directly using a temporary buffer on the stack. Last but not least we need to keep syscall params trivial as we need to copy them from/to user mode using copy_from/to_user.
2020-09-02Kernel: Handle committing pages in regions more gracefullyTom
Sometimes a physical underlying page may be there, but we may be unable to allocate a page table that may be needed to map it. Bubble up such mapping errors so that they can be handled more appropriately.