1010#include <linux/irqchip/riscv-aplic.h>
1111#include <linux/kvm_host.h>
1212#include <linux/math.h>
13+ #include <linux/nospec.h>
1314#include <linux/spinlock.h>
1415#include <linux/swab.h>
1516#include <kvm/iodev.h>
@@ -45,7 +46,7 @@ static u32 aplic_read_sourcecfg(struct aplic *aplic, u32 irq)
4546
4647 if (!irq || aplic -> nr_irqs <= irq )
4748 return 0 ;
48- irqd = & aplic -> irqs [irq ];
49+ irqd = & aplic -> irqs [array_index_nospec ( irq , aplic -> nr_irqs ) ];
4950
5051 raw_spin_lock_irqsave (& irqd -> lock , flags );
5152 ret = irqd -> sourcecfg ;
@@ -61,7 +62,7 @@ static void aplic_write_sourcecfg(struct aplic *aplic, u32 irq, u32 val)
6162
6263 if (!irq || aplic -> nr_irqs <= irq )
6364 return ;
64- irqd = & aplic -> irqs [irq ];
65+ irqd = & aplic -> irqs [array_index_nospec ( irq , aplic -> nr_irqs ) ];
6566
6667 if (val & APLIC_SOURCECFG_D )
6768 val = 0 ;
@@ -81,7 +82,7 @@ static u32 aplic_read_target(struct aplic *aplic, u32 irq)
8182
8283 if (!irq || aplic -> nr_irqs <= irq )
8384 return 0 ;
84- irqd = & aplic -> irqs [irq ];
85+ irqd = & aplic -> irqs [array_index_nospec ( irq , aplic -> nr_irqs ) ];
8586
8687 raw_spin_lock_irqsave (& irqd -> lock , flags );
8788 ret = irqd -> target ;
@@ -97,7 +98,7 @@ static void aplic_write_target(struct aplic *aplic, u32 irq, u32 val)
9798
9899 if (!irq || aplic -> nr_irqs <= irq )
99100 return ;
100- irqd = & aplic -> irqs [irq ];
101+ irqd = & aplic -> irqs [array_index_nospec ( irq , aplic -> nr_irqs ) ];
101102
102103 val &= APLIC_TARGET_EIID_MASK |
103104 (APLIC_TARGET_HART_IDX_MASK << APLIC_TARGET_HART_IDX_SHIFT ) |
@@ -116,7 +117,7 @@ static bool aplic_read_pending(struct aplic *aplic, u32 irq)
116117
117118 if (!irq || aplic -> nr_irqs <= irq )
118119 return false;
119- irqd = & aplic -> irqs [irq ];
120+ irqd = & aplic -> irqs [array_index_nospec ( irq , aplic -> nr_irqs ) ];
120121
121122 raw_spin_lock_irqsave (& irqd -> lock , flags );
122123 ret = (irqd -> state & APLIC_IRQ_STATE_PENDING ) ? true : false;
@@ -132,7 +133,7 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending)
132133
133134 if (!irq || aplic -> nr_irqs <= irq )
134135 return ;
135- irqd = & aplic -> irqs [irq ];
136+ irqd = & aplic -> irqs [array_index_nospec ( irq , aplic -> nr_irqs ) ];
136137
137138 raw_spin_lock_irqsave (& irqd -> lock , flags );
138139
@@ -170,7 +171,7 @@ static bool aplic_read_enabled(struct aplic *aplic, u32 irq)
170171
171172 if (!irq || aplic -> nr_irqs <= irq )
172173 return false;
173- irqd = & aplic -> irqs [irq ];
174+ irqd = & aplic -> irqs [array_index_nospec ( irq , aplic -> nr_irqs ) ];
174175
175176 raw_spin_lock_irqsave (& irqd -> lock , flags );
176177 ret = (irqd -> state & APLIC_IRQ_STATE_ENABLED ) ? true : false;
@@ -186,7 +187,7 @@ static void aplic_write_enabled(struct aplic *aplic, u32 irq, bool enabled)
186187
187188 if (!irq || aplic -> nr_irqs <= irq )
188189 return ;
189- irqd = & aplic -> irqs [irq ];
190+ irqd = & aplic -> irqs [array_index_nospec ( irq , aplic -> nr_irqs ) ];
190191
191192 raw_spin_lock_irqsave (& irqd -> lock , flags );
192193 if (enabled )
@@ -205,7 +206,7 @@ static bool aplic_read_input(struct aplic *aplic, u32 irq)
205206
206207 if (!irq || aplic -> nr_irqs <= irq )
207208 return false;
208- irqd = & aplic -> irqs [irq ];
209+ irqd = & aplic -> irqs [array_index_nospec ( irq , aplic -> nr_irqs ) ];
209210
210211 raw_spin_lock_irqsave (& irqd -> lock , flags );
211212
@@ -254,7 +255,7 @@ static void aplic_update_irq_range(struct kvm *kvm, u32 first, u32 last)
254255 for (irq = first ; irq <= last ; irq ++ ) {
255256 if (!irq || aplic -> nr_irqs <= irq )
256257 continue ;
257- irqd = & aplic -> irqs [irq ];
258+ irqd = & aplic -> irqs [array_index_nospec ( irq , aplic -> nr_irqs ) ];
258259
259260 raw_spin_lock_irqsave (& irqd -> lock , flags );
260261
@@ -283,7 +284,7 @@ int kvm_riscv_aia_aplic_inject(struct kvm *kvm, u32 source, bool level)
283284
284285 if (!aplic || !source || (aplic -> nr_irqs <= source ))
285286 return - ENODEV ;
286- irqd = & aplic -> irqs [source ];
287+ irqd = & aplic -> irqs [array_index_nospec ( source , aplic -> nr_irqs ) ];
287288 ie = (aplic -> domaincfg & APLIC_DOMAINCFG_IE ) ? true : false;
288289
289290 raw_spin_lock_irqsave (& irqd -> lock , flags );
0 commit comments