mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-26 19:51:35 +01:00
wfe_ldrex_strex.cpp
This commit is contained in:
16
README.adoc
16
README.adoc
@@ -18634,8 +18634,6 @@ However, likely no implementation likely does (TODO confirm), since:
|
|||||||
|
|
||||||
and power consumption is key in ARM applications.
|
and power consumption is key in ARM applications.
|
||||||
|
|
||||||
SEV is not the only thing that can wake up a WFE, it is only an explicit software way to do it. Notably, global monitor operations on memory accesses of regions marked by LDAXR and STLXR instructions can also wake up a WFE sleeping core. This is done to allow spinlocks opens to automatically wake up WFE sleeping cores at free time without the need for a explicit SEV.
|
|
||||||
|
|
||||||
Quotes for the above <<armarm8-db>> G1.18.1 "Wait For Event and Send Event":
|
Quotes for the above <<armarm8-db>> G1.18.1 "Wait For Event and Send Event":
|
||||||
|
|
||||||
____
|
____
|
||||||
@@ -18693,6 +18691,20 @@ The following Raspberry Pi bibliography helped us get this sample up and running
|
|||||||
|
|
||||||
For how userland spinlocks and mutexes are implemented see <<userland-mutex-implementation>>.
|
For how userland spinlocks and mutexes are implemented see <<userland-mutex-implementation>>.
|
||||||
|
|
||||||
|
====== ARM WFE global monitor events
|
||||||
|
|
||||||
|
link:userland/arch/aarch64/inline_asm/wfe_ldxr_stxr.cpp[]
|
||||||
|
|
||||||
|
SEV is not the only thing that can wake up a WFE, it is only an explicit software way to do it.
|
||||||
|
|
||||||
|
Notably, global monitor operations on memory accesses of regions marked by <<arm-ldxr-and-stxr-instructions,LDAXR and STLXR instructions>> can also wake up a WFE sleeping core.
|
||||||
|
|
||||||
|
This is done to allow spinlocks opens to automatically wake up WFE sleeping cores at free time without the need for a explicit SEV.
|
||||||
|
|
||||||
|
In the shown in the `wfe_ldrex_strex.cpp` example, which can only terminate in gem5 user mode simulation because due to this event.
|
||||||
|
|
||||||
|
Note that that program still terminates when running on top of the Linux kernel as explained at: <<wfe-from-userland>>.
|
||||||
|
|
||||||
====== WFE from userland
|
====== WFE from userland
|
||||||
|
|
||||||
WFE and SEV are usable from userland, and are part of an efficient spinlock implementation (which userland should arguably stay away from and rather use the <<futex-system-call>> which allow for non busy sleep instead), which maybe is not something that userland should ever tho and just stick to mutexes?
|
WFE and SEV are usable from userland, and are part of an efficient spinlock implementation (which userland should arguably stay away from and rather use the <<futex-system-call>> which allow for non busy sleep instead), which maybe is not something that userland should ever tho and just stick to mutexes?
|
||||||
|
|||||||
35
userland/arch/aarch64/inline_asm/wfe_ldxr_stxr.cpp
Normal file
35
userland/arch/aarch64/inline_asm/wfe_ldxr_stxr.cpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// https://cirosantilli.com/linux-kernel-module-cheat#arm-wfe-global-monitor-events
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
#include <atomic>
|
||||||
|
#include <iostream>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include <lkmc/futex.h>
|
||||||
|
|
||||||
|
std::atomic_ulong done;
|
||||||
|
int futex = 1;
|
||||||
|
|
||||||
|
void myfunc() {
|
||||||
|
__asm__ __volatile__ ("ldxr x0, [%0];wfe;wfe" : : "r" (&futex) : "x0");
|
||||||
|
done.store(futex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
bool do_sev = true;
|
||||||
|
if (argc > 1) {
|
||||||
|
do_sev = (argv[1][0] != '0');
|
||||||
|
}
|
||||||
|
done.store(0);
|
||||||
|
std::thread thread;
|
||||||
|
thread = std::thread(myfunc);
|
||||||
|
while (!done.load()) {
|
||||||
|
if (do_sev) {
|
||||||
|
__asm__ __volatile__ ("mov x0, 1;stxr w1, x0, [%0]" : : "r" (&futex) : "x0", "x1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user