Merge tag 'irq-core-2020-03-30' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 31 Mar 2020 00:35:14 +0000 (17:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 31 Mar 2020 00:35:14 +0000 (17:35 -0700)
Pull irq updates from Thomas Gleixner:
 "Updates for the interrupt subsystem:

  Treewide:

    - Cleanup of setup_irq() which is not longer required because the
      memory allocator is available early.

      Most cleanup changes come through the various maintainer trees, so
      the final removal of setup_irq() is postponed towards the end of
      the merge window.

  Core:

    - Protection against unsafe invocation of interrupt handlers and
      unsafe interrupt injection including a fixup of the offending
      PCI/AER error injection mechanism.

      Invoking interrupt handlers from arbitrary contexts, i.e. outside
      of an actual interrupt, can cause inconsistent state on the
      fragile x86 interrupt affinity changing hardware trainwreck.

  Drivers:

    - Second wave of support for the new ARM GICv4.1

    - Multi-instance support for Xilinx and PLIC interrupt controllers

    - CPU-Hotplug support for PLIC

    - The obligatory new driver for X1000 TCU

    - Enhancements, cleanups and fixes all over the place"

* tag 'irq-core-2020-03-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (58 commits)
  unicore32: Replace setup_irq() by request_irq()
  sh: Replace setup_irq() by request_irq()
  hexagon: Replace setup_irq() by request_irq()
  c6x: Replace setup_irq() by request_irq()
  alpha: Replace setup_irq() by request_irq()
  irqchip/gic-v4.1: Eagerly vmap vPEs
  irqchip/gic-v4.1: Add VSGI property setup
  irqchip/gic-v4.1: Add VSGI allocation/teardown
  irqchip/gic-v4.1: Move doorbell management to the GICv4 abstraction layer
  irqchip/gic-v4.1: Plumb set_vcpu_affinity SGI callbacks
  irqchip/gic-v4.1: Plumb get/set_irqchip_state SGI callbacks
  irqchip/gic-v4.1: Plumb mask/unmask SGI callbacks
  irqchip/gic-v4.1: Add initial SGI configuration
  irqchip/gic-v4.1: Plumb skeletal VSGI irqchip
  irqchip/stm32: Retrigger both in eoi and unmask callbacks
  irqchip/gic-v3: Move irq_domain_update_bus_token to after checking for NULL domain
  irqchip/xilinx: Do not call irq_set_default_host()
  irqchip/xilinx: Enable generic irq multi handler
  irqchip/xilinx: Fill error code when irq domain registration fails
  irqchip/xilinx: Add support for multiple instances
  ...

1  2 
arch/x86/Kconfig
arch/x86/kernel/apic/vector.c
drivers/irqchip/irq-gic-v3.c

diff --combined arch/x86/Kconfig
@@@ -128,6 -128,7 +128,7 @@@ config X8
        select GENERIC_GETTIMEOFDAY
        select GENERIC_VDSO_TIME_NS
        select GUP_GET_PTE_LOW_HIGH             if X86_PAE
+       select HARDIRQS_SW_RESEND
        select HARDLOCKUP_CHECK_TIMESTAMP       if X86_64
        select HAVE_ACPI_APEI                   if ACPI
        select HAVE_ACPI_APEI_NMI               if ACPI
@@@ -1875,6 -1876,7 +1876,6 @@@ config X86_SMA
  
  config X86_UMIP
        def_bool y
 -      depends on CPU_SUP_INTEL || CPU_SUP_AMD
        prompt "User Mode Instruction Prevention" if EXPERT
        ---help---
          User Mode Instruction Prevention (UMIP) is a security feature in
@@@ -557,6 -557,12 +557,12 @@@ static int x86_vector_alloc_irqs(struc
                irqd->hwirq = virq + i;
                irqd_set_single_target(irqd);
                /*
+                * Prevent that any of these interrupts is invoked in
+                * non interrupt context via e.g. generic_handle_irq()
+                * as that can corrupt the affinity move state.
+                */
+               irqd_set_handle_enforce_irqctx(irqd);
+               /*
                 * Legacy vectors are already assigned when the IOAPIC
                 * takes them over. They stay on the same vector. This is
                 * required for check_timer() to work correctly as it might
@@@ -838,15 -844,13 +844,15 @@@ static void free_moved_vector(struct ap
        bool managed = apicd->is_managed;
  
        /*
 -       * This should never happen. Managed interrupts are not
 -       * migrated except on CPU down, which does not involve the
 -       * cleanup vector. But try to keep the accounting correct
 -       * nevertheless.
 +       * Managed interrupts are usually not migrated away
 +       * from an online CPU, but CPU isolation 'managed_irq'
 +       * can make that happen.
 +       * 1) Activation does not take the isolation into account
 +       *    to keep the code simple
 +       * 2) Migration away from an isolated CPU can happen when
 +       *    a non-isolated CPU which is in the calculated
 +       *    affinity mask comes online.
         */
 -      WARN_ON_ONCE(managed);
 -
        trace_vector_free_moved(apicd->irq, cpu, vector, managed);
        irq_matrix_free(vector_matrix, cpu, vector, managed);
        per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
@@@ -34,7 -34,6 +34,7 @@@
  #define GICD_INT_NMI_PRI      (GICD_INT_DEF_PRI & ~0x80)
  
  #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996   (1ULL << 0)
 +#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1)
  
  struct redist_region {
        void __iomem            *redist_base;
@@@ -724,6 -723,7 +724,7 @@@ static void __init gic_dist_init(void
        unsigned int i;
        u64 affinity;
        void __iomem *base = gic_data.dist_base;
+       u32 val;
  
        /* Disable the distributor */
        writel_relaxed(0, base + GICD_CTLR);
        /* Now do the common stuff, and wait for the distributor to drain */
        gic_dist_config(base, GIC_LINE_NR, gic_dist_wait_for_rwp);
  
+       val = GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1;
+       if (gic_data.rdists.gicd_typer2 & GICD_TYPER2_nASSGIcap) {
+               pr_info("Enabling SGIs without active state\n");
+               val |= GICD_CTLR_nASSGIreq;
+       }
        /* Enable distributor with ARE, Group1 */
-       writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1,
-                      base + GICD_CTLR);
+       writel_relaxed(val, base + GICD_CTLR);
  
        /*
         * Set all global interrupts to the boot CPU only. ARE must be
@@@ -829,6 -834,7 +835,7 @@@ static int __gic_populate_rdist(struct 
        typer = gic_read_typer(ptr + GICR_TYPER);
        if ((typer >> 32) == aff) {
                u64 offset = ptr - region->redist_base;
+               raw_spin_lock_init(&gic_data_rdist()->rd_lock);
                gic_data_rdist_rd_base() = ptr;
                gic_data_rdist()->phys_base = region->phys_base + offset;
  
@@@ -1465,15 -1471,6 +1472,15 @@@ static bool gic_enable_quirk_msm8996(vo
        return true;
  }
  
 +static bool gic_enable_quirk_cavium_38539(void *data)
 +{
 +      struct gic_chip_data *d = data;
 +
 +      d->flags |= FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539;
 +
 +      return true;
 +}
 +
  static bool gic_enable_quirk_hip06_07(void *data)
  {
        struct gic_chip_data *d = data;
@@@ -1513,19 -1510,6 +1520,19 @@@ static const struct gic_quirk gic_quirk
                .init   = gic_enable_quirk_hip06_07,
        },
        {
 +              /*
 +               * Reserved register accesses generate a Synchronous
 +               * External Abort. This erratum applies to:
 +               * - ThunderX: CN88xx
 +               * - OCTEON TX: CN83xx, CN81xx
 +               * - OCTEON TX2: CN93xx, CN96xx, CN98xx, CNF95xx*
 +               */
 +              .desc   = "GICv3: Cavium erratum 38539",
 +              .iidr   = 0xa000034c,
 +              .mask   = 0xe8f00fff,
 +              .init   = gic_enable_quirk_cavium_38539,
 +      },
 +      {
        }
  };
  
@@@ -1600,16 -1584,10 +1607,15 @@@ static int __init gic_init_bases(void _
        pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32);
        pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR);
  
 -      gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2);
 +      /*
 +       * ThunderX1 explodes on reading GICD_TYPER2, in violation of the
 +       * architecture spec (which says that reserved registers are RES0).
 +       */
 +      if (!(gic_data.flags & FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539))
 +              gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2);
  
        gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops,
                                                 &gic_data);
-       irq_domain_update_bus_token(gic_data.domain, DOMAIN_BUS_WIRED);
        gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
        gic_data.rdists.has_rvpeid = true;
        gic_data.rdists.has_vlpis = true;
                goto out_free;
        }
  
+       irq_domain_update_bus_token(gic_data.domain, DOMAIN_BUS_WIRED);
        gic_data.has_rss = !!(typer & GICD_TYPER_RSS);
        pr_info("Distributor has %sRange Selector support\n",
                gic_data.has_rss ? "" : "no ");
@@@ -1785,6 -1765,7 +1793,7 @@@ static void __init gic_of_setup_kvm_inf
                gic_v3_kvm_info.vcpu = r;
  
        gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis;
+       gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
        gic_set_kvm_info(&gic_v3_kvm_info);
  }
  
@@@ -2100,6 -2081,7 +2109,7 @@@ static void __init gic_acpi_setup_kvm_i
        }
  
        gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis;
+       gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid;
        gic_set_kvm_info(&gic_v3_kvm_info);
  }