public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@web.de>
To: Avi Kivity <avi@qumranet.com>
Cc: "Nakajima, Jun" <jun.nakajima@intel.com>,
	kvm-devel <kvm@vger.kernel.org>,
	Mohammed Gamal <m.gamal005@gmail.com>,
	Anthony Liguori <anthony@codemonkey.ws>,
	Rik van Riel <riel@surriel.com>
Subject: Re: [PATCH 2/2] VMX: Reinject real mode exception
Date: Mon, 14 Jul 2008 12:28:51 +0200	[thread overview]
Message-ID: <487B2A63.5000802@web.de> (raw)
In-Reply-To: <487B24A1.3090309@qumranet.com>

Avi Kivity wrote:
> Nakajima, Jun wrote:
>> On 7/13/2008 8:31:44 AM, Avi Kivity wrote:
>>  
>>> Avi Kivity wrote:
>>>    
>>>> Well, xen and bochs do not push an error code for real mode #GP.  I
>>>> tried running the attached test program but it doesn't work on real
>>>> hardware (it does work on bochs).
>>>>
>>>>       
>>> Jun, perhaps you can clarify? do #GP exceptions in real-mode push an
>>> error code?
>>>     
>>
>> Avi,
>>
>> Exceptions in real-mode do not push an error code in the stack. 
> 
> Thanks.  You might consider updating the documentation, for example #DF
> states that an error code of 0 is always pushed.
> 
>> In vm86 mode #GP exceptions push an error code, triggering a
>> protected-mode handler in the monitor, as you know. Is it possible
>> that the guest is actually using vm86 mode?
>>   
> 
> No, it's a real mode guest.  It's emulated using vm86, of course, but it
> thinks it's in real mode.  The question was, when we inject a #GP, #SS,
> or #DF  exception, should we also inject an error code, and according to
> your clarification, the answer is no.

Meanwhile I found a clearer statement in the spec as well in chapter
15.1.4: "Exceptions do not return error codes in real-address mode." So
here is the update:

-----------

As we execute real mode guests in VM86 mode, exception have to be
reinjected appropriately when the guest triggered them. For this purpose
the patch adopts the real-mode injection pattern used in vmx_inject_irq
to vmx_queue_exception, additionally taking care that the IP is set
correctly for #BP exceptions. Furthermore it extends
handle_rmode_exception to reinject all those exceptions that can be
raised in real mode.

This fixes the execution of himem.exe from FreeDOS and also makes its
debug.com work properly.

Note that guest debugging in real mode is broken now. This has to be
fixed by the scheduled debugging infrastructure rework (will be done
once base patches for QEMU have been accepted).

Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
---
 arch/x86/kvm/vmx.c         |   41 +++++++++++++++++++++++++++++++++++++++--
 include/asm-x86/kvm_host.h |    4 ++++
 2 files changed, 43 insertions(+), 2 deletions(-)

Index: b/arch/x86/kvm/vmx.c
===================================================================
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -735,12 +735,30 @@ static void skip_emulated_instruction(st
 static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
 				bool has_error_code, u32 error_code)
 {
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+
+	if (has_error_code)
+		vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
+
+	if (vcpu->arch.rmode.active) {
+		vmx->rmode.irq.pending = true;
+		vmx->rmode.irq.vector = nr;
+		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
+		if (nr == BP_VECTOR)
+			vmx->rmode.irq.rip++;
+		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
+			     nr | INTR_TYPE_SOFT_INTR
+			     | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0)
+			     | INTR_INFO_VALID_MASK);
+		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
+		kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
+		return;
+	}
+
 	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
 		     nr | INTR_TYPE_EXCEPTION
 		     | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0)
 		     | INTR_INFO_VALID_MASK);
-	if (has_error_code)
-		vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
 }
 
 static bool vmx_exception_injected(struct kvm_vcpu *vcpu)
@@ -2231,6 +2249,25 @@ static int handle_rmode_exception(struct
 	if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0)
 		if (emulate_instruction(vcpu, NULL, 0, 0, 0) == EMULATE_DONE)
 			return 1;
+	/*
+	 * Forward all other exceptions that are valid in real mode.
+	 * FIXME: Breaks guest debugging in real mode, needs to be fixed with
+	 *        the required debugging infrastructure rework.
+	 */
+	switch (vec) {
+	case DE_VECTOR:
+	case DB_VECTOR:
+	case BP_VECTOR:
+	case OF_VECTOR:
+	case BR_VECTOR:
+	case UD_VECTOR:
+	case DF_VECTOR:
+	case SS_VECTOR:
+	case GP_VECTOR:
+	case MF_VECTOR:
+		kvm_queue_exception(vcpu, vec);
+		return 1;
+	}
 	return 0;
 }
 
Index: b/include/asm-x86/kvm_host.h
===================================================================
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -57,6 +57,9 @@
 
 #define DE_VECTOR 0
 #define DB_VECTOR 1
+#define BP_VECTOR 3
+#define OF_VECTOR 4
+#define BR_VECTOR 5
 #define UD_VECTOR 6
 #define NM_VECTOR 7
 #define DF_VECTOR 8
@@ -65,6 +68,7 @@
 #define SS_VECTOR 12
 #define GP_VECTOR 13
 #define PF_VECTOR 14
+#define MF_VECTOR 16
 #define MC_VECTOR 18
 
 #define SELECTOR_TI_MASK (1 << 2)

  reply	other threads:[~2008-07-14 10:28 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-13 11:40 [PATCH 2/2] VMX: Reinject real mode exception Jan Kiszka
2008-07-13 12:06 ` Avi Kivity
2008-07-13 12:27   ` Jan Kiszka
2008-07-13 15:28     ` Avi Kivity
2008-07-13 15:31       ` Avi Kivity
2008-07-13 18:47         ` Nakajima, Jun
2008-07-13 19:22           ` Mohammed Gamal
2008-07-14 10:04           ` Avi Kivity
2008-07-14 10:28             ` Jan Kiszka [this message]
2008-07-14 11:30               ` Avi Kivity
2008-07-14 16:00             ` Nakajima, Jun

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=487B2A63.5000802@web.de \
    --to=jan.kiszka@web.de \
    --cc=anthony@codemonkey.ws \
    --cc=avi@qumranet.com \
    --cc=jun.nakajima@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=m.gamal005@gmail.com \
    --cc=riel@surriel.com \
    /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