From: Paolo Bonzini <pbonzini@redhat.com>
To: Roman Penyaev <roman.penyaev@profitbricks.com>
Cc: Mikhail Sennikovskii <mikhail.sennikovskii@profitbricks.com>,
Gleb Natapov <gleb@kernel.org>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC] KVM: SVM: do not drop VMCB CPL to 0 if SS is not present
Date: Tue, 30 May 2017 23:09:20 +0200 [thread overview]
Message-ID: <faa52c86-cea0-4921-5c89-2d863b5b2baa@redhat.com> (raw)
In-Reply-To: <CAJrWOzBjoDvWYu6v-jKEoT+XabsiAU5prpnsk5fYV6V24R0AYA@mail.gmail.com>
On 30/05/2017 19:35, Roman Penyaev wrote:
> On Tue, May 30, 2017 at 4:47 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>
>>
>> On 19/05/2017 18:14, Roman Penyaev wrote:
>>> 2. A bit complicated, which makes sure the CPL field is preserved across
>>> KVM_GET/SET_SREGS calls and makes svm_set_segment() and svm_get_segment()
>>> functionality symmethric:
>>
>> I think I prefer this solution.
>>
>>> KVM SVM side:
>>> -------------
>>>
>>> --- a/arch/x86/kvm/svm.c
>>> +++ b/arch/x86/kvm/svm.c
>>> @@ -1999,7 +1999,7 @@ static void svm_set_segment(struct kvm_vcpu *vcpu,
>>> * would entail passing the CPL to userspace and back.
>>> */
>>> if (seg == VCPU_SREG_SS)
>>> - svm->vmcb->save.cpl = (s->attrib >>
>>> SVM_SELECTOR_DPL_SHIFT) & 3;
>>> + svm->vmcb->save.cpl = (var->dpl & 3);
>>>
>>> mark_dirty(svm->vmcb, VMCB_SEG);
>>> }
>>
>> I wonder why svm_set_segment is setting s->attrib = 0 at all. The
>> manual only mentions checking P=0. What about something like:
>>
>> s->base = var->base;
>> s->limit = var->limit;
>> s->selector = var->selector;
>> s->attrib = (var->type & SVM_SELECTOR_TYPE_MASK);
>> s->attrib |= (var->s & 1) << SVM_SELECTOR_S_SHIFT;
>> s->attrib |= (var->dpl & 3) << SVM_SELECTOR_DPL_SHIFT;
>> s->attrib |= (var->present && !var->unusable) << SVM_SELECTOR_P_SHIFT;
>> s->attrib |= (var->avl & 1) << SVM_SELECTOR_AVL_SHIFT;
>> s->attrib |= (var->l & 1) << SVM_SELECTOR_L_SHIFT;
>> s->attrib |= (var->db & 1) << SVM_SELECTOR_DB_SHIFT;
>> s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT;
>
> Do we care about compatibility issues? I mean can any old qemu send
> us "garbage" in other members of 'var' structure if 'var->unused' == 1 ?
That shouldn't matter, the processor shouldn't use them if P=0.
> Oh, it seems we require one more field in 'struct kvm_segment' for CPL.
Why? The point is exactly to use SS's var->dpl.
>>> QEMU side:
>>> ----------
>>>
>>> --- a/target/i386/kvm.c
>>> +++ b/target/i386/kvm.c
>>> @@ -1979,6 +1979,8 @@ static int kvm_get_sregs(X86CPU *cpu)
>>> get_seg(&env->segs[R_FS], &sregs.fs);
>>> get_seg(&env->segs[R_GS], &sregs.gs);
>>> get_seg(&env->segs[R_SS], &sregs.ss);
>>> + if (sregs.ss.unusable)
>>> + env->segs[R_SS].flags |= sregs.ss.dpl << DESC_DPL_SHIFT;
>>>
>>> get_seg(&env->tr, &sregs.tr);
>>> get_seg(&env->ldt, &sregs.ldt);
>>
>> I think what QEMU should do is, in get_seg
>>
>> if (rhs->unusable) {
>> lhs->flags &= ~DESC_P_MASK;
>>
>> This would preserve the SS.DPL field. This should still work fine with
>> QEMU commit 4cae9c9 (the loading side would set lhs->unusable).
>
> Indeed, it will preserve the *old* SS.DPL field, but will not take the *new*
> one from kvm side. And what if extend get_seg() with additional 'segtype'
> argument:
Or:
lhs->flags = (rhs->type << DESC_TYPE_SHIFT) |
(rhs->present * DESC_P_MASK) |
(rhs->dpl << DESC_DPL_SHIFT) |
(rhs->db << DESC_B_SHIFT) |
(rhs->s * DESC_S_MASK) |
(rhs->l << DESC_L_SHIFT) |
(rhs->g * DESC_G_MASK) |
(rhs->avl * DESC_AVL_MASK);
if (rhs->unusable) {
lhs->flags = 0;
}
which could also be simply
lhs->flags = ... |
((rhs->present && !rhs->unusable) * DESC_P_MASK) | ...;
as in the KVM code.
`
> Then we always keep convention and keep dpl alive along the way U->K->U to
> restore it as cpl.
Yes, exactly.
Paolo
next prev parent reply other threads:[~2017-05-30 21:09 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-19 16:14 Roman Penyaev
2017-05-21 3:31 ` Andy Lutomirski
2017-05-21 7:53 ` Roman Penyaev
2017-05-21 20:19 ` Andy Lutomirski
2017-05-24 19:19 ` Roman Penyaev
2017-05-30 14:47 ` Paolo Bonzini
2017-05-30 17:35 ` Roman Penyaev
2017-05-30 21:09 ` Paolo Bonzini [this message]
2017-05-31 10:17 ` Roman Penyaev
2017-05-31 10:50 ` Paolo Bonzini
2017-05-30 15:13 ` Paolo Bonzini
2017-05-30 15:58 ` Roman Penyaev
2017-05-30 16:05 ` Paolo Bonzini
2017-05-30 16:31 ` Gi-Oh Kim
2017-06-15 21:44 ` Andy Lutomirski
2017-06-16 8:44 ` Roman Penyaev
2017-06-16 16:40 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=faa52c86-cea0-4921-5c89-2d863b5b2baa@redhat.com \
--to=pbonzini@redhat.com \
--cc=gleb@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mikhail.sennikovskii@profitbricks.com \
--cc=roman.penyaev@profitbricks.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®