mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-27 13:00:25 +09:00
Registration of module callbacks for the pKVM hypervisor is lockless
thanks to the use of a cmpxchg.
Problem, a CPU can speculatively execute an indirect branch and
speculatively read variables used in that branch. We then need to order
the memory access between variables potentially set in the driver init
(before the callback registration happen) and the call to that
registered callback.
e.g. in the case of the serial.
CPU0: CPU1:
driver_init(): hyp_serial_enabled()
base_addr = 0xdeadbeef; enabled = __hyp_putc
barrier(); barrier();
ops->register_serial_driver(putc); if (enabled)
__hyp_putc(); /* read base_addr */
This is the same for the SMC and PSCI handler callbacks. The abort and
fault callbacks are not impacted: the driver init can only happen before
the kernel is deprivileged i.e. before the host stage-2 is in place and
then before any of those callbacks can be triggered.
Instead of a full barrier, we can use the acquire/release semantics:
relaxing cmpxchg to cmpxchg_release in the registration path and use a
load_acquire in hyp_serial_enabled().
Bug: 292470326
Change-Id: I4b5fe3713fe40cc5ab42ea0e9cdf54e8315dfb44
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>