Commit Graph

114 Commits

Author SHA1 Message Date
Andreas Kling
cfe54f86bd Kernel: Remove unused /proc/mm file
This was a file I used very early on to dump information about kernel
VM objects. It's long since superseded by other JSON-based files.
2021-01-17 21:14:20 +01:00
Tom
d3e6cdf21f Kernel: Provide consistent memory stats in ProcFS
We should take the MM lock when gathering all the statistics that
we need so that the values are consistent.
2021-01-05 10:59:00 +01:00
Tom
901ef3f1c8 Kernel: Specify default memory order for some non-synchronizing Atomics 2021-01-04 19:13:52 +01:00
Tom
0d44ee6f2b Kernel: Ignore TLB flush requests for user addresses of other processes
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-02 20:56:35 +01:00
Tom
476f17b3f1 Kernel: Merge PurgeableVMObject into AnonymousVMObject
This implements memory commitments and lazy-allocation of committed
memory.
2021-01-01 23:43:44 +01:00
Tom
b2a52f6208 Kernel: Implement lazy committed page allocation
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-01 23:43:44 +01:00
Tom
bc5d6992a4 Kernel: Memory purging improvements
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.
2021-01-01 23:43:44 +01:00
Andreas Kling
8e79bde2b7 Kernel: Move KBufferBuilder to the fallible KBuffer API
KBufferBuilder::build() now returns an OwnPtr<KBuffer> and can fail.
Clients of the API have been updated to handle that situation.
2020-12-18 19:22:26 +01:00
Tom
5b38132e3c Kernel: Protect the PageDirectory from concurrent access 2020-11-11 12:27:25 +01:00
Tom
13aa3d2d62 Kernel: Flush TLB when quick-mapping PD/PT that was mapped on other CPU
If a PD/PT was quick-mapped by another CPU we still need to flush the
TLB on the current CPU.

Fixes #3885
2020-11-01 18:48:36 +01:00
Ben Wiederhake
64cc3f51d0 Meta+Kernel: Make clang-format-10 clean 2020-09-25 21:18:17 +02:00
Tom
c8d9f1b9c9 Kernel: Make copy_to/from_user safe and remove unnecessary checks
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-13 21:19:15 +02:00
Tom
bf268a0185 Kernel: Handle committing pages in regions more gracefully
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.
2020-09-02 00:35:56 +02:00
Tom
83ddf3d850 Kernel: Fix memory purge clobbering mapped page directory in ensure_pte
If allocating a page table triggers purging memory, we need to call
quickmap_pd again to make sure the underlying physical page is
remapped to the correct one. This is needed because purging itself
may trigger calls to ensure_pte as well.

Fixes #3370
2020-09-01 22:08:43 +02:00
Tom
4b66692a55 Kernel: Make Heap implementation reusable, and make kmalloc expandable
Add an ExpandableHeap and switch kmalloc to use it, which allows
for the kmalloc heap to grow as needed.

In order to make heap expansion to work, we keep around a 1 MiB backup
memory region, because creating a region would require space in the
same heap. This means, the heap will grow as soon as the reported
utilization is less than 1 MiB. It will also return memory if an entire
subheap is no longer needed, although that is rarely possible.
2020-08-30 11:39:38 +02:00
Tom
67dbb56444 Kernel: Release page tables when no longer needed
When unmapping regions, check if page tables can be freed.

This is a follow-up change for #3254.
2020-08-28 09:21:24 +02:00
Tom
bcbe2fe525 Kernel: Protect looping over VMObject regions
We need to hold the memory manager lock so nobody else can modify
these lists while we're iterating them.
2020-08-26 01:25:06 +02:00
Tom
08a569fbe0 Kernel: Make PhysicalPage not movable and use atomic ref counting
We should not be moving ref-counted objects.
2020-08-25 09:48:48 +02:00
Andreas Kling
2fd9e72264 Revert "Kernel: Switch singletons to use new Singleton class"
This reverts commit f48feae0b2.
2020-08-22 18:01:59 +02:00
Andreas Kling
b0a24a83be Revert "Kernel: Fix regression where MemoryManager is initialized twice"
This reverts commit 8a75e0b892.
2020-08-22 16:34:15 +02:00
Andreas Kling
0db7e04c2e Revert "Kernel: Make PhysicalPage not movable and use atomic ref counting"
This reverts commit a89ccd842b.
2020-08-22 16:34:11 +02:00
Tom
a89ccd842b Kernel: Make PhysicalPage not movable and use atomic ref counting
We should not be moving ref-counted objects.
2020-08-22 10:46:24 +02:00
Tom
8a75e0b892 Kernel: Fix regression where MemoryManager is initialized twice
MemoryManager cannot use the Singleton class because
MemoryManager::initialize is called before the global constructors
are run. That caused the Singleton to be re-initialized, causing
it to create another MemoryManager instance.
2020-08-22 10:46:24 +02:00
Tom
f48feae0b2 Kernel: Switch singletons to use new Singleton class
Fixes #3226
2020-08-21 11:47:35 +02:00
Andreas Kling
be7add690d Kernel: Rename region_from_foo() => find_region_from_foo()
Let's emphasize that these functions actually go out and find regions.
2020-07-30 23:52:28 +02:00
Tom
bc107d0b33 Kernel: Add SMP IPI support
We can now properly initialize all processors without
crashing by sending SMP IPI messages to synchronize memory
between processors.

We now initialize the APs once we have the scheduler running.
This is so that we can process IPI messages from the other
cores.

Also rework interrupt handling a bit so that it's more of a
1:1 mapping. We need to allocate non-sharable interrupts for
IPIs.

This also fixes the occasional hang/crash because all
CPUs now synchronize memory with each other.
2020-07-06 17:07:44 +02:00
Tom
e373e5f007 Kernel: Fix signal delivery
When delivering urgent signals to the current thread
we need to check if we should be unblocked, and if not
we need to yield to another process.

We also need to make sure that we suppress context switches
during Process::exec() so that we don't clobber the registers
that it sets up (eip mainly) by a context switch. To be able
to do that we add the concept of a critical section, which are
similar to Process::m_in_irq but different in that they can be
requested at any time. Calls to Scheduler::yield and
Scheduler::donate_to will return instantly without triggering
a context switch, but the processor will then asynchronously
trigger a context switch once the critical section is left.
2020-07-03 19:32:34 +02:00
Tom
2a38cc9a12 Kernel: Add a quickmap region for each processor
Threads need to be able to concurrently quickmap things.
2020-07-01 12:07:01 +02:00
Tom
fb41d89384 Kernel: Implement software context switching and Processor structure
Moving certain globals into a new Processor structure for
each CPU allows us to eventually run an instance of the
scheduler on each CPU.
2020-07-01 12:07:01 +02:00
Tom
841364b609 Kernel: Add mechanism to identity map the lowest 2MB 2020-06-04 18:15:23 +02:00
etaIneLp
826dc94187 Kernel: Create page structures correctly in boot.s 2020-05-26 09:50:12 +02:00
Andreas Kling
55f61c0004 Kernel: Add for_each_vmobject_of_type<T>
This makes iterating over a specific type of VMObjects a bit nicer.
2020-05-08 22:10:47 +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
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
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
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
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
e28809a996 Kernel: Add forward declaration header 2020-02-16 01:50:32 +01:00
Andreas Kling
1d611e4a11 Kernel: Reduce header dependencies of MemoryManager and Region 2020-02-16 01:33:41 +01:00
Andreas Kling
a356e48150 Kernel: Move all code into the Kernel namespace 2020-02-16 01:27:42 +01:00
Andreas Kling
c624d3875e Kernel: Use a shared physical page for zero-filled pages until written
This patch adds a globally shared zero-filled PhysicalPage that will
be mapped into every slot of every zero-filled AnonymousVMObject until
that page is written to, achieving CoW-like zero-filled pages.

Initial testing show that this doesn't actually achieve any sharing yet
but it seems like a good design regardless, since it may reduce the
number of page faults taken by programs.

If you look at the refcount of MM.shared_zero_page() it will have quite
a high refcount, but that's just because everything maps it everywhere.
If you want to see the "real" refcount, you can build with the
MAP_SHARED_ZERO_PAGE_LAZILY flag, and we'll defer mapping of the shared
zero page until the first NP read fault.

I've left this behavior behind a flag for future testing of this code.
2020-02-15 13:17:40 +01:00
Liav A
200a5b0649 Kernel: Remove map_for_kernel() in MemoryManager
We don't need to have this method anymore. It was a hack that was used
in many components in the system but currently we use better methods to
create virtual memory mappings. To prevent any further use of this
method it's best to just remove it completely.

Also, the APIC code is disabled for now since it doesn't help booting
the system, and is broken since it relies on identity mapping to exist
in the first 1MB. Any call to the APIC code will result in assertion
failed.

In addition to that, the name of the method which is responsible to
create an identity mapping between 1MB to 2MB was changed, to be more
precise about its purpose.
2020-01-21 11:29:58 +01:00
Andreas Kling
6eab7b398d Kernel: Make ProcessPagingScope restore CR3 properly
Instead of restoring CR3 to the current process's paging scope when a
ProcessPagingScope goes out of scope, we now restore exactly whatever
the CR3 value was when we created the ProcessPagingScope.

This fixes breakage in situations where a process ends up with nested
ProcessPagingScopes. This was making profiling very fragile, and with
this change it's now possible to profile g++! :^)
2020-01-19 13:44:53 +01:00
Andreas Kling
f7b394e9a1 Kernel: Assert that copy_to/from_user() are called with user addresses
This will panic the kernel immediately if these functions are misused
so we can catch it and fix the misuse.

This patch fixes a couple of misuses:

    - create_signal_trampolines() writes to a user-accessible page
      above the 3GB address mark. We should really get rid of this
      page but that's a whole other thing.

    - CoW faults need to use copy_from_user rather than copy_to_user
      since it's the *source* pointer that points to user memory.

    - Inode faults need to use memcpy rather than copy_to_user since
      we're copying a kernel stack buffer into a quickmapped page.

This should make the copy_to/from_user() functions slightly less useful
for exploitation. Before this, they were essentially just glorified
memcpy() with SMAP disabled. :^)
2020-01-19 09:18:55 +01:00
Andreas Kling
2cd212e5df Kernel: Let's say that everything < 3GB is user virtual memory
Technically the bottom 2MB is still identity-mapped for the kernel and
not made available to userspace at all, but for simplicity's sake we
can just ignore that and make "address < 0xc0000000" the canonical
check for user/kernel.
2020-01-19 08:58:33 +01:00
Andreas Kling
94ca55cefd Meta: Add license header to source files
As suggested by Joshua, this commit adds the 2-clause BSD license as a
comment block to the top of every source file.

For the first pass, I've just added myself for simplicity. I encourage
everyone to add themselves as copyright holders of any file they've
added or modified in some significant way. If I've added myself in
error somewhere, feel free to replace it with the appropriate copyright
holder instead.

Going forward, all new source files should include a license header.
2020-01-18 09:45:54 +01:00
Andreas Kling
19c31d1617 Kernel: Always dump kernel regions when dumping process regions 2020-01-18 08:57:18 +01:00
Andreas Kling
345f92d5ac Kernel: Remove two unused MemoryManager functions 2020-01-18 08:57:18 +01:00