Upgrade to 4.4.50-rt62
[kvmfornfv.git] / kernel / drivers / irqchip / irq-gic-v3.c
index d7be6dd..e33c729 100644 (file)
@@ -142,7 +142,7 @@ static void gic_enable_redist(bool enable)
                        return; /* No PM support in this redistributor */
        }
 
-       while (count--) {
+       while (--count) {
                val = readl_relaxed(rbase + GICR_WAKER);
                if (enable ^ (val & GICR_WAKER_ChildrenAsleep))
                        break;
@@ -361,6 +361,13 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
                        if (static_key_true(&supports_deactivate))
                                gic_write_dir(irqnr);
 #ifdef CONFIG_SMP
+                       /*
+                        * Unlike GICv2, we don't need an smp_rmb() here.
+                        * The control dependency from gic_read_iar to
+                        * the ISB in gic_write_eoir is enough to ensure
+                        * that any shared data read by handle_IPI will
+                        * be read after the ACK.
+                        */
                        handle_IPI(irqnr, regs);
 #else
                        WARN_ONCE(true, "Unexpected SGI received!\n");
@@ -380,6 +387,15 @@ static void __init gic_dist_init(void)
        writel_relaxed(0, base + GICD_CTLR);
        gic_dist_wait_for_rwp();
 
+       /*
+        * Configure SPIs as non-secure Group-1. This will only matter
+        * if the GIC only has a single security state. This will not
+        * do the right thing if the kernel is running in secure mode,
+        * but that's not the intended use case anyway.
+        */
+       for (i = 32; i < gic_data.irq_nr; i += 32)
+               writel_relaxed(~0, base + GICD_IGROUPR + i / 8);
+
        gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp);
 
        /* Enable distributor with ARE, Group1 */
@@ -494,6 +510,9 @@ static void gic_cpu_init(void)
 
        rbase = gic_data_rdist_sgi_base();
 
+       /* Configure SGIs/PPIs as non-secure Group-1 */
+       writel_relaxed(~0, rbase + GICR_IGROUPR0);
+
        gic_cpu_config(rbase, gic_redist_wait_for_rwp);
 
        /* Give LPIs a spin */
@@ -525,7 +544,7 @@ static struct notifier_block gic_cpu_notifier = {
 static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
                                   unsigned long cluster_id)
 {
-       int cpu = *base_cpu;
+       int next_cpu, cpu = *base_cpu;
        unsigned long mpidr = cpu_logical_map(cpu);
        u16 tlist = 0;
 
@@ -539,9 +558,10 @@ static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
 
                tlist |= 1 << (mpidr & 0xf);
 
-               cpu = cpumask_next(cpu, mask);
-               if (cpu >= nr_cpu_ids)
+               next_cpu = cpumask_next(cpu, mask);
+               if (next_cpu >= nr_cpu_ids)
                        goto out;
+               cpu = next_cpu;
 
                mpidr = cpu_logical_map(cpu);