On Sun, Jun 13, 2021, stsp wrote: > Hi kvm developers. > > I am having the strange problem that can only be reproduced on a core2duo CPU > but not AMD FX or Intel Core I7. > > My code has 2 ways of setting the guest registers: one is the guest's ring0 > stub that just pops all regs from stack and does iret to ring3. That works > fine. But sometimes I use KVM_SET_SREGS and resume the VM directly to ring3. > That randomly results in either a good run or invalid guest state return, or > a page fault in guest. Hmm, a core2duo failure is more than likely due to lack of unrestricted guest. You verify this by loading kvm_intel on the Core i7 with unrestricted_guest=0. > I tried to analyze when either of the above happens exactly, and I have a > very strong suspection that the problem is in a way I update LDT. LDT is > shared between guest and host with KVM_SET_USER_MEMORY_REGION, and I modify > it on host. So it seems like if I just allocated the new LDT entry, there is > a risk of invalid guest state, as if the guest's LDT still doesn't have it. > If I modified some LDT entry, there can be a page fault in guest, as if the > entry is still old. IIUC, you are updating the LDT itself, e.g. an FS/GS descriptor in the LDT, as opposed to updating the LDT descriptor in the GDT? Either way, do you also update all relevant segments via KVM_SET_SREGS after modifying memory? Best guess is that KVM doesn't detect that the VM has state that needs to be emulated, or that KVM's internal register state and what's in memory are not consistent. > I've found that the one needs to check KVM_CAP_SYNC_MMU to safely write to > the guest memory, but it doesn't seem to be documented well. Of course maybe > my problem has nothing to do with that, but I think it does. So can it be > that even though I check for the KVM_CAP_SYNC_MMU, writing to the guest > memory from host is still unsafe? What is this KVM_CAP_SYNC_MMU actually all > about? On x86, KVM_CAP_SYNC_MMU means that the primary MMU will notify KVM of any relevant changes. As you surmised, this is needed if userspace is making changes via to mmap()/mprotect()/etc..., but is also used to react to PFN migration, NUMA balancing, etc... Anyways, I highly doubt this is a memory synchronization issue, a corner case related to lack of unrestricted guest is much more likely.