You need to use "-cpu host" in kvm/qemu. Also, those negative numbers are fine. The IRQ trigger works that you set counter value at -icount, and wait the overflow to zero to trigger the PMI IRQ. The patch is OK, but I don't think we need to worry about PMI version 0, especially when we committed on anything which does not have x2apic ☺
On Wed, Dec 16, 2015 at 2:45 PM, Barret Rhoden <[email protected]> wrote: > Hi - > > I get a GPF when I try to run this in qemu on the wrmsr in perf_init. > > I put together a minor fix for this (pasted below, and also at > origin/perf-b). If it looks good to you, I'll merge this patch set. > > Also, I tried using it on my desktop. The non-interrupt use looks fine: > > / $ perf record -e TLB_FLUSH:STLB_ANY,int=0,icount=0 -- sleep 10 > Event: TLB_FLUSH:STLB_ANY > 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 > > With the interrupt: > > / $ perf record -e TLB_FLUSH:STLB_ANY,int=1,icount=20 -- sleep 10 > Event: TLB_FLUSH:STLB_ANY > 281474976710643 281474976710636 281474976710636 281474976710636 > 281474976710636 281474976710636 281474976710636 281474976710636 > 281474976710636 28147497671 > > Those are close to negative numbers (e.g. 0xfffffffffff3). Whatever > the issue, we can deal with it in a follow-up patch. > > Barret > > > From 64d18dc7359cdda1f2980e19db62f0ec6400e31f Mon Sep 17 00:00:00 2001 > From: Barret Rhoden <[email protected]> > Date: Wed, 16 Dec 2015 17:14:36 -0500 > Subject: x86: Detect and handle missing perf support > > If a machine has perf version 0, which is the case for my Qemu, we'll get a > GPF during initialization. The per core initialization and any accesses to > the Qperf file will abort if we don't have the right version. > > This assumes that if open of a Qperf fails, that there is no other way for > the user to trigger access to the perf MSRs. > > Signed-off-by: Barret Rhoden <[email protected]> > --- > kern/arch/x86/devarch.c | 2 ++ > kern/arch/x86/init.c | 2 +- > kern/arch/x86/perfmon.c | 24 +++++++++++++----------- > kern/arch/x86/perfmon.h | 4 +++- > kern/arch/x86/smp_boot.c | 4 ++-- > 5 files changed, 21 insertions(+), 15 deletions(-) > > diff --git a/kern/arch/x86/devarch.c b/kern/arch/x86/devarch.c > index 6549891548aa..04dba60d728c 100644 > --- a/kern/arch/x86/devarch.c > +++ b/kern/arch/x86/devarch.c > @@ -475,6 +475,8 @@ static struct chan *archopen(struct chan *c, int omode) > c = devopen(c, omode, archdir, Qmax, devgen); > switch ((uint32_t) c->qid.path) { > case Qperf: > + if (!perfmon_supported()) > + error(ENODEV, "perf is not supported"); > assert(!c->aux); > c->aux = arch_create_perf_context(); > break; > diff --git a/kern/arch/x86/init.c b/kern/arch/x86/init.c > index fe35276262d1..a2080485938c 100644 > --- a/kern/arch/x86/init.c > +++ b/kern/arch/x86/init.c > @@ -80,6 +80,7 @@ void arch_init() > save_fp_state(&x86_default_fpu); /* used in arch/trap.h for fpu > init */ > pci_init(); > vmm_init(); > + perfmon_global_init(); > // this returns when all other cores are done and ready to receive > IPIs > #ifdef CONFIG_SINGLE_CORE > smp_percpu_init(); > @@ -88,7 +89,6 @@ void arch_init() > #endif > proc_init(); > > - perfmon_init(); > cons_irq_init(); > intel_lpc_init(); > #ifdef CONFIG_ENABLE_LEGACY_USB > diff --git a/kern/arch/x86/perfmon.c b/kern/arch/x86/perfmon.c > index 810be3c6e5ae..4ea89d8f3ba8 100644 > --- a/kern/arch/x86/perfmon.c > +++ b/kern/arch/x86/perfmon.c > @@ -291,23 +291,25 @@ static void perfmon_arm_irq(void) > write_mmreg32(LAPIC_LVT_PERFMON, IdtLAPIC_PCINT); > } > > -void perfmon_init(void) > +bool perfmon_supported(void) > +{ > + return cpu_caps.perfmon_version >= 2; > +} > + > +void perfmon_global_init(void) > +{ > + perfmon_read_cpu_caps(&cpu_caps); > +} > + > +void perfmon_pcpu_init(void) > { > int i; > > + if (!perfmon_supported()) > + return; > /* Enable user level access to the performance counters */ > lcr4(rcr4() | CR4_PCE); > > - /* This will be called from every core, no need to execute more > than once. > - * All the call to perfmon_init() will be done when the core > boots, so > - * they will be no perfmon users calling it, while > perfmon_read_cpu_caps() > - * is executing. > - * All the cores will be writing the same values, so even from > that POV, > - * no serialization is required. > - */ > - if (cpu_caps.perfmon_version == 0) > - perfmon_read_cpu_caps(&cpu_caps); > - > /* Reset all the counters and selectors to zero. > */ > write_msr(MSR_CORE_PERF_GLOBAL_CTRL, 0); > diff --git a/kern/arch/x86/perfmon.h b/kern/arch/x86/perfmon.h > index a655098df9bb..822b96a9e9cf 100644 > --- a/kern/arch/x86/perfmon.h > +++ b/kern/arch/x86/perfmon.h > @@ -49,7 +49,9 @@ struct perfmon_status { > uint64_t cores_values[0]; > }; > > -void perfmon_init(void); > +bool perfmon_supported(void); > +void perfmon_global_init(void); > +void perfmon_pcpu_init(void); > void perfmon_interrupt(struct hw_trapframe *hw_tf, void *data); > void perfmon_get_cpu_caps(struct perfmon_cpu_caps *pcc); > int perfmon_open_event(const struct core_set *cset, struct > perfmon_session *ps, > diff --git a/kern/arch/x86/smp_boot.c b/kern/arch/x86/smp_boot.c > index 7f6f4d9bf1fb..e248d9edee1f 100644 > --- a/kern/arch/x86/smp_boot.c > +++ b/kern/arch/x86/smp_boot.c > @@ -302,7 +302,7 @@ void __arch_pcpu_init(uint32_t coreid) > assert(read_msr(MSR_KERN_GS_BASE) == (uint64_t)pcpui); > /* Don't try setting up til after setting GS */ > x86_sysenter_init(x86_get_stacktop_tss(pcpui->tss)); > - /* need to init perfctr before potentiall using it in timer > handler */ > - perfmon_init(); > + /* need to init perfctr before potentially using it in timer > handler */ > + perfmon_pcpu_init(); > vmm_pcpu_init(); > } > -- > 2.6.0.rc2.230.g3dd15c0 > > > -- > You received this message because you are subscribed to the Google Groups > "Akaros" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
