ia64/xen-unstable

changeset 5364:7aa93c8e8029

bitkeeper revision 1.1668.1.4 (42a61917UcK9_yMNGefxIVZZpXkEpQ)

More hyperprivop work
Signed-off by: Dan Magenheimer <dan.magenheimer@hp.com>
author djm@kirby.fc.hp.com
date Tue Jun 07 22:00:55 2005 +0000 (2005-06-07)
parents f6850d7aec27
children ba7d283dc8dd
files xen/arch/ia64/asm-offsets.c xen/arch/ia64/hyperprivop.S xen/arch/ia64/process.c
line diff
     1.1 --- a/xen/arch/ia64/asm-offsets.c	Mon Jun 06 20:55:26 2005 +0000
     1.2 +++ b/xen/arch/ia64/asm-offsets.c	Tue Jun 07 22:00:55 2005 +0000
     1.3 @@ -49,6 +49,7 @@ void foo(void)
     1.4  	DEFINE(XSI_IPSR, (SHAREDINFO_ADDR+offsetof(vcpu_info_t, arch.ipsr)));
     1.5  	DEFINE(XSI_IPSR_OFS, offsetof(vcpu_info_t, arch.ipsr));
     1.6  	DEFINE(XSI_IFS_OFS, offsetof(vcpu_info_t, arch.ifs));
     1.7 +	DEFINE(XSI_ISR_OFS, offsetof(vcpu_info_t, arch.isr));
     1.8  	DEFINE(XSI_IIM_OFS, offsetof(vcpu_info_t, arch.iim));
     1.9  	DEFINE(XSI_BANKNUM_OFS, offsetof(vcpu_info_t, arch.banknum));
    1.10  	DEFINE(XSI_BANK0_OFS, offsetof(vcpu_info_t, arch.bank0_regs[0]));
     2.1 --- a/xen/arch/ia64/hyperprivop.S	Mon Jun 06 20:55:26 2005 +0000
     2.2 +++ b/xen/arch/ia64/hyperprivop.S	Tue Jun 07 22:00:55 2005 +0000
     2.3 @@ -14,6 +14,23 @@
     2.4  #include <asm/system.h>
     2.5  #include <public/arch-ia64.h>
     2.6  
     2.7 +#define FAST_HYPERPRIVOP_CNT
     2.8 +
     2.9 +// Should be included from common header file (also in process.c)
    2.10 +//  NO PSR_CLR IS DIFFERENT! (CPL)
    2.11 +#define IA64_PSR_CPL1	(__IA64_UL(1) << IA64_PSR_CPL1_BIT)
    2.12 +// note IA64_PSR_PK removed from following, why is this necessary?
    2.13 +#define	DELIVER_PSR_SET	(IA64_PSR_IC | IA64_PSR_I | \
    2.14 +			IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_CPL1 | \
    2.15 +			IA64_PSR_IT | IA64_PSR_BN)
    2.16 +
    2.17 +#define	DELIVER_PSR_CLR	(IA64_PSR_AC | IA64_PSR_DFL | IA64_PSR_DFH | \
    2.18 +			IA64_PSR_SP | IA64_PSR_DI | IA64_PSR_SI |	\
    2.19 +			IA64_PSR_DB | IA64_PSR_LP | IA64_PSR_TB | \
    2.20 +			IA64_PSR_MC | IA64_PSR_IS | \
    2.21 +			IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD | \
    2.22 +			IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | IA64_PSR_IA)
    2.23 +
    2.24  // Note: not hand-scheduled for now
    2.25  //  Registers at entry
    2.26  //	r16 == cr.isr
    2.27 @@ -22,7 +39,13 @@
    2.28  //	r19 == vpsr.ic (low 32 bits) | vpsr.i (high 32 bits)
    2.29  //	r31 == pr
    2.30  GLOBAL_ENTRY(fast_hyperprivop)
    2.31 -	//cover;;
    2.32 +#if 1
    2.33 +	// HYPERPRIVOP_SSM_I?
    2.34 +	// assumes domain interrupts pending, so just do it
    2.35 +	cmp.eq p7,p6=XEN_HYPER_SSM_I,r17
    2.36 +(p7)	br.sptk.many hyper_ssm_i;;
    2.37 +#endif
    2.38 +#if 1
    2.39  	// if domain interrupts pending, give up for now and do it the slow way
    2.40  	adds r20=XSI_PEND_OFS-XSI_PSR_IC_OFS,r18 ;;
    2.41  	ld8 r20=[r20] ;;
    2.42 @@ -33,21 +56,13 @@ GLOBAL_ENTRY(fast_hyperprivop)
    2.43  	cmp.eq p7,p6=XEN_HYPER_RFI,r17
    2.44  (p7)	br.sptk.many hyper_rfi;;
    2.45  
    2.46 -#if 0
    2.47 -	// HYPERPRIVOP_SSM_I?
    2.48 -	cmp.eq p7,p6=XEN_HYPER_SSM_I,r17
    2.49 -(p7)	br.sptk.many hyper_ssm_i;;
    2.50 -#endif
    2.51 -
    2.52 -#if 1
    2.53  // hard to test, because only called from rbs_switch
    2.54  	// HYPERPRIVOP_COVER?
    2.55  	cmp.eq p7,p6=XEN_HYPER_COVER,r17
    2.56  (p7)	br.sptk.many hyper_cover;;
    2.57  #endif
    2.58  
    2.59 -#if 0 // FIXME: This inexplicably causes the number of ssm_dt's to
    2.60 -      // skyrocket, thus slowing down everything
    2.61 +#if 1
    2.62  	// HYPERPRIVOP_SSM_DT?
    2.63  	cmp.eq p7,p6=XEN_HYPER_SSM_DT,r17
    2.64  (p7)	br.sptk.many hyper_ssm_dt;;
    2.65 @@ -62,6 +77,141 @@ GLOBAL_ENTRY(fast_hyperprivop)
    2.66  	// if not one of the above, give up for now and do it the slow way
    2.67  	br.sptk.many dispatch_break_fault ;;
    2.68  
    2.69 +
    2.70 +// give up for now if: ipsr.be==1, ipsr.pp==1
    2.71 +// from reflect_interruption, don't need to:
    2.72 +//  - printf first extint (debug only)
    2.73 +//  - check for interrupt collection enabled (routine will force on)
    2.74 +//  - set ifa (not valid for extint)
    2.75 +//  - set iha (not valid for extint)
    2.76 +//  - set itir (not valid for extint)
    2.77 +// DO need to
    2.78 +//  - increment the HYPER_SSM_I fast_hyperprivop counter
    2.79 +//  - set shared_mem iip to instruction after HYPER_SSM_I
    2.80 +//  - set cr.iip to guest iva+0x3000
    2.81 +//  - set shared_mem ipsr to [vcpu_get_ipsr_int_state]
    2.82 +//     be = pp = bn = 0; dt = it = rt = 1; cpl = 3 or 0;
    2.83 +//     i = shared_mem interrupt_delivery_enabled
    2.84 +//     ic = shared_mem interrupt_collection_enabled
    2.85 +//     ri = instruction after HYPER_SSM_I
    2.86 +//     all other bits unchanged from real cr.ipsr
    2.87 +//  - set cr.ipsr (DELIVER_PSR_SET/CLEAR, don't forget cpl!)
    2.88 +//  - set shared_mem isr: isr.ei to instr following HYPER_SSM_I
    2.89 +//	and isr.ri to cr.isr.ri (all other bits zero)
    2.90 +//  - cover and set shared_mem precover_ifs to cr.ifs
    2.91 +//		^^^ MISSED THIS FOR fast_break??
    2.92 +//  - set shared_mem ifs and incomplete_regframe to 0
    2.93 +//  - set shared_mem interrupt_delivery_enabled to 0
    2.94 +//  - set shared_mem interrupt_collection_enabled to 0
    2.95 +//  - set r31 to SHAREDINFO_ADDR
    2.96 +//  - virtual bank switch 0
    2.97 +// maybe implement later
    2.98 +//  - verify that there really IS a deliverable interrupt pending
    2.99 +//  - set shared_mem iva
   2.100 +// needs to be done but not implemented (in reflect_interruption)
   2.101 +//  - set shared_mem iipa
   2.102 +// don't know for sure
   2.103 +//  - set shared_mem unat
   2.104 +//	r16 == cr.isr
   2.105 +//	r17 == cr.iim
   2.106 +//	r18 == XSI_PSR_IC
   2.107 +//	r19 == vpsr.ic (low 32 bits) | vpsr.i (high 32 bits)
   2.108 +//	r22 == IA64_KR(CURRENT)+IA64_VCPU_BREAKIMM_OFFSET
   2.109 +//	r31 == pr
   2.110 +ENTRY(hyper_ssm_i)
   2.111 +	// give up for now if: ipsr.be==1, ipsr.pp==1
   2.112 +	mov r30=cr.ipsr;;
   2.113 +	mov r29=cr.iip;;
   2.114 +	extr.u r21=r30,IA64_PSR_BE_BIT,1 ;;
   2.115 +	cmp.ne p7,p0=r21,r0
   2.116 +(p7)	br.sptk.many dispatch_break_fault ;;
   2.117 +	extr.u r21=r30,IA64_PSR_PP_BIT,1 ;;
   2.118 +	cmp.ne p7,p0=r21,r0
   2.119 +(p7)	br.sptk.many dispatch_break_fault ;;
   2.120 +#ifdef FAST_HYPERPRIVOP_CNT
   2.121 +	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_SSM_I);;
   2.122 +	ld8 r21=[r20];;
   2.123 +	adds r21=1,r21;;
   2.124 +	st8 [r20]=r21;;
   2.125 +#endif
   2.126 +	// set shared_mem iip to instruction after HYPER_SSM_I
   2.127 +extr.u r20=r30,41,2 ;;
   2.128 +cmp.eq p6,p7=2,r20 ;;
   2.129 +(p6)	mov r20=0
   2.130 +(p6)	adds r29=16,r29
   2.131 +(p7)	adds r20=1,r20 ;;
   2.132 +	dep r30=r20,r30,41,2;;	// adjust cr.ipsr.ri but don't save yet
   2.133 +	adds r21=XSI_IIP_OFS-XSI_PSR_IC_OFS,r18 ;;
   2.134 +	st8 [r21]=r29 ;;
   2.135 +	// set shared_mem isr
   2.136 +	extr.u r16=r16,38,1;;	// grab cr.isr.ir bit
   2.137 +	dep r16=r16,r0,38,1 ;;	// insert into cr.isr (rest of bits zero)
   2.138 +	dep r16=r20,r16,41,2 ;; // deposit cr.isr.ri
   2.139 +	adds r21=XSI_ISR_OFS-XSI_PSR_IC_OFS,r18 ;; 
   2.140 +	st8 [r21]=r16 ;;
   2.141 +	// set cr.ipsr
   2.142 +	mov r29=r30 ;;
   2.143 +	movl r28=DELIVER_PSR_SET;;
   2.144 +	movl r27=~DELIVER_PSR_CLR;;
   2.145 +	or r29=r29,r28;;
   2.146 +	and r29=r29,r27;;
   2.147 +	mov cr.ipsr=r29;;
   2.148 +	// set shared_mem ipsr (from ipsr in r30 with ipsr.ri already set)
   2.149 +	extr.u r29=r30,IA64_PSR_CPL0_BIT,2;;
   2.150 +	cmp.eq p6,p7=3,r29;;
   2.151 +(p6)	dep r30=-1,r30,IA64_PSR_CPL0_BIT,2
   2.152 +(p7)	dep r30=0,r30,IA64_PSR_CPL0_BIT,2
   2.153 +	;;
   2.154 +	// FOR SSM_I ONLY, also turn on psr.i and psr.ic
   2.155 +	movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT|IA64_PSR_I|IA64_PSR_IC);;
   2.156 +	movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN);;
   2.157 +	or r30=r30,r28;;
   2.158 +	and r30=r30,r27;;
   2.159 +	adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
   2.160 +	st8 [r21]=r30 ;;
   2.161 +	// set shared_mem interrupt_delivery_enabled to 0
   2.162 +	// set shared_mem interrupt_collection_enabled to 0
   2.163 +	st8 [r18]=r0;;
   2.164 +	// cover and set shared_mem precover_ifs to cr.ifs
   2.165 +	// set shared_mem ifs and incomplete_regframe to 0
   2.166 +	cover ;;
   2.167 +	mov r20=cr.ifs;;
   2.168 +	adds r21=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
   2.169 +	st4 [r21]=r0 ;;
   2.170 +	adds r21=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   2.171 +	st8 [r21]=r0 ;;
   2.172 +	adds r21=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   2.173 +	st8 [r21]=r20 ;;
   2.174 +	// leave cr.ifs alone for later rfi
   2.175 +	// set iip to go to domain IVA break instruction vector
   2.176 +	mov r22=IA64_KR(CURRENT);;
   2.177 +	adds r22=IA64_VCPU_IVA_OFFSET,r22;;
   2.178 +	ld8 r23=[r22];;
   2.179 +	movl r24=0x3000;;
   2.180 +	add r24=r24,r23;;
   2.181 +	mov cr.iip=r24;;
   2.182 +	// OK, now all set to go except for switch to virtual bank0
   2.183 +	mov r30=r2; mov r29=r3;;
   2.184 +	adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
   2.185 +	adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
   2.186 +	bsw.1;;
   2.187 +	st8 [r2]=r16,16; st8 [r3]=r17,16 ;;
   2.188 +	st8 [r2]=r18,16; st8 [r3]=r19,16 ;;
   2.189 +	st8 [r2]=r20,16; st8 [r3]=r21,16 ;;
   2.190 +	st8 [r2]=r22,16; st8 [r3]=r23,16 ;;
   2.191 +	st8 [r2]=r24,16; st8 [r3]=r25,16 ;;
   2.192 +	st8 [r2]=r26,16; st8 [r3]=r27,16 ;;
   2.193 +	st8 [r2]=r28,16; st8 [r3]=r29,16 ;;
   2.194 +	st8 [r2]=r30,16; st8 [r3]=r31,16 ;;
   2.195 +	movl r31=XSI_IPSR;;
   2.196 +	bsw.0 ;;
   2.197 +	mov r2=r30; mov r3=r29;;
   2.198 +	adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
   2.199 +	st4 [r20]=r0 ;;
   2.200 +	mov pr=r31,-1 ;;
   2.201 +	rfi
   2.202 +	;;
   2.203 +
   2.204  // reflect domain breaks directly to domain
   2.205  // FIXME: DOES NOT WORK YET
   2.206  //	r16 == cr.isr
   2.207 @@ -150,7 +300,6 @@ GLOBAL_ENTRY(fast_break_reflect)
   2.208  
   2.209  // ensure that, if giving up, registers at entry to fast_hyperprivop unchanged
   2.210  ENTRY(hyper_rfi)
   2.211 -#define FAST_HYPERPRIVOP_CNT
   2.212  #ifdef FAST_HYPERPRIVOP_CNT
   2.213  	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_RFI);;
   2.214  	ld8 r21=[r20];;
   2.215 @@ -276,7 +425,7 @@ ENTRY(hyper_ssm_dt)
   2.216  	srlz.i;;
   2.217  	st4 [r20]=r0 ;;
   2.218  	// adjust return address to skip over break instruction
   2.219 -	extr.u r26=r24,41,2 ;;
   2.220 +1:	extr.u r26=r24,41,2 ;;
   2.221  	cmp.eq p6,p7=2,r26 ;;
   2.222  (p6)	mov r26=0
   2.223  (p6)	adds r25=16,r25
   2.224 @@ -286,7 +435,7 @@ ENTRY(hyper_ssm_dt)
   2.225  	;;
   2.226  	mov cr.ipsr=r24
   2.227  	mov cr.iip=r25
   2.228 -1:	mov pr=r31,-1 ;;
   2.229 +	mov pr=r31,-1 ;;
   2.230  	rfi
   2.231  	;;
   2.232  
   2.233 @@ -312,7 +461,7 @@ ENTRY(hyper_rsm_dt)
   2.234  	adds r21=1,r0 ;;
   2.235  	st4 [r20]=r21 ;;
   2.236  	// adjust return address to skip over break instruction
   2.237 -	extr.u r26=r24,41,2 ;;
   2.238 +1:	extr.u r26=r24,41,2 ;;
   2.239  	cmp.eq p6,p7=2,r26 ;;
   2.240  (p6)	mov r26=0
   2.241  (p6)	adds r25=16,r25
   2.242 @@ -322,26 +471,7 @@ ENTRY(hyper_rsm_dt)
   2.243  	;;
   2.244  	mov cr.ipsr=r24
   2.245  	mov cr.iip=r25
   2.246 -1:	mov pr=r31,-1 ;;
   2.247 -	rfi
   2.248 -	;;
   2.249 -
   2.250 -// enable interrupts (and also interrupt collection)
   2.251 -ENTRY(hyper_ssm_i)
   2.252 -#ifdef FAST_HYPERPRIVOP_CNT
   2.253 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_SSM_I);;
   2.254 -	ld8 r21=[r20];;
   2.255 -	adds r21=1,r21;;
   2.256 -	st8 [r20]=r21;;
   2.257 -#endif
   2.258 -	mov r24=cr.ipsr
   2.259 -	mov r25=cr.iip;;
   2.260 -	movl r20=0x100000001;;
   2.261 -	st8 [r18]=r20;;	// turn on both vpsr.i and vpsr.ic
   2.262 -// FIXME: NEED TO UPDATE IPSR/IIP TO SKIP BREAK INST
   2.263 -// FIXME: NEED TO CHECK FOR PENDING INTERRUPTS AND DELIVER THEM!
   2.264 -1:	mov pr=r31,-1 ;;
   2.265 +	mov pr=r31,-1 ;;
   2.266  	rfi
   2.267  	;;
   2.268  #endif
   2.269 -
     3.1 --- a/xen/arch/ia64/process.c	Mon Jun 06 20:55:26 2005 +0000
     3.2 +++ b/xen/arch/ia64/process.c	Tue Jun 07 22:00:55 2005 +0000
     3.3 @@ -238,6 +238,8 @@ panic_domain(regs,"psr.ic off, deliverin
     3.4  
     3.5  void foodpi(void) {}
     3.6  
     3.7 +unsigned long pending_false_positive = 0;
     3.8 +
     3.9  // ONLY gets called from ia64_leave_kernel
    3.10  // ONLY call with interrupts disabled?? (else might miss one?)
    3.11  // NEVER successful if already reflecting a trap/fault because psr.i==0
    3.12 @@ -254,6 +256,8 @@ void deliver_pending_interrupt(struct pt
    3.13  printf("*#*#*#* about to deliver early timer to domain %d!!!\n",v->domain->domain_id);
    3.14  			reflect_interruption(0,isr,0,regs,IA64_EXTINT_VECTOR);
    3.15  		}
    3.16 +		else if (PSCB(v,pending_interruption))
    3.17 +			++pending_false_positive;
    3.18  	}
    3.19  }
    3.20  
    3.21 @@ -764,7 +768,7 @@ if (!running_on_sim) { printf("SSC_OPEN,
    3.22  		vcpu_set_gr(current,8,-1L);
    3.23  		break;
    3.24  	    default:
    3.25 -		printf("ia64_handle_break: bad ssc code %lx\n",ssc);
    3.26 +		printf("ia64_handle_break: bad ssc code %lx, iip=%p\n",ssc,regs->cr_iip);
    3.27  		break;
    3.28  	}
    3.29  	vcpu_increment_iip(current);