Skip to content

Commit 846a017

Browse files
KAGA-KOKOrostedt
authored andcommitted
random: Make it work on rt
Delegate the random insertion to the forced threaded interrupt handler. Store the return IP of the hard interrupt handler in the irq descriptor and feed it into the random generator as a source of entropy. Signed-off-by: Thomas Gleixner <[email protected]>
1 parent 492db0f commit 846a017

File tree

6 files changed

+23
-9
lines changed

6 files changed

+23
-9
lines changed

drivers/char/random.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,28 +1218,27 @@ static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs)
12181218
return *ptr;
12191219
}
12201220

1221-
void add_interrupt_randomness(int irq, int irq_flags)
1221+
void add_interrupt_randomness(int irq, int irq_flags, __u64 ip)
12221222
{
12231223
struct entropy_store *r;
12241224
struct fast_pool *fast_pool = this_cpu_ptr(&irq_randomness);
1225-
struct pt_regs *regs = get_irq_regs();
12261225
unsigned long now = jiffies;
12271226
cycles_t cycles = random_get_entropy();
12281227
__u32 c_high, j_high;
1229-
__u64 ip;
12301228
unsigned long seed;
12311229
int credit = 0;
12321230

12331231
if (cycles == 0)
1234-
cycles = get_reg(fast_pool, regs);
1232+
cycles = get_reg(fast_pool, NULL);
12351233
c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0;
12361234
j_high = (sizeof(now) > 4) ? now >> 32 : 0;
12371235
fast_pool->pool[0] ^= cycles ^ j_high ^ irq;
12381236
fast_pool->pool[1] ^= now ^ c_high;
1239-
ip = regs ? instruction_pointer(regs) : _RET_IP_;
1237+
if (!ip)
1238+
ip = _RET_IP_;
12401239
fast_pool->pool[2] ^= ip;
12411240
fast_pool->pool[3] ^= (sizeof(ip) > 4) ? ip >> 32 :
1242-
get_reg(fast_pool, regs);
1241+
get_reg(fast_pool, NULL);
12431242

12441243
fast_mix(fast_pool);
12451244
add_interrupt_bench(cycles);

drivers/hv/vmbus_drv.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,8 @@ static void vmbus_isr(void)
966966
void *page_addr = hv_cpu->synic_event_page;
967967
struct hv_message *msg;
968968
union hv_synic_event_flags *event;
969+
struct pt_regs *regs = get_irq_regs();
970+
u64 ip = regs ? instruction_pointer(regs) : 0;
969971
bool handled = false;
970972

971973
if (unlikely(page_addr == NULL))
@@ -1009,7 +1011,7 @@ static void vmbus_isr(void)
10091011
tasklet_schedule(&hv_cpu->msg_dpc);
10101012
}
10111013

1012-
add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
1014+
add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0, ip);
10131015
}
10141016

10151017

include/linux/irqdesc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct irq_desc {
7070
unsigned int irqs_unhandled;
7171
atomic_t threads_handled;
7272
int threads_handled_last;
73+
u64 random_ip;
7374
raw_spinlock_t lock;
7475
struct cpumask *percpu_enabled;
7576
const struct cpumask *percpu_affinity;

include/linux/random.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static inline void add_latent_entropy(void) {}
3232

3333
extern void add_input_randomness(unsigned int type, unsigned int code,
3434
unsigned int value) __latent_entropy;
35-
extern void add_interrupt_randomness(int irq, int irq_flags) __latent_entropy;
35+
extern void add_interrupt_randomness(int irq, int irq_flags, __u64 ip) __latent_entropy;
3636

3737
extern void get_random_bytes(void *buf, int nbytes);
3838
extern int wait_for_random_bytes(void);

kernel/irq/handle.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,16 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc)
183183
{
184184
irqreturn_t retval;
185185
unsigned int flags = 0;
186+
struct pt_regs *regs = get_irq_regs();
187+
u64 ip = regs ? instruction_pointer(regs) : 0;
186188

187189
retval = __handle_irq_event_percpu(desc, &flags);
188190

189-
add_interrupt_randomness(desc->irq_data.irq, flags);
191+
#ifdef CONFIG_PREEMPT_RT_FULL
192+
desc->random_ip = ip;
193+
#else
194+
add_interrupt_randomness(desc->irq_data.irq, flags, ip);
195+
#endif
190196

191197
if (!noirqdebug)
192198
note_interrupt(desc, retval);

kernel/irq/manage.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,12 @@ static int irq_thread(void *data)
10311031
if (action_ret == IRQ_WAKE_THREAD)
10321032
irq_wake_secondary(desc, action);
10331033

1034+
#ifdef CONFIG_PREEMPT_RT_FULL
1035+
migrate_disable();
1036+
add_interrupt_randomness(action->irq, 0,
1037+
desc->random_ip ^ (unsigned long) action);
1038+
migrate_enable();
1039+
#endif
10341040
wake_threads_waitq(desc);
10351041
}
10361042

0 commit comments

Comments
 (0)