kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Gleb Natapov <gleb@redhat.com>
To: Marcelo Tosatti <mtosatti@redhat.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH 4/4] KVM: VMX: return correct segment limit and flags for CS/SS registers in real mode
Date: Wed, 12 Dec 2012 19:14:07 +0200	[thread overview]
Message-ID: <20121212171407.GS11016@redhat.com> (raw)
In-Reply-To: <20121212030713.GA16656@amt.cnet>

On Wed, Dec 12, 2012 at 01:07:13AM -0200, Marcelo Tosatti wrote:
> On Tue, Dec 11, 2012 at 03:14:13PM +0200, Gleb Natapov wrote:
> > VMX without unrestricted mode cannot virtualize real mode, so if
> > emulate_invalid_guest_state=0 kvm uses vm86 mode to approximate
> > it. Sometimes, when guest moves from protected mode to real mode, it
> > leaves segment descriptors in a state not suitable for use by vm86 mode
> > virtualization, so we keep shadow copy of segment descriptors for internal
> > use and load fake register to VMCS for guest entry to succeed. Till
> > now we kept shadow for all segments except SS and CS (for SS and CS we
> > returned parameters directly from VMCS), but since commit a5625189f6810
> > emulator enforces segment limits in real mode. This causes #GP during move
> > from protected mode to real mode when emulator fetches first instruction
> > after moving to real mode since it uses incorrect CS base and limit to
> > linearize the %rip. Fix by keeping shadow for SS and CS too.
> > 
> > Signed-off-by: Gleb Natapov <gleb@redhat.com>
> > ---
> >  arch/x86/kvm/vmx.c |    7 +++----
> >  1 file changed, 3 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > index cf11c40..44b0a94 100644
> > --- a/arch/x86/kvm/vmx.c
> > +++ b/arch/x86/kvm/vmx.c
> > @@ -2799,6 +2799,8 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
> >  	vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_DS], VCPU_SREG_DS);
> >  	vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_FS], VCPU_SREG_FS);
> >  	vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_GS], VCPU_SREG_GS);
> > +	vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_SS], VCPU_SREG_SS);
> > +	vmx_get_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_CS], VCPU_SREG_CS);
> >  
> >  	vmx->emulation_required = 1;
> >  	vmx->rmode.vm86_active = 1;
> > @@ -3114,10 +3116,7 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
> >  	struct vcpu_vmx *vmx = to_vmx(vcpu);
> >  	u32 ar;
> >  
> > -	if (vmx->rmode.vm86_active
> > -	    && (seg == VCPU_SREG_TR || seg == VCPU_SREG_ES
> > -		|| seg == VCPU_SREG_DS || seg == VCPU_SREG_FS
> > -		|| seg == VCPU_SREG_GS)) {
> > +	if (vmx->rmode.vm86_active && seg != VCPU_SREG_LDTR) {
> >  		*var = vmx->rmode.segs[seg];
> >  		if (seg == VCPU_SREG_TR
> >  		    || var->selector == vmx_read_guest_seg_selector(vmx, seg))
> 
> Fedora 8 32 fails with
> 
Now we emulate to much. Just sent another series that should address
that. But ultimately, the more correct we want vmx in real mode
be the more we need to emulate :(

> KVM internal error. Suberror: 1
> emulation failure
> EAX=00001c0d EBX=0000c008 ECX=00000005 EDX=00000000
> ESI=00009f75 EDI=00000000 EBP=00007ba6 ESP=00007ba0
> EIP=00009775 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
> ES =0000 00000000 0000ffff 00009300
> CS =0000 00000000 0000ffff 00009b00
> SS =0000 00000000 0000ffff 00009300
> DS =0000 00000000 0000ffff 00009300
> FS =0000 00000000 0000ffff 00009300
> GS =0000 00000000 0000ffff 00009300
> LDT=0000 00000000 0000ffff 00008200
> TR =0000 00000000 0000ffff 00008b00
> GDT=     00004810 0000002f
> IDT=     00000000 0000ffff
> CR0=00000012 CR2=00000000 CR3=00000000 CR4=00000000
> DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000
> DR3=0000000000000000 
> DR6=00000000ffff0ff0 DR7=0000000000000400
> EFER=0000000000000000
> Code=d3 ec c3 b4 10 cd 16 3c e0 75 02 30 c0 20 c0 74 04 bb 08 c0 <d7> c3
> bf 04 b4 e8 42 fd c6 45 ff 00 c3 bf 08 bc e8 37 fd 81 ef 09 bc 89 3e fa
> 9f c3 bf 08
> 
> QEMU 1.2.50 monitor - type 'help' for more information
> (qemu) x /20i 0x00009775 
> 0x0000000000009775:  xlat   %ds:(%bx)
> 0x0000000000009776:  ret    
> 

--
			Gleb.

      reply	other threads:[~2012-12-12 17:14 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-11 13:14 [PATCH 0/4] VMX: Fix emulate_invalid_guest_state=0 Gleb Natapov
2012-12-11 13:14 ` [PATCH 1/4] KVM: VMX: fix DPL during entry to protected mode Gleb Natapov
2012-12-11 13:14 ` [PATCH 2/4] VMX: remove unneeded enable_unrestricted_guest check Gleb Natapov
2012-12-11 13:14 ` [PATCH 3/4] KVM: emulator: fix real mode segment checks in address linearization Gleb Natapov
2012-12-11 13:14 ` [PATCH 4/4] KVM: VMX: return correct segment limit and flags for CS/SS registers in real mode Gleb Natapov
2012-12-12  3:07   ` Marcelo Tosatti
2012-12-12 17:14     ` Gleb Natapov [this message]

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=20121212171407.GS11016@redhat.com \
    --to=gleb@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mtosatti@redhat.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;
as well as URLs for NNTP newsgroup(s).