UEFI non-blocking StartupThisAP for EFI_MP_SERVICES_PROTOCOL

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
pietroborrello
Posts: 3
Joined: Wed Nov 24, 2021 3:54 am

UEFI non-blocking StartupThisAP for EFI_MP_SERVICES_PROTOCOL

Post by pietroborrello »

I am building a UEFI application that needs to execute instructions on two parallel cores concurrently.
I am using StartupThisAP in EFI_MP_SERVICES_PROTOCOL to wake up the second core to execute a given function.
Per my understanding of UEFI specification (https://uefi.org/sites/default/files/re ... ec_1_6.pdf page 485) the WaitEvent parameter of StartupThisAP in EFI_MP_SERVICES_PROTOCOL should set the execution of the Procedure to the non-blocking mode when set to not null:

Code: Select all

    EFI_EVENT Event = 0;
    status = uefi_call_wrapper(BS->CreateEvent, 5, 0, TPL_NOTIFY, NULL, NULL, &Event);
    if(EFI_ERROR(status) || !Event) {
        Print(L"[-] Failed to create event\n");
        return EFI_SUCCESS;
    }

    status = uefi_call_wrapper(mp->StartupThisAP, 7, mp, SMP_function, CORE1, Event, 0, (VOID*) NULL, NULL);
    if(EFI_ERROR(status)) {
        Print(L"[-] Failed to spawn SMP\n");
        return EFI_SUCCESS;
    }
However, I always observe the two cores executing sequentially, with the BSP core waiting for the termination of the AP. Am I using the API wrong?

I attach the code of the minimized UEFI application. It is launched from the UEFI shell, by simply executing it.
Am I not allowed to use EFI_MP_SERVICES_PROTOCOL in such a setup?
I am using gnu-efi to build the application, and I'm using a custom header to provide definitions for EFI_MP_SERVICES_PROTOCOL, which I did not find among the ones provided by gnu-efi.
The example function that is run in the AP is calling BootServices and issuing prints, I know in theory it is not MP safe, but this is an easy way to show if they are executing in parallel or not.
What I observe is always all the prints from the AP core being issued before the ones from BSP, never interleaved. I also print the core ID to be sure that the function is actually executed from the second core.

Code: Select all

Hello from SMP: 1
Hello from SMP: 1
Hello from SMP: 1
[...]
Hello from SMP: 1
Hello from BSP: 0
Hello from BSP: 0
[...]
Hello from BSP: 0
The platform is an x86-64 Intel CPU with two cores, two threads, with no hyperthreading support.
I also tried to use atomic variables to block the AP core on a polling loop until the BSP signals it to start, but this just breaks into a deadlock since the BSP is blocked until the AP finishes.
Attachments
Makefile.txt
makefile
(591 Bytes) Downloaded 37 times
efi-mp.h
header to provide definitions of EFI_MP_SERVICES_PROTOCOL for gnu-efi
(2.45 KiB) Downloaded 47 times
uefi_app.c
source code of the uefi application
(3.56 KiB) Downloaded 49 times
feryno
Member
Member
Posts: 73
Joined: Thu Feb 09, 2012 6:53 am
Location: Czechoslovakia
Contact:

Re: UEFI non-blocking StartupThisAP for EFI_MP_SERVICES_PROT

Post by feryno »

Something similar was already discussed here:
viewtopic.php?f=1&t=37207&start=5

Here a quick manual which could be helpful for you:
https://uefi.org/sites/default/files/re ... Daniel.pdf

You commented out the StartupAllAPs - did it work as you wanted, and only the following StartupThisAP didn't?
Doc about StartupAllAPs claims this: The parameter SingleThread: If TRUE, then all the enabled APs execute the function specified by Procedure one by one, in ascending order of processor handle number. If FALSE, then all the enabled APs execute the function specified by Procedure simultaneously.
The parameter WaitEvent: The event created by the caller with CreateEvent() service. If it is NULL, then execute in blocking mode. BSP waits until all APs finish or TimeoutInMicroSeconds expires. If it’s not NULL, then execute in non-blocking mode. BSP requests the function specified by Procedure to be started on all the enabled APs, and go on executing immediately. If all return from Procedure or TimeoutInMicroSeconds expires, this event is signaled. The BSP can use the CheckEvent() or WaitForEvent() services to check the state of event.
You did set the 2 parameters for StartupAllAPs correctly - SingleThread, WaitEvent - I believe this worked as you wanted (prior commenting it out and recompiling), or even this didn't?
hypervisor-based solutions developer (Intel, AMD)
pietroborrello
Posts: 3
Joined: Wed Nov 24, 2021 3:54 am

Re: UEFI non-blocking StartupThisAP for EFI_MP_SERVICES_PROT

Post by pietroborrello »

Thank you for your reply.
feryno wrote:Something similar was already discussed here:
viewtopic.php?f=1&t=37207&start=5
Unfortunately, I had already looked at the post but did not find the answer to my problem. They are seem not to argue about non-blocking mode not working
feryno wrote: Here a quick manual which could be helpful for you:
https://uefi.org/sites/default/files/re ... Daniel.pdf
I also had already had a look at this manual, and I'm following it, being the same as the documentation.
feryno wrote: You commented out the StartupAllAPs - did it work as you wanted, and only the following StartupThisAP didn't?
No not even StartupAllAPs is working as expected, even setting the SingleThread parameter to TRUE. However, that parameter controls the behaviour of the APs, since I have a single AP (in addition to the BSP, having two cores in total) it does not affect the behaviour. But still tried and didn't work.

What I observe is always the BSP being blocked waiting for the AP to complete, no matter what.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: UEFI non-blocking StartupThisAP for EFI_MP_SERVICES_PROT

Post by Octocontrabass »

pietroborrello wrote:The platform is an x86-64 Intel CPU with two cores, two threads, with no hyperthreading support.
Have you tried your code anywhere else? This could be a firmware bug.
feryno
Member
Member
Posts: 73
Joined: Thu Feb 09, 2012 6:53 am
Location: Czechoslovakia
Contact:

Re: UEFI non-blocking StartupThisAP for EFI_MP_SERVICES_PROT

Post by feryno »

yes, you filled everything properly, this problem is a mystery, maybe your uefi firmware is quite old, maybe around the time when MP support was added into uefi
hypervisor-based solutions developer (Intel, AMD)
pietroborrello
Posts: 3
Joined: Wed Nov 24, 2021 3:54 am

Re: UEFI non-blocking StartupThisAP for EFI_MP_SERVICES_PROT

Post by pietroborrello »

Thank you for your replies!
Yes, I'm on an old version (2017 American Megatrends with EFI specification revision 2.50 [revision 5.12]) but unfortunately, this is the exact version that I need.
I'll try to test on different systems to see if this is a firmware bug.
Post Reply