Wow. This is interesting.
Mutex objects have shared variables which are atomically updated, and based on the updated value (i.e., lock = 1 means the lock is already acquired, while a successful atomic operation acquires it with acquired semantics). So, this bug happens because while the atomic update is still in progress and its result is not yet known, the core speculatively assumes the lock will be acquired and starts executing the critical section. It may speculatively read or compute the values inside the critical section, leaving microarchitectural side effects (like cache changes), even though the execution is later rolled back if the lock acquisition actually fails.