ARM public key benchmark

Niels Möller nisse at lysator.liu.se
Fri Aug 23 09:04:32 CEST 2013


nisse at lysator.liu.se (Niels Möller) writes:

> David Miller <davem at davemloft.net> writes:
>>
>> #include <linux/smp.h>
>>
>> ...
>>
>> 	on_each_cpu(my_func, my_func_args, 1);
>
> Cool. I'll have to play with that, but probably not until next week.

And some months later... I tried that now. I use the below linux kernel
module which modifies the user enable register when loaded. On all
cores.

Nevertheless, when I read the enable bit in a user space program it is
zero (and instructions trying to access the cycle counter fails with
illegal instruction).

I then added some code to the module to display the value of the bit
before and after I try to write it. If I load and immediately unload the
module, the values are as I expect:

  root at arm:/home/nisse# insmod ~nisse/incoming/enableccnt.ko  ; rmmod enableccnt
  root at arm:/home/nisse# dmesg |tail -14
  [5728897.345672] enableccnt starting
  [5728897.349487] enableccnt enableccnt_write: 1
  [5728897.354186] enableccnt before: 0
  [5728897.357910] enableccnt after: 1
  [5728897.361572] enableccnt enableccnt_write: 1
  [5728897.366271] enableccnt before: 0
  [5728897.369995] enableccnt after: 1
  [5728897.385314] enableccnt stopping
  [5728897.392120] enableccnt enableccnt_write: 0
  [5728897.399871] enableccnt before: 1
  [5728897.406616] enableccnt after: 0
  [5728897.413146] enableccnt enableccnt_write: 0
  [5728897.420806] enableccnt before: 1
  [5728897.427429] enableccnt after: 0

(Note that there are two cores). But if I delay unload just a second,
something else resets the flag in the mean time:

  root at arm:/home/nisse# insmod ~nisse/incoming/enableccnt.ko  ; sleep 1; rmmod enableccnt
  root at arm:/home/nisse# dmesg |tail -14
  [5729055.679229] enableccnt starting
  [5729055.685974] enableccnt enableccnt_write: 1
  [5729055.693603] enableccnt before: 0
  [5729055.700286] enableccnt after: 1
  [5729055.706848] enableccnt enableccnt_write: 1
  [5729055.714508] enableccnt before: 0
  [5729055.721221] enableccnt after: 1
  [5729056.752655] enableccnt stopping
  [5729056.759399] enableccnt enableccnt_write: 0
  [5729056.767028] enableccnt before: 0
  [5729056.773742] enableccnt after: 0
  [5729056.780364] enableccnt enableccnt_write: 0
  [5729056.788024] enableccnt before: 0
  [5729056.794738] enableccnt after: 0

Which maybe isn't too surprising, after all the kernel "owns" all
registers. But I greped the kernel sources, and I really find no
accesses to this status register anywhere. So I'm lost now.

If anyone on this list have some hint on where to look, that's
appreciated. The platform is still an "OMAP4 Panda board". Otherwise I
guess I'll have to give up this track.

Regards,
/Niels

/* Adapted from http://bench.cr.yp.to/cpucycles/netwalker.html */
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("Dual BSD/GPL");

#define DEVICE_NAME "enableccnt"

static void
enableccnt_write (void *info)
{
  int val_write = *(int *) info;
  int val_read;
  printk (KERN_INFO DEVICE_NAME " enableccnt_write: %d\n", val_write);
  asm volatile ("mrc p15, 0, %0, c9, c14, 0": "=r"(val_read));         
  printk (KERN_INFO DEVICE_NAME " before: %d\n", val_read);
  asm volatile ("mcr p15, 0, %0, c9, c14, 0" :: "r"(val_write));
  asm volatile ("mrc p15, 0, %0, c9, c14, 0": "=r"(val_read));         
  printk (KERN_INFO DEVICE_NAME " after: %d\n", val_read);
}

static int enableccnt_init(void)
{
  int val = 1;
  printk(KERN_INFO DEVICE_NAME " starting\n");
  on_each_cpu (enableccnt_write, &val, 1);
  return 0;
}

static void enableccnt_exit(void)
{
  int val = 0;
  printk(KERN_INFO DEVICE_NAME " stopping\n");
  on_each_cpu (enableccnt_write, &val, 1);
}

module_init(enableccnt_init);
module_exit(enableccnt_exit);

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.


More information about the gmp-devel mailing list