# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 00061c916dbb765b928760665ad610929ce7aa95
# Parent 8bb494bccdac3c85bffcd134b15c247d7d566a90
Clean the pending_intr processing sequence and fix some potential bugs.
Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx>
Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx>
diff -r 8bb494bccdac -r 00061c916dbb xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Fri Mar 10 08:11:33 2006
+++ b/xen/arch/x86/hvm/vlapic.c Fri Mar 10 08:12:22 2006
@@ -943,6 +943,20 @@
return -1;
}
+int cpu_has_apic_interrupt(struct vcpu* v)
+{
+ struct vlapic *vlapic = VLAPIC(v);
+
+ if (vlapic && vlapic_enabled(vlapic)) {
+ int highest_irr = vlapic_find_highest_irr(vlapic);
+
+ if (highest_irr != -1 && highest_irr >= vlapic->processor_priority) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode)
{
struct vlapic *vlapic = VLAPIC(v);
diff -r 8bb494bccdac -r 00061c916dbb xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Fri Mar 10 08:11:33 2006
+++ b/xen/arch/x86/hvm/vmx/io.c Fri Mar 10 08:12:22 2006
@@ -86,28 +86,53 @@
}
static inline void
-enable_irq_window(unsigned long cpu_exec_control)
-{
- if (!(cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) {
- cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
- __vmwrite(CPU_BASED_VM_EXEC_CONTROL, cpu_exec_control);
+enable_irq_window(struct vcpu *v)
+{
+ u32 *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
+
+ if (!(*cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) {
+ *cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
+ __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
}
}
static inline void
-disable_irq_window(unsigned long cpu_exec_control)
-{
- if ( cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) {
- cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
- __vmwrite(CPU_BASED_VM_EXEC_CONTROL, cpu_exec_control);
- }
+disable_irq_window(struct vcpu *v)
+{
+ u32 *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
+
+ if ( *cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) {
+ *cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
+ __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
+ }
+}
+
+static inline int is_interruptibility_state(void)
+{
+ int interruptibility;
+ __vmread(GUEST_INTERRUPTIBILITY_INFO, &interruptibility);
+ return interruptibility;
+}
+
+/* check to see if there is pending interrupt */
+int cpu_has_pending_irq(struct vcpu *v)
+{
+ struct hvm_domain *plat = &v->domain->arch.hvm_domain;
+
+ /* APIC */
+ if ( cpu_has_apic_interrupt(v) ) return 1;
+
+ /* PIC */
+ if ( !vlapic_accept_pic_intr(v) ) return 0;
+
+ return plat->interrupt_request;
}
asmlinkage void vmx_intr_assist(void)
{
int intr_type = 0;
int highest_vector;
- unsigned long intr_fields, eflags, interruptibility, cpu_exec_control;
+ unsigned long eflags;
struct vcpu *v = current;
struct hvm_domain *plat=&v->domain->arch.hvm_domain;
struct hvm_virpit *vpit = &plat->vpit;
@@ -121,37 +146,21 @@
pic_set_irq(pic, 0, 1);
}
- __vmread_vcpu(v, CPU_BASED_VM_EXEC_CONTROL, &cpu_exec_control);
- __vmread(VM_ENTRY_INTR_INFO_FIELD, &intr_fields);
-
- if (intr_fields & INTR_INFO_VALID_MASK) {
- enable_irq_window(cpu_exec_control);
- HVM_DBG_LOG(DBG_LEVEL_1, "vmx_intr_assist: intr_fields: %lx",
- intr_fields);
- return;
- }
-
- __vmread(GUEST_INTERRUPTIBILITY_INFO, &interruptibility);
-
- if (interruptibility) {
- enable_irq_window(cpu_exec_control);
- HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility: %lx",interruptibility);
+ if ( !cpu_has_pending_irq(v) ) return;
+
+ if ( is_interruptibility_state() ) { /* pre-cleared for emulated
instruction */
+ enable_irq_window(v);
+ HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility");
return;
}
__vmread(GUEST_RFLAGS, &eflags);
if (irq_masked(eflags)) {
- enable_irq_window(cpu_exec_control);
+ enable_irq_window(v);
return;
}
highest_vector = cpu_get_interrupt(v, &intr_type);
-
- if (highest_vector == -1) {
- disable_irq_window(cpu_exec_control);
- return;
- }
-
switch (intr_type) {
case VLAPIC_DELIV_MODE_EXT:
case VLAPIC_DELIV_MODE_FIXED:
diff -r 8bb494bccdac -r 00061c916dbb xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Fri Mar 10 08:11:33 2006
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Fri Mar 10 08:12:22 2006
@@ -219,6 +219,7 @@
error |= __vmwrite(CR0_READ_SHADOW, cr0);
error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
MONITOR_CPU_BASED_EXEC_CONTROLS);
+ v->arch.hvm_vcpu.u.vmx.exec_control = MONITOR_CPU_BASED_EXEC_CONTROLS;
__asm__ __volatile__ ("mov %%cr4,%0" : "=r" (cr4) : );
diff -r 8bb494bccdac -r 00061c916dbb xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri Mar 10 08:11:33 2006
+++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Mar 10 08:12:22 2006
@@ -595,6 +595,7 @@
__vmread(GUEST_RIP, ¤t_eip);
__vmwrite(GUEST_RIP, current_eip + inst_len);
+ __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
}
@@ -2025,6 +2026,7 @@
case EXIT_REASON_PENDING_INTERRUPT:
__vmwrite(CPU_BASED_VM_EXEC_CONTROL,
MONITOR_CPU_BASED_EXEC_CONTROLS);
+ v->arch.hvm_vcpu.u.vmx.exec_control = MONITOR_CPU_BASED_EXEC_CONTROLS;
break;
case EXIT_REASON_TASK_SWITCH:
__hvm_bug(®s);
diff -r 8bb494bccdac -r 00061c916dbb xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h Fri Mar 10 08:11:33 2006
+++ b/xen/include/asm-x86/hvm/io.h Fri Mar 10 08:12:22 2006
@@ -154,6 +154,7 @@
extern void pic_irq_request(int *interrupt_request, int level);
extern void hvm_pic_assist(struct vcpu *v);
extern int cpu_get_interrupt(struct vcpu *v, int *type);
+extern int cpu_has_pending_irq(struct vcpu *v);
// XXX - think about this, maybe use bit 30 of the mfn to signify an MMIO
frame.
#define mmio_space(gpa) (!VALID_MFN(get_mfn_from_gpfn((gpa) >> PAGE_SHIFT)))
diff -r 8bb494bccdac -r 00061c916dbb xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h Fri Mar 10 08:11:33 2006
+++ b/xen/include/asm-x86/hvm/vlapic.h Fri Mar 10 08:12:22 2006
@@ -209,6 +209,7 @@
void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode);
+int cpu_has_apic_interrupt(struct vcpu* v);
int cpu_get_apic_interrupt(struct vcpu* v, int *mode);
extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
diff -r 8bb494bccdac -r 00061c916dbb xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h Fri Mar 10 08:11:33 2006
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Fri Mar 10 08:12:22 2006
@@ -69,6 +69,7 @@
struct arch_vmx_struct {
struct vmcs_struct *vmcs; /* VMCS pointer in virtual. */
unsigned int launch_cpu; /* VMCS is valid on this CPU. */
+ u32 exec_control; /* cache of cpu execution control */
unsigned long flags; /* VMCS flags */
unsigned long cpu_cr0; /* copy of guest CR0 */
unsigned long cpu_shadow_cr0; /* copy of guest read shadow CR0 */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|