hw/net/vmxnet3: Do not abort if guest provides bad interrupt numbers
vmxnet3_validate_interrupts() currently aborts via hw_error() if the guest provided bad interrupt numbers. This should not happen, QEMU should rather refuse to activate the device in this case instead. Thus propagate the error to the callers to handle it more gracefully there. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/539 Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Signed-off-by: Thomas Huth <thuth@redhat.com> Message-ID: <20260731113352.189066-1-thuth@redhat.com>
Thomas Huth committed
Jul 31, 2026 at 13:33 UTC
46099d99005588b25eb07957cd9cdd688c4fc476
1 file changed
+26
-8
hw/net/vmxnet3.c
+26
-8
@@ -1336,32 +1336,46 @@ static bool vmxnet3_verify_intx(VMXNET3State *s, int intx)
1336
|| intx == pci_get_byte(s->parent_obj.config + PCI_INTERRUPT_PIN) - 1;
1337
}
1338
1339
-static void vmxnet3_validate_interrupt_idx(bool is_msix, int idx)
1339
+static bool vmxnet3_validate_irq_idx(const char *type, bool is_msix, int idx)
1340
{
1341
int max_ints = is_msix ? VMXNET3_MAX_INTRS : VMXNET3_MAX_NMSIX_INTRS;
1342
+
1343
if (idx >= max_ints) {
1343
- hw_error("Bad interrupt index: %d\n", idx);
1344
+ qemu_log_mask(LOG_GUEST_ERROR,
1345
+ "vmxnet3: Bad %s queue interrupt index: %d\n",
1346
+ type, idx);
1347
+ return false;
1348
}
1349
+
1350
+ return true;
1351
}
1352
1347
-static void vmxnet3_validate_interrupts(VMXNET3State *s)
1353
+static bool vmxnet3_validate_interrupts(VMXNET3State *s)
1354
{
1355
int i;
1356
1357
VMW_CFPRN("Verifying event interrupt index (%d)", s->event_int_idx);
1352
- vmxnet3_validate_interrupt_idx(s->msix_used, s->event_int_idx);
1358
+ if (!vmxnet3_validate_irq_idx("event", s->msix_used, s->event_int_idx)) {
1359
+ return false;
1360
+ }
1361
1362
for (i = 0; i < s->txq_num; i++) {
1363
int idx = s->txq_descr[i].intr_idx;
1364
VMW_CFPRN("Verifying TX queue %d interrupt index (%d)", i, idx);
1357
- vmxnet3_validate_interrupt_idx(s->msix_used, idx);
1365
+ if (!vmxnet3_validate_irq_idx("TX", s->msix_used, idx)) {
1366
+ return false;
1367
+ }
1368
}
1369
1370
for (i = 0; i < s->rxq_num; i++) {
1371
int idx = s->rxq_descr[i].intr_idx;
1372
VMW_CFPRN("Verifying RX queue %d interrupt index (%d)", i, idx);
1363
- vmxnet3_validate_interrupt_idx(s->msix_used, idx);
1373
+ if (!vmxnet3_validate_irq_idx("RX", s->msix_used, idx)) {
1374
+ return false;
1375
+ }
1376
}
1377
+
1378
+ return true;
1379
}
1380
1381
static bool vmxnet3_validate_queues(VMXNET3State *s)
@@ -1554,7 +1568,9 @@ static void vmxnet3_activate_device(VMXNET3State *s)
1568
sizeof(s->rxq_descr[i].rxq_stats));
1569
}
1570
1557
- vmxnet3_validate_interrupts(s);
1571
+ if (!vmxnet3_validate_interrupts(s)) {
1572
+ return;
1573
+ }
1574
1575
/* Make sure everything is in place before device activation */
1576
smp_wmb();
@@ -2392,7 +2408,9 @@ static int vmxnet3_post_load(void *opaque, int version_id)
2408
if (!vmxnet3_validate_queues(s)) {
2409
return -1;
2410
}
2395
- vmxnet3_validate_interrupts(s);
2411
+ if (!vmxnet3_validate_interrupts(s)) {
2412
+ return -1;
2413
+ }
2414
2415
return 0;
2416
}