I just copy-pasted microseconds_since_boot and
set_interrupt_interval_usec from aarch64.
However, on RISC-V, they are not in microseconds.
The TimerRegisters struct is also unused.
current_time and set_compare can also be private and static.
IRQHandler is not the correct class to inherit from, as the timer
is not connected to an IRQController.
Each hart has one of these Timers directly connected to it.
I originally added this header because I misunderstood how
IRQControllers are supposed to be used.
I thought that I would need a IRQController class for the hart-local
interrupt controller, but apparently, this class is supposed to be used
for non-local interrupt controllers like the IOAPIC or RISC-V PLIC.
x86 LAPICs don't use this class either.
I am not sure why 096cecb95e disabled the stack protector and sanitizers
for all files, but this is not necessary.
Only the pre_init code needs to run without them, as that code runs
identity mapped.
SysFS, ProcFS and DevPtsFS were all sending filetype 0 when traversing
their directories, but it is actually very easy to send proper filetypes
in these filesystems.
This patch binds all RAM backed filesystems to use only one enum for
their internal filetype, to simplify the implementation and allow
sharing of code.
Please note that the Plan9FS case is currently not solved as I am not
familiar with this filesystem and its constructs.
The ProcFS mostly keeps track of the filetype, and a fix was needed for
the /proc root directory - all processes exhibit a directory inside it
which makes it very easy to hardcode the directory filetype for them.
There's also the `self` symlink inode which is now exposed as DT_LNK.
As for SysFS, we could leverage the fact everything inherits from the
SysFSComponent class, so we could have a virtual const method to return
the proper filetype.
Most of the files in SysFS are "regular" files though, so the base class
has a non-pure virtual method.
Lastly, the DevPtsFS simply hardcodes '.' and '..' as directory file
type, and everything else is hardcoded to send the character device file
type, as this filesystem is only exposing character pts device files.
This is for some reason needed for riscv64 clang, as otherwise the
kernel.map file would grow too big to fit in its section inside the
kernel image.
None of our other architectures have temporary locals in their
kernel.map.
We initialize the MMU by first setting up the page tables for the
kernel image and the initial kernel stack.
Then we jump to a identity mapped page which makes the newly created
kernel root page table active by setting `satp` and then jumps to
`init`.
This trap handler uses the SBI to print an error message via a newly
introduced panic function, which is necessary as `pre_init` is running
identity mapped.
Also add a header file for `pre_init.cpp` as we wan't to use the panic
and `dbgln` function in the MMU init code as well.
We first try to use the newer "SRST" extension for rebooting and
shutting down and if that fails, we try to shutdown using the legacy
"System Shutdown" extension (which can't reboot, so we always shutdown).
The kernel will halt, if we return from here due to all attempts at
rebooting / shutting down failing.
This device will be used by userspace to read mouse packets from all
mouse devices that are attached to the machine.
This change is a preparation before we can enable seamless hotplug
capabilities in WindowServer for mouse devices, without any major change
on the userspace side.
We do this by implementing the following fixes:
- The Key_Plus is assigned to a proper map entry index now which is 0x4e
both on the keypad and non-keypad keys.
- Shift+Q now prints out "Q" properly on scan code set 2.
- Key BackSlash (or Pipe on shift key being pressed down) is now working
properly as well.
- Key_Pipe (which is "|" for en-US layout) is now working in scan code
set 2.
- Numpad keys as well as the decimal separator key are working again.
According to RFC 9293 Section 3.6.1. Half-Closed Connections, we should
still accept incoming packets in the FinWait2 state. Additionally, we
didn't handle the FIN+ACK case. We should handle this the same we
handle the FIN flag. The ACK is only added to signify successful
reception of the last packet.
The specification uses awkward numbering, marking the first byte as 7,
and the last one as 0, which caused me to misunderstand their ordering,
and use the last byte's address as the first one, and so on.
This scan code set is more advanced than the basic scan code set 1, and
is required to be supported for some bare metal hardware that might not
properly enable the PS2 first port translation in the i8042 controller.
LibWeb can now also generate bindings for keyboard events like the Pause
key, as well as other function keys (such as Right Alt, etc).
The logic for handling scan code sets is implemented by the PS2 keyboard
driver and is abstracted from the main HID KeyboardDevice code which
only handles "standard" KeyEvent(s).
RISC-V uses a different convention for storing stack frame information
described here: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#frame-pointer-convention
This part of the psABI is not yet in a ratified version, but both GCC
and Clang seem to use this convention.
Note that the backtrace dumping code still won't work for the initial
stack, as it is located before `kernel_mapping_base`.
To allow for easy mapping between the kernel virtual addresses and
KASAN shadow memory, we map shadow memory at the very end of the
virtual range, so that we can index into it using just an offset.
To ensure this range is free when needed, we restrict the possible
KASLR range when KASAN is enabled to make sure we don't use the end of
the virtual range.
This fixes the random kernel panics that could occur when KASAN is
enabled, if the kernel was randomly placed at the very end of the
virtual range.
This commit adds minimal support for compiler-instrumentation based
memory access sanitization.
Currently we only support detection of kmalloc redzone accesses, and
kmalloc use-after-free accesses.
Support for inline checks (for improved performance), and for stack
use-after-return and use-after-return detection is left for future PRs.
This scan code set is more advanced than the basic scan code set 1, and
is required to be supported for some bare metal hardware that might not
properly enable the PS2 first port translation in the i8042 controller.
LibWeb can now also generate bindings for keyboard events like the Pause
key, as well as other function keys (such as Right Alt, etc).
The logic for handling scan code sets is implemented by the PS2 keyboard
driver and is abstracted from the main HID KeyboardDevice code which
only handles "standard" KeyEvent(s).
This will be used later on by WindowServer so it will not use the
scancode, which will represent the actual character index in the
keyboard mapping when using scan code set 2.
This adds a simple EHCI driver that currently only interrogates the
device and checks if all ports are addressable via associated legacy
controllers (companion controllers), and warns if this is not the case.
This also adds a lot of the other data structures needed for actually
driving the controller, but these are currently not hooked up to
anything.
To test this run with `SERENITY_EXTRA_QEMU_ARGS="--device usb-ehci"`
or the q35 machine type
This should allow us to eventually properly saturate high-bandwidth
network links when using TCP, once other nonoptimal parts of our
network stack are improved.
Instead of lying and claiming we always have space left in our receive
buffer, actually report the available space.
While this doesn't really affect network-bound workloads, it makes a
world of difference in cpu/disk-bound ones, like git clones. Resulting
in a considerable speed-up, and in some cases making them work at all.
(instead of the sender side hanging up the connection due to timeouts)
Previously we would incorrectly handle the (somewhat uncommon) case of
binding and then separately connecting a tcp socket to a server, as we
would register the socket during the manual bind(2) in the sockets by
tuple table, but our effective tuple would then change as the result of
the connect updating our target peer address. This would result in the
the entry not being removed from the table on destruction, which could
lead to a UAF.
We now make sure to update the table entry if needed during connects.
POSIX (rightfully so) specifies that the sendto address argument is
ignored in connection-oriented protocols.
The TCPSocket also assumed the peer address may not change post-connect
and would trigger a UAF in sockets_by_tuple() when it did.
POSIX requires that broadcast sends will only be allowed if the
SO_BROADCAST socket option was set on the socket.
Also, broadcast sends to protocols that do not support broadcast (like
TCP), should always fail.
Since the POSIX sigaltstack manpage suggests allocating the stack
region using malloc(), and many heap implementations (including ours)
store heap chunk metadata in memory just before the vended pointer,
we would end up zeroing the metadata, leading to various crashes.
In a bunch of cases, this actually ends up simplifying the code as
to_number will handle something such as:
```
Optional<I> opt;
if constexpr (IsSigned<I>)
opt = view.to_int<I>();
else
opt = view.to_uint<I>();
```
For us.
The main goal here however is to have a single generic number conversion
API between all of the String classes.
Our existing AnonymousVMObject cloning flow contains an optimization
wherein purgeable VMObjects which are marked volatile during the clone
are created as a new zero-filled VMObject (as if it was purged), which
lets us skip the expensive COW process.
Unfortunately, one crucial part was missing: Marking the cloned region
as purged, (which is the value returned from madvise when unmarking the
region as volatile) so the userland logic was left unaware of the
effective zero-ing of their memory region, resulting in odd behaviour
and crashes in places like our malloc's large allocation support.
The signal handling code (and possibly other code as well) expects this
struct to have an alignment of 16 bytes, as it pushes this struct on the
stack.
MasterPTY::read called DoubleBuffer::read which takes a mutex (which
may block) while holding m_slave's spinlock. If it did block, and was
later rescheduled on a different physical CPU, we would deadlock on
re-locking m_slave inside the unblock callback. (Since our recursive
spinlock implementation is processor based and not process based)
MasterPTY's double buffer unblock callback would take m_slave's
spinlock and then call evaluate_block_conditions() which would take
BlockerSet's spinlock, while on the other hand, BlockerSet's
add_blocker would take BlockerSet's spinlock, and then call
should_add_blocker, which would call unblock_if_conditions_are_met,
which would then call should_unblock, which will finally call
MasterPTY::can_read() which will take m_slave's spinlock.
Resolve this by moving the call to evaluate_block_conditions() out of
the scope of m_slave's spinlock, as there's no need to hold the lock
while calling it anyways.
If there's no loadable segments then there can't be any code to execute
either. This resolves a crash these kinds of ELF files would cause from
the directly following VERIFY statement.
Previously we would unintentionally leave them zero-initialized,
resulting in any threads created post fork (but without execve) having
invalid thread local storage pointers stored in their FS register.
This commit adds all necessary includes, so all functions are properly
declared.
PCI.cpp is moved to PCI/Initializer.cpp, as that matches the header
path.
The `[[gnu::packed]]` attribute apparently lowered the required
alignment of the structs, which caused the compiler to generate two
1 byte loads/stores on RISC-V. This caused the kernel to read/write
incorrect values, as the device only seems to accept 2 byte operations.
`MM.protect_kernel_image` would otherwise make the contents of these
sections read-only, as they were for some reason placed before `.data`
and after the start of `.text`.
RAMFS was passing 0, which lead to the userspace seeing all entries as
DT_UNKNOWN when iterating over the directory contents.
To repro prior to this commit, simply check `echo /tmp/*/`.
Following 77441079dd, the code in Kernel/Devices/HID/MouseDevice.cpp
is used by both USB and PS2 rodents. Make sure not to emit misleading
debug messages that could suggest that a USB mouse is a PS/2 one.
Other arches don't use the prekernel, so don't try to unmap it on
non-x86 platforms.
For some reason, this didn't cause aarch64 to crash, but on riscv64 this
would cause a panic.
This doesn't affect system functionality, but somewhat reduces the
reliance on complicated hardcoded paths. It also allows the user to
simply link /init (which is normally a symbolic link) to another program
to run it instead of SystemServer as the default option.
We could technically copy the dynamic loader to other path and run it
from there, so let's not assume paths.
If the user is so determined to do such thing, then a warning is quite
meaningless.
When writing to /sys/kernel/request_panic it will do a kernel panic.
Trying to truncate the node will result in kernel panic with a slightly
different message.
The networking subsystem currently assumes all adapters are Ethernet
adapters, including the LoopbackAdapter, so all packets are pre-pended
with an Ethernet Frame header. Since the MTU must not include any
overhead added by the data-link (Ethernet in this case) or physical
layers, we need to subtract it from the MTU.
This fixes a kernel panic which occurs when sending a packet that is at
least 65523 bytes long through the loopback adapter, which results in
the kernel "receiving" a packet which is larger than the support MTU
out the other end. (As the actual final size was increased by the
addition of the ethernet frame header)
As per POSIX, the behavior of listen() with a backlog value of 0 is
implementation defined: "A backlog argument of 0 may allow the socket
to accept connections, in which case the length of the listen queue may
be set to an implementation-defined minimum value."
Since creating a socket that can't accept any connections seems
relatively useless, and as other platforms (Linux, FreeBSD, etc) chose
to support accepting connections with this backlog value, support it as
well by normalizing it to 1.
This is necessary for being able to use the qemu `-kernel` option.
The QEMU virt machine uses OpenSBI's FW_DYNAMIC feature to pass
the kernel entry address, which is the virtual entry point address
specified in the kernel ELF. If we instead `objcopy` the kernel into a
raw binary, OpenSBI will jump to the physical kernel load address, which
is what we want it to do.
When the FileSystem does a sync, it gathers up all the inodes with
dirty metadata into a vector. The inode mutex is not held while
checking the inode dirty bit, which can lead to a kernel panic
due to concurrent inode modifications.
Fixes: #21796
It seems like the current implementation returns 0 in case we do not
have enough data for a whole packet yet. The 0 value gets propagated
to the return value of the syscall which according to the spec
should return non-zero values for non-errors cases. This causes panic,
as there is a VERIFY guard checking that more than > 0 bytes are
written if no error has occurred.
There's no need to have separate syscall for this kind of functionality,
as we can just have a device node in /dev, called "beep", that allows
writing tone generation packets to emulate the same behavior.
In addition to that, we remove LibC sysbeep function, as this function
was never being used by any C program nor it was standardized in any
way.
Instead, we move the userspace implementation to LibCore.
Previously, attempting to update an ext2 inode with a UID or GID
larger than 65535 would overflow. We now write the high bits of UIDs
and GIDs to the same place that Linux does within the `osd2` struct.
A bit old but a relatively uncomplicated device capable of outputting
1920x1080 video with 32-bit color. Tested with a Voodoo 3 3000 16MB
PCI card. Resolution switching from DisplaySettings also works.
If the requested mode contains timing information, it is used directly.
Otherwise, display timing values are selected from the EDID. First the
detailed timings are checked, and then standard and established
timings for which there is a matching DMT mode. The driver does not
(yet) read the actual EDID, so the generic EDID in DisplayConnector now
includes a set of common display modes to make this work.
The driver should also be compatible with the Voodoo Banshee, 4 and 5
but I don't have these cards to test this with. The PCI IDs of these
cards are included as a commented line in case someone wants to give it
a try.
Moving the DeviceManagement initialization, which is only needed by
userland in the first place, to after interrupt and time management
initialization (like other things that require randomness) allows the
SipHash initialization to access good randomness without problems.
Note: There currently is another, unrelated boot problem on aarch64,
which is not caused by SipHash as far as we know. This commit therefore
only fixes the SipHash regression.
This view is really nice to check flags, but when clearing them we must
make sure that we only ever try to set 1 bit at a time, which makes
setting bits through the structured view a footgun, as that fetches,
ors in and then sets, potentially resetting other flags.
According to multiboot spec if flag for framebuffer isn't
set then corresponding fields are invalid. In reality they're set
to 0 but let's be defensive.
Loaders try to put modules as low as reasonable but on
EFI often "reasonable" is much higher than on BIOS. As
a result target can be easily higher than source.
Then we have 2 problems:
* memmove compares virtual address and since target
is mapped higher it ends up going backwards which
is wrong if target is physically below source
* order of copying of sections must be inverted if
target is below source
Prekernel code currently assumes that mapping until MAX_KERNEL_SIZE
is enough to make the modules accessible. GRUB tries to load as low
as possible but higher than 1 MiB. Hence this is usually true.
However on EFI some ranges may already be used by boot services and
GRUB tries to avoid them if possible. This pushes modules higher.
The simplest solution is to map entire 4 GiB space.
As an additional benefit it makes the framebuffer accessible that
can be used for the debugging.
About half of the Processor code is common across architectures, so
let's share it with a templated base class. Also, other code that can be
shared in some ways, like FPUState and TrapFrame functions, is adjusted
here. Functions which cannot be shared trivially (without internal
refactoring) are left alone for now.
SipHash is highly HashDoS-resistent, initialized with a random seed at
startup (i.e. non-deterministic) and usable for security-critical use
cases with large enough parameters. We just use it because it's
reasonably secure with parameters 1-3 while having excellent properties
and not being significantly slower than before.
This subtraction is necessary to ensure that the section has the correct
address. Also, without this change, the Kernel ELF binary would explode
in size. This was forgotten in a0dd6ec6b1.
This field is in a packed struct, which makes it possibly misaligned.
This knowledge is lost when invoking `dbgln` triggering an unaligned
access to it, aka UB. By explicitely copying it we avoid this issue.