Add another undefined instruction handler for compat32 and watch out for
swp/swpb instructions. The atomic swap is done in assembly for simpler
fault handling that we can detect; atomic_fcmpset_{8,32} could have been
used, but it's harder to handle a fault as we have to do an atomic load
of the old value for the compare-and-swap operation. atomic_swap_8 is
easy to implement, but it suffers from the problem that there's no way
to set a fault handler and communicate the error back properly
swp_emulate_atomic just uses ll/sc to make for a simpler implementation.
SWP/SWPB were deprecated in ARMv6 and declared obsolete in ARMv7, but
this implementation is motivated by some proprietary software that still
uses SWP/SWPB. Because it's deprecated, emulation is pushed back behind
a sysctl that defaults to OFF in GENERIC so that it doesn't potentially
adversely affect package builds; it's unknown whether software may test
for a functional swp/swpb instruction with the desire of using it later,
so we err on the side of caution to ensure we don't end up with swp/swpb
use in freebsd/arm packages (which are built on aarch64).
The EMUL_SWP config option may be used to enable emulation by default in
environments where emulation is desired and won't really be turned off.
Sponsored by: Stormshield
Sponsored by: Klara, Inc.