Michalis Pappas [Wed, 2 Aug 2023 06:46:25 +0000 (08:46 +0200)]
lib/ukmmio: Refactor ukmmio
Derive parametrs from libukparam. Rewrite parsing.
Notice: This is an interim step before moving this into the
virtio-mmio driver. Right now this is not possible
as this driver is part of a larger libkvmvirtio library
and thus cannot override the library prefix for libukparam
to "virtio-mmio".
Marco Schlumpp [Mon, 20 Feb 2023 13:57:00 +0000 (14:57 +0100)]
plat/virtio: Implement support for event index notification suppression
This allows the drivers/device to specify the other side should
send a notification. This is required for firecracker which does not
support the original notification suppression flag.
This commit adds dynamic entry support to uk_store. Libraries can
dynamically register uk_store objects at runtime, each one of which
is associated with one or more entries. Similarly to static entries,
each dynamic entry is associated with a getter and / or a setter.
Consumers are notified for the lifetime of objects via events.
Checkpatch-Ignore: SPACING LONG_LINE
GitHub-Closes: #539 Co-authored-by: Michalis Pappas <michalis@unikraft.io> Signed-off-by: Cezar Craciunoiu <cezar.craciunoiu@gmail.com> Signed-off-by: Michalis Pappas <michalis@unikraft.io> Reviewed-by: Simon Kuenzer <simon@unikraft.io> Reviewed-by: Cezar Craciunoiu <cezar.craciunoiu@unikraft.io> Approved-by: Simon Kuenzer <simon@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #939
Michalis Pappas [Tue, 6 Jun 2023 08:34:05 +0000 (10:34 +0200)]
lib/ukalloc: Add entry IDs and update static entry definitions
Introduce header for definitions related to uk_store. Add
entry IDs for stats tracked by uk_alloc, and update static
entry definitions to pass entry IDs.
Signed-off-by: Michalis Pappas <michalis@unikraft.io> Reviewed-by: Simon Kuenzer <simon@unikraft.io> Reviewed-by: Cezar Craciunoiu <cezar.craciunoiu@unikraft.io> Approved-by: Simon Kuenzer <simon@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #939
Xingjian Zhang [Thu, 17 Aug 2023 13:42:54 +0000 (21:42 +0800)]
plat/drivers/virtio: Fix virtio_9p tag read
Swap the last two arguments of virtio_9p_feature_negotiate's first
call to virtio_config_get. As per the function definition, the last
argument needs to actually be the length of the type.
Signed-off-by: Xingjian Zhang <zhxj9823@qq.com> Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com> Reviewed-by: Sergiu Moga <sergiu@unikraft.io> Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com> Approved-by: Razvan Deaconescu <razvand@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1059
Sergiu Moga [Wed, 16 Aug 2023 15:20:39 +0000 (18:20 +0300)]
plat/kvm/x86: Ensure that lxboot initrd/cmdl regions are aligned
All memory region descriptors must be aligned. Therefore, ensure
that the initrd and command-line related memory regions inserted
when booting through the Linux Boot Protocol are also aligned.
Note: If these two are aligned, all the other memory regions reported
through the boot protocol should be already aligned. Thus, we do not
do this explicit alignment on the free memory regions, as they must
have been already aligned by the previous boot phase. If this is not
the case, then the issue lies in the entity that booted us.
Signed-off-by: Sergiu Moga <sergiu@unikraft.io> Reviewed-by: Marco Schlumpp <marco@unikraft.io> Approved-by: Razvan Deaconescu <razvand@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1057
Stefan Jumarea [Thu, 29 Jun 2023 08:59:30 +0000 (11:59 +0300)]
lib/vfscore: Add non-largefile variant for dirent
Unikraft defines the `dirent` structure as identical to `dirent64`.
This works fine if not using Unikraft in binary compatibility mode,
since we have total control over the internal functions/structures that
are used.
However, if we use Unikraft in binary compatibility mode, we want to use
Linux `dirent` and `dirent64` structures in order to maintain compatibility
with older libc versions that do not use the `*64` calls by default.
Since the filesystems `READDIR` vop uses `dirent64`, we will convert to a
`dirent` structure within the `readdir_r` call.
Signed-off-by: Stefan Jumarea <stefanjumarea02@gmail.com>
GitHub-Closes: #919 Reviewed-by: Radu Nichita <radunichita99@gmail.com> Reviewed-by: Sergiu Moga <sergiu@unikraft.io> Reviewed-by: Simon Kuenzer <simon@unikraft.io> Approved-by: Simon Kuenzer <simon@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #963
Sergiu Moga [Wed, 16 Aug 2023 08:56:15 +0000 (11:56 +0300)]
plat/kvm/arm: Use length when clean/invalidating cache in `KVM` entry
Fix second argument of [clean_and_]invalidate_dcache_range in `KVM`
entry to use the length of the range instead of the address of the
end of the range.
Xingjian Zhang [Mon, 14 Aug 2023 15:29:18 +0000 (23:29 +0800)]
plat/drivers: Add two configurations to ns16550
The register shift of ns16550 is hard-coded in the driver, but it does
not match the hardware on some platforms. The device-tree specification
has a property "reg-shift" to describe the register shift of a device.
To match the specification, the register shift of ns16550 is retrieved
from the device tree instead. If no such property is found, the default
value 0 is used.
The register width of ns16550 varies on different platforms. u-boot uses
a reg-io-width property in the device tree to determine it. If no such
property is found, the default value 1 is used. The read and write
macros are replaced by functions with the same name.
This patch also adds the corresponding configurations to override the
values when dts does not specify them.
These two configurations break the compatibility of the driver. To keep
the compatibility, the device tree should contain these properties or
set them in configurations.
plat/common/arm: Do not use a barrier on every invalidation
The current implementation of clean and invalidate by region uses
a barrier after every cache line. This is unnecessary and expensive.
Use a barrier once, at the end of the operation.
plat/kvm/arm: Do not clean & invalidate the cache after enabling the MMU
To maximize boot performance we only invalidate the cache for regions
accessed before enabling the MMU. This makes the clean & invalidate
step of the entire image region after enabling the MMU redundant.
plat/kvm: Do not unconditionally clean and invalidate the cache
The arm64 linux boot protocol provides the requirements for
the system's state before jumping into the kernel [1]. Among
these it is required that upon entry:
- The MMU is off
- The D-cache for the region corresponging to the loaded image
must be cleaned to the point of coherence.
Skip expensive cache clean & invalidate operations if the MMU is
found to be disabled at boot. Although this heuristic is not
strictly required it provides with some additional confidence
that the bootloader behaves as expected.
With a clean cache, additionally optmize cache invalidations by
limiting them to the regions accessed before the MMU is enabled.
Sergiu Moga [Tue, 15 Aug 2023 07:32:34 +0000 (10:32 +0300)]
lib/posix-environ: Ensure that compiled-in strings are writable
Previously, the elements of `__init_env` would be compile-in strings
that would correspond to `CONFIG_LIBPOSIX_ENVIRON_ENVPx` configurable
strings. This lead to these strings being placed by in the `.rodata`
section and making them unmodifiable.
Unfortunately, Redis represents an application whose code may want to
modify such data (see
commit 6356cf6808be ("Set process name in ps output to make operations safer.")).
Therefore, to appease such actions, make sure that this data is placed
in a modifiable section such as `.data` by using statically declared
global variables containing these very strings as an indirection.
To make it look somewhat nicer, do so with the help of two basic helper
macros: DECLARE_LIBPOSIX_ENVIRON_ENV_VAR to transparently declare such
variables and LIBPOSIX_ENVIRON_ENV_VAR to transparently access them.
Signed-off-by: Sergiu Moga <sergiu@unikraft.io> Reviewed-by: Michalis Pappas <michalis@unikraft.io> Approved-by: Simon Kuenzer <simon@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1054
Sergiu Moga [Mon, 14 Aug 2023 15:33:25 +0000 (18:33 +0300)]
plat/common: Align TLS sections to PAGE_SIZE
`mkbootinfo.py` takes each ELF segment and aligns it to PAGE_SIZE to
convert it to a `struct ukplat_memregion_desc`. However, this ends up
generating overlapping memregion descriptors in the case of the ELF
segment corresponding to the TLS sections.
To solve this, simply ensure that the TLS sections are already aligned
by PAGE_SIZE.
Sergiu Moga [Mon, 14 Aug 2023 15:50:04 +0000 (18:50 +0300)]
plat/kvm: Check return code of all memory region inserting methods
Make sure that we do check the return codes of all of the memory region
inserting methods so that we can crash in case of failure, instead
of letting the system run with a corrupted state.
Sergiu Moga [Mon, 14 Aug 2023 15:42:31 +0000 (18:42 +0300)]
plat/common: Increase granularity of hardcoded legacy high memory
To ensure compatibility with boot protocols that do report the
BIOS System Memory region as a reserved region, split the memory
region inserted by `ukplat_memregion_list_insert_legacy_hi_mem`
into two memory region descriptors: one to contain known memory
holes (e.g. VGA Text Mode framebuffer) and one to contain the
previously mentioned BIOS System Memory region. The former will
have read/write permissions to ensure that zones like the VGA
framebuffer or certain PCI BARs mapped by the BIOS are writable,
while the latter will only have read permissions to ensure
compatibility with other boot protocols.
Michalis Pappas [Mon, 14 Aug 2023 14:07:15 +0000 (16:07 +0200)]
plat/kvm/arm: Fix default choice in arm64 VMM menu
Fix the default selection of the VMM in Config.uk. Kconfig requires
that the default is defined as an attribute of the `choice` option
rather than the contained item.
Signed-off-by: Michalis Pappas <michalis@unikraft.io> Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com> Reviewed-by: Maria Sfiraiala <maria.sfiraiala@gmail.com> Approved-by: Razvan Deaconescu <razvand@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1053
Michalis Pappas [Mon, 14 Aug 2023 08:21:36 +0000 (10:21 +0200)]
plat/kvm/arm: Fix bootstack base alignment on arm64
280c69559 introduces a regression to the alignment of the
bootstack. Update __libkvmplat_entry to enforce the correct
alignment before assigning to the sp.
Sergiu Moga [Mon, 14 Aug 2023 08:08:17 +0000 (11:08 +0300)]
plat/common: Add BIOS system memory in legacy high memory region
Previously, `ukplat_memregion_list_insert_legacy_hi_mem` did not
include the `0xf0000 -> 0x100000` memory regions that would usually
contain the legacy BIOS system memory below the first 1MiB. This
would lead to x86 platforms that do not yet have any form of
ACPI (RSDP from BDA or UEFI System Tables) such as Firecracker
to crash when looking for the `RSDP` in that specific region.
Therefore, make sure that this region is also included so that it
can be mapped accordingly by the paging initialization phase.
Signed-off-by: Sergiu Moga <sergiu@unikraft.io> Reviewed-by: Marco Schlumpp <marco@unikraft.io> Approved-by: Michalis Pappas <michalis@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1046
Sergiu Moga [Sun, 13 Aug 2023 12:06:12 +0000 (15:06 +0300)]
plat/kvm/x86: Enable relocation for `Firecracker` `PIE` builds
Previously, `PIE` builds for `Firecracker VMM` would fail at runtime
due to the fact that the static boot page tables would not be
relocated.
Therefore, enable `Firecracker` builds to run as `PIE` by employing
the early self relocator from `libukreloc`. Since an early bootstack
is also required to backup `rsi` holding the Linux Boot Protocol
structure as well as to provide room to `do_uk_reloc`'s local variables,
use the already existing `lcpu_bootstack` since it does not matter
whether it ends up being tainted or not.
Signed-off-by: Sergiu Moga <sergiu@unikraft.io> Reviewed-by: Marco Schlumpp <marco@unikraft.io> Approved-by: Michalis Pappas <michalis@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1045
Sergiu Moga [Fri, 11 Aug 2023 17:51:08 +0000 (20:51 +0300)]
plat/kvm: Fix guest hang on `UKPLAT_HALT` during shutdown request
As soon as
commit 170a8a4fb242 ("plat/kvm/shutdown.c: If on a `UEFI` system, rely on Runtime Services")
got merged guests would not finish on successful runs by exiting, but
instead by halting.
Although confusing, the intention was to use `UKPLAT_HALT` for a
graceful shutdown instead of a `cpu_halt` as it acts now.
Therefore, fix this by deleting the `UKPLAT_HALT` `case` from the
`switch` statement.
Signed-off-by: Sergiu Moga <sergiu@unikraft.io> Reviewed-by: Alexander Jung <alex@unikraft.io> Reviewed-by: Simon Kuenzer <simon@unikraft.io> Approved-by: Simon Kuenzer <simon@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1039
Michalis Pappas [Fri, 23 Jun 2023 09:26:34 +0000 (11:26 +0200)]
plat/kvm/arm: Obtain dtb address from x0 when using lxboot
According to the arm64 linux boot protocol [1] the address of the
fdt blob is passed on x0. This is unlike the QEMU virt boot protocol
when an ELF is loaded that uses a fixed address at 0x40000000. Update
the entry code to handle this case.
Sergiu Moga [Tue, 23 May 2023 16:44:01 +0000 (19:44 +0300)]
plat/drivers/gic: Remove `fdt` argument from initialization methods
Now that we have separated the ways we probe the `GIC` (`Devicetree`
vs `ACPI`) and the `Devicetree` parts can fetch the `Devicetree` on
their own, remove the no longer necessary `fdt` function parameters
from the related functions.
Sergiu Moga [Tue, 23 May 2023 16:26:55 +0000 (19:26 +0300)]
plat/drivers/gic: Enable `GICv3` probing through `ACPI`
If `ACPI` is enabled, rely on it for probing the `GICv3`. Thus, we
need to take two steps for this:
- fetch the GIC Redistributor's base address and address range length
from the `GICR` `MADT` entry. Normally we should check first if there
exists a Redistributor. If there is none then we must get its address
from the `GICC` structure, since that means that the Redistributors
are not in an always-on power domain. Otherwise there could be a `GICR`
for each Redistributor region and the `DT` probe version does not
support multiple regions anyway. So, until there is need for
that (not the case for QEMU Virt), align `ACPI` probe with `DT` probe
and assume we only have one Redistributor region.
- fetch the `GIC Distributor`'s physical base address from `MADT`'s
`GICD` structure and check that the size is compliant with that of
`GICv3`.
Furthermore, separate the two ways of probing `GICv3` in two:
one for `ACPI` and one for `Devicetree`.
As a reminder, add a `TODO` in the `DT` probe for when someone decides
to actually improve this driver.
Sergiu Moga [Tue, 23 May 2023 13:00:27 +0000 (16:00 +0300)]
plat/drivers/gic: Enable `GICv2` probing through `ACPI`
If `ACPI` is enabled, rely on it for probing the `GICv2`. Thus, we
need to take two steps for this:
- fetch the GIC CPU interface's base address and default length from
the `GICC` `MADT` entry. Since there is only one `Redistributor`, all
`GICC`'s must have the same physical base address.
- fetch the `GIC Distributor`'s physical base
address from `MADT`'s `GICD` structure and check that the size is
compliant with that of `GICv2`.
`GICR Base Address` must be set to 0, otherwise this is `GICv3/4`.
Furthermore, separate the two ways of probing `GICv2` in two:
one for `ACPI` and one for `Devicetree`.
Sergiu Moga [Tue, 23 May 2023 12:52:42 +0000 (15:52 +0300)]
plat/drivers/gic: Add a method for fetching the `GICD` from `MADT`
Since this applies for both `GICv2` and `GICv3`, implement a generic
method of fetching the unique `GICD` structure from the `MADT`.
Unlike `Devicetree`'s `reg` property, `ACPI` does not inform us of
the length of the `GIC Distributor`'s address space and therefore
one must assume the page-aligned default size from the specification:
- for GICv2: ARM Generic Interrupt Controller Architecture version
2.0 Issue B.b
- for GICv3: ARM Generic Interrupt Controller Architecture version
3 and version 4 Issue H
Sergiu Moga [Sun, 21 May 2023 13:17:50 +0000 (16:17 +0300)]
plat: Enable secondary cores allocation through `ACPI` on `ARM64`
Split secondary cores enumeration in two methods:
- if CONFIG_UKPLAT_ACPI is enabled then get the information
through the `MADT`'s `GICC` structures
- else rely on the `Devicetree`'s `cpu@` nodes
Simon Kuenzer [Fri, 11 Aug 2023 13:10:37 +0000 (15:10 +0200)]
plat/kvm: Add configuration hint for EFI
Adds an hint in `menuconfig` that appears if the configuration dependencies
are not met for building a QEMU image compatible to boot from an EFI
firmware.
Signed-off-by: Simon Kuenzer <simon@unikraft.io> Reviewed-by: Sergiu Moga <sergiu@unikraft.io> Approved-by: Razvan Deaconescu <razvand@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1038
Sergiu Moga [Fri, 11 Aug 2023 12:45:13 +0000 (15:45 +0300)]
plat/common/x86: Fix `libukreloc` error for non-`PIE` `SMP` builds
After the merge of
commit cf8cc65cb0ae ("plat/kvm/x86: Make SMP init code resolve its own `start16` relocations")
SMP builds that were not built with `libukreloc` would fail due to
external references to `x86_start16_*` symbols no longer being declared.
Thus, fix this by making their declaration present regardless of
`CONFIG_LIBUKRELOC` being enabled or not. Furthermore, guard the no
longer necessary `START16_UKRELOC_*` macro's, as they are not needed
if the previously mentioned configuration is not enabled.
Signed-off-by: Sergiu Moga <sergiu@unikraft.io> Reviewed-by: Marco Schlumpp <marco@unikraft.io> Approved-by: Razvan Deaconescu <razvand@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1037
Andrei Tatar [Tue, 18 Jul 2023 18:08:54 +0000 (20:08 +0200)]
build: Add library registration for tree build
This change adds `addlib_tree` and `addlib_tree_s` as library
registration functions that enable build products to be placed in a
directory tree mirroring the source files. This is useful for code that
shares source filenames across multiple directories.
Signed-off-by: Andrei Tatar <andrei@unikraft.io> Reviewed-by: Maria Sfiraiala <maria.sfiraiala@gmail.com> Reviewed-by: Marco Schlumpp <marco@unikraft.io> Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com> Reviewed-by: Simon Kuenzer <simon@unikraft.io> Approved-by: Simon Kuenzer <simon@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1001
Andrei Tatar [Wed, 28 Jun 2023 14:14:25 +0000 (16:14 +0200)]
build: Add option to place build objects in a tree
This adds the feature to place build products in a directory tree
mirroring the tree their source files are in.
This feature piggy-backs on top of the $(LIBNAME)__BUILDTREE flag from 87065c2f (build: Add option for dedicated build directory).
In addition, the $(LIBNAME)_SRC make variable must point to the common
prefix of a library's source file paths. Any intermediate directories
are created automatically.
Signed-off-by: Andrei Tatar <andrei@unikraft.io> Reviewed-by: Maria Sfiraiala <maria.sfiraiala@gmail.com> Reviewed-by: Marco Schlumpp <marco@unikraft.io> Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com> Reviewed-by: Simon Kuenzer <simon@unikraft.io> Approved-by: Simon Kuenzer <simon@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1001
Andrei Tatar [Wed, 28 Jun 2023 13:47:28 +0000 (15:47 +0200)]
build: Add option for dedicated build directory
This change adds the option to place build files in a dedicated
`.../build/` directory under the library build path.
This feature is opt-in per-library and enabled if the $(LIBNAME)__BUILDTREE
make variable is set.
Signed-off-by: Andrei Tatar <andrei@unikraft.io> Reviewed-by: Maria Sfiraiala <maria.sfiraiala@gmail.com> Reviewed-by: Marco Schlumpp <marco@unikraft.io> Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com> Reviewed-by: Simon Kuenzer <simon@unikraft.io> Approved-by: Simon Kuenzer <simon@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1001
Write the code in such a manner that the same set of functions can
accommodate any version of ACPI. Thus, remove `acpi10_*` functions
and define an ACPI table generic fetching function `acpi_get_table`.
Sergiu Moga [Sun, 21 May 2023 08:36:15 +0000 (11:36 +0300)]
support/scripts/mkukimg: Add support for `EFI` Disk images
Begin by taking the setting up of the `EFI System Partition` layout
from `mkukefiiso` into a separate function `mkukefiesp`, since it
applies to any image involving an `EFI System Partition` with the
`Unikraft` `EFI` stub.
Next, create the usual disk image formatted with a `GPT` and a single
partition, that of the `EFI System Partition`, which has the same layout
as the `ISO` image.
Furthermore, clarify in the usage message that we now support disk
images for `ukefi` only and add the corresponding `OPTFORMAT` case.
To avoid ambiguity in the `OPTFORMAT` cases' messages, specify the
type of of bootloader that is not supported for the respective image
format.
Signed-off-by: Sergiu Moga <sergiu.moga@protonmail.com> Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com> Approved-by: Razvan Deaconescu <razvand@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #910
Sergiu Moga [Sat, 20 May 2023 18:40:09 +0000 (21:40 +0300)]
support/scripts: Allow building `UEFI` `ISO`'s
Give the script the ability to build `UEFI` bootable `ISO`'s.
The `FAT32` image contained within the `ISO` will have the
following layout:
```
└── EFI
└── BOOT
├── BOOT${OPTARCH}.EFI
├── ${OPTINITRD}
└── ${OPTCMDLINE}
```
Add two new options:
- b: to differentiate between possible bootloaders
- a: to differentiate between possible architectures
Furthermore, rename the script to highlight the fact that this is no
longer `GRUB` only.
Signed-off-by: Sergiu Moga <sergiu.moga@protonmail.com> Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com> Approved-by: Razvan Deaconescu <razvand@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #910
plat/common/efi: Add support for `TCG`'s `Reset Attack Mitigation`
Add `Trusted Computing Group`'s `Reset Attack Mitigation` mechanism.
Whenever a machine shuts down or reboots, due to lack of electric
charge, the contents of RAM may dissipate after a short amount of
time. However this may be enough for an attacker to quickly boot
again into a custom program and dump memory contents. Thus, by using
this, the OS instructs POST BIOS to overwrite memory contents before
continuing to boot into the rest of the BIOS code.
Since this is not really implemented in `OVMF`'s `NVRAM` variables
we disable this by default.
plat/kvm/shutdown.c: If on a `UEFI` system, rely on Runtime Services
Preferably, a UEFI system is also an ACPI system and thus these
functionalities should be implemented through ACPI methods. But for
now, make use of UEFI's Runtime Services for resetting the system,
since they are more reliable than what we have at the moment.
Sergiu Moga [Mon, 27 Mar 2023 10:00:30 +0000 (13:00 +0300)]
plat/kvm/arm: Enable the Unikernel to be built as an UEFI application
If `CONFIG_EFI_STUB` is enabled, add to the build system the ARM UEFI
entry stub and the ARM specific post-EFI stub that applies finishing
touches to the platform initialization.
Add a configuration entry `KVM_BOOT_QEMU_VIRT` to explicitly
indicate that we are booting from the default `QEMU virt`
environment. This will help us differentiate between UEFI and
non-UEFI ARM builds.
Sergiu Moga [Mon, 27 Mar 2023 09:51:22 +0000 (12:51 +0300)]
plat/kvm/arm: Add architecture specific post-EFI stub
Implement a stub that comes after the architecture generic EFI stub
calls the routine that exits `Boot Services`.
This is supposed to finish the architecture specific setupin order
to be able to have a Unikraft valid initial environment state before
`_libkvmplat_start` is execited.
Thus, the interrupt flags are masked, the data cache is invalidated
in the range of this image's instance and then default, warm reset
values are placed into the system registers that EFI would have
otherwise left modified.
Sergiu Moga [Mon, 27 Mar 2023 10:00:30 +0000 (13:00 +0300)]
plat/kvm/x86: Enable the Unikernel to be built as an UEFI application
If `CONFIG_EFI_STUB` is enabled, add to the build system the fake PE
header, the architecture generic EFI stub, and the x86 specific
post-EFI stub that applies finishing touches to the platform
initialization.
Sergiu Moga [Mon, 27 Mar 2023 09:51:22 +0000 (12:51 +0300)]
plat/kvm/x86: Add architecture specific post-EFI stub
Implement a stub that comes after the architecture generic EFI stub
calls the routine that exits `Boot Services`.
This is supposed to finish the architecture specific setupin order
to be able to have a Unikraft valid initial environment state before
`_ukplat_entry` is execited.
Thus, begin by disabling the `Interrupt Flag`, updating the root of
the page tables with our in-image static page tables, unmask the
legacy `8259 PIC`, since, at this point, we do not have `I/O APIC`
support, disable the `LAPIC Timer` initially setup by `UEFI`, set the
legacy shared PCI IRQ's as level triggered since UEFI does not do it
for us (unless we boot in `CSM`) and we do not, at this moment have a
proper IRQ subsystem and, finally, jump to `lcpu_start64` with the
entry function as `_ukplat_entry` and a statically allocated
page-sized stack.
Implements the small x86 specific UEFI entry point which will call
the early self relocator, adjust the initially unaligned stack and
finally jump to the architecture generic EFI stub.
Sergiu Moga [Mon, 27 Mar 2023 09:26:10 +0000 (12:26 +0300)]
support/scripts: Add `python3` script to patch fake PE header
This script allows patching of the architecture specific fake PE
headers. It only fills in the fields that UEFI firmware looks for
when validating and loading the image. Specifically, it does the
following:
- Write MS-DOS signature in the first bytes of the binary
- Write at the standard MS-DOS file offset `0x3c` the offset to the
beginning in file of the fake PE header
- Append the original ELF file that also contains the PE header
- Fill in the following fields of the Optional Header: SizeOfCode,
AddressOfEntryPoint, BaseOfCode, SizeOfImage
- Fill in the dummy PE sections, as PE, unlike ELF, is loaded by
sections:
- dummy .reloc section pointing to itsel with all fields
zeroed out except the VirtualAddress and PointerToRawData
fields which point to the section itself, to fool UEFI into
thinking this is a valid relocation.
- All PT_LOAD ELF Program Headers will be encapsulated into
PE sections with all permissions enabled (RWX)
For these sections, only the following fields are required to be filed
in: VirtualSize, VirtualAddress, SizeOfRawData, PointerToRawData.
Thus, the script fills in the bare-minimum fields, according to EDKII,
the most complete and official UEFI implementation, that are required
by an UEFI application's PE header to be considered valid and loadable.
Sergiu Moga [Tue, 28 Mar 2023 14:20:01 +0000 (17:20 +0300)]
plat/kvm/efi.c: Add support for Devicetree Blob file
This enables the EFI stub to load a Devicetree Blob file from the
same filesystem that the Unikraft image was loaded from (the EFI
System Partition) and register it as a `Memory Region Descriptor`.
The name of the `dtb` file is given through the
`CONFIG_UK_EFI_STUB_DTB_FNAME` configuration entry and it tells
the loader the name of the file to load from the `\EFI\BOOT` directory
of the EFI System Partition.
Sergiu Moga [Tue, 28 Mar 2023 14:20:01 +0000 (17:20 +0300)]
plat/kvm/efi.c: Add support for initial RAM disk file
This enables the EFI stub to load an initial RAM disk file from the
same filesystem that the Unikraft image was loaded from (the EFI
System Partition) and register it as a `Memory Region Descriptor`.
The name of the `initrd` file is given through the
`CONFIG_UK_EFI_STUB_INITRD_FNAME` configuration entry and it tells
the loader the name of the file to load from the `\EFI\BOOT` directory
of the EFI System Partition.
Sergiu Moga [Mon, 27 Mar 2023 10:08:34 +0000 (13:08 +0300)]
plat/kvm/efi.c: Add command-line arguments support
Implement support to pass command-line arguments through Unikraft's
`struct ukplat_bootinfo`.
This can be done in two ways:
1. Through the UEFI Shell when launching the image or through `qemu`'s
`-append` option.
2. Through the filesystem of the same partition (the EFI System
Partition) that the image was launched from. The loader will look
for a file with the name configured through the
`UK_EFI_STUB_CMDLINE_FNAME` in the `\EFI\BOOT' directory.
The first way, if applicable, takes priority over the second.
Sergiu Moga [Tue, 21 Mar 2023 13:31:02 +0000 (15:31 +0200)]
plat/kvm: Implement architecture generic EFI stub
Add an architecture generic EFI stub that sets up a
`struct ukplat_bootinfo`'s memory region descriptors, `bootloader`
and `bootprotocol` fields. Furthermore, the memory region descriptors
corresponding to the UEFI `Runtime Services` are gathered separately,
through UEFI's `Memory Attribute Table`, since they have to be
treated differently, in order for the `Runtime Services` to be
used properly after `exit_boot_services`.
At the end, the stub calls `uk_efi_jmp_to_kern` which each architecture
is supposed to independently implement the remaining setup for its
platform.
Sergiu Moga [Mon, 27 Mar 2023 09:44:46 +0000 (12:44 +0300)]
plat/kvm: Add `EFI_STUB` configuration entry
Add a configuration option to build the Unikernel as a valid,
loadable UEFI application. Make it depend on `ACPI` and, obviously,
on not having `PLAT_LINUXU` enabled.
Furthermore, remove default selection of the Multiboot boot protocol
if QEMU VMM is selected, now that a QEMU image can also be an EFI
image.
Add a description and proper dependencies for the
`KVM_BOOT_PROTO_LXBOOT` configuration entry. Since `Firecracker`
only supports the `Linux` 64-bit boot protocol and we do not yet
support booting through it on `QEMU`, make the dependencies
reflect that.
Add a description and proper dependencies for the
`KVM_BOOT_PROTO_MULTIBOOT` configuration entry. Since `Firecracker`
only supports the `Linux` 64-bit boot protocol and `Multiboot` is
x86 specific (not taking into consideration the `Multiboot` ported
to `ARM` for `Xen`), make the configuration entry reflect that.
Simon Kuenzer [Thu, 27 Jul 2023 20:27:42 +0000 (22:27 +0200)]
support/qemu-guest: Darwin support
This commit introduces native support for QEMU installations on
Darwin (MacOS). Apple's hypervisor framework is used for guest
acceleration instead of KVM on Linux hosts.
Signed-off-by: Simon Kuenzer <simon@unikraft.io> Reviewed-by: Alexander Jung <alex@unikraft.io> Approved-by: Razvan Deaconescu <razvand@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1034
Simon Kuenzer [Thu, 27 Jul 2023 10:56:27 +0000 (12:56 +0200)]
support/qemu-guest: Remove SGA bios parameter and warning
Starting with QEMU version 8.0, the `-device sga` parameter is removed from
the command line because it is no longer needed. These versions include a
SeaBIOS version that contains native support for serial consoles. If an
older version of QEMU is used with `qemu-guest`, the BIOS output may no
longer be visible but the guest would still be able to boot.
Signed-off-by: Simon Kuenzer <simon@unikraft.io> Reviewed-by: Alexander Jung <alex@unikraft.io> Approved-by: Razvan Deaconescu <razvand@unikraft.io> Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #1034