VirtualBox

Changeset 94465 in vbox


Ignore:
Timestamp:
Apr 5, 2022 11:43:09 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
150796
Message:

Devices/EFI: Fix possible triple fault with SMP configurations during reset

During initialization UEFI enumerates the available CPUs by issuing an IPI to all APs
and waiting a fixed amount of time (50ms by default) for all APs to serve the request.
The timeout is far too low for a hypervisor due to host scheduling interference resulting in the
timed wait to expire before the APs could startup. The BSP will then free the wakeup buffer which
the APs use to startup (switching from real mode to the final execution mode) and overwrite it with 0.
This causes the APs to execute garbage when the respective EMTs get finally scheduled causing all sorts
of weird behavior.

Because it is impossible to set a sane upper timeout without causing execessive delay this change
makes the plartform code query the maximum and current number of CPUs present for the guest so
it can exactly wait for the amount of available CPUs without using any fixed timeouts.

(I'm still puzzled why this only happens when the VM is reset and not during startup...)

Location:
trunk/src/VBox/Devices/EFI
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/DevEFI.cpp

    r93944 r94465  
    310310        case EFI_INFO_INDEX_VERTICAL_RESOLUTION:
    311311        case EFI_INFO_INDEX_HORIZONTAL_RESOLUTION:
     312        case EFI_INFO_INDEX_CPU_COUNT_CURRENT:
     313        case EFI_INFO_INDEX_CPU_COUNT_MAX:
    312314            return 4;
    313315        case EFI_INFO_INDEX_BOOT_ARGS:
     
    413415        case EFI_INFO_INDEX_HORIZONTAL_RESOLUTION:  return efiInfoNextByteU32(pThisCC, pThisCC->u32HorizontalResolution);
    414416        case EFI_INFO_INDEX_VERTICAL_RESOLUTION:    return efiInfoNextByteU32(pThisCC, pThisCC->u32VerticalResolution);
     417        case EFI_INFO_INDEX_CPU_COUNT_CURRENT:      return efiInfoNextByteU32(pThisCC, pThisCC->cCpus); /** @todo CPU hotplugging. */
     418        case EFI_INFO_INDEX_CPU_COUNT_MAX:          return efiInfoNextByteU32(pThisCC, pThisCC->cCpus);
    415419
    416420        /* Keep in sync with value in EfiThunk.asm */
  • trunk/src/VBox/Devices/EFI/DevEFI.h

    r93115 r94465  
    7373    EFI_INFO_INDEX_MCFG_SIZE,
    7474    EFI_INFO_INDEX_APIC_MODE,
     75    EFI_INFO_INDEX_CPU_COUNT_CURRENT,
     76    EFI_INFO_INDEX_CPU_COUNT_MAX,
    7577    EFI_INFO_INDEX_END
    7678} EfiInfoIndex;
  • trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/PlatformPei/Platform.c

    r85718 r94465  
    671671  )
    672672{
     673#ifndef VBOX
    673674  UINT16        BootCpuCount;
     675#else
     676  UINT32        BootCpuCount;
     677#endif
    674678  RETURN_STATUS PcdStatus;
    675679
     680#ifndef VBOX
    676681  //
    677682  // Try to fetch the boot CPU count.
     
    809814    }
    810815  }
     816#else
     817  GetVmVariable(EFI_INFO_INDEX_CPU_COUNT_CURRENT, &BootCpuCount, sizeof(BootCpuCount));
     818  GetVmVariable(EFI_INFO_INDEX_CPU_COUNT_MAX, &mMaxCpuCount, sizeof(mMaxCpuCount));
     819#endif
    811820
    812821  DEBUG ((DEBUG_INFO, "%a: BootCpuCount=%d mMaxCpuCount=%u\n", __FUNCTION__,
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette