ia64/xen-unstable

changeset 7142:98fb7e03a886

Some cleanup of reflection code
author djm@kirby.fc.hp.com
date Mon Oct 03 16:27:27 2005 -0600 (2005-10-03)
parents c22741d000a5
children f81e637e7741
files xen/arch/ia64/xen/process.c xen/arch/ia64/xen/vcpu.c
line diff
     1.1 --- a/xen/arch/ia64/xen/process.c	Thu Sep 29 17:29:23 2005 -0600
     1.2 +++ b/xen/arch/ia64/xen/process.c	Mon Oct 03 16:27:27 2005 -0600
     1.3 @@ -165,59 +165,34 @@ int dump_reflect_counts(char *buf)
     1.4  	return s - buf;
     1.5  }
     1.6  
     1.7 -void reflect_interruption(unsigned long ifa, unsigned long isr, unsigned long itiriim, struct pt_regs *regs, unsigned long vector)
     1.8 +// should never panic domain... if it does, stack may have been overrun
     1.9 +void check_bad_nested_interruption(unsigned long isr, struct pt_regs *regs, unsigned long vector)
    1.10  {
    1.11 -	unsigned long vcpu_get_ipsr_int_state(struct vcpu *,unsigned long);
    1.12 -	unsigned long vcpu_get_rr_ve(struct vcpu *,unsigned long);
    1.13 -	struct domain *d = current->domain;
    1.14  	struct vcpu *v = current;
    1.15  
    1.16 -	if (vector == IA64_EXTINT_VECTOR) {
    1.17 -
    1.18 -		extern unsigned long vcpu_verbose, privop_trace;
    1.19 -		static first_extint = 1;
    1.20 -		if (first_extint) {
    1.21 -			printf("Delivering first extint to domain: ifa=%p, isr=%p, itir=%p, iip=%p\n",ifa,isr,itiriim,regs->cr_iip);
    1.22 -			//privop_trace = 1; vcpu_verbose = 1;
    1.23 -			first_extint = 0;
    1.24 -		}
    1.25 +	if (!(PSCB(v,ipsr) & IA64_PSR_DT)) {
    1.26 +		panic_domain(regs,"psr.dt off, trying to deliver nested dtlb!\n");
    1.27  	}
    1.28 -	if (!PSCB(v,interrupt_collection_enabled)) {
    1.29 -		if (!(PSCB(v,ipsr) & IA64_PSR_DT)) {
    1.30 -			panic_domain(regs,"psr.dt off, trying to deliver nested dtlb!\n");
    1.31 -		}
    1.32 -		vector &= ~0xf;
    1.33 -		if (vector != IA64_DATA_TLB_VECTOR &&
    1.34 -		    vector != IA64_ALT_DATA_TLB_VECTOR &&
    1.35 -		    vector != IA64_VHPT_TRANS_VECTOR) {
    1.36 +	if (vector != IA64_DATA_TLB_VECTOR &&
    1.37 +		vector != IA64_ALT_DATA_TLB_VECTOR &&
    1.38 +		vector != IA64_VHPT_TRANS_VECTOR) {
    1.39  panic_domain(regs,"psr.ic off, delivering fault=%lx,ipsr=%p,iip=%p,ifa=%p,isr=%p,PSCB.iip=%p\n",
    1.40 -	vector,regs->cr_ipsr,regs->cr_iip,ifa,isr,PSCB(v,iip));
    1.41 -			
    1.42 -		}
    1.43 -//printf("Delivering NESTED DATA TLB fault\n");
    1.44 -		vector = IA64_DATA_NESTED_TLB_VECTOR;
    1.45 -		regs->cr_iip = ((unsigned long) PSCBX(v,iva) + vector) & ~0xffUL;
    1.46 -		regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
    1.47 -// NOTE: nested trap must NOT pass PSCB address
    1.48 -		//regs->r31 = (unsigned long) &PSCB(v);
    1.49 -		inc_slow_reflect_count(vector);
    1.50 -		return;
    1.51 +	vector,regs->cr_ipsr,regs->cr_iip,PSCB(v,ifa),isr,PSCB(v,iip));
    1.52 +	}
    1.53 +}
    1.54  
    1.55 -	}
    1.56 -	if ((vector & 0xf) == IA64_FORCED_IFA)
    1.57 -		ifa = PSCB(v,tmp[0]);
    1.58 -	vector &= ~0xf;
    1.59 -	PSCB(v,ifa) = ifa;
    1.60 -	if (vector < IA64_DATA_NESTED_TLB_VECTOR) /* VHPT miss, TLB miss, Alt TLB miss */
    1.61 -		vcpu_thash(v,ifa,&PSCB(current,iha));
    1.62 +void reflect_interruption(unsigned long isr, struct pt_regs *regs, unsigned long vector)
    1.63 +{
    1.64 +	unsigned long vcpu_get_ipsr_int_state(struct vcpu *,unsigned long);
    1.65 +	struct vcpu *v = current;
    1.66 +
    1.67 +	if (!PSCB(v,interrupt_collection_enabled))
    1.68 +		check_bad_nested_interruption(isr,regs,vector);
    1.69  	PSCB(v,unat) = regs->ar_unat;  // not sure if this is really needed?
    1.70  	PSCB(v,precover_ifs) = regs->cr_ifs;
    1.71  	vcpu_bsw0(v);
    1.72  	PSCB(v,ipsr) = vcpu_get_ipsr_int_state(v,regs->cr_ipsr);
    1.73 -	if (vector == IA64_BREAK_VECTOR || vector == IA64_SPECULATION_VECTOR)
    1.74 -		PSCB(v,iim) = itiriim;
    1.75 -	else PSCB(v,itir) = vcpu_get_itir_on_fault(v,ifa);
    1.76 -	PSCB(v,isr) = isr; // this is unnecessary except for interrupts!
    1.77 +	PSCB(v,isr) = isr;
    1.78  	PSCB(v,iip) = regs->cr_iip;
    1.79  	PSCB(v,ifs) = 0;
    1.80  	PSCB(v,incomplete_regframe) = 0;
    1.81 @@ -239,6 +214,24 @@ void foodpi(void) {}
    1.82  
    1.83  unsigned long pending_false_positive = 0;
    1.84  
    1.85 +void reflect_extint(struct pt_regs *regs)
    1.86 +{
    1.87 +	extern unsigned long vcpu_verbose, privop_trace;
    1.88 +	unsigned long isr = regs->cr_ipsr & IA64_PSR_RI;
    1.89 +	struct vcpu *v = current;
    1.90 +	static first_extint = 1;
    1.91 +
    1.92 +	if (first_extint) {
    1.93 +		printf("Delivering first extint to domain: isr=%p, iip=%p\n",isr,regs->cr_iip);
    1.94 +		//privop_trace = 1; vcpu_verbose = 1;
    1.95 +		first_extint = 0;
    1.96 +	}
    1.97 +	if (vcpu_timer_pending_early(v))
    1.98 +printf("*#*#*#* about to deliver early timer to domain %d!!!\n",v->domain->domain_id);
    1.99 +	PSCB(current,itir) = 0;
   1.100 +	reflect_interruption(isr,regs,IA64_EXTINT_VECTOR);
   1.101 +}
   1.102 +
   1.103  // ONLY gets called from ia64_leave_kernel
   1.104  // ONLY call with interrupts disabled?? (else might miss one?)
   1.105  // NEVER successful if already reflecting a trap/fault because psr.i==0
   1.106 @@ -249,12 +242,8 @@ void deliver_pending_interrupt(struct pt
   1.107  	// FIXME: Will this work properly if doing an RFI???
   1.108  	if (!is_idle_task(d) && user_mode(regs)) {
   1.109  		//vcpu_poke_timer(v);
   1.110 -		if (vcpu_deliverable_interrupts(v)) {
   1.111 -			unsigned long isr = regs->cr_ipsr & IA64_PSR_RI;
   1.112 -			if (vcpu_timer_pending_early(v))
   1.113 -printf("*#*#*#* about to deliver early timer to domain %d!!!\n",v->domain->domain_id);
   1.114 -			reflect_interruption(0,isr,0,regs,IA64_EXTINT_VECTOR);
   1.115 -		}
   1.116 +		if (vcpu_deliverable_interrupts(v))
   1.117 +			reflect_extint(regs);
   1.118  		else if (PSCB(v,pending_interruption))
   1.119  			++pending_false_positive;
   1.120  	}
   1.121 @@ -295,14 +284,12 @@ void ia64_do_page_fault (unsigned long a
   1.122  	}
   1.123  
   1.124  	fault = vcpu_translate(current,address,is_data,&pteval,&itir,&iha);
   1.125 -	if (fault == IA64_NO_FAULT)
   1.126 -	{
   1.127 +	if (fault == IA64_NO_FAULT) {
   1.128  		pteval = translate_domain_pte(pteval,address,itir);
   1.129  		vcpu_itc_no_srlz(current,is_data?2:1,address,pteval,-1UL,(itir>>2)&0x3f);
   1.130  		return;
   1.131  	}
   1.132 -	else if (IS_VMM_ADDRESS(iip))
   1.133 -	{
   1.134 +	if (IS_VMM_ADDRESS(iip)) {
   1.135  		if (!ia64_done_with_exception(regs)) {
   1.136  			// should never happen.  If it does, region 0 addr may
   1.137  			// indicate a bad xen pointer
   1.138 @@ -315,8 +302,22 @@ void ia64_do_page_fault (unsigned long a
   1.139  		}
   1.140  		return;
   1.141  	}
   1.142 +	if (!PSCB(current,interrupt_collection_enabled)) {
   1.143 +		check_bad_nested_interruption(isr,regs,fault);
   1.144 +		//printf("Delivering NESTED DATA TLB fault\n");
   1.145 +		fault = IA64_DATA_NESTED_TLB_VECTOR;
   1.146 +		regs->cr_iip = ((unsigned long) PSCBX(current,iva) + fault) & ~0xffUL;
   1.147 +		regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
   1.148 +		// NOTE: nested trap must NOT pass PSCB address
   1.149 +		//regs->r31 = (unsigned long) &PSCB(current);
   1.150 +		inc_slow_reflect_count(fault);
   1.151 +		return;
   1.152 +	}
   1.153  
   1.154 -	reflect_interruption(address, isr, 0, regs, fault);
   1.155 +	PSCB(current,itir) = itir;
   1.156 +	PSCB(current,iha) = iha;
   1.157 +	PSCB(current,ifa) = address;
   1.158 +	reflect_interruption(isr, regs, fault);
   1.159  }
   1.160  
   1.161  void
   1.162 @@ -521,7 +522,9 @@ printf("ia64_fault, vector=0x%p, ifa=%p,
   1.163  	}
   1.164  	//die_if_kernel(buf, regs, error);
   1.165  printk("ia64_fault: %s: reflecting\n",buf);
   1.166 -reflect_interruption(ifa,isr,iim,regs,IA64_GENEX_VECTOR);
   1.167 +PSCB(current,itir) = vcpu_get_itir_on_fault(current,ifa);
   1.168 +PSCB(current,ifa) = ifa;
   1.169 +reflect_interruption(isr,regs,IA64_GENEX_VECTOR);
   1.170  //while(1);
   1.171  	//force_sig(SIGILL, current);
   1.172  }
   1.173 @@ -668,7 +671,10 @@ ia64_handle_break (unsigned long ifa, st
   1.174  		if (ia64_hyperprivop(iim,regs))
   1.175  			vcpu_increment_iip(current);
   1.176  	}
   1.177 -	else reflect_interruption(ifa,isr,iim,regs,IA64_BREAK_VECTOR);
   1.178 +	else {
   1.179 +		PSCB(v,iim) = iim;
   1.180 +		reflect_interruption(isr,regs,IA64_BREAK_VECTOR);
   1.181 +	}
   1.182  }
   1.183  
   1.184  void
   1.185 @@ -680,10 +686,11 @@ ia64_handle_privop (unsigned long ifa, s
   1.186  	// FIXME: no need to pass itir in to this routine as we need to
   1.187  	// compute the virtual itir anyway (based on domain's RR.ps)
   1.188  	// AND ACTUALLY reflect_interruption doesn't use it anyway!
   1.189 -	itir = vcpu_get_itir_on_fault(v,ifa);
   1.190  	vector = priv_emulate(current,regs,isr);
   1.191  	if (vector != IA64_NO_FAULT && vector != IA64_RFI_IN_PROGRESS) {
   1.192 -		reflect_interruption(ifa,isr,itir,regs,vector);
   1.193 +		PSCB(current,itir) =
   1.194 +			vcpu_get_itir_on_fault(v,PSCB(current,ifa));
   1.195 +		reflect_interruption(isr,regs,vector);
   1.196  	}
   1.197  }
   1.198  
   1.199 @@ -697,15 +704,10 @@ ia64_handle_reflection (unsigned long if
   1.200  	struct vcpu *v = (struct domain *) current;
   1.201  	unsigned long check_lazy_cover = 0;
   1.202  	unsigned long psr = regs->cr_ipsr;
   1.203 -	unsigned long itir = vcpu_get_itir_on_fault(v,ifa);
   1.204  
   1.205  	if (!(psr & IA64_PSR_CPL)) {
   1.206  		printk("ia64_handle_reflection: reflecting with priv=0!!\n");
   1.207  	}
   1.208 -	// FIXME: no need to pass itir in to this routine as we need to
   1.209 -	// compute the virtual itir anyway (based on domain's RR.ps)
   1.210 -	// AND ACTUALLY reflect_interruption doesn't use it anyway!
   1.211 -	itir = vcpu_get_itir_on_fault(v,ifa);
   1.212  	switch(vector) {
   1.213  	    case 8:
   1.214  		vector = IA64_DIRTY_BIT_VECTOR; break;
   1.215 @@ -736,7 +738,7 @@ printf("*** Handled privop masquerading 
   1.216  		vector = IA64_NAT_CONSUMPTION_VECTOR; break;
   1.217  	    case 27:
   1.218  //printf("*** Handled speculation vector, itc=%lx!\n",ia64_get_itc());
   1.219 -		itir = iim;
   1.220 +		PSCB(current,iim) = iim;
   1.221  		vector = IA64_SPECULATION_VECTOR; break;
   1.222  	    case 30:
   1.223  		// FIXME: Should we handle unaligned refs in Xen??
   1.224 @@ -747,7 +749,9 @@ printf("*** Handled privop masquerading 
   1.225  		return;
   1.226  	}
   1.227  	if (check_lazy_cover && (isr & IA64_ISR_IR) && handle_lazy_cover(v, isr, regs)) return;
   1.228 -	reflect_interruption(ifa,isr,itir,regs,vector);
   1.229 +	PSCB(current,ifa) = ifa;
   1.230 +	PSCB(current,itir) = vcpu_get_itir_on_fault(v,ifa);
   1.231 +	reflect_interruption(isr,regs,vector);
   1.232  }
   1.233  
   1.234  unsigned long __hypercall_create_continuation(
     2.1 --- a/xen/arch/ia64/xen/vcpu.c	Thu Sep 29 17:29:23 2005 -0600
     2.2 +++ b/xen/arch/ia64/xen/vcpu.c	Mon Oct 03 16:27:27 2005 -0600
     2.3 @@ -266,15 +266,6 @@ IA64FAULT vcpu_set_psr_sm(VCPU *vcpu, UI
     2.4  	}
     2.5  	if (imm.dt) vcpu_set_metaphysical_mode(vcpu,FALSE);
     2.6  	__asm__ __volatile (";; mov psr.l=%0;; srlz.d"::"r"(psr):"memory");
     2.7 -#if 0 // now done with deliver_pending_interrupts
     2.8 -	if (enabling_interrupts) {
     2.9 -		if (vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR) {
    2.10 -//printf("with interrupts pending\n");
    2.11 -			return IA64_EXTINT_VECTOR;
    2.12 -		}
    2.13 -//else printf("but nothing pending\n");
    2.14 -	}
    2.15 -#endif
    2.16  	if (enabling_interrupts &&
    2.17  		vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR)
    2.18  			PSCB(vcpu,pending_interruption) = 1;
    2.19 @@ -323,13 +314,6 @@ IA64FAULT vcpu_set_psr_l(VCPU *vcpu, UIN
    2.20  		printf("*** DOMAIN TRYING TO TURN ON BIG-ENDIAN!!!\n");
    2.21  		return (IA64_ILLOP_FAULT);
    2.22  	}
    2.23 -	//__asm__ __volatile (";; mov psr.l=%0;; srlz.d"::"r"(psr):"memory");
    2.24 -#if 0 // now done with deliver_pending_interrupts
    2.25 -	if (enabling_interrupts) {
    2.26 -		if (vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR)
    2.27 -			return IA64_EXTINT_VECTOR;
    2.28 -	}
    2.29 -#endif
    2.30  	if (enabling_interrupts &&
    2.31  		vcpu_check_pending_interrupts(vcpu) != SPURIOUS_VECTOR)
    2.32  			PSCB(vcpu,pending_interruption) = 1;
    2.33 @@ -1245,8 +1229,8 @@ Privileged operation emulation routines
    2.34  
    2.35  IA64FAULT vcpu_force_data_miss(VCPU *vcpu, UINT64 ifa)
    2.36  {
    2.37 -	PSCB(vcpu,tmp[0]) = ifa;	// save ifa in vcpu structure, then specify IA64_FORCED_IFA
    2.38 -	return (vcpu_get_rr_ve(vcpu,ifa) ? IA64_DATA_TLB_VECTOR : IA64_ALT_DATA_TLB_VECTOR) | IA64_FORCED_IFA;
    2.39 +	PSCB(vcpu,ifa) = ifa;
    2.40 +	return (vcpu_get_rr_ve(vcpu,ifa) ? IA64_DATA_TLB_VECTOR : IA64_ALT_DATA_TLB_VECTOR);
    2.41  }
    2.42  
    2.43  
    2.44 @@ -1398,9 +1382,14 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UIN
    2.45  	/* check guest VHPT */
    2.46  	pta = PSCB(vcpu,pta);
    2.47  	rr.rrval = PSCB(vcpu,rrs)[address>>61];
    2.48 -	if (!rr.ve || !(pta & IA64_PTA_VE))
    2.49 +	if (!rr.ve || !(pta & IA64_PTA_VE)) {
    2.50 +// FIXME? does iha get set for alt faults? does xenlinux depend on it?
    2.51 +		vcpu_thash(vcpu, address, iha);
    2.52 +// FIXME?: does itir get set for alt faults?
    2.53 +		*itir = vcpu_get_itir_on_fault(vcpu,address);
    2.54  		return (is_data ? IA64_ALT_DATA_TLB_VECTOR :
    2.55  				IA64_ALT_INST_TLB_VECTOR);
    2.56 +	}
    2.57  	if (pta & IA64_PTA_VF) { /* long format VHPT - not implemented */
    2.58  		// thash won't work right?
    2.59  		panic_domain(vcpu_regs(vcpu),"can't do long format VHPT\n");
    2.60 @@ -1414,6 +1403,7 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UIN
    2.61  
    2.62  	vcpu_thash(vcpu, address, iha);
    2.63  	if (__copy_from_user(&pte, (void *)(*iha), sizeof(pte)) != 0)
    2.64 +// FIXME?: does itir get set for vhpt faults?
    2.65  		return IA64_VHPT_FAULT;
    2.66  
    2.67  	/*
    2.68 @@ -1444,11 +1434,7 @@ IA64FAULT vcpu_tpa(VCPU *vcpu, UINT64 va
    2.69  		*padr = (pteval & _PAGE_PPN_MASK & mask) | (vadr & ~mask);
    2.70  		return (IA64_NO_FAULT);
    2.71  	}
    2.72 -	else
    2.73 -	{
    2.74 -		PSCB(vcpu,tmp[0]) = vadr;       // save ifa in vcpu structure, then specify IA64_FORCED_IFA
    2.75 -		return (fault | IA64_FORCED_IFA);
    2.76 -	}
    2.77 +	return vcpu_force_data_miss(vcpu,vadr);
    2.78  }
    2.79  
    2.80  IA64FAULT vcpu_tak(VCPU *vcpu, UINT64 vadr, UINT64 *key)