Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plat: Rework paged memory init #1373

Merged
merged 28 commits into from
Jun 3, 2024

Conversation

michpappas
Copy link
Member

@michpappas michpappas commented Apr 1, 2024

Prerequisite checklist

  • Read the contribution guidelines regarding submitting new changes to the project;
  • Tested your changes against relevant architectures and platforms;
  • Ran the checkpatch.uk on your commit series before opening this PR;
  • Updated relevant documentation.

Base target

  • Architecture(s): [N/A]
  • Platform(s): [N/A]
  • Application(s): [N/A]

Additional configuration

Description of changes

This series reworks the initialization of paged memory to provide a more flexible implementation that is capable of handling regions beyond the limits defined in the boot page-tables. The motivation for this change is to allow mapping device regions that are unknown at compile-time, such as Unprotected IPA Alias regions of Arm CCA Realms [1][2], the address of which depends on the executing platform.

This rework has side-effects on the way device MMIO regions are mapped. To address these requirements, this PR performs the following changes:

  • Introduce early init boot stage in kvm/arm64.
  • Add early_init to drivers that use MMIO, and have these drivers register bootinfo mrds for these regions during early_init.
  • Add runtime mapping of MMIO regions to the initialization of relevant drivers.

All the above are described in further detail in the sections that follow.

Additional fixes include:

  • lib/ukbus: Use the correct init class and priority.
  • plat/drivers/uktty: Clean up driver init (ns16550 and pl011).
  • plat/drivers/uktty: Move driver init to uk_inttab (ns16550 and pl011).
  • plat/kvm/arm64: Remove console registration from platform setup.

Rework of paged memory init

Under the new scheme, bootinfo is simplified to only contain valid memory regions. Upon paged memory initialization these regions are either mapped with the protections defined in their mrd, or are already mapped, in which case only their protections are updated. An exception to this is mrds of the UKPLAT_MEMRT_DEVICE type, that are ignored to allow MMIO regions mapped during early device initialization to remain mapped.

Any memory not defined in bootinfo is unmapped. The theoretical bounds used as a reference are platform-specific and are defined in a newly introduced platform.h that must be provided by all platforms.

Early device initialization

early_init is invoked as the last call of early boot code, as soon as the stack and MMU are enabled.

Early devices are initialized before bootinfo setup, as the latter depends on UART for debug messages.

Early devices can use the APIs provided by libfdt / ACPI to obtain any information required from the firmware, such as device regions and the kernel command line.

Drivers that register with early_init are updated to append mrds of their MMIO regions to bootinfo. That is required so that their regions are not unmapped by paged memory init. The mrds added during early_init to bootinfo must use the newly introduced UKPLAT_MEMRT_DEVICE type.

Be aware that early drivers should not call ukplat_bootinfo_coalesce, as mrd coalescing is performed once at the end of bootinfo_setup, which is now performed as to the last step of early_init.

Notice that:

  • early_init is currently introduced in kvm/arm64, as it is the only platform that involves early initialization of drivers that use MMIO.
  • early_init is currently implemented as a simple placeholder from where drivers can add manual calls of their early_init functions. This should be replaced with an early inittab as soon as bootinfo is moved out of plat.

Late (i.e. non-early) device initialization

Given that all memory that is not backed by an mrd is unmapped during paged memory init, devices that don't register mrds during early init are now required to map their regions during probing. To address this requirement this PR updates relevant drivers to map their MMIO regions dynamically.

References

[1] Realm Management Monitor Specification DEN0137 Sect. D2.1
[2] #964

GitHub-Depends-On: #972
GitHub-Depends-On: #1212
GitHub-Depends-On: #1346

@michpappas michpappas requested review from a team as code owners April 1, 2024 21:28
@github-actions github-actions bot added area/include Part of include/uk area/lib Internal Unikraft Microlibrary area/plat Unikraft Patform area/support Support scripts, tools, services. lang/c Issues or PRs to do with C/C++ lang/python Issues or PRs to do with Python lib/ukboot lib/ukbus lib/vfscore VFS Core Interface plat/common Common to all platforms plat/driver plat/kvm Unikraft for KVM plat/xen Unikraft for Xen labels Apr 1, 2024
@michpappas michpappas marked this pull request as draft April 1, 2024 21:29
@github-actions github-actions bot added arch/arm arch/arm64 arch/x86_64 area/arch Unikraft Architecture lib/posix-process Information about system parameters labels Apr 7, 2024
razvand pushed a commit that referenced this pull request Jun 3, 2024
The direct-mapped area maps the first 512GiB of the address space
to an architecture-defined region. In arm64 that uses the highest
512GiB of the low VA range. Update DIRECTMAP_AREA_END to correctly
specify the end of the low VA range.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
VMSAv8-64 does not provide a naming scheme for the block
size mapped by PT block descriptors at various translation
levels. Moreover, the block size varies depending on the
size of the translation granule.

To provide granularity agnostic definitions, use the
x86_64 terminology of Large / Huge pages.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Rework the initialization of paged memory to provide a more flexible
implementation that is capable of handling regions beyond the limits
defined in the boot pagetables. The motivation for this change is to
allow mapping device regions that are unknown at compile-time, such
as Unprotected IPA Alias regions of Arm CCA Realms, the address of
which depends on the executing platform.

Under the new scheme bootinfo is reduced to only contain mrds that
correspond to valid memory regions. This deprecates the unmap_mrd
region and the UKPLAT_MEMRF_MAP / UKPLAT_MEMRF_UNMAP mrd flags.
Moreover, the boot pagetables are no longer updated during paged
memory init, but instead are replaced with a new pagetable that
initialized with the regions defined in bootinfo. Besides the
additional flexibility, this implementation has the potential of
some performance improvement as it removes expensive TLB flush
operations associated with unmap.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Co-authored-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Move vaddr check from pgarch_page_mapx() to its callers, as that
function is also used to map the direct-mapped region, the vaddr
of which is past (__VADDR_MAX - len).

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
UKPLAT_MEMRF_MAP / UKPLAT_MEMRF_UNMAP mrd types have been obsoleted by
the reworked implementation of paged memory init.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
UKPLAT_MEMRF_MAP / UKPLAT_MEMRF_UNMAP mrd types have been obsoleted by
the reworked implementation of paged memory init.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
UKPLAT_MEMRF_MAP / UKPLAT_MEMRF_UNMAP mrd types have been obsoleted by
the reworked implementation of paged memory init.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
UKPLAT_MEMRF_MAP / UKPLAT_MEMRF_UNMAP mrd types have been obsoleted by
the reworked implementation of paged memory init.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Update uk_bus_pf_devmap() to handle a multi-page region page-by-page,
to avoid an error caused by a partially mapped device region, which
would cause ukplat_page_map() would return EEXIST and in turn cause
the subsequent ukplat_page_set_attr() to fail.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Regions of this type are added by device drivers that implement
an early init. Specifically, upon completion of the earlyinit boot
stage, device regions are expected to be mapped with appropriate
protections, and additionally be added to bootinfo using the
UKPLAT_MEMRT_DEVICE type.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Remove coalescing out of bootinfo fdt setup to allow coalescing happen
at a boot protocol agnostic way at early_init(), after the initialization
of early devices.

Break down bootinfo_fdt_setup() into a pre and post coalesce functions
as the latter call ukplat_memory_alloc() which operates on ordered
regions.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Remove redundant extern keyword from function declarations in EFI
post on arm64 and x86_64.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Remove coalescing from EFI bootinfo setup to allow coalescing to
happen at a boot protocol agnostic way at early_init(), after the
initialization of early devices.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
With bootinfo coalesce having moved out of EFI common code,
and with kvm/x86 lacking an early init bootstage, do the coalescing
as the last part at EFI post before jumping to kernel.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Add boot stage for early initialization. This is invoked at the end
of early boot code, before passing control to the platform.

Early devices can use the APIs provided by the boot protocol to obtain
any information required, such as device regions and the kernel
command line.

Drivers that register with early_init() should append mrds of their
MMIO regions to bootinfo so that these regions are not unmapped
during paged memory init. These mrds must use the newly introduced
UKPLAT_MEMRT_DEVICE type.

Notice that early drivers should not call ukplat_bootinfo_coalesce(),
as mrd coalescing is performed once at the end of early_init().

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Clean up pl011 init. Functional changes:
 - Return an error when init fails
 - Downgrade diagnostic message severity to uk_pr_debug

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Map the pl011 region at runtime. This is now required as paged memory
init unmaps any memory not registered by early devices, thus if early
UART is not enabled the device regions is not mapped.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Move console initialization with the rest of devices at
UK_INIT_CLASS_SYS. Since the pf bus does not support priority
levels, and the console should start before the pf bus to
allow drivers to print their status, register directly with
init instead of the pf bus.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Add early device init. When paging is enabled, this adds an mrd for
the pl011 MMIO region to bootinfo so that the region is not unmapped
during paged memory init.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Clean ns16550 driver init. Functional changes:
- Return an error when init fails
- Downgrade diagnostic message severity to uk_pr_debug

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Map the ns16550 region at runtime. This is now required as paged memory
init unmaps any memory not registered by early devices, thus if early
UART is not enabled the device regions is not mapped.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Update the early console Kconfig option of ns16550 to aligned with the
current convention as well as the equivalent option of pl011.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Move console initialization with the rest of devices at
UK_INIT_CLASS_SYS. Since the pf bus does not support priority
levels, and the console should start before the pf bus to
allow drivers to print their status, register directly with
init instead of the pf bus.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Add early device init. When paging is enabled, this adds an mrd for
the ns16550 MMIO region to bootinfo so that the region is not unmapped
during paged memory init.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
With both UART drivers initialized by uk_inittab, remove console
registration from platform setup.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Register ns16550 and pl011 into ukplat_early_init.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Map GIC regions dynamically if paging is enabled. This is now required
as paged memory init unmaps any memory not backed by an mrd.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand pushed a commit that referenced this pull request Jun 3, 2024
Map pl031 regions dynamically if paging is enabled. This is now
required as paged memory init unmaps any memory not backed by an
mrd.

Signed-off-by: Michalis Pappas <michalis@unikraft.io>
Reviewed-by: Sergiu Moga <sergiu@unikraft.io>
Reviewed-by: Serban Sorohan <serban.sorohan@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1373
razvand added a commit to unikraft/meeting-notes that referenced this pull request Jun 11, 2024
The discussion was focused on the paged memory init PR:
unikraft/unikraft#1373

Signed-off-by: Razvan Deaconescu <razvand@unikraft.io>
Signed-off-by: Michalis Pappas <mpappas@fastmail.fm>
razvand added a commit to unikraft/meeting-notes that referenced this pull request Jun 11, 2024
The discussion was focused on the paged memory init PR:
unikraft/unikraft#1373

Signed-off-by: Razvan Deaconescu <razvand@unikraft.io>
Signed-off-by: Michalis Pappas <mpappas@fastmail.fm>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch/arm arch/arm64 arch/x86_64 area/arch Unikraft Architecture area/include Part of include/uk area/lib Internal Unikraft Microlibrary area/plat Unikraft Patform area/support Support scripts, tools, services. lang/c Issues or PRs to do with C/C++ lang/python Issues or PRs to do with Python lib/posix-process Information about system parameters lib/ukboot lib/ukbus lib/uksched lib/ukschedcoop lib/vfscore VFS Core Interface plat/common Common to all platforms plat/driver plat/kvm Unikraft for KVM plat/xen Unikraft for Xen release-note Denotes a PR that will be considered when it comes time to generate release notes.
Projects
Status: Done!
Development

Successfully merging this pull request may close these issues.

None yet

6 participants