@samitouri / QOSamiQemu / commits / c77944aa82

accel/mshv: reserve ioapic routes on s->irq_routes

We reserve 24 ioapic routes using the new functions that operate on the mshv apic state. commit/add_msi_routing() fn's can be removed now. Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com> Link: https://lore.kernel.org/r/20260417105618.3621-13-magnuskulke@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Magnus Kulke committed Apr 17, 2026 at 12:55 UTC c77944aa82c0518351ea423fc8a9b2fb7327ca21
3 files changed +18 -103
accel/mshv/irq.c
+18 -97
@@ -36,93 +36,6 @@ void mshv_init_msicontrol(void)
36 msi_control->updated = false;
37 }
38
39 -static int add_msi_routing(uint64_t addr, uint32_t data)
40 -{
41 - struct mshv_user_irq_entry *route_entry;
42 - uint32_t high_addr = addr >> 32;
43 - uint32_t low_addr = addr & 0xFFFFFFFF;
44 - int gsi;
45 - GHashTable *gsi_routes;
46 -
47 - trace_mshv_add_msi_routing(addr, data);
48 -
49 - assert(msi_control);
50 -
51 - WITH_QEMU_LOCK_GUARD(&msi_control_mutex) {
52 - /* find an empty slot */
53 - gsi = 0;
54 - gsi_routes = msi_control->gsi_routes;
55 - while (gsi < MSHV_MAX_MSI_ROUTES) {
56 - route_entry = g_hash_table_lookup(gsi_routes, GINT_TO_POINTER(gsi));
57 - if (!route_entry) {
58 - break;
59 - }
60 - gsi++;
61 - }
62 - if (gsi >= MSHV_MAX_MSI_ROUTES) {
63 - error_report("No empty gsi slot available");
64 - return -1;
65 - }
66 -
67 - /* create new entry */
68 - route_entry = g_new0(struct mshv_user_irq_entry, 1);
69 - route_entry->gsi = gsi;
70 - route_entry->address_hi = high_addr;
71 - route_entry->address_lo = low_addr;
72 - route_entry->data = data;
73 -
74 - g_hash_table_insert(gsi_routes, GINT_TO_POINTER(gsi), route_entry);
75 - msi_control->updated = true;
76 - }
77 -
78 - return gsi;
79 -}
80 -
81 -static int commit_msi_routing_table(int vm_fd)
82 -{
83 - guint len;
84 - int i, ret;
85 - size_t table_size;
86 - struct mshv_user_irq_table *table;
87 - GHashTableIter iter;
88 - gpointer key, value;
89 -
90 - assert(msi_control);
91 -
92 - WITH_QEMU_LOCK_GUARD(&msi_control_mutex) {
93 - if (!msi_control->updated) {
94 - /* nothing to update */
95 - return 0;
96 - }
97 -
98 - /* Calculate the size of the table */
99 - len = g_hash_table_size(msi_control->gsi_routes);
100 - table_size = sizeof(struct mshv_user_irq_table)
101 - + len * sizeof(struct mshv_user_irq_entry);
102 - table = g_malloc0(table_size);
103 -
104 - g_hash_table_iter_init(&iter, msi_control->gsi_routes);
105 - i = 0;
106 - while (g_hash_table_iter_next(&iter, &key, &value)) {
107 - struct mshv_user_irq_entry *entry = value;
108 - table->entries[i] = *entry;
109 - i++;
110 - }
111 - table->nr = i;
112 -
113 - trace_mshv_commit_msi_routing_table(vm_fd, len);
114 -
115 - ret = ioctl(vm_fd, MSHV_SET_MSI_ROUTING, table);
116 - g_free(table);
117 - if (ret < 0) {
118 - error_report("Failed to commit msi routing table");
119 - return -1;
120 - }
121 - msi_control->updated = false;
122 - }
123 - return 0;
124 -}
125 -
39 /* Pass an eventfd which is to be used for injecting interrupts from userland */
40 static int irqfd(int vm_fd, int fd, int resample_fd, uint32_t gsi,
41 uint32_t flags)
@@ -420,37 +333,45 @@ int mshv_irqchip_remove_irqfd_notifier_gsi(const EventNotifier *event,
333 return irqchip_update_irqfd_notifier_gsi(event, NULL, virq, false);
334 }
335
423 -int mshv_reserve_ioapic_msi_routes(int vm_fd)
336 +static int mshv_reserve_ioapic_msi_routes(MshvState *s)
337 {
425 - int ret, gsi;
338 + int ret, i;
339 + int gsi = 0;
340 + struct mshv_user_irq_entry blank_entry = { 0 };
341
342 /*
343 * Reserve GSI 0-23 for IOAPIC pins, to avoid conflicts of legacy
344 * peripherals with MSI-X devices
345 */
431 - for (gsi = 0; gsi < IOAPIC_NUM_PINS; gsi++) {
432 - ret = add_msi_routing(0, 0);
346 + for (i = 0; i < IOAPIC_NUM_PINS; i++) {
347 + /* ret = add_msi_routing(0, 0); */
348 + ret = irqchip_allocate_gsi(s, &gsi);
349 if (ret < 0) {
434 - error_report("Failed to reserve GSI %d", gsi);
350 + error_report("Failed to reserve GSI %d: %s", gsi, strerror(-ret));
351 return -1;
352 }
353 + blank_entry.gsi = gsi;
354 + add_routing_entry(s, &blank_entry);
355 }
356
439 - ret = commit_msi_routing_table(vm_fd);
440 - if (ret < 0) {
441 - error_report("Failed to commit reserved IOAPIC MSI routes");
442 - return -1;
443 - }
357 + mshv_irqchip_commit_routes(s);
358
359 return 0;
360 }
361
362 void mshv_init_irq_routing(MshvState *s)
363 {
364 + int ret;
365 int gsi_count = MSHV_MAX_MSI_ROUTES;
366
367 s->irq_routes = g_malloc0(sizeof(*s->irq_routes));
368 s->nr_allocated_irq_routes = 0;
369 s->gsi_count = gsi_count;
370 s->used_gsi_bitmap = bitmap_new(gsi_count);
371 +
372 + ret = mshv_reserve_ioapic_msi_routes(s);
373 + if (ret < 0) {
374 + error_report("Failed to reserve IOAPIC MSI routes");
375 + abort();
376 + }
377 }
accel/mshv/mshv-all.c
-5
@@ -264,11 +264,6 @@ static int create_vm(int mshv_fd, int *vm_fd)
264 return -1;
265 }
266
267 - ret = mshv_reserve_ioapic_msi_routes(*vm_fd);
268 - if (ret < 0) {
269 - return -1;
270 - }
271 -
267 ret = mshv_arch_post_init_vm(*vm_fd);
268 if (ret < 0) {
269 return -1;
include/system/mshv_int.h
-1
@@ -122,6 +122,5 @@ int mshv_configure_msr(const CPUState *cpu, const MshvMsrEntry *msrs,
122
123 /* interrupt */
124 void mshv_init_msicontrol(void);
125 -int mshv_reserve_ioapic_msi_routes(int vm_fd);
125
126 #endif