Skip to content

Commit

Permalink
iommu/vt-d: Don't clobber posted vCPU IRTE when host IRQ affinity cha…
Browse files Browse the repository at this point in the history
…nges

commit 688124c upstream.

Don't overwrite an IRTE that is posting IRQs to a vCPU with a posted MSI
entry if the host IRQ affinity happens to change.  If/when the IRTE is
reverted back to "host mode", it will be reconfigured as a posted MSI or
remapped entry as appropriate.

Drop the "mode" field, which doesn't differentiate between posted MSIs and
posted vCPUs, in favor of a dedicated posted_vcpu flag.  Note!  The two
posted_{msi,vcpu} flags are intentionally not mutually exclusive; an IRTE
can transition between posted MSI and posted vCPU.

Fixes: ed1e48e ("iommu/vt-d: Enable posted mode for device MSIs")
Cc: stable@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Link: https://lore.kernel.org/r/20250315025135.2365846-3-seanjc@google.com
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Sean Christopherson authored and Greg Kroah-Hartman committed Apr 20, 2025
1 parent c95a438 commit e953e11
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions drivers/iommu/intel/irq_remapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@
#include "../iommu-pages.h"
#include "cap_audit.h"

enum irq_mode {
IRQ_REMAPPING,
IRQ_POSTING,
};

struct ioapic_scope {
struct intel_iommu *iommu;
unsigned int id;
Expand All @@ -50,8 +45,8 @@ struct irq_2_iommu {
u16 irte_index;
u16 sub_handle;
u8 irte_mask;
enum irq_mode mode;
bool posted_msi;
bool posted_vcpu;
};

struct intel_ir_data {
Expand Down Expand Up @@ -139,7 +134,6 @@ static int alloc_irte(struct intel_iommu *iommu,
irq_iommu->irte_index = index;
irq_iommu->sub_handle = 0;
irq_iommu->irte_mask = mask;
irq_iommu->mode = IRQ_REMAPPING;
}
raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);

Expand Down Expand Up @@ -194,8 +188,6 @@ static int modify_irte(struct irq_2_iommu *irq_iommu,

rc = qi_flush_iec(iommu, index, 0);

/* Update iommu mode according to the IRTE mode */
irq_iommu->mode = irte->pst ? IRQ_POSTING : IRQ_REMAPPING;
raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);

return rc;
Expand Down Expand Up @@ -1177,9 +1169,18 @@ static void __intel_ir_reconfigure_irte(struct irq_data *irqd, bool force_host)
{
struct intel_ir_data *ir_data = irqd->chip_data;

/*
* Don't modify IRTEs for IRQs that are being posted to vCPUs if the
* host CPU affinity changes.
*/
if (ir_data->irq_2_iommu.posted_vcpu && !force_host)
return;

ir_data->irq_2_iommu.posted_vcpu = false;

if (ir_data->irq_2_iommu.posted_msi)
intel_ir_reconfigure_irte_posted(irqd);
else if (force_host || ir_data->irq_2_iommu.mode == IRQ_REMAPPING)
else
modify_irte(&ir_data->irq_2_iommu, &ir_data->irte_entry);
}

Expand Down Expand Up @@ -1274,6 +1275,7 @@ static int intel_ir_set_vcpu_affinity(struct irq_data *data, void *info)
irte_pi.pda_h = (vcpu_pi_info->pi_desc_addr >> 32) &
~(-1UL << PDA_HIGH_BIT);

ir_data->irq_2_iommu.posted_vcpu = true;
modify_irte(&ir_data->irq_2_iommu, &irte_pi);
}

Expand Down Expand Up @@ -1501,6 +1503,9 @@ static void intel_irq_remapping_deactivate(struct irq_domain *domain,
struct intel_ir_data *data = irq_data->chip_data;
struct irte entry;

WARN_ON_ONCE(data->irq_2_iommu.posted_vcpu);
data->irq_2_iommu.posted_vcpu = false;

memset(&entry, 0, sizeof(entry));
modify_irte(&data->irq_2_iommu, &entry);
}
Expand Down

0 comments on commit e953e11

Please sign in to comment.