aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-05-05 12:03:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-05-05 12:03:52 -0400
commitd9cee5d4f66ef36f69b0108dedbad7f7009bb6a8 (patch)
tree14dcf7cb49a884de4b5c55c5757f935c12462719
parentc02d7da3dd00cb32b58d9c87240456e19eebcc42 (diff)
parentf440c4ee3e53f767974fe60bcbc0b6687a5fb53f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu: "This fixes a build problem with bcm63xx and yet another fix to the memzero_explicit function to ensure that the memset is not elided" * git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: hwrng: bcm63xx - Fix driver compilation lib: make memzero_explicit more robust against dead store elimination
-rw-r--r--drivers/char/hw_random/bcm63xx-rng.c18
-rw-r--r--include/linux/compiler-gcc.h16
-rw-r--r--include/linux/compiler-intel.h3
-rw-r--r--include/linux/compiler.h4
-rw-r--r--lib/string.c2
5 files changed, 32 insertions, 11 deletions
diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c
index d1494ecd9e11..4b31f1387f37 100644
--- a/drivers/char/hw_random/bcm63xx-rng.c
+++ b/drivers/char/hw_random/bcm63xx-rng.c
@@ -57,7 +57,7 @@ static void bcm63xx_rng_cleanup(struct hwrng *rng)
57 val &= ~RNG_EN; 57 val &= ~RNG_EN;
58 __raw_writel(val, priv->regs + RNG_CTRL); 58 __raw_writel(val, priv->regs + RNG_CTRL);
59 59
60 clk_didsable_unprepare(prov->clk); 60 clk_disable_unprepare(priv->clk);
61} 61}
62 62
63static int bcm63xx_rng_data_present(struct hwrng *rng, int wait) 63static int bcm63xx_rng_data_present(struct hwrng *rng, int wait)
@@ -97,14 +97,14 @@ static int bcm63xx_rng_probe(struct platform_device *pdev)
97 priv->rng.name = pdev->name; 97 priv->rng.name = pdev->name;
98 priv->rng.init = bcm63xx_rng_init; 98 priv->rng.init = bcm63xx_rng_init;
99 priv->rng.cleanup = bcm63xx_rng_cleanup; 99 priv->rng.cleanup = bcm63xx_rng_cleanup;
100 prov->rng.data_present = bcm63xx_rng_data_present; 100 priv->rng.data_present = bcm63xx_rng_data_present;
101 priv->rng.data_read = bcm63xx_rng_data_read; 101 priv->rng.data_read = bcm63xx_rng_data_read;
102 102
103 priv->clk = devm_clk_get(&pdev->dev, "ipsec"); 103 priv->clk = devm_clk_get(&pdev->dev, "ipsec");
104 if (IS_ERR(priv->clk)) { 104 if (IS_ERR(priv->clk)) {
105 error = PTR_ERR(priv->clk); 105 ret = PTR_ERR(priv->clk);
106 dev_err(&pdev->dev, "no clock for device: %d\n", error); 106 dev_err(&pdev->dev, "no clock for device: %d\n", ret);
107 return error; 107 return ret;
108 } 108 }
109 109
110 if (!devm_request_mem_region(&pdev->dev, r->start, 110 if (!devm_request_mem_region(&pdev->dev, r->start,
@@ -120,11 +120,11 @@ static int bcm63xx_rng_probe(struct platform_device *pdev)
120 return -ENOMEM; 120 return -ENOMEM;
121 } 121 }
122 122
123 error = devm_hwrng_register(&pdev->dev, &priv->rng); 123 ret = devm_hwrng_register(&pdev->dev, &priv->rng);
124 if (error) { 124 if (ret) {
125 dev_err(&pdev->dev, "failed to register rng device: %d\n", 125 dev_err(&pdev->dev, "failed to register rng device: %d\n",
126 error); 126 ret);
127 return error; 127 return ret;
128 } 128 }
129 129
130 dev_info(&pdev->dev, "registered RNG driver\n"); 130 dev_info(&pdev->dev, "registered RNG driver\n");
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index cdf13ca7cac3..371e560d13cf 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -9,10 +9,24 @@
9 + __GNUC_MINOR__ * 100 \ 9 + __GNUC_MINOR__ * 100 \
10 + __GNUC_PATCHLEVEL__) 10 + __GNUC_PATCHLEVEL__)
11 11
12
13/* Optimization barrier */ 12/* Optimization barrier */
13
14/* The "volatile" is due to gcc bugs */ 14/* The "volatile" is due to gcc bugs */
15#define barrier() __asm__ __volatile__("": : :"memory") 15#define barrier() __asm__ __volatile__("": : :"memory")
16/*
17 * This version is i.e. to prevent dead stores elimination on @ptr
18 * where gcc and llvm may behave differently when otherwise using
19 * normal barrier(): while gcc behavior gets along with a normal
20 * barrier(), llvm needs an explicit input variable to be assumed
21 * clobbered. The issue is as follows: while the inline asm might
22 * access any memory it wants, the compiler could have fit all of
23 * @ptr into memory registers instead, and since @ptr never escaped
24 * from that, it proofed that the inline asm wasn't touching any of
25 * it. This version works well with both compilers, i.e. we're telling
26 * the compiler that the inline asm absolutely may see the contents
27 * of @ptr. See also: https://llvm.org/bugs/show_bug.cgi?id=15495
28 */
29#define barrier_data(ptr) __asm__ __volatile__("": :"r"(ptr) :"memory")
16 30
17/* 31/*
18 * This macro obfuscates arithmetic on a variable address so that gcc 32 * This macro obfuscates arithmetic on a variable address so that gcc
diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h
index ba147a1727e6..0c9a2f2c2802 100644
--- a/include/linux/compiler-intel.h
+++ b/include/linux/compiler-intel.h
@@ -13,9 +13,12 @@
13/* Intel ECC compiler doesn't support gcc specific asm stmts. 13/* Intel ECC compiler doesn't support gcc specific asm stmts.
14 * It uses intrinsics to do the equivalent things. 14 * It uses intrinsics to do the equivalent things.
15 */ 15 */
16#undef barrier_data
16#undef RELOC_HIDE 17#undef RELOC_HIDE
17#undef OPTIMIZER_HIDE_VAR 18#undef OPTIMIZER_HIDE_VAR
18 19
20#define barrier_data(ptr) barrier()
21
19#define RELOC_HIDE(ptr, off) \ 22#define RELOC_HIDE(ptr, off) \
20 ({ unsigned long __ptr; \ 23 ({ unsigned long __ptr; \
21 __ptr = (unsigned long) (ptr); \ 24 __ptr = (unsigned long) (ptr); \
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 0e41ca0e5927..867722591be2 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -169,6 +169,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
169# define barrier() __memory_barrier() 169# define barrier() __memory_barrier()
170#endif 170#endif
171 171
172#ifndef barrier_data
173# define barrier_data(ptr) barrier()
174#endif
175
172/* Unreachable code */ 176/* Unreachable code */
173#ifndef unreachable 177#ifndef unreachable
174# define unreachable() do { } while (1) 178# define unreachable() do { } while (1)
diff --git a/lib/string.c b/lib/string.c
index a5792019193c..bb3d4b6993c4 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -607,7 +607,7 @@ EXPORT_SYMBOL(memset);
607void memzero_explicit(void *s, size_t count) 607void memzero_explicit(void *s, size_t count)
608{ 608{
609 memset(s, 0, count); 609 memset(s, 0, count);
610 barrier(); 610 barrier_data(s);
611} 611}
612EXPORT_SYMBOL(memzero_explicit); 612EXPORT_SYMBOL(memzero_explicit);
613 613