ia64/xen-unstable

changeset 7145:0ba10f7fef51

Add support for fast mov_to_kr privops
Signed-off by: Dan Magenheimer <dan.magenheimer@hp.com>
author djm@kirby.fc.hp.com
date Sat Oct 08 11:37:45 2005 -0600 (2005-10-08)
parents cbe6b4c4480f
children 4e0c94871be2
files linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h xen/arch/ia64/asm-offsets.c xen/arch/ia64/xen/hyperprivop.S xen/arch/ia64/xen/privop.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S	Fri Oct 07 09:40:37 2005 -0600
     1.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S	Sat Oct 08 11:37:45 2005 -0600
     1.3 @@ -202,6 +202,61 @@ GLOBAL_ENTRY(xen_set_rr)
     1.4  	;;
     1.5  END(xen_set_rr)
     1.6  
     1.7 +GLOBAL_ENTRY(xen_set_kr)
     1.8 +	movl r8=running_on_xen;;
     1.9 +	ld4 r8=[r8];;
    1.10 +	cmp.ne p7,p0=r8,r0;;
    1.11 +(p7)	br.cond.spnt.few 1f;
    1.12 +	;;
    1.13 +	cmp.eq p7,p0=r8,r0
    1.14 +	adds r8=-1,r8;;
    1.15 +(p7)	mov ar0=r9
    1.16 +(p7)	br.ret.sptk.many rp;;
    1.17 +	cmp.eq p7,p0=r8,r0
    1.18 +	adds r8=-1,r8;;
    1.19 +(p7)	mov ar1=r9
    1.20 +(p7)	br.ret.sptk.many rp;;
    1.21 +	cmp.eq p7,p0=r8,r0
    1.22 +	adds r8=-1,r8;;
    1.23 +(p7)	mov ar2=r9
    1.24 +(p7)	br.ret.sptk.many rp;;
    1.25 +	cmp.eq p7,p0=r8,r0
    1.26 +	adds r8=-1,r8;;
    1.27 +(p7)	mov ar3=r9
    1.28 +(p7)	br.ret.sptk.many rp;;
    1.29 +	cmp.eq p7,p0=r8,r0
    1.30 +	adds r8=-1,r8;;
    1.31 +(p7)	mov ar4=r9
    1.32 +(p7)	br.ret.sptk.many rp;;
    1.33 +	cmp.eq p7,p0=r8,r0
    1.34 +	adds r8=-1,r8;;
    1.35 +(p7)	mov ar5=r9
    1.36 +(p7)	br.ret.sptk.many rp;;
    1.37 +	cmp.eq p7,p0=r8,r0
    1.38 +	adds r8=-1,r8;;
    1.39 +(p7)	mov ar6=r9
    1.40 +(p7)	br.ret.sptk.many rp;;
    1.41 +	cmp.eq p7,p0=r8,r0
    1.42 +	adds r8=-1,r8;;
    1.43 +(p7)	mov ar7=r9
    1.44 +(p7)	br.ret.sptk.many rp;;
    1.45 +
    1.46 +1:	movl r11=XSI_PSR_IC
    1.47 +	mov r8=r32
    1.48 +	mov r9=r33
    1.49 +	;;
    1.50 +	ld8 r10=[r11]
    1.51 +	;;
    1.52 +	st8 [r11]=r0
    1.53 +	;;
    1.54 +	XEN_HYPER_SET_KR
    1.55 +	;;
    1.56 +	st8 [r11]=r10
    1.57 +	;;
    1.58 +	br.ret.sptk.many rp
    1.59 +	;;
    1.60 +END(xen_set_rr)
    1.61 +
    1.62  GLOBAL_ENTRY(xen_fc)
    1.63  	movl r8=running_on_xen;;
    1.64  	ld4 r8=[r8];;
     2.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S	Fri Oct 07 09:40:37 2005 -0600
     2.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S	Sat Oct 08 11:37:45 2005 -0600
     2.3 @@ -61,6 +61,12 @@ GLOBAL_ENTRY(ia64_switch_to)
     2.4  	shr.u r26=r20,IA64_GRANULE_SHIFT
     2.5  	cmp.eq p7,p6=r25,in0
     2.6  	;;
     2.7 +#ifdef CONFIG_XEN
     2.8 +	movl r8=XSI_PSR_IC
     2.9 +	;;
    2.10 +	st4 [r8]=r0	// force psr.ic off for hyperprivop(s)
    2.11 +	;;
    2.12 +#endif
    2.13  	/*
    2.14  	 * If we've already mapped this task's page, we can skip doing it again.
    2.15  	 */
    2.16 @@ -69,18 +75,24 @@ GLOBAL_ENTRY(ia64_switch_to)
    2.17  	;;
    2.18  .done:
    2.19  #ifdef CONFIG_XEN
    2.20 +	// psr.ic already off
    2.21 +	// update "current" application register
    2.22 +	mov r8=IA64_KR_CURRENT
    2.23 +	mov r9=in0;;
    2.24 +	XEN_HYPER_SET_KR
    2.25 +	ld8 sp=[r21]			// load kernel stack pointer of new task
    2.26  	movl r27=XSI_PSR_IC
    2.27  	mov r8=1
    2.28  	;;
    2.29 -(p6)	st4 [r27]=r8
    2.30 +	st4 [r27]=r8			// psr.ic back on
    2.31  	;;
    2.32  #else
    2.33  (p6)	ssm psr.ic			// if we had to map, reenable the psr.ic bit FIRST!!!
    2.34  	;;
    2.35  (p6)	srlz.d
    2.36 -#endif
    2.37  	ld8 sp=[r21]			// load kernel stack pointer of new task
    2.38  	mov IA64_KR(CURRENT)=in0	// update "current" application register
    2.39 +#endif
    2.40  	mov r8=r13			// return pointer to previously running task
    2.41  	mov r13=in0			// set "current" pointer
    2.42  	;;
    2.43 @@ -93,9 +105,7 @@ GLOBAL_ENTRY(ia64_switch_to)
    2.44  
    2.45  .map:
    2.46  #ifdef CONFIG_XEN
    2.47 -	movl r27=XSI_PSR_IC
    2.48 -	;;
    2.49 -	st4 [r27]=r0
    2.50 +	// psr.ic already off
    2.51  #else
    2.52  	rsm psr.ic			// interrupts (psr.i) are already disabled here
    2.53  #endif
    2.54 @@ -115,13 +125,17 @@ GLOBAL_ENTRY(ia64_switch_to)
    2.55  	st8 [r8]=in0			 // VA of next task...
    2.56  	;;
    2.57  	mov r25=IA64_TR_CURRENT_STACK
    2.58 +	// remember last page we mapped...
    2.59 +	mov r8=IA64_KR_CURRENT_STACK
    2.60 +	mov r9=r26;;
    2.61 +	XEN_HYPER_SET_KR;;
    2.62  #else
    2.63  	mov cr.itir=r25
    2.64  	mov cr.ifa=in0			// VA of next task...
    2.65  	;;
    2.66  	mov r25=IA64_TR_CURRENT_STACK
    2.67 +	mov IA64_KR(CURRENT_STACK)=r26	// remember last page we mapped...
    2.68  #endif
    2.69 -	mov IA64_KR(CURRENT_STACK)=r26	// remember last page we mapped...
    2.70  	;;
    2.71  	itr.d dtr[r25]=r23		// wire in new mapping...
    2.72  	br.cond.sptk .done
     3.1 --- a/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h	Fri Oct 07 09:40:37 2005 -0600
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h	Sat Oct 08 11:37:45 2005 -0600
     3.3 @@ -32,6 +32,7 @@
     3.4  #define	XEN_HYPER_ITR_D			break 0xf
     3.5  #define	XEN_HYPER_GET_RR		break 0x10
     3.6  #define	XEN_HYPER_SET_RR		break 0x11
     3.7 +#define	XEN_HYPER_SET_KR		break 0x12
     3.8  #endif
     3.9  
    3.10  #ifndef __ASSEMBLY__
    3.11 @@ -93,9 +94,6 @@ extern void xen_set_eflag(unsigned long)
    3.12  	XEN_HYPER_SSM_I;						\
    3.13  })
    3.14  
    3.15 -// for now, just use privop.  may use hyperprivop later
    3.16 -/*#define xen_set_kr(regnum,val) (__ia64_setreg(regnum,val)) */
    3.17 -
    3.18  /* turning off interrupts can be paravirtualized simply by writing
    3.19   * to a memory-mapped virtual psr.i bit (implemented as a 16-bit bool) */
    3.20  #define xen_rsm_i()	xen_set_virtual_psr_i(0)
    3.21 @@ -157,6 +155,7 @@ extern void xen_set_tpr(unsigned long);
    3.22  extern void xen_eoi(void);
    3.23  extern void xen_set_rr(unsigned long index, unsigned long val);
    3.24  extern unsigned long xen_get_rr(unsigned long index);
    3.25 +extern void xen_set_kr(unsigned long index, unsigned long val);
    3.26  
    3.27  /* Note: It may look wrong to test for running_on_xen in each case.
    3.28   * However regnum is always a constant so, as written, the compiler
    3.29 @@ -193,9 +192,8 @@ extern unsigned long xen_get_rr(unsigned
    3.30  ({									\
    3.31  	switch(regnum) {						\
    3.32  	case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7:			\
    3.33 -/* for now, just use privop.  may use hyperprivop later */		\
    3.34 -/*		(running_on_xen) ?					\
    3.35 -			xen_set_kr((regnum-_IA64_REG_AR_KR0), val) : */	\
    3.36 +		(running_on_xen) ?					\
    3.37 +			xen_set_kr((regnum-_IA64_REG_AR_KR0), val) :	\
    3.38  			__ia64_setreg(regnum,val);			\
    3.39  		break;							\
    3.40  	case _IA64_REG_CR_ITM:						\
     4.1 --- a/xen/arch/ia64/asm-offsets.c	Fri Oct 07 09:40:37 2005 -0600
     4.2 +++ b/xen/arch/ia64/asm-offsets.c	Sat Oct 08 11:37:45 2005 -0600
     4.3 @@ -69,6 +69,7 @@ void foo(void)
     4.4  	DEFINE(XSI_TPR_OFS, offsetof(mapped_regs_t, tpr));
     4.5  	DEFINE(XSI_PTA_OFS, offsetof(mapped_regs_t, pta));
     4.6  	DEFINE(XSI_ITV_OFS, offsetof(mapped_regs_t, itv));
     4.7 +	DEFINE(XSI_KR0_OFS, offsetof(mapped_regs_t, krs[0]));
     4.8  	//DEFINE(IA64_TASK_BLOCKED_OFFSET,offsetof (struct task_struct, blocked));
     4.9  	//DEFINE(IA64_TASK_CLEAR_CHILD_TID_OFFSET,offsetof (struct task_struct, clear_child_tid));
    4.10  	//DEFINE(IA64_TASK_GROUP_LEADER_OFFSET, offsetof (struct task_struct, group_leader));
     5.1 --- a/xen/arch/ia64/xen/hyperprivop.S	Fri Oct 07 09:40:37 2005 -0600
     5.2 +++ b/xen/arch/ia64/xen/hyperprivop.S	Sat Oct 08 11:37:45 2005 -0600
     5.3 @@ -44,6 +44,7 @@
     5.4  #define    XEN_HYPER_ITR_D         0xf
     5.5  #define    XEN_HYPER_GET_RR        0x10
     5.6  #define    XEN_HYPER_SET_RR        0x11
     5.7 +#define    XEN_HYPER_SET_KR        0x12
     5.8  
     5.9  #ifdef CONFIG_SMP
    5.10  #warning "FIXME: ptc.ga instruction requires spinlock for SMP"
    5.11 @@ -169,6 +170,10 @@ 1:	// when we get to here r20=~=interrup
    5.12  	cmp.eq p7,p6=XEN_HYPER_THASH,r17
    5.13  (p7)	br.sptk.many hyper_thash;;
    5.14  
    5.15 +	// HYPERPRIVOP_SET_KR?
    5.16 +	cmp.eq p7,p6=XEN_HYPER_SET_KR,r17
    5.17 +(p7)	br.sptk.many hyper_set_kr;;
    5.18 +
    5.19  	// if not one of the above, give up for now and do it the slow way
    5.20  	br.sptk.many dispatch_break_fault ;;
    5.21  
    5.22 @@ -1459,6 +1464,62 @@ 1:	mov r24=cr.ipsr
    5.23  	;;
    5.24  END(hyper_set_rr)
    5.25  
    5.26 +ENTRY(hyper_set_kr)
    5.27 +	extr.u r25=r8,3,61;;
    5.28 +	cmp.ne p7,p0=r0,r25	// if kr# > 7, go slow way
    5.29 +(p7)	br.spnt.many dispatch_break_fault ;;
    5.30 +#ifdef FAST_HYPERPRIVOP_CNT
    5.31 +	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_SET_KR);;
    5.32 +	ld8 r21=[r20];;
    5.33 +	adds r21=1,r21;;
    5.34 +	st8 [r20]=r21;;
    5.35 +#endif
    5.36 +	adds r21=XSI_KR0_OFS-XSI_PSR_IC_OFS,r18 ;;
    5.37 +	shl r20=r8,3;;
    5.38 +	add r22=r20,r21;;
    5.39 +	st8 [r21]=r9;;
    5.40 +	cmp.eq p7,p0=r8,r0
    5.41 +	adds r8=-1,r8;;
    5.42 +(p7)	mov ar0=r9;;
    5.43 +	cmp.eq p7,p0=r8,r0
    5.44 +	adds r8=-1,r8;;
    5.45 +(p7)	mov ar1=r9;;
    5.46 +	cmp.eq p7,p0=r8,r0
    5.47 +	adds r8=-1,r8;;
    5.48 +(p7)	mov ar2=r9;;
    5.49 +	cmp.eq p7,p0=r8,r0
    5.50 +	adds r8=-1,r8;;
    5.51 +(p7)	mov ar3=r9;;
    5.52 +	cmp.eq p7,p0=r8,r0
    5.53 +	adds r8=-1,r8;;
    5.54 +(p7)	mov ar4=r9;;
    5.55 +	cmp.eq p7,p0=r8,r0
    5.56 +	adds r8=-1,r8;;
    5.57 +(p7)	mov ar5=r9;;
    5.58 +	cmp.eq p7,p0=r8,r0
    5.59 +	adds r8=-1,r8;;
    5.60 +(p7)	mov ar6=r9;;
    5.61 +	cmp.eq p7,p0=r8,r0
    5.62 +	adds r8=-1,r8;;
    5.63 +(p7)	mov ar7=r9;;
    5.64 +	// done, mosey on back
    5.65 +1:	mov r24=cr.ipsr
    5.66 +	mov r25=cr.iip;;
    5.67 +	extr.u r26=r24,41,2 ;;
    5.68 +	cmp.eq p6,p7=2,r26 ;;
    5.69 +(p6)	mov r26=0
    5.70 +(p6)	adds r25=16,r25
    5.71 +(p7)	adds r26=1,r26
    5.72 +	;;
    5.73 +	dep r24=r26,r24,41,2
    5.74 +	;;
    5.75 +	mov cr.ipsr=r24
    5.76 +	mov cr.iip=r25
    5.77 +	mov pr=r31,-1 ;;
    5.78 +	rfi
    5.79 +	;;
    5.80 +END(hyper_set_kr)
    5.81 +
    5.82  // this routine was derived from optimized assembly output from
    5.83  // vcpu_thash so it is dense and difficult to read but it works
    5.84  // On entry:
     6.1 --- a/xen/arch/ia64/xen/privop.c	Fri Oct 07 09:40:37 2005 -0600
     6.2 +++ b/xen/arch/ia64/xen/privop.c	Sat Oct 08 11:37:45 2005 -0600
     6.3 @@ -757,12 +757,13 @@ priv_emulate(VCPU *vcpu, REGS *regs, UIN
     6.4  #define HYPERPRIVOP_ITR_D		0xf
     6.5  #define HYPERPRIVOP_GET_RR		0x10
     6.6  #define HYPERPRIVOP_SET_RR		0x11
     6.7 -#define HYPERPRIVOP_MAX			0x11
     6.8 +#define HYPERPRIVOP_SET_KR		0x12
     6.9 +#define HYPERPRIVOP_MAX			0x12
    6.10  
    6.11  char *hyperpriv_str[HYPERPRIVOP_MAX+1] = {
    6.12  	0, "rfi", "rsm.dt", "ssm.dt", "cover", "itc.d", "itc.i", "ssm.i",
    6.13  	"=ivr", "=tpr", "tpr=", "eoi", "itm=", "thash", "ptc.ga", "itr.d",
    6.14 -	"=rr", "rr=",
    6.15 +	"=rr", "rr=", "kr=",
    6.16  	0
    6.17  };
    6.18  
    6.19 @@ -848,6 +849,9 @@ ia64_hyperprivop(unsigned long iim, REGS
    6.20  	    case HYPERPRIVOP_SET_RR:
    6.21  		(void)vcpu_set_rr(v,regs->r8,regs->r9);
    6.22  		return 1;
    6.23 +	    case HYPERPRIVOP_SET_KR:
    6.24 +		(void)vcpu_set_ar(v,regs->r8,regs->r9);
    6.25 +		return 1;
    6.26  	}
    6.27  	return 0;
    6.28  }