public inbox for linux-s390@vger.kernel.org
 help / color / mirror / Atom feed
From: Harald Freudenberger <freude@linux.ibm.com>
To: dengler@linux.ibm.com, ifranzki@linux.ibm.com,
	fcallies@linux.ibm.com, hca@linux.ibm.com, gor@linux.ibm.com,
	agordeev@linux.ibm.com
Cc: linux-s390@vger.kernel.org, herbert@gondor.apana.org.au
Subject: [PATCH v3 03/21] s390/ap: Introduce ap message buffer pool
Date: Thu, 27 Mar 2025 15:39:23 +0100	[thread overview]
Message-ID: <20250327143941.45507-4-freude@linux.ibm.com> (raw)
In-Reply-To: <20250327143941.45507-1-freude@linux.ibm.com>

There is a need for a do-not-allocate-memory path through the
ap bus layer. When ap_init_apmsg() with use_mempool set to true
is called, instead of kmalloc() the ap message buffer is
allocated from the ap_msg_pool. This pool only holds a limited
amount of buffers: ap_msg_pool_min_items with the item size
AP_DEFAULT_MAX_MSG_SIZE and exactly one of these items (if available)
is returned if ap_init_apmsg() with the use_mempool arg set to true
is called. When this pool is exhausted and use_mempool is set true,
ap_init_apmsg() returns -ENOMEM without any attempt to allocate
memory.

Default values for this mempool of ap messages is:
 * Each buffer is 12KB (that is the default AP bus size
   and all the urgend messages should fit into this space).
 * Minimum items held in the pool is 8. This value is adjustable
   via module parameter ap.msgpool_min_items.

The zcrypt layer may use this flag to indicate to the ap bus
that the processing path for this message should not allocate
memory but should use pre-allocated memory buffer instead.
This is to prevent deadlocks with crypto and io for example
with encrypted swap volumes.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
---
 drivers/s390/crypto/ap_bus.c     | 57 ++++++++++++++++++++++++++++----
 drivers/s390/crypto/ap_bus.h     |  3 +-
 drivers/s390/crypto/zcrypt_api.c | 10 +++---
 3 files changed, 57 insertions(+), 13 deletions(-)

diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 4940eaf538e9..75dbab9dff4a 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -40,6 +40,7 @@
 #include <linux/module.h>
 #include <asm/uv.h>
 #include <asm/chsc.h>
+#include <linux/mempool.h>
 
 #include "ap_bus.h"
 #include "ap_debug.h"
@@ -101,6 +102,23 @@ static struct ap_config_info *const ap_qci_info_old = &qci[1];
  */
 debug_info_t *ap_dbf_info;
 
+/*
+ * There is a need for a do-not-allocate-memory path through the
+ * ap bus layer. When ap_init_apmsg() with use_mempool set to true
+ * is called, instead of kmalloc() the ap message buffer is
+ * allocated from the ap_msg_pool. This pool only holds a limited
+ * amount of buffers: ap_msg_pool_min_items with the item size
+ * AP_DEFAULT_MAX_MSG_SIZE and exactly one of these items (if available)
+ * is returned if ap_init_apmsg() with the use_mempool arg set to true
+ * is called. When this pool is exhausted and use_mempool is set true,
+ * ap_init_apmsg() returns -ENOMEM without any attempt to allocate
+ * memory.
+ */
+static mempool_t *ap_msg_pool;
+static unsigned int ap_msg_pool_min_items = 8;
+module_param_named(msgpool_min_items, ap_msg_pool_min_items, uint, 0440);
+MODULE_PARM_DESC(msgpool_min_items, "AP message pool minimal items.");
+
 /*
  * AP bus rescan related things.
  */
@@ -548,14 +566,25 @@ static void ap_poll_thread_stop(void)
 
 /**
  * ap_init_apmsg() - Initialize ap_message.
- * Initialize a message before using. Otherwise this might result in
- * unexpected behaviour.
+ * Initialize struct ap_message and allocate buffer to construct
+ * the ap message.
  */
-int ap_init_apmsg(struct ap_message *ap_msg)
+int ap_init_apmsg(struct ap_message *ap_msg, bool use_mempool)
 {
-	unsigned int maxmsgsize = atomic_read(&ap_max_msg_size);
+	unsigned int maxmsgsize;
 
 	memset(ap_msg, 0, sizeof(*ap_msg));
+
+	if (use_mempool) {
+		ap_msg->msg = mempool_alloc_preallocated(ap_msg_pool);
+		if (!ap_msg->msg)
+			return -ENOMEM;
+		ap_msg->bufsize = AP_DEFAULT_MAX_MSG_SIZE;
+		ap_msg->flags |= AP_MSG_FLAG_MEMPOOL;
+		return 0;
+	}
+
+	maxmsgsize = atomic_read(&ap_max_msg_size);
 	ap_msg->msg = kmalloc(maxmsgsize, GFP_KERNEL);
 	if (!ap_msg->msg)
 		return -ENOMEM;
@@ -567,12 +596,16 @@ EXPORT_SYMBOL(ap_init_apmsg);
 
 /**
  * ap_release_apmsg() - Release ap_message.
- * Releases all memory used internal within the ap_message struct
- * Currently this is the message and private field.
+ * Cleanup struct ap_message and release all memory held.
  */
 void ap_release_apmsg(struct ap_message *ap_msg)
 {
-	kfree_sensitive(ap_msg->msg);
+	if (ap_msg->flags & AP_MSG_FLAG_MEMPOOL) {
+		memzero_explicit(ap_msg->msg, ap_msg->bufsize);
+		mempool_free(ap_msg->msg, ap_msg_pool);
+	} else {
+		kfree_sensitive(ap_msg->msg);
+	}
 }
 EXPORT_SYMBOL(ap_release_apmsg);
 
@@ -2461,6 +2494,14 @@ static int __init ap_module_init(void)
 	/* init ap_queue hashtable */
 	hash_init(ap_queues);
 
+	/* create ap msg buffer memory pool */
+	ap_msg_pool = mempool_create_kmalloc_pool(ap_msg_pool_min_items,
+						  AP_DEFAULT_MAX_MSG_SIZE);
+	if (IS_ERR(ap_msg_pool)) {
+		ap_msg_pool = NULL;
+		goto out;
+	}
+
 	/* set up the AP permissions (ioctls, ap and aq masks) */
 	ap_perms_init();
 
@@ -2507,6 +2548,7 @@ static int __init ap_module_init(void)
 out_bus:
 	bus_unregister(&ap_bus_type);
 out:
+	mempool_destroy(ap_msg_pool);
 	ap_debug_exit();
 	return rc;
 }
@@ -2517,6 +2559,7 @@ static void __exit ap_module_exit(void)
 	ap_irq_exit();
 	root_device_unregister(ap_root_device);
 	bus_unregister(&ap_bus_type);
+	mempool_destroy(ap_msg_pool);
 	ap_debug_exit();
 }
 
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 483231bcdea6..60c41d8116ad 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -236,8 +236,9 @@ struct ap_message {
 #define AP_MSG_FLAG_SPECIAL  0x0001	/* flag msg as 'special' with NQAP */
 #define AP_MSG_FLAG_USAGE    0x0002	/* CCA, EP11: usage (no admin) msg */
 #define AP_MSG_FLAG_ADMIN    0x0004	/* CCA, EP11: admin (=control) msg */
+#define AP_MSG_FLAG_MEMPOOL  0x0008 /* ap msg buffer allocated via mempool */
 
-int ap_init_apmsg(struct ap_message *ap_msg);
+int ap_init_apmsg(struct ap_message *ap_msg, bool use_mempool);
 void ap_release_apmsg(struct ap_message *ap_msg);
 
 enum ap_sm_wait ap_sm_event(struct ap_queue *aq, enum ap_sm_event event);
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 78df25da0b95..ad09c5306e28 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -648,7 +648,7 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,
 
 	trace_s390_zcrypt_req(mex, TP_ICARSAMODEXPO);
 
-	rc = ap_init_apmsg(&ap_msg);
+	rc = ap_init_apmsg(&ap_msg, false);
 	if (rc)
 		goto out;
 
@@ -753,7 +753,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
 
 	trace_s390_zcrypt_req(crt, TP_ICARSACRT);
 
-	rc = ap_init_apmsg(&ap_msg);
+	rc = ap_init_apmsg(&ap_msg, false);
 	if (rc)
 		goto out;
 
@@ -861,7 +861,7 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
 
 	xcrb->status = 0;
 
-	rc = ap_init_apmsg(&ap_msg);
+	rc = ap_init_apmsg(&ap_msg, false);
 	if (rc)
 		goto out;
 
@@ -1045,7 +1045,7 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
 
 	trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB);
 
-	rc = ap_init_apmsg(&ap_msg);
+	rc = ap_init_apmsg(&ap_msg, false);
 	if (rc)
 		goto out;
 
@@ -1219,7 +1219,7 @@ static long zcrypt_rng(char *buffer)
 
 	trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB);
 
-	rc = ap_init_apmsg(&ap_msg);
+	rc = ap_init_apmsg(&ap_msg, false);
 	if (rc)
 		goto out;
 	rc = prep_rng_ap_msg(&ap_msg, &func_code, &domain);
-- 
2.43.0


  parent reply	other threads:[~2025-03-27 14:39 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-27 14:39 [PATCH v3 00/21] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 01/21] s390/ap: Move response_type struct into ap_msg struct Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 02/21] s390/ap/zcrypt: Rework AP message buffer allocation Harald Freudenberger
2025-03-31 10:47   ` Heiko Carstens
2025-03-27 14:39 ` Harald Freudenberger [this message]
2025-03-31 10:46   ` [PATCH v3 03/21] s390/ap: Introduce ap message buffer pool Heiko Carstens
2025-03-27 14:39 ` [PATCH v3 04/21] s390/ap/zcrypt: New xflag parameter Harald Freudenberger
2025-03-31 11:03   ` Heiko Carstens
2025-04-09  8:40   ` Holger Dengler
2025-04-09 13:46     ` Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 05/21] s390/zcrypt: Introduce cprb mempool for cca misc functions Harald Freudenberger
2025-03-31 11:20   ` Heiko Carstens
2025-03-27 14:39 ` [PATCH v3 06/21] s390/zcrypt: Introduce cprb mempool for ep11 " Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 07/21] s390/zcrypt: Rework zcrypt function zcrypt_device_status_mask_ext Harald Freudenberger
2025-04-09  8:56   ` Holger Dengler
2025-04-09 13:42     ` Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 08/21] s390/zcrypt: Introduce pre-allocated device status array for cca misc Harald Freudenberger
2025-04-09 10:13   ` Holger Dengler
2025-03-27 14:39 ` [PATCH v3 09/21] s390/zcrypt: Introduce pre-allocated device status array for ep11 misc Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 10/21] s390/zcrypt: Remove unused functions from cca misc Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 11/21] s390/zcrypt: Remove CCA and EP11 card and domain info caches Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 12/21] s390/zcrypt/pkey: Rework cca findcard() implementation and callers Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 13/21] s390/zcrypt/pkey: Rework ep11 " Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 14/21] s390/zcrypt: Rework cca misc functions kmallocs to use the cprb mempool Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 15/21] s390/zcrypt: Propagate xflags argument with cca_get_info() Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 16/21] s390/zcrypt: Locate ep11_domain_query_info onto the stack instead of kmalloc Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 17/21] s390/zcrypt: Rework ep11 misc functions to use cprb mempool Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 18/21] s390/pkey: Rework CCA pkey handler to use stack for small memory allocs Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 19/21] s390/pkey: Rework EP11 " Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 20/21] s390/zcrypt/pkey: Provide and pass xflags within pkey and zcrypt layers Harald Freudenberger
2025-03-27 14:39 ` [PATCH v3 21/21] s390/pkey/crypto: Introduce xflags param for pkey in-kernel API Harald Freudenberger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250327143941.45507-4-freude@linux.ibm.com \
    --to=freude@linux.ibm.com \
    --cc=agordeev@linux.ibm.com \
    --cc=dengler@linux.ibm.com \
    --cc=fcallies@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=ifranzki@linux.ibm.com \
    --cc=linux-s390@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox