mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
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 RTEs1aeb1156fa("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 in2ca9fbd739("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:1aeb1156famaster date: 2015-03-26 11:18:28 +0100 master commit:c33c51b81cmaster date: 2015-04-24 12:06:26 +0200
This commit is contained in:
1 parent
cb296dd085
commit
718f183bf4
2 files changed
+7
-4
No files matched your search
+3
-2
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||