• Marc Zyngier's avatar
    KVM: arm64: Make vcpu flag updates non-preemptible · 35dcb3ac
    Marc Zyngier authored
    Per-vcpu flags are updated using a non-atomic RMW operation.
    Which means it is possible to get preempted between the read and
    write operations.
    
    Another interesting thing to note is that preemption also updates
    flags, as we have some flag manipulation in both the load and put
    operations.
    
    It is thus possible to lose information communicated by either
    load or put, as the preempted flag update will overwrite the flags
    when the thread is resumed. This is specially critical if either
    load or put has stored information which depends on the physical
    CPU the vcpu runs on.
    
    This results in really elusive bugs, and kudos must be given to
    Mostafa for the long hours of debugging, and finally spotting
    the problem.
    
    Fix it by disabling preemption during the RMW operation, which
    ensures that the state stays consistent. Also upgrade vcpu_get_flag
    path to use READ_ONCE() to make sure the field is always atomically
    accessed.
    
    Fixes: e87abb73 ("KVM: arm64: Add helpers to manipulate vcpu flags among a set")
    Reported-by: default avatarMostafa Saleh <smostafa@google.com>
    Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/20230418125737.2327972-1-maz@kernel.orgSigned-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
    35dcb3ac
kvm_host.h 33.5 KB