[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Some cleanup of reflection code
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |