On Fri, Sep 02, 2022 at 02:19:36AM +0200, Paolo Bonzini wrote: > 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 <gs...@redhat.com> > Cc: Peter Xu <pet...@redhat.com> > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com>
Reviewed-by: Peter Xu <pet...@redhat.com> Thanks (again)! -- Peter Xu