kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marcelo Tosatti <mtosatti@redhat.com>
To: Gleb Natapov <gleb@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 01:07:13 -0200	[thread overview]
Message-ID: <20121212030713.GA16656@amt.cnet> (raw)
In-Reply-To: <1355231653-18357-5-git-send-email-gleb@redhat.com>

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

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    



  reply	other threads:[~2012-12-12  4:27 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 [this message]
2012-12-12 17:14     ` Gleb Natapov

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=20121212030713.GA16656@amt.cnet \
    --to=mtosatti@redhat.com \
    --cc=gleb@redhat.com \
    --cc=kvm@vger.kernel.org \
    /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).