diff options
author | Jan Glauber <jang@linux.vnet.ibm.com> | 2011-10-30 18:17:20 +0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-10-30 18:16:47 +0400 |
commit | 5f4026f8b2e4c5e26713d6c707592a33326a88c4 (patch) | |
tree | 9819bcca00f6de5f265cd48523f9009a04d303ef /drivers/s390/cio/qdio.h | |
parent | 2a3a2d66aa4e5abaf8f9222d21735321f02a00dc (diff) | |
download | linux-5f4026f8b2e4c5e26713d6c707592a33326a88c4.tar.xz |
[S390] qdio: prevent dsci access without adapter interrupts
A kernel panic may occur during sending or receiving network packets
on a machine without adapter interrupts since commit d36deae.
The bug is triggered by writing to the shared indicator address which
is set to 0 if the machine doesn't have adapter interrupts.
Make the reading and setting of the shared indicator dependent on the
adapter interrupt feature and while at it move the code to the
file containing the adapter interrupt related code.
Thanks to Jan Jaeger for tracking this down.
Reported-by: Jan Jaeger <jan.jaeger@westnet.com.au>
Tested-by: Jan Jaeger <jan.jaeger@westnet.com.au>
Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/qdio.h')
-rw-r--r-- | drivers/s390/cio/qdio.h | 29 |
1 files changed, 2 insertions, 27 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 498a4cd99ff8..b962ffbc0803 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -418,32 +418,6 @@ static inline int multicast_outbound(struct qdio_q *q) #define queue_irqs_disabled(q) \ (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0) -#define TIQDIO_SHARED_IND 63 - -/* device state change indicators */ -struct indicator_t { - u32 ind; /* u32 because of compare-and-swap performance */ - atomic_t count; /* use count, 0 or 1 for non-shared indicators */ -}; - -extern struct indicator_t *q_indicators; - -static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq) -{ - return irq->nr_input_qs > 1; -} - -static inline int references_shared_dsci(struct qdio_irq *irq) -{ - return irq->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; -} - -static inline int shared_ind(struct qdio_q *q) -{ - struct qdio_irq *i = q->irq_ptr; - return references_shared_dsci(i) || has_multiple_inq_on_dsci(i); -} - extern u64 last_ai_time; /* prototypes for thin interrupt */ @@ -457,7 +431,8 @@ int tiqdio_allocate_memory(void); void tiqdio_free_memory(void); int tiqdio_register_thinints(void); void tiqdio_unregister_thinints(void); - +void clear_nonshared_ind(struct qdio_irq *); +int test_nonshared_ind(struct qdio_irq *); /* prototypes for setup */ void qdio_inbound_processing(unsigned long data); |