dasharo-issues icon indicating copy to clipboard operation
dasharo-issues copied to clipboard

Booting is slow in QEMU

Open krystian-hebel opened this issue 1 year ago • 3 comments

Component

Dasharo firmware

Device

QEMU Q35 Emulator

Dasharo version

v0.2.0

Dasharo Tools Suite version

No response

Brief summary

Booting takes 15-25 seconds before logo is shown. In addition, saving multiple UEFI variables at once (e.g. restoring default SB keys) is also slow.

How reproducible

100%

How to reproduce

Start with ./qemu_run.sh graphic firmware and wait for logo.

Expected behavior

  • Start QEMU
  • Wait a second or two
  • See the Dasharo logo

Actual behavior

  • Start QEMU
  • Wait a second or two
  • More waiting
  • Just a bit more more
  • See the Dasharo logo

Screenshots

No response

Additional context

Booting is significantly faster with Secure Boot enabled, but still not as fast as it should be.

Solutions you've tried

Using OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf instead of HPET makes it boot faster, but it also makes the delays shorter, up to a point where tests can't traverse iPXE menu before autoboot, which should normally should take 3 seconds. It may be controlled by modifying gEfiMdePkgTokenSpaceGuid.PcdFSBClock (MdePkg defines it as 200M, while most of OVMF platforms use 1G), however I haven't tested how it would work on other platforms.

krystian-hebel avatar Jun 25 '24 06:06 krystian-hebel

@krystian-hebel do we know where we should look for the solution to this problem? Any specific ideas to test out?

macpijan avatar Mar 07 '25 08:03 macpijan

Yes, the ones described in Solutions you've tried. What is left to be tested is the impact of that change on other platforms.

krystian-hebel avatar Mar 07 '25 09:03 krystian-hebel

Could you please link a patch/MR, so we can coordinate testing it perhaps during some other testing activities on other platforms?

Which aspects should be investigated for potential regressions on real hardware platforms?

macpijan avatar Mar 07 '25 09:03 macpijan

Notes from Krystian

I haven’t pushed anything yet, but if I remember correctly, after replacing the following lines:

with: OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf

and setting the frequency in:

to 1GHz, the time started flowing correctly.

However, this would break other platforms, so the change should be applied conditionally (at minimum the frequency change; possibly switching from HPET to LAPIC alone might work). Alternatively, add code to change it at runtime.

Instead of modifying MdePkg.dec directly, consider moving the change to a different .dsc file—similar to how OVMF handles it here:


Implementation Plan

  • [ ] Replace TimerLib references in:

  • [ ] Set timer frequency to 1GHz in build config:

    • [ ] Preferably not directly in MdePkg.dec
    • [ ] Instead, move this setting to a local .dsc (e.g., like in OvmfPkgX64.dsc)
  • [ ] Implement platform-specific conditional logic:

    • [ ] Ensure the change does not break other platforms
    • [ ] Potentially add a runtime switch (e.g., HPET → LAPIC)
  • [ ] Test time flow across all supported platforms to confirm no regressions (we can define here a list of platforms to be tested)

macpijan avatar May 12 '25 12:05 macpijan

@macpijan this may also be relevant:

!if $(CPU_TIMER_LIB_ENABLE) == TRUE
  TimerLib|UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf
!else
  TimerLib|DasharoPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
!endif

The timer used depends on whether certain CPUID leaves are present to determine the TSC tick frequency. For QEMU these CPUID leaves are definitely not available, so the payload is built with HPET timer support. FYI.

We can add a new define CPU_LAPIC_TIMER_LIB_ENABLE (QEMU exclusive) which would select the LAPIC timer instead of HPET timer to produce gEfiTimerArchProtocolGuid.

miczyg1 avatar May 12 '25 12:05 miczyg1

Have you tried disabling HPET in QEMU with -machine hpet=off parameter as a possible workaround (-machine q35,smm=on,hpet=off) instead of doing it Firmware image side? I have never used UEFI Secure Boot nor TPM in QEMU, but I do recall encountering people claiming slow boot issues with OVMF Secure Boot enabled images and QEMU SMM, check this: https://old.reddit.com/r/VFIO/comments/1jzg2uy/need_help_investigating_slow_boot_times/

So perhaps it may be a QEMU/OVMF side issue?

zirblazer avatar May 12 '25 17:05 zirblazer

Couldn't changing the timer from HPET to APIC be achieved using EDK2_USE_LAPIC_TIMER config?

config EDK2_USE_LAPIC_TIMER
	bool "Use LAPIC timer instead of HPET"
	default n
	help
	  Select this option to use the LAPIC timer instead of HPET in edk2. The LAPIC is closer
	  to the CPU than the HPET (on the PCH), resulting in lower latency / higher resolution.
	  This setting is at least needed for platforms with Core 2 processors, which are reported
	  to have issues with HPET.

philipanda avatar May 14 '25 07:05 philipanda

Have you tried disabling HPET in QEMU with -machine hpet=off parameter as a possible workaround (-machine q35,smm=on,hpet=off) instead of doing it Firmware image side?

Disabling the hpet like you suggested causes the firmware to not boot at all. Even after 60 seconds the image is still black, no serial output.

philipanda avatar May 14 '25 08:05 philipanda

Couldn't changing the timer from HPET to APIC be achieved using EDK2_USE_LAPIC_TIMER config?

config EDK2_USE_LAPIC_TIMER
	bool "Use LAPIC timer instead of HPET"
	default n
	help
	  Select this option to use the LAPIC timer instead of HPET in edk2. The LAPIC is closer
	  to the CPU than the HPET (on the PCH), resulting in lower latency / higher resolution.
	  This setting is at least needed for platforms with Core 2 processors, which are reported
	  to have issues with HPET.

This will cause the CPU_LAPIC_TIMER_LIB_ENABLE to be set for the build. However as I explained, it requires the CPUID leaf which QEMU doesn't support AFAIK, so this option won't do.

Disabling the hpet like you suggested causes the firmware to not boot at all. Even after 60 seconds the image is still black, no serial output.

Because you end up without any timer in that case...

miczyg1 avatar May 14 '25 09:05 miczyg1

Changes to fix the issue were implemented: https://github.com/Dasharo/edk2/pull/245 https://github.com/Dasharo/coreboot/pull/674 First boot takes up to 8-9 seconds now, with the consecutive reboots being quicker.

philipanda avatar May 19 '25 15:05 philipanda