# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID 98fb7e03a886148f687f84ce0e475f98be1e7ffc
# Parent c22741d000a5a812ea93c199c3f5a3cc4ab04d4a
Some cleanup of reflection code
diff -r c22741d000a5 -r 98fb7e03a886 xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c Thu Sep 29 23:29:23 2005
+++ b/xen/arch/ia64/xen/process.c Mon Oct 3 22:27:27 2005
@@ -165,59 +165,34 @@
return s - buf;
}
-void reflect_interruption(unsigned long ifa, unsigned long isr, unsigned long
itiriim, struct pt_regs *regs, unsigned long vector)
+// should never panic domain... if it does, stack may have been overrun
+void check_bad_nested_interruption(unsigned long isr, struct pt_regs *regs,
unsigned long vector)
+{
+ struct vcpu *v = current;
+
+ if (!(PSCB(v,ipsr) & IA64_PSR_DT)) {
+ panic_domain(regs,"psr.dt off, trying to deliver nested
dtlb!\n");
+ }
+ if (vector != IA64_DATA_TLB_VECTOR &&
+ vector != IA64_ALT_DATA_TLB_VECTOR &&
+ vector != IA64_VHPT_TRANS_VECTOR) {
+panic_domain(regs,"psr.ic off, delivering
fault=%lx,ipsr=%p,iip=%p,ifa=%p,isr=%p,PSCB.iip=%p\n",
+ vector,regs->cr_ipsr,regs->cr_iip,PSCB(v,ifa),isr,PSCB(v,iip));
+ }
+}
+
+void reflect_interruption(unsigned long isr, struct pt_regs *regs, unsigned
long vector)
{
unsigned long vcpu_get_ipsr_int_state(struct vcpu *,unsigned long);
- unsigned long vcpu_get_rr_ve(struct vcpu *,unsigned long);
- struct domain *d = current->domain;
struct vcpu *v = current;
- if (vector == IA64_EXTINT_VECTOR) {
-
- extern unsigned long vcpu_verbose, privop_trace;
- static first_extint = 1;
- if (first_extint) {
- printf("Delivering first extint to domain: ifa=%p,
isr=%p, itir=%p, iip=%p\n",ifa,isr,itiriim,regs->cr_iip);
- //privop_trace = 1; vcpu_verbose = 1;
- first_extint = 0;
- }
- }
- if (!PSCB(v,interrupt_collection_enabled)) {
- if (!(PSCB(v,ipsr) & IA64_PSR_DT)) {
- panic_domain(regs,"psr.dt off, trying to deliver nested
dtlb!\n");
- }
- vector &= ~0xf;
- if (vector != IA64_DATA_TLB_VECTOR &&
- vector != IA64_ALT_DATA_TLB_VECTOR &&
- vector != IA64_VHPT_TRANS_VECTOR) {
-panic_domain(regs,"psr.ic off, delivering
fault=%lx,ipsr=%p,iip=%p,ifa=%p,isr=%p,PSCB.iip=%p\n",
- vector,regs->cr_ipsr,regs->cr_iip,ifa,isr,PSCB(v,iip));
-
- }
-//printf("Delivering NESTED DATA TLB fault\n");
- vector = IA64_DATA_NESTED_TLB_VECTOR;
- regs->cr_iip = ((unsigned long) PSCBX(v,iva) + vector) &
~0xffUL;
- regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) |
DELIVER_PSR_SET;
-// NOTE: nested trap must NOT pass PSCB address
- //regs->r31 = (unsigned long) &PSCB(v);
- inc_slow_reflect_count(vector);
- return;
-
- }
- if ((vector & 0xf) == IA64_FORCED_IFA)
- ifa = PSCB(v,tmp[0]);
- vector &= ~0xf;
- PSCB(v,ifa) = ifa;
- if (vector < IA64_DATA_NESTED_TLB_VECTOR) /* VHPT miss, TLB miss, Alt
TLB miss */
- vcpu_thash(v,ifa,&PSCB(current,iha));
+ if (!PSCB(v,interrupt_collection_enabled))
+ check_bad_nested_interruption(isr,regs,vector);
PSCB(v,unat) = regs->ar_unat; // not sure if this is really needed?
PSCB(v,precover_ifs) = regs->cr_ifs;
vcpu_bsw0(v);
PSCB(v,ipsr) = vcpu_get_ipsr_int_state(v,regs->cr_ipsr);
- if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR)
- PSCB(v,iim) = itiriim;
- else PSCB(v,itir) = vcpu_get_itir_on_fault(v,ifa);
- PSCB(v,isr) = isr; // this is unnecessary except for interrupts!
+ PSCB(v,isr) = isr;
PSCB(v,iip) = regs->cr_iip;
PSCB(v,ifs) = 0;
PSCB(v,incomplete_regframe) = 0;
@@ -239,6 +214,24 @@
unsigned long pending_false_positive = 0;
+void reflect_extint(struct pt_regs *regs)
+{
+ extern unsigned long vcpu_verbose, privop_trace;
+ unsigned long isr = regs->cr_ipsr & IA64_PSR_RI;
+ struct vcpu *v = current;
+ static first_extint = 1;
+
+ if (first_extint) {
+ printf("Delivering first extint to domain: isr=%p,
iip=%p\n",isr,regs->cr_iip);
+ //privop_trace = 1; vcpu_verbose = 1;
+ first_extint = 0;
+ }
+ if (vcpu_timer_pending_early(v))
+printf("*#*#*#* about to deliver early timer to domain
%d!!!\n",v->domain->domain_id);
+ PSCB(current,itir) = 0;
+ reflect_interruption(isr,regs,IA64_EXTINT_VECTOR);
+}
+
// ONLY gets called from ia64_leave_kernel
// ONLY call with interrupts disabled?? (else might miss one?)
// NEVER successful if already reflecting a trap/fault because psr.i==0
@@ -249,12 +242,8 @@
// FIXME: Will this work properly if doing an RFI???
if (!is_idle_task(d) && user_mode(regs)) {
//vcpu_poke_timer(v);
- if (vcpu_deliverable_interrupts(v)) {
- unsigned long isr = regs->cr_ipsr & IA64_PSR_RI;
- if (vcpu_timer_pending_early(v))
-printf("*#*#*#* about to deliver early timer to domain
%d!!!\n",v->domain->domain_id);
- reflect_interruption(0,isr,0,regs,IA64_EXTINT_VECTOR);
- }
+ if (vcpu_deliverable_interrupts(v))
+ reflect_extint(regs);
else if (PSCB(v,pending_interruption))
++pending_false_positive;
}
@@ -295,14 +284,12 @@
}
fault = vcpu_translate(current,address,is_data,&pteval,&itir,&iha);
- if (fault == IA64_NO_FAULT)
- {
+ if (fault == IA64_NO_FAULT) {
pteval = translate_domain_pte(pteval,address,itir);
vcpu_itc_no_srlz(current,is_data?2:1,address,pteval,-1UL,(itir>>2)&0x3f);
return;
}
- else if (IS_VMM_ADDRESS(iip))
- {
+ if (IS_VMM_ADDRESS(iip)) {
if (!ia64_done_with_exception(regs)) {
// should never happen. If it does, region 0 addr may
// indicate a bad xen pointer
@@ -315,8 +302,22 @@
}
return;
}
-
- reflect_interruption(address, isr, 0, regs, fault);
+ if (!PSCB(current,interrupt_collection_enabled)) {
+ check_bad_nested_interruption(isr,regs,fault);
+ //printf("Delivering NESTED DATA TLB fault\n");
+ fault = IA64_DATA_NESTED_TLB_VECTOR;
+ regs->cr_iip = ((unsigned long) PSCBX(current,iva) + fault) &
~0xffUL;
+ regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) |
DELIVER_PSR_SET;
+ // NOTE: nested trap must NOT pass PSCB address
+ //regs->r31 = (unsigned long) &PSCB(current);
+ inc_slow_reflect_count(fault);
+ return;
+ }
+
+ PSCB(current,itir) = itir;
+ PSCB(current,iha) = iha;
+ PSCB(current,ifa) = address;
+ reflect_interruption(isr, regs, fault);
}
void
@@ -521,7 +522,9 @@
}
//die_if_kernel(buf, regs, error);
printk("ia64_fault: %s: reflecting\n",buf);
-reflect_interruption(ifa,isr,iim,regs,IA64_GENEX_VECTOR);
+PSCB(current,itir) = vcpu_get_itir_on_fault(current,ifa);
+PSCB(current,ifa) = ifa;
+reflect_interruption(isr,regs,IA64_GENEX_VECTOR);
//while(1);
//force_sig(SIGILL, current);
}
@@ -668,7 +671,10 @@
if (ia64_hyperprivop(iim,regs))
vcpu_increment_iip(current);
}
- else reflect_interruption(ifa,isr,iim,regs,IA64_BREAK_VECTOR);
+ else {
+ PSCB(v,iim) = iim;
+ reflect_interruption(isr,regs,IA64_BREAK_VECTOR);
+ }
}
void
@@ -680,10 +686,11 @@
// FIXME: no need to pass itir in to this routine as we need to
// compute the virtual itir anyway (based on domain's RR.ps)
// AND ACTUALLY reflect_interruption doesn't use it anyway!
- itir = vcpu_get_itir_on_fault(v,ifa);
vector = priv_emulate(current,regs,isr);
if (vector != IA64_NO_FAULT && vector != IA64_RFI_IN_PROGRESS) {
- reflect_interruption(ifa,isr,itir,regs,vector);
+ PSCB(current,itir) =
+ vcpu_get_itir_on_fault(v,PSCB(current,ifa));
+ reflect_interruption(isr,regs,vector);
}
}
@@ -697,15 +704,10 @@
struct vcpu *v = (struct domain *) current;
unsigned long check_lazy_cover = 0;
unsigned long psr = regs->cr_ipsr;
- unsigned long itir = vcpu_get_itir_on_fault(v,ifa);
if (!(psr & IA64_PSR_CPL)) {
printk("ia64_handle_reflection: reflecting with priv=0!!\n");
}
- // FIXME: no need to pass itir in to this routine as we need to
- // compute the virtual itir anyway (based on domain's RR.ps)
- // AND ACTUALLY reflect_interruption doesn't use it anyway!
- itir = vcpu_get_itir_on_fault(v,ifa);
switch(vector) {
case 8:
vector = IA64_DIRTY_BIT_VECTOR; break;
@@ -736,7 +738,7 @@
vector = IA64_NAT_CONSUMPTION_VECTOR; break;
case 27:
//printf("*** Handled speculation vector, itc=%lx!\n",ia64_get_itc());
- itir = iim;
+ PSCB(current,iim) = iim;
vector = IA64_SPECULATION_VECTOR; break;
case 30:
// FIXME: Should we handle unaligned refs in Xen??
@@ -747,7 +749,9 @@
return;
}
if (check_lazy_cover && (isr & IA64_ISR_IR) && handle_lazy_cover(v,
isr, regs)) return;
- reflect_interruption(ifa,isr,itir,regs,vector);
+ PSCB(current,ifa) = ifa;
+ PSCB(current,itir) = vcpu_get_itir_on_fault(v,ifa);
+ reflect_interruption(isr,regs,vector);
}
unsigned long __hypercall_create_continuation(
diff -r c22741d000a5 -r 98fb7e03a886 xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c Thu Sep 29 23:29:23 2005
+++ b/xen/arch/ia64/xen/vcpu.c Mon Oct 3 22:27:27 2005
@@ -266,15 +266,6 @@
}
if (imm.dt) vcpu_set_metaphysical_mode(vcpu,FALSE);
__asm__ __volatile (";; mov psr.l=%0;; srlz.d"::"r"(psr):"memory");
-#if 0 // now done with deliver_pending_interrupts
- if (enabling_interrupts) {
- if (vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR) {
-//printf("with interrupts pending\n");
- return IA64_EXTINT_VECTOR;
- }
-//else printf("but nothing pending\n");
- }
-#endif
if (enabling_interrupts &&
vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR)
PSCB(vcpu,pending_interruption) = 1;
@@ -323,13 +314,6 @@
printf("*** DOMAIN TRYING TO TURN ON BIG-ENDIAN!!!\n");
return (IA64_ILLOP_FAULT);
}
- //__asm__ __volatile (";; mov psr.l=%0;; srlz.d"::"r"(psr):"memory");
-#if 0 // now done with deliver_pending_interrupts
- if (enabling_interrupts) {
- if (vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR)
- return IA64_EXTINT_VECTOR;
- }
-#endif
if (enabling_interrupts &&
vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR)
PSCB(vcpu,pending_interruption) = 1;
@@ -1245,8 +1229,8 @@
IA64FAULT vcpu_force_data_miss(VCPU *vcpu, UINT64 ifa)
{
- PSCB(vcpu,tmp[0]) = ifa; // save ifa in vcpu structure, then
specify IA64_FORCED_IFA
- return (vcpu_get_rr_ve(vcpu,ifa) ? IA64_DATA_TLB_VECTOR :
IA64_ALT_DATA_TLB_VECTOR) | IA64_FORCED_IFA;
+ PSCB(vcpu,ifa) = ifa;
+ return (vcpu_get_rr_ve(vcpu,ifa) ? IA64_DATA_TLB_VECTOR :
IA64_ALT_DATA_TLB_VECTOR);
}
@@ -1398,9 +1382,14 @@
/* check guest VHPT */
pta = PSCB(vcpu,pta);
rr.rrval = PSCB(vcpu,rrs)[address>>61];
- if (!rr.ve || !(pta & IA64_PTA_VE))
+ if (!rr.ve || !(pta & IA64_PTA_VE)) {
+// FIXME? does iha get set for alt faults? does xenlinux depend on it?
+ vcpu_thash(vcpu, address, iha);
+// FIXME?: does itir get set for alt faults?
+ *itir = vcpu_get_itir_on_fault(vcpu,address);
return (is_data ? IA64_ALT_DATA_TLB_VECTOR :
IA64_ALT_INST_TLB_VECTOR);
+ }
if (pta & IA64_PTA_VF) { /* long format VHPT - not implemented */
// thash won't work right?
panic_domain(vcpu_regs(vcpu),"can't do long format VHPT\n");
@@ -1414,6 +1403,7 @@
vcpu_thash(vcpu, address, iha);
if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0)
+// FIXME?: does itir get set for vhpt faults?
return IA64_VHPT_FAULT;
/*
@@ -1444,11 +1434,7 @@
*padr = (pteval & _PAGE_PPN_MASK & mask) | (vadr & ~mask);
return (IA64_NO_FAULT);
}
- else
- {
- PSCB(vcpu,tmp[0]) = vadr; // save ifa in vcpu structure,
then specify IA64_FORCED_IFA
- return (fault | IA64_FORCED_IFA);
- }
+ return vcpu_force_data_miss(vcpu,vadr);
}
IA64FAULT vcpu_tak(VCPU *vcpu, UINT64 vadr, UINT64 *key)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|