Commit Graph

3390 Commits

Author SHA1 Message Date
Tom
5f51d85184 Kernel: Improve time keeping and dramatically reduce interrupt load
This implements a number of changes related to time:
* If a HPET is present, it is now used only as a system timer, unless
  the Local APIC timer is used (in which case the HPET timer will not
  trigger any interrupts at all).
* If a HPET is present, the current time can now be as accurate as the
  chip can be, independently from the system timer. We now query the
  HPET main counter for the current time in CPU #0's system timer
  interrupt, and use that as a base line. If a high precision time is
  queried, that base line is used in combination with quering the HPET
  timer directly, which should give a much more accurate time stamp at
  the expense of more overhead. For faster time stamps, the more coarse
  value based on the last interrupt will be returned. This also means
  that any missed interrupts should not cause the time to drift.
* The default system interrupt rate is reduced to about 250 per second.
* Fix calculation of Thread CPU usage by using the amount of ticks they
  used rather than the number of times a context switch happened.
* Implement CLOCK_REALTIME_COARSE and CLOCK_MONOTONIC_COARSE and use it
  for most cases where precise timestamps are not needed.
2020-12-21 18:26:12 +01:00
Liav A
469f20d4ee Kernel: Introduce the StorageManagement class
The StorageManagement class has 2 roles:
1. During boot, it should find all storage controllers in the machine,
and then determine what is the boot device.
2. Later on boot, it is a registrar of all storage controllers and
storage devices. Thus, it could be used to show information about these
devices when implemented.

This change allows the user to specify a boot driver other than /dev/hda
and if it's connected in the machine - it will boot.
2020-12-21 00:19:21 +01:00
Liav A
78ae4b0530 Kernel: Change the indexing of storage devices in IDEController class
Previously, the indexing scheme was that 0 is Primary-Master, 1 is
Primary-Slave, 2 is Secondary-Master, 3 is Secondary-Slave.

Instead of merely matching between numbers to the channel & position,
the IDEController code will try to find all available drives connected to
the two channels, then it will create a Vector with nonnull RefPtr to
them. Then we take use the given index with this Vector.
2020-12-21 00:19:21 +01:00
Liav A
6a691306b5 Kernel: Add a method to gather the devices count of a Storage controller
Also, change device() method to be const.
2020-12-21 00:19:21 +01:00
Liav A
e3b3805abf Kernel: Add a method to check the type of a StorageController
Also, the device method in the StorageController class is public now.
2020-12-21 00:19:21 +01:00
Liav A
28599af387 Kernel: Allow to initialize an IDE device on the secondary channel
We now use major number 3, and the minor number is set to 0 or 2 if
initialized on the primary channel, otherwise 1 or 3 on the secondary
channel.
2020-12-21 00:19:21 +01:00
Liav A
0a2b00a1bf Kernel: Introduce the new Storage subsystem
This new subsystem is somewhat replacing the IDE disk code we had with a
new flexible design.

StorageDevice is a generic class that represent a generic storage
device. It is meant that specific storage hardware will override the
interface. StorageController is a generic class that represent
a storage controller that can be found in a machine.

The IDEController class governs two IDEChannels. An IDEChannel is
responsible to manage the master & slave devices of the channel,
therefore an IDEChannel is an IRQHandler.
2020-12-21 00:19:21 +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
Liav A
cf0a12c68f Kernel: Add various methods to handle interrupts in the PCI subsystem
For now, we only are able to enable or disable pin based interrupts.
Later, when implemented, we could utilize MSI & MSI-X interrupts.
2020-12-21 00:19:21 +01:00
Liav A
97b36febd5 Kernel: Add a method to retrieve the Physical ID for a PCI address 2020-12-21 00:19:21 +01:00
Liav A
85b4256d10 PCI: Add list of capabilities for each device during first enumeration 2020-12-21 00:19:21 +01:00
Liav A
9d10eb473d Kernel: Add the DeviceController class in the PCI subsystem
Such device is not an IRQHandler by itself, but actually a controller of
many IRQ or MSI devices. The purpose of this class is to manage multiple
sources of interrupts.

For example, a generic ISA IDE controller controls 2 IRQ sources - 14
and 15. So, when we initialize the IDE controller, it will initialize
two IDE channels (also known as PATAChannels) to utilize IRQ 14 and 15,
respectively. NVMe with MSI-X support can theoretically handle up to
2048 interrupts.
2020-12-21 00:19:21 +01:00
Liav A
afba614d68 Kernel: Don't skip if found free page to allocate from a super region
This was a bad pattern that wasn't detected because we only had one
super physical region that was initialized by MemoryManager.
2020-12-21 00:15:58 +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
Andreas Kling
34e9df3c5e Kernel: Randomize memory location of the dynamic loader :^)
This should make it a little bit harder for those who would mess with
our loader.
2020-12-20 18:49:24 +01:00
Andreas Kling
02ef3f6343 Kernel: Ptrace should not assert on poke in non-mapped tracee memory 2020-12-20 18:49:24 +01:00
Andreas Kling
9bf02c32c0 Kernel: Activate SUID/SGID credentials earlier in sys$execve()
Switch on the new credentials before loading the new executable into
memory. This ensures that attempts to ptrace() the program from an
unprivileged process will fail.

This covers one bug that was exploited in the 2020 HXP CTF:
https://hxp.io/blog/79/hxp-CTF-2020-wisdom2/

Thanks to yyyyyyy for finding the bug! :^)
2020-12-20 18:49:18 +01:00
Andreas Kling
5505159a94 Kernel: Silence debug spam about select() being interrupted 2020-12-20 16:06:52 +01:00
Andreas Kling
e5eda151b4 Kernel: Silence debug spam when running dynamically linked programs 2020-12-20 16:06:39 +01:00
Andreas Kling
d893498e57 Kernel: Use fallible KBuffer API in PerformanceEventBuffer 2020-12-19 10:23:12 +01:00
Andreas Kling
3d02597316 Kernel: Avoid a heap allocation for every outgoing TCP packet 2020-12-18 19:22:26 +01:00
Andreas Kling
befabe31c9 Kernel/Net: Avoid a heap allocation for every outgoing UDP packet
We can use a stack buffer to build the UDP packet instead.
2020-12-18 19:22:26 +01:00
Andreas Kling
8cc81c2953 Kernel/Net: Make IPv4Socket::protocol_receive() take a ReadonlyBytes
The overrides of this function don't need to know how the original
packet was stored, so let's just give them a ReadonlyBytes view of
the raw packet data.
2020-12-18 19:22:26 +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
Andreas Kling
d936d86332 Kernel: Add KBuffer::try_create_with_bytes()
Here's another fallible KBuffer construction API that creates a KBuffer
and populates it with a range of bytes.
2020-12-18 19:22:26 +01:00
Andreas Kling
bcd2844439 TmpFS: Use fallible KBuffer API
If allocation fails, some TmpFS operations can now fail with ENOMEM.
2020-12-18 19:22:26 +01:00
Andreas Kling
47da86d136 Ext2FS: Fail the mount if BGD table cache allocation fails
Instead of asserting if we can't allocate enough memory for a BGD table
cache, just fail the mount instead.
2020-12-18 19:22:26 +01:00
Andreas Kling
8cde8ba511 Kernel: Add KBuffer::try_create_with_size()
We need to stop assuming that KBuffer allocation always succeeds.
This patch adds the following API:

- static OwnPtr<KBuffer> KBuffer::create_with_size(size_t);

All KBuffer clients should move towards using this (and handling any
failures with grace.)
2020-12-18 19:22:26 +01:00
Andreas Kling
4232874270 Kernel: Don't dump core when OOM-killing a process
Trying to generate a core dump under low memory conditions is not the
best idea.

Fixes #4428.
2020-12-18 11:22:21 +01:00
Liav A
5a146187cf Kernel: Workaround QEMU bug and initialize i8042 controller
ACPI 2 declared the third revision of FADT, that should have
IAPC_BOOT_ARCH flags in it, also to indicate if i8042 is present.
Q35 machine reports that it has FADT with revision 3, but the code
in QEMU simply ignores these flags and put zero on them no matter
the revision of FADT.
2020-12-18 10:02:14 +01:00
Liav A
f36feb42bd Kernel: Return a correct name string of async write request 2020-12-17 19:36:56 +01:00
Tom
c4176b0da1 Kernel: Fix Lock race causing infinite spinning between two threads
We need to account for how many shared lock instances the current
thread owns, so that we can properly release such references when
yielding execution.

We also need to release the process lock when donating.
2020-12-16 23:38:17 +01:00
Andreas Kling
4befc2c282 Kernel: Avoid null dereference in sys$profiling_disable()
If we can't create a profiling coredump object, we shouldn't try to
call write() on it.
2020-12-15 11:25:51 +01:00
Andreas Kling
be0816507a Kernel: Remove harmless OOB ELF header access in core dump generation 2020-12-15 11:24:46 +01:00
Andreas Kling
28c042e46f Kernel: Make CoreDump::m_num_program_headers const
This makes it an error to assign to it after construction.
2020-12-15 11:24:46 +01:00
Andreas Kling
ff8bf4db8d Kernel: Don't take LexicalPath as argument
LexicalPath is a big and heavy class that's really meant as a helper
for extracting parts of a path, not for storage or passing around.
Instead, pass paths around as strings and use LexicalPath locally
as needed.
2020-12-15 11:17:01 +01:00
Itamar
1efbbf3ac3 Kernel: Don't generate a backtrace when a process exists with non-zero
..status
2020-12-14 23:05:53 +01:00
Itamar
5392f42731 Kernel: Generate coredumps for profiled processes
These coredumps will be used by the Profile Viewer to symbolicate the
profiling samples.
2020-12-14 23:05:53 +01:00
Itamar
39890af833 Kernel: Pass full path of output coredump file to CoreDump 2020-12-14 23:05:53 +01:00
Itamar
349c6780ce LibELF: Refactor coredump notes section structures 2020-12-14 23:05:53 +01:00
Itamar
345abc3132 Kernel: Move InodeWatcher::Event into Kernel/API/InodeWatcherEvent
This allows userspace code to parse these events.
2020-12-14 23:05:53 +01:00
Itamar
b4842d33bb Kernel: Generate a coredump file when a process crashes
When a process crashes, we generate a coredump file and write it in
/tmp/coredumps/.

The coredump file is an ELF file of type ET_CORE.
It contains a segment for every userspace memory region of the process,
and an additional PT_NOTE segment that contains the registers state for
each thread, and a additional data about memory regions
(e.g their name).
2020-12-14 23:05:53 +01:00
Itamar
efe4da57df Loader: Stabilize loader & Use shared libraries everywhere :^)
The dynamic loader is now stable enough to be used everywhere in the
system - so this commit does just that.
No More .a Files, Long Live .so's!
2020-12-14 23:05:53 +01:00
Itamar
9ca1a0731f Kernel: Support TLS allocation from userspace
This adds an allocate_tls syscall through which a userspace process
can request the allocation of a TLS region with a given size.

This will be used by the dynamic loader to allocate TLS for the main
executable & its libraries.
2020-12-14 23:05:53 +01:00
Itamar
5b87904ab5 Kernel: Add ability to load interpreter instead of main program
When the main executable needs an interpreter, we load the requested
interpreter program, and pass to it an open file decsriptor to the main
executable via the auxiliary vector.

Note that we do not allocate a TLS region for the interpreter.
2020-12-14 23:05:53 +01:00
Andreas Kling
48589db3aa Kernel/Net: Socket connected state change should reevaluate blocks
This fixes an issue where TCP sockets could get into the Established
state too quickly and fail to unblock a subsequent sys$select() call.

This makes websites load *significantly* faster. :^)
2020-12-13 19:15:42 +01:00
Tom
1042762deb Kernel: Fix block recursion
Since the process lock is using the Lock class, re-locking the process
lock may cause another call to Thread::block. This caused some problems
with multiple blockers attempting to be used at the same time. To solve
this problem, remember if the process lock was held, and if it was then
relock after we're done with the blockers, just before returning.
2020-12-12 21:28:12 +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
47ede74326 Kernel: Execute timer handlers outside of irq handler
This allows us to do things in timer handlers that involve e.g. scheduling,
such as using the Lock class or unblocking threads.
2020-12-12 21:28:12 +01:00
Tom
4bbee00650 Kernel: disown should unblock any potential waiters
This is necessary because if a process changes the state to Stopped
or resumes from that state, a wait entry is created in the parent
process. So, if a child process does this before disown is called,
we need to clear those entries to avoid leaking references/zombies
that won't be cleaned up until the former parent exits.

This also should solve an even more unlikely corner case where another
thread is waiting on a pid that is being disowned by another thread.
2020-12-12 21:28:12 +01:00