# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1168550859 25200
# Node ID d607d575ec6a03ca7f67f37020bef70a731d1c74
# Parent b440f5dbca1f926e7f20f9d0dd962859b969c5f5
[IA64] Can't inject event, when guest is executing rfi
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@xxxxxxxxx>
---
xen/arch/ia64/xen/faults.c | 5 +++++
xen/arch/ia64/xen/vcpu.c | 29 +++++++++++++++++------------
xen/include/asm-ia64/vcpu.h | 2 ++
3 files changed, 24 insertions(+), 12 deletions(-)
diff -r b440f5dbca1f -r d607d575ec6a xen/arch/ia64/xen/faults.c
--- a/xen/arch/ia64/xen/faults.c Fri Jan 12 12:52:54 2007 -0700
+++ b/xen/arch/ia64/xen/faults.c Thu Jan 11 14:27:39 2007 -0700
@@ -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",
diff -r b440f5dbca1f -r d607d575ec6a xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c Fri Jan 12 12:52:54 2007 -0700
+++ b/xen/arch/ia64/xen/vcpu.c Thu Jan 11 14:27:39 2007 -0700
@@ -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);
diff -r b440f5dbca1f -r d607d575ec6a xen/include/asm-ia64/vcpu.h
--- a/xen/include/asm-ia64/vcpu.h Fri Jan 12 12:52:54 2007 -0700
+++ b/xen/include/asm-ia64/vcpu.h Thu Jan 11 14:27:39 2007 -0700
@@ -22,6 +22,8 @@ extern u64 cycle_to_ns(u64 cycle);
#define PSCBX(_v,_x) (_v->arch._x)
#define SPURIOUS_VECTOR 0xf
+
+extern void dorfirfi(void);
/* general registers */
extern u64 vcpu_get_gr(VCPU * vcpu, unsigned long reg);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|