]> git.proxmox.com Git - mirror_qemu.git/commit
KVM: use store-release to mark dirty pages as harvested
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 2 Sep 2022 00:15:34 +0000 (02:15 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Sun, 18 Sep 2022 07:17:40 +0000 (09:17 +0200)
commit52281c6d11ec68b802e8a264780df2c4b981e6bc
tree8ad61871e6a253b45f4e085da094787c75a75e18
parentd29201ff34a135cdfc197f4413c1c5047e4f58bb
KVM: use store-release to mark dirty pages as harvested

The following scenario can happen if QEMU sets more RESET flags while
the KVM_RESET_DIRTY_RINGS ioctl is ongoing on another host CPU:

    CPU0                     CPU1               CPU2
    ------------------------ ------------------ ------------------------
                                                fill gfn0
                                                store-rel flags for gfn0
                                                fill gfn1
                                                store-rel flags for gfn1
    load-acq flags for gfn0
    set RESET for gfn0
    load-acq flags for gfn1
    set RESET for gfn1
    do ioctl! ----------->
                             ioctl(RESET_RINGS)
                                                fill gfn2
                                                store-rel flags for gfn2
    load-acq flags for gfn2
    set RESET for gfn2
                             process gfn0
                             process gfn1
                             process gfn2
    do ioctl!
    etc.

The three load-acquire in CPU0 synchronize with the three store-release
in CPU2, but CPU0 and CPU1 are only synchronized up to gfn1 and CPU1
may miss gfn2's fields other than flags.

The kernel must be able to cope with invalid values of the fields, and
userspace *will* invoke the ioctl once more.  However, once the RESET flag
is cleared on gfn2, it is lost forever, therefore in the above scenario
CPU1 must read the correct value of gfn2's fields.

Therefore RESET must be set with a store-release, that will synchronize
with KVM's load-acquire in CPU1.

Cc: Gavin Shan <gshan@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
accel/kvm/kvm-all.c