History

timekeeping: Add raw clock fallback for random_get_entropy()

The addition of random_get_entropy_fallback() provides access to whichever time source has the highest frequency, which is useful for gathering entropy on platforms without available cycle counters. It's not necessarily as good as being able to quickly access a cycle counter that the CPU has, but it's still something, even when it falls back to being jiffies-based. In the event that a given arch does not define get_cycles(), falling back to the get_cycles() default implementation that returns 0 is really not the best we can do. Instead, at least calling random_get_entropy_fallback() would be preferable, because that always needs to return _something_, even falling back to jiffies eventually. It's not as though random_get_entropy_fallback() is super high precision or guaranteed to be entropic, but basically anything that's not zero all the time is better than returning zero all the time. Finally, since random_get_entropy_fallback() is used during extremely early boot when randomizing freelists in mm_init(), it can be called before timekeeping has been initialized. In that case there really is nothing we can do; jiffies hasn't even started ticking yet. So just give up and return 0.

Jason A. Donenfeld committed 4 years ago

Commit 13669921 parent 516dd4a2 files · +23 −0Browse files

Unified · Split

2 files
  1. include/linux/timex.h +8 −0
  2. kernel/time/timekeeping.c +15 −0
include/linux/timex.h+8−0
@@ -62,6 +62,8 @@ · 61 unmodified lines
62#include <linux/types.h>62#include <linux/types.h>
63#include <linux/param.h>63#include <linux/param.h>
64 64
65unsigned long random_get_entropy_fallback(void);
66
65#include <asm/timex.h>67#include <asm/timex.h>
66 68
67#ifndef random_get_entropy69#ifndef random_get_entropy
@@ -74,8 +76,14 @@ · 6 unmodified lines
74 *76 *
75 * By default we use get_cycles() for this purpose, but individual77 * By default we use get_cycles() for this purpose, but individual
76 * architectures may override this in their asm/timex.h header file.78 * architectures may override this in their asm/timex.h header file.
79 * If a given arch does not have get_cycles(), then we fallback to
80 * using random_get_entropy_fallback().
77 */81 */
82#ifdef get_cycles
78#define random_get_entropy() ((unsigned long)get_cycles())83#define random_get_entropy() ((unsigned long)get_cycles())
84#else
85#define random_get_entropy() random_get_entropy_fallback()
86#endif
79#endif87#endif
80 88
81/*89/*
kernel/time/timekeeping.c+15−0
@@ -17,6 +17,7 @@ · 16 unmodified lines
17#include <linux/clocksource.h>17#include <linux/clocksource.h>
18#include <linux/jiffies.h>18#include <linux/jiffies.h>
19#include <linux/time.h>19#include <linux/time.h>
20#include <linux/timex.h>
20#include <linux/tick.h>21#include <linux/tick.h>
21#include <linux/stop_machine.h>22#include <linux/stop_machine.h>
22#include <linux/pvclock_gtod.h>23#include <linux/pvclock_gtod.h>
@@ -2380,6 +2381,20 @@ static int timekeeping_validate_timex(const struct __kernel_timex *txc) · 2357 unmodified lines
2380 return 0;2381 return 0;
2381}2382}
2382 2383
2384/**
2385 * random_get_entropy_fallback - Returns the raw clock source value,
2386 * used by random.c for platforms with no valid random_get_entropy().
2387 */
2388unsigned long random_get_entropy_fallback(void)
2389{
2390 struct tk_read_base *tkr = &tk_core.timekeeper.tkr_mono;
2391 struct clocksource *clock = READ_ONCE(tkr->clock);
2392
2393 if (unlikely(timekeeping_suspended || !clock))
2394 return 0;
2395 return clock->read(clock);
2396}
2397EXPORT_SYMBOL_GPL(random_get_entropy_fallback);
2383 2398
2384/**2399/**
2385 * do_adjtimex() - Accessor function to NTP __do_adjtimex function2400 * do_adjtimex() - Accessor function to NTP __do_adjtimex function

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t