From: Dave Taht <dave.t...@bufferbloat.net> The basic mips patch (deleted here) is not the full architecture for faster random number generation. This patchset adds better inlining specific to mips architectures. --- .../307-mips-Reimplement-get_cycles.patch | 69 ------------- ...w-architectures-to-optionally-define-rand.patch | 90 +++++++++++++++++ ...zed-support-for-get_cycles-and-random_get.patch | 102 ++++++++++++++++++++ ...-mainline-linux-doesnt-have-prid_imp_mask.patch | 28 ++++++ 4 files changed, 220 insertions(+), 69 deletions(-) delete mode 100644 target/linux/generic/patches-3.10/307-mips-Reimplement-get_cycles.patch create mode 100644 target/linux/generic/patches-3.10/350-random-allow-architectures-to-optionally-define-rand.patch create mode 100644 target/linux/generic/patches-3.10/351-MIPS-optimized-support-for-get_cycles-and-random_get.patch create mode 100644 target/linux/generic/patches-3.10/352-mips-mainline-linux-doesnt-have-prid_imp_mask.patch
diff --git a/target/linux/generic/patches-3.10/307-mips-Reimplement-get_cycles.patch b/target/linux/generic/patches-3.10/307-mips-Reimplement-get_cycles.patch deleted file mode 100644 index 6a8f5b1..0000000 --- a/target/linux/generic/patches-3.10/307-mips-Reimplement-get_cycles.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 9c9b415c50bc298ac61412dff856eae2f54889ee Mon Sep 17 00:00:00 2001 -From: Ralf Baechle <r...@linux-mips.org> -Date: Thu, 12 Sep 2013 13:47:32 +0200 -Subject: [PATCH] MIPS: Reimplement get_cycles(). - -This essentially reverts commit efb9ca08b5a2374b29938cdcab417ce4feb14b54 -(kernel.org) / 58020a106879a8b372068741c81f0015c9b0b96dbv [[MIPS] Change -get_cycles to always return 0.] - -Most users of get_cycles() invoke it as a timing interface. That's why -in modern kernels it was never very much missed for. /dev/random however -uses get_cycles() in the how the jitter in the interrupt timing contains -some useful entropy. - -Signed-off-by: Ralf Baechle <r...@linux-mips.org> ---- - arch/mips/include/asm/timex.h | 33 ++++++++++++++++++++++++++++++++- - 1 file changed, 32 insertions(+), 1 deletion(-) - ---- a/arch/mips/include/asm/timex.h -+++ b/arch/mips/include/asm/timex.h -@@ -10,6 +10,7 @@ - - #ifdef __KERNEL__ - -+#include <asm/cpu-features.h> - #include <asm/mipsregs.h> - - /* -@@ -33,9 +34,38 @@ - - typedef unsigned int cycles_t; - -+/* -+ * On R4000/R4400 before version 5.0 an erratum exists such that if the -+ * cycle counter is read in the exact moment that it is matching the -+ * compare register, no interrupt will be generated. -+ * -+ * There is a suggested workaround and also the erratum can't strike if -+ * the compare interrupt isn't being used as the clock source device. -+ * However for now the implementaton of this function doesn't get these -+ * fine details right. -+ */ - static inline cycles_t get_cycles(void) - { -- return 0; -+ switch (cpu_data[0].cputype) { -+ case CPU_R4400PC: -+ case CPU_R4400SC: -+ case CPU_R4400MC: -+ if ((read_c0_prid() & 0xff) >= 0x0050) -+ return read_c0_count(); -+ break; -+ -+ case CPU_R4000PC: -+ case CPU_R4000SC: -+ case CPU_R4000MC: -+ break; -+ -+ default: -+ if (cpu_has_counter) -+ return read_c0_count(); -+ break; -+ } -+ -+ return 0; /* no usable counter */ - } - - #endif /* __KERNEL__ */ diff --git a/target/linux/generic/patches-3.10/350-random-allow-architectures-to-optionally-define-rand.patch b/target/linux/generic/patches-3.10/350-random-allow-architectures-to-optionally-define-rand.patch new file mode 100644 index 0000000..c2d2e1c --- /dev/null +++ b/target/linux/generic/patches-3.10/350-random-allow-architectures-to-optionally-define-rand.patch @@ -0,0 +1,90 @@ +From e4e35c9ea9893df758bb24a0027f018a5427e39d Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o <ty...@mit.edu> +Date: Sat, 21 Sep 2013 13:58:22 -0400 +Subject: [PATCH 1/2] random: allow architectures to optionally define + random_get_entropy() + +Allow architectures which have a disabled get_cycles() function to +provide a random_get_entropy() function which provides a fine-grained, +rapidly changing counter that can be used by the /dev/random driver. + +For example, an architecture might have a rapidly changing register +used to control random TLB cache eviction, or DRAM refresh that +doesn't meet the requirements of get_cycles(), but which is good +enough for the needs of the random driver. + +Signed-off-by: "Theodore Ts'o" <ty...@mit.edu> +Cc: sta...@vger.kernel.org +--- + drivers/char/random.c | 8 ++++---- + include/linux/timex.h | 14 ++++++++++++++ + 2 files changed, 18 insertions(+), 4 deletions(-) + +diff --git a/drivers/char/random.c b/drivers/char/random.c +index 81eefa1..5c4626a 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -643,7 +643,7 @@ struct timer_rand_state { + */ + void add_device_randomness(const void *buf, unsigned int size) + { +- unsigned long time = get_cycles() ^ jiffies; ++ unsigned long time = random_get_entropy() ^ jiffies; + + mix_pool_bytes(&input_pool, buf, size, NULL); + mix_pool_bytes(&input_pool, &time, sizeof(time), NULL); +@@ -680,7 +680,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) + goto out; + + sample.jiffies = jiffies; +- sample.cycles = get_cycles(); ++ sample.cycles = random_get_entropy(); + sample.num = num; + mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL); + +@@ -747,7 +747,7 @@ void add_interrupt_randomness(int irq, int irq_flags) + struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness); + struct pt_regs *regs = get_irq_regs(); + unsigned long now = jiffies; +- __u32 input[4], cycles = get_cycles(); ++ __u32 input[4], cycles = random_get_entropy(); + + input[0] = cycles ^ jiffies; + input[1] = irq; +@@ -1485,7 +1485,7 @@ unsigned int get_random_int(void) + + hash = get_cpu_var(get_random_int_hash); + +- hash[0] += current->pid + jiffies + get_cycles(); ++ hash[0] += current->pid + jiffies + random_get_entropy(); + md5_transform(hash, random_int_secret); + ret = hash[0]; + put_cpu_var(get_random_int_hash); +diff --git a/include/linux/timex.h b/include/linux/timex.h +index dd3edd7..9d3f1a5 100644 +--- a/include/linux/timex.h ++++ b/include/linux/timex.h +@@ -64,6 +64,20 @@ + + #include <asm/timex.h> + ++#ifndef random_get_entropy ++/* ++ * The random_get_entropy() function is used by the /dev/random driver ++ * in order to extract entropy via the relative unpredictability of ++ * when an interrupt takes places versus a high speed, fine-grained ++ * timing source or cycle counter. Since it will be occurred on every ++ * single interrupt, it must have a very low cost/overhead. ++ * ++ * By default we use get_cycles() for this purpose, but individual ++ * architectures may override this in their asm/timex.h header file. ++ */ ++#define random_get_entropy() get_cycles() ++#endif ++ + /* + * SHIFT_PLL is used as a dampening factor to define how much we + * adjust the frequency correction for a given offset in PLL mode. +-- +1.7.9.5 + diff --git a/target/linux/generic/patches-3.10/351-MIPS-optimized-support-for-get_cycles-and-random_get.patch b/target/linux/generic/patches-3.10/351-MIPS-optimized-support-for-get_cycles-and-random_get.patch new file mode 100644 index 0000000..73feb64 --- /dev/null +++ b/target/linux/generic/patches-3.10/351-MIPS-optimized-support-for-get_cycles-and-random_get.patch @@ -0,0 +1,102 @@ +From 5c0d494fa62435107fb3118ef309cbe65f58f15a Mon Sep 17 00:00:00 2001 +From: Dave Taht <dave.t...@bufferbloat.net> +Date: Sat, 19 Oct 2013 17:43:06 -0700 +Subject: [PATCH 2/2] MIPS: optimized support for get_cycles() and + random_get_entropy + +--- + arch/mips/include/asm/timex.h | 62 ++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 61 insertions(+), 1 deletion(-) + +diff --git a/arch/mips/include/asm/timex.h b/arch/mips/include/asm/timex.h +index 6529704..1fb165f 100644 +--- a/arch/mips/include/asm/timex.h ++++ b/arch/mips/include/asm/timex.h +@@ -4,12 +4,17 @@ + * for more details. + * + * Copyright (C) 1998, 1999, 2003 by Ralf Baechle ++ * Copyright (C) 2013 by Maciej W. Rozycki + */ + #ifndef _ASM_TIMEX_H + #define _ASM_TIMEX_H + + #ifdef __KERNEL__ + ++#include <linux/compiler.h> ++ ++#include <asm/cpu.h> ++#include <asm/cpu-features.h> + #include <asm/mipsregs.h> + + /* +@@ -33,10 +38,65 @@ + + typedef unsigned int cycles_t; + ++/* ++ * On R4000/R4400 before version 5.0 an erratum exists such that if the ++ * cycle counter is read in the exact moment that it is matching the ++ * compare register, no interrupt will be generated. ++ * ++ * There is a suggested workaround and also the erratum can't strike if ++ * the compare interrupt isn't being used as the clock source device. ++ * However for now the implementaton of this function doesn't get these ++ * fine details right. ++ */ ++static inline int can_use_mips_counter(unsigned int prid) ++{ ++ int comp = (prid & PRID_COMP_MASK) != PRID_COMP_LEGACY; ++ ++ if (__builtin_constant_p(cpu_has_counter) && !cpu_has_counter) ++ return 0; ++ else if (__builtin_constant_p(cpu_has_mips_r) && cpu_has_mips_r) ++ return 1; ++ else if (likely(!__builtin_constant_p(cpu_has_mips_r) && comp)) ++ return 1; ++ /* Make sure we don't peek at cpu_data[0].options in the fast path! */ ++ if (!__builtin_constant_p(cpu_has_counter)) ++ asm volatile("" : "=m" (cpu_data[0].options)); ++ if (likely(cpu_has_counter && ++ prid >= (PRID_IMP_R4000 | PRID_REV_ENCODE_44(5, 0)))) ++ return 1; ++ else ++ return 0; ++} ++ + static inline cycles_t get_cycles(void) + { +- return 0; ++ if (can_use_mips_counter(read_c0_prid())) ++ return read_c0_count(); ++ else ++ return 0; /* no usable counter */ ++} ++ ++/* ++ * Like get_cycles - but where c0_count is not available we desperately ++ * use c0_random in a desperate attempt to get at least a little bit of ++ * entropy. ++ * ++ * R6000 and R6000A neither have a count register nor a random register. ++ * That leaves no entropy source in the CPU itself. ++ */ ++static inline unsigned long random_get_entropy(void) ++{ ++ unsigned int prid = read_c0_prid(); ++ unsigned int imp = prid & PRID_IMP_MASK; ++ ++ if (can_use_mips_counter(prid)) ++ return read_c0_count(); ++ else if (likely(imp != PRID_IMP_R6000 && imp != PRID_IMP_R6000A)) ++ return read_c0_random(); ++ else ++ return 0; /* no usable register */ + } ++#define random_get_entropy random_get_entropy + + #endif /* __KERNEL__ */ + +-- +1.7.9.5 + diff --git a/target/linux/generic/patches-3.10/352-mips-mainline-linux-doesnt-have-prid_imp_mask.patch b/target/linux/generic/patches-3.10/352-mips-mainline-linux-doesnt-have-prid_imp_mask.patch new file mode 100644 index 0000000..c2d600e --- /dev/null +++ b/target/linux/generic/patches-3.10/352-mips-mainline-linux-doesnt-have-prid_imp_mask.patch @@ -0,0 +1,28 @@ +From b5178d0126b87d3793a677bb8bad026b821957d5 Mon Sep 17 00:00:00 2001 +From: Dave Taht <dave.t...@bufferbloat.net> +Date: Sat, 19 Oct 2013 18:09:17 -0700 +Subject: [PATCH] mips: mainline linux doesnt have prid_imp_mask + +--- + arch/mips/include/asm/timex.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/mips/include/asm/timex.h b/arch/mips/include/asm/timex.h +index 1fb165f..6601ccc 100644 +--- a/arch/mips/include/asm/timex.h ++++ b/arch/mips/include/asm/timex.h +@@ -38,6 +38,11 @@ + + typedef unsigned int cycles_t; + ++/* Mainline linux doesn't have PRID_COMP_MASK or PRID_IMP_MASK */ ++ ++#define PRID_COMP_MASK 0x00ff0000 ++#define PRID_IMP_MASK 0x0000ff00 ++ + /* + * On R4000/R4400 before version 5.0 an erratum exists such that if the + * cycle counter is read in the exact moment that it is matching the +-- +1.7.9.5 + -- 1.7.9.5 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel