All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper
@ 2010-08-14  0:19 Mohammed Gamal
  2010-08-14  0:19 ` [RFC PATCH v2 3/4] VMX: Emulated real mode interrupt injection Mohammed Gamal
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Mohammed Gamal @ 2010-08-14  0:19 UTC (permalink / raw)
  To: avi; +Cc: mtosatti, kvm, Mohammed Gamal

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

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

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1722d37..d3ba1c3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3936,6 +3936,39 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu)
 		kvm_queue_exception(vcpu, ctxt->exception);
 }
 
+int inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq)
+{       
+	struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
+	int cs_db, cs_l, ret;
+	cache_all_regs(vcpu);
+
+	kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
+
+	vcpu->arch.emulate_ctxt.vcpu = vcpu;
+	vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
+	vcpu->arch.emulate_ctxt.eip = kvm_rip_read(vcpu);
+	vcpu->arch.emulate_ctxt.mode =
+		(!is_protmode(vcpu)) ? X86EMUL_MODE_REAL :
+		(vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM)
+		? X86EMUL_MODE_VM86 : cs_l
+		? X86EMUL_MODE_PROT64 : cs_db
+		? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+	memset(c, 0, sizeof(struct decode_cache));
+	memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
+
+	ret = emulate_int_real(&vcpu->arch.emulate_ctxt, &emulate_ops, irq);
+
+	if (ret != X86EMUL_CONTINUE)
+		return EMULATE_FAIL;
+
+	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);
+
+	return EMULATE_DONE;
+}
+EXPORT_SYMBOL_GPL(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 b7a4047..c6e8a4d 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -67,5 +67,6 @@ 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 inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
 
 #endif
-- 
1.7.0.4


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

* [RFC PATCH v2 3/4] VMX: Emulated real mode interrupt injection
  2010-08-14  0:19 [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper Mohammed Gamal
@ 2010-08-14  0:19 ` Mohammed Gamal
  2010-08-14  0:19 ` [RFC PATCH v2 4/4] x86 emulator: Eagerly commit emulation ctxt eip in emulate_int_real() Mohammed Gamal
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Mohammed Gamal @ 2010-08-14  0:19 UTC (permalink / raw)
  To: avi; +Cc: mtosatti, kvm, Mohammed Gamal

Signed-off-by: Mohammed Gamal <m.gamal005@gmail.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 652d317..1f4387b 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;
@@ -1048,16 +1043,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 (inject_realmode_interrupt(vcpu, nr) != EMULATE_DONE)
+			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
 		return;
 	}
 
@@ -2838,16 +2825,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 (inject_realmode_interrupt(vcpu, irq) != EMULATE_DONE)
+			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
 		return;
 	}
 	intr = irq | INTR_INFO_VALID_MASK;
@@ -2879,14 +2858,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 (inject_realmode_interrupt(vcpu, NMI_VECTOR) != EMULATE_DONE)
+			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
 		return;
 	}
 	vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
@@ -3848,29 +3821,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,
@@ -3880,9 +3830,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.0.4


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

* [RFC PATCH v2 4/4] x86 emulator: Eagerly commit emulation ctxt eip in emulate_int_real()
  2010-08-14  0:19 [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper Mohammed Gamal
  2010-08-14  0:19 ` [RFC PATCH v2 3/4] VMX: Emulated real mode interrupt injection Mohammed Gamal
@ 2010-08-14  0:19 ` Mohammed Gamal
  2010-08-15 12:42   ` Avi Kivity
  2010-08-15  7:41 ` [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper Gleb Natapov
  2010-08-15 12:37 ` Avi Kivity
  3 siblings, 1 reply; 6+ messages in thread
From: Mohammed Gamal @ 2010-08-14  0:19 UTC (permalink / raw)
  To: avi; +Cc: mtosatti, kvm, Mohammed Gamal

emulate_int_real() is to be used outside the emulator. Hence, we shouldn't
wait for writeback to write the eip value stored in the decode cache. Save it
in emulation context eagerly instead.

Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
---
 arch/x86/kvm/emulate.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 32498e3..ae45b04 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1245,7 +1245,7 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	c->eip = eip;
+	ctxt->eip = eip;
 
 	return rc;
 }
-- 
1.7.0.4


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

* Re: [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper
  2010-08-14  0:19 [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper Mohammed Gamal
  2010-08-14  0:19 ` [RFC PATCH v2 3/4] VMX: Emulated real mode interrupt injection Mohammed Gamal
  2010-08-14  0:19 ` [RFC PATCH v2 4/4] x86 emulator: Eagerly commit emulation ctxt eip in emulate_int_real() Mohammed Gamal
@ 2010-08-15  7:41 ` Gleb Natapov
  2010-08-15 12:37 ` Avi Kivity
  3 siblings, 0 replies; 6+ messages in thread
From: Gleb Natapov @ 2010-08-15  7:41 UTC (permalink / raw)
  To: Mohammed Gamal; +Cc: avi, mtosatti, kvm

On Sat, Aug 14, 2010 at 03:19:39AM +0300, Mohammed Gamal wrote:
> This adds a wrapper function inject_realmode_interrupt() around the
> emulator function emulate_int_real() to allow real mode interrupt injection.
> 
> Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
> ---
>  arch/x86/kvm/x86.c |   33 +++++++++++++++++++++++++++++++++
>  arch/x86/kvm/x86.h |    1 +
>  2 files changed, 34 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 1722d37..d3ba1c3 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -3936,6 +3936,39 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu)
>  		kvm_queue_exception(vcpu, ctxt->exception);
>  }
>  
> +int inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq)
> +{       
> +	struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
> +	int cs_db, cs_l, ret;
> +	cache_all_regs(vcpu);
> +
> +	kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
> +
> +	vcpu->arch.emulate_ctxt.vcpu = vcpu;
> +	vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
> +	vcpu->arch.emulate_ctxt.eip = kvm_rip_read(vcpu);
> +	vcpu->arch.emulate_ctxt.mode =
> +		(!is_protmode(vcpu)) ? X86EMUL_MODE_REAL :
> +		(vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM)
> +		? X86EMUL_MODE_VM86 : cs_l
> +		? X86EMUL_MODE_PROT64 : cs_db
> +		? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
> +	memset(c, 0, sizeof(struct decode_cache));
> +	memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
> +
We have this code in 2 places already: kvm_task_switch() and emulate_instruction().
This will be the third one. Should be moved to separate function.

> +	ret = emulate_int_real(&vcpu->arch.emulate_ctxt, &emulate_ops, irq);
> +
> +	if (ret != X86EMUL_CONTINUE)
> +		return EMULATE_FAIL;
> +
> +	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);
> +
> +	return EMULATE_DONE;
> +}
> +EXPORT_SYMBOL_GPL(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 b7a4047..c6e8a4d 100644
> --- a/arch/x86/kvm/x86.h
> +++ b/arch/x86/kvm/x86.h
> @@ -67,5 +67,6 @@ 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 inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
>  
>  #endif
> -- 
> 1.7.0.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
			Gleb.

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

* Re: [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper
  2010-08-14  0:19 [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper Mohammed Gamal
                   ` (2 preceding siblings ...)
  2010-08-15  7:41 ` [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper Gleb Natapov
@ 2010-08-15 12:37 ` Avi Kivity
  3 siblings, 0 replies; 6+ messages in thread
From: Avi Kivity @ 2010-08-15 12:37 UTC (permalink / raw)
  To: Mohammed Gamal; +Cc: mtosatti, kvm

  On 08/14/2010 03:19 AM, Mohammed Gamal wrote:
> This adds a wrapper function inject_realmode_interrupt() around the
> emulator function emulate_int_real() to allow real mode interrupt injection.
>
> +EXPORT_SYMBOL_GPL(inject_realmode_interrupt);
> +

Global symbols should start with kvm_.

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


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

* Re: [RFC PATCH v2 4/4] x86 emulator: Eagerly commit emulation ctxt eip in emulate_int_real()
  2010-08-14  0:19 ` [RFC PATCH v2 4/4] x86 emulator: Eagerly commit emulation ctxt eip in emulate_int_real() Mohammed Gamal
@ 2010-08-15 12:42   ` Avi Kivity
  0 siblings, 0 replies; 6+ messages in thread
From: Avi Kivity @ 2010-08-15 12:42 UTC (permalink / raw)
  To: Mohammed Gamal; +Cc: mtosatti, kvm

  On 08/14/2010 03:19 AM, Mohammed Gamal wrote:
> emulate_int_real() is to be used outside the emulator. Hence, we shouldn't
> wait for writeback to write the eip value stored in the decode cache. Save it
> in emulation context eagerly instead.
>
> Signed-off-by: Mohammed Gamal<m.gamal005@gmail.com>
> ---
>   arch/x86/kvm/emulate.c |    2 +-
>   1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 32498e3..ae45b04 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -1245,7 +1245,7 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
>   	if (rc != X86EMUL_CONTINUE)
>   		return rc;
>
> -	c->eip = eip;
> +	ctxt->eip = eip;
>
>   	return rc;
>   }

Doesn't seem right.  It should work like the rest of the emulator.

Instead, the wrapper code in x86.c should do this.

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


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

end of thread, other threads:[~2010-08-15 16:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-14  0:19 [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper Mohammed Gamal
2010-08-14  0:19 ` [RFC PATCH v2 3/4] VMX: Emulated real mode interrupt injection Mohammed Gamal
2010-08-14  0:19 ` [RFC PATCH v2 4/4] x86 emulator: Eagerly commit emulation ctxt eip in emulate_int_real() Mohammed Gamal
2010-08-15 12:42   ` Avi Kivity
2010-08-15  7:41 ` [RFC PATCH v2 2/4] x86: Add inject_realmode_interrupt() wrapper Gleb Natapov
2010-08-15 12:37 ` Avi Kivity

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.