Commit graph

75 commits

Author SHA1 Message Date
Andreas Kling
b51031bb54 Kernel: Add a /proc/all process table dump.
This will be useful for implementing some process-related utilities.
2019-02-03 18:53:18 +01:00
Andreas Kling
2d17fe58bc Kernel: Remove unnecessary assertion in page_in_from_inode().
Turns out I had confused myself about the situation. Just because a page
has been paged in by another process doesn't mean that the *current*
process's page directory has the present bit set! D'oh. :^)
2019-02-03 03:04:40 +01:00
Andreas Kling
3eeff0dd14 Kernel: Improve crash info if page_in_from_inode() is called redundantly. 2019-02-03 02:49:59 +01:00
Andreas Kling
7e4376d469 Kernel: When entering page_in_from_inode(), assert that !physical_page.
It would be really weird to enter here with a physical page already present
in the VMObject's page slot. Let's assert that this doesn't happen.
2019-02-03 02:33:47 +01:00
Andreas Kling
abe3f515b1 Make font loading use mmap().
This exposed a serious race condition in page_in_from_inode().
Reordered the logic and added a paging lock to VMObject.
Now, only one process can page in from a VMObject at a time.
There are definitely ways to optimize this, for instance by making
the locking be per-page instead. It's not something that I'm going
to worry about right now though.
2019-02-03 01:36:25 +01:00
Andreas Kling
ffab6897aa Big, possibly complete sweep of naming changes. 2019-01-31 17:31:23 +01:00
Andreas Kling
0932efe72e Kernel: Actually zero-fill eagerly committed regions.
Previously, calling Region::commit() would make sure to allocate any missing
physical pages, but they would contain uninitialized data. This was very
obvious when allocating GraphicsBitmaps as they would have garbage pixels
rather than being filled with black.

The MM quickmap mechanism didn't work when operating on a non-active page
directory (which happens when we're in the middle of exec, for example.)
This patch changes quickmap to reside in the shared kernel page directory.

Also added some missing clobber lists to inline asm that I stumbled on.
2019-01-31 04:03:05 +01:00
Andreas Kling
6d351bb326 Kernel: Move RAM size detection to MemoryManager and use what we learn. 2019-01-27 10:17:27 +01:00
Andreas Kling
11b73c38d8 Kernel: Fix incorrect EFAULTs when syscall would write into COW pages. 2019-01-25 01:39:15 +01:00
Andreas Kling
aa24547e12 Kernel: Finally stop exposing Region members to the public. 2019-01-24 18:09:46 +01:00
Andreas Kling
07f4c8b01b VFS: Get rid of the deprecated Inode::write(const ByteBuffer&).
Fix the only remaining call site to use Inode::write_bytes().
2019-01-23 04:59:47 +01:00
Andreas Kling
2f2f28f212 Kernel: Refactor Region/PageDirectory ownership model.
Make PageDirectory retainable and have each Region co-own the PageDirectory
they're mapped into. When unmapped, Region has no associated PageDirectory.

This allows Region to automatically unmap itself when destroyed.
2019-01-22 05:06:22 +01:00
Andreas Kling
76a2881793 Mark the two Regions used GraphicsBitmaps as explicitly shared.
This fixes a goofy problem where forking a GUI process would cowify the
GraphicsBitmap for everyone making a hue confusing mess.
2019-01-21 05:18:28 +01:00
Andreas Kling
b75ee4aacb Coding style fixes in AK. 2019-01-19 22:53:05 +01:00
Andreas Kling
4fef895eda Rework WindowServer to use select() in its main event loop.
The system can finally idle without burning CPU. :^)

There are some issues with scheduling making the mouse cursor sloppy
and unresponsive that need to be dealt with.
2019-01-16 17:20:58 +01:00
Andreas Kling
b46ae2bf09 Get rid of Vnode concept.
We already have an abstraction between Process and Inode/CharacterDevice/FIFO
and it's called FileDescriptor. :^)
2019-01-16 12:57:07 +01:00
Andreas Kling
a8baee4dcd Tidy up memory map a bit and write out the general map in MemoryManager.
There was a bug that given enough supervisor page allocation, we would
eventually start dipping into the kmalloc range.
2019-01-16 00:44:09 +01:00
Andreas Kling
c0ef060a7c Let's just assume we have 32MB of physical memory to work with.
I should eventually figure out the exact amount of memory but not now.
2019-01-15 06:48:36 +01:00
Andreas Kling
659c54e32b Switch into 1024x768x32bpp VESA LFB mode at boot.
This is going to be pretty cool once I can hook up the Widgets/ code to it.
2019-01-09 02:29:11 +01:00
Andreas Kling
683185e4aa MM: Allocate page tables from a separate set of physical pages.
The old approach only worked because of an overpermissive accident.
There's now a concept of supervisor physical pages that can be allocated.
They all sit in the low 4 MB of physical memory and are identity mapped,
shared between all processes, and only ring 0 can access them.
2019-01-01 02:09:43 +01:00
Andreas Kling
a5ffa2eec7 Add a PageDirectory::flush() that does nothing if another PD is active.
This way callers can just flush() every time after making any modification
and the PageDirectory itself will decide if TLB invalidation is necessary.
2018-12-31 20:52:59 +01:00
Andreas Kling
9eca2ffd41 Make PhysicalPage eternally allocated. 2018-12-31 20:25:42 +01:00
Andreas Kling
3e37a1f5c3 Optimize PageDirectory destruction.
Remove an extra hash lookup and only iterate over the actually-used
PhysicalPages that we need to clean up.
2018-12-31 15:18:02 +01:00
Andreas Kling
edac1d6748 Make PageDirectory store physical pages in a HashMap.
This container is really just there to keep a retain on the individual
PhysicalPages for each page table. A HashMap does the job with far greater
space efficiency.
2018-12-31 15:10:12 +01:00
Andreas Kling
193ead94f8 Let PageDirectory have a PhysicalPage for the PDB instead of being the PDB.
This is more efficient than using the wasteful kmalloc_aligned() approach
to allocation. It also allows much tighter encapsulation of the class.
2018-12-31 14:58:03 +01:00
Andreas Kling
0dd5279eb1 MM: Fix bug when mapping a region with a VMO with non-zero offset. 2018-12-29 03:35:48 +01:00
Andreas Kling
f6179ad9f9 Add slightly better kmalloc_aligned() and kfree_aligned().
Process page directories can now actually be freed. This could definitely
be implemented in a nicer, less wasteful way, but this works for now.

The spawn stress test can now run for a lot longer but eventually dies
due to kmalloc running out of memory.
2018-12-26 21:47:15 +01:00
Andreas Kling
aff89d2fd7 Yet more coding style fixes. 2018-12-03 01:38:22 +01:00
Andreas Kling
629c5be10b Add basic zero faults.
mmap() will now map uncommitted pages that get allocated and zeroed upon the
first access. I also made /proc/PID/vm show number of "committed" bytes in
each region. This is so cool! :^)
2018-11-19 02:17:20 +01:00
Andreas Kling
457a5df7d5 Rename:
VirtualFileSystem -> VFS
VirtualFileSystem::Node -> Vnode
2018-11-15 14:43:10 +01:00
Andreas Kling
10c470e95f Make page_in_from_vnode 2x faster.
...by adding a new class called Ext2Inode that inherits CoreInode.
The idea is that a vnode will wrap a CoreInode rather than InodeIdentifier.
Each CoreInode subclass can keep whatever caches they like.

Right now, Ext2Inode caches the list of block indices since it can be very
expensive to retrieve.
2018-11-13 13:02:39 +01:00
Andreas Kling
d5d45d1088 Rage hacking to get bash to run. It finally runs. So cool! :^) 2018-11-11 15:38:07 +01:00
Andreas Kling
c97a5862ce Remove MM::allocate_physical_pages() since it wasn't used.
Everyone was allocating one page at a time with allocate_physical_page().
2018-11-10 22:14:41 +01:00
Andreas Kling
e71cb1c56b Fix some paging related bugs exposed by the spawn stress test.
- Process::exec() needs to restore the original paging scope when called
  on a non-current process.
- Add missing InterruptDisabler guards around g_processes access.
- Only flush the TLB when modifying the active page tables.
2018-11-09 01:25:31 +01:00
Andreas Kling
7b96218389 Fix VMO leak in Process::exec().
Gotta make sure things get cleaned up before we yield-teleport in exec().
Also VMOs and regions are now viewable through /proc/mm and /proc/regions.
2018-11-08 22:25:29 +01:00
Andreas Kling
cd1e7419f0 Teach Process::exec() about the magic of file-backed VMO's.
This is really sweet! :^) The four instances of /bin/sh spawned at
startup now share their read-only text pages.

There are problems and limitations here, and plenty of room for
improvement. But it kinda works.
2018-11-08 21:20:09 +01:00
Andreas Kling
3b2dcd5929 Add a VMO pointer to VNode.
This way, if anyone tries to map an already mapped file, we share the VMO.
2018-11-08 15:39:26 +01:00
Andreas Kling
862f108cb5 Refactor the virtual memory object model a bit:
Process now has a number of Regions.
Each Region is backed by a VMObject.
A VMObject can be file-backed or anonymous. These can be shared.
2018-11-08 14:42:16 +01:00
Andreas Kling
3c8064a787 Support basic mmap'ing of a file!
All right, we can now mmap() a file and it gets magically paged in from fs
in response to an NP page fault. This is really cool :^)

I need to refactor this to support sharing of read-only file-backed pages,
but it's cool to just have something working.
2018-11-08 12:59:16 +01:00
Andreas Kling
153ea704af Add some basic signal support.
It only works for sending a signal to a process that's in userspace code.

We implement reception by synthesizing a PUSHA+PUSHF in the receiving process
(operating on values in the TSS.)
The TSS CS:EIP is then rerouted to the signal handler and a tiny return
trampoline is constructed in a dedicated region in the receiving process.

Also hacked up /bin/kill to be able to send arbitrary signals (kill -N PID)
2018-11-06 10:56:41 +01:00
Andreas Kling
9e62eb4856 Only COW on fault if the physical page has retain_count > 1.
This makes COW pages lazily-but-transparently revert back to read/write.
2018-11-05 14:11:21 +01:00
Andreas Kling
2d045d2a64 Implement COW pages! :^)
sys$fork() now clones all writable regions with per-page COW bits.
The pages are then mapped read-only and we handle a PF by COWing the pages.

This is quite delightful. Obviously there's lots of work to do still,
and it needs better data structures, but the general concept works.
2018-11-05 13:48:07 +01:00
Andreas Kling
e85c22fe58 Tidy up the page fault code a bit in preparation. 2018-11-05 10:29:19 +01:00
Andreas Kling
72cdc62155 Replace zones with individually tracked physical pages.
It's just a simple struct { ref_count, paddr }.
This will allow me to implement lazy zeroing and COW pages.
2018-11-05 10:23:00 +01:00
Andreas Kling
7fe4063323 Region::clone() should share the zone if it's read-only.
This avoids copying the .text and .rodata segments in fork().
The next step is copy-on-write support for the writable regions.
2018-11-03 23:20:49 +01:00
Andreas Kling
da13c9a264 Map pages in read-only ELF sections as non-writable.
This is so cool! :^) Now you'll crash if you try to write into your
.text or .rodata segments.
2018-11-03 11:36:45 +01:00
Andreas Kling
aa6d06b47e Use ELF program headers to load executables smarter.
This turned out way better than the old code. ELF loading is now quite
straightforward, and we don't need the weird concept of subregions anymore.

Next step is to respect the is_writable flag.
2018-11-03 11:29:30 +01:00
Andreas Kling
20fb1fc377 Fix some bugs in execve() and make sh use it for process launching.
Interrupting children of sh now always works with ^C :^)
2018-11-03 02:08:06 +01:00
Andreas Kling
202bdb553c Implemented sys$execve().
It's really crufty, but it basically works!
2018-11-03 01:51:42 +01:00
Andreas Kling
b59ce22fc5 Fix dumb-but-hard-to-find bug in paging.
This was the fix:

-process.m_page_directory[0] = m_kernel_page_directory[0];
-process.m_page_directory[1] = m_kernel_page_directory[1];
+process.m_page_directory->entries[0] = m_kernel_page_directory->entries[0];
+process.m_page_directory->entries[1] = m_kernel_page_directory->entries[1];

I spent a good two hours scratching my head, not being able to figure out why
user process page directories felt they had ownership of page tables in the
kernel page directory.

It was because I was copying the entire damn kernel page directory into
the process instead of only sharing the two first PDE's. Dang!
2018-11-03 00:35:57 +01:00