From ffdf5a5f292d3ae73f62422ad66297eb84da26c4 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 21 Dec 2008 17:37:44 -0800 Subject: [PATCH] Print a message instead of panicking upon an unexpected interrupt. We cannot expect that we know in detail ever interrupt that can occur on real hardware, so we must cope with exceptional cases a little better. --- src/threads/interrupt.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/threads/interrupt.c b/src/threads/interrupt.c index 9ffd873..e3b90dc 100644 --- a/src/threads/interrupt.c +++ b/src/threads/interrupt.c @@ -33,6 +33,10 @@ static intr_handler_func *intr_handlers[INTR_CNT]; /* Names for each interrupt, for debugging purposes. */ static const char *intr_names[INTR_CNT]; +/* Number of unexpected interrupts for each vector. An + unexpected interrupt is one that has no registered handler. */ +static unsigned int unexpected_cnt[INTR_CNT]; + /* External interrupts are those generated by devices outside the CPU, such as the timer. External interrupts run with interrupts turned off, so they never nest, nor are they ever @@ -54,6 +58,7 @@ static inline uint64_t make_idtr_operand (uint16_t limit, void *base); /* Interrupt handlers. */ void intr_handler (struct intr_frame *args); +static void unexpected_interrupt (const struct intr_frame *); /* Returns the current interrupt status. */ enum intr_level @@ -366,13 +371,8 @@ intr_handler (struct intr_frame *frame) spuriously due to a hardware fault or hardware race condition. Ignore it. */ } - else - { - /* No handler and not spurious. Invoke the unexpected - interrupt handler. */ - intr_dump_frame (frame); - PANIC ("Unexpected interrupt"); - } + else + unexpected_interrupt (frame); /* Complete the processing of an external interrupt. */ if (external) @@ -388,6 +388,24 @@ intr_handler (struct intr_frame *frame) } } +/* Handles an unexpected interrupt with interrupt frame F. An + unexpected interrupt is one that has no registered handler. */ +static void +unexpected_interrupt (const struct intr_frame *f) +{ + /* Count the number so far. */ + unsigned int n = ++unexpected_cnt[f->vec_no]; + + /* If the number is a power of 2, print a message. This rate + limiting means that we get information about an uncommon + unexpected interrupt the first time and fairly often after + that, but one that occurs many times will not overwhelm the + console. */ + if ((n & (n - 1)) == 0) + printf ("Unexpected interrupt %#04x (%s)\n", + f->vec_no, intr_names[f->vec_no]); +} + /* Dumps interrupt frame F to the console, for debugging. */ void intr_dump_frame (const struct intr_frame *f) -- 2.30.2