[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.