ia64/xen-unstable

changeset 5264:a0723a72717d

bitkeeper revision 1.1564.1.6 (429e165dilv2Yl2AOW9ZyHrCpVrJDg)

Add counters for hyperprivops and reflections
Preliminary work for fast break reflection
Signed-off by: Dan Magenheimer <dan.magenheimer@hp.com>
author djm@kirby.fc.hp.com
date Wed Jun 01 20:11:09 2005 +0000 (2005-06-01)
parents 8356773d6de6
children c061e9a30cdf
files xen/arch/ia64/asm-offsets.c xen/arch/ia64/dom_fw.c xen/arch/ia64/domain.c xen/arch/ia64/hyperprivop.S xen/arch/ia64/ivt.S xen/arch/ia64/privop.c xen/arch/ia64/process.c xen/include/asm-ia64/domain.h
line diff
     1.1 --- a/xen/arch/ia64/asm-offsets.c	Tue May 31 20:54:20 2005 +0000
     1.2 +++ b/xen/arch/ia64/asm-offsets.c	Wed Jun 01 20:11:09 2005 +0000
     1.3 @@ -45,10 +45,15 @@ void foo(void)
     1.4  	DEFINE(XSI_PSR_IC, (SHAREDINFO_ADDR+offsetof(vcpu_info_t, arch.interrupt_collection_enabled)));
     1.5  	DEFINE(XSI_PSR_I_OFS, offsetof(vcpu_info_t, arch.interrupt_delivery_enabled));
     1.6  	DEFINE(XSI_IIP_OFS, offsetof(vcpu_info_t, arch.iip));
     1.7 +	DEFINE(XSI_IPSR, (SHAREDINFO_ADDR+offsetof(vcpu_info_t, arch.ipsr)));
     1.8  	DEFINE(XSI_IPSR_OFS, offsetof(vcpu_info_t, arch.ipsr));
     1.9  	DEFINE(XSI_IFS_OFS, offsetof(vcpu_info_t, arch.ifs));
    1.10 +	DEFINE(XSI_IIM_OFS, offsetof(vcpu_info_t, arch.iim));
    1.11  	DEFINE(XSI_BANKNUM_OFS, offsetof(vcpu_info_t, arch.banknum));
    1.12 +	DEFINE(XSI_BANK0_OFS, offsetof(vcpu_info_t, arch.bank0_regs[0]));
    1.13 +	DEFINE(XSI_BANK1_OFS, offsetof(vcpu_info_t, arch.bank1_regs[0]));
    1.14  	DEFINE(XSI_METAPHYS_OFS, offsetof(vcpu_info_t, arch.metaphysical_mode));
    1.15 +	DEFINE(XSI_PRECOVER_IFS_OFS, offsetof(vcpu_info_t, arch.precover_ifs));
    1.16  	DEFINE(XSI_INCOMPL_REG_OFS, offsetof(vcpu_info_t, arch.incomplete_regframe));
    1.17  	DEFINE(XSI_PEND_OFS, offsetof(vcpu_info_t, arch.pending_interruption));
    1.18  	DEFINE(XSI_RR0_OFS, offsetof(vcpu_info_t, arch.rrs[0]));
    1.19 @@ -66,6 +71,8 @@ void foo(void)
    1.20  
    1.21  	DEFINE(IA64_VCPU_META_RR0_OFFSET, offsetof (struct exec_domain, arch.metaphysical_rr0));
    1.22  	DEFINE(IA64_VCPU_META_SAVED_RR0_OFFSET, offsetof (struct exec_domain, arch.metaphysical_saved_rr0));
    1.23 +	DEFINE(IA64_VCPU_BREAKIMM_OFFSET, offsetof (struct exec_domain, arch.breakimm));
    1.24 +	DEFINE(IA64_VCPU_IVA_OFFSET, offsetof (struct exec_domain, arch.iva));
    1.25  
    1.26  	BLANK();
    1.27  
     2.1 --- a/xen/arch/ia64/dom_fw.c	Tue May 31 20:54:20 2005 +0000
     2.2 +++ b/xen/arch/ia64/dom_fw.c	Wed Jun 01 20:11:09 2005 +0000
     2.3 @@ -50,7 +50,7 @@ void dom_efi_hypercall_patch(struct doma
     2.4  
     2.5  	if (d == dom0) paddr += dom0_start;
     2.6  	imva = domain_mpa_to_imva(d,paddr);
     2.7 -	build_hypercall_bundle(imva,d->breakimm,hypercall,1);
     2.8 +	build_hypercall_bundle(imva,d->arch.breakimm,hypercall,1);
     2.9  }
    2.10  
    2.11  
    2.12 @@ -61,7 +61,7 @@ void dom_fw_hypercall_patch(struct domai
    2.13  
    2.14  	if (d == dom0) paddr += dom0_start;
    2.15  	imva = domain_mpa_to_imva(d,paddr);
    2.16 -	build_hypercall_bundle(imva,d->breakimm,hypercall,ret);
    2.17 +	build_hypercall_bundle(imva,d->arch.breakimm,hypercall,ret);
    2.18  }
    2.19  
    2.20  
     3.1 --- a/xen/arch/ia64/domain.c	Tue May 31 20:54:20 2005 +0000
     3.2 +++ b/xen/arch/ia64/domain.c	Wed Jun 01 20:11:09 2005 +0000
     3.3 @@ -210,7 +210,7 @@ void arch_do_createdomain(struct exec_do
     3.4  	 */
     3.5  	d->xen_vastart = 0xf000000000000000;
     3.6  	d->xen_vaend = 0xf300000000000000;
     3.7 -	d->breakimm = 0x1000;
     3.8 +	d->arch.breakimm = 0x1000;
     3.9  
    3.10  	// stay on kernel stack because may get interrupts!
    3.11  	// ia64_ret_from_clone (which b0 gets in new_thread) switches
    3.12 @@ -256,7 +256,8 @@ void arch_do_createdomain(struct exec_do
    3.13  	d->xen_vastart = 0xf000000000000000;
    3.14  	d->xen_vaend = 0xf300000000000000;
    3.15  	d->shared_info_va = 0xf100000000000000;
    3.16 -	d->breakimm = 0x1000;
    3.17 +	d->arch.breakimm = 0x1000;
    3.18 +	ed->arch.breakimm = d->arch.breakimm;
    3.19  	// stay on kernel stack because may get interrupts!
    3.20  	// ia64_ret_from_clone (which b0 gets in new_thread) switches
    3.21  	// to user stack
     4.1 --- a/xen/arch/ia64/hyperprivop.S	Tue May 31 20:54:20 2005 +0000
     4.2 +++ b/xen/arch/ia64/hyperprivop.S	Wed Jun 01 20:11:09 2005 +0000
     4.3 @@ -62,6 +62,92 @@ GLOBAL_ENTRY(fast_hyperprivop)
     4.4  	// if not one of the above, give up for now and do it the slow way
     4.5  	br.sptk.many dispatch_break_fault ;;
     4.6  
     4.7 +// reflect domain breaks directly to domain
     4.8 +// FIXME: DOES NOT WORK YET
     4.9 +//	r16 == cr.isr
    4.10 +//	r17 == cr.iim
    4.11 +//	r18 == XSI_PSR_IC
    4.12 +//	r19 == vpsr.ic (low 32 bits) | vpsr.i (high 32 bits)
    4.13 +//	r22 == IA64_KR(CURRENT)+IA64_VCPU_BREAKIMM_OFFSET
    4.14 +//	r31 == pr
    4.15 +GLOBAL_ENTRY(fast_break_reflect)
    4.16 +	mov r20=cr.ipsr;;
    4.17 +	// if big-endian domain or privileged-perfmon bits set, do slow way
    4.18 +	extr.u r21=r20,IA64_PSR_BE_BIT,1 ;;
    4.19 +	cmp.ne p7,p0=r21,r0
    4.20 +(p7)	br.sptk.many dispatch_break_fault ;;
    4.21 +	extr.u r21=r20,IA64_PSR_PP_BIT,1 ;;
    4.22 +	cmp.ne p7,p0=r21,r0
    4.23 +(p7)	br.sptk.many dispatch_break_fault ;;
    4.24 +	// ensure ipsr.cpl==2, ipsr.ri==0
    4.25 +	// FIXME: any other psr bits need to be properly set/validated?
    4.26 +	//   ...see process.c: DELIVER_PSR_CLR/SET
    4.27 +	extr.u r21=r20,IA64_PSR_CPL0_BIT,2;;
    4.28 +	extr.u r23=r20,IA64_PSR_RI_BIT,2;;
    4.29 +	dep r20=-1,r20,IA64_PSR_CPL1_BIT,1 ;;
    4.30 +	dep r20=0,r20,IA64_PSR_CPL0_BIT,1 ;;
    4.31 +	dep r20=0,r20,IA64_PSR_RI_BIT,2 ;;
    4.32 +	mov cr.ipsr=r20;;
    4.33 +	// save ipsr in shared_info, vipsr.cpl==(ipsr.cpl==3)?3:0
    4.34 +	cmp.ne p7,p0=3,r21;;
    4.35 +(p7)	mov r21=r0
    4.36 +	dep r20=r21,r20,IA64_PSR_CPL0_BIT,2 ;;
    4.37 +	dep r20=r23,r20,IA64_PSR_RI_BIT,2 ;;
    4.38 +	// vipsr.i=vpsr.i
    4.39 +	adds r21=XSI_PSR_I_OFS-XSI_PSR_IC_OFS,r18 ;;
    4.40 +	ld4 r21=[r21];;
    4.41 +	dep r20=r21,r20,IA64_PSR_I_BIT,1 ;;
    4.42 +	adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
    4.43 +	// FIXME: any other vpsr bits need to be properly set/validated?
    4.44 +	st8 [r21]=r20;;
    4.45 +	// save iim in shared_info
    4.46 +	adds r21=XSI_IIM_OFS-XSI_PSR_IC_OFS,r18 ;;
    4.47 +	st8 [r21]=r17;;
    4.48 +	// save iip in shared_info
    4.49 +	mov r20=cr.iip;;
    4.50 +	adds r21=XSI_IIP_OFS-XSI_PSR_IC_OFS,r18 ;;
    4.51 +	st8 [r21]=r20;;
    4.52 +	// save ifs in shared_info
    4.53 +	adds r21=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
    4.54 +	st4 [r21]=r0 ;;
    4.55 +	adds r21=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18
    4.56 +	st8 [r21]=r0 ;;
    4.57 +	cover ;;
    4.58 +	mov r20=cr.ifs;;
    4.59 +	adds r21=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
    4.60 +	st8 [r21]=r20;;
    4.61 +	// vpsr.i = vpsr.ic = 0 on delivery of interruption
    4.62 +	st8 [r18]=r0;;
    4.63 +	// FIXME: need to save iipa and isr to be arch-compliant
    4.64 +	// set iip to go to domain IVA break instruction vector
    4.65 +	adds r22=IA64_VCPU_IVA_OFFSET-IA64_VCPU_BREAKIMM_OFFSET,r22;;
    4.66 +	ld8 r23=[r22];;
    4.67 +	movl r24=0x2c00;;
    4.68 +	add r24=r24,r23;;
    4.69 +	mov cr.iip=r24;;
    4.70 +	// OK, now all set to go except for switch to virtual bank0
    4.71 +	mov r30=r2; mov r29=r3;;
    4.72 +	adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
    4.73 +	adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
    4.74 +	bsw.1;;
    4.75 +	st8 [r2]=r16,16; st8 [r3]=r17,16 ;;
    4.76 +	st8 [r2]=r18,16; st8 [r3]=r19,16 ;;
    4.77 +	st8 [r2]=r20,16; st8 [r3]=r21,16 ;;
    4.78 +	st8 [r2]=r22,16; st8 [r3]=r23,16 ;;
    4.79 +	st8 [r2]=r24,16; st8 [r3]=r25,16 ;;
    4.80 +	st8 [r2]=r26,16; st8 [r3]=r27,16 ;;
    4.81 +	st8 [r2]=r28,16; st8 [r3]=r29,16 ;;
    4.82 +	st8 [r2]=r30,16; st8 [r3]=r31,16 ;;
    4.83 +	movl r31=XSI_IPSR;;
    4.84 +	bsw.0 ;;
    4.85 +	mov r2=r30; mov r3=r29;;
    4.86 +	adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
    4.87 +	st4 [r20]=r0 ;;
    4.88 +	mov pr=r31,-1 ;;
    4.89 +	rfi
    4.90 +	;;
    4.91 +
    4.92 +
    4.93  // ensure that, if giving up, registers at entry to fast_hyperprivop unchanged
    4.94  ENTRY(hyper_rfi)
    4.95  #define FAST_HYPERPRIVOP_CNT
    4.96 @@ -112,8 +198,6 @@ ENTRY(hyper_rfi)
    4.97  	ld8 r20=[r20];;
    4.98  	dep r20=0,r20,38,25;; // ensure ifs has no reserved bits set
    4.99  	mov cr.ifs=r20 ;;
   4.100 -// TODO: increment a counter so we can count how many rfi's go the fast way
   4.101 -//    but where?  counter must be pinned
   4.102  	// ipsr.cpl == (vcr.ipsr.cpl == 0) 2 : 3;
   4.103  	dep r21=-1,r21,IA64_PSR_CPL1_BIT,1 ;;
   4.104  	// vpsr.i = vcr.ipsr.i; vpsr.ic = vcr.ipsr.ic
     5.1 --- a/xen/arch/ia64/ivt.S	Tue May 31 20:54:20 2005 +0000
     5.2 +++ b/xen/arch/ia64/ivt.S	Wed Jun 01 20:11:09 2005 +0000
     5.3 @@ -783,20 +783,26 @@ ENTRY(break_fault)
     5.4  	ld8 r19=[r18]
     5.5  	;;
     5.6  	cmp.eq p7,p0=r0,r17			// is this a psuedo-cover?
     5.7 -(p7)	br.sptk.many dispatch_privop_fault
     5.8 +(p7)	br.spnt.many dispatch_privop_fault
     5.9  	;;
    5.10 -	cmp4.ne p7,p0=r0,r19
    5.11 -(p7)	br.sptk.many dispatch_break_fault
    5.12 -	// If we get to here, we have a hyperprivop
    5.13 -	// For now, hyperprivops are handled through the break mechanism
    5.14 -	// Later, they will be fast hand-coded assembly with psr.ic off
    5.15 +	// if vpsr.ic is off, we have a hyperprivop
    5.16 +	// A hyperprivop is hand-coded assembly with psr.ic off
    5.17  	// which means no calls, no use of r1-r15 and no memory accesses
    5.18  	// except to pinned addresses!
    5.19 -#define FAST_HYPERPRIVOPS
    5.20 -#ifdef FAST_HYPERPRIVOPS
    5.21 -	br.sptk.many fast_hyperprivop
    5.22 +	cmp4.eq p7,p0=r0,r19
    5.23 +(p7)	br.sptk.many fast_hyperprivop
    5.24 +	;;
    5.25 +	mov r22=IA64_KR(CURRENT);;
    5.26 +	adds r22=IA64_VCPU_BREAKIMM_OFFSET,r22;;
    5.27 +	ld4 r23=[r22];;
    5.28 +	cmp4.eq p6,p7=r23,r17			// Xen-reserved breakimm?
    5.29 +(p6)	br.spnt.many dispatch_break_fault
    5.30 +	;;
    5.31 +//#define FAST_BREAK
    5.32 +#ifdef FAST_BREAK
    5.33 +	br.sptk.many fast_break_reflect
    5.34  #else
    5.35 -	br.sptk.many dispatch_break_fault
    5.36 +	br.spnt.many dispatch_break_fault
    5.37  #endif
    5.38  	;;
    5.39  #endif
     6.1 --- a/xen/arch/ia64/privop.c	Tue May 31 20:54:20 2005 +0000
     6.2 +++ b/xen/arch/ia64/privop.c	Wed Jun 01 20:11:09 2005 +0000
     6.3 @@ -987,14 +987,14 @@ int dump_hyperprivop_counts(char *buf)
     6.4  	char *s = buf;
     6.5  	unsigned long total = 0;
     6.6  	for (i = 1; i <= HYPERPRIVOP_MAX; i++) total += slow_hyperpriv_cnt[i];
     6.7 -	s += sprintf(s,"Slow hyperprivops (total %d:\n",total);
     6.8 +	s += sprintf(s,"Slow hyperprivops (total %d):\n",total);
     6.9  	for (i = 1; i <= HYPERPRIVOP_MAX; i++)
    6.10  		if (slow_hyperpriv_cnt[i])
    6.11  			s += sprintf(s,"%10d %s\n",
    6.12  				slow_hyperpriv_cnt[i], hyperpriv_str[i]);
    6.13  	total = 0;
    6.14  	for (i = 1; i <= HYPERPRIVOP_MAX; i++) total += fast_hyperpriv_cnt[i];
    6.15 -	s += sprintf(s,"Fast hyperprivops (total %d:\n",total);
    6.16 +	s += sprintf(s,"Fast hyperprivops (total %d):\n",total);
    6.17  	for (i = 1; i <= HYPERPRIVOP_MAX; i++)
    6.18  		if (fast_hyperpriv_cnt[i])
    6.19  			s += sprintf(s,"%10d %s\n",
    6.20 @@ -1016,6 +1016,7 @@ int dump_privop_counts_to_user(char __us
    6.21  	int n = dump_privop_counts(buf);
    6.22  
    6.23  	n += dump_hyperprivop_counts(buf + n);
    6.24 +	n += dump_reflect_counts(buf + n);
    6.25  #ifdef PRIVOP_ADDR_COUNT
    6.26  	n += dump_privop_addrs(buf + n);
    6.27  #endif
    6.28 @@ -1033,6 +1034,7 @@ int zero_privop_counts_to_user(char __us
    6.29  #ifdef PRIVOP_ADDR_COUNT
    6.30  	zero_privop_addrs();
    6.31  #endif
    6.32 +	zero_reflect_counts();
    6.33  	if (len < TMPBUFLEN) return -1;
    6.34  	if (__copy_to_user(ubuf,buf,n)) return -1;
    6.35  	return n;
     7.1 --- a/xen/arch/ia64/process.c	Tue May 31 20:54:20 2005 +0000
     7.2 +++ b/xen/arch/ia64/process.c	Wed Jun 01 20:11:09 2005 +0000
     7.3 @@ -130,6 +130,42 @@ unsigned long translate_domain_mpaddr(un
     7.4  	return ((pteval & _PAGE_PPN_MASK) | (mpaddr & ~PAGE_MASK));
     7.5  }
     7.6  
     7.7 +unsigned long slow_reflect_count[0x80] = { 0 };
     7.8 +unsigned long fast_reflect_count[0x80] = { 0 };
     7.9 +
    7.10 +#define inc_slow_reflect_count(vec) slow_reflect_count[vec>>8]++;
    7.11 +
    7.12 +void zero_reflect_counts(void)
    7.13 +{
    7.14 +	int i;
    7.15 +	for (i=0; i<0x80; i++) slow_reflect_count[i] = 0;
    7.16 +	for (i=0; i<0x80; i++) fast_reflect_count[i] = 0;
    7.17 +}
    7.18 +
    7.19 +int dump_reflect_counts(char *buf)
    7.20 +{
    7.21 +	int i,j,cnt;
    7.22 +	char *s = buf;
    7.23 +
    7.24 +	s += sprintf(s,"Slow reflections by vector:\n");
    7.25 +	for (i = 0, j = 0; i < 0x80; i++) {
    7.26 +		if (cnt = slow_reflect_count[i]) {
    7.27 +			s += sprintf(s,"0x%02x00:%10d, ",i,cnt);
    7.28 +			if ((j++ & 3) == 3) s += sprintf(s,"\n");
    7.29 +		}
    7.30 +	}
    7.31 +	if (j & 3) s += sprintf(s,"\n");
    7.32 +	s += sprintf(s,"Fast reflections by vector:\n");
    7.33 +	for (i = 0, j = 0; i < 0x80; i++) {
    7.34 +		if (cnt = fast_reflect_count[i]) {
    7.35 +			s += sprintf(s,"0x%02x00:%10d, ",i,cnt);
    7.36 +			if ((j++ & 3) == 3) s += sprintf(s,"\n");
    7.37 +		}
    7.38 +	}
    7.39 +	if (j & 3) s += sprintf(s,"\n");
    7.40 +	return s - buf;
    7.41 +}
    7.42 +
    7.43  void reflect_interruption(unsigned long ifa, unsigned long isr, unsigned long itiriim, struct pt_regs *regs, unsigned long vector)
    7.44  {
    7.45  	unsigned long vcpu_get_ipsr_int_state(struct exec_domain *,unsigned long);
    7.46 @@ -165,6 +201,7 @@ panic_domain(regs,"psr.ic off, deliverin
    7.47  		regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
    7.48  // NOTE: nested trap must NOT pass PSCB address
    7.49  		//regs->r31 = (unsigned long) &PSCB(ed);
    7.50 +		inc_slow_reflect_count(vector);
    7.51  		return;
    7.52  
    7.53  	}
    7.54 @@ -195,6 +232,8 @@ panic_domain(regs,"psr.ic off, deliverin
    7.55  
    7.56  	PSCB(ed,interrupt_delivery_enabled) = 0;
    7.57  	PSCB(ed,interrupt_collection_enabled) = 0;
    7.58 +
    7.59 +	inc_slow_reflect_count(vector);
    7.60  }
    7.61  
    7.62  void foodpi(void) {}
    7.63 @@ -748,7 +787,7 @@ ia64_handle_break (unsigned long ifa, st
    7.64  		if (running_on_sim) do_ssc(vcpu_get_gr(current,36), regs);
    7.65  		else do_ssc(vcpu_get_gr(current,36), regs);
    7.66  	}
    7.67 -	else if (iim == d->breakimm) {
    7.68 +	else if (iim == d->arch.breakimm) {
    7.69  		if (ia64_hypercall(regs))
    7.70  			vcpu_increment_iip(current);
    7.71  	}
     8.1 --- a/xen/include/asm-ia64/domain.h	Tue May 31 20:54:20 2005 +0000
     8.2 +++ b/xen/include/asm-ia64/domain.h	Wed Jun 01 20:11:09 2005 +0000
     8.3 @@ -49,7 +49,6 @@ struct arch_domain {
     8.4  #define starting_rid arch.starting_rid
     8.5  #define ending_rid arch.ending_rid
     8.6  #define rid_bits arch.rid_bits
     8.7 -#define breakimm arch.breakimm
     8.8  #define xen_vastart arch.xen_vastart
     8.9  #define xen_vaend arch.xen_vaend
    8.10  #define shared_info_va arch.shared_info_va
    8.11 @@ -75,6 +74,7 @@ struct arch_exec_domain {
    8.12      void *regs;	/* temporary until find a better way to do privops */
    8.13      int metaphysical_rr0;		// from arch_domain (so is pinned)
    8.14      int metaphysical_saved_rr0;		// from arch_domain (so is pinned)
    8.15 +    int breakimm;			// from arch_domain (so is pinned)
    8.16      struct mm_struct *active_mm;
    8.17      struct thread_struct _thread;	// this must be last
    8.18  #ifdef CONFIG_VTI