All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Real mode interrupt injection emulation
@ 2010-09-19 12:34 Avi Kivity
  2010-09-19 12:34 ` [PATCH 1/4] KVM: x86 emulator: Expose emulate_int_real() Avi Kivity
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Avi Kivity @ 2010-09-19 12:34 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm; +Cc: Mohammed Gamal

Our current real mode interrupt injection injects external interrupts as
software interrupts, which is somewhat hacky.  This is problematic in big
real mode (can't use vmx there) and on via processors (a cpu bug prevents
this from working correctly).

Replace the current mechanism with emulation; we now inject the interrupt
by looking up the vector in the IVT, updating the stack, etc. using the
emulator. This is somewhat slower but works in all cases.

Avi Kivity (1):
  KVM: VMX: Respect interrupt window in big real mode

Mohammed Gamal (3):
  KVM: x86 emulator: Expose emulate_int_real()
  KVM: Add kvm_inject_realmode_interrupt() wrapper
  KVM: VMX: Emulated real mode interrupt injection

 arch/x86/include/asm/kvm_emulate.h |    3 +-
 arch/x86/kvm/vmx.c                 |   74 +++++++----------------------------
 arch/x86/kvm/x86.c                 |   29 ++++++++++++++
 arch/x86/kvm/x86.h                 |    1 +
 4 files changed, 47 insertions(+), 60 deletions(-)

-- 
1.7.2.3


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

* [PATCH 1/4] KVM: x86 emulator: Expose emulate_int_real()
  2010-09-19 12:34 [PATCH 0/4] Real mode interrupt injection emulation Avi Kivity
@ 2010-09-19 12:34 ` Avi Kivity
  2010-09-19 12:34 ` [PATCH 2/4] KVM: Add kvm_inject_realmode_interrupt() wrapper Avi Kivity
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Avi Kivity @ 2010-09-19 12:34 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm; +Cc: Mohammed Gamal

From: Mohammed Gamal <m.gamal005@gmail.com>

Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/include/asm/kvm_emulate.h |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 5187dd8..b36c6b3 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -260,5 +260,6 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt);
 int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
 			 u16 tss_selector, int reason,
 			 bool has_error_code, u32 error_code);
-
+int emulate_int_real(struct x86_emulate_ctxt *ctxt,
+		     struct x86_emulate_ops *ops, int irq);
 #endif /* _ASM_X86_KVM_X86_EMULATE_H */
-- 
1.7.2.3


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

* [PATCH 2/4] KVM: Add kvm_inject_realmode_interrupt() wrapper
  2010-09-19 12:34 [PATCH 0/4] Real mode interrupt injection emulation Avi Kivity
  2010-09-19 12:34 ` [PATCH 1/4] KVM: x86 emulator: Expose emulate_int_real() Avi Kivity
@ 2010-09-19 12:34 ` Avi Kivity
  2010-09-19 12:34 ` [PATCH 3/4] KVM: VMX: Emulated real mode interrupt injection Avi Kivity
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Avi Kivity @ 2010-09-19 12:34 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm; +Cc: Mohammed Gamal

From: Mohammed Gamal <m.gamal005@gmail.com>

This adds a wrapper function kvm_inject_realmode_interrupt() around the
emulator function emulate_int_real() to allow real mode interrupt injection.

[avi: initialize operand and address sizes before emulating interrupts]
[avi: initialize rip for real mode interrupt injection]
[avi: clear interrupt pending flag after emulating interrupt injection]

Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/x86.c |   29 +++++++++++++++++++++++++++++
 arch/x86/kvm/x86.h |    1 +
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index a51635e..a3fc151 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4187,6 +4187,35 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
 	memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
 }
 
+int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq)
+{
+	struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
+	int ret;
+
+	init_emulate_ctxt(vcpu);
+
+	vcpu->arch.emulate_ctxt.decode.op_bytes = 2;
+	vcpu->arch.emulate_ctxt.decode.ad_bytes = 2;
+	vcpu->arch.emulate_ctxt.decode.eip = vcpu->arch.emulate_ctxt.eip;
+	ret = emulate_int_real(&vcpu->arch.emulate_ctxt, &emulate_ops, irq);
+
+	if (ret != X86EMUL_CONTINUE)
+		return EMULATE_FAIL;
+
+	vcpu->arch.emulate_ctxt.eip = c->eip;
+	memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
+	kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
+	kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
+
+	if (irq == NMI_VECTOR)
+		vcpu->arch.nmi_pending = false;
+	else
+		vcpu->arch.interrupt.pending = false;
+
+	return EMULATE_DONE;
+}
+EXPORT_SYMBOL_GPL(kvm_inject_realmode_interrupt);
+
 static int handle_emulation_failure(struct kvm_vcpu *vcpu)
 {
 	++vcpu->stat.insn_emulation_fail;
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index bf4dc2f..2cea414 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -72,6 +72,7 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
 
 void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
 void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
+int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
 
 void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data);
 
-- 
1.7.2.3


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

* [PATCH 3/4] KVM: VMX: Emulated real mode interrupt injection
  2010-09-19 12:34 [PATCH 0/4] Real mode interrupt injection emulation Avi Kivity
  2010-09-19 12:34 ` [PATCH 1/4] KVM: x86 emulator: Expose emulate_int_real() Avi Kivity
  2010-09-19 12:34 ` [PATCH 2/4] KVM: Add kvm_inject_realmode_interrupt() wrapper Avi Kivity
@ 2010-09-19 12:34 ` Avi Kivity
  2010-09-20 17:30   ` Marcelo Tosatti
  2010-09-19 12:34 ` [PATCH 4/4] KVM: VMX: Respect interrupt window in big real mode Avi Kivity
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Avi Kivity @ 2010-09-19 12:34 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm; +Cc: Mohammed Gamal

From: Mohammed Gamal <m.gamal005@gmail.com>

Replace the inject-as-software-interrupt hack we currently have with
emulated injection.

Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/vmx.c |   65 ++++-----------------------------------------------
 1 files changed, 6 insertions(+), 59 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 8ef6199..2572153 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -155,11 +155,6 @@ struct vcpu_vmx {
 			u32 limit;
 			u32 ar;
 		} tr, es, ds, fs, gs;
-		struct {
-			bool pending;
-			u8 vector;
-			unsigned rip;
-		} irq;
 	} rmode;
 	int vpid;
 	bool emulation_required;
@@ -1034,16 +1029,8 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
 	}
 
 	if (vmx->rmode.vm86_active) {
-		vmx->rmode.irq.pending = true;
-		vmx->rmode.irq.vector = nr;
-		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
-		if (kvm_exception_is_soft(nr))
-			vmx->rmode.irq.rip +=
-				vmx->vcpu.arch.event_exit_inst_len;
-		intr_info |= INTR_TYPE_SOFT_INTR;
-		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
-		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
-		kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
+		if (kvm_inject_realmode_interrupt(vcpu, nr) != EMULATE_DONE)
+			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
 		return;
 	}
 
@@ -2822,16 +2809,8 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu)
 
 	++vcpu->stat.irq_injections;
 	if (vmx->rmode.vm86_active) {
-		vmx->rmode.irq.pending = true;
-		vmx->rmode.irq.vector = irq;
-		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
-		if (vcpu->arch.interrupt.soft)
-			vmx->rmode.irq.rip +=
-				vmx->vcpu.arch.event_exit_inst_len;
-		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
-			     irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK);
-		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
-		kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
+		if (kvm_inject_realmode_interrupt(vcpu, irq) != EMULATE_DONE)
+			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
 		return;
 	}
 	intr = irq | INTR_INFO_VALID_MASK;
@@ -2863,14 +2842,8 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
 
 	++vcpu->stat.nmi_injections;
 	if (vmx->rmode.vm86_active) {
-		vmx->rmode.irq.pending = true;
-		vmx->rmode.irq.vector = NMI_VECTOR;
-		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
-		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
-			     NMI_VECTOR | INTR_TYPE_SOFT_INTR |
-			     INTR_INFO_VALID_MASK);
-		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
-		kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
+		if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR) != EMULATE_DONE)
+			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
 		return;
 	}
 	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
@@ -3832,29 +3805,6 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
 			ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
 }
 
-/*
- * Failure to inject an interrupt should give us the information
- * in IDT_VECTORING_INFO_FIELD.  However, if the failure occurs
- * when fetching the interrupt redirection bitmap in the real-mode
- * tss, this doesn't happen.  So we do it ourselves.
- */
-static void fixup_rmode_irq(struct vcpu_vmx *vmx, u32 *idt_vectoring_info)
-{
-	vmx->rmode.irq.pending = 0;
-	if (kvm_rip_read(&vmx->vcpu) + 1 != vmx->rmode.irq.rip)
-		return;
-	kvm_rip_write(&vmx->vcpu, vmx->rmode.irq.rip);
-	if (*idt_vectoring_info & VECTORING_INFO_VALID_MASK) {
-		*idt_vectoring_info &= ~VECTORING_INFO_TYPE_MASK;
-		*idt_vectoring_info |= INTR_TYPE_EXT_INTR;
-		return;
-	}
-	*idt_vectoring_info =
-		VECTORING_INFO_VALID_MASK
-		| INTR_TYPE_EXT_INTR
-		| vmx->rmode.irq.vector;
-}
-
 static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
 				      u32 idt_vectoring_info,
 				      int instr_len_field,
@@ -3864,9 +3814,6 @@ static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
 	int type;
 	bool idtv_info_valid;
 
-	if (vmx->rmode.irq.pending)
-		fixup_rmode_irq(vmx, &idt_vectoring_info);
-
 	idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
 
 	vmx->vcpu.arch.nmi_injected = false;
-- 
1.7.2.3


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

* [PATCH 4/4] KVM: VMX: Respect interrupt window in big real mode
  2010-09-19 12:34 [PATCH 0/4] Real mode interrupt injection emulation Avi Kivity
                   ` (2 preceding siblings ...)
  2010-09-19 12:34 ` [PATCH 3/4] KVM: VMX: Emulated real mode interrupt injection Avi Kivity
@ 2010-09-19 12:34 ` Avi Kivity
  2010-09-19 15:25 ` [PATCH 0/4] Real mode interrupt injection emulation Avi Kivity
  2010-09-21 18:32 ` Marcelo Tosatti
  5 siblings, 0 replies; 11+ messages in thread
From: Avi Kivity @ 2010-09-19 12:34 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm; +Cc: Mohammed Gamal

If an interrupt is pending, we need to stop emulation so we
can inject it.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/vmx.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 2572153..1a5ecfd 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3588,8 +3588,17 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	enum emulation_result err = EMULATE_DONE;
 	int ret = 1;
+	u32 cpu_exec_ctrl;
+	bool intr_window_requested;
+
+	cpu_exec_ctrl = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
+	intr_window_requested = cpu_exec_ctrl & CPU_BASED_VIRTUAL_INTR_PENDING;
 
 	while (!guest_state_valid(vcpu)) {
+		if (intr_window_requested
+		    && (kvm_get_rflags(&vmx->vcpu) & X86_EFLAGS_IF))
+			return handle_interrupt_window(&vmx->vcpu);
+
 		err = emulate_instruction(vcpu, 0, 0, 0);
 
 		if (err == EMULATE_DO_MMIO) {
-- 
1.7.2.3


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

* Re: [PATCH 0/4] Real mode interrupt injection emulation
  2010-09-19 12:34 [PATCH 0/4] Real mode interrupt injection emulation Avi Kivity
                   ` (3 preceding siblings ...)
  2010-09-19 12:34 ` [PATCH 4/4] KVM: VMX: Respect interrupt window in big real mode Avi Kivity
@ 2010-09-19 15:25 ` Avi Kivity
  2010-09-21 18:32 ` Marcelo Tosatti
  5 siblings, 0 replies; 11+ messages in thread
From: Avi Kivity @ 2010-09-19 15:25 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm; +Cc: Mohammed Gamal

  On 09/19/2010 02:34 PM, Avi Kivity wrote:
> Our current real mode interrupt injection injects external interrupts as
> software interrupts, which is somewhat hacky.  This is problematic in big
> real mode (can't use vmx there) and on via processors (a cpu bug prevents
> this from working correctly).
>
> Replace the current mechanism with emulation; we now inject the interrupt
> by looking up the vector in the IVT, updating the stack, etc. using the
> emulator. This is somewhat slower but works in all cases.
>
>

This patchset survived an autotest run.

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


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

* Re: [PATCH 3/4] KVM: VMX: Emulated real mode interrupt injection
  2010-09-19 12:34 ` [PATCH 3/4] KVM: VMX: Emulated real mode interrupt injection Avi Kivity
@ 2010-09-20 17:30   ` Marcelo Tosatti
  2010-09-21 11:56     ` Avi Kivity
  0 siblings, 1 reply; 11+ messages in thread
From: Marcelo Tosatti @ 2010-09-20 17:30 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm, Mohammed Gamal

On Sun, Sep 19, 2010 at 02:34:07PM +0200, Avi Kivity wrote:
> From: Mohammed Gamal <m.gamal005@gmail.com>
> 
> Replace the inject-as-software-interrupt hack we currently have with
> emulated injection.
> 
> Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
>  arch/x86/kvm/vmx.c |   65 ++++-----------------------------------------------
>  1 files changed, 6 insertions(+), 59 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 8ef6199..2572153 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -155,11 +155,6 @@ struct vcpu_vmx {
>  			u32 limit;
>  			u32 ar;
>  		} tr, es, ds, fs, gs;
> -		struct {
> -			bool pending;
> -			u8 vector;
> -			unsigned rip;
> -		} irq;
>  	} rmode;
>  	int vpid;
>  	bool emulation_required;
> @@ -1034,16 +1029,8 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
>  	}
>  
>  	if (vmx->rmode.vm86_active) {
> -		vmx->rmode.irq.pending = true;
> -		vmx->rmode.irq.vector = nr;
> -		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
> -		if (kvm_exception_is_soft(nr))
> -			vmx->rmode.irq.rip +=
> -				vmx->vcpu.arch.event_exit_inst_len;
> -		intr_info |= INTR_TYPE_SOFT_INTR;
> -		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
> -		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
> -		kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
> +		if (kvm_inject_realmode_interrupt(vcpu, nr) != EMULATE_DONE)
> +			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
>  		return;
>  	}
>  
> @@ -2822,16 +2809,8 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu)
>  
>  	++vcpu->stat.irq_injections;
>  	if (vmx->rmode.vm86_active) {
> -		vmx->rmode.irq.pending = true;
> -		vmx->rmode.irq.vector = irq;
> -		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
> -		if (vcpu->arch.interrupt.soft)
> -			vmx->rmode.irq.rip +=
> -				vmx->vcpu.arch.event_exit_inst_len;
> -		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
> -			     irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK);
> -		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
> -		kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
> +		if (kvm_inject_realmode_interrupt(vcpu, irq) != EMULATE_DONE)
> +			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
>  		return;
>  	}
>  	intr = irq | INTR_INFO_VALID_MASK;
> @@ -2863,14 +2842,8 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
>  
>  	++vcpu->stat.nmi_injections;
>  	if (vmx->rmode.vm86_active) {
> -		vmx->rmode.irq.pending = true;
> -		vmx->rmode.irq.vector = NMI_VECTOR;
> -		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
> -		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
> -			     NMI_VECTOR | INTR_TYPE_SOFT_INTR |
> -			     INTR_INFO_VALID_MASK);
> -		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
> -		kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
> +		if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR) != EMULATE_DONE)
> +			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
>  		return;
>  	}
>  	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
> @@ -3832,29 +3805,6 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
>  			ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
>  }
>  
> -/*
> - * Failure to inject an interrupt should give us the information
> - * in IDT_VECTORING_INFO_FIELD.  However, if the failure occurs
> - * when fetching the interrupt redirection bitmap in the real-mode
> - * tss, this doesn't happen.  So we do it ourselves.
> - */
> -static void fixup_rmode_irq(struct vcpu_vmx *vmx, u32 *idt_vectoring_info)
> -{
> -	vmx->rmode.irq.pending = 0;
> -	if (kvm_rip_read(&vmx->vcpu) + 1 != vmx->rmode.irq.rip)
> -		return;
> -	kvm_rip_write(&vmx->vcpu, vmx->rmode.irq.rip);
> -	if (*idt_vectoring_info & VECTORING_INFO_VALID_MASK) {
> -		*idt_vectoring_info &= ~VECTORING_INFO_TYPE_MASK;
> -		*idt_vectoring_info |= INTR_TYPE_EXT_INTR;
> -		return;
> -	}
> -	*idt_vectoring_info =
> -		VECTORING_INFO_VALID_MASK
> -		| INTR_TYPE_EXT_INTR
> -		| vmx->rmode.irq.vector;
> -}
> -
>  static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
>  				      u32 idt_vectoring_info,
>  				      int instr_len_field,
> @@ -3864,9 +3814,6 @@ static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
>  	int type;
>  	bool idtv_info_valid;
>  
> -	if (vmx->rmode.irq.pending)
> -		fixup_rmode_irq(vmx, &idt_vectoring_info);
> -

Don't you have to undo kvm_inject_realmode_interrupt if injection fails?

>  	idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
>  
>  	vmx->vcpu.arch.nmi_injected = false;
> -- 
> 1.7.2.3

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

* Re: [PATCH 3/4] KVM: VMX: Emulated real mode interrupt injection
  2010-09-20 17:30   ` Marcelo Tosatti
@ 2010-09-21 11:56     ` Avi Kivity
  2010-09-21 15:36       ` Marcelo Tosatti
  0 siblings, 1 reply; 11+ messages in thread
From: Avi Kivity @ 2010-09-21 11:56 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: kvm, Mohammed Gamal

  On 09/20/2010 07:30 PM, Marcelo Tosatti wrote:
> >   static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
> >   				u32 idt_vectoring_info,
> >   				int instr_len_field,
> >  @@ -3864,9 +3814,6 @@ static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
> >   	int type;
> >   	bool idtv_info_valid;
> >
> >  -	if (vmx->rmode.irq.pending)
> >  -		fixup_rmode_irq(vmx,&idt_vectoring_info);
> >  -
>
> Don't you have to undo kvm_inject_realmode_interrupt if injection fails?
>
>

Injection cannot fail (at least, in the same sense as the vmx 
injections).  It's actually not about failures, it's about guest entry 
being cancelled due to a signal or some KVM_REQ that needs attention.  
For vmx style injections, we need to undo the injection to keep things 
in a consistent state.  To realmode emulated injection, everything is in 
a consistent state already, so no need to undo anything (it's also 
impossible, since we overwrote memory on the stack).


-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.


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

* Re: [PATCH 3/4] KVM: VMX: Emulated real mode interrupt injection
  2010-09-21 11:56     ` Avi Kivity
@ 2010-09-21 15:36       ` Marcelo Tosatti
  2010-09-21 16:00         ` Avi Kivity
  0 siblings, 1 reply; 11+ messages in thread
From: Marcelo Tosatti @ 2010-09-21 15:36 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm, Mohammed Gamal

On Tue, Sep 21, 2010 at 01:56:50PM +0200, Avi Kivity wrote:
>  On 09/20/2010 07:30 PM, Marcelo Tosatti wrote:
> >>   static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
> >>   				u32 idt_vectoring_info,
> >>   				int instr_len_field,
> >>  @@ -3864,9 +3814,6 @@ static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
> >>   	int type;
> >>   	bool idtv_info_valid;
> >>
> >>  -	if (vmx->rmode.irq.pending)
> >>  -		fixup_rmode_irq(vmx,&idt_vectoring_info);
> >>  -
> >
> >Don't you have to undo kvm_inject_realmode_interrupt if injection fails?
> >
> >
> 
> Injection cannot fail (at least, in the same sense as the vmx
> injections).  It's actually not about failures, it's about guest
> entry being cancelled due to a signal or some KVM_REQ that needs
> attention.  For vmx style injections, we need to undo the injection
> to keep things in a consistent state.  To realmode emulated
> injection, everything is in a consistent state already, so no need
> to undo anything (it's also impossible, since we overwrote memory on
> the stack).

Aren't you going to push EFLAGS,CS,EIP on the stack twice if that
occurs?

Yes, can't undo it...

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

* Re: [PATCH 3/4] KVM: VMX: Emulated real mode interrupt injection
  2010-09-21 15:36       ` Marcelo Tosatti
@ 2010-09-21 16:00         ` Avi Kivity
  0 siblings, 0 replies; 11+ messages in thread
From: Avi Kivity @ 2010-09-21 16:00 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: kvm, Mohammed Gamal

  On 09/21/2010 05:36 PM, Marcelo Tosatti wrote:
> On Tue, Sep 21, 2010 at 01:56:50PM +0200, Avi Kivity wrote:
> >   On 09/20/2010 07:30 PM, Marcelo Tosatti wrote:
> >  >>    static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
> >  >>    				u32 idt_vectoring_info,
> >  >>    				int instr_len_field,
> >  >>   @@ -3864,9 +3814,6 @@ static void __vmx_complete_interrupts(struct vcpu_vmx *vmx,
> >  >>    	int type;
> >  >>    	bool idtv_info_valid;
> >  >>
> >  >>   -	if (vmx->rmode.irq.pending)
> >  >>   -		fixup_rmode_irq(vmx,&idt_vectoring_info);
> >  >>   -
> >  >
> >  >Don't you have to undo kvm_inject_realmode_interrupt if injection fails?
> >  >
> >  >
> >
> >  Injection cannot fail (at least, in the same sense as the vmx
> >  injections).  It's actually not about failures, it's about guest
> >  entry being cancelled due to a signal or some KVM_REQ that needs
> >  attention.  For vmx style injections, we need to undo the injection
> >  to keep things in a consistent state.  To realmode emulated
> >  injection, everything is in a consistent state already, so no need
> >  to undo anything (it's also impossible, since we overwrote memory on
> >  the stack).
>
> Aren't you going to push EFLAGS,CS,EIP on the stack twice if that
> occurs?
>

No, since we clear the pending flag (we do that even for vmx-injected 
interrupts; then cancel or injection failure re-sets the flag).

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


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

* Re: [PATCH 0/4] Real mode interrupt injection emulation
  2010-09-19 12:34 [PATCH 0/4] Real mode interrupt injection emulation Avi Kivity
                   ` (4 preceding siblings ...)
  2010-09-19 15:25 ` [PATCH 0/4] Real mode interrupt injection emulation Avi Kivity
@ 2010-09-21 18:32 ` Marcelo Tosatti
  5 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2010-09-21 18:32 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm, Mohammed Gamal

On Sun, Sep 19, 2010 at 02:34:04PM +0200, Avi Kivity wrote:
> Our current real mode interrupt injection injects external interrupts as
> software interrupts, which is somewhat hacky.  This is problematic in big
> real mode (can't use vmx there) and on via processors (a cpu bug prevents
> this from working correctly).
> 
> Replace the current mechanism with emulation; we now inject the interrupt
> by looking up the vector in the IVT, updating the stack, etc. using the
> emulator. This is somewhat slower but works in all cases.
> 
> Avi Kivity (1):
>   KVM: VMX: Respect interrupt window in big real mode
> 
> Mohammed Gamal (3):
>   KVM: x86 emulator: Expose emulate_int_real()
>   KVM: Add kvm_inject_realmode_interrupt() wrapper
>   KVM: VMX: Emulated real mode interrupt injection
> 
>  arch/x86/include/asm/kvm_emulate.h |    3 +-
>  arch/x86/kvm/vmx.c                 |   74 +++++++----------------------------
>  arch/x86/kvm/x86.c                 |   29 ++++++++++++++
>  arch/x86/kvm/x86.h                 |    1 +
>  4 files changed, 47 insertions(+), 60 deletions(-)
> 
> -- 
> 1.7.2.3

Applied, thanks.


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

end of thread, other threads:[~2010-09-22 20:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-19 12:34 [PATCH 0/4] Real mode interrupt injection emulation Avi Kivity
2010-09-19 12:34 ` [PATCH 1/4] KVM: x86 emulator: Expose emulate_int_real() Avi Kivity
2010-09-19 12:34 ` [PATCH 2/4] KVM: Add kvm_inject_realmode_interrupt() wrapper Avi Kivity
2010-09-19 12:34 ` [PATCH 3/4] KVM: VMX: Emulated real mode interrupt injection Avi Kivity
2010-09-20 17:30   ` Marcelo Tosatti
2010-09-21 11:56     ` Avi Kivity
2010-09-21 15:36       ` Marcelo Tosatti
2010-09-21 16:00         ` Avi Kivity
2010-09-19 12:34 ` [PATCH 4/4] KVM: VMX: Respect interrupt window in big real mode Avi Kivity
2010-09-19 15:25 ` [PATCH 0/4] Real mode interrupt injection emulation Avi Kivity
2010-09-21 18:32 ` Marcelo Tosatti

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.