Commit graph

261 commits

Author SHA1 Message Date
Linus Groh bbe787a0af Everywhere: Re-format with clang-format-11
Compared to version 10 this fixes a bunch of formatting issues, mostly
around structs/classes with attributes like [[gnu::packed]], and
incorrect insertion of spaces in parameter types ("T &"/"T &&").
I also removed a bunch of // clang-format off/on and FIXME comments that
are no longer relevant - on the other hand it tried to destroy a couple of
neatly formatted comments, so I had to add some as well.
2020-12-31 21:51:00 +01:00
Luke 865f5ed4f6 Kernel: Prevent sign bit extension when creating a PDPTE
When doing the cast to u64 on the page directory physical address,
the sign bit was being extended. This only beomes an issue when
crossing the 2 GiB boundary. At >= 2 GiB, the physical address
has the sign bit set. For example, 0x80000000.

This set all the reserved bits in the PDPTE, causing a GPF
when loading the PDPT pointer into CR3. The reserved bits are
presumably there to stop you writing out a physical address that
the CPU physically cannot handle, as the size of the reserved bits
is determined by the physical address width of the CPU.

This fixes this by casting to FlatPtr instead. I believe the sign
extension only happens when casting to a bigger type. I'm also using
FlatPtr because it's a pointer we're writing into the PDPTE.
sizeof(FlatPtr) will always be the same size as sizeof(void*).

This also now asserts that the physical address in the PDPTE is
within the max physical address the CPU supports. This is better
than getting a GPF, because CPU::handle_crash tries to do the same
operation that caused the GPF in the first place. That would cause
an infinite loop of GPFs until the stack was exhausted, causing a
triple fault.

As far as I know and tested, I believe we can now use the full 32-bit
physical range without crashing.

Fixes #4584. See that issue for the full debugging story.
2020-12-30 20:33:15 +01:00
Lenny Maiorani b2316701a8 Everywhere: void arguments to C functions
Problem:
- C functions with no arguments require a single `void` in the argument list.

Solution:
- Put the `void` in the argument list of functions in C header files.
2020-12-26 10:10:27 +01:00
Andreas Kling c25cf5fb56 Kernel: Panic if we're about to switch to a user thread with IOPL!=0
This is a crude protection against IOPL elevation attacks. If for
any reason we find ourselves about to switch to a user mode thread
with IOPL != 0, we'll now simply panic the kernel.

If this happens, it basically means that something tricked the kernel
into incorrectly modifying the IOPL of a thread, so it's no longer
safe to trust the kernel anyway.
2020-12-23 14:30:10 +01:00
Andreas Kling 6bfbc5f5f5 Kernel: Don't allow modifying IOPL via sys$ptrace() or sys$sigreturn()
It was possible to overwrite the entire EFLAGS register since we didn't
do any masking in the ptrace and sigreturn syscalls.

This made it trivial to gain IO privileges by raising IOPL to 3 and
then you could talk to hardware to do all kinds of nasty things.

Thanks to @allesctf for finding these issues! :^)

Their exploit/write-up: https://github.com/allesctf/writeups/blob/master/2020/hxpctf/wisdom2/writeup.md
2020-12-22 19:38:25 +01:00
Liav A 39c1783387 Kernel: Allow to install a real IRQ handler on a spurious one
IRQ 7 and 15 on the PIC architecture are used for spurious interrupts.
IRQ 7 could also be used for LPT connection, and IRQ 15 can be used for
the secondary IDE channel. Therefore, we need to allow to install a
real IRQ handler and check if a real IRQ was asserted. If so, we handle
them in the usual way.

A note on this fix - unregistering or registering a new IRQ handler
after we already registered one in the spurious interrupt handler is
not supported yet.
2020-12-21 00:19:21 +01:00
Lenny Maiorani 765936ebae
Everywhere: Switch from (void) to [[maybe_unused]] (#4473)
Problem:
- `(void)` simply casts the expression to void. This is understood to
  indicate that it is ignored, but this is really a compiler trick to
  get the compiler to not generate a warning.

Solution:
- Use the `[[maybe_unused]]` attribute to indicate the value is unused.

Note:
- Functions taking a `(void)` argument list have also been changed to
  `()` because this is not needed and shows up in the same grep
  command.
2020-12-21 00:09:48 +01:00
Tom c455fc2030 Kernel: Change wait blocking to Process-only blocking
This prevents zombies created by multi-threaded applications and brings
our model back to closer to what other OSs do.

This also means that SIGSTOP needs to halt all threads, and SIGCONT needs
to resume those threads.
2020-12-12 21:28:12 +01:00
Tom da5cc34ebb Kernel: Fix some issues related to fixes and block conditions
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-12 21:28:12 +01:00
Tom 766db673c1 Kernel: Flush TLBs concurrently
Instead of flushing the TLB on the current processor first and then
notifying the other processors to do the same, notify the others
first, and while waiting on the others flush our own.
2020-12-02 23:49:52 +01:00
Tom 5e08ae4e14 Kernel: Fix counting interrupts
Move counting interrupts out of the handle_interrupt method so that
it is done in all cases without the interrupt handler having to
implement it explicitly.

Also make the counter an atomic value as e.g. the LocalAPIC interrupts
may be triggered on multiple processors simultaneously.

Fixes #4297
2020-12-02 23:19:59 +01:00
Tom 78f1b5e359 Kernel: Fix some problems with Thread::wait_on and Lock
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-12-01 09:48:34 +01:00
Tom 6a620562cc Kernel: Allow passing a thread argument for new kernel threads
This adds the ability to pass a pointer to kernel thread/process.
Also add the ability to use a closure as thread function, which
allows passing information to a kernel thread more easily.
2020-11-30 13:17:02 +01:00
Tom dc9ddf8104 Kernel: Fix deadlock when unicasting/broadcasting SMP message
When two processors send each others a SMP message at the same time
they need to process messages while waiting for delivery of the
message they just sent, or they will deadlock.
2020-11-11 12:27:25 +01:00
Tom 3ee7c21fae Kernel: Implement capturing stack trace on a different CPU
When trying to get a stack trace of a thread on another CPU we send
a SMP message to that processor to capture the stack trace for us.
2020-11-11 12:27:25 +01:00
Tom e26e0445b5 Kernel: Make m_halt_requested an atomic variable
We need to make sure the change to this variable is visible to all
processors instantly.
2020-11-11 12:27:25 +01:00
Tom b9a97ff81f Kernel: Add mechanism to queue deferred function calls
Function calls that are deferred will be executed before a thread
enters a pre-emptable state (meaning it is not in a critical section
and it is not in an irq handler). If it is not already in such a
state, it will be called immediately.

This is meant to be used from e.g. IRQ handlers where we might want
to block a thread until an interrupt happens.
2020-11-04 21:21:37 +01:00
Tom 328e481ee9 Kernel: Halt all processors on assertion failure 2020-10-26 08:57:25 +01:00
Tom b8ad4932a9 Kernel: Fix race condition waiting for IPI while other CPU requested halt
It's possible that we broadcast an IPI message right at the same time
another processor requests a halt. Rather than spinning forever waiting
for that message to be handled, check if we should halt while waiting.
2020-10-26 08:57:25 +01:00
Lenny Maiorani d1fe6a0b53
Everywhere: Redundant inline specifier on constexpr functions (#3807)
Problem:
- `constexpr` functions are decorated with the `inline` specifier
  keyword. This is redundant because `constexpr` functions are
  implicitly `inline`.
- [dcl.constexpr], §7.1.5/2 in the C++11 standard): "constexpr
  functions and constexpr constructors are implicitly inline (7.1.2)".

Solution:
- Remove the redundant `inline` keyword.
2020-10-20 18:08:13 +02:00
Nico Weber 8a01be4849 Kernel: Add some CPU feature flags related to TSC
In case we want to rely more on TSC in time keeping in the future, idk

This adds:

- RDTSCP, for when the RDTSCP instruction is available

- CONSTANT_TSC, for when the TSC has a constant frequency, invariant
  under things like the CPU boosting its frequency.

- NONSTOP_TSC, for when the TSC doesn't pause when the CPU enters
  sleep states.

AMD cpus and newer intel cpus set the INVSTC bit (bit 8 in edx of
extended cpuid 0x8000000008), which implies both CONSTANT_TSC and
NONSTOP_TSC. Some older intel processors have CONSTANT_TSC but not
NONSTOP_TSC; this is set based on cpu model checks.

There isn't a ton of documentation on this, so this follows Linux
terminology and http://blog.tinola.com/?e=54

CONSTANT_TSC:
39b3a79105

NONSTOP_TSC:
40fb17152c

qemu disables invtsc (bit 8 in edx of extended cpuid 0x8000000008)
by default even if the host cpu supports it. It can be enabled by
running with `SERENITY_QEMU_CPU=host,migratable=off` set.
2020-10-08 10:00:39 +02:00
Linus Groh bcfc6f0c57 Everywhere: Fix more typos 2020-10-03 12:36:49 +02:00
Ben Wiederhake 64cc3f51d0 Meta+Kernel: Make clang-format-10 clean 2020-09-25 21:18:17 +02:00
Tom 365fa05a82 Kernel: Handle safe_memcpy/safe_memset/safe_strnlen faults in irq handlers
Fix gracefully failing these calls if used within IRQ handlers. If we're
handling IRQs, we need to handle these failures first, because we can't
really resolve page faults in a meaningful way. But if we know that it
was one of these functions that failed, then we can gracefully handle
the situation.

This solves a crash where the Scheduler attempts to produce backtraces
in the timer irq, some of which cause faults.

Fixes #3492
2020-09-14 21:18:59 +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 7d1b8417bd Kernel: Add safe_memcpy, safe_memset and safe_strnlen
These special functions can be used to safely copy/set memory or
determine the length of a string, e.g. provided by user mode.

In the event of a page fault, safe_memcpy/safe_memset will return
false and safe_strnlen will return -1.
2020-09-13 21:19:15 +02:00
Tom 0fab0ee96a Kernel: Rename Process::is_ring0/3 to Process::is_kernel/user_process
Since "rings" typically refer to code execution and user processes
can also execute in ring 0, rename these functions to more accurately
describe what they mean: kernel processes and user processes.
2020-09-10 19:57:15 +02:00
Tom 19ffd9d677 Kernel: Fix detecting in what ring a crash happened
The ring is determined based on the CS register. This fixes crashes
being handled as ring 3 crashes even though EIP/CS clearly showed
that the crash happened in the kernel.
2020-09-10 19:57:15 +02:00
Luke 8a2fd0e436 Kernel: Fix Processor::features_string() stopping too early and detect more features
The exit condition for the loop was sizeof(m_features) * 8,
which was 32. Presumably this was supposed to mean 32 bits, but it
actually made it stop as soon as it reached the 6th bit.

Also add detection for more SIMD CPU features.
2020-08-31 18:57:54 +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
Muhammad Zahalqa e035640cd5
Kernel: Remove unneeded #include in ProcessorInfo.cpp (#3211) 2020-08-19 11:25:12 +02:00
Muhammad Zahalqa ff577e22a3 Kernel: ProcessorInfo.cpp remove unused headers 2020-08-18 13:41:08 +02:00
Nico Weber 430b265cd4 AK: Rename KB, MB, GB to KiB, MiB, GiB
The SI prefixes "k", "M", "G" mean "10^3", "10^6", "10^9".
The IEC prefixes "Ki", "Mi", "Gi" mean "2^10", "2^20", "2^30".

Let's use the correct name, at least in code.

Only changes the name of the constants, no other behavior change.
2020-08-16 16:33:28 +02:00
Itamar 3b422564f3 Kernel: Fix behaviour of PT_TRACEME in ptrace
The behaviour of the PT_TRACEME feature has been broken for some time,
this change fixes it.

When this ptrace flag is used, the traced process should be paused
before exiting execve.
We previously were sending the SIGSTOP signal at a stage where
interrupts are disabled, and the traced process continued executing
normally, without pausing and waiting for the tracer.
This change fixes it.
2020-08-15 15:06:35 +02:00
Ben Wiederhake 936d5dcc01 Kernel: Tell compiler about invisible calls
This makes the Kernel build cleanly with -Wmissing-declarations.
2020-08-12 20:40:59 +02:00
Tom 728de56481 Kernel: Prevent recursive calls into the scheduler
Upon leaving a critical section (such as a SpinLock) we need to
check if we're already asynchronously invoking the Scheduler.
Otherwise we might end up triggering another context switch
as soon as leaving the scheduler lock.

Fixes #2883
2020-08-02 17:15:11 +02:00
etaIneLp 586ada7a14 Kernel: Tell the bootloader to put us into graphics mode 2020-08-01 07:57:29 +02:00
Nico Weber 4eb967b5eb LibC+Kernel: Start implementing sysconf
For now, only the non-standard _SC_NPROCESSORS_CONF and
_SC_NPROCESSORS_ONLN are implemented.

Use them to make ninja pick a better default -j value.
While here, make the ninja package script not fail if
no other port has been built yet.
2020-07-15 00:07:20 +02:00
Tom b02d33bd63 Kernel: Fix some flaws that caused crashes or hangs during boot
We need to halt the BSP briefly until all APs are ready for the
first context switch, but we can't hold the same spinlock by all
of them while doing so. So, while the APs are waiting on each other
they need to release the scheduler lock, and then once signaled
re-acquire it. Should solve some timing dependent hangs or crashes,
most easily observed using qemu with kvm disabled.
2020-07-09 23:24:55 +02:00
Tom ce5ae83963 Kernel: Detect syscall/sysenter support 2020-07-08 23:47:36 +02:00
Tom 06d50f64b0 Kernel: Aggregate TLB flush requests for Regions for SMP
Rather than sending one TLB flush request for each page,
aggregate them so that we're not spamming the other
processors with FlushTLB IPIs.
2020-07-06 22:39:06 +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
Andreas Kling 163c9d5f8f Kernel: Thread::wait_on() must always leave interrupts enabled on exit
The short-circuit path added for waiting on a queue that already had a
pending wake was able to return with interrupts disabled, which breaks
the API contract of wait_on() always returning with IF=1.

Fix this by adding a way to override the restored IF in ScopedCritical.
2020-07-06 11:33:32 +02:00
Andreas Kling 3e0020e67d Kernel: Tidy up the ScopedCritical class a little bit 2020-07-06 11:33:32 +02:00
Tom 2a82a25fec Kernel: Various context switch fixes
These changes solve a number of problems with the software
context swithcing:

* The scheduler lock really should be held throughout context switches
* Transitioning from the initial (idle) thread to another needs to
  hold the scheduler lock
* Transitioning from a dying thread to another also needs to hold
  the scheduler lock
* Dying threads cannot necessarily be finalized if they haven't
  switched out of it yet, so flag them as active while a processor
  is running it (the Running state may be switched to Dying while
  it still is actually running)
2020-07-06 10:00:24 +02:00
Tom bb84fad0bf Kernel: Fix retreiving frame pointer from a thread
If we're trying to walk the stack for another thread, we can
no longer retreive the EBP register from Thread::m_tss. Instead,
we need to look at the top of the kernel stack, because all threads
not currently running were last in kernel mode. Context switches
now always trigger a brief switch to kernel mode, and Thread::m_tss
only is used to save ESP and EIP.

Fixes #2678
2020-07-03 21:16:56 +02:00
Tom 9b4e6f6a23 Kernel: Consolidate features into CPUFeature enum
This allows us to consolidate printing out all the CPU features
into one log statement. Also expose them in /proc/cpuinfo
2020-07-03 19:32:34 +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 57b61b2dde Kernel: Split initialization of Processor structure
We need to very early on initialize the Processor structure so
that we can use RecursiveSpinLock early on.
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 16783bd14d Kernel: Turn Thread::current and Process::current into functions
This allows us to query the current thread and process on a
per processor basis
2020-07-01 12:07:01 +02:00
Tom d99901660d Kernel/LibCore: Expose processor id where a thread last ran 2020-07-01 12:07:01 +02:00
Tom d98edb3171 Kernel: List all CPUs in /proc/cpuinfo 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
3541 4fa6301523 Kernel: Add g_cpu_supports_rdseed
CPUs which support RDRAND do not necessarily support RDSEED. This
introduces a flag g_cpu_supports_rdseed which is set appropriately
by CPUID. This causes Haswell CPUs in particular (and probably a lot
of AMD chips) to now fail to boot with #2634, rather than an illegal
instruction.

It seems like the KernelRng needs either an initial reseed call or
more random events added before the first call to get_good_random,
but I don't feel qualified to make that kind of change.
2020-06-27 12:57:03 +02:00
Andreas Kling 723f4e5ee6 Meta: Scale back overly informal user-facing strings
We were getting a little overly memey in some places, so let's scale
things back to business-casual.

Informal language is fine in comments, commits and debug logs,
but let's keep the runtime nice and presentable. :^)
2020-06-17 18:35:49 +02:00
Tom 0bc92c259d Kernel: Detect APs and boot them into protected mode
This isn't fully working, the APs pretend like they're
fully initialized and are just halted permanently for now.
2020-06-04 18:15:23 +02:00
etaIneLp 7bc871ca8d Kernel: Stop bootloader from setting video mode with Multiboot
Meta: Update INSTALL.md and grub configs for new boot_mode option
2020-05-28 00:50:55 +02:00
etaIneLp 82d0352a67 Kernel: Unmap first MB after jumping above 3GB 2020-05-26 09:50:12 +02:00
etaIneLp 826dc94187 Kernel: Create page structures correctly in boot.s 2020-05-26 09:50:12 +02:00
Andreas Kling 84b7bc5e14 Kernel: Add convenient ways to map whole BIOS and EBDA into memory
This patch adds a MappedROM abstraction to the Kernel VM subsystem.
It's basically the read-only byte buffer equivalent of a TypedMapping.

We use this in the ACPI and MP table parsers to scan for interesting
stuff in low memory instead of doing a bunch of address arithmetic.
2020-05-22 13:17:38 +02:00
Andreas Kling 81d35c6891 Kernel: Always inline stac(), clac() and SmapDisabler
Let's not be paying the function call overhead for these tiny ops.
Maybe there's an argument for having fewer gadgets in the kernel but
for now we're actually seeing stac() in profiles so let's put
that above theoretical security issues.
2020-05-20 14:17:01 +02:00
Andreas Kling 21d5f4ada1 Kernel: Absorb LibBareMetal back into the kernel
This was supposed to be the foundation for some kind of pre-kernel
environment, but nobody is working on it right now, so let's move
everything back into the kernel and remove all the confusion.
2020-05-16 12:00:04 +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
Itamar d04409b444 CPU: Handle Debug exception
We currently only care about debug exceptions that are triggered
by the single-step execution mode.

The debug exception is translated to a SIGTRAP, which can be caught
and handled by the tracing thread.
2020-04-13 23:20:59 +02:00
Itamar 77f671b462 CPU: Handle breakpoint trap
Also, start working on the debugger app.
2020-04-13 00:53:22 +02:00
Marco Wang 3fae4cb054 Kernel: Prepend missing license 2020-04-03 09:12:29 +02:00
Liav A f7b207c7ae CPU: Move EOI call to the end of handle_interrupt() 2020-03-24 16:15:33 +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 9a303cc5a5 Kernel: Add the NonMaskableInterruptDisabler class
This class will be used later to disable NMIs when we
initialize the RTC timer.
2020-03-19 15:48:00 +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
Liav A 9991a36d1a CPU: Prevent leakage of virtual addresses to kernel log 2020-03-06 15:57:19 +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
Liav A 773afefe7c Kernel: Change HandlerPurpose to HandlerType
Also, GenericInterruptHandler class requires to implement two new
methods.
2020-03-06 11:19:51 +01:00
Andreas Kling 2709116334 Kernel: Fix strange looking output on unhandled page fault 2020-03-06 10:41:08 +01:00
Liav A f33fb151b4 CPU: Allow to use IRQs in range of 50 to 178 2020-03-06 10:32:32 +01:00
Liav A 251b7f3776 CPU: Change debug messages to fit the latest changes 2020-03-02 22:23:39 +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 c3c8eae25a Kernel: Remove some unnecessary .characters() when doing dbg()<<String 2020-03-01 13:23:26 +01:00
Liav A 86395810a9 CPU: Simplify handle_interrupt() function 2020-02-29 00:12:46 +01:00
Liav A b41e2d25b4 CPU: Use dbg() instead of dbgprintf() 2020-02-27 13:05:12 +01:00
Liav A fe664965c2 Kernel: Change get_sharing_devices_count() in GenericInterruptHandler
The new method' name is sharing_devices_count().
The Serenity Coding Style tends to not accept the word "get" in
methods' names if possible.
2020-02-24 11:27:03 +01:00
Liav A e3b24d0478 Kernel: Delete unused files 2020-02-24 11:27:03 +01:00
Liav A bb73802b15 CPU: Use the new interrupt components
Now we use the GenericInterruptHandler class instead of IRQHandler in
the CPU functions.
This commit adds an include to the ISR stub macros header file.
Also, this commit adds support for IRQ sharing, so when an IRQHandler
will try to register to already-assigned IRQ number, a SharedIRQHandler
will be created to register both IRQHandlers.
2020-02-24 11:27:03 +01:00
Liav A 71371d39b3 CPU: Add 2 files with ISR stub macros 2020-02-24 11:27:03 +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
Andreas Kling 48f7c28a5c Kernel: Replace "current" with Thread::current and Process::current
Suggested by Sergey. The currently running Thread and Process are now
Thread::current and Process::current respectively. :^)
2020-02-17 15:04:27 +01:00
Andreas Kling a356e48150 Kernel: Move all code into the Kernel namespace 2020-02-16 01:27:42 +01:00
Andreas Kling 0341ddc5eb Kernel: Rename RegisterDump => RegisterState 2020-02-16 00:15:37 +01:00
Andreas Kling 27f0102bbe Kernel: Add getter and setter for the X86 CR3 register
This gets rid of a bunch of inline assembly.
2020-02-10 20:00:32 +01:00
Andreas Kling ccfee3e573 Kernel: Remove more <LibBareMetal/Output/kstdio.h> includes 2020-02-10 12:07:48 +01:00
Liav A 99ea80695e Kernel: Use VirtualAddress & PhysicalAddress classes from LibBareMetal 2020-02-09 19:38:17 +01:00
Liav A e559af2008 Kernel: Apply changes to use LibBareMetal definitions 2020-02-09 19:38:17 +01:00
Andreas Kling a9d7902bb7 x86: Simplify region unmapping a bit
Add PageTableEntry::clear() to zero out a whole PTE, and use that for
unmapping instead of clearing individual fields.
2020-02-08 12:49:38 +01:00
Andreas Kling 37d336d741 Kernel: Add memory scrubbing in slab_alloc() and slab_dealloc()
These now scrub allocated and freed memory like kmalloc()/kfree() was
already doing.
2020-02-01 10:56:17 +01:00
Andreas Kling 8d51352b96 Kernel: Add crash logging heuristic for uninitialized kmalloc()/kfree()
Since we scrub both kmalloc() and kfree() with predictable values, we
can log a helpful message when hitting a crash that looks like it might
be a dereference of such scrubbed data.
2020-02-01 10:56:17 +01:00
Andreas Kling e64c335e5a Revert "Kernel: Replace IRQHandler with the new InterruptHandler class"
This reverts commit 6c72736b26.

I am unable to boot on my home machine with this change in the tree.
2020-01-22 22:27:06 +01:00
Liav A 6c72736b26 Kernel: Replace IRQHandler with the new InterruptHandler class
System components that need an IRQ handling are now inheriting the
InterruptHandler class.

In addition to that, the initialization process of PATAChannel was
changed to fit the changes.
PATAChannel, E1000NetworkAdapter and RTL8139NetworkAdapter are now
inheriting from PCI::Device instead of InterruptHandler directly.
2020-01-22 12:22:09 +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 4b7a89911c Kernel: Remove some unnecessary casts to uintptr_t
VirtualAddress is constructible from uintptr_t and const void*.
PhysicalAddress is constructible from uintptr_t but not const void*.
2020-01-20 13:13:03 +01:00
Andreas Kling a246e9cd7e Use uintptr_t instead of u32 when storing pointers as integers
uintptr_t is 32-bit or 64-bit depending on the target platform.
This will help us write pointer size agnostic code so that when the day
comes that we want to do a 64-bit port, we'll be in better shape.
2020-01-20 13:13:03 +01:00
Andreas Kling 38fc31ff11 Kernel: Always switch to own page tables when crashing/asserting
I noticed this while debugging a crash in backtrace generation.
If a process would crash while temporarily inspecting another process's
address space, the crashing thread would still use the other process's
page tables while handling the crash, causing all kinds of confusion
when trying to walk the stack of the crashing thread.
2020-01-19 10:33:17 +01:00
Andreas Kling c3e4387c57 Kernel: Stop flushing GDT/IDT registers all the time 2020-01-18 11:10:44 +01:00
Andreas Kling 6fea316611 Kernel: Move all CPU feature initialization into cpu_setup()
..and do it very very early in boot.
2020-01-18 10:11:29 +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 3e8b60c618 Kernel: Clean up MemoryManager initialization a bit more
Move the CPU feature enabling to functions in Arch/i386/CPU.cpp.
2020-01-18 00:28:16 +01:00
Andreas Kling e362b56b4f Kernel: Move kernel above the 3GB virtual address mark
The kernel and its static data structures are no longer identity-mapped
in the bottom 8MB of the address space, but instead move above 3GB.

The first 8MB above 3GB are pseudo-identity-mapped to the bottom 8MB of
the physical address space. But things don't have to stay this way!

Thanks to Jesse who made an earlier attempt at this, it was really easy
to get device drivers working once the page tables were in place! :^)

Fixes #734.
2020-01-17 22:34:26 +01:00
Liav A a9884fbbe5 Kernel: Remove problematic memory mapping methods
mmap() & mmap_region() methods are removed from ACPI & DMI components,
and we replace them with the new MM.allocate_kernel_region() helper.

Instead of doing a raw calculation for each VM address, from now on we
can use helper functions to do perform those calculations in a neat,
reusable and readable way.
2020-01-14 15:38:58 +01:00
Andreas Kling 17ef5bc0ac Kernel: Rename {ss,esp}_if_crossRing to userspace_{ss,esp}
These were always so awkwardly named.
2020-01-09 18:02:01 +01:00
Andreas Kling 372f9e9a11 Kernel: Enable SMAP protection on IRQ and exception entry
It would be nice to do this in the assembly code, but we have to check
if the feature is available before doing a CLAC, so I've put this in
the C++ code for now.
2020-01-08 10:37:53 +01:00
Andreas Kling 0e6ea49410 Kernel: Fix SMAP violation when doing a crash dump 2020-01-06 14:26:47 +01:00
Andreas Kling 9eef39d68a Kernel: Start implementing x86 SMAP support
Supervisor Mode Access Prevention (SMAP) is an x86 CPU feature that
prevents the kernel from accessing userspace memory. With SMAP enabled,
trying to read/write a userspace memory address while in the kernel
will now generate a page fault.

Since it's sometimes necessary to read/write userspace memory, there
are two new instructions that quickly switch the protection on/off:
STAC (disables protection) and CLAC (enables protection.)
These are exposed in kernel code via the stac() and clac() helpers.

There's also a SmapDisabler RAII object that can be used to ensure
that you don't forget to re-enable protection before returning to
userspace code.

THis patch also adds copy_to_user(), copy_from_user() and memset_user()
which are the "correct" way of doing things. These functions allow us
to briefly disable protection for a specific purpose, and then turn it
back on immediately after it's done. Going forward all kernel code
should be moved to using these and all uses of SmapDisabler are to be
considered FIXME's.

Note that we're not realizing the full potential of this feature since
I've used SmapDisabler quite liberally in this initial bring-up patch.
2020-01-05 18:14:51 +01:00
Andreas Kling 9026598999 Kernel: Add a more expressive API for getting random bytes
We now have these API's in <Kernel/Random.h>:

    - get_fast_random_bytes(u8* buffer, size_t buffer_size)
    - get_good_random_bytes(u8* buffer, size_t buffer_size)
    - get_fast_random<T>()
    - get_good_random<T>()

Internally they both use x86 RDRAND if available, otherwise they fall
back to the same LCG we had in RandomDevice all along.

The main purpose of this patch is to give kernel code a way to better
express its needs for random data.

Randomness is something that will require a lot more work, but this is
hopefully a step in the right direction.
2020-01-03 12:43:07 +01:00
Andreas Kling 1d94b5eb04 Kernel: Add a random offset to kernel stacks upon syscall entry
When entering the kernel from a syscall, we now insert a small bit of
stack padding after the RegisterDump. This makes kernel stacks less
deterministic across syscalls and may make some bugs harder to exploit.

Inspired by Elena Reshetova's talk on kernel stack exploitation.
2020-01-01 23:21:24 +01:00
Andreas Kling 38f93ef13b Kernel: Disable x86 RDTSC instruction in userspace
It's still possible to read the TSC via the read_tsc() syscall, but we
will now clear some of the bottom bits for unprivileged users.
2020-01-01 18:22:20 +01:00
Andreas Kling 37329c2009 Kernel: Fix typo in Descriptor::set_limit()
x86 descriptor limits are 20 bytes, not 24 bytes. This was already
a 4-bit wide bitfield, so no damage done, but let's be correct.
2020-01-01 17:21:43 +01:00
Andreas Kling fd740829d1 Kernel: Switch to eagerly restoring x86 FPU state on context switch
Lazy FPU restore is well known to be vulnerable to timing attacks,
and eager restore is a lot simpler anyway, so let's just do it eagerly.
2020-01-01 16:54:21 +01:00
Andreas Kling 9c0836ce97 Kernel: Enable x86 UMIP (User Mode Instruction Prevention) if supported
This prevents code running outside of kernel mode from using the
following instructions:

* SGDT - Store Global Descriptor Table
* SIDT - Store Interrupt Descriptor Table
* SLDT - Store Local Descriptor Table
* SMSW - Store Machine Status Word
* STR - Store Task Register

There's no need for userspace to be able to use these instructions so
let's just disable them to prevent information leakage.
2020-01-01 13:21:15 +01:00
Andreas Kling 5aeaab601e Kernel: Move CPU feature detection to Arch/x86/CPU.{cpp.h}
We now refuse to boot on machines that don't support PAE since all
of our paging code depends on it.

Also let's only enable SSE and PGE support if the CPU advertises it.
2020-01-01 12:57:00 +01:00
Andreas Kling c22a4301ed Kernel: Interpret "reserved bit violation" page faults correctly
We don't actually react to these in any meaningful way other than
crashing, but let's at least print the correct information. :^)
2019-12-25 13:35:57 +01:00
Andreas Kling 52deb09382 Kernel: Enable PAE (Physical Address Extension)
Introduce one more (CPU) indirection layer in the paging code: the page
directory pointer table (PDPT). Each PageDirectory now has 4 separate
PageDirectoryEntry arrays, governing 1 GB of VM each.

A really neat side-effect of this is that we can now share the physical
page containing the >=3GB kernel-only address space metadata between
all processes, instead of lazily cloning it on page faults.

This will give us access to the NX (No eXecute) bit, allowing us to
prevent execution of memory that's not supposed to be executed.
2019-12-25 13:35:57 +01:00
Andreas Kling 336ac9e8e7 Kernel: Clean up CPU fault register dumps
These were looking a bit messy after we started using 32-bit fields
to store segment registers in RegisterDumps.
2019-12-25 02:58:03 +01:00
Andreas Kling f4b2b72c8e Kernel: Remove AK_MAKE_NONCOPYABLE from PDE and PTE classes
This avoids -Wclass-memaccess warnings exposed by the new Makefiles.
2019-12-20 20:20:23 +01:00
Andreas Kling f01fd54d1b Kernel: Make separate kernel entry points for each PIC IRQ
Instead of having a common entry point and looking at the PIC ISR to
figure out which IRQ we're servicing, just make a separate entryway
for each IRQ that pushes the IRQ number and jumps to a common routine.

This fixes a weird issue where incoming network packets would sometimes
cause the mouse to stop working. I didn't track it down further than
realizing we were sometimes EOI'ing the wrong IRQ.
2019-12-15 12:47:53 +01:00
Andreas Kling e49d6cc7e9 Kernel: Tidy up kernel entry points a little bit
Now that we can see the kernel entry points all the time in profiles,
let's tweak the names a little bit and switch to named exceptions.
2019-12-14 16:16:57 +01:00
Andreas Kling f692577559 Kernel: Disable interrupts while modifying the PIC IMR 2019-12-14 16:16:37 +01:00
Andreas Kling 7d0583a33f Kernel: Ignore IRQ 15 for now
Sometimes QEMU hits us with an IRQ 15 and I don't know what it is.
Just ignore it for now instead of crashing the system.
2019-12-14 12:21:39 +01:00
Andreas Kling a0e38922bd Kernel: Break out of the idle loop on WaitQueue wake instead of on IRQ
Now that we have proper wait queues to drive waiter wakeup, we can use
the wake actions to break out of the scheduler's idle loop when we've
got a thread to run.
2019-12-08 00:33:35 +01:00
Andreas Kling 9ed272ce98 Kernel: Disable interrupts while setting up a thread blocker
There was a race window between instantiating a WaitQueueBlocker and
setting the thread state to Blocked. If a thread was preempted between
those steps, someone else might try to wake the wait queue and find an
unblocked thread in a wait queue, which is not sane.
2019-12-01 12:47:33 +01:00
Andreas Kling 9a157b5e81 Revert "Kernel: Move Kernel mapping to 0xc0000000"
This reverts commit bd33c66273.

This broke the network card drivers, since they depended on kmalloc
addresses being identity-mapped.
2019-11-23 17:27:09 +01:00
Jesse Buhagiar bd33c66273 Kernel: Move Kernel mapping to 0xc0000000
The kernel is now no longer identity mapped to the bottom 8MiB of
memory, and is now mapped at the higher address of `0xc0000000`.

The lower ~1MiB of memory (from GRUB's mmap), however is still
identity mapped to provide an easy way for the kernel to get
physical pages for things such as DMA etc. These could later be
mapped to the higher address too, as I'm not too sure how to
go about doing this elegantly without a lot of address subtractions.
2019-11-22 16:23:23 +01:00
Andreas Kling 794758df3a Kernel: Implement some basic stack pointer validation
VM regions can now be marked as stack regions, which is then validated
on syscall, and on page fault.

If a thread is caught with its stack pointer pointing into anything
that's *not* a Region with its stack bit set, we'll crash the whole
process with SIGSTKFLT.

Userspace must now allocate custom stacks by using mmap() with the new
MAP_STACK flag. This mechanism was first introduced in OpenBSD, and now
we have it too, yay! :^)
2019-11-17 12:15:43 +01:00
Andreas Kling b285a1944e Kernel: Clear the x86 DF flag when entering the kernel
The SysV ABI says that the DF flag should be clear on function entry.
That means we have to clear it when jumping into the kernel from some
random userspace context.
2019-11-09 22:42:19 +01:00
supercomputer7 c3c905aa6c Kernel: Removing hardcoded offsets from Memory Manager
Now the kernel page directory and the page tables are located at a
safe address, to prevent from paging data colliding with garbage.
2019-11-08 17:38:23 +01:00
Andreas Kling 9a4b117f48 Kernel: Simplify kernel entry points slightly
It was silly to push the address of the stack pointer when we can also
just change the callee argument to be a value type.
2019-11-06 13:15:55 +01:00
Andreas Kling 1c6f8d3cbd Kernel: Don't build with -mregparm=3
It was really confusing to have different calling conventions in kernel
and userspace. Also this has prevented us from linking with libgcc.
2019-11-06 13:04:47 +01:00
Andreas Kling 5b7f8634e3 Kernel: Set the G (global) bit for kernel page tables
Since the kernel page tables are shared between all processes, there's
no need to (implicitly) flush the TLB for them on every context switch.

Setting the G bit on kernel page tables allows the CPU to keep the
translation caches around.
2019-11-03 23:51:55 +01:00
Andreas Kling dc35b1d647 Kernel: Remove nonsense in bootstrap code
This code was not doing anything important. Since we're building the
kernel with -mregparm=3, the first function argument goes in %eax.
2019-11-03 14:40:28 +01:00
Tidux d09a28856f Kernel: Move Boot/ into Arch/i386/Boot (#667) 2019-10-20 08:15:39 +02:00
Tom 00a7c48d6e APIC: Enable APIC and start APs 2019-10-16 19:14:02 +02:00
Andreas Kling 98c7fd7aed Kernel: Clarify code that saves FPU state after FNINIT
After we clear the FPU state in a thread when it uses the FPU for the
first time, we also save the clean slate in the thread's FPU state
buffer. When we're doing that, let's write through current->fpu_state()
just to make it clear what's going on.

It was actually safe, since we'd just overwritten the g_last_fpu_thread
pointer anyway, but this patch improves the communication of intent.

Spotted by Bryan Steele, thanks!
2019-10-13 20:39:59 +02:00
Andreas Kling 44fb71261a Kernel: Fix accidental restore of bogus FPU state after fork
Cloned threads (basically, forked processes) inherit the complete FPU
state of their origin thread. There was a bug in the lazy FPU state
save/restore mechanism where a cloned thread would believe it had a
buffer full of valid FPU state (because the inherited flag said so)
but the origin thread had never actually copied any FPU state into it.

This patch fixes that by forcing out an FPU state save after doing
the initial FPU initialization (FNINIT) in a thread. :^)
2019-10-13 14:39:04 +02:00
Drew Stratford c136fd3fe2 Kernel: Send SIGSEGV on seg-fault
Now programs can catch the SIGSEGV signal when they segfault.

This commit also introduced the send_urgent_signal_to_self method,
which is needed to send signals to a thread when handling exceptions
caused by the same thread.
2019-10-07 16:39:47 +02:00
Drew Stratford 7fc903b97a Kernel: Add exception_code to RegisterDump.
Added the exception_code field to RegisterDump, removing the need
for RegisterDumpWithExceptionCode. To accomplish this, I had to
push a dummy exception code during some interrupt entries to properly
pad out the RegisterDump. Note that we also needed to change some code
in sys$sigreturn to deal with the new RegisterDump layout.
2019-10-07 16:39:47 +02:00
Andreas Kling e1481dcb42 Kernel: Stop idling after handling an IRQ
If we receive an IRQ while the idle task is running, prevent it from
re-halting the CPU after the IRQ handler returns.

Instead have the idle task yield to the scheduler, so we can see if
the IRQ has unblocked something.
2019-09-14 20:21:10 +02:00
Drew Stratford e529042895 Kernel: Remove reduntant kernel/user signal stacks.
Due to the changes in signal handling m_kernel_stack_for_signal_handler_region
and m_signal_stack_user_region are no longer necessary, and so, have been
removed. I've also removed the similarly reduntant m_tss_to_resume_kernel.
2019-09-09 08:35:43 +02:00
Andreas Kling e29fd3cd20 Kernel: Display virtual addresses as V%p instead of L%x
The L was a leftover from when these were called linear addresses.
2019-08-26 11:31:58 +02:00
Andreas Kling 272bd1d3ef Kernel: Make crash dumps look aligned once again
This broke with the recent changes to make printf hex fields behave
a bit more correctly.
2019-08-17 21:29:46 +02:00
Andreas Kling 945f8eb22a Kernel: Don't treat read faults like CoW exceptions
I'm not sure why we would have a non-readable CoW region, but I suppose
we could, so let's not Copy-on-Read in those cases.
2019-08-06 09:39:39 +02:00