qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Li Qiang <liq3ea@gmail.com>, Qemu Developers <qemu-devel@nongnu.org>
Subject: Re: Questions about the real mode in kvm/qemu
Date: Thu, 26 Sep 2019 11:15:25 +0200	[thread overview]
Message-ID: <b24f9938-d0a7-2680-0078-c02e1abebc59@redhat.com> (raw)
In-Reply-To: <CAKXe6SJfZt8WcA43Vsh0=GT=jBedcAOUx9DNGZ4Bsvi10oCkog@mail.gmail.com>

On 26/09/19 09:52, Li Qiang wrote:
> Hi Paolo and all,
> 
> There are some question about the emulation for real mode in kvm/qemu.
> For all the 
> question I suppose the 'unstrict guest' is not enabled. 
> 
> 1. how the protected mode CPU emulate the real mode? It seems it uses
> vm86, however, vm86 is not available in x86_64 CPU? So what's the
> 'to_vmx(vcpu)->rmode.vm86_active' here vm86 means?

vm86 mode is available in 64-bit CPUs; it is not available in 64-bit
mode (EFER.LMA=1).

Once KVM places the processor in VMX non-root mode (VMLAUNCH/VMRESUME),
the processor can leave 64-bit mode and run in vm86 mode.  And that's
exactly what KVM does on processors without unrestricted guest support.

In that mode, KVM will start trapping all exceptions and send them to
handle_rmode_exception.  This in turn will either emulate privileged
instructions (for #GP or #SS) or inject them as realmode exceptions.

However...

> 2. Does the guest's real mode code run directly in native CPU? It seems
> 'vmx->emulation_required' is also be false, it the vmx_vcpu_run will do
> a switch to guest.

... as soon as the guest tries to enter protected mode, it will get into
a situation which is not real mode but doesn't have the segment
registers properly loaded with selectors.  Therefore, it will either
hack things together (enter_pmode) or emulate instructions until the
state is accepted even without unrestricted guest support.

The "hacking things together" part however does not work for big real
mode (where you enter 32-bit mode, load segment registers with a flat 4G
segment, and go back to real mode with the 4G segments).  In big real
mode, therefore, KVM cannot use vm86 and will keep emulating (slowly -
up to 1000x slower than unrestricted guest).

> 3. How the EPT work in guest real mode? The EPT is for GVA->GPA->HPA,
> however there is no GVA, seems the identity mapping does something. But
> there also some confusion for me. For example the real mode uses CS*4 +
> IP to address the code.  Who does this calculation? In the kernel emulator? 

Right, and in fact the CR0.PG and CR0.PE bits must be 1 when running in
VMX non-root mode with unrestricted guest disabled.

Therefore, KVM places a 4 KiB identity map at an address provided by
userspace (with KVM_SET_IDENTITY_MAP_ADDR).  When 1) EPT is enabled 2)
unrestricted guest isn't 3) CR0.PG=0, KVM points CR3 to it and runs the
guest with CR0.PG=1, CR4.PAE=0, CR4.PSE=1.  This CR4 setup enables 4 MiB
huge pages so that a 4 GiB identity map fits in 4 KiB.  This is the only
case where EPT is enabled but CR3 loads and stores will trap to the
hypervisor.  This way, the guest CR3 value is faked in the vmexit
handler, but the processor always uses the identity GVA->GPA mapping.

Paolo



  parent reply	other threads:[~2019-09-26  9:16 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-26  7:52 Questions about the real mode in kvm/qemu Li Qiang
2019-09-26  8:31 ` Maxim Levitsky
2019-09-26  8:52   ` Li Qiang
2019-09-26  8:59     ` Maxim Levitsky
2019-09-26  9:18       ` Paolo Bonzini
2019-09-26  9:24         ` Maxim Levitsky
2019-09-26  9:33           ` Paolo Bonzini
2019-09-26  9:41             ` Maxim Levitsky
2019-09-26 10:00               ` Paolo Bonzini
2019-09-26 10:03                 ` Maxim Levitsky
2019-09-28 22:10         ` Avi Kivity
2019-09-29  7:39         ` Li Qiang
2019-09-26  9:15 ` Paolo Bonzini [this message]
2019-09-26  9:35   ` Maxim Levitsky
2019-09-26  9:35   ` Li Qiang
2019-09-26  9:53     ` Paolo Bonzini
2019-09-26 11:47       ` Li Qiang

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=b24f9938-d0a7-2680-0078-c02e1abebc59@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=liq3ea@gmail.com \
    --cc=qemu-devel@nongnu.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).