|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] SVM: re-work VMCB sync-ing
>>> On 27.04.18 at 20:29, <boris.ostrovsky@xxxxxxxxxx> wrote:
> On 04/27/2018 11:52 AM, Jan Beulich wrote:
>>>>> On 26.04.18 at 19:27, <boris.ostrovsky@xxxxxxxxxx> wrote:
>>> On 04/26/2018 11:55 AM, Jan Beulich wrote:
>>>>>>> On 26.04.18 at 17:20, <boris.ostrovsky@xxxxxxxxxx> wrote:
>>>>> On 04/26/2018 09:33 AM, Jan Beulich wrote:
>>>>>>>> -static void svm_sync_vmcb(struct vcpu *v)
>>>>>>>> +static void svm_sync_vmcb(struct vcpu *v, enum vmcb_sync_state
>>>>>>>> new_state)
>>>>>>>> {
>>>>>>>> struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
>>>>>>>>
>>>>>>>> - if ( arch_svm->vmcb_in_sync )
>>>>>>>> - return;
>>>>>>>> -
>>>>>>>> - arch_svm->vmcb_in_sync = 1;
>>>>>>>> + if ( arch_svm->vmcb_sync_state == vmcb_needs_vmsave )
>>>>>>>> + svm_vmsave(arch_svm->vmcb);
>>>>>>>>
>>>>>>>> - svm_vmsave(arch_svm->vmcb);
>>>>>>>> + if ( arch_svm->vmcb_sync_state != vmcb_needs_vmload )
>>>>>>>> + arch_svm->vmcb_sync_state = new_state;
>>>>>>> This is slightly awkward for a couple of reasons. First, passing
>>>>>>> vmcb_in_sync in forget the fact that a vmload is needed.
>>>>>> Certainly not - that's the purpose of the if() around it.
>>>>>>
>>>>>>> In my patch, I introduced svm_sync_vmcb_for_update(), rather than
>>>>>>> requiring a parameter to be passed in. I think this is a better API,
>>>>>>> and it shrinks the size of the patch.
>>>>>> I'm not convinced of the "better", and even less so of the "shrinks". But
>>>>>> I'll wait to see what the SVM maintainers say.
>>>>> I think a single function is better. In fact, I was wondering whether
>>>>> svm_vmload() could also be folded into svm_sync_vmcb() since it is also
>>>>> a syncing operation.
>>>> That doesn't look like it would produce a usable interface: How would
>>>> you envision the state transition to be specified by the caller? Right
>>>> now the intended new state gets passed in, but in your model
>>>> vmcb_in_sync could mean either vmload or vmsave is needed. The
>>>> two svm_vmload() uses right now would pass that value in addition
>>>> to the svm_sync_vmcb() calls already doing so. And the function
>>>> couldn't tell what to do from the current state (if it's
>>>> vmcb_needs_vmload, a load is only needed in the cases where
>>>> svm_vmload() is called right now). Adding a 3rd parameter or a
>>>> second enum
>>> I was thinking about another enum value, e.g. sync_to_cpu (and
>>> sync_to_vmcb replacing vmcb_needs_vmsave).
>>>
>>> This will allow us to hide (v->arch.hvm_svm.vmcb_sync_state ==
>>> vmcb_needs_vmload) test.
>> I'm still not entirely clear how you want that to look like. At the example
>> of svm_get_segment_register() and svm_set_segment_register(), how
>> would the svm_sync_vmcb() calls look like? I.e. how do you distinguish
>> the sync_to_vmcb/transition-to-clean case from the
>> sync_to_vmcb/transition-to-dirty one?
>
>
> Something like
>
> static void svm_sync_vmcb(struct vcpu *v, enum vmcb_sync_state new_state)
> {
> struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
>
>
> if ( new_state == vmcb_sync_to_cpu )
But that's not a state, but a transition. An enum should consist of only
states or only transitions. I'll produce a variant of this as v2, but I'm
afraid you won't be overly happy with it.
Jan
> {
> if (v->arch.hvm_svm.vmcb_sync_state == vmcb_needs_vmload )
> {
> svm_vmload(vmcb);
> v->arch.hvm_svm.vmcb_sync_state = vmcb_in_sync;
> }
> return;
> }
>
> if ( arch_svm->vmcb_sync_state == vmcb_needs_vmsave )
> svm_vmsave(arch_svm->vmcb);
>
> if ( arch_svm->vmcb_sync_state != vmcb_needs_vmload )
> arch_svm->vmcb_sync_state = new_state;
> }
>
>
> -boris
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |