提交 214e45da 编写于 作者: J Jason A. Donenfeld 提交者: Zheng Zengkai

random: help compiler out with fast_mix() by using simpler arguments

stable inclusion
from stable-v5.10.119
commit 772edeb8c76abcfc37bb7f75e7679936b6c50b2c
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5L6BB

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=772edeb8c76abcfc37bb7f75e7679936b6c50b2c

--------------------------------

commit 791332b3 upstream.

Now that fast_mix() has more than one caller, gcc no longer inlines it.
That's fine. But it also doesn't handle the compound literal argument we
pass it very efficiently, nor does it handle the loop as well as it
could. So just expand the code to spell out this function so that it
generates the same code as it did before. Performance-wise, this now
behaves as it did before the last commit. The difference in actual code
size on x86 is 45 bytes, which is less than a cache line.
Signed-off-by: NJason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
上级 b04b86ad
...@@ -1031,25 +1031,30 @@ static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = { ...@@ -1031,25 +1031,30 @@ static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = {
* and therefore this has no security on its own. s represents the * and therefore this has no security on its own. s represents the
* four-word SipHash state, while v represents a two-word input. * four-word SipHash state, while v represents a two-word input.
*/ */
static void fast_mix(unsigned long s[4], const unsigned long v[2]) static void fast_mix(unsigned long s[4], unsigned long v1, unsigned long v2)
{ {
size_t i;
for (i = 0; i < 2; ++i) {
s[3] ^= v[i];
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
s[0] += s[1]; s[1] = rol64(s[1], 13); s[1] ^= s[0]; s[0] = rol64(s[0], 32); #define PERM() do { \
s[2] += s[3]; s[3] = rol64(s[3], 16); s[3] ^= s[2]; s[0] += s[1]; s[1] = rol64(s[1], 13); s[1] ^= s[0]; s[0] = rol64(s[0], 32); \
s[0] += s[3]; s[3] = rol64(s[3], 21); s[3] ^= s[0]; s[2] += s[3]; s[3] = rol64(s[3], 16); s[3] ^= s[2]; \
s[2] += s[1]; s[1] = rol64(s[1], 17); s[1] ^= s[2]; s[2] = rol64(s[2], 32); s[0] += s[3]; s[3] = rol64(s[3], 21); s[3] ^= s[0]; \
s[2] += s[1]; s[1] = rol64(s[1], 17); s[1] ^= s[2]; s[2] = rol64(s[2], 32); \
} while (0)
#else #else
s[0] += s[1]; s[1] = rol32(s[1], 5); s[1] ^= s[0]; s[0] = rol32(s[0], 16); #define PERM() do { \
s[2] += s[3]; s[3] = rol32(s[3], 8); s[3] ^= s[2]; s[0] += s[1]; s[1] = rol32(s[1], 5); s[1] ^= s[0]; s[0] = rol32(s[0], 16); \
s[0] += s[3]; s[3] = rol32(s[3], 7); s[3] ^= s[0]; s[2] += s[3]; s[3] = rol32(s[3], 8); s[3] ^= s[2]; \
s[2] += s[1]; s[1] = rol32(s[1], 13); s[1] ^= s[2]; s[2] = rol32(s[2], 16); s[0] += s[3]; s[3] = rol32(s[3], 7); s[3] ^= s[0]; \
s[2] += s[1]; s[1] = rol32(s[1], 13); s[1] ^= s[2]; s[2] = rol32(s[2], 16); \
} while (0)
#endif #endif
s[0] ^= v[i];
} s[3] ^= v1;
PERM();
s[0] ^= v1;
s[3] ^= v2;
PERM();
s[0] ^= v2;
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -1119,10 +1124,8 @@ void add_interrupt_randomness(int irq) ...@@ -1119,10 +1124,8 @@ void add_interrupt_randomness(int irq)
struct pt_regs *regs = get_irq_regs(); struct pt_regs *regs = get_irq_regs();
unsigned int new_count; unsigned int new_count;
fast_mix(fast_pool->pool, (unsigned long[2]){ fast_mix(fast_pool->pool, entropy,
entropy, (regs ? instruction_pointer(regs) : _RET_IP_) ^ swab(irq));
(regs ? instruction_pointer(regs) : _RET_IP_) ^ swab(irq)
});
new_count = ++fast_pool->count; new_count = ++fast_pool->count;
if (new_count & MIX_INFLIGHT) if (new_count & MIX_INFLIGHT)
...@@ -1162,8 +1165,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned int nu ...@@ -1162,8 +1165,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned int nu
* sometime after, so mix into the fast pool. * sometime after, so mix into the fast pool.
*/ */
if (in_irq()) { if (in_irq()) {
fast_mix(this_cpu_ptr(&irq_randomness)->pool, fast_mix(this_cpu_ptr(&irq_randomness)->pool, entropy, num);
(unsigned long[2]){ entropy, num });
} else { } else {
spin_lock_irqsave(&input_pool.lock, flags); spin_lock_irqsave(&input_pool.lock, flags);
_mix_pool_bytes(&entropy, sizeof(entropy)); _mix_pool_bytes(&entropy, sizeof(entropy));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册