Commit Graph

273 Commits

Author SHA1 Message Date
Andreas Kling
042b1f6814 Kernel: Propagate failure to commit VM regions in more places
Ultimately we should not panic just because we can't fully commit a VM
region (by populating it with physical pages.)

This patch handles some of the situations where commit() can fail.
2020-05-08 21:47:08 +02:00
Andreas Kling
d74650e80d Kernel: Use NonnullRefPtrVector<T> instead of Vector<RefPtr<T>> some 2020-05-08 21:12:16 +02:00
Andreas Kling
beaec6bd2d Kernel: Memory purging was incorrectly "purging" the shared zero page
This caused us to report one purged page per occurrence of the shared
zero page in a purgeable memory region, despite it being a no-op.

Thanks to Sergey for spotting the bad assertion removal that led to
this being found!
2020-05-07 09:44:41 +02:00
Andreas Kling
6fe83b0ac4 Kernel: Crash the current process on OOM (instead of panicking kernel)
This patch adds PageFaultResponse::OutOfMemory which informs the fault
handler that we were unable to allocate a necessary physical page and
cannot continue.

In response to this, the kernel will crash the current process. Because
we are OOM, we can't symbolicate the crash like we normally would
(since the ELF symbolication code needs to allocate), so we also
communicate to Process::crash() that we're out of memory.

Now we can survive "allocate 300 MB" (only the allocate process dies.)
This is definitely not perfect and can easily end up killing a random
innocent other process who happened to allocate one page at the wrong
time, but it's a *lot* better than panicking on OOM. :^)
2020-05-06 22:28:23 +02:00
Andreas Kling
c633c1c2ea Kernel: Assert on OOM in Region::commit()
This function has a lot of callers that don't bother checking if it
returns successfully or not. We'll need to handle failure in a bunch
of places and then we can remove this assertion.
2020-05-06 22:28:23 +02:00
Andreas Kling
43593455db Kernel: Don't assert on OOM in allocate_user_physical_page()
We now give callers a chance to react to OOM situations.
2020-05-06 22:28:23 +02:00
Andreas Kling
4419685b7e Kernel: Leave VMObject alone on OOM during CoW fault
If we OOM during a CoW fault and fail to allocate a new page for the
writing process, just leave the original VMObject alone so everyone
else can keep using it.
2020-04-28 17:05:14 +02:00
Andreas Kling
9c856811b2 Kernel: Add Region helpers for accessing underlying physical pages
Since a Region is basically a view into a potentially larger VMObject,
it was always necessary to include the Region starting offset when
accessing its underlying physical pages.

Until now, you had to do that manually, but this patch adds a simple
Region::physical_page() for read-only access and a physical_page_slot()
when you want a mutable reference to the RefPtr<PhysicalPage> itself.

A lot of code is simplified by making use of this.
2020-04-28 17:05:14 +02:00
Andreas Kling
1d43544e08 Kernel: Switch the first-8MB-of-upper-3GB pseudo mappings to 4KB pages
This memory range was set up using 2MB pages by the code in boot.S.
Because of that, the kernel image protection code didn't work, since it
assumed 4KB pages.

We now switch to 4KB pages during MemoryManager initialization. This
makes the kernel image protection code work correctly again. :^)
2020-04-13 22:35:37 +02:00
Itamar
b306ac9b2b ptrace: Add PT_POKE
PT_POKE writes a single word to the tracee's address space.

Some caveats:
- If the user requests to write to an address in a read-only region, we
temporarily change the page's protections to allow it.

- If the user requests to write to a region that's backed by a
SharedInodeVMObject, we replace the vmobject with a PrivateIndoeVMObject.
2020-04-13 00:53:22 +02:00
Andreas Kling
c19b56dc99 Kernel+LibC: Add minherit() and MAP_INHERIT_ZERO
This patch adds the minherit() syscall originally invented by OpenBSD.
Only the MAP_INHERIT_ZERO mode is supported for now. If set on an mmap
region, that region will be zeroed out on fork().
2020-04-12 20:22:26 +02:00
Andreas Kling
f614f0e2cb Kernel: Add typed_map<T>(PhysicalAddress) and use it in ACPI parsing
There was a frequently occurring pattern of "map this physical address
into kernel VM, then read from it, then unmap it again".

This new typed_map() encapsulates that logic by giving you back a
typed pointer to the kind of structure you're interested in accessing.

It returns a TypedMapping<T> that can be used mostly like a pointer.
When destroyed, the TypedMapping object will unmap the memory. :^)
2020-04-09 17:19:11 +02:00
Andreas Kling
522d8c5d71 Kernel: Non-readable-but-writable regions should still be mapped
Fixes #1436.
2020-04-03 10:10:56 +02:00
Andreas Kling
7d862dd5fc AK: Reduce header dependency graph of String.h
String.h no longer pulls in StringView.h. We do this by moving a bunch
of String functions out-of-line.
2020-03-23 13:48:44 +01:00
Shannon Booth
81adefef27 Kernel: Run clang-format on files
Let's rip off the band-aid
2020-03-22 01:22:32 +01:00
Liav A
d6e122fd3a Kernel: Allow contiguous allocations in physical memory
For that, we have a new type of VMObject, called
ContiguousVMObject, that is responsible for allocating contiguous
physical pages.
2020-03-08 14:13:30 +01:00
Andreas Kling
fa9fba6901 Kernel: Add missing #includes now that <AK/StdLibExtras.h> is smaller 2020-03-08 13:06:51 +01:00
Andreas Kling
b1058b33fb AK: Add global FlatPtr typedef. It's u32 or u64, based on sizeof(void*)
Use this instead of uintptr_t throughout the codebase. This makes it
possible to pass a FlatPtr to something that has u32 and u64 overloads.
2020-03-08 13:06:51 +01:00
Andreas Kling
7a6c4a72d5 LibWeb: Move everything into the Web namespace 2020-03-07 10:27:02 +01:00
Andreas Kling
c6693f9b3a Kernel: Simplify a bunch of dbg() and klog() calls
LogStream can handle VirtualAddress and PhysicalAddress directly.
2020-03-06 15:00:44 +01:00
Andreas Kling
94f287b1c0 Kernel: Unmap non-readable pages
This was caught by running all crash tests with "crash -A".
Basically, non-readable pages need to not be mapped *at all* so that
a "page not present" exception is provoked on access.

Unfortunately x86 does not support write-only mappings, so this is
the best we can do.

Fixes #1336.
2020-03-06 09:58:59 +01:00
Liav A
0fc60e41dd Kernel: Use klog() instead of kprintf()
Also, duplicate data in dbg() and klog() calls were removed.
In addition, leakage of virtual address to kernel log is prevented.
This is done by replacing kprintf() calls to dbg() calls with the
leaked data instead.
Also, other kprintf() calls were replaced with klog().
2020-03-02 22:23:39 +01:00
Andreas Kling
918ebabf60 Kernel: MemoryManager should create cacheable regions by default 2020-03-02 13:04:17 +01:00
Andreas Kling
ecdd9a5bc6 Kernel: Reduce code duplication a little bit in Region allocation
This patch reduces the number of code paths that lead to the allocation
of a Region object. It's quite hard to follow the various ways in which
this can happen, so this is an effort to simplify.
2020-03-01 15:56:23 +01:00
Andreas Kling
5e0c4d689f Kernel: Move ProcessPagingScope to its own files 2020-03-01 15:38:09 +01:00
Andreas Kling
fee20bd8de Kernel: Remove some more harmless InodeVMObject miscasts 2020-03-01 12:27:03 +01:00
Andreas Kling
b614462079 Kernel: Include the dirty bits when cloning an InodeVMObject
Now that (private) InodeVMObjects can be CoW-cloned on fork(), we need
to make sure we clone the dirty bits as well.
2020-03-01 12:11:50 +01:00
Andreas Kling
48bbfe51fb Kernel: Add some InodeVMObject type assertions in Region::clone()
Let's make sure that we're never cloning shared inode-backed objects
as if they were private, and vice versa.
2020-03-01 11:23:10 +01:00
Andreas Kling
88b334135b Kernel: Remove some Region construction helpers
It's now up to the caller to provide a VMObject when constructing a new
Region object. This will make it easier to handle things going wrong,
like allocation failures, etc.
2020-03-01 11:23:10 +01:00
Andreas Kling
fddc3c957b Kernel: CoW-clone private inode-backed memory regions on fork()
When forking a process, we now turn all of the private inode-backed
mmap() regions into copy-on-write regions in both the parent and child.

This patch also removes an assertion that becomes irrelevant.
2020-03-01 11:23:10 +01:00
Andreas Kling
7cd1bdfd81 Kernel: Simplify some dbg() logging
We don't have to log the process name/PID/TID, dbg() automatically adds
that as a prefix to every line.

Also we don't have to do .characters() on Strings passed to dbg() :^)
2020-02-29 13:39:06 +01:00
Andreas Kling
5f7056d62c Kernel: Expose the VMObject type of each Region in /proc/PID/vm 2020-02-28 23:25:40 +01:00
Andreas Kling
aa1e209845 Kernel: Remove some unnecessary indirection in InodeFile::mmap()
InodeFile now directly calls Process::allocate_region_with_vmobject()
instead of taking an awkward detour via a special Region constructor.
2020-02-28 20:29:14 +01:00
Andreas Kling
651417a085 Kernel: Split InodeVMObject into two subclasses
We now have PrivateInodeVMObject and SharedInodeVMObject, corresponding
to MAP_PRIVATE and MAP_SHARED respectively.

Note that PrivateInodeVMObject is not used yet.
2020-02-28 20:20:35 +01:00
Andreas Kling
07a26aece3 Kernel: Rename InodeVMObject => SharedInodeVMObject 2020-02-28 20:07:51 +01:00
Liav A
d16b26f83a MemoryManager: Use dbg() instead of dbgprintf() 2020-02-27 13:05:12 +01:00
Liav A
42665817d1 RangeAllocator: Use dbg() instead of dbgprintf() 2020-02-27 13:05:12 +01:00
Liav A
3f2d5f2774 PhysicalPage: Use dbg() instead of dbgprintf() 2020-02-27 13:05:12 +01:00
Liav A
24d2aeda8e Region: Use dbg() instead of dbgprintf() 2020-02-27 13:05:12 +01:00
Liav A
3f95a7fc97 InodeVMObject: Use dbg() instead of dbgprintf() 2020-02-27 13:05:12 +01:00
Liav A
62adbbc598 PageDirectory: Use dbg() instead of dbgprintf() 2020-02-27 13:05:12 +01:00
Andreas Kling
ceec1a7d38 AK: Make Vector use size_t for its size and capacity 2020-02-25 14:52:35 +01:00
Andreas Kling
30a8991dbf Kernel: Make Region weakable and use WeakPtr<Region> instead of Region*
This turns use-after-free bugs into null pointer dereferences instead.
2020-02-24 13:32:45 +01:00
Andreas Kling
0763f67043 AK: Make Bitmap use size_t for its size
Also rework its API's to return Optional<size_t> instead of int with -1
as the error value.
2020-02-24 09:56:07 +01:00
Andreas Kling
7ec758773c Kernel: Dump all kernel regions when we hit a page fault during IRQ
This way you can try to figure out what the faulting address is.
2020-02-23 11:10:52 +01:00
Andreas Kling
f020081a38 Kernel: Put "Couldn't find user region" spam behind MM_DEBUG
This basically never tells us anything actionable anyway, and it's a
real annoyance when doing something validation-heavy like profiling.
2020-02-22 10:09:54 +01:00
Andreas Kling
b298c01e92 Kernel: Log instead of crashing when getting a page fault during IRQ
This is definitely a bug, but it seems to happen randomly every now
and then and we need more info to track it down, so let's log for now.
2020-02-21 19:05:45 +01:00
Andreas Kling
04e40da188 Kernel: Fix crash when reading /proc/PID/vmobjects
InodeVMObjects can have nulled-out physical page slots. That just means
we haven't cached that page from disk right now.
2020-02-21 16:03:56 +01:00
Andreas Kling
59b9e49bcd Kernel: Don't trigger page faults during profiling stack walk
The kernel sampling profiler will walk thread stacks during the timer
tick handler. Since it's not safe to trigger page faults during IRQ's,
we now avoid this by checking the page tables manually before accessing
each stack location.
2020-02-21 15:49:39 +01:00
Andreas Kling
d46071c08f Kernel: Assert on page fault during IRQ
We're not equipped to deal with page faults during an IRQ handler,
so add an assertion so we can immediately tell what's wrong.

This is why profiling sometimes hangs the system -- walking the stack
of the profiled thread causes a page fault and things fall apart.
2020-02-21 15:49:34 +01:00