@@ -685,6 +685,7 @@ struct kvm_lapic_irq {
u32 trig_mode;
u32 shorthand;
u32 dest_id;
+ bool msi_redir_hint;
};
struct kvm_x86_ops {
@@ -347,6 +347,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status)
irqe.delivery_mode = entry->fields.delivery_mode << 8;
irqe.level = 1;
irqe.shorthand = 0;
+ irqe.msi_redir_hint = false;
if (irqe.trig_mode == IOAPIC_EDGE_TRIG)
ioapic->irr &= ~(1 << irq);
@@ -103,12 +103,6 @@ static inline void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e,
MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
irq->vector = (e->msi.data &
MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT;
- /*
- * TODO Deal with RH bit of MSI message address
- * IF RH=1, then MSI delivers only to the processor with the
- * lowest interrupt priority among processors that can receive
- * the interrupt.
- */
if ((e->msi.address_lo & MSI_ADDR_REDIRECTION_LOWPRI) &&
(e->msi.address_lo & MSI_ADDR_DEST_MODE_LOGICAL))
irq->dest_mode = APIC_DEST_LOGICAL;
@@ -116,9 +110,8 @@ static inline void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e,
irq->dest_mode = APIC_DEST_PHYSICAL;
irq->trig_mode = (1 << MSI_DATA_TRIGGER_SHIFT) & e->msi.data;
irq->delivery_mode = e->msi.data & 0x700;
- if (e->msi.address_lo & MSI_ADDR_REDIRECTION_LOWPRI)
- pr_warn_once(
- "kvm: MSIs may not be correctly delivered with RH set.\n");
+ irq->msi_redir_hint = ((e->msi.address_lo
+ & MSI_ADDR_REDIRECTION_LOWPRI) > 0);
irq->level = 1;
irq->shorthand = 0;
}
@@ -892,6 +892,7 @@ static void apic_send_ipi(struct kvm_lapic *apic)
irq.level = icr_low & APIC_INT_ASSERT;
irq.trig_mode = icr_low & APIC_INT_LEVELTRIG;
irq.shorthand = icr_low & APIC_SHORT_MASK;
+ irq.msi_redir_hint = false;
if (apic_x2apic_mode(apic))
irq.dest_id = icr_high;
else
@@ -901,10 +902,11 @@ static void apic_send_ipi(struct kvm_lapic *apic)
apic_debug("icr_high 0x%x, icr_low 0x%x, "
"short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
- "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n",
+ "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x, "
+ "msi_redir_hint 0x%x\n",
icr_high, icr_low, irq.shorthand, irq.dest_id,
irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode,
- irq.vector);
+ irq.vector, irq.msi_redir_hint);
kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq, NULL);
}
@@ -5902,6 +5902,7 @@ static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid)
lapic_irq.shorthand = 0;
lapic_irq.dest_mode = 0;
lapic_irq.dest_id = apicid;
+ lapic_irq.msi_redir_hint = false;
lapic_irq.delivery_mode = APIC_DM_REMRD;
kvm_irq_delivery_to_apic(kvm, 0, &lapic_irq, NULL);
Signed-off-by: James Sullivan <sullivan.james.f@gmail.com> --- The following changes are added in this patch: * Initialize msi_redir_hint = true in kvm_set_msi_irq when RH=1 * Initialize msi_redir_hint = false otherwise * Added value of msi_redir_hint to debug message dump of IRQ in apic_send_ipi Changes since v1: * Squashed a number of smaller commits into this one commit, which adds and initializes the msi_redir_hint variable and extends existing debug messages to display its value. 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/include/asm/kvm_host.h | 1 + arch/x86/kvm/ioapic.c | 1 + arch/x86/kvm/irq_comm.c | 11 ++--------- arch/x86/kvm/lapic.c | 6 ++++-- arch/x86/kvm/x86.c | 1 + 5 files changed, 9 insertions(+), 11 deletions(-)