]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - rt-patches/0216-random-Make-it-work-on-rt.patch
WAR:media:i2c:ov5693: add flip and mirror setting
[hercules2020/nv-tegra/linux-4.4.git] / rt-patches / 0216-random-Make-it-work-on-rt.patch
1 From e2849410757919ff26a7731a8fef17227d080600 Mon Sep 17 00:00:00 2001
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Tue, 21 Aug 2012 20:38:50 +0200
4 Subject: [PATCH 216/365] random: Make it work on rt
5
6 Delegate the random insertion to the forced threaded interrupt
7 handler. Store the return IP of the hard interrupt handler in the irq
8 descriptor and feed it into the random generator as a source of
9 entropy.
10
11 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
12 ---
13  drivers/char/random.c   | 11 +++++------
14  include/linux/irqdesc.h |  1 +
15  include/linux/random.h  |  2 +-
16  kernel/irq/handle.c     |  8 +++++++-
17  kernel/irq/manage.c     |  6 ++++++
18  5 files changed, 20 insertions(+), 8 deletions(-)
19
20 diff --git a/drivers/char/random.c b/drivers/char/random.c
21 index dd5346c..afffbc7 100644
22 --- a/drivers/char/random.c
23 +++ b/drivers/char/random.c
24 @@ -891,28 +891,27 @@ static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs)
25         return *(ptr + f->reg_idx++);
26  }
27  
28 -void add_interrupt_randomness(int irq, int irq_flags)
29 +void add_interrupt_randomness(int irq, int irq_flags, __u64 ip)
30  {
31         struct entropy_store    *r;
32         struct fast_pool        *fast_pool = this_cpu_ptr(&irq_randomness);
33 -       struct pt_regs          *regs = get_irq_regs();
34         unsigned long           now = jiffies;
35         cycles_t                cycles = random_get_entropy();
36         __u32                   c_high, j_high;
37 -       __u64                   ip;
38         unsigned long           seed;
39         int                     credit = 0;
40  
41         if (cycles == 0)
42 -               cycles = get_reg(fast_pool, regs);
43 +               cycles = get_reg(fast_pool, NULL);
44         c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0;
45         j_high = (sizeof(now) > 4) ? now >> 32 : 0;
46         fast_pool->pool[0] ^= cycles ^ j_high ^ irq;
47         fast_pool->pool[1] ^= now ^ c_high;
48 -       ip = regs ? instruction_pointer(regs) : _RET_IP_;
49 +       if (!ip)
50 +               ip = _RET_IP_;
51         fast_pool->pool[2] ^= ip;
52         fast_pool->pool[3] ^= (sizeof(ip) > 4) ? ip >> 32 :
53 -               get_reg(fast_pool, regs);
54 +               get_reg(fast_pool, NULL);
55  
56         fast_mix(fast_pool);
57         add_interrupt_bench(cycles);
58 diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
59 index a587a33..ad57402 100644
60 --- a/include/linux/irqdesc.h
61 +++ b/include/linux/irqdesc.h
62 @@ -61,6 +61,7 @@ struct irq_desc {
63         unsigned int            irqs_unhandled;
64         atomic_t                threads_handled;
65         int                     threads_handled_last;
66 +       u64                     random_ip;
67         raw_spinlock_t          lock;
68         struct cpumask          *percpu_enabled;
69  #ifdef CONFIG_SMP
70 diff --git a/include/linux/random.h b/include/linux/random.h
71 index 9c29122..e7f2f86 100644
72 --- a/include/linux/random.h
73 +++ b/include/linux/random.h
74 @@ -20,7 +20,7 @@ struct random_ready_callback {
75  extern void add_device_randomness(const void *, unsigned int);
76  extern void add_input_randomness(unsigned int type, unsigned int code,
77                                  unsigned int value);
78 -extern void add_interrupt_randomness(int irq, int irq_flags);
79 +extern void add_interrupt_randomness(int irq, int irq_flags, __u64 ip);
80  
81  extern void get_random_bytes(void *buf, int nbytes);
82  extern int add_random_ready_callback(struct random_ready_callback *rdy);
83 diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
84 index 57bff78..6c65c92 100644
85 --- a/kernel/irq/handle.c
86 +++ b/kernel/irq/handle.c
87 @@ -134,6 +134,8 @@ void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
88  
89  irqreturn_t handle_irq_event_percpu(struct irq_desc *desc)
90  {
91 +       struct pt_regs *regs = get_irq_regs();
92 +       u64 ip = regs ? instruction_pointer(regs) : 0;
93         irqreturn_t retval = IRQ_NONE;
94         unsigned int flags = 0, irq = desc->irq_data.irq;
95         struct irqaction *action = desc->action;
96 @@ -176,7 +178,11 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc)
97                 action = action->next;
98         }
99  
100 -       add_interrupt_randomness(irq, flags);
101 +#ifdef CONFIG_PREEMPT_RT_FULL
102 +       desc->random_ip = ip;
103 +#else
104 +       add_interrupt_randomness(irq, flags, ip);
105 +#endif
106  
107         if (!noirqdebug)
108                 note_interrupt(desc, retval);
109 diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
110 index 5b1ad63..ba2a42a 100644
111 --- a/kernel/irq/manage.c
112 +++ b/kernel/irq/manage.c
113 @@ -1045,6 +1045,12 @@ static int irq_thread(void *data)
114                 if (action_ret == IRQ_WAKE_THREAD)
115                         irq_wake_secondary(desc, action);
116  
117 +#ifdef CONFIG_PREEMPT_RT_FULL
118 +               migrate_disable();
119 +               add_interrupt_randomness(action->irq, 0,
120 +                                desc->random_ip ^ (unsigned long) action);
121 +               migrate_enable();
122 +#endif
123                 wake_threads_waitq(desc);
124         }
125  
126 -- 
127 2.7.4
128