ia64/xen-unstable

changeset 9987:c3506e73b63e

[IA64] Display the information in fault handler

This patch modifies the interruption handler to display the
information about the interruption and then do panic in the case of the
fault occurred in hypervisor, or reflect to the guest when handling the
fault in guest.

The modification is as follows:
1. In each handler in IVT, the procedure is added to branch to fault
handler or reflection according to ipsr.cpl.
2. In the case of the fault occurred in hypervisor(ipsr.cpl==0), the
fault handler displays the information (vector, registers, and stack by
calling show_registers()), and then do panic().
3. In the case of the fault occurred in guest(ipsr.cpl!=0), it is
reflected to the guest.

With this modification, some faults which were always treated to be
reflected to the guest are changed to do panic when they occur in
hypervisor.

Signed-off-by: Tetsu Yamamoto <yamamoto.tetsu@jp.fujitsu.com>
author awilliam@xenbuild.aw
date Wed May 10 15:50:27 2006 -0600 (2006-05-10)
parents f024bb5f5a07
children 1283874dff10
files xen/arch/ia64/xen/ivt.S xen/arch/ia64/xen/process.c
line diff
     1.1 --- a/xen/arch/ia64/xen/ivt.S	Wed May 10 15:29:54 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/ivt.S	Wed May 10 15:50:27 2006 -0600
     1.3 @@ -100,6 +100,15 @@
     1.4  	mov r19=n;;			/* prepare to save predicates */		\
     1.5  	br.sptk.many dispatch_to_fault_handler
     1.6  
     1.7 +#define FAULT_OR_REFLECT(n)								\
     1.8 +	mov r31=pr;	 	 							\
     1.9 +	mov r20=cr.ipsr;;								\
    1.10 +	mov r19=n;	/* prepare to save predicates */				\
    1.11 +	extr.u r20=r20,IA64_PSR_CPL0_BIT,2;;   						\
    1.12 +	cmp.ne p6,p0=r0,r20; 	/* cpl != 0?*/						\
    1.13 +(p6)	br.dptk.many dispatch_reflection;						\
    1.14 +	br.sptk.few dispatch_to_fault_handler
    1.15 +
    1.16  #ifdef XEN
    1.17  #define REFLECT(n)									\
    1.18  	mov r31=pr;									\
    1.19 @@ -697,7 +706,7 @@ END(nested_dtlb_miss)
    1.20  ENTRY(ikey_miss)
    1.21  	DBG_FAULT(6)
    1.22  #ifdef XEN
    1.23 -	REFLECT(6)
    1.24 +	FAULT_OR_REFLECT(6)
    1.25  #endif
    1.26  	FAULT(6)
    1.27  END(ikey_miss)
    1.28 @@ -746,7 +755,7 @@ END(page_fault)
    1.29  ENTRY(dkey_miss)
    1.30  	DBG_FAULT(7)
    1.31  #ifdef XEN
    1.32 -	REFLECT(7)
    1.33 +	FAULT_OR_REFLECT(7)
    1.34  #endif
    1.35  	FAULT(7)
    1.36  END(dkey_miss)
    1.37 @@ -757,7 +766,7 @@ END(dkey_miss)
    1.38  ENTRY(dirty_bit)
    1.39  	DBG_FAULT(8)
    1.40  #ifdef XEN
    1.41 -	REFLECT(8)
    1.42 +	FAULT_OR_REFLECT(8)
    1.43  #endif
    1.44  	/*
    1.45  	 * What we do here is to simply turn on the dirty bit in the PTE.  We need to
    1.46 @@ -1523,7 +1532,7 @@ END(dispatch_to_fault_handler)
    1.47  ENTRY(page_not_present)
    1.48  	DBG_FAULT(20)
    1.49  #ifdef XEN
    1.50 -	REFLECT(20)
    1.51 +	FAULT_OR_REFLECT(20)
    1.52  #endif
    1.53  	mov r16=cr.ifa
    1.54  	rsm psr.dt
    1.55 @@ -1546,7 +1555,7 @@ END(page_not_present)
    1.56  ENTRY(key_permission)
    1.57  	DBG_FAULT(21)
    1.58  #ifdef XEN
    1.59 -	REFLECT(21)
    1.60 +	FAULT_OR_REFLECT(21)
    1.61  #endif
    1.62  	mov r16=cr.ifa
    1.63  	rsm psr.dt
    1.64 @@ -1562,7 +1571,7 @@ END(key_permission)
    1.65  ENTRY(iaccess_rights)
    1.66  	DBG_FAULT(22)
    1.67  #ifdef XEN
    1.68 -	REFLECT(22)
    1.69 +	FAULT_OR_REFLECT(22)
    1.70  #endif
    1.71  	mov r16=cr.ifa
    1.72  	rsm psr.dt
    1.73 @@ -1637,7 +1646,7 @@ ENTRY(disabled_fp_reg)
    1.74  	mov pr=r20,-1
    1.75  	;;
    1.76  #endif
    1.77 -	REFLECT(25)
    1.78 +	FAULT_OR_REFLECT(25)
    1.79  //floating_panic:
    1.80  //	br.sptk.many floating_panic
    1.81  	;;
    1.82 @@ -1656,7 +1665,7 @@ END(disabled_fp_reg)
    1.83  ENTRY(nat_consumption)
    1.84  	DBG_FAULT(26)
    1.85  #ifdef XEN
    1.86 -	REFLECT(26)
    1.87 +	FAULT_OR_REFLECT(26)
    1.88  #endif
    1.89  	FAULT(26)
    1.90  END(nat_consumption)
    1.91 @@ -1668,7 +1677,7 @@ ENTRY(speculation_vector)
    1.92  	DBG_FAULT(27)
    1.93  #ifdef XEN
    1.94  	// this probably need not reflect...
    1.95 -	REFLECT(27)
    1.96 +	FAULT_OR_REFLECT(27)
    1.97  #endif
    1.98  	/*
    1.99  	 * A [f]chk.[as] instruction needs to take the branch to the recovery code but
   1.100 @@ -1714,7 +1723,7 @@ END(speculation_vector)
   1.101  ENTRY(debug_vector)
   1.102  	DBG_FAULT(29)
   1.103  #ifdef XEN
   1.104 -	REFLECT(29)
   1.105 +	FAULT_OR_REFLECT(29)
   1.106  #endif
   1.107  	FAULT(29)
   1.108  END(debug_vector)
   1.109 @@ -1725,7 +1734,7 @@ END(debug_vector)
   1.110  ENTRY(unaligned_access)
   1.111  	DBG_FAULT(30)
   1.112  #ifdef XEN
   1.113 -	REFLECT(30)
   1.114 +	FAULT_OR_REFLECT(30)
   1.115  #endif
   1.116  	mov r16=cr.ipsr
   1.117  	mov r31=pr		// prepare to save predicates
   1.118 @@ -1739,7 +1748,7 @@ END(unaligned_access)
   1.119  ENTRY(unsupported_data_reference)
   1.120  	DBG_FAULT(31)
   1.121  #ifdef XEN
   1.122 -	REFLECT(31)
   1.123 +	FAULT_OR_REFLECT(31)
   1.124  #endif
   1.125  	FAULT(31)
   1.126  END(unsupported_data_reference)
   1.127 @@ -1750,7 +1759,7 @@ END(unsupported_data_reference)
   1.128  ENTRY(floating_point_fault)
   1.129  	DBG_FAULT(32)
   1.130  #ifdef XEN
   1.131 -	REFLECT(32)
   1.132 +	FAULT_OR_REFLECT(32)
   1.133  #endif
   1.134  	FAULT(32)
   1.135  END(floating_point_fault)
   1.136 @@ -1761,7 +1770,7 @@ END(floating_point_fault)
   1.137  ENTRY(floating_point_trap)
   1.138  	DBG_FAULT(33)
   1.139  #ifdef XEN
   1.140 -	REFLECT(33)
   1.141 +	FAULT_OR_REFLECT(33)
   1.142  #endif
   1.143  	FAULT(33)
   1.144  END(floating_point_trap)
   1.145 @@ -1772,7 +1781,7 @@ END(floating_point_trap)
   1.146  ENTRY(lower_privilege_trap)
   1.147  	DBG_FAULT(34)
   1.148  #ifdef XEN
   1.149 -	REFLECT(34)
   1.150 +	FAULT_OR_REFLECT(34)
   1.151  #endif
   1.152  	FAULT(34)
   1.153  END(lower_privilege_trap)
   1.154 @@ -1783,7 +1792,7 @@ END(lower_privilege_trap)
   1.155  ENTRY(taken_branch_trap)
   1.156  	DBG_FAULT(35)
   1.157  #ifdef XEN
   1.158 -	REFLECT(35)
   1.159 +	FAULT_OR_REFLECT(35)
   1.160  #endif
   1.161  	FAULT(35)
   1.162  END(taken_branch_trap)
   1.163 @@ -1794,7 +1803,7 @@ END(taken_branch_trap)
   1.164  ENTRY(single_step_trap)
   1.165  	DBG_FAULT(36)
   1.166  #ifdef XEN
   1.167 -	REFLECT(36)
   1.168 +	FAULT_OR_REFLECT(36)
   1.169  #endif
   1.170  	FAULT(36)
   1.171  END(single_step_trap)
   1.172 @@ -1853,7 +1862,7 @@ END(single_step_trap)
   1.173  ENTRY(ia32_exception)
   1.174  	DBG_FAULT(45)
   1.175  #ifdef XEN
   1.176 -	REFLECT(45)
   1.177 +	FAULT_OR_REFLECT(45)
   1.178  #endif
   1.179  	FAULT(45)
   1.180  END(ia32_exception)
   1.181 @@ -1864,7 +1873,7 @@ END(ia32_exception)
   1.182  ENTRY(ia32_intercept)
   1.183  	DBG_FAULT(46)
   1.184  #ifdef XEN
   1.185 -	REFLECT(46)
   1.186 +	FAULT_OR_REFLECT(46)
   1.187  #endif
   1.188  #ifdef	CONFIG_IA32_SUPPORT
   1.189  	mov r31=pr
   1.190 @@ -1897,7 +1906,7 @@ END(ia32_intercept)
   1.191  ENTRY(ia32_interrupt)
   1.192  	DBG_FAULT(47)
   1.193  #ifdef XEN
   1.194 -	REFLECT(47)
   1.195 +	FAULT_OR_REFLECT(47)
   1.196  #endif
   1.197  #ifdef CONFIG_IA32_SUPPORT
   1.198  	mov r31=pr
     2.1 --- a/xen/arch/ia64/xen/process.c	Wed May 10 15:29:54 2006 -0600
     2.2 +++ b/xen/arch/ia64/xen/process.c	Wed May 10 15:50:27 2006 -0600
     2.3 @@ -367,10 +367,10 @@ ia64_fault (unsigned long vector, unsign
     2.4  		"Unknown fault 9", "Unknown fault 10", "Unknown fault 11", "Unknown fault 12",
     2.5  		"Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
     2.6  	};
     2.7 -#if 0
     2.8 -printf("ia64_fault, vector=0x%p, ifa=%p, iip=%p, ipsr=%p, isr=%p\n",
     2.9 - vector, ifa, regs->cr_iip, regs->cr_ipsr, isr);
    2.10 -#endif
    2.11 +
    2.12 +	printf("ia64_fault, vector=0x%p, ifa=%p, iip=%p, ipsr=%p, isr=%p\n",
    2.13 +	       vector, ifa, regs->cr_iip, regs->cr_ipsr, isr);
    2.14 +
    2.15  
    2.16  	if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
    2.17  		/*
    2.18 @@ -383,15 +383,48 @@ printf("ia64_fault, vector=0x%p, ifa=%p,
    2.19  	}
    2.20  
    2.21  	switch (vector) {
    2.22 -	      case 24: /* General Exception */
    2.23 +	    case 0:
    2.24 +		printk("VHPT Translation.\n");
    2.25 +		break;
    2.26 +	  
    2.27 +	    case 4:
    2.28 +		printk("Alt ITLB.\n");
    2.29 +		break;
    2.30 +	  
    2.31 +	    case 6:
    2.32 +		printk("Instruction Key Miss.\n");
    2.33 +		break;
    2.34 +
    2.35 +	    case 7: 
    2.36 +		printk("Data Key Miss.\n");
    2.37 +		break;
    2.38 +
    2.39 +	    case 8: 
    2.40 +		printk("Dirty-bit.\n");
    2.41 +		break;
    2.42 +
    2.43 +	    case 20:
    2.44 +		printk("Page Not Found.\n");
    2.45 +		break;
    2.46 +
    2.47 +	    case 21:
    2.48 +		printk("Key Permission.\n");
    2.49 +		break;
    2.50 +
    2.51 +	    case 22:
    2.52 +		printk("Instruction Access Rights.\n");
    2.53 +		break;
    2.54 +
    2.55 +	    case 24: /* General Exception */
    2.56  		code = (isr >> 4) & 0xf;
    2.57  		sprintf(buf, "General Exception: %s%s", reason[code],
    2.58 -			(code == 3) ? ((isr & (1UL << 37))
    2.59 -				       ? " (RSE access)" : " (data access)") : "");
    2.60 +		        (code == 3) ? ((isr & (1UL << 37)) ? " (RSE access)" :
    2.61 +		                       " (data access)") : "");
    2.62  		if (code == 8) {
    2.63  # ifdef CONFIG_IA64_PRINT_HAZARDS
    2.64  			printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
    2.65 -			       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri,
    2.66 +			       current->comm, current->pid,
    2.67 +			       regs->cr_iip + ia64_psr(regs)->ri,
    2.68  			       regs->pr);
    2.69  # endif
    2.70  			printf("ia64_fault: returning on hazard\n");
    2.71 @@ -399,162 +432,65 @@ printf("ia64_fault, vector=0x%p, ifa=%p,
    2.72  		}
    2.73  		break;
    2.74  
    2.75 -	      case 25: /* Disabled FP-Register */
    2.76 -		if (isr & 2) {
    2.77 -			//disabled_fph_fault(regs);
    2.78 -			//return;
    2.79 -		}
    2.80 -		sprintf(buf, "Disabled FPL fault---not supposed to happen!");
    2.81 +	    case 25:
    2.82 +		printk("Disabled FP-Register.\n");
    2.83 +		break;
    2.84 +
    2.85 +	    case 26:
    2.86 +		printk("NaT consumption.\n");
    2.87 +		break;
    2.88 +
    2.89 +	    case 29:
    2.90 +		printk("Debug.\n");
    2.91  		break;
    2.92  
    2.93 -	      case 26: /* NaT Consumption */
    2.94 -		if (user_mode(regs)) {
    2.95 -			void *addr;
    2.96 -
    2.97 -			if (((isr >> 4) & 0xf) == 2) {
    2.98 -				/* NaT page consumption */
    2.99 -				//sig = SIGSEGV;
   2.100 -				//code = SEGV_ACCERR;
   2.101 -				addr = (void *) ifa;
   2.102 -			} else {
   2.103 -				/* register NaT consumption */
   2.104 -				//sig = SIGILL;
   2.105 -				//code = ILL_ILLOPN;
   2.106 -				addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
   2.107 -			}
   2.108 -			//siginfo.si_signo = sig;
   2.109 -			//siginfo.si_code = code;
   2.110 -			//siginfo.si_errno = 0;
   2.111 -			//siginfo.si_addr = addr;
   2.112 -			//siginfo.si_imm = vector;
   2.113 -			//siginfo.si_flags = __ISR_VALID;
   2.114 -			//siginfo.si_isr = isr;
   2.115 -			//force_sig_info(sig, &siginfo, current);
   2.116 -			//return;
   2.117 -		} //else if (ia64_done_with_exception(regs))
   2.118 -			//return;
   2.119 -		sprintf(buf, "NaT consumption");
   2.120 +	    case 30:
   2.121 +		printk("Unaligned Reference.\n");
   2.122  		break;
   2.123  
   2.124 -	      case 31: /* Unsupported Data Reference */
   2.125 -		if (user_mode(regs)) {
   2.126 -			//siginfo.si_signo = SIGILL;
   2.127 -			//siginfo.si_code = ILL_ILLOPN;
   2.128 -			//siginfo.si_errno = 0;
   2.129 -			//siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
   2.130 -			//siginfo.si_imm = vector;
   2.131 -			//siginfo.si_flags = __ISR_VALID;
   2.132 -			//siginfo.si_isr = isr;
   2.133 -			//force_sig_info(SIGILL, &siginfo, current);
   2.134 -			//return;
   2.135 -		}
   2.136 -		sprintf(buf, "Unsupported data reference");
   2.137 +	    case 31:
   2.138 +		printk("Unsupported data reference.\n");
   2.139 +		break;
   2.140 +
   2.141 +	    case 32:
   2.142 +		printk("Floating-Point Fault.\n");
   2.143 +		break;
   2.144 +
   2.145 +	    case 33:
   2.146 +		printk("Floating-Point Trap.\n");
   2.147  		break;
   2.148  
   2.149 -	      case 29: /* Debug */
   2.150 -	      case 35: /* Taken Branch Trap */
   2.151 -	      case 36: /* Single Step Trap */
   2.152 -		//if (fsys_mode(current, regs)) {}
   2.153 -		switch (vector) {
   2.154 -		      case 29:
   2.155 -			//siginfo.si_code = TRAP_HWBKPT;
   2.156 -#ifdef CONFIG_ITANIUM
   2.157 -			/*
   2.158 -			 * Erratum 10 (IFA may contain incorrect address) now has
   2.159 -			 * "NoFix" status.  There are no plans for fixing this.
   2.160 -			 */
   2.161 -			if (ia64_psr(regs)->is == 0)
   2.162 -			  ifa = regs->cr_iip;
   2.163 -#endif
   2.164 -			break;
   2.165 -		      case 35: ifa = 0; break;
   2.166 -		      case 36: ifa = 0; break;
   2.167 -		      //case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
   2.168 -		      //case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
   2.169 -		}
   2.170 -		//siginfo.si_signo = SIGTRAP;
   2.171 -		//siginfo.si_errno = 0;
   2.172 -		//siginfo.si_addr  = (void *) ifa;
   2.173 -		//siginfo.si_imm   = 0;
   2.174 -		//siginfo.si_flags = __ISR_VALID;
   2.175 -		//siginfo.si_isr   = isr;
   2.176 -		//force_sig_info(SIGTRAP, &siginfo, current);
   2.177 -		//return;
   2.178 +	    case 34:
   2.179 +		printk("Lower Privilege Transfer Trap.\n");
   2.180 +		break;
   2.181  
   2.182 -	      case 32: /* fp fault */
   2.183 -	      case 33: /* fp trap */
   2.184 -		//result = handle_fpu_swa((vector == 32) ? 1 : 0, regs, isr);
   2.185 -		//if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {
   2.186 -			//siginfo.si_signo = SIGFPE;
   2.187 -			//siginfo.si_errno = 0;
   2.188 -			//siginfo.si_code = FPE_FLTINV;
   2.189 -			//siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
   2.190 -			//siginfo.si_flags = __ISR_VALID;
   2.191 -			//siginfo.si_isr = isr;
   2.192 -			//siginfo.si_imm = 0;
   2.193 -			//force_sig_info(SIGFPE, &siginfo, current);
   2.194 -		//}
   2.195 -		//return;
   2.196 -		sprintf(buf, "FP fault/trap");
   2.197 +	    case 35:
   2.198 +		printk("Taken Branch Trap.\n");
   2.199 +		break;
   2.200 +
   2.201 +	    case 36:
   2.202 +		printk("Single Step Trap.\n");
   2.203 +		break;
   2.204 +    
   2.205 +	    case 45:
   2.206 +		printk("IA-32 Exception.\n");
   2.207  		break;
   2.208  
   2.209 -	      case 34:
   2.210 -		if (isr & 0x2) {
   2.211 -			/* Lower-Privilege Transfer Trap */
   2.212 -			/*
   2.213 -			 * Just clear PSR.lp and then return immediately: all the
   2.214 -			 * interesting work (e.g., signal delivery is done in the kernel
   2.215 -			 * exit path).
   2.216 -			 */
   2.217 -			//ia64_psr(regs)->lp = 0;
   2.218 -			//return;
   2.219 -			sprintf(buf, "Lower-Privilege Transfer trap");
   2.220 -		} else {
   2.221 -			/* Unimplemented Instr. Address Trap */
   2.222 -			if (user_mode(regs)) {
   2.223 -				//siginfo.si_signo = SIGILL;
   2.224 -				//siginfo.si_code = ILL_BADIADDR;
   2.225 -				//siginfo.si_errno = 0;
   2.226 -				//siginfo.si_flags = 0;
   2.227 -				//siginfo.si_isr = 0;
   2.228 -				//siginfo.si_imm = 0;
   2.229 -				//siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
   2.230 -				//force_sig_info(SIGILL, &siginfo, current);
   2.231 -				//return;
   2.232 -			}
   2.233 -			sprintf(buf, "Unimplemented Instruction Address fault");
   2.234 -		}
   2.235 +	    case 46:
   2.236 +		printk("IA-32 Intercept.\n");
   2.237 +		break;
   2.238 +
   2.239 +	    case 47:
   2.240 +		printk("IA-32 Interrupt.\n");
   2.241  		break;
   2.242  
   2.243 -	      case 45:
   2.244 -		printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
   2.245 -		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
   2.246 -		       regs->cr_iip, ifa, isr);
   2.247 -		//force_sig(SIGSEGV, current);
   2.248 -		break;
   2.249 -
   2.250 -	      case 46:
   2.251 -		printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
   2.252 -		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
   2.253 -		       regs->cr_iip, ifa, isr, iim);
   2.254 -		//force_sig(SIGSEGV, current);
   2.255 -		return;
   2.256 -
   2.257 -	      case 47:
   2.258 -		sprintf(buf, "IA-32 Interruption Fault (int 0x%lx)", isr >> 16);
   2.259 -		break;
   2.260 -
   2.261 -	      default:
   2.262 -		sprintf(buf, "Fault %lu", vector);
   2.263 +	    default:
   2.264 +		printk("Fault %lu\n", vector);
   2.265  		break;
   2.266  	}
   2.267 -	//die_if_kernel(buf, regs, error);
   2.268 -printk("ia64_fault: %s: reflecting\n",buf);
   2.269 -PSCB(current,itir) = vcpu_get_itir_on_fault(current,ifa);
   2.270 -PSCB(current,ifa) = ifa;
   2.271 -reflect_interruption(isr,regs,IA64_GENEX_VECTOR);
   2.272 -//while(1);
   2.273 -	//force_sig(SIGILL, current);
   2.274 +
   2.275 +	show_registers(regs);
   2.276 +	panic("Fault in Xen.\n");
   2.277  }
   2.278  
   2.279  unsigned long running_on_sim = 0;