Skip to content

Commit add570b

Browse files
Marc Zyngieroupton
authored andcommitted
KVM: arm64: vgic: Make vgic_get_irq() more robust
vgic_get_irq() has an awkward signature, as it takes both a kvm *and* a vcpu, where the vcpu is allowed to be NULL if the INTID being looked up is a global interrupt (SPI or LPI). This leads to potentially problematic situations where the INTID passed is a private interrupt, but that there is no vcpu. In order to make things less ambiguous, let have *two* helpers instead: - vgic_get_irq(struct kvm *kvm, u32 intid), which is only concerned with *global* interrupts, as indicated by the lack of vcpu. - vgic_get_vcpu_irq(struct kvm_vcpu *vcpu, u32 intid), which can return *any* interrupt class, but must have of course a non-NULL vcpu. Most of the code nicely falls under one or the other situations, except for a couple of cases (close to the UABI or in the debug code) where we have to distinguish between the two cases. Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20241117165757.247686-3-maz@kernel.org Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
1 parent d561491 commit add570b

File tree

11 files changed

+71
-57
lines changed

11 files changed

+71
-57
lines changed

arch/arm64/kvm/vgic/vgic-debug.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,10 @@ static int vgic_debug_show(struct seq_file *s, void *v)
287287
* Expect this to succeed, as iter_mark_lpis() takes a reference on
288288
* every LPI to be visited.
289289
*/
290-
irq = vgic_get_irq(kvm, vcpu, iter->intid);
290+
if (iter->intid < VGIC_NR_PRIVATE_IRQS)
291+
irq = vgic_get_vcpu_irq(vcpu, iter->intid);
292+
else
293+
irq = vgic_get_irq(kvm, iter->intid);
291294
if (WARN_ON_ONCE(!irq))
292295
return -EINVAL;
293296

arch/arm64/kvm/vgic/vgic-init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ int vgic_init(struct kvm *kvm)
322322
goto out;
323323

324324
for (i = 0; i < VGIC_NR_PRIVATE_IRQS; i++) {
325-
struct vgic_irq *irq = vgic_get_irq(kvm, vcpu, i);
325+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, i);
326326

327327
switch (dist->vgic_model) {
328328
case KVM_DEV_TYPE_ARM_VGIC_V3:

arch/arm64/kvm/vgic/vgic-its.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
4242
struct kvm_vcpu *vcpu)
4343
{
4444
struct vgic_dist *dist = &kvm->arch.vgic;
45-
struct vgic_irq *irq = vgic_get_irq(kvm, NULL, intid), *oldirq;
45+
struct vgic_irq *irq = vgic_get_irq(kvm, intid), *oldirq;
4646
unsigned long flags;
4747
int ret;
4848

@@ -419,7 +419,7 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
419419
last_byte_offset = byte_offset;
420420
}
421421

422-
irq = vgic_get_irq(vcpu->kvm, NULL, intid);
422+
irq = vgic_get_irq(vcpu->kvm, intid);
423423
if (!irq)
424424
continue;
425425

@@ -1288,7 +1288,7 @@ int vgic_its_invall(struct kvm_vcpu *vcpu)
12881288
unsigned long intid;
12891289

12901290
xa_for_each(&dist->lpi_xa, intid, irq) {
1291-
irq = vgic_get_irq(kvm, NULL, intid);
1291+
irq = vgic_get_irq(kvm, intid);
12921292
if (!irq)
12931293
continue;
12941294

@@ -1354,7 +1354,7 @@ static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its,
13541354
return 0;
13551355

13561356
xa_for_each(&dist->lpi_xa, intid, irq) {
1357-
irq = vgic_get_irq(kvm, NULL, intid);
1357+
irq = vgic_get_irq(kvm, intid);
13581358
if (!irq)
13591359
continue;
13601360

arch/arm64/kvm/vgic/vgic-mmio-v2.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ static void vgic_mmio_write_sgir(struct kvm_vcpu *source_vcpu,
148148
if (!(targets & (1U << c)))
149149
continue;
150150

151-
irq = vgic_get_irq(source_vcpu->kvm, vcpu, intid);
151+
irq = vgic_get_vcpu_irq(vcpu, intid);
152152

153153
raw_spin_lock_irqsave(&irq->irq_lock, flags);
154154
irq->pending_latch = true;
@@ -167,7 +167,7 @@ static unsigned long vgic_mmio_read_target(struct kvm_vcpu *vcpu,
167167
u64 val = 0;
168168

169169
for (i = 0; i < len; i++) {
170-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
170+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
171171

172172
val |= (u64)irq->targets << (i * 8);
173173

@@ -191,7 +191,7 @@ static void vgic_mmio_write_target(struct kvm_vcpu *vcpu,
191191
return;
192192

193193
for (i = 0; i < len; i++) {
194-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, NULL, intid + i);
194+
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, intid + i);
195195
int target;
196196

197197
raw_spin_lock_irqsave(&irq->irq_lock, flags);
@@ -213,7 +213,7 @@ static unsigned long vgic_mmio_read_sgipend(struct kvm_vcpu *vcpu,
213213
u64 val = 0;
214214

215215
for (i = 0; i < len; i++) {
216-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
216+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
217217

218218
val |= (u64)irq->source << (i * 8);
219219

@@ -231,7 +231,7 @@ static void vgic_mmio_write_sgipendc(struct kvm_vcpu *vcpu,
231231
unsigned long flags;
232232

233233
for (i = 0; i < len; i++) {
234-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
234+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
235235

236236
raw_spin_lock_irqsave(&irq->irq_lock, flags);
237237

@@ -253,7 +253,7 @@ static void vgic_mmio_write_sgipends(struct kvm_vcpu *vcpu,
253253
unsigned long flags;
254254

255255
for (i = 0; i < len; i++) {
256-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
256+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
257257

258258
raw_spin_lock_irqsave(&irq->irq_lock, flags);
259259

arch/arm64/kvm/vgic/vgic-mmio-v3.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ static unsigned long vgic_mmio_read_irouter(struct kvm_vcpu *vcpu,
194194
gpa_t addr, unsigned int len)
195195
{
196196
int intid = VGIC_ADDR_TO_INTID(addr, 64);
197-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, NULL, intid);
197+
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, intid);
198198
unsigned long ret = 0;
199199

200200
if (!irq)
@@ -220,7 +220,7 @@ static void vgic_mmio_write_irouter(struct kvm_vcpu *vcpu,
220220
if (addr & 4)
221221
return;
222222

223-
irq = vgic_get_irq(vcpu->kvm, NULL, intid);
223+
irq = vgic_get_irq(vcpu->kvm, intid);
224224

225225
if (!irq)
226226
return;
@@ -548,7 +548,7 @@ static void vgic_mmio_write_invlpi(struct kvm_vcpu *vcpu,
548548

549549
vgic_set_rdist_busy(vcpu, true);
550550

551-
irq = vgic_get_irq(vcpu->kvm, NULL, intid);
551+
irq = vgic_get_irq(vcpu->kvm, intid);
552552
if (irq) {
553553
vgic_its_inv_lpi(vcpu->kvm, irq);
554554
vgic_put_irq(vcpu->kvm, irq);
@@ -1025,7 +1025,7 @@ int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
10251025

10261026
static void vgic_v3_queue_sgi(struct kvm_vcpu *vcpu, u32 sgi, bool allow_group1)
10271027
{
1028-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, sgi);
1028+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, sgi);
10291029
unsigned long flags;
10301030

10311031
raw_spin_lock_irqsave(&irq->irq_lock, flags);

arch/arm64/kvm/vgic/vgic-mmio.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ unsigned long vgic_mmio_read_group(struct kvm_vcpu *vcpu,
5050

5151
/* Loop over all IRQs affected by this read */
5252
for (i = 0; i < len * 8; i++) {
53-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
53+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
5454

5555
if (irq->group)
5656
value |= BIT(i);
@@ -74,7 +74,7 @@ void vgic_mmio_write_group(struct kvm_vcpu *vcpu, gpa_t addr,
7474
unsigned long flags;
7575

7676
for (i = 0; i < len * 8; i++) {
77-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
77+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
7878

7979
raw_spin_lock_irqsave(&irq->irq_lock, flags);
8080
irq->group = !!(val & BIT(i));
@@ -102,7 +102,7 @@ unsigned long vgic_mmio_read_enable(struct kvm_vcpu *vcpu,
102102

103103
/* Loop over all IRQs affected by this read */
104104
for (i = 0; i < len * 8; i++) {
105-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
105+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
106106

107107
if (irq->enabled)
108108
value |= (1U << i);
@@ -122,7 +122,7 @@ void vgic_mmio_write_senable(struct kvm_vcpu *vcpu,
122122
unsigned long flags;
123123

124124
for_each_set_bit(i, &val, len * 8) {
125-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
125+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
126126

127127
raw_spin_lock_irqsave(&irq->irq_lock, flags);
128128
if (irq->hw && vgic_irq_is_sgi(irq->intid)) {
@@ -171,7 +171,7 @@ void vgic_mmio_write_cenable(struct kvm_vcpu *vcpu,
171171
unsigned long flags;
172172

173173
for_each_set_bit(i, &val, len * 8) {
174-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
174+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
175175

176176
raw_spin_lock_irqsave(&irq->irq_lock, flags);
177177
if (irq->hw && vgic_irq_is_sgi(irq->intid) && irq->enabled)
@@ -193,7 +193,7 @@ int vgic_uaccess_write_senable(struct kvm_vcpu *vcpu,
193193
unsigned long flags;
194194

195195
for_each_set_bit(i, &val, len * 8) {
196-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
196+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
197197

198198
raw_spin_lock_irqsave(&irq->irq_lock, flags);
199199
irq->enabled = true;
@@ -214,7 +214,7 @@ int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu,
214214
unsigned long flags;
215215

216216
for_each_set_bit(i, &val, len * 8) {
217-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
217+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
218218

219219
raw_spin_lock_irqsave(&irq->irq_lock, flags);
220220
irq->enabled = false;
@@ -236,7 +236,7 @@ static unsigned long __read_pending(struct kvm_vcpu *vcpu,
236236

237237
/* Loop over all IRQs affected by this read */
238238
for (i = 0; i < len * 8; i++) {
239-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
239+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
240240
unsigned long flags;
241241
bool val;
242242

@@ -309,7 +309,7 @@ static void __set_pending(struct kvm_vcpu *vcpu, gpa_t addr, unsigned int len,
309309
unsigned long flags;
310310

311311
for_each_set_bit(i, &val, len * 8) {
312-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
312+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
313313

314314
/* GICD_ISPENDR0 SGI bits are WI when written from the guest. */
315315
if (is_vgic_v2_sgi(vcpu, irq) && !is_user) {
@@ -395,7 +395,7 @@ static void __clear_pending(struct kvm_vcpu *vcpu,
395395
unsigned long flags;
396396

397397
for_each_set_bit(i, &val, len * 8) {
398-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
398+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
399399

400400
/* GICD_ICPENDR0 SGI bits are WI when written from the guest. */
401401
if (is_vgic_v2_sgi(vcpu, irq) && !is_user) {
@@ -494,7 +494,7 @@ static unsigned long __vgic_mmio_read_active(struct kvm_vcpu *vcpu,
494494

495495
/* Loop over all IRQs affected by this read */
496496
for (i = 0; i < len * 8; i++) {
497-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
497+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
498498

499499
/*
500500
* Even for HW interrupts, don't evaluate the HW state as
@@ -598,7 +598,7 @@ static void __vgic_mmio_write_cactive(struct kvm_vcpu *vcpu,
598598
int i;
599599

600600
for_each_set_bit(i, &val, len * 8) {
601-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
601+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
602602
vgic_mmio_change_active(vcpu, irq, false);
603603
vgic_put_irq(vcpu->kvm, irq);
604604
}
@@ -635,7 +635,7 @@ static void __vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
635635
int i;
636636

637637
for_each_set_bit(i, &val, len * 8) {
638-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
638+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
639639
vgic_mmio_change_active(vcpu, irq, true);
640640
vgic_put_irq(vcpu->kvm, irq);
641641
}
@@ -672,7 +672,7 @@ unsigned long vgic_mmio_read_priority(struct kvm_vcpu *vcpu,
672672
u64 val = 0;
673673

674674
for (i = 0; i < len; i++) {
675-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
675+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
676676

677677
val |= (u64)irq->priority << (i * 8);
678678

@@ -698,7 +698,7 @@ void vgic_mmio_write_priority(struct kvm_vcpu *vcpu,
698698
unsigned long flags;
699699

700700
for (i = 0; i < len; i++) {
701-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
701+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
702702

703703
raw_spin_lock_irqsave(&irq->irq_lock, flags);
704704
/* Narrow the priority range to what we actually support */
@@ -719,7 +719,7 @@ unsigned long vgic_mmio_read_config(struct kvm_vcpu *vcpu,
719719
int i;
720720

721721
for (i = 0; i < len * 4; i++) {
722-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
722+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, intid + i);
723723

724724
if (irq->config == VGIC_CONFIG_EDGE)
725725
value |= (2U << (i * 2));
@@ -750,7 +750,7 @@ void vgic_mmio_write_config(struct kvm_vcpu *vcpu,
750750
if (intid + i < VGIC_NR_PRIVATE_IRQS)
751751
continue;
752752

753-
irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
753+
irq = vgic_get_irq(vcpu->kvm, intid + i);
754754
raw_spin_lock_irqsave(&irq->irq_lock, flags);
755755

756756
if (test_bit(i * 2 + 1, &val))
@@ -775,7 +775,7 @@ u32 vgic_read_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid)
775775
if ((intid + i) < VGIC_NR_SGIS || (intid + i) >= nr_irqs)
776776
continue;
777777

778-
irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
778+
irq = vgic_get_vcpu_irq(vcpu, intid + i);
779779
if (irq->config == VGIC_CONFIG_LEVEL && irq->line_level)
780780
val |= (1U << i);
781781

@@ -799,7 +799,7 @@ void vgic_write_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid,
799799
if ((intid + i) < VGIC_NR_SGIS || (intid + i) >= nr_irqs)
800800
continue;
801801

802-
irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
802+
irq = vgic_get_vcpu_irq(vcpu, intid + i);
803803

804804
/*
805805
* Line level is set irrespective of irq type

arch/arm64/kvm/vgic/vgic-v2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
7272
kvm_notify_acked_irq(vcpu->kvm, 0,
7373
intid - VGIC_NR_PRIVATE_IRQS);
7474

75-
irq = vgic_get_irq(vcpu->kvm, vcpu, intid);
75+
irq = vgic_get_vcpu_irq(vcpu, intid);
7676

7777
raw_spin_lock(&irq->irq_lock);
7878

arch/arm64/kvm/vgic/vgic-v3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
6565
kvm_notify_acked_irq(vcpu->kvm, 0,
6666
intid - VGIC_NR_PRIVATE_IRQS);
6767

68-
irq = vgic_get_irq(vcpu->kvm, vcpu, intid);
68+
irq = vgic_get_vcpu_irq(vcpu, intid);
6969
if (!irq) /* An LPI could have been unmapped. */
7070
continue;
7171

arch/arm64/kvm/vgic/vgic-v4.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ static void vgic_v4_enable_vsgis(struct kvm_vcpu *vcpu)
123123
* IRQ. The SGI code will do its magic.
124124
*/
125125
for (i = 0; i < VGIC_NR_SGIS; i++) {
126-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, i);
126+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, i);
127127
struct irq_desc *desc;
128128
unsigned long flags;
129129
int ret;
@@ -160,7 +160,7 @@ static void vgic_v4_disable_vsgis(struct kvm_vcpu *vcpu)
160160
int i;
161161

162162
for (i = 0; i < VGIC_NR_SGIS; i++) {
163-
struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, i);
163+
struct vgic_irq *irq = vgic_get_vcpu_irq(vcpu, i);
164164
struct irq_desc *desc;
165165
unsigned long flags;
166166
int ret;

0 commit comments

Comments
 (0)