ia64/xen-unstable

changeset 5243:8356773d6de6

bitkeeper revision 1.1564.1.5 (429ccefcMIcuaJH4b_1aAdD0JTIaMg)

Two more hyperprivops
Signed-off by: Dan Magenheimer <dan.magenheimer@hp.com>
author djm@kirby.fc.hp.com
date Tue May 31 20:54:20 2005 +0000 (2005-05-31)
parents 5d02e3d0e0f6
children a0723a72717d
files xen/arch/ia64/hyperprivop.S xen/arch/ia64/privop.c xen/arch/ia64/vcpu.c xen/include/public/arch-ia64.h
line diff
     1.1 --- a/xen/arch/ia64/hyperprivop.S	Thu May 26 21:28:39 2005 +0000
     1.2 +++ b/xen/arch/ia64/hyperprivop.S	Tue May 31 20:54:20 2005 +0000
     1.3 @@ -32,11 +32,45 @@ GLOBAL_ENTRY(fast_hyperprivop)
     1.4  	// HYPERPRIVOP_RFI?
     1.5  	cmp.eq p7,p6=XEN_HYPER_RFI,r17
     1.6  (p7)	br.sptk.many hyper_rfi;;
     1.7 -	// if not rfi, give up for now and do it the slow way
     1.8 +
     1.9 +#if 0
    1.10 +	// HYPERPRIVOP_SSM_I?
    1.11 +	cmp.eq p7,p6=XEN_HYPER_SSM_I,r17
    1.12 +(p7)	br.sptk.many hyper_ssm_i;;
    1.13 +#endif
    1.14 +
    1.15 +#if 1
    1.16 +// hard to test, because only called from rbs_switch
    1.17 +	// HYPERPRIVOP_COVER?
    1.18 +	cmp.eq p7,p6=XEN_HYPER_COVER,r17
    1.19 +(p7)	br.sptk.many hyper_cover;;
    1.20 +#endif
    1.21 +
    1.22 +#if 0 // FIXME: This inexplicably causes the number of ssm_dt's to
    1.23 +      // skyrocket, thus slowing down everything
    1.24 +	// HYPERPRIVOP_SSM_DT?
    1.25 +	cmp.eq p7,p6=XEN_HYPER_SSM_DT,r17
    1.26 +(p7)	br.sptk.many hyper_ssm_dt;;
    1.27 +#endif
    1.28 +
    1.29 +#if 1
    1.30 +	// HYPERPRIVOP_RSM_DT?
    1.31 +	cmp.eq p7,p6=XEN_HYPER_RSM_DT,r17
    1.32 +(p7)	br.sptk.many hyper_rsm_dt;;
    1.33 +#endif
    1.34 +
    1.35 +	// if not one of the above, give up for now and do it the slow way
    1.36  	br.sptk.many dispatch_break_fault ;;
    1.37  
    1.38  // ensure that, if giving up, registers at entry to fast_hyperprivop unchanged
    1.39  ENTRY(hyper_rfi)
    1.40 +#define FAST_HYPERPRIVOP_CNT
    1.41 +#ifdef FAST_HYPERPRIVOP_CNT
    1.42 +	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_RFI);;
    1.43 +	ld8 r21=[r20];;
    1.44 +	adds r21=1,r21;;
    1.45 +	st8 [r20]=r21;;
    1.46 +#endif
    1.47  	adds r20=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
    1.48  	ld8 r21=[r20];;		// r21 = vcr.ipsr
    1.49  	extr.u r22=r21,IA64_PSR_BE_BIT,1 ;;
    1.50 @@ -101,3 +135,129 @@ ENTRY(hyper_rfi)
    1.51  	;;
    1.52  	rfi
    1.53  	;;
    1.54 +
    1.55 +ENTRY(hyper_cover)
    1.56 +#ifdef FAST_HYPERPRIVOP_CNT
    1.57 +	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_COVER);;
    1.58 +	ld8 r21=[r20];;
    1.59 +	adds r21=1,r21;;
    1.60 +	st8 [r20]=r21;;
    1.61 +#endif
    1.62 +	mov r24=cr.ipsr
    1.63 +	mov r25=cr.iip;;
    1.64 +	// skip test for vpsr.ic.. it's a prerequisite for hyperprivops
    1.65 +	cover ;;
    1.66 +	adds r20=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
    1.67 +	mov r30=cr.ifs;;
    1.68 +	adds r22=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18
    1.69 +	ld4 r21=[r20] ;;
    1.70 +	cmp.eq p6,p7=r21,r0 ;;
    1.71 +(p6)	st8 [r22]=r30;;
    1.72 +(p7)	st4 [r20]=r0;;
    1.73 +	mov cr.ifs=r0;;
    1.74 +	// adjust return address to skip over break instruction
    1.75 +	extr.u r26=r24,41,2 ;;
    1.76 +	cmp.eq p6,p7=2,r26 ;;
    1.77 +(p6)	mov r26=0
    1.78 +(p6)	adds r25=16,r25
    1.79 +(p7)	adds r26=1,r26
    1.80 +	;;
    1.81 +	dep r24=r26,r24,41,2
    1.82 +	;;
    1.83 +	mov cr.ipsr=r24
    1.84 +	mov cr.iip=r25
    1.85 +	mov pr=r31,-1 ;;
    1.86 +	rfi
    1.87 +	;;
    1.88 +
    1.89 +#if 1
    1.90 +// return from metaphysical mode (meta=1) to virtual mode (meta=0)
    1.91 +ENTRY(hyper_ssm_dt)
    1.92 +#ifdef FAST_HYPERPRIVOP_CNT
    1.93 +	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_SSM_DT);;
    1.94 +	ld8 r21=[r20];;
    1.95 +	adds r21=1,r21;;
    1.96 +	st8 [r20]=r21;;
    1.97 +#endif
    1.98 +	mov r24=cr.ipsr
    1.99 +	mov r25=cr.iip;;
   1.100 +	adds r20=XSI_METAPHYS_OFS-XSI_PSR_IC_OFS,r18 ;;
   1.101 +	ld4 r21=[r20];;
   1.102 +	cmp.eq p7,p0=r21,r0	// meta==0?
   1.103 +(p7)	br.spnt.many	1f ;;	// already in virtual mode
   1.104 +	mov r22=IA64_KR(CURRENT);;
   1.105 +	adds r22=IA64_VCPU_META_SAVED_RR0_OFFSET,r22;;
   1.106 +	ld4 r23=[r22];;
   1.107 +	mov rr[r0]=r23;;
   1.108 +	srlz.i;;
   1.109 +	st4 [r20]=r0 ;;
   1.110 +	// adjust return address to skip over break instruction
   1.111 +	extr.u r26=r24,41,2 ;;
   1.112 +	cmp.eq p6,p7=2,r26 ;;
   1.113 +(p6)	mov r26=0
   1.114 +(p6)	adds r25=16,r25
   1.115 +(p7)	adds r26=1,r26
   1.116 +	;;
   1.117 +	dep r24=r26,r24,41,2
   1.118 +	;;
   1.119 +	mov cr.ipsr=r24
   1.120 +	mov cr.iip=r25
   1.121 +1:	mov pr=r31,-1 ;;
   1.122 +	rfi
   1.123 +	;;
   1.124 +
   1.125 +// go to metaphysical mode (meta=1) from virtual mode (meta=0)
   1.126 +ENTRY(hyper_rsm_dt)
   1.127 +#ifdef FAST_HYPERPRIVOP_CNT
   1.128 +	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_RSM_DT);;
   1.129 +	ld8 r21=[r20];;
   1.130 +	adds r21=1,r21;;
   1.131 +	st8 [r20]=r21;;
   1.132 +#endif
   1.133 +	mov r24=cr.ipsr
   1.134 +	mov r25=cr.iip;;
   1.135 +	adds r20=XSI_METAPHYS_OFS-XSI_PSR_IC_OFS,r18 ;;
   1.136 +	ld4 r21=[r20];;
   1.137 +	cmp.ne p7,p0=r21,r0	// meta==0?
   1.138 +(p7)	br.spnt.many	1f ;;	// already in metaphysical mode
   1.139 +	mov r22=IA64_KR(CURRENT);;
   1.140 +	adds r22=IA64_VCPU_META_RR0_OFFSET,r22;;
   1.141 +	ld4 r23=[r22];;
   1.142 +	mov rr[r0]=r23;;
   1.143 +	srlz.i;;
   1.144 +	adds r21=1,r0 ;;
   1.145 +	st4 [r20]=r21 ;;
   1.146 +	// adjust return address to skip over break instruction
   1.147 +	extr.u r26=r24,41,2 ;;
   1.148 +	cmp.eq p6,p7=2,r26 ;;
   1.149 +(p6)	mov r26=0
   1.150 +(p6)	adds r25=16,r25
   1.151 +(p7)	adds r26=1,r26
   1.152 +	;;
   1.153 +	dep r24=r26,r24,41,2
   1.154 +	;;
   1.155 +	mov cr.ipsr=r24
   1.156 +	mov cr.iip=r25
   1.157 +1:	mov pr=r31,-1 ;;
   1.158 +	rfi
   1.159 +	;;
   1.160 +
   1.161 +// enable interrupts (and also interrupt collection)
   1.162 +ENTRY(hyper_ssm_i)
   1.163 +#ifdef FAST_HYPERPRIVOP_CNT
   1.164 +	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_SSM_I);;
   1.165 +	ld8 r21=[r20];;
   1.166 +	adds r21=1,r21;;
   1.167 +	st8 [r20]=r21;;
   1.168 +#endif
   1.169 +	mov r24=cr.ipsr
   1.170 +	mov r25=cr.iip;;
   1.171 +	movl r20=0x100000001;;
   1.172 +	st8 [r18]=r20;;	// turn on both vpsr.i and vpsr.ic
   1.173 +// FIXME: NEED TO UPDATE IPSR/IIP TO SKIP BREAK INST
   1.174 +// FIXME: NEED TO CHECK FOR PENDING INTERRUPTS AND DELIVER THEM!
   1.175 +1:	mov pr=r31,-1 ;;
   1.176 +	rfi
   1.177 +	;;
   1.178 +#endif
   1.179 +
     2.1 --- a/xen/arch/ia64/privop.c	Thu May 26 21:28:39 2005 +0000
     2.2 +++ b/xen/arch/ia64/privop.c	Tue May 31 20:54:20 2005 +0000
     2.3 @@ -747,14 +747,16 @@ priv_emulate(VCPU *vcpu, REGS *regs, UIN
     2.4  #define HYPERPRIVOP_COVER		0x4
     2.5  #define HYPERPRIVOP_ITC_D		0x5
     2.6  #define HYPERPRIVOP_ITC_I		0x6
     2.7 -#define HYPERPRIVOP_MAX			0x6
     2.8 +#define HYPERPRIVOP_SSM_I		0x7
     2.9 +#define HYPERPRIVOP_MAX			0x7
    2.10  
    2.11  char *hyperpriv_str[HYPERPRIVOP_MAX+1] = {
    2.12 -	0, "rfi", "rsm.dt", "ssm.dt", "cover", "itc.d", "itc.i",
    2.13 +	0, "rfi", "rsm.dt", "ssm.dt", "cover", "itc.d", "itc.i", "ssm.i",
    2.14  	0
    2.15  };
    2.16  
    2.17 -unsigned long hyperpriv_cnt[HYPERPRIVOP_MAX+1] = { 0 };
    2.18 +unsigned long slow_hyperpriv_cnt[HYPERPRIVOP_MAX+1] = { 0 };
    2.19 +unsigned long fast_hyperpriv_cnt[HYPERPRIVOP_MAX+1] = { 0 };
    2.20  
    2.21  /* hyperprivops are generally executed in assembly (with physical psr.ic off)
    2.22   * so this code is primarily used for debugging them */
    2.23 @@ -765,13 +767,12 @@ ia64_hyperprivop(unsigned long iim, REGS
    2.24  	INST64 inst;
    2.25  	UINT64 val;
    2.26  
    2.27 -// FIXME: Add instrumentation for these
    2.28  // FIXME: Handle faults appropriately for these
    2.29  	if (!iim || iim > HYPERPRIVOP_MAX) {
    2.30  		printf("bad hyperprivop; ignored\n");
    2.31  		return 1;
    2.32  	}
    2.33 -	hyperpriv_cnt[iim]++;
    2.34 +	slow_hyperpriv_cnt[iim]++;
    2.35  	switch(iim) {
    2.36  	    case HYPERPRIVOP_RFI:
    2.37  		(void)vcpu_rfi(ed);
    2.38 @@ -793,6 +794,9 @@ ia64_hyperprivop(unsigned long iim, REGS
    2.39  		inst.inst = 0;
    2.40  		(void)priv_itc_i(ed,inst);
    2.41  		return 1;
    2.42 +	    case HYPERPRIVOP_SSM_I:
    2.43 +		(void)vcpu_set_psr_i(ed);
    2.44 +		return 1;
    2.45  	}
    2.46  	return 0;
    2.47  }
    2.48 @@ -981,18 +985,28 @@ int dump_hyperprivop_counts(char *buf)
    2.49  {
    2.50  	int i;
    2.51  	char *s = buf;
    2.52 -	s += sprintf(s,"Slow hyperprivops:\n");
    2.53 +	unsigned long total = 0;
    2.54 +	for (i = 1; i <= HYPERPRIVOP_MAX; i++) total += slow_hyperpriv_cnt[i];
    2.55 +	s += sprintf(s,"Slow hyperprivops (total %d:\n",total);
    2.56  	for (i = 1; i <= HYPERPRIVOP_MAX; i++)
    2.57 -		if (hyperpriv_cnt[i])
    2.58 +		if (slow_hyperpriv_cnt[i])
    2.59  			s += sprintf(s,"%10d %s\n",
    2.60 -				hyperpriv_cnt[i], hyperpriv_str[i]);
    2.61 +				slow_hyperpriv_cnt[i], hyperpriv_str[i]);
    2.62 +	total = 0;
    2.63 +	for (i = 1; i <= HYPERPRIVOP_MAX; i++) total += fast_hyperpriv_cnt[i];
    2.64 +	s += sprintf(s,"Fast hyperprivops (total %d:\n",total);
    2.65 +	for (i = 1; i <= HYPERPRIVOP_MAX; i++)
    2.66 +		if (fast_hyperpriv_cnt[i])
    2.67 +			s += sprintf(s,"%10d %s\n",
    2.68 +				fast_hyperpriv_cnt[i], hyperpriv_str[i]);
    2.69  	return s - buf;
    2.70  }
    2.71  
    2.72  void zero_hyperprivop_counts(void)
    2.73  {
    2.74  	int i;
    2.75 -	for (i = 0; i <= HYPERPRIVOP_MAX; i++) hyperpriv_cnt[i] = 0;
    2.76 +	for (i = 0; i <= HYPERPRIVOP_MAX; i++) slow_hyperpriv_cnt[i] = 0;
    2.77 +	for (i = 0; i <= HYPERPRIVOP_MAX; i++) fast_hyperpriv_cnt[i] = 0;
    2.78  }
    2.79  
    2.80  #define TMPBUFLEN 8*1024
     3.1 --- a/xen/arch/ia64/vcpu.c	Thu May 26 21:28:39 2005 +0000
     3.2 +++ b/xen/arch/ia64/vcpu.c	Tue May 31 20:54:20 2005 +0000
     3.3 @@ -173,6 +173,7 @@ IA64FAULT vcpu_set_psr_dt(VCPU *vcpu)
     3.4  IA64FAULT vcpu_set_psr_i(VCPU *vcpu)
     3.5  {
     3.6  	PSCB(vcpu,interrupt_delivery_enabled) = 1;
     3.7 +	PSCB(vcpu,interrupt_collection_enabled) = 1;
     3.8  	return IA64_NO_FAULT;
     3.9  }
    3.10  
    3.11 @@ -649,6 +650,7 @@ IA64FAULT vcpu_get_ivr(VCPU *vcpu, UINT6
    3.12  #ifdef HEARTBEAT_FREQ
    3.13  #define N_DOMS 16	// period in seconds
    3.14  	static long count[N_DOMS] = { 0 };
    3.15 +	static long nonclockcount[N_DOMS] = { 0 };
    3.16  	REGS *regs = vcpu_regs(vcpu);
    3.17  	unsigned domid = vcpu->domain->domain_id;
    3.18  #endif
    3.19 @@ -670,15 +672,15 @@ IA64FAULT vcpu_get_ivr(VCPU *vcpu, UINT6
    3.20  	}
    3.21  #ifdef HEARTBEAT_FREQ
    3.22  	if (domid >= N_DOMS) domid = N_DOMS-1;
    3.23 -	if (vector == (PSCB(vcpu,itv) & 0xff) &&
    3.24 -	    !(++count[domid] & ((HEARTBEAT_FREQ*1024)-1))) {
    3.25 -		printf("Dom%d heartbeat... iip=%p,psr.i=%d,pend=%d\n",
    3.26 -			domid, regs->cr_iip,
    3.27 -			current->vcpu_info->arch.interrupt_delivery_enabled,
    3.28 -			current->vcpu_info->arch.pending_interruption);
    3.29 -		count[domid] = 0;
    3.30 -		dump_runq();
    3.31 +	if (vector == (PSCB(vcpu,itv) & 0xff)) {
    3.32 +	    if (!(++count[domid] & ((HEARTBEAT_FREQ*1024)-1))) {
    3.33 +		printf("Dom%d heartbeat... ticks=%lx,nonticks=%lx\n",
    3.34 +			domid, count[domid], nonclockcount[domid]);
    3.35 +		//count[domid] = 0;
    3.36 +		//dump_runq();
    3.37 +	    }
    3.38  	}
    3.39 +	else nonclockcount[domid]++;
    3.40  #endif
    3.41  	// now have an unmasked, pending, deliverable vector!
    3.42  	// getting ivr has "side effects"
     4.1 --- a/xen/include/public/arch-ia64.h	Thu May 26 21:28:39 2005 +0000
     4.2 +++ b/xen/include/public/arch-ia64.h	Tue May 31 20:54:20 2005 +0000
     4.3 @@ -82,10 +82,11 @@ typedef struct vcpu_guest_context {
     4.4  #endif /* !__ASSEMBLY__ */
     4.5  
     4.6  #define	XEN_HYPER_RFI			1
     4.7 -#define	XEN_HYPER_RSM_PSR_DT		2
     4.8 -#define	XEN_HYPER_SSM_PSR_DT		3
     4.9 +#define	XEN_HYPER_RSM_DT		2
    4.10 +#define	XEN_HYPER_SSM_DT		3
    4.11  #define	XEN_HYPER_COVER			4
    4.12  #define	XEN_HYPER_ITC_D			5
    4.13  #define	XEN_HYPER_ITC_I			6
    4.14 +#define	XEN_HYPER_SSM_I			7
    4.15  
    4.16  #endif /* __HYPERVISOR_IF_IA64_H__ */