On Thu, Oct 27, 2016 at 11:11:04AM +0200, Pavel Machek wrote:
> How to work around rowhammer, break my system _and_ make kernel perf
> maintainers scream at the same time: (:-) )
> 
> I think I got the place now. Let me try...

Lol ;-)

> 
> diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
> index d31735f..ce83f5e 100644
> --- a/arch/x86/events/core.c
> +++ b/arch/x86/events/core.c
> @@ -1495,6 +1495,11 @@ perf_event_nmi_handler(unsigned int cmd, struct 
> pt_regs *regs)
>  
>       perf_sample_event_took(finish_clock - start_clock);
>  
> +     /* Here */
> +     {
> +             udelay(58000);
> +     }
> +
>       return ret;
>  }
>  NOKPROBE_SYMBOL(perf_event_nmi_handler);

Like you guess, not quite ;-)


I think you want to register a custom overflow handler with your event.

So you get something like:


struct perf_event_attr rh_attr = {
        .type   = PERF_TYPE_HARDWARE,
        .config = PERF_COUNT_HW_CACHE_MISSES,
        .size   = sizeof(struct perf_event_attr),
        .pinned = 1,
        .sample_period = 1000000,
};

static DEFINE_PER_CPU(struct perf_event *, rh_event);
static DEFINE_PER_CPU(u64, rh_timestamp);

static void rh_overflow(struct perf_event *event, struct perf_sample_data 
*data, struct pt_regs *regs)
{
        u64 *ts = this_cpu_ptr(&rh_timestamp); /* this is NMI context */
        u64 now = ktime_get_mono_fast_ns();
        s64 delta = now - *ts;

        *ts = now;

        if (delta > 64 * NSEC_PER_USEC)
                udelay(58000);
}

__init int my_module_init()
{
        int cpu;

        /* XXX borken vs hotplug */

        for_each_online_cpu(cpu) {
                struct perf_event *event = per_cpu(event, cpu);

                event = perf_event_create_kernel_counter(&rh_attr, cpu, NULL, 
rh_overflow, NULL);
                if (!event)
                        /* meh */
                        ;

        }
}

__exit void my_module_exit()
{
        int cpu;

        for_each_online_cpu(cpu) {
                struct perf_event *event = per_cpu(event, cpu);

                if (event)
                        perf_event_release_kernel(event);
        }
}

Reply via email to