Ulrich Weigand wrote:
> Hmmm. It seems we have again a guest flags vs. monitor flags
> problem here (remember the discussion about the trap flag?).
Initially, it's not important to emulate VIF/VIP
functionality, as most OSes don't use it anyway.
We could always think about this later on if needed.
> As with the TF, we can for now gloss over that distinction
> in the case of the VIF/VIP, but definitely *not* in the case
> of the IF; for example, you have added this piece of code:
>
> + /* Copy eflags.vif to eflags.if; iret will restore it later */
> + if (context->eflags & (1<<19))
> + context->eflags |= (1<<9);
> + else
> + context->eflags &= ~(1<<9);
>
> which means that you sometimes execute guest code with *IF clear*!
Uh, hang on... I think you misunderstood my code,
or else I'm being *very* confused. context->eflags
are the flags that will be *pushed onto the stack*.
new_eflags are the real eflags to be set; at this
point, context->eflags will never be loaded (check
later on in the function, it'll say
context->eflags = new_eflags;
or something similar). The reason I copy VIF to IF
in the stack-image of EFLAGS is that if the host OS
changes the stack-image of the flags, the changes are
reactivated in the monitor on iret. Notice that in
emulate_iret(), I copy IF back to VIF and then *SET*
IF !!! (actually, I don't change IF 'cause IF is always
on. It's the same trick with SAFE_FLAGS as you use
in monitor.c. I just moved SAFE_FLAGS to freemware.h).
So, in fact, IF will never go off. Only in the eflags
stack image it might; that's called 'virtualisation'
;).
> B.t.w. there's another problem with the CLI/STI code: you need to
> check the current guest CPL; if it is greater than the guest IOPL,
> CLI/STI should trap to the guest GPF handler (unless the guest has
> activated PVI if we want to support that ...). But this is probably
> not critical for now.
It's pretty critical, I just forgot it. It's pretty
trivial anyway. However, I couldn't find where the
guest IOPL was emulated... there's no guest_iopl
field in nexus_t !? If you tell me that, I'll add it
and I'll also add it in the iret code (where the
same check is needed; I temporarily hardcoded iopl=0
there for now).
-- Ramon