Blob Blame History Raw
From: Harald Freudenberger <freude@linux.ibm.com>
Subject: s390/zcrypt: Rework ap init in case of out of range domain param.
Patch-mainline: v4.13-rc1
Git-commit: ac994e80f94f440138774830f2edf148d6ece1f3
References: FATE#325689, LTC#167899, bsc#1113520

Summary:     zcrypt: AP bus support for alternate driver(s)
Description: AP bus support for alternate driver(s) and deterministic
             driver binding. For details please read the patch header
             for commit 7e0bdbe5c21cb8316a694e46ad5aad339f6894a6

Upstream-Description:

             s390/zcrypt: Rework ap init in case of out of range domain param.

             When a out of range domain parameter was given, the init function
             returned with -EINVAL and the driver was not operational. As the
             driver is statically build into the kernel and is able to work
             with multiple domains anyway the init function should continue.
             Now the user has a chance to write a new default domain value
             via sysfs attribute file. Also added two new dbf debug messages
             related to the domain value handling.

             Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
             Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/s390/crypto/ap_bus.c |   21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -803,7 +803,7 @@ static ssize_t ap_domain_store(struct bu
 	ap_domain_index = domain;
 	spin_unlock_bh(&ap_domain_lock);
 
-	AP_DBF(DBF_DEBUG, "store new default domain=%d\n", domain);
+	AP_DBF(DBF_DEBUG, "stored new default domain=%d\n", domain);
 
 	return count;
 }
@@ -991,6 +991,7 @@ static int ap_select_domain(void)
 	}
 	if (best_domain >= 0){
 		ap_domain_index = best_domain;
+		AP_DBF(DBF_DEBUG, "new ap_domain_index=%d\n", ap_domain_index);
 		spin_unlock_bh(&ap_domain_lock);
 		return 0;
 	}
@@ -1068,7 +1069,7 @@ static void ap_scan_bus(struct work_stru
 	ap_qid_t qid;
 	int depth = 0, type = 0;
 	unsigned int functions = 0;
-	int rc, id, dom, borked, domains;
+	int rc, id, dom, borked, domains, defdomdevs = 0;
 
 	AP_DBF(DBF_DEBUG, "ap_scan_bus running\n");
 
@@ -1132,6 +1133,8 @@ static void ap_scan_bus(struct work_stru
 				put_device(dev);
 				if (!borked) {
 					domains++;
+					if (dom == ap_domain_index)
+						defdomdevs++;
 					continue;
 				}
 			}
@@ -1181,6 +1184,8 @@ static void ap_scan_bus(struct work_stru
 				continue;
 			}
 			domains++;
+			if (dom == ap_domain_index)
+				defdomdevs++;
 		} /* end domain loop */
 		if (ac) {
 			/* remove card dev if there are no queue devices */
@@ -1189,6 +1194,11 @@ static void ap_scan_bus(struct work_stru
 			put_device(&ac->ap_dev.device);
 		}
 	} /* end device loop */
+
+	if (defdomdevs < 1)
+		AP_DBF(DBF_INFO, "no queue device with default domain %d available\n",
+		       ap_domain_index);
+
 out:
 	mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
 }
@@ -1257,14 +1267,14 @@ int __init ap_module_init(void)
 	ap_init_configuration();
 
 	if (ap_configuration)
-		max_domain_id = ap_max_domain_id ? : (AP_DOMAINS - 1);
+		max_domain_id =
+			ap_max_domain_id ? ap_max_domain_id : AP_DOMAINS - 1;
 	else
 		max_domain_id = 15;
 	if (ap_domain_index < -1 || ap_domain_index > max_domain_id) {
 		pr_warn("%d is not a valid cryptographic domain\n",
 			ap_domain_index);
-		rc = -EINVAL;
-		goto out_free;
+		ap_domain_index = -1;
 	}
 	/* In resume callback we need to know if the user had set the domain.
 	 * If so, we can not just reset it.
@@ -1337,7 +1347,6 @@ out:
 	unregister_reset_call(&ap_reset_call);
 	if (ap_using_interrupts())
 		unregister_adapter_interrupt(&ap_airq);
-out_free:
 	kfree(ap_configuration);
 	return rc;
 }