On 14.01.19 18:35, Philippe Gerum wrote:
Non-cobalt kernel code may hook interrupts using ipipe_request_irq()
directly, which means that xnintr_vec_first() cannot assume that
__ipipe_irq_cookie() always returns a valid xnintr struct for all
irqs.

Is there an out-of-tree use case for that already, or is this rather defensive?


We need to detect those irqs while iterating over the interrupt
namespace when pulling data from /proc files not to dereference
invalid memory.

Fixes:
/proc/xenomai/irq
/proc/xenomai/sched/stat
/proc/xenomai/sched/acct

Signed-off-by: Philippe Gerum <[email protected]>
---
  kernel/cobalt/intr.c | 48 +++++++++++++++++++++++++++++++++++---------
  1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/kernel/cobalt/intr.c b/kernel/cobalt/intr.c
index 184ffad13..ba6409ebb 100644
--- a/kernel/cobalt/intr.c
+++ b/kernel/cobalt/intr.c
@@ -449,6 +449,17 @@ out:
        }
  }
+static inline bool cobalt_owns_irq(int irq)
+{
+       ipipe_irq_handler_t h;
+
+       h = __ipipe_irq_handler(&xnsched_realtime_domain, irq);
+
+       return h == xnintr_vec_handler ||
+               h == xnintr_edge_vec_handler ||
+               h == xnintr_irq_handler;
+}
+
  static inline int xnintr_irq_attach(struct xnintr *intr)
  {
        struct xnintr_vector *vec = vectors + intr->irq;
@@ -538,9 +549,19 @@ struct xnintr_vector {
static struct xnintr_vector vectors[IPIPE_NR_IRQS]; +static inline bool cobalt_owns_irq(int irq)
+{
+       ipipe_irq_handler_t h;
+
+       h = __ipipe_irq_handler(&xnsched_realtime_domain, irq);
+
+       return h == xnintr_irq_handler;
+}
+
  static inline struct xnintr *xnintr_vec_first(unsigned int irq)
  {
-       return __ipipe_irq_cookie(&xnsched_realtime_domain, irq);
+       return cobalt_owns_irq(irq) ?
+               __ipipe_irq_cookie(&xnsched_realtime_domain, irq) : NULL;
  }
static inline struct xnintr *xnintr_vec_next(struct xnintr *prev)
@@ -1067,6 +1088,7 @@ static inline int format_irq_proc(unsigned int irq,
                                  struct xnvfile_regular_iterator *it)
  {
        struct xnintr *intr;
+       struct irq_desc *d;
        int cpu;
for_each_realtime_cpu(cpu)
@@ -1100,15 +1122,21 @@ static inline int format_irq_proc(unsigned int irq,
mutex_lock(&intrlock); - intr = xnintr_vec_first(irq);
-       if (intr) {
-               xnvfile_puts(it, "        ");
-
-               do {
-                       xnvfile_putc(it, ' ');
-                       xnvfile_puts(it, intr->name);
-                       intr = xnintr_vec_next(intr);
-               } while (intr);
+       if (!cobalt_owns_irq(irq)) {
+               xnvfile_puts(it, "         ");
+               d = irq_to_desc(irq);
+               xnvfile_puts(it, d && d->name ? d->name : "-");
+       } else {
+               intr = xnintr_vec_first(irq);
+               if (intr) {
+                       xnvfile_puts(it, "        ");
+
+                       do {
+                               xnvfile_putc(it, ' ');
+                               xnvfile_puts(it, intr->name);
+                               intr = xnintr_vec_next(intr);
+                       } while (intr);
+               }
        }
mutex_unlock(&intrlock);


Jan

--
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux

Reply via email to