Add a new function pointer to struct clocksource that can optionally be filled in by clocksources deemed to be high enough resolution to feed the random number generator entropy pool. CC: Matt Mackall <mpm@xxxxxxxxxxx> CC: "Venkatesh Pallipadi (Venki)" <venki@xxxxxxxxxx> CC: Thomas Gleixner <tglx@xxxxxxxxxxxxx> CC: Ingo Molnar <mingo@xxxxxxx> CC: John Stultz <johnstul@xxxxxxxxxx> CC: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> CC: "David S. Miller" <davem@xxxxxxxxxxxxx> Signed-off-by: Jarod Wilson <jarod@xxxxxxxxxx> --- include/linux/clocksource.h | 6 ++++++ kernel/time/clocksource.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 0 deletions(-) diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index d4646b4..c74bcf2 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -156,6 +156,8 @@ extern u64 timecounter_cyc2time(struct timecounter *tc, * @vread: vsyscall based read * @suspend: suspend function for the clocksource, if necessary * @resume: resume function for the clocksource, if necessary + * @entropy: random entropy pool addition function (optional, and + * requires a fairly high-resolution clocksource) */ struct clocksource { /* @@ -184,6 +186,7 @@ struct clocksource { unsigned long flags; void (*suspend)(struct clocksource *cs); void (*resume)(struct clocksource *cs); + void (*entropy)(struct clocksource *cs); #ifdef CONFIG_CLOCKSOURCE_WATCHDOG /* Watchdog related data, used by the framework */ @@ -279,6 +282,9 @@ extern void clocksource_resume(void); extern struct clocksource * __init __weak clocksource_default_clock(void); extern void clocksource_mark_unstable(struct clocksource *cs); +extern bool clocksource_entropy_available(void); +extern void clocksource_add_entropy(void); + extern void clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec); diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 1c95fd6..71006ef 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -745,6 +745,39 @@ void clocksource_unregister(struct clocksource *cs) } EXPORT_SYMBOL(clocksource_unregister); +/** + * Do we have at least one clocksource that can generate entropy? + */ +bool clocksource_entropy_available(void) +{ + struct clocksource *src; + bool entropy_possible = false; + + mutex_lock(&clocksource_mutex); + list_for_each_entry(src, &clocksource_list, list) { + if (src->entropy) { + entropy_possible = true; + break; + } + } + mutex_unlock(&clocksource_mutex); + + return entropy_possible; +} +EXPORT_SYMBOL(clocksource_entropy_available); + +/** + * Call the clocksource's entropy-generation function, if set + */ +void clocksource_add_entropy(void) +{ + if (!curr_clocksource->entropy) + return; + + curr_clocksource->entropy(curr_clocksource); +} +EXPORT_SYMBOL(clocksource_add_entropy); + #ifdef CONFIG_SYSFS /** * sysfs_show_current_clocksources - sysfs interface for current clocksource -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html