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

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to