Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 updates and fixes from Thomas Gleixner:

- Fix the (late) fallout from the vector management rework causing
hlist corruption and irq descriptor reference leaks caused by a
missing sanity check.

The straight forward fix triggered another long standing issue to
surface. The pre rework code hid the issue due to being way slower,
but now the chance that user space sees an EBUSY error return when
updating irq affinities is way higher, though quite a bunch of
userspace tools do not handle it properly despite the fact that EBUSY
could be returned for at least 10 years.

It turned out that the EBUSY return can be avoided completely by
utilizing the existing delayed affinity update mechanism for irq
remapped scenarios as well. That's a bit more error handling in the
kernel, but avoids fruitless fingerpointing discussions with tool
developers.

- Decouple PHYSICAL_MASK from AMD SME as its going to be required for
the upcoming Intel memory encryption support as well.

- Handle legacy device ACPI detection properly for newer platforms

- Fix the wrong argument ordering in the vector allocation tracepoint

- Simplify the IDT setup code for the APIC=n case

- Use the proper string helpers in the MTRR code

- Remove a stale unused VDSO source file

- Convert the microcode update lock to a raw spinlock as its used in
atomic context.

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/intel_rdt: Enable CMT and MBM on new Skylake stepping
x86/apic/vector: Print APIC control bits in debugfs
genirq/affinity: Defer affinity setting if irq chip is busy
x86/platform/uv: Use apic_ack_irq()
x86/ioapic: Use apic_ack_irq()
irq_remapping: Use apic_ack_irq()
x86/apic: Provide apic_ack_irq()
genirq/migration: Avoid out of line call if pending is not set
genirq/generic_pending: Do not lose pending affinity update
x86/apic/vector: Prevent hlist corruption and leaks
x86/vector: Fix the args of vector_alloc tracepoint
x86/idt: Simplify the idt_setup_apic_and_irq_gates()
x86/platform/uv: Remove extra parentheses
x86/mm: Decouple dynamic __PHYSICAL_MASK from AMD SME
x86: Mark native_set_p4d() as __always_inline
x86/microcode: Make the late update update_lock a raw lock for RT
x86/mtrr: Convert to use strncpy_from_user() helper
x86/mtrr: Convert to use match_string() helper
x86/vdso: Remove unused file
x86/i8237: Register device based on FADT legacy boot flag

+175 -79
+4
arch/x86/Kconfig
··· 334 334 config FIX_EARLYCON_MEM 335 335 def_bool y 336 336 337 + config DYNAMIC_PHYSICAL_MASK 338 + bool 339 + 337 340 config PGTABLE_LEVELS 338 341 int 339 342 default 5 if X86_5LEVEL ··· 1489 1486 config AMD_MEM_ENCRYPT 1490 1487 bool "AMD Secure Memory Encryption (SME) support" 1491 1488 depends on X86_64 && CPU_SUP_AMD 1489 + select DYNAMIC_PHYSICAL_MASK 1492 1490 ---help--- 1493 1491 Say yes to enable support for the encryption of system memory. 1494 1492 This requires an AMD processor that supports Secure Memory
+5
arch/x86/boot/compressed/kaslr_64.c
··· 69 69 /* The top level page table entry pointer. */ 70 70 static unsigned long top_level_pgt; 71 71 72 + phys_addr_t physical_mask = (1ULL << __PHYSICAL_MASK_SHIFT) - 1; 73 + 72 74 /* 73 75 * Mapping information structure passed to kernel_ident_mapping_init(). 74 76 * Due to relocation, pointers must be assigned at run time not build time. ··· 82 80 { 83 81 /* If running as an SEV guest, the encryption mask is required. */ 84 82 set_sev_encryption_mask(); 83 + 84 + /* Exclude the encryption mask from __PHYSICAL_MASK */ 85 + physical_mask &= ~sme_me_mask; 85 86 86 87 /* Init mapping_info with run-time function/buffer pointers. */ 87 88 mapping_info.alloc_pgt_page = alloc_pgt_page;
+2
arch/x86/include/asm/apic.h
··· 436 436 437 437 #endif /* CONFIG_X86_LOCAL_APIC */ 438 438 439 + extern void apic_ack_irq(struct irq_data *data); 440 + 439 441 static inline void ack_APIC_irq(void) 440 442 { 441 443 /*
+7 -1
arch/x86/include/asm/page_types.h
··· 17 17 #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) 18 18 #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) 19 19 20 - #define __PHYSICAL_MASK ((phys_addr_t)(__sme_clr((1ULL << __PHYSICAL_MASK_SHIFT) - 1))) 21 20 #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) 22 21 23 22 /* Cast *PAGE_MASK to a signed type so that it is sign-extended if ··· 53 54 #endif /* CONFIG_X86_64 */ 54 55 55 56 #ifndef __ASSEMBLY__ 57 + 58 + #ifdef CONFIG_DYNAMIC_PHYSICAL_MASK 59 + extern phys_addr_t physical_mask; 60 + #define __PHYSICAL_MASK physical_mask 61 + #else 62 + #define __PHYSICAL_MASK ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1)) 63 + #endif 56 64 57 65 extern int devmem_is_allowed(unsigned long pagenr); 58 66
+2 -2
arch/x86/include/asm/pgtable_64.h
··· 216 216 } 217 217 #endif 218 218 219 - static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d) 219 + static __always_inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d) 220 220 { 221 221 pgd_t pgd; 222 222 ··· 230 230 *p4dp = native_make_p4d(native_pgd_val(pgd)); 231 231 } 232 232 233 - static inline void native_p4d_clear(p4d_t *p4d) 233 + static __always_inline void native_p4d_clear(p4d_t *p4d) 234 234 { 235 235 native_set_p4d(p4d, native_make_p4d(0)); 236 236 }
+1 -1
arch/x86/include/asm/trace/irq_vectors.h
··· 236 236 TP_PROTO(unsigned int irq, unsigned int vector, bool reserved, 237 237 int ret), 238 238 239 - TP_ARGS(irq, vector, ret, reserved), 239 + TP_ARGS(irq, vector, reserved, ret), 240 240 241 241 TP_STRUCT__entry( 242 242 __field( unsigned int, irq )
+1
arch/x86/include/asm/x86_init.h
··· 301 301 extern void x86_early_init_platform_quirks(void); 302 302 extern void x86_init_noop(void); 303 303 extern void x86_init_uint_noop(unsigned int unused); 304 + extern bool x86_pnpbios_disabled(void); 304 305 305 306 #endif
+1 -1
arch/x86/kernel/apic/io_apic.c
··· 1851 1851 * intr-remapping table entry. Hence for the io-apic 1852 1852 * EOI we use the pin number. 1853 1853 */ 1854 - ack_APIC_irq(); 1854 + apic_ack_irq(irq_data); 1855 1855 eoi_ioapic_pin(data->entry.vector, data); 1856 1856 } 1857 1857
+30 -15
arch/x86/kernel/apic/vector.c
··· 235 235 if (vector && cpu_online(cpu) && cpumask_test_cpu(cpu, dest)) 236 236 return 0; 237 237 238 + /* 239 + * Careful here. @apicd might either have move_in_progress set or 240 + * be enqueued for cleanup. Assigning a new vector would either 241 + * leave a stale vector on some CPU around or in case of a pending 242 + * cleanup corrupt the hlist. 243 + */ 244 + if (apicd->move_in_progress || !hlist_unhashed(&apicd->clist)) 245 + return -EBUSY; 246 + 238 247 vector = irq_matrix_alloc(vector_matrix, dest, resvd, &cpu); 239 248 if (vector > 0) 240 249 apic_update_vector(irqd, vector, cpu); ··· 588 579 static void x86_vector_debug_show(struct seq_file *m, struct irq_domain *d, 589 580 struct irq_data *irqd, int ind) 590 581 { 591 - unsigned int cpu, vector, prev_cpu, prev_vector; 592 - struct apic_chip_data *apicd; 582 + struct apic_chip_data apicd; 593 583 unsigned long flags; 594 584 int irq; 595 585 ··· 604 596 return; 605 597 } 606 598 607 - apicd = irqd->chip_data; 608 - if (!apicd) { 599 + if (!irqd->chip_data) { 609 600 seq_printf(m, "%*sVector: Not assigned\n", ind, ""); 610 601 return; 611 602 } 612 603 613 604 raw_spin_lock_irqsave(&vector_lock, flags); 614 - cpu = apicd->cpu; 615 - vector = apicd->vector; 616 - prev_cpu = apicd->prev_cpu; 617 - prev_vector = apicd->prev_vector; 605 + memcpy(&apicd, irqd->chip_data, sizeof(apicd)); 618 606 raw_spin_unlock_irqrestore(&vector_lock, flags); 619 - seq_printf(m, "%*sVector: %5u\n", ind, "", vector); 620 - seq_printf(m, "%*sTarget: %5u\n", ind, "", cpu); 621 - if (prev_vector) { 622 - seq_printf(m, "%*sPrevious vector: %5u\n", ind, "", prev_vector); 623 - seq_printf(m, "%*sPrevious target: %5u\n", ind, "", prev_cpu); 607 + 608 + seq_printf(m, "%*sVector: %5u\n", ind, "", apicd.vector); 609 + seq_printf(m, "%*sTarget: %5u\n", ind, "", apicd.cpu); 610 + if (apicd.prev_vector) { 611 + seq_printf(m, "%*sPrevious vector: %5u\n", ind, "", apicd.prev_vector); 612 + seq_printf(m, "%*sPrevious target: %5u\n", ind, "", apicd.prev_cpu); 624 613 } 614 + seq_printf(m, "%*smove_in_progress: %u\n", ind, "", apicd.move_in_progress ? 1 : 0); 615 + seq_printf(m, "%*sis_managed: %u\n", ind, "", apicd.is_managed ? 1 : 0); 616 + seq_printf(m, "%*scan_reserve: %u\n", ind, "", apicd.can_reserve ? 1 : 0); 617 + seq_printf(m, "%*shas_reserved: %u\n", ind, "", apicd.has_reserved ? 1 : 0); 618 + seq_printf(m, "%*scleanup_pending: %u\n", ind, "", !hlist_unhashed(&apicd.clist)); 625 619 } 626 620 #endif 627 621 ··· 810 800 return 1; 811 801 } 812 802 803 + void apic_ack_irq(struct irq_data *irqd) 804 + { 805 + irq_move_irq(irqd); 806 + ack_APIC_irq(); 807 + } 808 + 813 809 void apic_ack_edge(struct irq_data *irqd) 814 810 { 815 811 irq_complete_move(irqd_cfg(irqd)); 816 - irq_move_irq(irqd); 817 - ack_APIC_irq(); 812 + apic_ack_irq(irqd); 818 813 } 819 814 820 815 static struct irq_chip lapic_controller = {
+2
arch/x86/kernel/cpu/intel_rdt.c
··· 845 845 case INTEL_FAM6_SKYLAKE_X: 846 846 if (boot_cpu_data.x86_stepping <= 4) 847 847 set_rdt_options("!cmt,!mbmtotal,!mbmlocal,!l3cat"); 848 + else 849 + set_rdt_options("!l3cat"); 848 850 } 849 851 } 850 852
+3 -3
arch/x86/kernel/cpu/microcode/core.c
··· 70 70 /* 71 71 * Serialize late loading so that CPUs get updated one-by-one. 72 72 */ 73 - static DEFINE_SPINLOCK(update_lock); 73 + static DEFINE_RAW_SPINLOCK(update_lock); 74 74 75 75 struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; 76 76 ··· 560 560 if (__wait_for_cpus(&late_cpus_in, NSEC_PER_SEC)) 561 561 return -1; 562 562 563 - spin_lock(&update_lock); 563 + raw_spin_lock(&update_lock); 564 564 apply_microcode_local(&err); 565 - spin_unlock(&update_lock); 565 + raw_spin_unlock(&update_lock); 566 566 567 567 /* siblings return UCODE_OK because their engine got updated already */ 568 568 if (err > UCODE_NFOUND) {
+12 -21
arch/x86/kernel/cpu/mtrr/if.c
··· 106 106 107 107 memset(line, 0, LINE_SIZE); 108 108 109 - length = len; 110 - length--; 111 - 112 - if (length > LINE_SIZE - 1) 113 - length = LINE_SIZE - 1; 114 - 109 + length = strncpy_from_user(line, buf, LINE_SIZE - 1); 115 110 if (length < 0) 116 - return -EINVAL; 117 - 118 - if (copy_from_user(line, buf, length)) 119 - return -EFAULT; 111 + return length; 120 112 121 113 linelen = strlen(line); 122 114 ptr = line + linelen - 1; ··· 141 149 return -EINVAL; 142 150 ptr = skip_spaces(ptr + 5); 143 151 144 - for (i = 0; i < MTRR_NUM_TYPES; ++i) { 145 - if (strcmp(ptr, mtrr_strings[i])) 146 - continue; 147 - base >>= PAGE_SHIFT; 148 - size >>= PAGE_SHIFT; 149 - err = mtrr_add_page((unsigned long)base, (unsigned long)size, i, true); 150 - if (err < 0) 151 - return err; 152 - return len; 153 - } 154 - return -EINVAL; 152 + i = match_string(mtrr_strings, MTRR_NUM_TYPES, ptr); 153 + if (i < 0) 154 + return i; 155 + 156 + base >>= PAGE_SHIFT; 157 + size >>= PAGE_SHIFT; 158 + err = mtrr_add_page((unsigned long)base, (unsigned long)size, i, true); 159 + if (err < 0) 160 + return err; 161 + return len; 155 162 } 156 163 157 164 static long
+25
arch/x86/kernel/i8237.c
··· 9 9 * your option) any later version. 10 10 */ 11 11 12 + #include <linux/dmi.h> 12 13 #include <linux/init.h> 13 14 #include <linux/syscore_ops.h> 14 15 15 16 #include <asm/dma.h> 17 + #include <asm/x86_init.h> 16 18 17 19 /* 18 20 * This module just handles suspend/resume issues with the ··· 51 49 52 50 static int __init i8237A_init_ops(void) 53 51 { 52 + /* 53 + * From SKL PCH onwards, the legacy DMA device is removed in which the 54 + * I/O ports (81h-83h, 87h, 89h-8Bh, 8Fh) related to it are removed 55 + * as well. All removed ports must return 0xff for a inb() request. 56 + * 57 + * Note: DMA_PAGE_2 (port 0x81) should not be checked for detecting 58 + * the presence of DMA device since it may be used by BIOS to decode 59 + * LPC traffic for POST codes. Original LPC only decodes one byte of 60 + * port 0x80 but some BIOS may choose to enhance PCH LPC port 0x8x 61 + * decoding. 62 + */ 63 + if (dma_inb(DMA_PAGE_0) == 0xFF) 64 + return -ENODEV; 65 + 66 + /* 67 + * It is not required to load this driver as newer SoC may not 68 + * support 8237 DMA or bus mastering from LPC. Platform firmware 69 + * must announce the support for such legacy devices via 70 + * ACPI_FADT_LEGACY_DEVICES field in FADT table. 71 + */ 72 + if (x86_pnpbios_disabled() && dmi_get_bios_year() >= 2017) 73 + return -ENODEV; 74 + 54 75 register_syscore_ops(&i8237_syscore_ops); 55 76 return 0; 56 77 }
+2 -5
arch/x86/kernel/idt.c
··· 317 317 set_intr_gate(i, entry); 318 318 } 319 319 320 - for_each_clear_bit_from(i, system_vectors, NR_VECTORS) { 321 320 #ifdef CONFIG_X86_LOCAL_APIC 321 + for_each_clear_bit_from(i, system_vectors, NR_VECTORS) { 322 322 set_bit(i, system_vectors); 323 323 set_intr_gate(i, spurious_interrupt); 324 - #else 325 - entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR); 326 - set_intr_gate(i, entry); 327 - #endif 328 324 } 325 + #endif 329 326 } 330 327 331 328 /**
+6 -1
arch/x86/kernel/platform-quirks.c
··· 33 33 x86_platform.set_legacy_features(); 34 34 } 35 35 36 + bool __init x86_pnpbios_disabled(void) 37 + { 38 + return x86_platform.legacy.devices.pnpbios == 0; 39 + } 40 + 36 41 #if defined(CONFIG_PNPBIOS) 37 42 bool __init arch_pnpbios_disabled(void) 38 43 { 39 - return x86_platform.legacy.devices.pnpbios == 0; 44 + return x86_pnpbios_disabled(); 40 45 } 41 46 #endif
+3
arch/x86/mm/mem_encrypt_identity.c
··· 527 527 /* SEV state cannot be controlled by a command line option */ 528 528 sme_me_mask = me_mask; 529 529 sev_enabled = true; 530 + physical_mask &= ~sme_me_mask; 530 531 return; 531 532 } 532 533 ··· 562 561 sme_me_mask = 0; 563 562 else 564 563 sme_me_mask = active_by_default ? me_mask : 0; 564 + 565 + physical_mask &= ~sme_me_mask; 565 566 }
+5
arch/x86/mm/pgtable.c
··· 8 8 #include <asm/fixmap.h> 9 9 #include <asm/mtrr.h> 10 10 11 + #ifdef CONFIG_DYNAMIC_PHYSICAL_MASK 12 + phys_addr_t physical_mask __ro_after_init = (1ULL << __PHYSICAL_MASK_SHIFT) - 1; 13 + EXPORT_SYMBOL(physical_mask); 14 + #endif 15 + 11 16 #define PGALLOC_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO) 12 17 13 18 #ifdef CONFIG_HIGHPTE
+1 -1
arch/x86/platform/uv/tlb_uv.c
··· 615 615 616 616 /* spin on the status MMR, waiting for it to go idle */ 617 617 while (descriptor_stat != UV2H_DESC_IDLE) { 618 - if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT)) { 618 + if (descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT) { 619 619 /* 620 620 * A h/w bug on the destination side may 621 621 * have prevented the message being marked
+1 -6
arch/x86/platform/uv/uv_irq.c
··· 47 47 48 48 static void uv_noop(struct irq_data *data) { } 49 49 50 - static void uv_ack_apic(struct irq_data *data) 51 - { 52 - ack_APIC_irq(); 53 - } 54 - 55 50 static int 56 51 uv_set_irq_affinity(struct irq_data *data, const struct cpumask *mask, 57 52 bool force) ··· 68 73 .name = "UV-CORE", 69 74 .irq_mask = uv_noop, 70 75 .irq_unmask = uv_noop, 71 - .irq_eoi = uv_ack_apic, 76 + .irq_eoi = apic_ack_irq, 72 77 .irq_set_affinity = uv_set_irq_affinity, 73 78 }; 74 79
+1 -1
drivers/iommu/amd_iommu.c
··· 4385 4385 4386 4386 static struct irq_chip amd_ir_chip = { 4387 4387 .name = "AMD-IR", 4388 - .irq_ack = ir_ack_apic_edge, 4388 + .irq_ack = apic_ack_irq, 4389 4389 .irq_set_affinity = amd_ir_set_affinity, 4390 4390 .irq_set_vcpu_affinity = amd_ir_set_vcpu_affinity, 4391 4391 .irq_compose_msi_msg = ir_compose_msi_msg,
+1 -1
drivers/iommu/intel_irq_remapping.c
··· 1223 1223 1224 1224 static struct irq_chip intel_ir_chip = { 1225 1225 .name = "INTEL-IR", 1226 - .irq_ack = ir_ack_apic_edge, 1226 + .irq_ack = apic_ack_irq, 1227 1227 .irq_set_affinity = intel_ir_set_affinity, 1228 1228 .irq_compose_msi_msg = intel_ir_compose_msi_msg, 1229 1229 .irq_set_vcpu_affinity = intel_ir_set_vcpu_affinity,
-5
drivers/iommu/irq_remapping.c
··· 156 156 panic(msg); 157 157 } 158 158 159 - void ir_ack_apic_edge(struct irq_data *data) 160 - { 161 - ack_APIC_irq(); 162 - } 163 - 164 159 /** 165 160 * irq_remapping_get_ir_irq_domain - Get the irqdomain associated with the IOMMU 166 161 * device serving request @info
-2
drivers/iommu/irq_remapping.h
··· 65 65 extern struct irq_remap_ops intel_irq_remap_ops; 66 66 extern struct irq_remap_ops amd_iommu_irq_ops; 67 67 68 - extern void ir_ack_apic_edge(struct irq_data *data); 69 - 70 68 #else /* CONFIG_IRQ_REMAP */ 71 69 72 70 #define irq_remapping_enabled 0
+6 -1
include/linux/irq.h
··· 552 552 #endif 553 553 554 554 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) 555 - void irq_move_irq(struct irq_data *data); 555 + void __irq_move_irq(struct irq_data *data); 556 + static inline void irq_move_irq(struct irq_data *data) 557 + { 558 + if (unlikely(irqd_is_setaffinity_pending(data))) 559 + __irq_move_irq(data); 560 + } 556 561 void irq_move_masked_irq(struct irq_data *data); 557 562 void irq_force_complete_move(struct irq_desc *desc); 558 563 #else
+35 -2
kernel/irq/manage.c
··· 205 205 return ret; 206 206 } 207 207 208 + #ifdef CONFIG_GENERIC_PENDING_IRQ 209 + static inline int irq_set_affinity_pending(struct irq_data *data, 210 + const struct cpumask *dest) 211 + { 212 + struct irq_desc *desc = irq_data_to_desc(data); 213 + 214 + irqd_set_move_pending(data); 215 + irq_copy_pending(desc, dest); 216 + return 0; 217 + } 218 + #else 219 + static inline int irq_set_affinity_pending(struct irq_data *data, 220 + const struct cpumask *dest) 221 + { 222 + return -EBUSY; 223 + } 224 + #endif 225 + 226 + static int irq_try_set_affinity(struct irq_data *data, 227 + const struct cpumask *dest, bool force) 228 + { 229 + int ret = irq_do_set_affinity(data, dest, force); 230 + 231 + /* 232 + * In case that the underlying vector management is busy and the 233 + * architecture supports the generic pending mechanism then utilize 234 + * this to avoid returning an error to user space. 235 + */ 236 + if (ret == -EBUSY && !force) 237 + ret = irq_set_affinity_pending(data, dest); 238 + return ret; 239 + } 240 + 208 241 int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask, 209 242 bool force) 210 243 { ··· 248 215 if (!chip || !chip->irq_set_affinity) 249 216 return -EINVAL; 250 217 251 - if (irq_can_move_pcntxt(data)) { 252 - ret = irq_do_set_affinity(data, mask, force); 218 + if (irq_can_move_pcntxt(data) && !irqd_is_setaffinity_pending(data)) { 219 + ret = irq_try_set_affinity(data, mask, force); 253 220 } else { 254 221 irqd_set_move_pending(data); 255 222 irq_copy_pending(desc, mask);
+19 -10
kernel/irq/migration.c
··· 38 38 void irq_move_masked_irq(struct irq_data *idata) 39 39 { 40 40 struct irq_desc *desc = irq_data_to_desc(idata); 41 - struct irq_chip *chip = desc->irq_data.chip; 41 + struct irq_data *data = &desc->irq_data; 42 + struct irq_chip *chip = data->chip; 42 43 43 - if (likely(!irqd_is_setaffinity_pending(&desc->irq_data))) 44 + if (likely(!irqd_is_setaffinity_pending(data))) 44 45 return; 45 46 46 - irqd_clr_move_pending(&desc->irq_data); 47 + irqd_clr_move_pending(data); 47 48 48 49 /* 49 50 * Paranoia: cpu-local interrupts shouldn't be calling in here anyway. 50 51 */ 51 - if (irqd_is_per_cpu(&desc->irq_data)) { 52 + if (irqd_is_per_cpu(data)) { 52 53 WARN_ON(1); 53 54 return; 54 55 } ··· 74 73 * For correct operation this depends on the caller 75 74 * masking the irqs. 76 75 */ 77 - if (cpumask_any_and(desc->pending_mask, cpu_online_mask) < nr_cpu_ids) 78 - irq_do_set_affinity(&desc->irq_data, desc->pending_mask, false); 76 + if (cpumask_any_and(desc->pending_mask, cpu_online_mask) < nr_cpu_ids) { 77 + int ret; 79 78 79 + ret = irq_do_set_affinity(data, desc->pending_mask, false); 80 + /* 81 + * If the there is a cleanup pending in the underlying 82 + * vector management, reschedule the move for the next 83 + * interrupt. Leave desc->pending_mask intact. 84 + */ 85 + if (ret == -EBUSY) { 86 + irqd_set_move_pending(data); 87 + return; 88 + } 89 + } 80 90 cpumask_clear(desc->pending_mask); 81 91 } 82 92 83 - void irq_move_irq(struct irq_data *idata) 93 + void __irq_move_irq(struct irq_data *idata) 84 94 { 85 95 bool masked; 86 96 ··· 101 89 * disabled. So we avoid an "#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY" here. 102 90 */ 103 91 idata = irq_desc_get_irq_data(irq_data_to_desc(idata)); 104 - 105 - if (likely(!irqd_is_setaffinity_pending(idata))) 106 - return; 107 92 108 93 if (unlikely(irqd_irq_disabled(idata))) 109 94 return;