@@ -2602,6 +2602,28 @@ void fixup_irqs(const cpumask_t *mask, bool verbose)
&cpu_online_map);
}
+ if ( desc->arch.move_in_progress &&
+ !cpumask_test_cpu(cpu, &cpu_online_map) &&
+ cpumask_test_cpu(cpu, desc->arch.old_cpu_mask) )
+ {
+ /*
+ * This CPU is going offline, remove it from ->arch.old_cpu_mask
+ * and possibly release the old vector if the old mask becomes
+ * empty.
+ *
+ * Note cleaning ->arch.old_cpu_mask is required if the CPU is
+ * brought offline and then online again, as when re-onlined the
+ * per-cpu vector table will no longer have ->arch.old_vector
+ * setup, and hence ->arch.old_cpu_mask would be stale.
+ */
+ cpumask_clear_cpu(cpu, desc->arch.old_cpu_mask);
+ if ( cpumask_empty(desc->arch.old_cpu_mask) )
+ {
+ desc->arch.move_in_progress = 0;
+ release_old_vec(desc);
+ }
+ }
+
/*
* Avoid shuffling the interrupt around as long as current target CPUs
* are a subset of the input mask. What fixup_irqs() cares about is
Given the current logic it's possible for ->arch.old_cpu_mask to get out of sync: if a CPU set in old_cpu_mask is offlined and then onlined again without old_cpu_mask having been updated the data in the mask will no longer be accurate, as when brought back online the CPU will no longer have old_vector configured to handle the old interrupt source. If there's an interrupt movement in progress, and the to be offlined CPU (which is the call context) is in the old_cpu_mask clear it and update the mask, so it doesn't contain stale data. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> --- xen/arch/x86/irq.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)