* [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.