• Marc Zyngier's avatar
    KVM: arm/arm64: Close VMID generation race · f0cf47d9
    Marc Zyngier authored
    Before entering the guest, we check whether our VMID is still
    part of the current generation. In order to avoid taking a lock,
    we start with checking that the generation is still current, and
    only if not current do we take the lock, recheck, and update the
    generation and VMID.
    
    This leaves open a small race: A vcpu can bump up the global
    generation number as well as the VM's, but has not updated
    the VMID itself yet.
    
    At that point another vcpu from the same VM comes in, checks
    the generation (and finds it not needing anything), and jumps
    into the guest. At this point, we end-up with two vcpus belonging
    to the same VM running with two different VMIDs. Eventually, the
    VMID used by the second vcpu will get reassigned, and things will
    really go wrong...
    
    A simple solution would be to drop this initial check, and always take
    the lock. This is likely to cause performance issues. A middle ground
    is to convert the spinlock to a rwlock, and only take the read lock
    on the fast path. If the check fails at that point, drop it and
    acquire the write lock, rechecking the condition.
    
    This ensures that the above scenario doesn't occur.
    
    Cc: stable@vger.kernel.org
    Reported-by: default avatarMark Rutland <mark.rutland@arm.com>
    Tested-by: default avatarShannon Zhao <zhaoshenglong@huawei.com>
    Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
    f0cf47d9
arm.c 35.4 KB