kvm: Make kvm_irqchip_commit_routes an internal service

Automatically commit route changes after kvm_add_routing_entry and
kvm_irqchip_release_virq. There is no performance relevant use case for
which collecting multiple route changes is beneficial. This makes
kvm_irqchip_commit_routes an internal service which assert()s that the
corresponding IOCTL will always succeed.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
Jan Kiszka 2012-05-17 10:32:35 -03:00 committed by Avi Kivity
parent 1e2aa8be09
commit e7b2030862
3 changed files with 15 additions and 18 deletions

View File

@ -56,7 +56,7 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
{ {
#ifdef CONFIG_KVM #ifdef CONFIG_KVM
KVMState *s = kvm_state; KVMState *s = kvm_state;
int ret, i; int i;
if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) { if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
for (i = 0; i < 8; ++i) { for (i = 0; i < 8; ++i) {
@ -77,10 +77,6 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
} }
} }
} }
ret = kvm_irqchip_commit_routes(s);
if (ret < 0) {
hw_error("KVM IRQ routing setup failed");
}
} }
#endif /* CONFIG_KVM */ #endif /* CONFIG_KVM */
} }

View File

@ -908,6 +908,15 @@ static void kvm_init_irq_routing(KVMState *s)
kvm_arch_init_irq_routing(s); kvm_arch_init_irq_routing(s);
} }
static void kvm_irqchip_commit_routes(KVMState *s)
{
int ret;
s->irq_routes->flags = 0;
ret = kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
assert(ret == 0);
}
static void kvm_add_routing_entry(KVMState *s, static void kvm_add_routing_entry(KVMState *s,
struct kvm_irq_routing_entry *entry) struct kvm_irq_routing_entry *entry)
{ {
@ -933,6 +942,8 @@ static void kvm_add_routing_entry(KVMState *s,
new->u = entry->u; new->u = entry->u;
set_gsi(s, entry->gsi); set_gsi(s, entry->gsi);
kvm_irqchip_commit_routes(s);
} }
void kvm_irqchip_add_irq_route(KVMState *s, int irq, int irqchip, int pin) void kvm_irqchip_add_irq_route(KVMState *s, int irq, int irqchip, int pin)
@ -949,12 +960,6 @@ void kvm_irqchip_add_irq_route(KVMState *s, int irq, int irqchip, int pin)
kvm_add_routing_entry(s, &e); kvm_add_routing_entry(s, &e);
} }
int kvm_irqchip_commit_routes(KVMState *s)
{
s->irq_routes->flags = 0;
return kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes);
}
void kvm_irqchip_release_virq(KVMState *s, int virq) void kvm_irqchip_release_virq(KVMState *s, int virq)
{ {
struct kvm_irq_routing_entry *e; struct kvm_irq_routing_entry *e;
@ -968,6 +973,8 @@ void kvm_irqchip_release_virq(KVMState *s, int virq)
} }
} }
clear_gsi(s, virq); clear_gsi(s, virq);
kvm_irqchip_commit_routes(s);
} }
static unsigned int kvm_hash_msi(uint32_t data) static unsigned int kvm_hash_msi(uint32_t data)
@ -1049,7 +1056,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
route = kvm_lookup_msi_route(s, msg); route = kvm_lookup_msi_route(s, msg);
if (!route) { if (!route) {
int virq, ret; int virq;
virq = kvm_irqchip_get_virq(s); virq = kvm_irqchip_get_virq(s);
if (virq < 0) { if (virq < 0) {
@ -1068,11 +1075,6 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
QTAILQ_INSERT_TAIL(&s->msi_hashtab[kvm_hash_msi(msg.data)], route, QTAILQ_INSERT_TAIL(&s->msi_hashtab[kvm_hash_msi(msg.data)], route,
entry); entry);
ret = kvm_irqchip_commit_routes(s);
if (ret < 0) {
return ret;
}
} }
assert(route->kroute.type == KVM_IRQ_ROUTING_MSI); assert(route->kroute.type == KVM_IRQ_ROUTING_MSI);

1
kvm.h
View File

@ -135,7 +135,6 @@ int kvm_irqchip_set_irq(KVMState *s, int irq, int level);
int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg); int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin); void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin);
int kvm_irqchip_commit_routes(KVMState *s);
void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic); void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);
void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic); void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic);