[IA64] Can't inject event, when guest is executing rfi
authorawilliam@xenbuild2.aw <awilliam@xenbuild2.aw>
Thu, 11 Jan 2007 21:27:39 +0000 (14:27 -0700)
committerawilliam@xenbuild2.aw <awilliam@xenbuild2.aw>
Thu, 11 Jan 2007 21:27:39 +0000 (14:27 -0700)
Can't inject event, when guest is executing rfi, and both
both PSCB(v, ifs) and regs->ifs are valid

It's very rare case, but I did catch it.
It caused domain0 crash

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
xen/arch/ia64/xen/faults.c
xen/arch/ia64/xen/vcpu.c
xen/include/asm-ia64/vcpu.h

index 8893c7395fe51ec14169dc161cc11621eb40ba95..454bdd69a6489de9c03bb345181b8b70b619dbc5 100644 (file)
@@ -134,6 +134,11 @@ void reflect_event(struct pt_regs *regs)
        if (!event_pending(v))
                return;
 
+       // can't inject event, when XEN is emulating rfi 
+       // and both PSCB(v, ifs) and regs->ifs are valid
+       if (regs->cr_iip == *(unsigned long *)dorfirfi)
+               return;
+
        if (!PSCB(v, interrupt_collection_enabled))
                printk("psr.ic off, delivering event, ipsr=%lx,iip=%lx,"
                       "isr=%lx,viip=0x%lx\n",
index 8adad97c210a103110bde18cca675f6e8acc679e..10a8227ef7d43d0193b568e6ab4dbc646b48e93f 100644 (file)
@@ -1326,7 +1326,6 @@ IA64FAULT vcpu_rfi(VCPU * vcpu)
        u64 int_enable, regspsr = 0;
        u64 ifs;
        REGS *regs = vcpu_regs(vcpu);
-       extern void dorfirfi(void);
 
        psr.i64 = PSCB(vcpu, ipsr);
        if (psr.ia64_psr.cpl < 3)
@@ -1350,18 +1349,24 @@ IA64FAULT vcpu_rfi(VCPU * vcpu)
                return IA64_ILLOP_FAULT;
        }
        PSCB(vcpu, incomplete_regframe) = 0;    // is this necessary?
+
        ifs = PSCB(vcpu, ifs);
-       //if ((ifs & regs->cr_ifs & 0x8000000000000000L) && ifs != regs->cr_ifs) {
-       //if ((ifs & 0x8000000000000000L) && ifs != regs->cr_ifs) {
-       if (ifs & regs->cr_ifs & 0x8000000000000000L) {
-               // TODO: validate PSCB(vcpu,iip)
-               // TODO: PSCB(vcpu,ipsr) = psr;
-               PSCB(vcpu, ipsr) = psr.i64;
-               // now set up the trampoline
-               regs->cr_iip = *(unsigned long *)dorfirfi; // function pointer!!
-               __asm__ __volatile("mov %0=psr;;":"=r"(regspsr)::"memory");
-               regs->cr_ipsr =
-                   regspsr & ~(IA64_PSR_I | IA64_PSR_IC | IA64_PSR_BN);
+       if (ifs > 0x8000000000000000UL) {
+               if (regs->cr_ifs > 0x8000000000000000UL) {
+                       // TODO: validate PSCB(vcpu,iip)
+                       // TODO: PSCB(vcpu,ipsr) = psr;
+                       PSCB(vcpu, ipsr) = psr.i64;
+                       // now set up the trampoline
+                       regs->cr_iip = *(unsigned long *)dorfirfi; // func ptr!
+                       __asm__ __volatile("mov %0=psr;;":"=r"(regspsr)
+                                          ::"memory");
+                       regs->cr_ipsr = regspsr & ~(IA64_PSR_I | IA64_PSR_IC |
+                                                   IA64_PSR_BN);
+               } else {
+                       regs->cr_ifs = ifs;
+                       regs->cr_ipsr = psr.i64;
+                       regs->cr_iip = PSCB(vcpu, iip);
+               }
        } else {
                regs->cr_ipsr = psr.i64;
                regs->cr_iip = PSCB(vcpu, iip);
index b61915e3b2884c3ced0ab7c3d2a840fe32a6f3ea..e403213d65a9f00fa87b581c8fb4337040fc6627 100644 (file)
@@ -23,6 +23,8 @@ extern u64 cycle_to_ns(u64 cycle);
 
 #define SPURIOUS_VECTOR 0xf
 
+extern void dorfirfi(void);
+
 /* general registers */
 extern u64 vcpu_get_gr(VCPU * vcpu, unsigned long reg);
 extern IA64FAULT vcpu_get_gr_nat(VCPU * vcpu, unsigned long reg, u64 * val);