Commit d1ebdbf9 authored by James Sullivan's avatar James Sullivan Committed by Paolo Bonzini

kvm: x86: Deliver MSI IRQ to only lowest prio cpu if msi_redir_hint is true

An MSI interrupt should only be delivered to the lowest priority CPU
when it has RH=1, regardless of the delivery mode. Modified
kvm_is_dm_lowest_prio() to check for either irq->delivery_mode == APIC_DM_LOWPRI
or irq->msi_redir_hint.

Moved kvm_is_dm_lowest_prio() into lapic.h and renamed to
kvm_lowest_prio_delivery().

Changed a check in kvm_irq_delivery_to_apic_fast() from
irq->delivery_mode == APIC_DM_LOWPRI to kvm_is_dm_lowest_prio().
Signed-off-by: default avatarJames Sullivan <sullivan.james.f@gmail.com>
Reviewed-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 93bbf0b8
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include "ioapic.h" #include "ioapic.h"
#include "lapic.h"
static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e, static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
struct kvm *kvm, int irq_source_id, int level, struct kvm *kvm, int irq_source_id, int level,
bool line_status) bool line_status)
...@@ -48,11 +50,6 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e, ...@@ -48,11 +50,6 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
line_status); line_status);
} }
inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq)
{
return irq->delivery_mode == APIC_DM_LOWEST;
}
int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
struct kvm_lapic_irq *irq, unsigned long *dest_map) struct kvm_lapic_irq *irq, unsigned long *dest_map)
{ {
...@@ -60,7 +57,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, ...@@ -60,7 +57,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
struct kvm_vcpu *vcpu, *lowest = NULL; struct kvm_vcpu *vcpu, *lowest = NULL;
if (irq->dest_mode == 0 && irq->dest_id == 0xff && if (irq->dest_mode == 0 && irq->dest_id == 0xff &&
kvm_is_dm_lowest_prio(irq)) { kvm_lowest_prio_delivery(irq)) {
printk(KERN_INFO "kvm: apic: phys broadcast and lowest prio\n"); printk(KERN_INFO "kvm: apic: phys broadcast and lowest prio\n");
irq->delivery_mode = APIC_DM_FIXED; irq->delivery_mode = APIC_DM_FIXED;
} }
...@@ -76,7 +73,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, ...@@ -76,7 +73,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
irq->dest_id, irq->dest_mode)) irq->dest_id, irq->dest_mode))
continue; continue;
if (!kvm_is_dm_lowest_prio(irq)) { if (!kvm_lowest_prio_delivery(irq)) {
if (r < 0) if (r < 0)
r = 0; r = 0;
r += kvm_apic_set_irq(vcpu, irq, dest_map); r += kvm_apic_set_irq(vcpu, irq, dest_map);
......
...@@ -728,7 +728,7 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src, ...@@ -728,7 +728,7 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
dst = map->logical_map[cid]; dst = map->logical_map[cid];
if (irq->delivery_mode == APIC_DM_LOWEST) { if (kvm_lowest_prio_delivery(irq)) {
int l = -1; int l = -1;
for_each_set_bit(i, &bitmap, 16) { for_each_set_bit(i, &bitmap, 16) {
if (!dst[i]) if (!dst[i])
......
...@@ -153,6 +153,12 @@ static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu) ...@@ -153,6 +153,12 @@ static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu)
return vcpu->arch.apic->pending_events; return vcpu->arch.apic->pending_events;
} }
static inline bool kvm_lowest_prio_delivery(struct kvm_lapic_irq *irq)
{
return (irq->delivery_mode == APIC_DM_LOWEST ||
irq->msi_redir_hint);
}
bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector); bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector);
void wait_lapic_expire(struct kvm_vcpu *vcpu); void wait_lapic_expire(struct kvm_vcpu *vcpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment