ia64/xen-unstable

changeset 5445:9dc7db2ffb41

bitkeeper revision 1.1709.1.1 (42adb204Ml32H28eX0bWoUwiEkfXzw)

Additional interrupt checking for fast hyper_rfi
author djm@kirby.fc.hp.com
date Mon Jun 13 16:19:16 2005 +0000 (2005-06-13)
parents da92dcde82ea
children 01a9f1e50dd8
files xen/arch/ia64/asm-offsets.c xen/arch/ia64/hyperprivop.S
line diff
     1.1 --- a/xen/arch/ia64/asm-offsets.c	Fri Jun 10 15:45:23 2005 +0000
     1.2 +++ b/xen/arch/ia64/asm-offsets.c	Mon Jun 13 16:19:16 2005 +0000
     1.3 @@ -75,6 +75,9 @@ void foo(void)
     1.4  	DEFINE(IA64_VCPU_META_SAVED_RR0_OFFSET, offsetof (struct vcpu, arch.metaphysical_saved_rr0));
     1.5  	DEFINE(IA64_VCPU_BREAKIMM_OFFSET, offsetof (struct vcpu, arch.breakimm));
     1.6  	DEFINE(IA64_VCPU_IVA_OFFSET, offsetof (struct vcpu, arch.iva));
     1.7 +	DEFINE(IA64_VCPU_IRR0_OFFSET, offsetof (struct vcpu, arch.irr[0]));
     1.8 +	DEFINE(IA64_VCPU_IRR3_OFFSET, offsetof (struct vcpu, arch.irr[3]));
     1.9 +	DEFINE(IA64_VCPU_INSVC3_OFFSET, offsetof (struct vcpu, arch.insvc[3]));
    1.10  
    1.11  	BLANK();
    1.12  
     2.1 --- a/xen/arch/ia64/hyperprivop.S	Fri Jun 10 15:45:23 2005 +0000
     2.2 +++ b/xen/arch/ia64/hyperprivop.S	Mon Jun 13 16:19:16 2005 +0000
     2.3 @@ -41,40 +41,46 @@
     2.4  //	r19 == vpsr.ic (low 32 bits) | vpsr.i (high 32 bits)
     2.5  //	r31 == pr
     2.6  GLOBAL_ENTRY(fast_hyperprivop)
     2.7 -#if 1
     2.8  	// HYPERPRIVOP_SSM_I?
     2.9  	// assumes domain interrupts pending, so just do it
    2.10  	cmp.eq p7,p6=XEN_HYPER_SSM_I,r17
    2.11  (p7)	br.sptk.many hyper_ssm_i;;
    2.12 -#endif
    2.13 -#if 1
    2.14 -	// if domain interrupts pending, give up for now and do it the slow way
    2.15 +
    2.16 +	// FIXME. This algorithm gives up (goes to the slow path) if there
    2.17 +	// are ANY interrupts pending, even if they are currently
    2.18 +	// undeliverable.  This should be improved later...
    2.19  	adds r20=XSI_PEND_OFS-XSI_PSR_IC_OFS,r18 ;;
    2.20 -	ld8 r20=[r20] ;;
    2.21 -	cmp.ne p7,p0=r0,r20
    2.22 -(p7)	br.sptk.many dispatch_break_fault ;;
    2.23 +	ld4 r20=[r20] ;;
    2.24 +	cmp.eq p7,p0=r0,r20
    2.25 +(p7)	br.cond.sptk.many 1f
    2.26 +	mov r20=IA64_KR(CURRENT);;
    2.27 +	adds r21=IA64_VCPU_IRR0_OFFSET,r20;
    2.28 +	adds r22=IA64_VCPU_IRR0_OFFSET+8,r20;;
    2.29 +	ld8 r23=[r21],16; ld8 r24=[r22],16;;
    2.30 +	ld8 r21=[r21]; ld8 r22=[r22];;
    2.31 +	or r23=r23,r24; or r21=r21,r22;;
    2.32 +	or r20=r23,r21;;
    2.33 +1:	// when we get to here r20=~=interrupts pending
    2.34  
    2.35  	// HYPERPRIVOP_RFI?
    2.36  	cmp.eq p7,p6=XEN_HYPER_RFI,r17
    2.37  (p7)	br.sptk.many hyper_rfi;;
    2.38  
    2.39 +	cmp.ne p7,p0=r20,r0
    2.40 +(p7)	br.spnt.many dispatch_break_fault ;;
    2.41 +
    2.42  // hard to test, because only called from rbs_switch
    2.43  	// HYPERPRIVOP_COVER?
    2.44  	cmp.eq p7,p6=XEN_HYPER_COVER,r17
    2.45  (p7)	br.sptk.many hyper_cover;;
    2.46 -#endif
    2.47  
    2.48 -#if 1
    2.49  	// HYPERPRIVOP_SSM_DT?
    2.50  	cmp.eq p7,p6=XEN_HYPER_SSM_DT,r17
    2.51  (p7)	br.sptk.many hyper_ssm_dt;;
    2.52 -#endif
    2.53  
    2.54 -#if 1
    2.55  	// HYPERPRIVOP_RSM_DT?
    2.56  	cmp.eq p7,p6=XEN_HYPER_RSM_DT,r17
    2.57  (p7)	br.sptk.many hyper_rsm_dt;;
    2.58 -#endif
    2.59  
    2.60  	// if not one of the above, give up for now and do it the slow way
    2.61  	br.sptk.many dispatch_break_fault ;;
    2.62 @@ -336,12 +342,16 @@ GLOBAL_ENTRY(fast_break_reflect)
    2.63  
    2.64  // ensure that, if giving up, registers at entry to fast_hyperprivop unchanged
    2.65  ENTRY(hyper_rfi)
    2.66 -#ifdef FAST_HYPERPRIVOP_CNT
    2.67 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_RFI);;
    2.68 -	ld8 r21=[r20];;
    2.69 -	adds r21=1,r21;;
    2.70 -	st8 [r20]=r21;;
    2.71 -#endif
    2.72 +	// if no interrupts pending, proceed
    2.73 +	cmp.eq p7,p0=r20,r0
    2.74 +(p7)	br.sptk.many 1f
    2.75 +	// interrupts pending, if rfi'ing to interrupts on, go slow way
    2.76 +	adds r20=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
    2.77 +	ld8 r21=[r20];;		// r21 = vcr.ipsr
    2.78 +	extr.u r22=r21,IA64_PSR_I_BIT,1 ;;
    2.79 +	cmp.ne p7,p0=r22,r0 ;;
    2.80 +(p7)	br.spnt.many dispatch_break_fault ;;
    2.81 +1:
    2.82  	adds r20=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
    2.83  	ld8 r21=[r20];;		// r21 = vcr.ipsr
    2.84  	extr.u r22=r21,IA64_PSR_BE_BIT,1 ;;
    2.85 @@ -375,7 +385,13 @@ ENTRY(hyper_rfi)
    2.86  (p7)	br.sptk.many dispatch_break_fault ;;
    2.87  
    2.88  	// OK now, let's do an rfi.
    2.89 -	// r18=&vpsr.i|vpsr.ic, r21==vpsr, r20==&vcr.iip, r22=vcr.iip
    2.90 +#ifdef FAST_HYPERPRIVOP_CNT
    2.91 +	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_RFI);;
    2.92 +	ld8 r23=[r20];;
    2.93 +	adds r23=1,r23;;
    2.94 +	st8 [r20]=r23;;
    2.95 +#endif
    2.96 +	// r18=&vpsr.i|vpsr.ic, r21==vpsr, r22=vcr.iip
    2.97  	mov cr.iip=r22;;
    2.98  	adds r20=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
    2.99  	st4 [r20]=r0 ;;