public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH] emulator: Fix task switch into/out of VM86
@ 2012-01-09 20:10 Kevin Wolf
  2012-01-10  3:08 ` Takuya Yoshikawa
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Kevin Wolf @ 2012-01-09 20:10 UTC (permalink / raw)
  To: kvm; +Cc: kwolf

Not sure if it actually makes sense to send a patch with this as I have
more problems to describe than lines that actually fix something - but
well, this hack at least makes some hardware task switches into/out of
VM86 work for me that failed before.

So what I really intend is to get information on what I need to do to
get this right (alternatively consider this a bug report and do the fix
yourself):

* I have disabled privilege checks for task gates (I need to switch out
  of VM86/ring 3 back into ring 0). This is wrong, they still need to be
  applied for software interrupts, but not for exceptions or IRQs (note
  that the check was wrong anyway, it should check the task gate DPL,
  not the TSS one).

  How do I find out what kind of interrupt caused the task switch? (Hm,
  I guess vmx->idt_vectoring_info could do it for Intel and I would have
  to pass this down into the emulator; for AMD see below)

* May the emulator access the vcpu or should this go through a new
  x86_emulate_ops.set_rflags function pointer?

* This works with VMX, but with SVM I have an additional problem: When
  trying to exit VM86 (usually by an exception) through a task gate in
  the IDT, the code runs into the reason = TASK_SWITCH_CALL path. I
  searched a bit in the documentation, but didn't find any obvious way
  to fix this.

* Yes, I've yet to write a nice testcase for kvm-unittests

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 arch/x86/kvm/emulate.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 05a562b..fdd3cca 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1227,6 +1227,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
 		seg_desc.type = 3;
 		seg_desc.p = 1;
 		seg_desc.s = 1;
+		seg_desc.dpl = 3;
 		goto load;
 	}
 
@@ -2246,6 +2247,9 @@ static void save_state_to_tss32(struct x86_emulate_ctxt *ctxt,
 	tss->ldt_selector = get_segment_selector(ctxt, VCPU_SREG_LDTR);
 }
 
+#define emul_to_vcpu(ctxt) \
+	container_of(ctxt, struct kvm_vcpu, arch.emulate_ctxt)
+
 static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
 				 struct tss_segment_32 *tss)
 {
@@ -2254,7 +2258,14 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
 	if (ctxt->ops->set_cr(ctxt, 3, tss->cr3))
 		return emulate_gp(ctxt, 0);
 	ctxt->_eip = tss->eip;
+
 	ctxt->eflags = tss->eflags | 2;
+	if (ctxt->eflags & 0x20000)
+		ctxt->mode = X86EMUL_MODE_VM86;
+	else
+		ctxt->mode = X86EMUL_MODE_PROT32;
+	kvm_set_rflags(emul_to_vcpu(ctxt), ctxt->eflags);
+
 	ctxt->regs[VCPU_REGS_RAX] = tss->eax;
 	ctxt->regs[VCPU_REGS_RCX] = tss->ecx;
 	ctxt->regs[VCPU_REGS_RDX] = tss->edx;
@@ -2372,7 +2383,7 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
 
 	/* FIXME: check that next_tss_desc is tss */
 
-	if (reason != TASK_SWITCH_IRET) {
+	if (reason != TASK_SWITCH_IRET && reason != TASK_SWITCH_GATE) {
 		if ((tss_selector & 3) > next_tss_desc.dpl ||
 		    ops->cpl(ctxt) > next_tss_desc.dpl)
 			return emulate_gp(ctxt, 0);
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2012-01-16 15:58 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-09 20:10 [RFC PATCH] emulator: Fix task switch into/out of VM86 Kevin Wolf
2012-01-10  3:08 ` Takuya Yoshikawa
2012-01-10  4:07 ` Takuya Yoshikawa
2012-01-10  9:01 ` Gleb Natapov
2012-01-10  9:28   ` Kevin Wolf
2012-01-10 10:17     ` Gleb Natapov
2012-01-10 11:25     ` Kevin Wolf
2012-01-10 11:30       ` Gleb Natapov
2012-01-10 17:51         ` Joerg Roedel
2012-01-16 15:37           ` Kevin Wolf
2012-01-16 15:57             ` Joerg Roedel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox