Feedback requested on switching the exception wrapper used for the PMU interrupt on ppc64

Corey J Ashford cjashfor at
Fri May 16 10:26:18 EST 2008

Paul Mackerras <paulus at> wrote on 05/15/2008 04:36:02 PM:

> Corey J Ashford writes:
> > Ideally, what I'm looking for is something that mimics the operation of
> > I've been looking at the kernel code (entry_64.S, exception.h,
> > but am finding it quite complicated and hard to follow, particularly in
> > area of interrupt disabling wrt the soft and hard disable logic.
> >
> > My initial thought is to do something like this in the beginning of my
> > perfmon2 interrupt handler:
> >
> > void perfmon_pmu_int_handler(struct pt_regs *regs) {
> >
> >       if (get_paca()->soft_enabled == 0) {
> >             /* disable hardware interrupts */
> >             get_paca()->hard_enabled = 0;
> >             regs->msr &= ^MSR_EE;
> >             return;
> >       }
> > ...
> > }
> >
> > Does this seem like it might work?
> That's a start (with ~MSR_EE rather than ^MSR_EE, of course).  You
> also need to set a flag in that case, and test the flag in the part of
> arch/powerpc/kernel/irq.c:raw_local_irq_restore() that hard-enables
> interrupts.  If the flag is set then you should call back into the
> perfmon2 code at that point (and clear the flag, of course).  You
> could add a field to the paca for that flag.
> You probably also want to read some of the PMU's SPRs when you first
> get the interrupt and save their values away, and then when you get
> the call back from raw_local_irq_restore, use the saved values rather
> than what's currently in the SPRs, since the saved values will be more
> accurate.
> Paul.

Hi Paul,

Thanks for the feedback.  I don't believe I need a separate flag, because
the PMU interrupt (via the PMAO bit) will still be pending when interrupts
are hard enabled again, and the handler will be reentered automatically.

I'll think about the issue of caching the SPR values some more, but I don't
want to complicate things too much.  PMU event counts are not so critical
that they need to so accurately reflect the exact value at the time of the

I discovered through some trial and error that get_paca() doesn't work
correctly in the interrupt handler.  It appears that the value of r13 (the
PACA pointer) is not initialized.  Perhaps r13 is a scratch register used
by the compiler?

Fortunately, because the soft enable flag is available in the pt_regs
structure, and because the hard enable flag will be set to the same as the
value of regs->msr's MSR_EE flag in the restore code, I now have this code
in the interrupt handler:

void perfmon_pmu_int_handler(struct pt_regs *regs) {

      if (regs->softe == 0) {
            /* disable hardware interrupts */
            regs->msr &= ~MSR_EE;

This code does seem to be working, but needs more testing.


- Corey

Corey Ashford
Software Engineer
IBM Linux Technology Center, Linux Toolchain
Beaverton, OR
cjashfor at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Linuxppc-dev mailing list