|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 1/6] xen/arm: ffa: Fix NPI injection when vcpu0 is offline
RX-buffer-full notifications currently inject the notification pending
interrupt through vcpu0 only. Secure notification delivery already walks
the domain's online vCPUs, but the RX-buffer-full path does not. When
vcpu0 is offline, the notification remains pending and the guest never
receives it.
Extract the common notification injection path and reuse it from
ffa_raise_rx_buffer_full(). The shared helper delivers the global
notification to the first online vCPU and keeps the existing ratelimited
debug message when none are online.
Functional impact: RX-buffer-full notifications are delivered even when
vcpu0 is offline.
Fixes: 3935c705688e ("xen/arm: ffa: Add buffer full notification support")
Signed-off-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
---
xen/arch/arm/tee/ffa_notif.c | 45 ++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c
index 186e72641237..07bc5cb3a430 100644
--- a/xen/arch/arm/tee/ffa_notif.c
+++ b/xen/arch/arm/tee/ffa_notif.c
@@ -19,6 +19,29 @@
static bool __ro_after_init fw_notif_enabled;
static unsigned int __ro_after_init notif_sri_irq;
+static void inject_notif_pending(struct domain *d)
+{
+ struct vcpu *v;
+
+ /*
+ * Since we're only delivering global notification, always
+ * deliver to the first online vCPU. It doesn't matter
+ * which we chose, as long as it's available.
+ */
+ for_each_vcpu(d, v)
+ {
+ if ( is_vcpu_online(v) )
+ {
+ vgic_inject_irq(d, v, GUEST_FFA_NOTIF_PEND_INTR_ID, true);
+ return;
+ }
+ }
+
+ if ( printk_ratelimit() )
+ printk(XENLOG_G_DEBUG "%pd: ffa: can't inject NPI, all vCPUs
offline\n",
+ d);
+}
+
int32_t ffa_handle_notification_bind(struct cpu_user_regs *regs)
{
struct domain *d = current->domain;
@@ -190,7 +213,7 @@ void ffa_raise_rx_buffer_full(struct domain *d)
ACCESS_ONCE(ctx->notif.buff_full_pending) = true;
if ( !test_and_set_bool(ctx->notif.vm_pending) )
- vgic_inject_irq(d, d->vcpu[0], GUEST_FFA_NOTIF_PEND_INTR_ID, true);
+ inject_notif_pending(d);
}
#endif
@@ -238,7 +261,6 @@ static void notif_vm_pend_intr(uint16_t vm_id)
{
struct ffa_ctx *ctx;
struct domain *d;
- struct vcpu *v;
/*
* vm_id == 0 means a notifications pending for Xen itself, but
@@ -277,24 +299,7 @@ static void notif_vm_pend_intr(uint16_t vm_id)
* it.
*/
ACCESS_ONCE(ctx->notif.secure_pending) = true;
-
- /*
- * Since we're only delivering global notification, always
- * deliver to the first online vCPU. It doesn't matter
- * which we chose, as long as it's available.
- */
- for_each_vcpu(d, v)
- {
- if ( is_vcpu_online(v) )
- {
- vgic_inject_irq(d, v, GUEST_FFA_NOTIF_PEND_INTR_ID,
- true);
- break;
- }
- }
- if ( !v && printk_ratelimit() )
- printk(XENLOG_G_DEBUG "%pd: ffa: can't inject NPI, all vCPUs
offline\n",
- d);
+ inject_notif_pending(d);
out_unlock:
rcu_unlock_domain(d);
--
2.53.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |