Am 06.02.2012 11:32, schrieb Avi Kivity: > On 02/03/2012 08:29 PM, Kevin Wolf wrote: >> Task switches can switch between Protected Mode and VM86. The current >> mode must be updated during the task switch emulation so that the new >> segment selectors are interpreted correctly. >> >> In order to let privilege checks succeed, rflags needs to be updated in >> the vcpu struct as this causes a CPL update. >> >> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c >> index 4124a7e..38d5ef3 100644 >> --- a/arch/x86/kvm/svm.c >> +++ b/arch/x86/kvm/svm.c >> @@ -1286,6 +1286,7 @@ static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu) >> static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) >> { >> to_svm(vcpu)->vmcb->save.rflags = rflags; >> + svm_update_cpl(vcpu); >> } > > This can trigger the (cs&3)!=0 && (cr0&1) != 0 problem, right after we > enter protected mode. > > What this code does is slave the cpl to other x86 state (copying vmx), > whereas in reality it is separate state (with independent existence from > the mov cr0 instruction until the next far jump...). Yes, as discussed in v2, eventually we'll want to call set_cpl() rather than set_rflags() during the task switch (I left a TODO comment there). Then the not quite correct update in svm_set_rflags can be removed again. > We can fix this with > > if ((save.rflags ^ rflags) & EFLAGS_VM) > svm_update_cpl(vcpu) > > but that leaves us with an unupdated cpl after live migration (well, it > will update after loading segment registers). Both are bad, but I think > my version is less bad - live migration is broken anyway in this window, > since we don't save the cpl. Right, it just leaves broken what is already broken. If the rest of the series is okay now, I'll resend with a check if rflags.VM has changed. Kevin -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html