From: Anthony Liguori <anthony@codemonkey.ws>
To: "Martin Kejík" <kejda@centrum.cz>
Cc: kvm@vger.kernel.org
Subject: Re: kvm + kqemu enabled at the same time
Date: Tue, 28 Oct 2008 17:06:48 -0500 [thread overview]
Message-ID: <49078CF8.9070704@codemonkey.ws> (raw)
In-Reply-To: <200810282220.59240.kejda@centrum.cz>
Martin Kejík wrote:
> Hello,
> I've compiled the KVM enabled QEMU with support for both KVM and KQEMU. Both modules loaded and
> QEMU running saying "kvm: enabled" and "kqemu: enabled for user code".
>
> How does this work?? What does QEMU really do in this situation when we look closer to CPU??
>
You're using both accelerators at the same time and getting 2x
acceleration. It will actually go faster than native now :-)
Seriously, it's working based on sheer luck. If you look at the
cpu_exec() loop (which is the core execution loop in QEMU, you'll see):
> #ifdef USE_KQEMU
> if (kqemu_is_ok(env) && env->interrupt_request == 0) {
> int ret;
> env->eflags = env->eflags |
> cc_table[CC_OP].compute_all() | (DF & DF_MASK);
> ret = kqemu_cpu_exec(env);
> /* put eflags in CPU temporary format */
> CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A |
> CC_P | CC_C);
> DF = 1 - (2 * ((env->eflags >> 10) & 1));
> CC_OP = CC_OP_EFLAGS;
> env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A |
> CC_P | CC_C);
> if (ret == 1) {
> /* exception */
> longjmp(env->jmp_env, 1);
> } else if (ret == 2) {
> /* softmmu execution needed */
> } else {
> if (env->interrupt_request != 0) {
> /* hardware interrupt will be executed just
> after */
> } else {
> /* otherwise, we restart */
> longjmp(env->jmp_env, 1);
> }
> }
> }
> #endif
>
> if (kvm_enabled()) {
> kvm_cpu_exec(env);
> longjmp(env->jmp_env, 1);
> }
What's letting this work is kqemu_is_ok(env). This check looks like this:
> static inline int kqemu_is_ok(CPUState *env)
> {
> return(env->kqemu_enabled &&
> (env->cr[0] & CR0_PE_MASK) &&
> !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
> (env->eflags & IF_MASK) &&
> !(env->eflags & VM_MASK) &&
> (env->kqemu_enabled == 2 ||
> ((env->hflags & HF_CPL_MASK) == 3 &&
> (env->eflags & IOPL_MASK) != IOPL_MASK)));
> }
This is checking whether you're in protected mode, not in an interrupt
window, interrupts are enabled, you aren't in vm86 mode, and if not
using kernel-kqemu, CPL == 3 and IOPL > CPL.
As an optimization, KVM does not synchronize CPUState very often which
means that env is very stale. This means that it's likely that CPUState
is in the initial CPU state (in real mode).
As long as kqemu never gets to execute, you should be ok. If you force
KVM to sync CPUState, you'll see kqemu actually execute and bad things
will happen.
But the more important question is, why in the world are you doing this
in the first place?
Regards,
Anthony Liguori
> thanx
>
next prev parent reply other threads:[~2008-10-28 22:06 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-28 21:20 kvm + kqemu enabled at the same time Martin Kejík
2008-10-28 22:06 ` Anthony Liguori [this message]
2008-10-29 7:21 ` Avi Kivity
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=49078CF8.9070704@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=kejda@centrum.cz \
--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