diff options
Diffstat (limited to 'xen/arch/ia64/privop.c')
-rw-r--r-- | xen/arch/ia64/privop.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/xen/arch/ia64/privop.c b/xen/arch/ia64/privop.c index 19ff98fc8d..1f50ea2448 100644 --- a/xen/arch/ia64/privop.c +++ b/xen/arch/ia64/privop.c @@ -747,14 +747,16 @@ priv_emulate(VCPU *vcpu, REGS *regs, UINT64 isr) #define HYPERPRIVOP_COVER 0x4 #define HYPERPRIVOP_ITC_D 0x5 #define HYPERPRIVOP_ITC_I 0x6 -#define HYPERPRIVOP_MAX 0x6 +#define HYPERPRIVOP_SSM_I 0x7 +#define HYPERPRIVOP_MAX 0x7 char *hyperpriv_str[HYPERPRIVOP_MAX+1] = { - 0, "rfi", "rsm.dt", "ssm.dt", "cover", "itc.d", "itc.i", + 0, "rfi", "rsm.dt", "ssm.dt", "cover", "itc.d", "itc.i", "ssm.i", 0 }; -unsigned long hyperpriv_cnt[HYPERPRIVOP_MAX+1] = { 0 }; +unsigned long slow_hyperpriv_cnt[HYPERPRIVOP_MAX+1] = { 0 }; +unsigned long fast_hyperpriv_cnt[HYPERPRIVOP_MAX+1] = { 0 }; /* hyperprivops are generally executed in assembly (with physical psr.ic off) * so this code is primarily used for debugging them */ @@ -765,13 +767,12 @@ ia64_hyperprivop(unsigned long iim, REGS *regs) INST64 inst; UINT64 val; -// FIXME: Add instrumentation for these // FIXME: Handle faults appropriately for these if (!iim || iim > HYPERPRIVOP_MAX) { printf("bad hyperprivop; ignored\n"); return 1; } - hyperpriv_cnt[iim]++; + slow_hyperpriv_cnt[iim]++; switch(iim) { case HYPERPRIVOP_RFI: (void)vcpu_rfi(v); @@ -793,6 +794,9 @@ ia64_hyperprivop(unsigned long iim, REGS *regs) inst.inst = 0; (void)priv_itc_i(v,inst); return 1; + case HYPERPRIVOP_SSM_I: + (void)vcpu_set_psr_i(v); + return 1; } return 0; } @@ -981,18 +985,28 @@ int dump_hyperprivop_counts(char *buf) { int i; char *s = buf; - s += sprintf(s,"Slow hyperprivops:\n"); + unsigned long total = 0; + for (i = 1; i <= HYPERPRIVOP_MAX; i++) total += slow_hyperpriv_cnt[i]; + s += sprintf(s,"Slow hyperprivops (total %d):\n",total); + for (i = 1; i <= HYPERPRIVOP_MAX; i++) + if (slow_hyperpriv_cnt[i]) + s += sprintf(s,"%10d %s\n", + slow_hyperpriv_cnt[i], hyperpriv_str[i]); + total = 0; + for (i = 1; i <= HYPERPRIVOP_MAX; i++) total += fast_hyperpriv_cnt[i]; + s += sprintf(s,"Fast hyperprivops (total %d):\n",total); for (i = 1; i <= HYPERPRIVOP_MAX; i++) - if (hyperpriv_cnt[i]) + if (fast_hyperpriv_cnt[i]) s += sprintf(s,"%10d %s\n", - hyperpriv_cnt[i], hyperpriv_str[i]); + fast_hyperpriv_cnt[i], hyperpriv_str[i]); return s - buf; } void zero_hyperprivop_counts(void) { int i; - for (i = 0; i <= HYPERPRIVOP_MAX; i++) hyperpriv_cnt[i] = 0; + for (i = 0; i <= HYPERPRIVOP_MAX; i++) slow_hyperpriv_cnt[i] = 0; + for (i = 0; i <= HYPERPRIVOP_MAX; i++) fast_hyperpriv_cnt[i] = 0; } #define TMPBUFLEN 8*1024 @@ -1002,6 +1016,7 @@ int dump_privop_counts_to_user(char __user *ubuf, int len) int n = dump_privop_counts(buf); n += dump_hyperprivop_counts(buf + n); + n += dump_reflect_counts(buf + n); #ifdef PRIVOP_ADDR_COUNT n += dump_privop_addrs(buf + n); #endif @@ -1019,6 +1034,7 @@ int zero_privop_counts_to_user(char __user *ubuf, int len) #ifdef PRIVOP_ADDR_COUNT zero_privop_addrs(); #endif + zero_reflect_counts(); if (len < TMPBUFLEN) return -1; if (__copy_to_user(ubuf,buf,n)) return -1; return n; |