@@ -31,6 +31,8 @@
#include "ioapic.h"
+#include "lapic.h"
+
static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
struct kvm *kvm, int irq_source_id, int level,
bool line_status)
@@ -48,11 +50,6 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
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,
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,
struct kvm_vcpu *vcpu, *lowest = NULL;
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");
irq->delivery_mode = APIC_DM_FIXED;
}
@@ -76,7 +73,7 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
irq->dest_id, irq->dest_mode))
continue;
- if (!kvm_is_dm_lowest_prio(irq)) {
+ if (!kvm_lowest_prio_delivery(irq)) {
if (r < 0)
r = 0;
r += kvm_apic_set_irq(vcpu, irq, dest_map);
@@ -701,8 +701,7 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
dst = map->logical_map[cid];
bitmap = apic_logical_id(map, mda);
-
- if (irq->delivery_mode == APIC_DM_LOWEST) {
+ if (kvm_lowest_prio_delivery(irq)) {
int l = -1;
for_each_set_bit(i, &bitmap, 16) {
if (!dst[i])
@@ -168,6 +168,12 @@ static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu)
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);
void wait_lapic_expire(struct kvm_vcpu *vcpu);
Signed-off-by: James Sullivan <sullivan.james.f@gmail.com> --- The following changes are added in this patch: * Move kvm_is_dm_lowest_prio() -> lapic.h, rename to kvm_lowest_prio_delivery, set condition to (APIC_DM_LOWPRI || msi_redir_hint) * Change check in kvm_irq_delivery_to_apic_fast() for APIC_DM_LOWPRI or msi_redir_hint to a check for kvm_is_dm_lowest_prio() Changes since v1: * Squashed a number of smaller commits into this one commit, which implements MSI delivery to only the lowest-priority CPU whenever RH=1 using the above helper kvm_lowest_prio_delivery(). This patch relies on a past submission that adds a check to kvm_set_msi_irq() for RH=1, setting APIC_DEST_LOGICAL only when RH=1/DM=1 and otherwise defaulting to APIC_DEST_PHYSICAL. (See <5502FEDB.3030606@gmail.com>) arch/x86/kvm/irq_comm.c | 11 ++++------- arch/x86/kvm/lapic.c | 3 +-- arch/x86/kvm/lapic.h | 6 ++++++ 3 files changed, 11 insertions(+), 9 deletions(-)