[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] VM_EVENT_FLAG_SET_REGISTERS and sync_vcpu_execstate()



On 08/08/2016 03:47 PM, Razvan Cojocaru wrote:
> On 08/08/2016 03:01 PM, Andrew Cooper wrote:
>> On 08/08/16 11:31, Razvan Cojocaru wrote:
>>> Hello,
>>>
>>> We've been mostly setting registers by using xc_vcpu_setcontext():
>>>
>>> https://github.com/razvan-cojocaru/libbdvmi/blob/master/src/bdvmixendriver.cpp#L504
>>>
>>> but lately trying to push as much of that as possible to the
>>> VM_EVENT_FLAG_SET_REGISTERS-related code (i.e. via the vm_event replies)
>>> to save processing time.
>>>
>>> So with the xc_vcpu_setcontext() call removed, I've found that there are
>>> cases where vm_event_set_registers() won't work properly unless I kept
>>> the xc_vcpu_getcontext() call. This would appear to be not because of
>>> anything that arch_get_info_guest() does (please see the implementation
>>> for XEN_DOMCTL_getvcpucontext), but because of the vcpu_pause() call, or
>>> more specifically, because of its calling sync_vcpu_execstate().
>>>
>>> So it would appear that a sync_vcpu_execstate(v) call is necessary at
>>> the start of vm_event_set_registers() for the vcpu struct instance to be
>>> synchronized with the current VCPU state.
>>>
>>> Any objections to a patch with this simple modification?
>>
>> It would be helpful to identify exactly what is currently going wrong,
>> and why sync_vcpu_execstate(v) helps.
> 
> I've placed a
> 
> printk("EIP: 0x%016lx, 0x%016lx\n", v->arch.user_regs.eip,
> rsp->data.regs.x86.rip);
> 
> at the top of vm_event_set_registers(), so I could see what the old
> value is (v->arch.user_regs.eip) vs. the new value (rsp->data.regs.x86.rip).
> 
> I'm also logging these in my application, the difference there being
> that the old value is the value that came with the vm_event request,
> which has been obtained with guest_cpu_user_regs()->eip (where in
> vm_event_set_registers() we set v->arch.user_regs.eip, since v != current).
> 
> Here's a short test run, with xl dmesg:
> 
> (XEN) [  395.739543] EIP: 0xfffff80001be5957, 0xfffff80001be595b
> (XEN) [  409.795311] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  416.675023] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  421.475567] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  428.275125] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  435.507009] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  441.318224] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  445.514807] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  452.539190] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  454.762810] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  459.538651] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  462.027222] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  481.770470] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  483.298493] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  486.522344] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  491.042325] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  494.874468] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  497.450765] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  500.562738] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  509.179754] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  510.826236] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  512.106206] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  518.658092] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  520.450156] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  521.882088] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  523.250092] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  524.577987] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  525.962042] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  527.353942] EIP: 0xfffff80001be4812, 0xfffff80001be4812
> (XEN) [  528.714089] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  530.065994] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  531.357762] EIP: 0xfffff80001be4812, 0xfffff80001be4812
> (XEN) [  532.594016] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  533.849886] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  535.145879] EIP: 0xfffff80001be4812, 0xfffff80001be4812
> (XEN) [  536.546846] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  537.905756] EIP: 0xfffff80001be480f, 0xfffff80001be4812
> (XEN) [  539.209454] EIP: 0xfffff80001be4812, 0xfffff80001be4812
> 
> and the corresponding part in the userspace application's log:
> 
> GET EIP: 0xfffff80001be5957 SET EIP: 0xfffff80001be595b
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> GET EIP: 0xfffff80001be480f SET EIP: 0xfffff80001be4812
> 
> As you can see, they're different (and correct in the application log),
> but (for example for the last one) they both already have the same value
> in the hypervisor. So it would appear that guest_cpu_user_regs()->eip !=
> v->arch.user_regs.eip at that point (and likely even more state than
> that differs there).
> 
> These are EPT fault events, all of them, and I just reply with
> VM_EVENT_FLAG_SET_REGISTERS to them here, and nothing else.

I think the issue might be that vm_event_vcpu_pause() uses
vcpu_pause_nosync(), and it's being used everywhere we pause the VCPU in
the course of sending out a vm_event.

So this creates the premise for a race condition: either some more
things happen between sending out the vm_event and replying to it that
cause v->arch.user_regs to be synchronized - in which case everything
works (this has been the case when I was reading the VCPU context via a
domctl that did vcpu_pause()) -, or not, in which case all bets are off.

In this case, we should either drop vm_event_vcpu_pause() completely and
just use vcpu_pause() everywhere, modify it to use vcpu_sleep_sync()
(and basically turn it into vcpu_pause()), or only sync in
vm_event_set_registers() as I've suggested.


Thanks,
Razvan

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.