ia64/xen-unstable

changeset 4784:674bf85fff9a

bitkeeper revision 1.1389.9.1 (427ba309i_zOrtoMDOTBwa5_vBiEXQ)

Add support for privified mov-from-pmd
Add counters for privified-fc and privified-cpuid
Add optional support for counting addresses of privops
Remove unnecessary PCI stuff
Add optional heartbeat console output
Signed-off by: Dan Magenheimer <dan.magenheimer@hp.com>
author djm@kirby.fc.hp.com
date Fri May 06 17:02:01 2005 +0000 (2005-05-06)
parents 7bb775134a42
children 214e5c4b003d
files xen/arch/ia64/privop.c xen/arch/ia64/vcpu.c xen/arch/ia64/xenmisc.c xen/arch/ia64/xentime.c xen/include/asm-ia64/config.h xen/include/asm-ia64/vcpu.h
line diff
     1.1 --- a/xen/arch/ia64/privop.c	Tue May 03 17:24:41 2005 +0000
     1.2 +++ b/xen/arch/ia64/privop.c	Fri May 06 17:02:01 2005 +0000
     1.3 @@ -417,10 +417,17 @@ IA64FAULT priv_mov_from_pmc(VCPU *vcpu, 
     1.4  	UINT64 val;
     1.5  	IA64FAULT fault;
     1.6  	
     1.7 -	fault = vcpu_get_pmc(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val);
     1.8 -	if (fault == IA64_NO_FAULT)
     1.9 -		return vcpu_set_gr(vcpu, inst.M43.r1, val);
    1.10 -	else return fault;
    1.11 +	if (inst.M43.r1 > 63) { // privified mov from pmd
    1.12 +		fault = vcpu_get_pmd(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val);
    1.13 +		if (fault == IA64_NO_FAULT)
    1.14 +			return vcpu_set_gr(vcpu, inst.M43.r1-64, val);
    1.15 +	}
    1.16 +	else {
    1.17 +		fault = vcpu_get_pmc(vcpu,vcpu_get_gr(vcpu,inst.M43.r3),&val);
    1.18 +		if (fault == IA64_NO_FAULT)
    1.19 +			return vcpu_set_gr(vcpu, inst.M43.r1, val);
    1.20 +	}
    1.21 +	return fault;
    1.22  }
    1.23  
    1.24  unsigned long from_cr_cnt[128] = { 0 };
    1.25 @@ -531,6 +538,8 @@ struct {
    1.26  	unsigned long bsw0;
    1.27  	unsigned long bsw1;
    1.28  	unsigned long cover;
    1.29 +	unsigned long fc;
    1.30 +	unsigned long cpuid;
    1.31  	unsigned long Mpriv_cnt[64];
    1.32  } privcnt = { 0 };
    1.33  
    1.34 @@ -631,7 +640,11 @@ priv_handle_op(VCPU *vcpu, REGS *regs, i
    1.35  				else x6 = 0x1a;
    1.36  			}
    1.37  		}
    1.38 -		privcnt.Mpriv_cnt[x6]++;
    1.39 +		if (x6 == 52 && inst.M28.r3 > 63)
    1.40 +			privcnt.fc++;
    1.41 +		else if (x6 == 16 && inst.M43.r3 > 63)
    1.42 +			privcnt.cpuid++;
    1.43 +		else privcnt.Mpriv_cnt[x6]++;
    1.44  		return (*pfunc)(vcpu,inst);
    1.45  		break;
    1.46  	    case B:
    1.47 @@ -826,6 +839,12 @@ int dump_privop_counts(char *buf)
    1.48  	if (privcnt.cover)
    1.49  		s += sprintf(s,"%10d  %s [%d%%]\r\n", privcnt.cover,
    1.50  			"cover", (privcnt.cover*100L)/sum);
    1.51 +	if (privcnt.fc)
    1.52 +		s += sprintf(s,"%10d  %s [%d%%]\r\n", privcnt.fc,
    1.53 +			"privified-fc", (privcnt.fc*100L)/sum);
    1.54 +	if (privcnt.cpuid)
    1.55 +		s += sprintf(s,"%10d  %s [%d%%]\r\n", privcnt.cpuid,
    1.56 +			"privified-getcpuid", (privcnt.cpuid*100L)/sum);
    1.57  	for (i=0; i < 64; i++) if (privcnt.Mpriv_cnt[i]) {
    1.58  		if (!Mpriv_str[i]) s += sprintf(s,"PRIVSTRING NULL!!\r\n");
    1.59  		else s += sprintf(s,"%10d  %s [%d%%]\r\n", privcnt.Mpriv_cnt[i],
    1.60 @@ -864,6 +883,7 @@ int zero_privop_counts(char *buf)
    1.61  	privcnt.ssm = 0; privcnt.rsm = 0;
    1.62  	privcnt.rfi = 0; privcnt.bsw0 = 0;
    1.63  	privcnt.bsw1 = 0; privcnt.cover = 0;
    1.64 +	privcnt.fc = 0; privcnt.cpuid = 0;
    1.65  	for (i=0; i < 64; i++) privcnt.Mpriv_cnt[i] = 0;
    1.66  	for (j=0; j < 128; j++) from_cr_cnt[j] = 0;
    1.67  	for (j=0; j < 128; j++) to_cr_cnt[j] = 0;
    1.68 @@ -871,12 +891,61 @@ int zero_privop_counts(char *buf)
    1.69  	return s - buf;
    1.70  }
    1.71  
    1.72 +#ifdef PRIVOP_ADDR_COUNT
    1.73 +
    1.74 +extern struct privop_addr_count privop_addr_counter[];
    1.75 +
    1.76 +void privop_count_addr(unsigned long iip, int inst)
    1.77 +{
    1.78 +	struct privop_addr_count *v = &privop_addr_counter[inst];
    1.79 +	int i;
    1.80 +
    1.81 +	for (i = 0; i < PRIVOP_COUNT_NADDRS; i++) {
    1.82 +		if (!v->addr[i]) { v->addr[i] = iip; v->count[i]++; return; }
    1.83 +		else if (v->addr[i] == iip)  { v->count[i]++; return; }
    1.84 +	}
    1.85 +	v->overflow++;;
    1.86 +}
    1.87 +
    1.88 +int dump_privop_addrs(char *buf)
    1.89 +{
    1.90 +	int i,j;
    1.91 +	char *s = buf;
    1.92 +	s += sprintf(s,"Privop addresses:\r\n");
    1.93 +	for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
    1.94 +		struct privop_addr_count *v = &privop_addr_counter[i];
    1.95 +		s += sprintf(s,"%s:\n",v->instname);
    1.96 +		for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) {
    1.97 +			if (!v->addr[j]) break;
    1.98 +			s += sprintf(s," @%p #%ld\n",v->addr[j],v->count[j]);
    1.99 +		}
   1.100 +		if (v->overflow) 
   1.101 +			s += sprintf(s," other #%ld\n",v->overflow);
   1.102 +	}
   1.103 +	return s - buf;
   1.104 +}
   1.105 +
   1.106 +void zero_privop_addrs(void)
   1.107 +{
   1.108 +	int i,j;
   1.109 +	for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
   1.110 +		struct privop_addr_count *v = &privop_addr_counter[i];
   1.111 +		for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
   1.112 +			v->addr[j] = v->count[j] = 0;
   1.113 +		v->overflow = 0;
   1.114 +	}
   1.115 +}
   1.116 +#endif
   1.117 +
   1.118  #define TMPBUFLEN 8*1024
   1.119  int dump_privop_counts_to_user(char __user *ubuf, int len)
   1.120  {
   1.121  	char buf[TMPBUFLEN];
   1.122  	int n = dump_privop_counts(buf);
   1.123  
   1.124 +#ifdef PRIVOP_ADDR_COUNT
   1.125 +	n += dump_privop_addrs(buf + n);
   1.126 +#endif
   1.127  	if (len < TMPBUFLEN) return -1;
   1.128  	if (__copy_to_user(ubuf,buf,n)) return -1;
   1.129  	return n;
   1.130 @@ -887,6 +956,9 @@ int zero_privop_counts_to_user(char __us
   1.131  	char buf[TMPBUFLEN];
   1.132  	int n = zero_privop_counts(buf);
   1.133  
   1.134 +#ifdef PRIVOP_ADDR_COUNT
   1.135 +	zero_privop_addrs();
   1.136 +#endif
   1.137  	if (len < TMPBUFLEN) return -1;
   1.138  	if (__copy_to_user(ubuf,buf,n)) return -1;
   1.139  	return n;
     2.1 --- a/xen/arch/ia64/vcpu.c	Tue May 03 17:24:41 2005 +0000
     2.2 +++ b/xen/arch/ia64/vcpu.c	Fri May 06 17:02:01 2005 +0000
     2.3 @@ -37,6 +37,17 @@ typedef	union {
     2.4  
     2.5  #define STATIC
     2.6  
     2.7 +#ifdef PRIVOP_ADDR_COUNT
     2.8 +struct privop_addr_count privop_addr_counter[PRIVOP_COUNT_NINSTS] = {
     2.9 +	{ "rsm", { 0 }, { 0 }, 0 },
    2.10 +	{ "ssm", { 0 }, { 0 }, 0 }
    2.11 +};
    2.12 +extern void privop_count_addr(unsigned long addr, int inst);
    2.13 +#define	PRIVOP_COUNT_ADDR(regs,inst) privop_count_addr(regs->cr_iip,inst)
    2.14 +#else
    2.15 +#define	PRIVOP_COUNT_ADDR(x,y) do {} while (0)
    2.16 +#endif
    2.17 +
    2.18  unsigned long vcpu_verbose = 0;
    2.19  #define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0)
    2.20  
    2.21 @@ -77,30 +88,20 @@ vcpu_set_gr(VCPU *vcpu, unsigned reg, UI
    2.22  IA64FAULT vcpu_set_ar(VCPU *vcpu, UINT64 reg, UINT64 val)
    2.23  {
    2.24  	if (reg == 44) return (vcpu_set_itc(vcpu,val));
    2.25 -	if (reg == 27) return (IA64_ILLOP_FAULT);
    2.26 -	if (reg > 7) return (IA64_ILLOP_FAULT);
    2.27 -	PSCB(vcpu,krs[reg]) = val;
    2.28 -#if 0
    2.29 -// for now, privify kr read's so all kr accesses are privileged
    2.30 -	switch (reg) {
    2.31 -	      case 0: asm volatile ("mov ar.k0=%0" :: "r"(val)); break;
    2.32 -	      case 1: asm volatile ("mov ar.k1=%0" :: "r"(val)); break;
    2.33 -	      case 2: asm volatile ("mov ar.k2=%0" :: "r"(val)); break;
    2.34 -	      case 3: asm volatile ("mov ar.k3=%0" :: "r"(val)); break;
    2.35 -	      case 4: asm volatile ("mov ar.k4=%0" :: "r"(val)); break;
    2.36 -	      case 5: asm volatile ("mov ar.k5=%0" :: "r"(val)); break;
    2.37 -	      case 6: asm volatile ("mov ar.k6=%0" :: "r"(val)); break;
    2.38 -	      case 7: asm volatile ("mov ar.k7=%0" :: "r"(val)); break;
    2.39 -	      case 27: asm volatile ("mov ar.cflg=%0" :: "r"(val)); break;
    2.40 -	}
    2.41 -#endif
    2.42 +	else if (reg == 27) return (IA64_ILLOP_FAULT);
    2.43 +	else if (reg == 24)
    2.44 +	    printf("warning: setting ar.eflg is a no-op; no IA-32 support\n");
    2.45 +	else if (reg > 7) return (IA64_ILLOP_FAULT);
    2.46 +	else PSCB(vcpu,krs[reg]) = val;
    2.47  	return IA64_NO_FAULT;
    2.48  }
    2.49  
    2.50  IA64FAULT vcpu_get_ar(VCPU *vcpu, UINT64 reg, UINT64 *val)
    2.51  {
    2.52 -	if (reg > 7) return (IA64_ILLOP_FAULT);
    2.53 -	*val = PSCB(vcpu,krs[reg]);
    2.54 +	if (reg == 24)
    2.55 +	    printf("warning: getting ar.eflg is a no-op; no IA-32 support\n");
    2.56 +	else if (reg > 7) return (IA64_ILLOP_FAULT);
    2.57 +	else *val = PSCB(vcpu,krs[reg]);
    2.58  	return IA64_NO_FAULT;
    2.59  }
    2.60  
    2.61 @@ -124,6 +125,7 @@ IA64FAULT vcpu_reset_psr_sm(VCPU *vcpu, 
    2.62  	struct ia64_psr psr, imm, *ipsr;
    2.63  	REGS *regs = vcpu_regs(vcpu);
    2.64  
    2.65 +	PRIVOP_COUNT_ADDR(regs,_RSM);
    2.66  	// TODO: All of these bits need to be virtualized
    2.67  	// TODO: Only allowed for current vcpu
    2.68  	__asm__ __volatile ("mov %0=psr;;" : "=r"(psr) :: "memory");
    2.69 @@ -158,6 +160,7 @@ IA64FAULT vcpu_set_psr_sm(VCPU *vcpu, UI
    2.70  	REGS *regs = vcpu_regs(vcpu);
    2.71  	UINT64 mask, enabling_interrupts = 0;
    2.72  
    2.73 +	PRIVOP_COUNT_ADDR(regs,_SSM);
    2.74  	// TODO: All of these bits need to be virtualized
    2.75  	__asm__ __volatile ("mov %0=psr;;" : "=r"(psr) :: "memory");
    2.76  	imm = *(struct ia64_psr *)&imm24;
     3.1 --- a/xen/arch/ia64/xenmisc.c	Tue May 03 17:24:41 2005 +0000
     3.2 +++ b/xen/arch/ia64/xenmisc.c	Fri May 06 17:02:01 2005 +0000
     3.3 @@ -133,80 +133,13 @@ void free_page_type(struct pfn_info *pag
     3.4  }
     3.5  
     3.6  ///////////////////////////////
     3.7 -// from arch/x86/pci.c
     3.8 -///////////////////////////////
     3.9 -
    3.10 -int
    3.11 -pcibios_prep_mwi (struct pci_dev *dev)
    3.12 -{
    3.13 -	dummy();
    3.14 -}
    3.15 -
    3.16 -///////////////////////////////
    3.17 -// from arch/x86/pci-irq.c
    3.18 -///////////////////////////////
    3.19 -
    3.20 -void pcibios_enable_irq(struct pci_dev *dev)
    3.21 -{
    3.22 -	dummy();
    3.23 -}
    3.24 -
    3.25 -///////////////////////////////
    3.26 -// from arch/ia64/pci-pc.c
    3.27 -///////////////////////////////
    3.28 -
    3.29 -#include <xen/pci.h>
    3.30 -
    3.31 -int pcibios_enable_device(struct pci_dev *dev, int mask)
    3.32 -{
    3.33 -	dummy();
    3.34 -	return 0;
    3.35 -}
    3.36 -
    3.37 -int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL;
    3.38 -int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL;
    3.39 -
    3.40 -//struct pci_fixup pcibios_fixups[] = { { 0 } };
    3.41 -struct pci_fixup pcibios_fixups[] = { { 0 } };
    3.42 -
    3.43 -void
    3.44 -pcibios_align_resource(void *data, struct resource *res,
    3.45 -		       unsigned long size, unsigned long align)
    3.46 -{
    3.47 -	dummy();
    3.48 -}
    3.49 -
    3.50 -void
    3.51 -pcibios_update_resource(struct pci_dev *dev, struct resource *root,
    3.52 -			struct resource *res, int resource)
    3.53 -{
    3.54 -	dummy();
    3.55 -}
    3.56 -
    3.57 -void __devinit  pcibios_fixup_bus(struct pci_bus *b)
    3.58 -{
    3.59 -	dummy();
    3.60 -}
    3.61 -
    3.62 -void __init pcibios_init(void)
    3.63 -{
    3.64 -	dummy();
    3.65 -}
    3.66 -
    3.67 -char * __devinit  pcibios_setup(char *str)
    3.68 -{
    3.69 -	dummy();
    3.70 -	return 0;
    3.71 -}
    3.72 -
    3.73 -///////////////////////////////
    3.74  // from arch/ia64/traps.c
    3.75  ///////////////////////////////
    3.76  
    3.77  void show_registers(struct pt_regs *regs)
    3.78  {
    3.79  	printf("*** ADD REGISTER DUMP HERE FOR DEBUGGING\n");
    3.80 -}	
    3.81 +}
    3.82  
    3.83  ///////////////////////////////
    3.84  // from common/keyhandler.c
     4.1 --- a/xen/arch/ia64/xentime.c	Tue May 03 17:24:41 2005 +0000
     4.2 +++ b/xen/arch/ia64/xentime.c	Fri May 06 17:02:01 2005 +0000
     4.3 @@ -84,6 +84,17 @@ xen_timer_interrupt (int irq, void *dev_
     4.4  {
     4.5  	unsigned long new_itm;
     4.6  
     4.7 +#define HEARTBEAT_FREQ 16	// period in seconds
     4.8 +#ifdef HEARTBEAT_FREQ
     4.9 +	static long count = 0;
    4.10 +	if (!(++count & ((HEARTBEAT_FREQ*1024)-1))) {
    4.11 +		printf("Heartbeat... iip=%p,psr.i=%d,pend=%d\n",
    4.12 +			regs->cr_iip,
    4.13 +			current->vcpu_info->arch.interrupt_delivery_enabled,
    4.14 +			current->vcpu_info->arch.pending_interruption);
    4.15 +		count = 0;
    4.16 +	}
    4.17 +#endif
    4.18  #ifndef XEN
    4.19  	if (unlikely(cpu_is_offline(smp_processor_id()))) {
    4.20  		return IRQ_HANDLED;
     5.1 --- a/xen/include/asm-ia64/config.h	Tue May 03 17:24:41 2005 +0000
     5.2 +++ b/xen/include/asm-ia64/config.h	Fri May 06 17:02:01 2005 +0000
     5.3 @@ -174,12 +174,6 @@ struct device {
     5.4  #endif
     5.5  };
     5.6  
     5.7 -// from linux/include/linux/pci.h
     5.8 -struct pci_bus_region {
     5.9 -	unsigned long start;
    5.10 -	unsigned long end;
    5.11 -};
    5.12 -
    5.13  // warning: unless search_extable is declared, the return value gets
    5.14  // truncated to 32-bits, causing a very strange error in privop handling
    5.15  struct exception_table_entry;
     6.1 --- a/xen/include/asm-ia64/vcpu.h	Tue May 03 17:24:41 2005 +0000
     6.2 +++ b/xen/include/asm-ia64/vcpu.h	Fri May 06 17:02:01 2005 +0000
     6.3 @@ -21,6 +21,21 @@ typedef struct pt_regs REGS;
     6.4  //#define vcpu_regs(vcpu)		&((struct spk_thread_t *)vcpu)->thread_regs
     6.5  //#define vcpu_thread(vcpu)	((struct spk_thread_t *)vcpu)
     6.6  
     6.7 +#define PRIVOP_ADDR_COUNT
     6.8 +#ifdef PRIVOP_ADDR_COUNT
     6.9 +#define _RSM 0
    6.10 +#define _SSM 1
    6.11 +#define PRIVOP_COUNT_NINSTS 2
    6.12 +#define PRIVOP_COUNT_NADDRS 30
    6.13 +
    6.14 +struct privop_addr_count {
    6.15 +	char *instname;
    6.16 +	unsigned long addr[PRIVOP_COUNT_NADDRS];
    6.17 +	unsigned long count[PRIVOP_COUNT_NADDRS];
    6.18 +	unsigned long overflow;
    6.19 +};
    6.20 +#endif
    6.21 +
    6.22  /* general registers */
    6.23  extern UINT64 vcpu_get_gr(VCPU *vcpu, unsigned reg);
    6.24  extern IA64FAULT vcpu_set_gr(VCPU *vcpu, unsigned reg, UINT64 value);