aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-xp
diff options
context:
space:
mode:
authorRobin Holt <holt@sgi.com>2010-10-26 17:21:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-26 19:52:03 -0400
commit09358972bff5ce99de496bbba97c85d417b3c054 (patch)
treee7007ac80fc9dd6101db5c9ca07cbc0246b597e4 /drivers/misc/sgi-xp
parent482db6df1746c4fa7d64a2441d4cb2610249c679 (diff)
sgi-xp: incoming XPC channel messages can come in after the channel's partition structures have been torn down
Under some workloads, some channel messages have been observed being delayed on the sending side past the point where the receiving side has been able to tear down its partition structures. This condition is already detected in xpc_handle_activate_IRQ_uv(), but that information is not given to xpc_handle_activate_mq_msg_uv(). As a result, xpc_handle_activate_mq_msg_uv() assumes the structures still exist and references them, causing a NULL-pointer deref. Signed-off-by: Robin Holt <holt@sgi.com> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-xp')
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index 1f59ee2226ca..17bbacb1b4b1 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -417,6 +417,7 @@ xpc_process_activate_IRQ_rcvd_uv(void)
417static void 417static void
418xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, 418xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
419 struct xpc_activate_mq_msghdr_uv *msg_hdr, 419 struct xpc_activate_mq_msghdr_uv *msg_hdr,
420 int part_setup,
420 int *wakeup_hb_checker) 421 int *wakeup_hb_checker)
421{ 422{
422 unsigned long irq_flags; 423 unsigned long irq_flags;
@@ -481,6 +482,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
481 case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: { 482 case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: {
482 struct xpc_activate_mq_msg_chctl_closerequest_uv *msg; 483 struct xpc_activate_mq_msg_chctl_closerequest_uv *msg;
483 484
485 if (!part_setup)
486 break;
487
484 msg = container_of(msg_hdr, struct 488 msg = container_of(msg_hdr, struct
485 xpc_activate_mq_msg_chctl_closerequest_uv, 489 xpc_activate_mq_msg_chctl_closerequest_uv,
486 hdr); 490 hdr);
@@ -497,6 +501,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
497 case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: { 501 case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: {
498 struct xpc_activate_mq_msg_chctl_closereply_uv *msg; 502 struct xpc_activate_mq_msg_chctl_closereply_uv *msg;
499 503
504 if (!part_setup)
505 break;
506
500 msg = container_of(msg_hdr, struct 507 msg = container_of(msg_hdr, struct
501 xpc_activate_mq_msg_chctl_closereply_uv, 508 xpc_activate_mq_msg_chctl_closereply_uv,
502 hdr); 509 hdr);
@@ -511,6 +518,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
511 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: { 518 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: {
512 struct xpc_activate_mq_msg_chctl_openrequest_uv *msg; 519 struct xpc_activate_mq_msg_chctl_openrequest_uv *msg;
513 520
521 if (!part_setup)
522 break;
523
514 msg = container_of(msg_hdr, struct 524 msg = container_of(msg_hdr, struct
515 xpc_activate_mq_msg_chctl_openrequest_uv, 525 xpc_activate_mq_msg_chctl_openrequest_uv,
516 hdr); 526 hdr);
@@ -528,6 +538,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
528 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: { 538 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: {
529 struct xpc_activate_mq_msg_chctl_openreply_uv *msg; 539 struct xpc_activate_mq_msg_chctl_openreply_uv *msg;
530 540
541 if (!part_setup)
542 break;
543
531 msg = container_of(msg_hdr, struct 544 msg = container_of(msg_hdr, struct
532 xpc_activate_mq_msg_chctl_openreply_uv, hdr); 545 xpc_activate_mq_msg_chctl_openreply_uv, hdr);
533 args = &part->remote_openclose_args[msg->ch_number]; 546 args = &part->remote_openclose_args[msg->ch_number];
@@ -545,6 +558,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
545 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: { 558 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: {
546 struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg; 559 struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg;
547 560
561 if (!part_setup)
562 break;
563
548 msg = container_of(msg_hdr, struct 564 msg = container_of(msg_hdr, struct
549 xpc_activate_mq_msg_chctl_opencomplete_uv, hdr); 565 xpc_activate_mq_msg_chctl_opencomplete_uv, hdr);
550 spin_lock_irqsave(&part->chctl_lock, irq_flags); 566 spin_lock_irqsave(&part->chctl_lock, irq_flags);
@@ -621,6 +637,7 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id)
621 637
622 part_referenced = xpc_part_ref(part); 638 part_referenced = xpc_part_ref(part);
623 xpc_handle_activate_mq_msg_uv(part, msg_hdr, 639 xpc_handle_activate_mq_msg_uv(part, msg_hdr,
640 part_referenced,
624 &wakeup_hb_checker); 641 &wakeup_hb_checker);
625 if (part_referenced) 642 if (part_referenced)
626 xpc_part_deref(part); 643 xpc_part_deref(part);