public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] VMX: Reinject real mode exception
@ 2008-07-13 11:40 Jan Kiszka
  2008-07-13 12:06 ` Avi Kivity
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Kiszka @ 2008-07-13 11:40 UTC (permalink / raw)
  To: kvm-devel; +Cc: Avi Kivity, Mohammed Gamal, Anthony Liguori, Rik van Riel

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         |   40 ++++++++++++++++++++++++++++++++++++++--
 include/asm-x86/kvm_host.h |    2 ++
 2 files changed, 40 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)
@@ -2234,6 +2252,24 @@ 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, need to be fixed with
+	 *        the required debugging infrastructure rework.
+	 */
+	switch (vec) {
+	case DF_VECTOR:
+	case SS_VECTOR:
+	case GP_VECTOR:
+		kvm_queue_exception_e(vcpu, vec, err_code);
+		return 1;
+		break;
+	case DE_VECTOR ... NM_VECTOR:
+	case MF_VECTOR:
+	case MC_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,7 @@
 
 #define DE_VECTOR 0
 #define DB_VECTOR 1
+#define BP_VECTOR 3
 #define UD_VECTOR 6
 #define NM_VECTOR 7
 #define DF_VECTOR 8
@@ -65,6 +66,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)

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

* Re: [PATCH 2/2] VMX: Reinject real mode exception
  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
  0 siblings, 1 reply; 11+ messages in thread
From: Avi Kivity @ 2008-07-13 12:06 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: kvm-devel, Mohammed Gamal, Anthony Liguori, Rik van Riel

Jan Kiszka wrote:
> 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         |   40 ++++++++++++++++++++++++++++++++++++++--
>  include/asm-x86/kvm_host.h |    2 ++
>  2 files changed, 40 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;
> +	}
> +
>   

It's a little sad that this duplicates vmx_inject_irq.  But we can live 
with it.

>  	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)
> @@ -2234,6 +2252,24 @@ 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, need to be fixed with
> +	 *        the required debugging infrastructure rework.
> +	 */
> +	switch (vec) {
> +	case DF_VECTOR:
> +	case SS_VECTOR:
> +	case GP_VECTOR:
> +		kvm_queue_exception_e(vcpu, vec, err_code);
>   

These don't actually queue an error code in real mode.  Compare the 
'Real-Address Mode Exceptions' section with the 'Protected Mode 
Exceptions' section  for most instructions in the Intel manual.

> +		return 1;
> +		break;
> +	case DE_VECTOR ... NM_VECTOR:
>   

Please spell out explicitly.  Also, NM_VECTOR is used by the host for 
managing the guest fpu, so some NM_VECTORs should not be reflected.  I 
suggest simply dropping NM_VECTOR until this is worked out, as many 
real-mode operating systems don't implement lazy fpu switching.

Also, NMI shouldn't be handled here.

> +	case MF_VECTOR:
> +	case MC_VECTOR:
>   

I don't think #MC should be handled here.  Machine checks have to be 
handled by the host.

> +		kvm_queue_exception(vcpu, vec);
> +		return 1;
> +	}
>  	return 0;
>  }
>  

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 2/2] VMX: Reinject real mode exception
  2008-07-13 12:06 ` Avi Kivity
@ 2008-07-13 12:27   ` Jan Kiszka
  2008-07-13 15:28     ` Avi Kivity
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Kiszka @ 2008-07-13 12:27 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm-devel, Mohammed Gamal, Anthony Liguori, Rik van Riel

Avi Kivity wrote:
> Jan Kiszka wrote:
...
>> @@ -2234,6 +2252,24 @@ 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, need to be fixed with
>> +     *        the required debugging infrastructure rework.
>> +     */
>> +    switch (vec) {
>> +    case DF_VECTOR:
>> +    case SS_VECTOR:
>> +    case GP_VECTOR:
>> +        kvm_queue_exception_e(vcpu, vec, err_code);
>>   
> 
> These don't actually queue an error code in real mode.  Compare the
> 'Real-Address Mode Exceptions' section with the 'Protected Mode
> Exceptions' section  for most instructions in the Intel manual.

Unless you can points out a better reference, I prefer following chapter
5.15 of the System Programming Guide on this. And that one doesn't make
a difference when it says, e.g., "Exception Error Code: Zero. The
processor always pushes an error code of 0 onto the stack of the
doublefault handler."

> 
>> +        return 1;
>> +        break;
>> +    case DE_VECTOR ... NM_VECTOR:
>>   
> 
> Please spell out explicitly.  Also, NM_VECTOR is used by the host for
> managing the guest fpu, so some NM_VECTORs should not be reflected.  I
> suggest simply dropping NM_VECTOR until this is worked out, as many
> real-mode operating systems don't implement lazy fpu switching.

OK.

> 
> Also, NMI shouldn't be handled here.

Yep.

> 
>> +    case MF_VECTOR:
>> +    case MC_VECTOR:
>>   
> 
> I don't think #MC should be handled here.  Machine checks have to be
> handled by the host.

OK, update below.

-------------

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         |   43 +++++++++++++++++++++++++++++++++++++++++--
 include/asm-x86/kvm_host.h |    4 ++++
 2 files changed, 45 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)
@@ -2234,6 +2252,27 @@ 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, need to be fixed with
+	 *        the required debugging infrastructure rework.
+	 */
+	switch (vec) {
+	case DF_VECTOR:
+	case SS_VECTOR:
+	case GP_VECTOR:
+		kvm_queue_exception_e(vcpu, vec, err_code);
+		return 1;
+	case DE_VECTOR:
+	case DB_VECTOR:
+	case BP_VECTOR:
+	case OF_VECTOR:
+	case BR_VECTOR:
+	case UD_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)

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

* Re: [PATCH 2/2] VMX: Reinject real mode exception
  2008-07-13 12:27   ` Jan Kiszka
@ 2008-07-13 15:28     ` Avi Kivity
  2008-07-13 15:31       ` Avi Kivity
  0 siblings, 1 reply; 11+ messages in thread
From: Avi Kivity @ 2008-07-13 15:28 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: kvm-devel, Mohammed Gamal, Anthony Liguori, Rik van Riel

[-- Attachment #1: Type: text/plain, Size: 1510 bytes --]

Jan Kiszka wrote:
> Avi Kivity wrote:
>   
>> Jan Kiszka wrote:
>>     
> ...
>   
>>> @@ -2234,6 +2252,24 @@ 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, need to be fixed with
>>> +     *        the required debugging infrastructure rework.
>>> +     */
>>> +    switch (vec) {
>>> +    case DF_VECTOR:
>>> +    case SS_VECTOR:
>>> +    case GP_VECTOR:
>>> +        kvm_queue_exception_e(vcpu, vec, err_code);
>>>   
>>>       
>> These don't actually queue an error code in real mode.  Compare the
>> 'Real-Address Mode Exceptions' section with the 'Protected Mode
>> Exceptions' section  for most instructions in the Intel manual.
>>     
>
> Unless you can points out a better reference, I prefer following chapter
> 5.15 of the System Programming Guide on this. And that one doesn't make
> a difference when it says, e.g., "Exception Error Code: Zero. The
> processor always pushes an error code of 0 onto the stack of the
> doublefault handler."
>
>   

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).



-- 
error compiling committee.c: too many arguments to function


[-- Attachment #2: Makefile --]
[-- Type: text/plain, Size: 327 bytes --]

all: real-mode-exception.iso

real-mode-exception.o: real-mode-exception.S
	as -o $@ $^

real-mode-exception.boot:  real-mode-exception.o real-mode-exception.ld
	ld -T real-mode-exception.ld -o $@ real-mode-exception.o
	dd < /dev/zero >> $@ count=2879

real-mode-exception.iso: real-mode-exception.boot
	mkisofs -o $@ -b $^ $^

[-- Attachment #3: real-mode-exception.ld --]
[-- Type: text/plain, Size: 222 bytes --]

OUTPUT_FORMAT(binary)

SECTIONS
{
    . = 0x7c00;
    stext = .;
    .text : { *(.init) *(.text) }
    . = ALIGN(4K);
    .data : { *(.data) }
    . = ALIGN(16);
    .bss : { *(.bss) }
    . = ALIGN(4K);
    edata = .;
}


[-- Attachment #4: real-mode-exception.S --]
[-- Type: text/plain, Size: 396 bytes --]

.code16

start:
	ljmp $0, $restart
restart:
	mov $0x39, %al
	mov $10, %ah
	mov $0, %bx
	mov $20, %cx
	int $0x10
	mov $0, %ax
	mov %ax, %ds
	movw $gp_handler, 13*4
	mov %cs, 13*4+2
	mov %sp, %dx
	addr32 testb $0, 0x100000
loop:	jmp loop

gp_handler:
	sub %sp, %dx
	shr $1, %dx
	add $48, %dl
	mov %dl, %al
	mov $10, %ah
	mov $0, %bx
	mov $10, %cx
	int $0x10
	jmp loop

. = 0x1fe

.byte 0x55, 0xaa


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

* Re: [PATCH 2/2] VMX: Reinject real mode exception
  2008-07-13 15:28     ` Avi Kivity
@ 2008-07-13 15:31       ` Avi Kivity
  2008-07-13 18:47         ` Nakajima, Jun
  0 siblings, 1 reply; 11+ messages in thread
From: Avi Kivity @ 2008-07-13 15:31 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: kvm-devel, Mohammed Gamal, Anthony Liguori, Rik van Riel,
	Nakajima, Jun

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?

-- 
error compiling committee.c: too many arguments to function


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

* RE: [PATCH 2/2] VMX: Reinject real mode exception
  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
  0 siblings, 2 replies; 11+ messages in thread
From: Nakajima, Jun @ 2008-07-13 18:47 UTC (permalink / raw)
  To: Avi Kivity, Jan Kiszka
  Cc: kvm-devel, Mohammed Gamal, Anthony Liguori, Rik van Riel

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. 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?

>
> --
> error compiling committee.c: too many arguments to function
>
             .
Jun Nakajima | Intel Open Source Technology Center

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

* Re: [PATCH 2/2] VMX: Reinject real mode exception
  2008-07-13 18:47         ` Nakajima, Jun
@ 2008-07-13 19:22           ` Mohammed Gamal
  2008-07-14 10:04           ` Avi Kivity
  1 sibling, 0 replies; 11+ messages in thread
From: Mohammed Gamal @ 2008-07-13 19:22 UTC (permalink / raw)
  To: Nakajima, Jun
  Cc: Avi Kivity, Jan Kiszka, kvm-devel, Anthony Liguori, Rik van Riel

On Sun, Jul 13, 2008 at 9:47 PM, Nakajima, Jun <jun.nakajima@intel.com> 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. 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?
>
>>
>> --
>> error compiling committee.c: too many arguments to function
>>
>             .
> Jun Nakajima | Intel Open Source Technology Center
>

Yes it is. FreeDOS runs in real mode, and KVM uses vm86 mode instead
of fully emulating real mode. If you check the register dump caused by
the exception you'll find the VM bit set in the guest's eflags.

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

* Re: [PATCH 2/2] VMX: Reinject real mode exception
  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
  2008-07-14 16:00             ` Nakajima, Jun
  1 sibling, 2 replies; 11+ messages in thread
From: Avi Kivity @ 2008-07-14 10:04 UTC (permalink / raw)
  To: Nakajima, Jun
  Cc: Jan Kiszka, kvm-devel, Mohammed Gamal, Anthony Liguori,
	Rik van Riel

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.

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH 2/2] VMX: Reinject real mode exception
  2008-07-14 10:04           ` Avi Kivity
@ 2008-07-14 10:28             ` Jan Kiszka
  2008-07-14 11:30               ` Avi Kivity
  2008-07-14 16:00             ` Nakajima, Jun
  1 sibling, 1 reply; 11+ messages in thread
From: Jan Kiszka @ 2008-07-14 10:28 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Nakajima, Jun, kvm-devel, Mohammed Gamal, Anthony Liguori,
	Rik van Riel

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)

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

* Re: [PATCH 2/2] VMX: Reinject real mode exception
  2008-07-14 10:28             ` Jan Kiszka
@ 2008-07-14 11:30               ` Avi Kivity
  0 siblings, 0 replies; 11+ messages in thread
From: Avi Kivity @ 2008-07-14 11:30 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Nakajima, Jun, kvm-devel, Mohammed Gamal, Anthony Liguori,
	Rik van Riel

Jan Kiszka wrote:
> 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).
>
>   

Applied, thanks.

-- 
error compiling committee.c: too many arguments to function


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

* RE: [PATCH 2/2] VMX: Reinject real mode exception
  2008-07-14 10:04           ` Avi Kivity
  2008-07-14 10:28             ` Jan Kiszka
@ 2008-07-14 16:00             ` Nakajima, Jun
  1 sibling, 0 replies; 11+ messages in thread
From: Nakajima, Jun @ 2008-07-14 16:00 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Jan Kiszka, kvm-devel, Mohammed Gamal, Anthony Liguori,
	Rik van Riel

On 7/14/2008 3:04:17 AM, 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.
>

If you are looking at the description of Chapter 5, at the top it says "This chapter describes the interrupt and exception-handling mechanism when operating in protected mode on an Intel 64 or IA-32 processor. ... Chapter 15, "8086 Emulation," describes information specific to interrupt and exception mechanisms in real-address and virtual-8086 mode.".
             .
Jun Nakajima | Intel Open Source Technology Center

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

end of thread, other threads:[~2008-07-14 16:09 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2008-07-14 11:30               ` Avi Kivity
2008-07-14 16:00             ` Nakajima, Jun

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