[S390] zcrypt device registration/unregistration race.

Fix a race condition during AP device registration and unregistration.

Signed-off-by: Ralph Wuerthner <rwuerthn@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by Ralph Wuerthner and committed by Martin Schwidefsky 4e56296d f1ee3281

+12 -11
+12 -11
drivers/s390/crypto/ap_bus.c
··· 449 450 ap_dev->drv = ap_drv; 451 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV; 452 - if (rc) 453 - ap_dev->unregistered = 1; 454 return rc; 455 } 456 ··· 485 struct ap_device *ap_dev = to_ap_dev(dev); 486 struct ap_driver *ap_drv = ap_dev->drv; 487 488 - spin_lock_bh(&ap_dev->lock); 489 - __ap_flush_queue(ap_dev); 490 - /** 491 - * set ->unregistered to 1 while holding the lock. This prevents 492 - * new messages to be put on the queue from now on. 493 - */ 494 - ap_dev->unregistered = 1; 495 - spin_unlock_bh(&ap_dev->lock); 496 if (ap_drv->remove) 497 ap_drv->remove(ap_dev); 498 return 0; ··· 754 break; 755 ap_dev->qid = qid; 756 ap_dev->queue_depth = queue_depth; 757 spin_lock_init(&ap_dev->lock); 758 INIT_LIST_HEAD(&ap_dev->pendingq); 759 INIT_LIST_HEAD(&ap_dev->requestq); ··· 776 /* Add device attributes. */ 777 rc = sysfs_create_group(&ap_dev->device.kobj, 778 &ap_dev_attr_group); 779 - if (rc) 780 device_unregister(&ap_dev->device); 781 } 782 } ··· 967 rc = __ap_queue_message(ap_dev, ap_msg); 968 if (!rc) 969 wake_up(&ap_poll_wait); 970 } else { 971 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); 972 rc = 0; ··· 1027 spin_lock(&ap_dev->lock); 1028 if (!ap_dev->unregistered) { 1029 rc = ap_poll_queue(to_ap_dev(dev), (unsigned long *) data); 1030 } else 1031 rc = 0; 1032 spin_unlock(&ap_dev->lock);
··· 449 450 ap_dev->drv = ap_drv; 451 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV; 452 return rc; 453 } 454 ··· 487 struct ap_device *ap_dev = to_ap_dev(dev); 488 struct ap_driver *ap_drv = ap_dev->drv; 489 490 + ap_flush_queue(ap_dev); 491 if (ap_drv->remove) 492 ap_drv->remove(ap_dev); 493 return 0; ··· 763 break; 764 ap_dev->qid = qid; 765 ap_dev->queue_depth = queue_depth; 766 + ap_dev->unregistered = 1; 767 spin_lock_init(&ap_dev->lock); 768 INIT_LIST_HEAD(&ap_dev->pendingq); 769 INIT_LIST_HEAD(&ap_dev->requestq); ··· 784 /* Add device attributes. */ 785 rc = sysfs_create_group(&ap_dev->device.kobj, 786 &ap_dev_attr_group); 787 + if (!rc) { 788 + spin_lock_bh(&ap_dev->lock); 789 + ap_dev->unregistered = 0; 790 + spin_unlock_bh(&ap_dev->lock); 791 + } 792 + else 793 device_unregister(&ap_dev->device); 794 } 795 } ··· 970 rc = __ap_queue_message(ap_dev, ap_msg); 971 if (!rc) 972 wake_up(&ap_poll_wait); 973 + if (rc == -ENODEV) 974 + ap_dev->unregistered = 1; 975 } else { 976 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); 977 rc = 0; ··· 1028 spin_lock(&ap_dev->lock); 1029 if (!ap_dev->unregistered) { 1030 rc = ap_poll_queue(to_ap_dev(dev), (unsigned long *) data); 1031 + if (rc) 1032 + ap_dev->unregistered = 1; 1033 } else 1034 rc = 0; 1035 spin_unlock(&ap_dev->lock);