Merge tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 6 Aug 2014 15:16:24 +0000 (08:16 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 6 Aug 2014 15:16:24 +0000 (08:16 -0700)
Pull randomness updates from Ted Ts'o:
 "Cleanups and bug fixes to /dev/random, add a new getrandom(2) system
  call, which is a superset of OpenBSD's getentropy(2) call, for use
  with userspace crypto libraries such as LibreSSL.

  Also add the ability to have a kernel thread to pull entropy from
  hardware rng devices into /dev/random"

* tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random:
  hwrng: Pass entropy to add_hwgenerator_randomness() in bits, not bytes
  random: limit the contribution of the hw rng to at most half
  random: introduce getrandom(2) system call
  hw_random: fix sparse warning (NULL vs 0 for pointer)
  random: use registers from interrupted code for CPU's w/o a cycle counter
  hwrng: add per-device entropy derating
  hwrng: create filler thread
  random: add_hwgenerator_randomness() for feeding entropy from devices
  random: use an improved fast_mix() function
  random: clean up interrupt entropy accounting for archs w/o cycle counters
  random: only update the last_pulled time if we actually transferred entropy
  random: remove unneeded hash of a portion of the entropy pool
  random: always update the entropy pool under the spinlock

1  2 
arch/x86/syscalls/syscall_32.tbl
arch/x86/syscalls/syscall_64.tbl
drivers/char/hw_random/core.c
drivers/char/random.c
include/linux/syscalls.h
include/uapi/asm-generic/unistd.h

  351   i386    sched_setattr           sys_sched_setattr
  352   i386    sched_getattr           sys_sched_getattr
  353   i386    renameat2               sys_renameat2
 +354   i386    seccomp                 sys_seccomp
+ 355   i386    getrandom               sys_getrandom
  314   common  sched_setattr           sys_sched_setattr
  315   common  sched_getattr           sys_sched_getattr
  316   common  renameat2               sys_renameat2
 +317   common  seccomp                 sys_seccomp
+ 318   common  getrandom               sys_getrandom
  
  #
  # x32-specific system call numbers start at 512 to avoid cache impact
@@@ -53,42 -55,42 +55,62 @@@ static struct task_struct *hwrng_fill
  static LIST_HEAD(rng_list);
  static DEFINE_MUTEX(rng_mutex);
  static int data_avail;
- static u8 *rng_buffer;
+ static u8 *rng_buffer, *rng_fillbuf;
+ static unsigned short current_quality;
+ static unsigned short default_quality; /* = 0; default to "off" */
+ module_param(current_quality, ushort, 0644);
+ MODULE_PARM_DESC(current_quality,
+                "current hwrng entropy estimation per mill");
+ module_param(default_quality, ushort, 0644);
+ MODULE_PARM_DESC(default_quality,
+                "default entropy content of hwrng per mill");
+ static void start_khwrngd(void);
  
 +static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
 +                             int wait);
 +
  static size_t rng_buffer_size(void)
  {
        return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
  }
  
 -static inline int hwrng_init(struct hwrng *rng)
 +static void add_early_randomness(struct hwrng *rng)
  {
 -      int err;
 +      unsigned char bytes[16];
 +      int bytes_read;
 +
 +      /*
 +       * Currently only virtio-rng cannot return data during device
 +       * probe, and that's handled in virtio-rng.c itself.  If there
 +       * are more such devices, this call to rng_get_data can be
 +       * made conditional here instead of doing it per-device.
 +       */
 +      bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
 +      if (bytes_read > 0)
 +              add_device_randomness(bytes, bytes_read);
 +}
  
 +static inline int hwrng_init(struct hwrng *rng)
 +{
        if (rng->init) {
 -              err = rng->init(rng);
 -              if (err)
 -                      return err;
 +              int ret;
 +
 +              ret =  rng->init(rng);
 +              if (ret)
 +                      return ret;
        }
 +      add_early_randomness(rng);
+       current_quality = rng->quality ? : default_quality;
+       current_quality &= 1023;
+       if (current_quality == 0 && hwrng_fill)
+               kthread_stop(hwrng_fill);
+       if (current_quality > 0 && !hwrng_fill)
+               start_khwrngd();
        return 0;
  }
  
Simple merge
@@@ -866,6 -866,7 +866,9 @@@ asmlinkage long sys_process_vm_writev(p
  asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type,
                         unsigned long idx1, unsigned long idx2);
  asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags);
 +asmlinkage long sys_seccomp(unsigned int op, unsigned int flags,
 +                          const char __user *uargs);
+ asmlinkage long sys_getrandom(char __user *buf, size_t count,
+                             unsigned int flags);
  #endif
@@@ -699,11 -699,11 +699,13 @@@ __SYSCALL(__NR_sched_setattr, sys_sched
  __SYSCALL(__NR_sched_getattr, sys_sched_getattr)
  #define __NR_renameat2 276
  __SYSCALL(__NR_renameat2, sys_renameat2)
 +#define __NR_seccomp 277
 +__SYSCALL(__NR_seccomp, sys_seccomp)
+ #define __NR_getrandom 278
+ __SYSCALL(__NR_getrandom, sys_getrandom)
  
  #undef __NR_syscalls
- #define __NR_syscalls 278
+ #define __NR_syscalls 279
  
  /*
   * All syscalls below here should go away really,