# HG changeset patch # User gingold@virtu10 # Node ID f5a4620c4ece5a6fd5607cc865b2d391f5ed2a73 # Parent fc6c3d866477a2a7454ba032281744b534d78bf8 Convert remaining stat counter to perfc. Get rid of unsafe hypercall. Signed-off-by: Tristan Gingold diff -r fc6c3d866477 -r f5a4620c4ece xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/arch/ia64/xen/domain.c Thu Aug 10 15:40:00 2006 +0200 @@ -47,7 +47,6 @@ #include #include #include -#include unsigned long dom0_size = 512*1024*1024; unsigned long dom0_align = 64*1024*1024; diff -r fc6c3d866477 -r f5a4620c4ece xen/arch/ia64/xen/faults.c --- a/xen/arch/ia64/xen/faults.c Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/arch/ia64/xen/faults.c Thu Aug 10 15:40:00 2006 +0200 @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff -r fc6c3d866477 -r f5a4620c4ece xen/arch/ia64/xen/hypercall.c --- a/xen/arch/ia64/xen/hypercall.c Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/arch/ia64/xen/hypercall.c Thu Aug 10 15:40:00 2006 +0200 @@ -28,7 +28,6 @@ #include #include #include -#include static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop); static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg); @@ -275,43 +274,12 @@ fw_hypercall (struct pt_regs *regs) return IA64_NO_FAULT; } -/* opt_unsafe_hypercall: If true, unsafe debugging hypercalls are allowed. - These can create security hole. */ -static int opt_unsafe_hypercall = 0; -boolean_param("unsafe_hypercall", opt_unsafe_hypercall); - IA64FAULT ia64_hypercall (struct pt_regs *regs) { struct vcpu *v = current; unsigned long index = regs->r2; int privlvl = (regs->cr_ipsr & IA64_PSR_CPL) >> IA64_PSR_CPL0_BIT; - - if (index >= FW_HYPERCALL_FIRST_USER) { - /* Note: user hypercalls are not safe, since Xen doesn't - check memory access privilege: Xen does not deny reading - or writing to kernel memory. */ - if (!opt_unsafe_hypercall) { - printf("user xen/ia64 hypercalls disabled\n"); - regs->r8 = -1; - } - else switch (index) { - case 0xffff: - regs->r8 = dump_privop_counts_to_user( - (char *) vcpu_get_gr(v,32), - (int) vcpu_get_gr(v,33)); - break; - case 0xfffe: - regs->r8 = zero_privop_counts_to_user( - (char *) vcpu_get_gr(v,32), - (int) vcpu_get_gr(v,33)); - break; - default: - printf("unknown user xen/ia64 hypercall %lx\n", index); - regs->r8 = do_ni_hypercall(); - } - return IA64_NO_FAULT; - } /* Hypercalls are only allowed by kernel. Kernel checks memory accesses. */ diff -r fc6c3d866477 -r f5a4620c4ece xen/arch/ia64/xen/privop.c --- a/xen/arch/ia64/xen/privop.c Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/arch/ia64/xen/privop.c Thu Aug 10 15:40:00 2006 +0200 @@ -13,7 +13,6 @@ #include #include #include -#include long priv_verbose=0; unsigned long privop_trace = 0; diff -r fc6c3d866477 -r f5a4620c4ece xen/arch/ia64/xen/privop_stat.c --- a/xen/arch/ia64/xen/privop_stat.c Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/arch/ia64/xen/privop_stat.c Thu Aug 10 15:40:00 2006 +0200 @@ -1,26 +1,47 @@ +#include +#include +#include +#include #include -#include -#include -#include -#ifdef PRIVOP_ADDR_COUNT -#define PRIVOP_COUNT_NINSTS 2 -#define PRIVOP_COUNT_NADDRS 30 +#ifdef CONFIG_PRIVOP_ADDRS struct privop_addr_count { - const char *instname; unsigned long addr[PRIVOP_COUNT_NADDRS]; - unsigned long count[PRIVOP_COUNT_NADDRS]; - unsigned long overflow; + unsigned int count[PRIVOP_COUNT_NADDRS]; + unsigned int overflow; + atomic_t *perfc_addr; + atomic_t *perfc_count; + atomic_t *perfc_overflow; }; -static struct privop_addr_count privop_addr_counter[PRIVOP_COUNT_NINSTS] = { - [_GET_IFA] = { "=ifa", { 0 }, { 0 }, 0 }, - [_THASH] = { "thash", { 0 }, { 0 }, 0 } +static struct privop_addr_count privop_addr_counter[] = { +#undef PERFCOUNTER +#undef PERFCOUNTER_CPU +#undef PERFCOUNTER_ARRAY +#undef PERFSTATUS +#undef PERFSTATUS_CPU +#undef PERFSTATUS_ARRAY +#define PERFCOUNTER( var, name ) +#define PERFCOUNTER_CPU( var, name ) +#define PERFCOUNTER_ARRAY( var, name, size ) +#define PERFSTATUS( var, name ) +#define PERFSTATUS_CPU( var, name ) +#define PERFSTATUS_ARRAY( var, name, size ) +#undef PERFPRIVOPADDR +#define PERFPRIVOPADDR(name) \ + { { 0 }, { 0 }, 0 , \ + perfcounters.privop_addr_##name##_addr, \ + perfcounters.privop_addr_##name##_count, \ + perfcounters.privop_addr_##name##_overflow \ + }, +#include }; -void privop_count_addr(unsigned long iip, int inst) +#define PRIVOP_COUNT_NINSTS (sizeof(privop_addr_counter)/sizeof(privop_addr_counter[0])) + +void privop_count_addr(unsigned long iip, enum privop_inst inst) { struct privop_addr_count *v = &privop_addr_counter[inst]; int i; @@ -41,29 +62,28 @@ void privop_count_addr(unsigned long iip v->overflow++;; } -static int dump_privop_addrs(char *buf) +void gather_privop_addrs(void) { int i, j; - char *s = buf; - s += sprintf(s, "Privop addresses:\n"); + atomic_t *v; for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) { - struct privop_addr_count *v = &privop_addr_counter[i]; - s += sprintf(s, "%s:\n", v->instname); - for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) { - if (!v->addr[j]) - break; - s += sprintf(s, " at 0x%lx #%ld\n", - v->addr[j], v->count[j]); - } - if (v->overflow) - s += sprintf(s, " other #%ld\n", v->overflow); + /* Note: addresses are truncated! */ + v = privop_addr_counter[i].perfc_addr; + for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) + atomic_set(&v[j], privop_addr_counter[i].addr[j]); + + v = privop_addr_counter[i].perfc_count; + for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) + atomic_set(&v[j], privop_addr_counter[i].count[j]); + + atomic_set (privop_addr_counter[i].perfc_overflow, + privop_addr_counter[i].overflow); } - return s - buf; } -static void zero_privop_addrs(void) +void reset_privop_addrs(void) { - int i,j; + int i, j; for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) { struct privop_addr_count *v = &privop_addr_counter[i]; for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) @@ -119,30 +139,3 @@ static const char * const hyperpriv_str[ "=rr", "rr=", "kr=", "fc", "=cpuid", "=pmd", "=ar.eflg", "ar.eflg=" }; #endif - -#define TMPBUFLEN 8*1024 -int dump_privop_counts_to_user(char __user *ubuf, int len) -{ - char buf[TMPBUFLEN]; - int n; - - if (len < TMPBUFLEN) - return -1; - - n = 0; -#ifdef PRIVOP_ADDR_COUNT - n += dump_privop_addrs(buf + n); -#endif - n += dump_vhpt_stats(buf + n); - if (__copy_to_user(ubuf,buf,n)) - return -1; - return n; -} - -int zero_privop_counts_to_user(char __user *ubuf, int len) -{ -#ifdef PRIVOP_ADDR_COUNT - zero_privop_addrs(); -#endif - return 0; -} diff -r fc6c3d866477 -r f5a4620c4ece xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/arch/ia64/xen/vcpu.c Thu Aug 10 15:40:00 2006 +0200 @@ -473,7 +473,7 @@ IA64FAULT vcpu_get_iip(VCPU *vcpu, UINT6 IA64FAULT vcpu_get_ifa(VCPU *vcpu, UINT64 *pval) { - PRIVOP_COUNT_ADDR(vcpu_regs(vcpu),_GET_IFA); + PRIVOP_COUNT_ADDR(vcpu_regs(vcpu),privop_inst_get_ifa); *pval = PSCB(vcpu,ifa); return (IA64_NO_FAULT); } @@ -540,7 +540,7 @@ IA64FAULT vcpu_get_iim(VCPU *vcpu, UINT6 IA64FAULT vcpu_get_iha(VCPU *vcpu, UINT64 *pval) { - PRIVOP_COUNT_ADDR(vcpu_regs(vcpu),_THASH); + PRIVOP_COUNT_ADDR(vcpu_regs(vcpu),privop_inst_thash); *pval = PSCB(vcpu,iha); return (IA64_NO_FAULT); } diff -r fc6c3d866477 -r f5a4620c4ece xen/arch/ia64/xen/vhpt.c --- a/xen/arch/ia64/xen/vhpt.c Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/arch/ia64/xen/vhpt.c Thu Aug 10 15:40:00 2006 +0200 @@ -261,13 +261,12 @@ void flush_tlb_mask(cpumask_t mask) (cpu, (void (*)(void *))flush_tlb_vhpt_all, NULL, 1, 1); } -int dump_vhpt_stats(char *buf) +#ifdef PERF_COUNTERS +void gather_vhpt_stats(void) { int i, cpu; - char *s = buf; - - s += sprintf(s,"VHPT usage (%ld entries):\n", - (unsigned long) VHPT_NUM_ENTRIES); + + perfc_set(vhpt_nbr_entries, VHPT_NUM_ENTRIES); for_each_present_cpu (cpu) { struct vhpt_lf_entry *v = __va(per_cpu(vhpt_paddr, cpu)); @@ -276,8 +275,7 @@ int dump_vhpt_stats(char *buf) for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++) if (!(v->ti_tag & INVALID_TI_TAG)) vhpt_valid++; - s += sprintf(s," cpu %d: %ld\n", cpu, vhpt_valid); - } - - return s - buf; -} + perfc_seta (vhpt_valid_entries, cpu, vhpt_valid); + } +} +#endif diff -r fc6c3d866477 -r f5a4620c4ece xen/include/asm-ia64/config.h --- a/xen/include/asm-ia64/config.h Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/include/asm-ia64/config.h Thu Aug 10 15:40:00 2006 +0200 @@ -36,6 +36,12 @@ #define supervisor_mode_kernel (0) #define MAX_DMADOM_PFN (0x7FFFFFFFUL >> PAGE_SHIFT) /* 31 addressable bits */ + +/* If PERFC is used, include privop maps. */ +#ifdef PERF_COUNTERS +#define CONFIG_PRIVOP_ADDRS +#define PRIVOP_COUNT_NADDRS 30 +#endif #ifndef __ASSEMBLY__ diff -r fc6c3d866477 -r f5a4620c4ece xen/include/asm-ia64/perfc.h --- a/xen/include/asm-ia64/perfc.h Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/include/asm-ia64/perfc.h Thu Aug 10 15:40:00 2006 +0200 @@ -1,5 +1,8 @@ #ifndef __ASM_PERFC_H__ #define __ASM_PERFC_H__ + +#include +#include static inline void arch_perfc_printall (void) { @@ -7,10 +10,17 @@ static inline void arch_perfc_printall ( static inline void arch_perfc_reset (void) { +#ifdef CONFIG_PRIVOP_ADDRS + reset_privop_addrs (); +#endif } static inline void arch_perfc_gather (void) { + gather_vhpt_stats (); +#ifdef CONFIG_PRIVOP_ADDRS + gather_privop_addrs (); +#endif } #endif diff -r fc6c3d866477 -r f5a4620c4ece xen/include/asm-ia64/perfc_defn.h --- a/xen/include/asm-ia64/perfc_defn.h Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/include/asm-ia64/perfc_defn.h Thu Aug 10 15:40:00 2006 +0200 @@ -40,3 +40,20 @@ PERFCOUNTER_ARRAY(fast_hyperprivop, "f PERFCOUNTER_ARRAY(slow_reflect, "slow reflection", 0x80) PERFCOUNTER_ARRAY(fast_reflect, "fast reflection", 0x80) + +PERFSTATUS(vhpt_nbr_entries, "nbr of entries per VHPT") +PERFSTATUS_CPU(vhpt_valid_entries, "nbr of valid entries in VHPT") + +#ifdef CONFIG_PRIVOP_ADDRS +#ifndef PERFPRIVOPADDR +#define PERFPRIVOPADDR(name) \ +PERFSTATUS_ARRAY(privop_addr_##name##_addr, "privop-addrs addr " #name, \ + PRIVOP_COUNT_NADDRS) \ +PERFSTATUS_ARRAY(privop_addr_##name##_count, "privop-addrs count " #name, \ + PRIVOP_COUNT_NADDRS) \ +PERFSTATUS(privop_addr_##name##_overflow, "privop-addrs overflow " #name) +#endif + +PERFPRIVOPADDR(get_ifa) +PERFPRIVOPADDR(thash) +#endif diff -r fc6c3d866477 -r f5a4620c4ece xen/include/asm-ia64/privop_stat.h --- a/xen/include/asm-ia64/privop_stat.h Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/include/asm-ia64/privop_stat.h Thu Aug 10 15:40:00 2006 +0200 @@ -1,19 +1,34 @@ #ifndef _XEN_UA64_PRIVOP_STAT_H #define _XEN_UA64_PRIVOP_STAT_H -#include +#include -extern int dump_privop_counts_to_user(char *, int); -extern int zero_privop_counts_to_user(char *, int); +#ifdef CONFIG_PRIVOP_ADDRS -#define PRIVOP_ADDR_COUNT +extern void gather_privop_addrs (void); +extern void reset_privop_addrs (void); -#ifdef PRIVOP_ADDR_COUNT -/* INST argument of PRIVOP_COUNT_ADDR. */ -#define _GET_IFA 0 -#define _THASH 1 +#undef PERFCOUNTER +#undef PERFCOUNTER_CPU +#undef PERFCOUNTER_ARRAY +#undef PERFSTATUS +#undef PERFSTATUS_CPU +#undef PERFSTATUS_ARRAY +#define PERFCOUNTER( var, name ) +#define PERFCOUNTER_CPU( var, name ) +#define PERFCOUNTER_ARRAY( var, name, size ) +#define PERFSTATUS( var, name ) +#define PERFSTATUS_CPU( var, name ) +#define PERFSTATUS_ARRAY( var, name, size ) +#undef PERFPRIVOPADDR +#define PERFPRIVOPADDR(name) privop_inst_##name, +enum privop_inst { +#include +#undef PERFPRIVOPADDR +}; + #define PRIVOP_COUNT_ADDR(regs,inst) privop_count_addr(regs->cr_iip,inst) -extern void privop_count_addr(unsigned long addr, int inst); +extern void privop_count_addr(unsigned long addr, enum privop_inst inst); #else #define PRIVOP_COUNT_ADDR(x,y) do {} while (0) diff -r fc6c3d866477 -r f5a4620c4ece xen/include/asm-ia64/vhpt.h --- a/xen/include/asm-ia64/vhpt.h Wed Aug 09 10:32:23 2006 -0600 +++ b/xen/include/asm-ia64/vhpt.h Thu Aug 10 15:40:00 2006 +0200 @@ -32,7 +32,7 @@ struct vhpt_lf_entry { #define INVALID_TI_TAG 0x8000000000000000L extern void vhpt_init (void); -extern int dump_vhpt_stats(char *buf); +extern void gather_vhpt_stats(void); extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte, unsigned long logps); extern void vhpt_insert (unsigned long vadr, unsigned long pte,