Commit 061196b3 authored by Philippe Gerum's avatar Philippe Gerum Committed by Jan Kiszka

cobalt/intr: vfile: do not assume all irqs are cobalt-managed

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.

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's avatarPhilippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka's avatarJan Kiszka <jan.kiszka@siemens.com>
parent 085ddd5e
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment