VariadicFormatParams only stores pointers to the parameters, so
the device.device_name() parameter will dangle.
This fixes broken dmesgln_pci output on riscv64 GCC.
Linux did the same thing 18 years ago and their reasons for the change
are similar to ours - https://github.com/torvalds/linux/commit/7d12e78
Most interrupt handlers (i.e. IRQ handlers) never used the register
state reference anywhere so there's simply no need of passing it around.
I didn't measure the performance boost but surely this change can't make
things worse anyway.
Instead, start by trying to read a buffer with size of Elf_Ehdr, and
check it for the shebang sign. If it's indeed an executable with shebang
then read again from the file, now with PAGE_SIZE size, which should
suffice for finding the interpreter path.
However, if the executable is an ELF, we quickly validate it and then
pass the preliminary buffer to the find_elf_interpreter_for_executable
method.
That method calculates the last byte offset which is needed to read all
of the program headers, so we don't just assume 4096 bytes is sufficient
anymore. The same pattern is applied when loading the interpreter ELF
main header and its program headers.
In Ext2FSInode::compute_block_list_impl(), each call to
process_block_array() creates a new ByteBuffer, which leads to a
kmalloc() call. The ByteBuffer is then discarded when
process_block_array() exits, leading to a kfree() call.
This leads to repeated kmalloc() and kfree() calls as ByteBuffers are
created and destroyed each time process_block_array() is called.
This commit makes it so that only 1 ByteBuffer is created for each level
of inode indirect block (so only 3 ByteBuffers are created at most).
These ByteBuffers are re-used on each call to process_block_array().
This reduces the number of kmalloc() and kfree() calls during
compute_block_list_impl(), especially for larger files.
Using sysretq clobbers rcx and r11 as this instruction loads the rip and
rflags from those registers. This is fine for normal syscalls.
Signal dispatching works like this:
The kernel makes userspace jump to the signal trampoline when a signal
is dispatched. That trampoline then executes the sigreturn syscall after
calling the signal handler to continue executing the code before the
signal was dispatched.
Since e71c320154 the sigreturn syscall is done via the syscall
instruction (and int 0x82 support was removed in the next commit),
which causes the kernel to currently use sysretq to return to userspace.
But signals can happen at any time, not just during syscalls, so the
sigreturn syscall shouldn't clobber the contents of those registers when
returning to userspace.
This allows us to properly limit our block requests to the device's
capabilities, and choose more optimal block counts for I/O operations.
In theory, as Qemu only advertises a block limit above our current
internal block size limit of u16::max and does not advertise any optimal
transfer lengths.
This is apparently what bootloaders do before using a USB storage device
so we should likely do so as well, especially when no BIOS is present,
like on riscv.
Co-Authored-By: Sönke Holz <sholz8530@gmail.com>
Instead calculate the load offset at runtime.
The mapping of the initial stack is now done explicitly. It was
previously included in the 2 MiB-aligned kernel range.
We need to use kernel8.img now, as we no longer hard-code the physical
addresses of all sections in the linker script. QEMU would otherwise
try to load us at KERNEL_MAPPING_BASE.
This is slightly better than assuming that cutting off the high 32 bits
results in the physical address. This worked for now because the kernel
(and stack) is mapped at KERNEL_MAPPING_BASE + PHYSICAL_LOAD_ADDR and
KERNEL_MAPPING_BASE & 0xffff'ffff == 0.
The next commit will move the kernel to KERNEL_MAPPINGS_BASE + 0, so
we need to get the physical address in a slightly less hacky way.
This makes Processor::capture_stack_trace() work on all our
architectures. For this function to work on AArch64 and RISC-V, the
frame pointer has to be saved during context switches.
AArch64 and RISC-V don't support SMP yet, so the code for getting a
backtrace for processes running on other cores is guarded behind a
'#if ARCH(X86_64)'.
This function was only used to verify that we are running in kernel
mode. But it is pretty much impossible that we will ever end up in
kernel code and actually are able to execute it in user mode. A lot of
stuff must go completely wrong to end up in such a situation.
Getting the current privilege level is also impossible on RISC-V by
design.
Writes to SharedInodeVMObjects could cause a Protection Violation if a
page was marked as dirty by a different process.
This happened due to a combination of 2 things:
* handle_dirty_on_write_fault() was skipped if a page was already marked
as dirty
* when a page was marked as dirty, only the Region that caused the page
fault was remapped
This commit:
* fixes the crash by making handle_fault() stop checking if a page was
marked dirty before running handle_dirty_on_write_fault()
* modifies handle_dirty_on_write_fault() so that it always marks the
page as dirty and remaps the page (this avoids a 2nd bug that was
never hit due to the 1st bug)
Resolve a regression caused by 01e1af732b.
This unbreaks coredump generation, because we need to use the VFS root
context of the crashed process and not of the FinalizerTask, as it will
hold an empty VFS root context that is assigned to kernel processes.
Bulk transfers also use Normal TRBs, so move the reusable normal TRB
setup code from submit_async_interrupt_transfer into a new function
prepare_normal_transfer.
submit_bulk_transfer and submit_async_interrupt_transfer use this
function and then either block on the completion or submit it
asynchronously and wrap it into a PeriodicPendingTransfer.
Instead of using a raw `KBuffer` and letting each implementation to
populating the specific flags on its own, we change things so we only
let each FileSystem implementation to validate the flag and its value
but then store it in a HashMap which its key is the flag name and
the value is a special new class called `FileSystemSpecificOption`
which wraps around `AK::Variant<...>`.
This approach has multiple advantages over the previous:
- It allows runtime inspection of what the user has set on a `MountFile`
description for a specific filesystem.
- It ensures accidental overriding of filesystem specific option that
was already set is not possible
- It removes ugly casting of a `KBuffer` contents to a strongly-typed
values. Instead, a strongly-typed `AK::Variant` is used which ensures
we always get a value without doing any casting.
Please note that we have removed support for ASCII string-oriented flags
as there were no actual use cases, and supporting such type would make
`FileSystemSpecificOption` more complicated unnecessarily for now.
The sysret instruction restores the rflags value from the r11 register.
Before, we expected that the value in RegisterState::r11 is still the
rflags value saved by syscall and therefore didn't copy
RegisterState::rflags to r11 before the sysret.
But signal handlers and ptrace can change the value in
RegisterState::r11 while we are handling a syscall, so we shouldn't
assume that it still contains the saved rflags.
While handling a syscall the contents of RegisterState::rflags may also
have been updated by e.g. ptrace in which case we should restore the
updated rflags, not the original state on syscall entry.
This fixes incorrect assumptions about the layout of descriptors and
gets rid of all the pointer arithmetic.
The USB spec doesn't define a strict order for all descriptors to appear
in.
It just says that endpoint descriptors follow its interface descriptor.
We also have to skip all unknown descriptors (which also can appear
anywhere), not just HID descriptors.
The superblock of an ext2 filesystem is always found on the storage
device at offset 1024. This 1024 number was hardcoded in the Ext2FS
code.
This commit:
* adds a constexpr to replace the hardcoded 1024 values
* removes a comment about one of the the hardcoded 1024 values which is
now umnecessary
All USB Devices (including hubs) need to have a configuration set before
you can use them. We already do this in other USB drivers, but forgot to
do it for USB hubs as well.
This adds a minimal (that is, just enough to make USB mouse/keyboard
work) implementation of an xHCI driver, to let us use serenity on
modern baremetal machines.
Both the calculation for the interface descriptor address and the
endpoint descriptors addresses (for second interface and above) were
incorrect, and would read the wrong data (and go out-of-bounds as well)
Previously USB::Pipe would just try to poorly maintain copies of some
of the relevant properties of USB::Device. (address & speed)
Now it just holds a reference to it's owning device and can query them
when needed.