diff --git a/core/include/kernel/notif.h b/core/include/kernel/notif.h index 7d32f7170ad..d374ba55ddf 100644 --- a/core/include/kernel/notif.h +++ b/core/include/kernel/notif.h @@ -108,11 +108,16 @@ struct notif_driver { * @ops Notifier callback operations or NULL if none * @flags: NOTIF_IT_FLAG_* properties * @priv Driver private data of NULL + * @set_mask Copy of set_mask entry for pager optims + * + * @set_mask is a copy of set_mask handler from ops. It is copied here + * to help set_mask be DECLARE_KEEP_PAGER() without its whole related ops. */ struct notif_it { unsigned int id; const struct notif_it_ops *ops; unsigned int flags; + void (*set_mask)(struct notif_it *notif_it, bool do_mask); void *priv; }; @@ -126,10 +131,12 @@ struct notif_it { /* * struct notif_it_ops - Interrupt notifier operations * + * @set_mask Fasctcall callback for (un)masking the event or NULL if not used * @set_state Callback for enabling/disabling the event or NULL if not used * @set_wakeup Callback for enabling/disabling standby wakeup source or NULL */ struct notif_it_ops { + void (*set_mask)(struct notif_it *notif_it, bool do_mask); TEE_Result (*set_state)(struct notif_it *notif_it, bool do_enable); TEE_Result (*set_wakeup)(struct notif_it *notif_it, bool do_enable); }; diff --git a/core/kernel/notif.c b/core/kernel/notif.c index 51bc6258295..9af90dd3bc5 100644 --- a/core/kernel/notif.c +++ b/core/kernel/notif.c @@ -8,8 +8,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -253,8 +255,11 @@ void notif_it_set_mask(unsigned int id, bool do_mask) { struct notif_it *notif = find_notif_it(id); - if (notif) + if (notif) { set_it_mask(id, do_mask); + if (notif->set_mask) + notif->set_mask(notif, do_mask); + } } /* @@ -367,6 +372,11 @@ TEE_Result notif_it_register(unsigned int id, const struct notif_it_ops *ops, if (find_notif_it(id)) return TEE_ERROR_BAD_PARAMETERS; + if (ops && ops->set_mask && !is_unpaged(ops->set_mask)) { + DMSG("ops and set_mask handler must be unpaged"); + return TEE_ERROR_GENERIC; + } + assert(!bit_test(notif_it_pending, id)); old_itr_status = cpu_spin_lock_xsave(&it_lock); bit_clear(notif_it_pending, id); @@ -390,10 +400,13 @@ TEE_Result notif_it_register(unsigned int id, const struct notif_it_ops *ops, notif->id = id; notif->ops = ops; notif->priv = priv; + if (ops) + notif->set_mask = ops->set_mask; set_it_mask(id, 1); add_notif_it_handler(notif); + if (notif_it_ref) *notif_it_ref = notif;