x86: don't change affinity with interrupt unmasked

With ->startup unmasking the IRQ, setting the affinity afterwards
without masking the IRQ again is invalid namely for MSI (address and
data can't be updated atomically and may - at least for MSI-X - be
cached while unmasked).

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

AMD IOMMU: only translate remapped IO-APIC RTEs

1aeb1156fa ("x86 don't change affinity with interrupt unmasked")
introducing RTE reads prior to the respective interrupt having got
enabled for the first time uncovered a bug in 2ca9fbd739 ("AMD IOMMU:
allocate IRTE entries instead of using a static mapping"): We obviously
shouldn't be translating RTEs for which remapping didn't get set up
yet.

Reported-by: Sander Eikelenboom <linux@eikelenboom.it>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>

master commit: 1aeb1156fa
master date: 2015-03-26 11:18:28 +0100
master commit: c33c51b81c
master date: 2015-04-24 12:06:26 +0200
This commit is contained in:
Jan Beulich committed 2015-05-19 11:54:12 +02:00
1 parent cb296dd085
commit 718f183bf4
2 files changed
+7 -4

No files matched your search

+3 -2
View File
@@ -1605,12 +1605,13 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
init_timer(&action->eoi_timer, irq_guest_eoi_timer_fn, desc, 0);
desc->status |= IRQ_GUEST;
desc->status &= ~IRQ_DISABLED;
desc->handler->startup(desc);
/* Attempt to bind the interrupt target to the correct CPU. */
if ( !opt_noirqbalance && (desc->handler->set_affinity != NULL) )
desc->handler->set_affinity(desc, cpumask_of(v->processor));
desc->status &= ~IRQ_DISABLED;
desc->handler->startup(desc);
}
else if ( !will_share || !action->shareable )
{
+4 -2
View File
@@ -365,15 +365,17 @@ unsigned int amd_iommu_read_ioapic_from_ire(
unsigned int apic, unsigned int reg)
{
unsigned int val = __io_apic_read(apic, reg);
unsigned int pin = (reg - 0x10) / 2;
unsigned int offset = ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx[pin];
if ( !(reg & 1) )
if ( !(reg & 1) && offset < INTREMAP_ENTRIES )
{
unsigned int offset = val & (INTREMAP_ENTRIES - 1);
u16 bdf = ioapic_sbdf[IO_APIC_ID(apic)].bdf;
u16 seg = ioapic_sbdf[IO_APIC_ID(apic)].seg;
u16 req_id = get_intremap_requestor_id(seg, bdf);
const u32 *entry = get_intremap_entry(seg, req_id, offset);
ASSERT(offset == (val & (INTREMAP_ENTRIES - 1)));
val &= ~(INTREMAP_ENTRIES - 1);
val |= get_field_from_reg_u32(*entry,
INT_REMAP_ENTRY_INTTYPE_MASK,
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.