As per the issue, this was detected via failure of the g++.dg/ext/sync-4.C gcc dejaGNU tests when running qemu usermode.
To fix this, we simply need to use the _ra variants inside the llock/scond TCG helpers, and pass the current PC value via GETPC().
An important note is that "env->arconnect.lpa_lf = entry;" is pulled before the relevant load, so it should never be NULL.
However, as the llock/scond variants are guarded with mutex locks, there is a deadlock if we retry any llock/scond after such an exception.
To prevent this, we ask QEMU to run a callback for the relevant exceptions.
QEMU provides .record_sigsegv and .record_sigbus TCGCPUOps for this specific purpose.
In these callbacks, all we need to do is check if there is a lock and respective LF flag, and if so unlock and clear them.
As per issue https://github.com/foss-for-synopsys-dwc-arc-processors/qemu/issues/166, user mode llock load/store exceptions are currently not recoverable, even if there is a proper handler for them.
As per the issue, this was detected via failure of the g++.dg/ext/sync-4.C gcc dejaGNU tests when running qemu usermode.
To fix this, we simply need to use the _ra variants inside the llock/scond TCG helpers, and pass the current PC value via GETPC(). An important note is that "env->arconnect.lpa_lf = entry;" is pulled before the relevant load, so it should never be NULL.
However, as the llock/scond variants are guarded with mutex locks, there is a deadlock if we retry any llock/scond after such an exception.
To prevent this, we ask QEMU to run a callback for the relevant exceptions. QEMU provides .record_sigsegv and .record_sigbus TCGCPUOps for this specific purpose.
In these callbacks, all we need to do is check if there is a lock and respective LF flag, and if so unlock and clear them.