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