* [RFC PATCH v3 1/4] x86 emulator: Expose emulate_int_real()
2010-08-15 21:46 [RFC PATCH v3 0/4] Real mode interrupt injection Mohammed Gamal
@ 2010-08-15 21:47 ` Mohammed Gamal
2010-08-15 21:47 ` [RFC PATCH v3 2/4] x86: Separate emulation context initialization in a separate function Mohammed Gamal
` (4 subsequent siblings)
5 siblings, 0 replies; 17+ messages in thread
From: Mohammed Gamal @ 2010-08-15 21:47 UTC (permalink / raw)
To: avi; +Cc: kvm, mtosatti, Mohammed Gamal
Signed-off-by: Mohammed Gamal <m.gamal005@gmail.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 f22e5da..6a7cce0 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -255,5 +255,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.0.4
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC PATCH v3 2/4] x86: Separate emulation context initialization in a separate function
2010-08-15 21:46 [RFC PATCH v3 0/4] Real mode interrupt injection Mohammed Gamal
2010-08-15 21:47 ` [RFC PATCH v3 1/4] x86 emulator: Expose emulate_int_real() Mohammed Gamal
@ 2010-08-15 21:47 ` Mohammed Gamal
2010-08-15 21:47 ` [RFC PATCH v3 3/4] x86: Add kvm_inject_realmode_interrupt() wrapper Mohammed Gamal
` (3 subsequent siblings)
5 siblings, 0 replies; 17+ messages in thread
From: Mohammed Gamal @ 2010-08-15 21:47 UTC (permalink / raw)
To: avi; +Cc: kvm, mtosatti, Mohammed Gamal
The code for initializing the emulation context is duplicated at two
locations (emulate_instruction() and kvm_task_switch()). Separate it
in a separate function and call it from there.
Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com>
---
arch/x86/kvm/x86.c | 54 ++++++++++++++++++++++++---------------------------
1 files changed, 25 insertions(+), 29 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1722d37..f24e594 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3936,6 +3936,28 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu)
kvm_queue_exception(vcpu, ctxt->exception);
}
+static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
+{
+ struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
+ int cs_db, cs_l;
+
+ 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);
+}
+
static int handle_emulation_failure(struct kvm_vcpu *vcpu)
{
++vcpu->stat.insn_emulation_fail;
@@ -3992,20 +4014,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
cache_all_regs(vcpu);
if (!(emulation_type & EMULTYPE_NO_DECODE)) {
- int cs_db, cs_l;
- 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);
+ init_emulate_ctxt(vcpu);
vcpu->arch.emulate_ctxt.interruptibility = 0;
vcpu->arch.emulate_ctxt.exception = -1;
vcpu->arch.emulate_ctxt.perm_ok = false;
@@ -5064,22 +5073,9 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason,
bool has_error_code, u32 error_code)
{
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);
+ int ret;
- 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);
+ init_emulate_ctxt(vcpu);
ret = emulator_task_switch(&vcpu->arch.emulate_ctxt,
tss_selector, reason, has_error_code,
--
1.7.0.4
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC PATCH v3 3/4] x86: Add kvm_inject_realmode_interrupt() wrapper
2010-08-15 21:46 [RFC PATCH v3 0/4] Real mode interrupt injection Mohammed Gamal
2010-08-15 21:47 ` [RFC PATCH v3 1/4] x86 emulator: Expose emulate_int_real() Mohammed Gamal
2010-08-15 21:47 ` [RFC PATCH v3 2/4] x86: Separate emulation context initialization in a separate function Mohammed Gamal
@ 2010-08-15 21:47 ` Mohammed Gamal
2010-08-15 21:47 ` [RFC PATCH v3 4/4] VMX: Emulated real mode interrupt injection Mohammed Gamal
` (2 subsequent siblings)
5 siblings, 0 replies; 17+ messages in thread
From: Mohammed Gamal @ 2010-08-15 21:47 UTC (permalink / raw)
To: avi; +Cc: kvm, mtosatti, Mohammed Gamal
This adds a wrapper function kvm_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 | 21 +++++++++++++++++++++
arch/x86/kvm/x86.h | 1 +
2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f24e594..59b708c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3958,6 +3958,27 @@ 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);
+
+ 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);
+
+ 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 b7a4047..8b83da5 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 kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
#endif
--
1.7.0.4
^ permalink raw reply related [flat|nested] 17+ messages in thread* [RFC PATCH v3 4/4] VMX: Emulated real mode interrupt injection
2010-08-15 21:46 [RFC PATCH v3 0/4] Real mode interrupt injection Mohammed Gamal
` (2 preceding siblings ...)
2010-08-15 21:47 ` [RFC PATCH v3 3/4] x86: Add kvm_inject_realmode_interrupt() wrapper Mohammed Gamal
@ 2010-08-15 21:47 ` Mohammed Gamal
2010-08-15 23:37 ` [RFC PATCH v3 0/4] Real " Mohammed Gamal
2010-08-16 10:14 ` Avi Kivity
5 siblings, 0 replies; 17+ messages in thread
From: Mohammed Gamal @ 2010-08-15 21:47 UTC (permalink / raw)
To: avi; +Cc: kvm, mtosatti, 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..0f9e3e4 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 (kvm_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 (kvm_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 (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,
@@ -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] 17+ messages in thread* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-15 21:46 [RFC PATCH v3 0/4] Real mode interrupt injection Mohammed Gamal
` (3 preceding siblings ...)
2010-08-15 21:47 ` [RFC PATCH v3 4/4] VMX: Emulated real mode interrupt injection Mohammed Gamal
@ 2010-08-15 23:37 ` Mohammed Gamal
2010-08-16 8:51 ` Avi Kivity
2010-08-16 13:19 ` Avi Kivity
2010-08-16 10:14 ` Avi Kivity
5 siblings, 2 replies; 17+ messages in thread
From: Mohammed Gamal @ 2010-08-15 23:37 UTC (permalink / raw)
To: avi; +Cc: kvm, mtosatti, Mohammed Gamal
On Mon, Aug 16, 2010 at 12:46 AM, Mohammed Gamal <m.gamal005@gmail.com> wrote:
> This patch introduces real mode interrupt injection for VMX.
> It currently invokes the x86 emulator to emulate interrupts
> instead of manually setting VMX controls.
>
> Needless to say, this is not meant for merging in its current state.
> The emulator still needs some more work to get this completely operational.
>
> Mohammed Gamal (4):
> x86 emulator: Expose emulate_int_real()
> x86: Separate emulation context initialization in a separate function
> x86: Add kvm_inject_realmode_interrupt() wrapper
> VMX: Emulated real mode interrupt injection
>
> arch/x86/include/asm/kvm_emulate.h | 3 +-
> arch/x86/kvm/vmx.c | 65 +++----------------------------
> arch/x86/kvm/x86.c | 75 ++++++++++++++++++++++--------------
> arch/x86/kvm/x86.h | 1 +
> 4 files changed, 55 insertions(+), 89 deletions(-)
> ---
> Changes since v2:
> - Refactored emulation context initialization code
> - Commit eip value from the decode cache to the emulation context in x86.c rather than the emulator
> - Add kvm_* prefix to inject_realmode_interrupt() global symbol for consistency
>
Here is a full trace of a MINIX guest since bootup. Looks like we get
stuck somewhere in the BIOS.
https://docs.google.com/leaf?id=0B9UodZT1IuENMzJhNWQxM2YtYzE3YS00YWY4LTk2YTgtZWY3ODNhMWUxMDkx&sort=name&layout=list&num=50
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-15 23:37 ` [RFC PATCH v3 0/4] Real " Mohammed Gamal
@ 2010-08-16 8:51 ` Avi Kivity
2010-08-16 13:19 ` Avi Kivity
1 sibling, 0 replies; 17+ messages in thread
From: Avi Kivity @ 2010-08-16 8:51 UTC (permalink / raw)
To: Mohammed Gamal; +Cc: kvm, mtosatti
On 08/16/2010 02:37 AM, Mohammed Gamal wrote:
>
> Here is a full trace of a MINIX guest since bootup. Looks like we get
> stuck somewhere in the BIOS.
> https://docs.google.com/leaf?id=0B9UodZT1IuENMzJhNWQxM2YtYzE3YS00YWY4LTk2YTgtZWY3ODNhMWUxMDkx&sort=name&layout=list&num=50
> qemu-system-x86-28953 [000] 1927.399942: kvm_inj_virq: irq 16
> qemu-system-x86-28953 [000] 1927.399949:
> kvm_inject_realmode_interrupt: cs=c000
> qemu-system-x86-28953 [000] 1927.399951:
> kvm_inject_realmode_interrupt: eip=40a3
> qemu-system-x86-28953 [000] 1927.399957:
> kvm_inject_realmode_interrupt: cs=c000
> qemu-system-x86-28953 [000] 1927.399958:
> kvm_inject_realmode_interrupt: eip=8339
> qemu-system-x86-28953 [000] 1927.399960: kvm_entry: vcpu 0
> qemu-system-x86-28953 [000] 1927.399965: kvm_exit: reason
> EXCEPTION_NMI rip 0x8339
> qemu-system-x86-28953 [000] 1927.399966: kvm_page_fault: address
> c8339 error_code 1d
> qemu-system-x86-28953 [000] 1927.399970: kvm_entry: vcpu 0
> qemu-system-x86-28953 [000] 1927.399975: kvm_exit: reason
> IO_INSTRUCTION rip 0x67d9
> qemu-system-x86-28953 [000] 1927.399976: kvm_pio: pio_read at 0x3c4
> size 2 count 1
> qemu-system-x86-28953 [000] 1927.399985: kvm_entry: vcpu 0
> qemu-system-x86-28953 [000] 1927.399991: kvm_exit: reason
> EXCEPTION_NMI rip 0x3d4
This is bogus, it's in the middle of an instruction:
f93d1: 2e 67 8b 9a 00 00 f1 addr32 mov %cs:-0xf0000(%edx),%bx
f93d8: ff
f93d9: 66 0f b7 eb movzwl %bx,%ebp
Everything after that is invalid.
So we need to know how we got to rip = 0x3d4, it looks like an I/O port
used by vga. Please rerun with emulation on all real mode instructions.
> qemu-system-x86-28953 [000] 1927.399992: kvm_page_fault: address
> f93d4 error_code 1d
> qemu-system-x86-28953 [000] 1927.399996: kvm_entry: vcpu 0
> qemu-system-x86-28953 [000] 1927.400000: kvm_exit: reason
> EXCEPTION_NMI rip 0x0
> qemu-system-x86-28953 [000] 1927.400003: kvm_inj_exception: #DB (0x0)
> qemu-system-x86-28953 [000] 1927.400005:
> kvm_inject_realmode_interrupt: cs=fff1
> qemu-system-x86-28953 [000] 1927.400006:
> kvm_inject_realmode_interrupt: eip=0
> qemu-system-x86-28953 [000] 1927.400011:
> kvm_inject_realmode_interrupt: cs=f000
> qemu-system-x86-28953 [000] 1927.400012:
> kvm_inject_realmode_interrupt: eip=ff53
> qemu-system-x86-28953 [000] 1927.400014: kvm_entry: vcpu 0
--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-15 23:37 ` [RFC PATCH v3 0/4] Real " Mohammed Gamal
2010-08-16 8:51 ` Avi Kivity
@ 2010-08-16 13:19 ` Avi Kivity
2010-08-16 13:28 ` Mohammed Gamal
1 sibling, 1 reply; 17+ messages in thread
From: Avi Kivity @ 2010-08-16 13:19 UTC (permalink / raw)
To: Mohammed Gamal; +Cc: kvm, mtosatti
On 08/16/2010 02:37 AM, Mohammed Gamal wrote:
> On Mon, Aug 16, 2010 at 12:46 AM, Mohammed Gamal<m.gamal005@gmail.com> wrote:
>> This patch introduces real mode interrupt injection for VMX.
>> It currently invokes the x86 emulator to emulate interrupts
>> instead of manually setting VMX controls.
>>
>> Needless to say, this is not meant for merging in its current state.
>> The emulator still needs some more work to get this completely operational.
>>
>> Mohammed Gamal (4):
>> x86 emulator: Expose emulate_int_real()
>> x86: Separate emulation context initialization in a separate function
>> x86: Add kvm_inject_realmode_interrupt() wrapper
>> VMX: Emulated real mode interrupt injection
>>
>> arch/x86/include/asm/kvm_emulate.h | 3 +-
>> arch/x86/kvm/vmx.c | 65 +++----------------------------
>> arch/x86/kvm/x86.c | 75 ++++++++++++++++++++++--------------
>> arch/x86/kvm/x86.h | 1 +
>> 4 files changed, 55 insertions(+), 89 deletions(-)
>> ---
>> Changes since v2:
>> - Refactored emulation context initialization code
>> - Commit eip value from the decode cache to the emulation context in x86.c rather than the emulator
>> - Add kvm_* prefix to inject_realmode_interrupt() global symbol for consistency
>>
> Here is a full trace of a MINIX guest since bootup. Looks like we get
> stuck somewhere in the BIOS.
> https://docs.google.com/leaf?id=0B9UodZT1IuENMzJhNWQxM2YtYzE3YS00YWY4LTk2YTgtZWY3ODNhMWUxMDkx&sort=name&layout=list&num=50
I debugged this for a bit - emulate_int_real() is completely broken.
emulate_push() doesn't push anything, it only schedules a push; running
these back-to-back will result in only the last push to be executed.
With that fixed, I get the boot splash. Not 100% perfect but much closer.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-16 13:19 ` Avi Kivity
@ 2010-08-16 13:28 ` Mohammed Gamal
2010-08-16 14:16 ` Avi Kivity
0 siblings, 1 reply; 17+ messages in thread
From: Mohammed Gamal @ 2010-08-16 13:28 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm, mtosatti
On Mon, Aug 16, 2010 at 4:19 PM, Avi Kivity <avi@redhat.com> wrote:
> On 08/16/2010 02:37 AM, Mohammed Gamal wrote:
>>
>> On Mon, Aug 16, 2010 at 12:46 AM, Mohammed Gamal<m.gamal005@gmail.com>
>> wrote:
>>>
>>> This patch introduces real mode interrupt injection for VMX.
>>> It currently invokes the x86 emulator to emulate interrupts
>>> instead of manually setting VMX controls.
>>>
>>> Needless to say, this is not meant for merging in its current state.
>>> The emulator still needs some more work to get this completely
>>> operational.
>>>
>>> Mohammed Gamal (4):
>>> x86 emulator: Expose emulate_int_real()
>>> x86: Separate emulation context initialization in a separate function
>>> x86: Add kvm_inject_realmode_interrupt() wrapper
>>> VMX: Emulated real mode interrupt injection
>>>
>>> arch/x86/include/asm/kvm_emulate.h | 3 +-
>>> arch/x86/kvm/vmx.c | 65
>>> +++----------------------------
>>> arch/x86/kvm/x86.c | 75
>>> ++++++++++++++++++++++--------------
>>> arch/x86/kvm/x86.h | 1 +
>>> 4 files changed, 55 insertions(+), 89 deletions(-)
>>> ---
>>> Changes since v2:
>>> - Refactored emulation context initialization code
>>> - Commit eip value from the decode cache to the emulation context in
>>> x86.c rather than the emulator
>>> - Add kvm_* prefix to inject_realmode_interrupt() global symbol for
>>> consistency
>>>
>> Here is a full trace of a MINIX guest since bootup. Looks like we get
>> stuck somewhere in the BIOS.
>>
>> https://docs.google.com/leaf?id=0B9UodZT1IuENMzJhNWQxM2YtYzE3YS00YWY4LTk2YTgtZWY3ODNhMWUxMDkx&sort=name&layout=list&num=50
>
> I debugged this for a bit - emulate_int_real() is completely broken.
> emulate_push() doesn't push anything, it only schedules a push; running
> these back-to-back will result in only the last push to be executed.
>
So we need write back the decode cache after each push. Or let
emulate_push() change the emulation context directly. Please CMIIW
> With that fixed, I get the boot splash. Not 100% perfect but much closer.
>
> --
> error compiling committee.c: too many arguments to function
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-16 13:28 ` Mohammed Gamal
@ 2010-08-16 14:16 ` Avi Kivity
2010-08-16 14:29 ` Gleb Natapov
0 siblings, 1 reply; 17+ messages in thread
From: Avi Kivity @ 2010-08-16 14:16 UTC (permalink / raw)
To: Mohammed Gamal; +Cc: kvm, mtosatti
On 08/16/2010 04:28 PM, Mohammed Gamal wrote:
>
>> I debugged this for a bit - emulate_int_real() is completely broken.
>> emulate_push() doesn't push anything, it only schedules a push; running
>> these back-to-back will result in only the last push to be executed.
>>
> So we need write back the decode cache after each push. Or let
> emulate_push() change the emulation context directly. Please CMIIW
I wrote a push_std() that uses ->write_std() instead of
->write_emulated() and can be used back-to-back. Long term we'll need a
write queue but for the short term this will do.
I'll clean up my patches and push them later on.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-16 14:16 ` Avi Kivity
@ 2010-08-16 14:29 ` Gleb Natapov
2010-08-16 14:47 ` Avi Kivity
0 siblings, 1 reply; 17+ messages in thread
From: Gleb Natapov @ 2010-08-16 14:29 UTC (permalink / raw)
To: Avi Kivity; +Cc: Mohammed Gamal, kvm, mtosatti
On Mon, Aug 16, 2010 at 05:16:01PM +0300, Avi Kivity wrote:
> On 08/16/2010 04:28 PM, Mohammed Gamal wrote:
> >
> >>I debugged this for a bit - emulate_int_real() is completely broken.
> >> emulate_push() doesn't push anything, it only schedules a push; running
> >>these back-to-back will result in only the last push to be executed.
> >>
> >So we need write back the decode cache after each push. Or let
> >emulate_push() change the emulation context directly. Please CMIIW
>
> I wrote a push_std() that uses ->write_std() instead of
> ->write_emulated() and can be used back-to-back. Long term we'll
> need a write queue but for the short term this will do.
>
Why not just call writeback() after the emulate_push()? emulate_pusha()
does it.
--
Gleb.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-16 14:29 ` Gleb Natapov
@ 2010-08-16 14:47 ` Avi Kivity
2010-08-16 15:23 ` Mohammed Gamal
0 siblings, 1 reply; 17+ messages in thread
From: Avi Kivity @ 2010-08-16 14:47 UTC (permalink / raw)
To: Gleb Natapov; +Cc: Mohammed Gamal, kvm, mtosatti
On 08/16/2010 05:29 PM, Gleb Natapov wrote:
>
>> I wrote a push_std() that uses ->write_std() instead of
>> ->write_emulated() and can be used back-to-back. Long term we'll
>> need a write queue but for the short term this will do.
>>
> Why not just call writeback() after the emulate_push()? emulate_pusha()
> does it.
Good idea. I'll do that.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-16 14:47 ` Avi Kivity
@ 2010-08-16 15:23 ` Mohammed Gamal
2010-08-16 15:31 ` Gleb Natapov
0 siblings, 1 reply; 17+ messages in thread
From: Mohammed Gamal @ 2010-08-16 15:23 UTC (permalink / raw)
To: Avi Kivity; +Cc: Gleb Natapov, kvm, mtosatti
On Mon, Aug 16, 2010 at 5:47 PM, Avi Kivity <avi@redhat.com> wrote:
> On 08/16/2010 05:29 PM, Gleb Natapov wrote:
>>
>>> I wrote a push_std() that uses ->write_std() instead of
>>> ->write_emulated() and can be used back-to-back. Long term we'll
>>> need a write queue but for the short term this will do.
>>>
>> Why not just call writeback() after the emulate_push()? emulate_pusha()
>> does it.
>
> Good idea. I'll do that.
I tried it, but it doesn't seem to make any difference.
>
> --
> error compiling committee.c: too many arguments to function
>
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-16 15:23 ` Mohammed Gamal
@ 2010-08-16 15:31 ` Gleb Natapov
2010-08-16 15:33 ` Avi Kivity
2010-08-16 15:43 ` Mohammed Gamal
0 siblings, 2 replies; 17+ messages in thread
From: Gleb Natapov @ 2010-08-16 15:31 UTC (permalink / raw)
To: Mohammed Gamal; +Cc: Avi Kivity, kvm, mtosatti
On Mon, Aug 16, 2010 at 06:23:18PM +0300, Mohammed Gamal wrote:
> On Mon, Aug 16, 2010 at 5:47 PM, Avi Kivity <avi@redhat.com> wrote:
> > On 08/16/2010 05:29 PM, Gleb Natapov wrote:
> >>
> >>> I wrote a push_std() that uses ->write_std() instead of
> >>> ->write_emulated() and can be used back-to-back. Long term we'll
> >>> need a write queue but for the short term this will do.
> >>>
> >> Why not just call writeback() after the emulate_push()? emulate_pusha()
> >> does it.
> >
> > Good idea. I'll do that.
>
> I tried it, but it doesn't seem to make any difference.
>
It should. Can you post what you've tried?
--
Gleb.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-16 15:31 ` Gleb Natapov
@ 2010-08-16 15:33 ` Avi Kivity
2010-08-16 15:43 ` Mohammed Gamal
1 sibling, 0 replies; 17+ messages in thread
From: Avi Kivity @ 2010-08-16 15:33 UTC (permalink / raw)
To: Gleb Natapov; +Cc: Mohammed Gamal, kvm, mtosatti
On 08/16/2010 06:31 PM, Gleb Natapov wrote:
> On Mon, Aug 16, 2010 at 06:23:18PM +0300, Mohammed Gamal wrote:
>> On Mon, Aug 16, 2010 at 5:47 PM, Avi Kivity<avi@redhat.com> wrote:
>>> On 08/16/2010 05:29 PM, Gleb Natapov wrote:
>>>>> I wrote a push_std() that uses ->write_std() instead of
>>>>> ->write_emulated() and can be used back-to-back. Long term we'll
>>>>> need a write queue but for the short term this will do.
>>>>>
>>>> Why not just call writeback() after the emulate_push()? emulate_pusha()
>>>> does it.
>>> Good idea. I'll do that.
>> I tried it, but it doesn't seem to make any difference.
>>
> It should. Can you post what you've tried?
>
There are other bugs involved. I'll post a patchset soon.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-16 15:31 ` Gleb Natapov
2010-08-16 15:33 ` Avi Kivity
@ 2010-08-16 15:43 ` Mohammed Gamal
1 sibling, 0 replies; 17+ messages in thread
From: Mohammed Gamal @ 2010-08-16 15:43 UTC (permalink / raw)
To: Gleb Natapov; +Cc: Avi Kivity, kvm, mtosatti
2010/8/16 Gleb Natapov <gleb@redhat.com>:
> On Mon, Aug 16, 2010 at 06:23:18PM +0300, Mohammed Gamal wrote:
>> On Mon, Aug 16, 2010 at 5:47 PM, Avi Kivity <avi@redhat.com> wrote:
>> > On 08/16/2010 05:29 PM, Gleb Natapov wrote:
>> >>
>> >>> I wrote a push_std() that uses ->write_std() instead of
>> >>> ->write_emulated() and can be used back-to-back. Long term we'll
>> >>> need a write queue but for the short term this will do.
>> >>>
>> >> Why not just call writeback() after the emulate_push()? emulate_pusha()
>> >> does it.
>> >
>> > Good idea. I'll do that.
>>
>> I tried it, but it doesn't seem to make any difference.
>>
> It should. Can you post what you've tried?
>
arch/x86/kvm/emulate.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 32498e3..4002c87 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1219,14 +1219,23 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
/* TODO: Add limit checks */
c->src.val = ctxt->eflags;
emulate_push(ctxt, ops);
+ rc = writeback(ctxt, ops);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC);
c->src.val = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu);
emulate_push(ctxt, ops);
+ rc = writeback(ctxt, ops);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
c->src.val = c->eip;
emulate_push(ctxt, ops);
+ rc = writeback(ctxt, ops);
+ if (rc != X86EMUL_CONTINUE)
+ return rc;
I also added some trace_printk()'s and the values for RSP are not
updated after writeback.
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [RFC PATCH v3 0/4] Real mode interrupt injection
2010-08-15 21:46 [RFC PATCH v3 0/4] Real mode interrupt injection Mohammed Gamal
` (4 preceding siblings ...)
2010-08-15 23:37 ` [RFC PATCH v3 0/4] Real " Mohammed Gamal
@ 2010-08-16 10:14 ` Avi Kivity
5 siblings, 0 replies; 17+ messages in thread
From: Avi Kivity @ 2010-08-16 10:14 UTC (permalink / raw)
To: Mohammed Gamal; +Cc: kvm, mtosatti
On 08/16/2010 12:46 AM, Mohammed Gamal wrote:
> This patch introduces real mode interrupt injection for VMX.
> It currently invokes the x86 emulator to emulate interrupts
> instead of manually setting VMX controls.
>
> Needless to say, this is not meant for merging in its current state.
> The emulator still needs some more work to get this completely operational.
>
> Mohammed Gamal (4):
> x86 emulator: Expose emulate_int_real()
> x86: Separate emulation context initialization in a separate function
> x86: Add kvm_inject_realmode_interrupt() wrapper
> VMX: Emulated real mode interrupt injection
>
I applied the second patch to next, rest are applied to
non-atomic-injection branch. Thanks.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 17+ messages in thread