|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v13 08/14] xen/arm: ffa: fix notification SRI across CPU hotplug/suspend
The FF-A notification SRI interrupt handler was not correctly tied to
CPU hotplug and suspend/resume. As a result, CPUs going offline and
back online could end up with stale or missing handlers, breaking
delivery of FF-A notifications.
Signed-off-by: Mykola Kvach <mykola_kvach@xxxxxxxx>
Reviewed-by: Luca Fancellu <luca.fancellu@xxxxxxx>
Reviewed-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
---
Changes in V13:
- Use false for free_on_release (MISRA Rule 10.3). No functional change.
- Explicitly discard request_sri_irq()'s result on secondary CPUs. The
helper logs errors, preserving the existing behavior (MISRA Rule 17.7).
No functional change.
- Explain why the notifier ignores other CPU events (MISRA Rule 16.4). No
functional change.
---
xen/arch/arm/tee/ffa_notif.c | 63 +++++++++++++++++++++++++++++-------
1 file changed, 51 insertions(+), 12 deletions(-)
diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c
index c64bc39f03..1ec455d2ad 100644
--- a/xen/arch/arm/tee/ffa_notif.c
+++ b/xen/arch/arm/tee/ffa_notif.c
@@ -360,10 +360,28 @@ static int32_t ffa_notification_bitmap_destroy(uint16_t
vm_id)
return ffa_simple_call(FFA_NOTIFICATION_BITMAP_DESTROY, vm_id, 0, 0, 0);
}
-void ffa_notif_init_interrupt(void)
+static DEFINE_PER_CPU_READ_MOSTLY(struct irqaction, sri_irq);
+
+static int request_sri_irq(void)
{
int ret;
+ struct irqaction *sri_action = &this_cpu(sri_irq);
+
+ sri_action->name = "FF-A notif";
+ sri_action->handler = notif_irq_handler;
+ sri_action->dev_id = NULL;
+ sri_action->free_on_release = false;
+
+ ret = setup_irq(notif_sri_irq, 0, sri_action);
+ if ( ret )
+ printk(XENLOG_ERR "ffa: setup_irq irq %u failed: error %d\n",
+ notif_sri_irq, ret);
+
+ return ret;
+}
+void ffa_notif_init_interrupt(void)
+{
if ( fw_notif_enabled && notif_sri_irq < NR_GIC_SGI )
{
/*
@@ -376,14 +394,37 @@ void ffa_notif_init_interrupt(void)
* pending, while the SPMC in the secure world will not notice that
* the interrupt was lost.
*/
- ret = request_irq(notif_sri_irq, 0, notif_irq_handler, "FF-A notif",
- NULL);
- if ( ret )
- printk(XENLOG_ERR "ffa: request_irq irq %u failed: error %d\n",
- notif_sri_irq, ret);
+ (void)request_sri_irq();
+ }
+}
+
+static void deinit_ffa_notif_interrupt(void)
+{
+ if ( fw_notif_enabled && notif_sri_irq < NR_GIC_SGI )
+ release_irq(notif_sri_irq, NULL);
+}
+
+static int cpu_ffa_notif_callback(struct notifier_block *nfb,
+ unsigned long action,
+ void *hcpu)
+{
+ switch ( action )
+ {
+ case CPU_DYING:
+ deinit_ffa_notif_interrupt();
+ break;
+ default:
+ /* Ignore other CPU events. */
+ break;
}
+
+ return NOTIFY_DONE;
}
+static struct notifier_block cpu_ffa_notif_nfb = {
+ .notifier_call = cpu_ffa_notif_callback,
+};
+
void ffa_notif_init(void)
{
const struct arm_smccc_1_2_regs arg = {
@@ -416,13 +457,11 @@ void ffa_notif_init(void)
return;
}
}
- ret = request_irq(irq, 0, notif_irq_handler, "FF-A notif", NULL);
- if ( ret )
- {
- printk(XENLOG_ERR "ffa: request_irq irq %u failed: error %d\n",
- irq, ret);
+
+ if ( request_sri_irq() )
return;
- }
+
+ register_cpu_notifier(&cpu_ffa_notif_nfb);
fw_notif_enabled = true;
}
}
--
2.53.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |