* [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches
@ 2025-03-04 17:20 Harald Freudenberger
2025-03-04 17:20 ` [PATCH v2 01/20] s390/ap: Move response_type struct into ap_msg struct Harald Freudenberger
` (20 more replies)
0 siblings, 21 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:20 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
This series of patches has the goal to open up a do-not-allocate
memory path from the callers of the pkey in-kernel api down to
the crypto cards and back.
The asynch in-kernel cipher implementations (and the s390 PAES
cipher implementations are one of them) may be called in a
context where memory allocations which trigger IO is not acceptable.
So this patch series reworks the AP bus code, the zcrypt layer,
the pkey layer and the pkey handlers to respect this situation
by processing a new parameter xflags (execution hints flags).
There is a flag PKEY_XFLAG_NOMEMALLOC which tells the code to
not allocate memory which may lead to IO operations.
To reach this goal, the actual code changes have been differed.
The zcrypt misc functions which need memory for cprb build
use a pre allocated memory pool for this purpose. The findcard()
functions have one temp memory area preallocated and protected
with a mutex. Some smaller data is not allocated any more but went
to the stack instead. The AP bus also uses a pre-allocated
memory pool for building AP message requests.
Note that the PAES implementation still needs to get reworked
to run the protected key derivation in a real asynchronous way.
However, this rework of AP bus, zcrypt and pkey is the base work
required before reconsidering the PAES implementation.
The patch series starts bottom (AP bus) and goes up the call
chain (PKEY). At any time in the patch stack it should compile.
For easier review I tried to have one logic code change by
each patch and thus keep the patches "small". For the upstream
version I intend to fold them together into only a few commits.
Changelog:
v1: initial version
v2: - Rework on patch 0001 and 0002 based on feedback from Holger.
Also there was one place in zcrypt_msgtype50.c where still
an ap msg buffer was alloacated.
- Rework on patch 0003 - fixed feedback from Holger. Also the
min poolitems is now a module parameter and defaults to 8.
- Rework on patch 0004 - as suggested by Holger the "userspace"
parameter is now included into the ap msg flags.
- Rework on patch 0005 - nr of cca cprbs in the mempool is now
a module parameter.
- Rework on patch 0006 - nr of ep11 cprbs in the mempool is now
a module parameter.
- Rework on patch 0007 - as suggested by Holger instead of
implementing a copy-and-pasted new function
zcrypt_device_status_mask_ext2() use and extend the existing
the existing function to avoid code duplication.
- The rest of the patch series needed adaptions but there is
no functional change compared to v1.
Harald Freudenberger (20):
s390/ap: Move response_type struct into ap_msg struct
s390/ap/zcrypt: Rework AP message buffer allocation
s390/ap: Introduce ap message buffer pool
s390/ap/zcrypt: New xflag parameter and extension of the ap msg flags
s390/zcrypt: Introduce cprb mempool for cca misc functions
s390/zcrypt: Introduce cprb mempool for ep11 misc functions
s390/zcrypt: Rework zcrypt function zcrypt_device_status_mask_ext
s390/zcrypt: Introduce pre-allocated device status array for cca misc
s390/zcrypt: Introduce pre-allocated device status array for ep11 misc
s390/zcrypt/pkey: Rework cca findcard() implementation and callers
s390/zcrypt/pkey: Rework ep11 findcard() implementation and callers
s390/zcrypt: Rework cca misc functions kmallocs to use the cprb
mempool
s390/zcrypt: Add small mempool for cca info list entries
s390/zcrypt: Locate ep11_domain_query_info onto the stack instead of
kmalloc
s390/zcrypt: Rework ep11 misc functions to use cprb mempool
s390/zcrypt: Add small mempool for ep11 card info list entries
s390/pkey: Rework CCA pkey handler to use stack for small memory
allocs
s390/pkey: Rework EP11 pkey handler to use stack for small memory
allocs
s390/zcrypt/pkey: Provide and pass xflags within pkey and zcrypt
layers
s390/pkey/crypto: Introduce xflags param for pkey in-kernel API
arch/s390/crypto/paes_s390.c | 2 +-
arch/s390/include/asm/pkey.h | 15 +-
drivers/s390/crypto/ap_bus.c | 73 +++++
drivers/s390/crypto/ap_bus.h | 37 +--
drivers/s390/crypto/pkey_api.c | 54 ++--
drivers/s390/crypto/pkey_base.c | 34 ++-
drivers/s390/crypto/pkey_base.h | 37 ++-
drivers/s390/crypto/pkey_cca.c | 121 ++++----
drivers/s390/crypto/pkey_ep11.c | 106 +++----
drivers/s390/crypto/pkey_pckmo.c | 9 +-
drivers/s390/crypto/pkey_sysfs.c | 4 +-
drivers/s390/crypto/pkey_uv.c | 16 +-
drivers/s390/crypto/zcrypt_api.c | 172 +++++++----
drivers/s390/crypto/zcrypt_api.h | 42 ++-
drivers/s390/crypto/zcrypt_ccamisc.c | 350 +++++++++++++++-------
drivers/s390/crypto/zcrypt_ccamisc.h | 41 +--
drivers/s390/crypto/zcrypt_cex4.c | 16 +-
drivers/s390/crypto/zcrypt_ep11misc.c | 387 ++++++++++++++++---------
drivers/s390/crypto/zcrypt_ep11misc.h | 28 +-
drivers/s390/crypto/zcrypt_msgtype50.c | 36 ++-
drivers/s390/crypto/zcrypt_msgtype6.c | 121 ++++----
drivers/s390/crypto/zcrypt_msgtype6.h | 4 +-
22 files changed, 1032 insertions(+), 673 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH v2 01/20] s390/ap: Move response_type struct into ap_msg struct
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
@ 2025-03-04 17:20 ` Harald Freudenberger
2025-03-17 9:38 ` Holger Dengler
2025-03-04 17:20 ` [PATCH v2 02/20] s390/ap/zcrypt: Rework AP message buffer allocation Harald Freudenberger
` (19 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:20 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Move the very small response_type struct into struct ap_msg.
So there is no need to kmalloc this tiny struct with each
ap message preparation.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/ap_bus.h | 8 ++-
drivers/s390/crypto/zcrypt_msgtype50.c | 16 ++----
drivers/s390/crypto/zcrypt_msgtype6.c | 74 ++++++++++----------------
3 files changed, 38 insertions(+), 60 deletions(-)
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index f4622ee4d894..7fd24c207bdf 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -214,6 +214,11 @@ struct ap_queue {
typedef enum ap_sm_wait (ap_func_t)(struct ap_queue *queue);
+struct ap_response_type {
+ struct completion work;
+ int type;
+};
+
struct ap_message {
struct list_head list; /* Request queueing. */
unsigned long psmid; /* Message id. */
@@ -222,7 +227,7 @@ struct ap_message {
size_t bufsize; /* allocated msg buffer size */
u16 flags; /* Flags, see AP_MSG_FLAG_xxx */
int rc; /* Return code for this message */
- void *private; /* ap driver private pointer. */
+ struct ap_response_type response;
/* receive is called from tasklet context */
void (*receive)(struct ap_queue *, struct ap_message *,
struct ap_message *);
@@ -250,7 +255,6 @@ static inline void ap_init_message(struct ap_message *ap_msg)
static inline void ap_release_message(struct ap_message *ap_msg)
{
kfree_sensitive(ap_msg->msg);
- kfree_sensitive(ap_msg->private);
}
enum ap_sm_wait ap_sm_event(struct ap_queue *aq, enum ap_sm_event event);
diff --git a/drivers/s390/crypto/zcrypt_msgtype50.c b/drivers/s390/crypto/zcrypt_msgtype50.c
index adc65eddaa1e..47c401f5409b 100644
--- a/drivers/s390/crypto/zcrypt_msgtype50.c
+++ b/drivers/s390/crypto/zcrypt_msgtype50.c
@@ -438,7 +438,7 @@ static void zcrypt_msgtype50_receive(struct ap_queue *aq,
msg->len = sizeof(error_reply);
}
out:
- complete((struct completion *)msg->private);
+ complete(&msg->response.work);
}
static atomic_t zcrypt_step = ATOMIC_INIT(0);
@@ -454,7 +454,6 @@ static long zcrypt_msgtype50_modexpo(struct zcrypt_queue *zq,
struct ica_rsa_modexpo *mex,
struct ap_message *ap_msg)
{
- struct completion work;
int rc;
ap_msg->bufsize = MSGTYPE50_CRB3_MAX_MSG_SIZE;
@@ -464,15 +463,14 @@ static long zcrypt_msgtype50_modexpo(struct zcrypt_queue *zq,
ap_msg->receive = zcrypt_msgtype50_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
- ap_msg->private = &work;
rc = ICAMEX_msg_to_type50MEX_msg(zq, ap_msg, mex);
if (rc)
goto out;
- init_completion(&work);
+ init_completion(&ap_msg->response.work);
rc = ap_queue_message(zq->queue, ap_msg);
if (rc)
goto out;
- rc = wait_for_completion_interruptible(&work);
+ rc = wait_for_completion_interruptible(&ap_msg->response.work);
if (rc == 0) {
rc = ap_msg->rc;
if (rc == 0)
@@ -485,7 +483,6 @@ static long zcrypt_msgtype50_modexpo(struct zcrypt_queue *zq,
}
out:
- ap_msg->private = NULL;
if (rc)
pr_debug("send me cprb at dev=%02x.%04x rc=%d\n",
AP_QID_CARD(zq->queue->qid),
@@ -504,7 +501,6 @@ static long zcrypt_msgtype50_modexpo_crt(struct zcrypt_queue *zq,
struct ica_rsa_modexpo_crt *crt,
struct ap_message *ap_msg)
{
- struct completion work;
int rc;
ap_msg->bufsize = MSGTYPE50_CRB3_MAX_MSG_SIZE;
@@ -514,15 +510,14 @@ static long zcrypt_msgtype50_modexpo_crt(struct zcrypt_queue *zq,
ap_msg->receive = zcrypt_msgtype50_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
- ap_msg->private = &work;
rc = ICACRT_msg_to_type50CRT_msg(zq, ap_msg, crt);
if (rc)
goto out;
- init_completion(&work);
+ init_completion(&ap_msg->response.work);
rc = ap_queue_message(zq->queue, ap_msg);
if (rc)
goto out;
- rc = wait_for_completion_interruptible(&work);
+ rc = wait_for_completion_interruptible(&ap_msg->response.work);
if (rc == 0) {
rc = ap_msg->rc;
if (rc == 0)
@@ -535,7 +530,6 @@ static long zcrypt_msgtype50_modexpo_crt(struct zcrypt_queue *zq,
}
out:
- ap_msg->private = NULL;
if (rc)
pr_debug("send crt cprb at dev=%02x.%04x rc=%d\n",
AP_QID_CARD(zq->queue->qid),
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
index b64c9d9fc613..521cc0b39990 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -31,10 +31,7 @@
#define CEIL4(x) ((((x) + 3) / 4) * 4)
-struct response_type {
- struct completion work;
- int type;
-};
+struct response_type;
#define CEXXC_RESPONSE_TYPE_ICA 0
#define CEXXC_RESPONSE_TYPE_XCRB 1
@@ -856,7 +853,7 @@ static void zcrypt_msgtype6_receive(struct ap_queue *aq,
.type = TYPE82_RSP_CODE,
.reply_code = REP82_ERROR_MACHINE_FAILURE,
};
- struct response_type *resp_type = msg->private;
+ struct ap_response_type *resp_type = &msg->response;
struct type86x_reply *t86r;
int len;
@@ -920,7 +917,7 @@ static void zcrypt_msgtype6_receive_ep11(struct ap_queue *aq,
.type = TYPE82_RSP_CODE,
.reply_code = REP82_ERROR_MACHINE_FAILURE,
};
- struct response_type *resp_type = msg->private;
+ struct ap_response_type *resp_type = &msg->response;
struct type86_ep11_reply *t86r;
int len;
@@ -967,9 +964,7 @@ static long zcrypt_msgtype6_modexpo(struct zcrypt_queue *zq,
struct ica_rsa_modexpo *mex,
struct ap_message *ap_msg)
{
- struct response_type resp_type = {
- .type = CEXXC_RESPONSE_TYPE_ICA,
- };
+ struct ap_response_type *resp_type = &ap_msg->response;
int rc;
ap_msg->msg = (void *)get_zeroed_page(GFP_KERNEL);
@@ -979,15 +974,15 @@ static long zcrypt_msgtype6_modexpo(struct zcrypt_queue *zq,
ap_msg->receive = zcrypt_msgtype6_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
- ap_msg->private = &resp_type;
rc = icamex_msg_to_type6mex_msgx(zq, ap_msg, mex);
if (rc)
goto out_free;
- init_completion(&resp_type.work);
+ resp_type->type = CEXXC_RESPONSE_TYPE_ICA;
+ init_completion(&resp_type->work);
rc = ap_queue_message(zq->queue, ap_msg);
if (rc)
goto out_free;
- rc = wait_for_completion_interruptible(&resp_type.work);
+ rc = wait_for_completion_interruptible(&resp_type->work);
if (rc == 0) {
rc = ap_msg->rc;
if (rc == 0)
@@ -1001,7 +996,6 @@ static long zcrypt_msgtype6_modexpo(struct zcrypt_queue *zq,
out_free:
free_page((unsigned long)ap_msg->msg);
- ap_msg->private = NULL;
ap_msg->msg = NULL;
return rc;
}
@@ -1017,9 +1011,7 @@ static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue *zq,
struct ica_rsa_modexpo_crt *crt,
struct ap_message *ap_msg)
{
- struct response_type resp_type = {
- .type = CEXXC_RESPONSE_TYPE_ICA,
- };
+ struct ap_response_type *resp_type = &ap_msg->response;
int rc;
ap_msg->msg = (void *)get_zeroed_page(GFP_KERNEL);
@@ -1029,15 +1021,15 @@ static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue *zq,
ap_msg->receive = zcrypt_msgtype6_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
- ap_msg->private = &resp_type;
rc = icacrt_msg_to_type6crt_msgx(zq, ap_msg, crt);
if (rc)
goto out_free;
- init_completion(&resp_type.work);
+ resp_type->type = CEXXC_RESPONSE_TYPE_ICA;
+ init_completion(&resp_type->work);
rc = ap_queue_message(zq->queue, ap_msg);
if (rc)
goto out_free;
- rc = wait_for_completion_interruptible(&resp_type.work);
+ rc = wait_for_completion_interruptible(&resp_type->work);
if (rc == 0) {
rc = ap_msg->rc;
if (rc == 0)
@@ -1051,7 +1043,6 @@ static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue *zq,
out_free:
free_page((unsigned long)ap_msg->msg);
- ap_msg->private = NULL;
ap_msg->msg = NULL;
return rc;
}
@@ -1069,9 +1060,7 @@ int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
struct ap_message *ap_msg,
unsigned int *func_code, unsigned short **dom)
{
- struct response_type resp_type = {
- .type = CEXXC_RESPONSE_TYPE_XCRB,
- };
+ struct ap_response_type *resp_type = &ap_msg->response;
ap_msg->bufsize = atomic_read(&ap_max_msg_size);
ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
@@ -1080,9 +1069,7 @@ int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
ap_msg->receive = zcrypt_msgtype6_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
- ap_msg->private = kmemdup(&resp_type, sizeof(resp_type), GFP_KERNEL);
- if (!ap_msg->private)
- return -ENOMEM;
+ resp_type->type = CEXXC_RESPONSE_TYPE_XCRB;
return xcrb_msg_to_type6cprb_msgx(userspace, ap_msg, xcrb, func_code, dom);
}
@@ -1097,7 +1084,7 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
struct ica_xcRB *xcrb,
struct ap_message *ap_msg)
{
- struct response_type *rtype = ap_msg->private;
+ struct ap_response_type *resp_type = &ap_msg->response;
struct {
struct type6_hdr hdr;
struct CPRBX cprbx;
@@ -1128,11 +1115,11 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
msg->hdr.fromcardlen1 -= delta;
}
- init_completion(&rtype->work);
+ init_completion(&resp_type->work);
rc = ap_queue_message(zq->queue, ap_msg);
if (rc)
goto out;
- rc = wait_for_completion_interruptible(&rtype->work);
+ rc = wait_for_completion_interruptible(&resp_type->work);
if (rc == 0) {
rc = ap_msg->rc;
if (rc == 0)
@@ -1166,9 +1153,7 @@ int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
struct ap_message *ap_msg,
unsigned int *func_code, unsigned int *domain)
{
- struct response_type resp_type = {
- .type = CEXXC_RESPONSE_TYPE_EP11,
- };
+ struct ap_response_type *resp_type = &ap_msg->response;
ap_msg->bufsize = atomic_read(&ap_max_msg_size);
ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
@@ -1177,9 +1162,7 @@ int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
ap_msg->receive = zcrypt_msgtype6_receive_ep11;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
- ap_msg->private = kmemdup(&resp_type, sizeof(resp_type), GFP_KERNEL);
- if (!ap_msg->private)
- return -ENOMEM;
+ resp_type->type = CEXXC_RESPONSE_TYPE_EP11;
return xcrb_msg_to_type6_ep11cprb_msgx(userspace, ap_msg, xcrb,
func_code, domain);
}
@@ -1197,7 +1180,7 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *
{
int rc;
unsigned int lfmt;
- struct response_type *rtype = ap_msg->private;
+ struct ap_response_type *resp_type = &ap_msg->response;
struct {
struct type6_hdr hdr;
struct ep11_cprb cprbx;
@@ -1251,11 +1234,11 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *
msg->hdr.fromcardlen1 = zq->reply.bufsize -
sizeof(struct type86_hdr) - sizeof(struct type86_fmt2_ext);
- init_completion(&rtype->work);
+ init_completion(&resp_type->work);
rc = ap_queue_message(zq->queue, ap_msg);
if (rc)
goto out;
- rc = wait_for_completion_interruptible(&rtype->work);
+ rc = wait_for_completion_interruptible(&resp_type->work);
if (rc == 0) {
rc = ap_msg->rc;
if (rc == 0)
@@ -1279,9 +1262,7 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *
int prep_rng_ap_msg(struct ap_message *ap_msg, int *func_code,
unsigned int *domain)
{
- struct response_type resp_type = {
- .type = CEXXC_RESPONSE_TYPE_XCRB,
- };
+ struct ap_response_type *resp_type = &ap_msg->response;
ap_msg->bufsize = AP_DEFAULT_MAX_MSG_SIZE;
ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
@@ -1290,9 +1271,8 @@ int prep_rng_ap_msg(struct ap_message *ap_msg, int *func_code,
ap_msg->receive = zcrypt_msgtype6_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
- ap_msg->private = kmemdup(&resp_type, sizeof(resp_type), GFP_KERNEL);
- if (!ap_msg->private)
- return -ENOMEM;
+
+ resp_type->type = CEXXC_RESPONSE_TYPE_XCRB;
rng_type6cprb_msgx(ap_msg, ZCRYPT_RNG_BUFFER_SIZE, domain);
@@ -1319,16 +1299,16 @@ static long zcrypt_msgtype6_rng(struct zcrypt_queue *zq,
short int verb_length;
short int key_length;
} __packed * msg = ap_msg->msg;
- struct response_type *rtype = ap_msg->private;
+ struct ap_response_type *resp_type = &ap_msg->response;
int rc;
msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid);
- init_completion(&rtype->work);
+ init_completion(&resp_type->work);
rc = ap_queue_message(zq->queue, ap_msg);
if (rc)
goto out;
- rc = wait_for_completion_interruptible(&rtype->work);
+ rc = wait_for_completion_interruptible(&resp_type->work);
if (rc == 0) {
rc = ap_msg->rc;
if (rc == 0)
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 02/20] s390/ap/zcrypt: Rework AP message buffer allocation
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
2025-03-04 17:20 ` [PATCH v2 01/20] s390/ap: Move response_type struct into ap_msg struct Harald Freudenberger
@ 2025-03-04 17:20 ` Harald Freudenberger
2025-03-17 13:57 ` Holger Dengler
2025-03-04 17:20 ` [PATCH v2 03/20] s390/ap: Introduce ap message buffer pool Harald Freudenberger
` (18 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:20 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Slight rework on the way how AP message buffers are allocated.
Instead of having multiple places with kmalloc() calls all
the AP message buffers are now allocated and freed on exactly
one place: ap_init_apmsg() allocates the current AP bus max
limit of ap_max_msg_size (defaults to 12KB). The AP message
buffer is then freed in ap_release_apmsg().
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/ap_bus.c | 30 ++++++++++++++++
drivers/s390/crypto/ap_bus.h | 21 ++---------
drivers/s390/crypto/zcrypt_api.c | 49 +++++++++++++++-----------
drivers/s390/crypto/zcrypt_msgtype50.c | 20 ++++++-----
drivers/s390/crypto/zcrypt_msgtype6.c | 35 +++++++++---------
5 files changed, 90 insertions(+), 65 deletions(-)
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 26e1ea1940ec..4940eaf538e9 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -546,6 +546,36 @@ static void ap_poll_thread_stop(void)
#define is_card_dev(x) ((x)->parent == ap_root_device)
#define is_queue_dev(x) ((x)->parent != ap_root_device)
+/**
+ * ap_init_apmsg() - Initialize ap_message.
+ * Initialize a message before using. Otherwise this might result in
+ * unexpected behaviour.
+ */
+int ap_init_apmsg(struct ap_message *ap_msg)
+{
+ unsigned int maxmsgsize = atomic_read(&ap_max_msg_size);
+
+ memset(ap_msg, 0, sizeof(*ap_msg));
+ ap_msg->msg = kmalloc(maxmsgsize, GFP_KERNEL);
+ if (!ap_msg->msg)
+ return -ENOMEM;
+ ap_msg->bufsize = maxmsgsize;
+
+ return 0;
+}
+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.
+ */
+void ap_release_apmsg(struct ap_message *ap_msg)
+{
+ kfree_sensitive(ap_msg->msg);
+}
+EXPORT_SYMBOL(ap_release_apmsg);
+
/**
* ap_bus_match()
* @dev: Pointer to device
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 7fd24c207bdf..483231bcdea6 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -237,25 +237,8 @@ struct ap_message {
#define AP_MSG_FLAG_USAGE 0x0002 /* CCA, EP11: usage (no admin) msg */
#define AP_MSG_FLAG_ADMIN 0x0004 /* CCA, EP11: admin (=control) msg */
-/**
- * ap_init_message() - Initialize ap_message.
- * Initialize a message before using. Otherwise this might result in
- * unexpected behaviour.
- */
-static inline void ap_init_message(struct ap_message *ap_msg)
-{
- memset(ap_msg, 0, sizeof(*ap_msg));
-}
-
-/**
- * ap_release_message() - Release ap_message.
- * Releases all memory used internal within the ap_message struct
- * Currently this is the message and private field.
- */
-static inline void ap_release_message(struct ap_message *ap_msg)
-{
- kfree_sensitive(ap_msg->msg);
-}
+int ap_init_apmsg(struct ap_message *ap_msg);
+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);
enum ap_sm_wait ap_sm_event_loop(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 5020696f1379..78df25da0b95 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -642,16 +642,17 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,
struct zcrypt_queue *zq, *pref_zq;
struct ap_message ap_msg;
unsigned int wgt = 0, pref_wgt = 0;
- unsigned int func_code;
- int cpen, qpen, qid = 0, rc = -ENODEV;
+ unsigned int func_code = 0;
+ int cpen, qpen, qid = 0, rc;
struct module *mod;
trace_s390_zcrypt_req(mex, TP_ICARSAMODEXPO);
- ap_init_message(&ap_msg);
+ rc = ap_init_apmsg(&ap_msg);
+ if (rc)
+ goto out;
if (mex->outputdatalength < mex->inputdatalength) {
- func_code = 0;
rc = -EINVAL;
goto out;
}
@@ -728,7 +729,7 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,
spin_unlock(&zcrypt_list_lock);
out:
- ap_release_message(&ap_msg);
+ ap_release_apmsg(&ap_msg);
if (tr) {
tr->last_rc = rc;
tr->last_qid = qid;
@@ -746,16 +747,17 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
struct zcrypt_queue *zq, *pref_zq;
struct ap_message ap_msg;
unsigned int wgt = 0, pref_wgt = 0;
- unsigned int func_code;
- int cpen, qpen, qid = 0, rc = -ENODEV;
+ unsigned int func_code = 0;
+ int cpen, qpen, qid = 0, rc;
struct module *mod;
trace_s390_zcrypt_req(crt, TP_ICARSACRT);
- ap_init_message(&ap_msg);
+ rc = ap_init_apmsg(&ap_msg);
+ if (rc)
+ goto out;
if (crt->outputdatalength < crt->inputdatalength) {
- func_code = 0;
rc = -EINVAL;
goto out;
}
@@ -832,7 +834,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
spin_unlock(&zcrypt_list_lock);
out:
- ap_release_message(&ap_msg);
+ ap_release_apmsg(&ap_msg);
if (tr) {
tr->last_rc = rc;
tr->last_qid = qid;
@@ -850,15 +852,18 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
struct zcrypt_queue *zq, *pref_zq;
struct ap_message ap_msg;
unsigned int wgt = 0, pref_wgt = 0;
- unsigned int func_code;
+ unsigned int func_code = 0;
unsigned short *domain, tdom;
- int cpen, qpen, qid = 0, rc = -ENODEV;
+ int cpen, qpen, qid = 0, rc;
struct module *mod;
trace_s390_zcrypt_req(xcrb, TB_ZSECSENDCPRB);
xcrb->status = 0;
- ap_init_message(&ap_msg);
+
+ rc = ap_init_apmsg(&ap_msg);
+ if (rc)
+ goto out;
rc = prep_cca_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);
if (rc)
@@ -962,7 +967,7 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
spin_unlock(&zcrypt_list_lock);
out:
- ap_release_message(&ap_msg);
+ ap_release_apmsg(&ap_msg);
if (tr) {
tr->last_rc = rc;
tr->last_qid = qid;
@@ -1033,14 +1038,16 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
struct ep11_target_dev *targets;
unsigned short target_num;
unsigned int wgt = 0, pref_wgt = 0;
- unsigned int func_code, domain;
+ unsigned int func_code = 0, domain;
struct ap_message ap_msg;
- int cpen, qpen, qid = 0, rc = -ENODEV;
+ int cpen, qpen, qid = 0, rc;
struct module *mod;
trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB);
- ap_init_message(&ap_msg);
+ rc = ap_init_apmsg(&ap_msg);
+ if (rc)
+ goto out;
target_num = (unsigned short)xcrb->targets_num;
@@ -1164,7 +1171,7 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
out_free:
kfree(targets);
out:
- ap_release_message(&ap_msg);
+ ap_release_apmsg(&ap_msg);
if (tr) {
tr->last_rc = rc;
tr->last_qid = qid;
@@ -1212,7 +1219,9 @@ static long zcrypt_rng(char *buffer)
trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB);
- ap_init_message(&ap_msg);
+ rc = ap_init_apmsg(&ap_msg);
+ if (rc)
+ goto out;
rc = prep_rng_ap_msg(&ap_msg, &func_code, &domain);
if (rc)
goto out;
@@ -1258,7 +1267,7 @@ static long zcrypt_rng(char *buffer)
spin_unlock(&zcrypt_list_lock);
out:
- ap_release_message(&ap_msg);
+ ap_release_apmsg(&ap_msg);
trace_s390_zcrypt_rep(buffer, func_code, rc,
AP_QID_CARD(qid), AP_QID_QUEUE(qid));
return rc;
diff --git a/drivers/s390/crypto/zcrypt_msgtype50.c b/drivers/s390/crypto/zcrypt_msgtype50.c
index 47c401f5409b..fc0a2a053dc2 100644
--- a/drivers/s390/crypto/zcrypt_msgtype50.c
+++ b/drivers/s390/crypto/zcrypt_msgtype50.c
@@ -449,6 +449,10 @@ static atomic_t zcrypt_step = ATOMIC_INIT(0);
* @zq: pointer to zcrypt_queue structure that identifies the
* CEXxA device to the request distributor
* @mex: pointer to the modexpo request buffer
+ * This function assumes that ap_msg has been initialized with
+ * ap_init_apmsg() and thus a valid buffer with the size of
+ * ap_msg->bufsize is available within ap_msg. Also the caller has
+ * to make sure ap_release_apmsg() is always called even on failure.
*/
static long zcrypt_msgtype50_modexpo(struct zcrypt_queue *zq,
struct ica_rsa_modexpo *mex,
@@ -456,10 +460,8 @@ static long zcrypt_msgtype50_modexpo(struct zcrypt_queue *zq,
{
int rc;
- ap_msg->bufsize = MSGTYPE50_CRB3_MAX_MSG_SIZE;
- ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
- if (!ap_msg->msg)
- return -ENOMEM;
+ if (ap_msg->bufsize < MSGTYPE50_CRB3_MAX_MSG_SIZE)
+ return -EMSGSIZE;
ap_msg->receive = zcrypt_msgtype50_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
@@ -496,6 +498,10 @@ static long zcrypt_msgtype50_modexpo(struct zcrypt_queue *zq,
* @zq: pointer to zcrypt_queue structure that identifies the
* CEXxA device to the request distributor
* @crt: pointer to the modexpoc_crt request buffer
+ * This function assumes that ap_msg has been initialized with
+ * ap_init_apmsg() and thus a valid buffer with the size of
+ * ap_msg->bufsize is available within ap_msg. Also the caller has
+ * to make sure ap_release_apmsg() is always called even on failure.
*/
static long zcrypt_msgtype50_modexpo_crt(struct zcrypt_queue *zq,
struct ica_rsa_modexpo_crt *crt,
@@ -503,10 +509,8 @@ static long zcrypt_msgtype50_modexpo_crt(struct zcrypt_queue *zq,
{
int rc;
- ap_msg->bufsize = MSGTYPE50_CRB3_MAX_MSG_SIZE;
- ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
- if (!ap_msg->msg)
- return -ENOMEM;
+ if (ap_msg->bufsize < MSGTYPE50_CRB3_MAX_MSG_SIZE)
+ return -EMSGSIZE;
ap_msg->receive = zcrypt_msgtype50_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
index 521cc0b39990..76972027edfd 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -1052,9 +1052,10 @@ static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue *zq,
* Prepare a CCA AP msg: fetch the required data from userspace,
* prepare the AP msg, fill some info into the ap_message struct,
* extract some data from the CPRB and give back to the caller.
- * This function allocates memory and needs an ap_msg prepared
- * by the caller with ap_init_message(). Also the caller has to
- * make sure ap_release_message() is always called even on failure.
+ * This function assumes that ap_msg has been initialized with
+ * ap_init_apmsg() and thus a valid buffer with the size of
+ * ap_msg->bufsize is available within ap_msg. Also the caller has
+ * to make sure ap_release_apmsg() is always called even on failure.
*/
int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
struct ap_message *ap_msg,
@@ -1062,10 +1063,6 @@ int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
{
struct ap_response_type *resp_type = &ap_msg->response;
- ap_msg->bufsize = atomic_read(&ap_max_msg_size);
- ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
- if (!ap_msg->msg)
- return -ENOMEM;
ap_msg->receive = zcrypt_msgtype6_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
@@ -1145,9 +1142,10 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
* Prepare an EP11 AP msg: fetch the required data from userspace,
* prepare the AP msg, fill some info into the ap_message struct,
* extract some data from the CPRB and give back to the caller.
- * This function allocates memory and needs an ap_msg prepared
- * by the caller with ap_init_message(). Also the caller has to
- * make sure ap_release_message() is always called even on failure.
+ * This function assumes that ap_msg has been initialized with
+ * ap_init_apmsg() and thus a valid buffer with the size of
+ * ap_msg->bufsize is available within ap_msg. Also the caller has
+ * to make sure ap_release_apmsg() is always called even on failure.
*/
int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
struct ap_message *ap_msg,
@@ -1155,10 +1153,6 @@ int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
{
struct ap_response_type *resp_type = &ap_msg->response;
- ap_msg->bufsize = atomic_read(&ap_max_msg_size);
- ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
- if (!ap_msg->msg)
- return -ENOMEM;
ap_msg->receive = zcrypt_msgtype6_receive_ep11;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
@@ -1259,15 +1253,20 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *
return rc;
}
+/*
+ * Prepare a CEXXC get random request ap message.
+ * This function assumes that ap_msg has been initialized with
+ * ap_init_apmsg() and thus a valid buffer with the size of
+ * ap_max_msg_size is available within ap_msg. Also the caller has
+ * to make sure ap_release_apmsg() is always called even on failure.
+ */
int prep_rng_ap_msg(struct ap_message *ap_msg, int *func_code,
unsigned int *domain)
{
struct ap_response_type *resp_type = &ap_msg->response;
- ap_msg->bufsize = AP_DEFAULT_MAX_MSG_SIZE;
- ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
- if (!ap_msg->msg)
- return -ENOMEM;
+ if (ap_msg->bufsize < AP_DEFAULT_MAX_MSG_SIZE)
+ return -EMSGSIZE;
ap_msg->receive = zcrypt_msgtype6_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 03/20] s390/ap: Introduce ap message buffer pool
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
2025-03-04 17:20 ` [PATCH v2 01/20] s390/ap: Move response_type struct into ap_msg struct Harald Freudenberger
2025-03-04 17:20 ` [PATCH v2 02/20] s390/ap/zcrypt: Rework AP message buffer allocation Harald Freudenberger
@ 2025-03-04 17:20 ` Harald Freudenberger
2025-03-17 16:14 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 04/20] s390/ap/zcrypt: New xflag parameter and extension of the ap msg flags Harald Freudenberger
` (17 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:20 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
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>
---
drivers/s390/crypto/ap_bus.c | 57 ++++++++++++++++++++++++++++----
drivers/s390/crypto/ap_bus.h | 9 ++---
drivers/s390/crypto/zcrypt_api.c | 10 +++---
3 files changed, 60 insertions(+), 16 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..a7bd44e5cc76 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -233,11 +233,12 @@ struct ap_message {
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_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 from 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
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 04/20] s390/ap/zcrypt: New xflag parameter and extension of the ap msg flags
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (2 preceding siblings ...)
2025-03-04 17:20 ` [PATCH v2 03/20] s390/ap: Introduce ap message buffer pool Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-18 12:16 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 05/20] s390/zcrypt: Introduce cprb mempool for cca misc functions Harald Freudenberger
` (16 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Introduce a new flag parameter for the both cprb send functions
zcrypt_send_cprb() and zcrypt_send_ep11_cprb(). This new
xflags parameter ("execution flags") shall be used to provide
execution hints and flags for this crypto request.
There are two flags implemented to be used with these functions:
* ZCRYPT_XFLAG_USERSPACE - indicates to the lower layers that
all the ptrs address userspace. So when construction the ap msg
copy_from_user() is to be used. If this flag is NOT set, the ptrs
address kernel memory and thus memcpy() is to be used.
* ZCRYPT_XFLAG_NOMEMALLOC - indicates that this task must not
allocate memory which may be allocated with io operations.
For the zcrypt layer this limits the number of EP11 targets
to 16 APQNs. But as this flag is passed down the stack, it
may induce further restrictions.
For the AP bus and zcrypt message layer this means:
* The ZCRYPT_XFLAG_USERSPACE is mapped to the AP flag
AP_MSG_FLAG_USERSPACE stored into the flags field of each
ap message in the ap_message struct. This replaces the extra
function parameter "userspace" and makes some function
invocations simpler.
* The ZCRYPT_XFLAG_NOMEMALLOC causes the AP message buffer to
use buffer space from the AP message mempool instead of
allocating memory via kmalloc. Note that the buffer space
from the AP message mem pool is limited to 12KB per item.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/ap_bus.c | 6 +-
drivers/s390/crypto/ap_bus.h | 11 ++--
drivers/s390/crypto/zcrypt_api.c | 90 +++++++++++++++------------
drivers/s390/crypto/zcrypt_api.h | 36 +++++++----
drivers/s390/crypto/zcrypt_ccamisc.c | 16 ++---
drivers/s390/crypto/zcrypt_ep11misc.c | 10 +--
drivers/s390/crypto/zcrypt_msgtype6.c | 12 ++--
drivers/s390/crypto/zcrypt_msgtype6.h | 4 +-
8 files changed, 107 insertions(+), 78 deletions(-)
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 75dbab9dff4a..7b092fb82ac3 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -569,18 +569,18 @@ static void ap_poll_thread_stop(void)
* Initialize struct ap_message and allocate buffer to construct
* the ap message.
*/
-int ap_init_apmsg(struct ap_message *ap_msg, bool use_mempool)
+int ap_init_apmsg(struct ap_message *ap_msg, u32 flags)
{
unsigned int maxmsgsize;
memset(ap_msg, 0, sizeof(*ap_msg));
+ ap_msg->flags = flags;
- if (use_mempool) {
+ if (flags & AP_MSG_FLAG_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;
}
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index a7bd44e5cc76..5581fb13af73 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -233,12 +233,13 @@ struct ap_message {
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 from mempool */
+#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 from mempool */
+#define AP_MSG_FLAG_USERSPACE 0x0010 /* pointers address userspace memory */
-int ap_init_apmsg(struct ap_message *ap_msg, bool use_mempool);
+int ap_init_apmsg(struct ap_message *ap_msg, u32 flags);
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 ad09c5306e28..659fe7afb67e 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, false);
+ rc = ap_init_apmsg(&ap_msg, AP_MSG_FLAG_USERSPACE);
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, false);
+ rc = ap_init_apmsg(&ap_msg, AP_MSG_FLAG_USERSPACE);
if (rc)
goto out;
@@ -844,7 +844,7 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
return rc;
}
-static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
+static long _zcrypt_send_cprb(u32 xflags, struct ap_perms *perms,
struct zcrypt_track *tr,
struct ica_xcRB *xcrb)
{
@@ -856,16 +856,19 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
unsigned short *domain, tdom;
int cpen, qpen, qid = 0, rc;
struct module *mod;
+ u32 flags;
trace_s390_zcrypt_req(xcrb, TB_ZSECSENDCPRB);
xcrb->status = 0;
- rc = ap_init_apmsg(&ap_msg, false);
+ flags = (xflags & ZCRYPT_XFLAG_USERSPACE ? AP_MSG_FLAG_USERSPACE : 0) |
+ (xflags & ZCRYPT_XFLAG_NOMEMALLOC ? AP_MSG_FLAG_MEMPOOL : 0);
+ rc = ap_init_apmsg(&ap_msg, flags);
if (rc)
goto out;
- rc = prep_cca_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);
+ rc = prep_cca_ap_msg(xcrb, &ap_msg, &func_code, &domain);
if (rc)
goto out;
print_hex_dump_debug("ccareq: ", DUMP_PREFIX_ADDRESS, 16, 1,
@@ -956,7 +959,7 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
if (*domain == AUTOSEL_DOM)
*domain = AP_QID_QUEUE(qid);
- rc = pref_zq->ops->send_cprb(userspace, pref_zq, xcrb, &ap_msg);
+ rc = pref_zq->ops->send_cprb(pref_zq, xcrb, &ap_msg);
if (!rc) {
print_hex_dump_debug("ccarpl: ", DUMP_PREFIX_ADDRESS, 16, 1,
ap_msg.msg, ap_msg.len, false);
@@ -977,7 +980,7 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
return rc;
}
-long zcrypt_send_cprb(struct ica_xcRB *xcrb)
+long zcrypt_send_cprb(struct ica_xcRB *xcrb, u32 xflags)
{
struct zcrypt_track tr;
int rc;
@@ -985,13 +988,13 @@ long zcrypt_send_cprb(struct ica_xcRB *xcrb)
memset(&tr, 0, sizeof(tr));
do {
- rc = _zcrypt_send_cprb(false, &ap_perms, &tr, xcrb);
+ rc = _zcrypt_send_cprb(xflags, &ap_perms, &tr, xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
/* on ENODEV failure: retry once again after a requested rescan */
if (rc == -ENODEV && zcrypt_process_rescan())
do {
- rc = _zcrypt_send_cprb(false, &ap_perms, &tr, xcrb);
+ rc = _zcrypt_send_cprb(xflags, &ap_perms, &tr, xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
@@ -1029,52 +1032,58 @@ static bool is_desired_ep11_queue(unsigned int dev_qid,
return false;
}
-static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
+static long _zcrypt_send_ep11_cprb(u32 xflags, struct ap_perms *perms,
struct zcrypt_track *tr,
struct ep11_urb *xcrb)
{
struct zcrypt_card *zc, *pref_zc;
struct zcrypt_queue *zq, *pref_zq;
- struct ep11_target_dev *targets;
+ struct ep11_target_dev targetbuf[16], *targets = NULL;
unsigned short target_num;
unsigned int wgt = 0, pref_wgt = 0;
unsigned int func_code = 0, domain;
struct ap_message ap_msg;
int cpen, qpen, qid = 0, rc;
struct module *mod;
+ u32 flags;
trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB);
- rc = ap_init_apmsg(&ap_msg, false);
+ flags = (xflags & ZCRYPT_XFLAG_USERSPACE ? AP_MSG_FLAG_USERSPACE : 0) |
+ (xflags & ZCRYPT_XFLAG_NOMEMALLOC ? AP_MSG_FLAG_MEMPOOL : 0);
+ rc = ap_init_apmsg(&ap_msg, flags);
if (rc)
goto out;
target_num = (unsigned short)xcrb->targets_num;
/* empty list indicates autoselect (all available targets) */
- targets = NULL;
+ rc = -ENOMEM;
if (target_num != 0) {
struct ep11_target_dev __user *uptr;
- targets = kcalloc(target_num, sizeof(*targets), GFP_KERNEL);
- if (!targets) {
- func_code = 0;
- rc = -ENOMEM;
+ if (target_num <= ARRAY_SIZE(targetbuf)) {
+ targets = targetbuf;
+ } else if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
goto out;
+ } else {
+ targets = kcalloc(target_num,
+ sizeof(*targets), GFP_KERNEL);
+ if (!targets)
+ goto out;
}
uptr = (struct ep11_target_dev __force __user *)xcrb->targets;
- if (z_copy_from_user(userspace, targets, uptr,
- target_num * sizeof(*targets))) {
- func_code = 0;
+ if (z_copy_from_user(xflags & ZCRYPT_XFLAG_USERSPACE, targets,
+ uptr, target_num * sizeof(*targets))) {
rc = -EFAULT;
- goto out_free;
+ goto out;
}
}
- rc = prep_ep11_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);
+ rc = prep_ep11_ap_msg(xcrb, &ap_msg, &func_code, &domain);
if (rc)
- goto out_free;
+ goto out;
print_hex_dump_debug("ep11req: ", DUMP_PREFIX_ADDRESS, 16, 1,
ap_msg.msg, ap_msg.len, false);
@@ -1082,11 +1091,11 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
if (ap_msg.flags & AP_MSG_FLAG_ADMIN) {
if (!test_bit_inv(domain, perms->adm)) {
rc = -ENODEV;
- goto out_free;
+ goto out;
}
} else if ((ap_msg.flags & AP_MSG_FLAG_USAGE) == 0) {
rc = -EOPNOTSUPP;
- goto out_free;
+ goto out;
}
}
@@ -1154,11 +1163,11 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
pr_debug("no match for address ff.ffff => ENODEV\n");
}
rc = -ENODEV;
- goto out_free;
+ goto out;
}
qid = pref_zq->queue->qid;
- rc = pref_zq->ops->send_ep11_cprb(userspace, pref_zq, xcrb, &ap_msg);
+ rc = pref_zq->ops->send_ep11_cprb(pref_zq, xcrb, &ap_msg);
if (!rc) {
print_hex_dump_debug("ep11rpl: ", DUMP_PREFIX_ADDRESS, 16, 1,
ap_msg.msg, ap_msg.len, false);
@@ -1168,9 +1177,9 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt);
spin_unlock(&zcrypt_list_lock);
-out_free:
- kfree(targets);
out:
+ if (targets && targets != targetbuf)
+ kfree(targets);
ap_release_apmsg(&ap_msg);
if (tr) {
tr->last_rc = rc;
@@ -1181,7 +1190,7 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
return rc;
}
-long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
+long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb, u32 xflags)
{
struct zcrypt_track tr;
int rc;
@@ -1189,13 +1198,13 @@ long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
memset(&tr, 0, sizeof(tr));
do {
- rc = _zcrypt_send_ep11_cprb(false, &ap_perms, &tr, xcrb);
+ rc = _zcrypt_send_ep11_cprb(xflags, &ap_perms, &tr, xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
/* on ENODEV failure: retry once again after a requested rescan */
if (rc == -ENODEV && zcrypt_process_rescan())
do {
- rc = _zcrypt_send_ep11_cprb(false, &ap_perms, &tr, xcrb);
+ rc = _zcrypt_send_ep11_cprb(xflags, &ap_perms, &tr, xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
@@ -1219,7 +1228,7 @@ static long zcrypt_rng(char *buffer)
trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB);
- rc = ap_init_apmsg(&ap_msg, false);
+ rc = ap_init_apmsg(&ap_msg, 0);
if (rc)
goto out;
rc = prep_rng_ap_msg(&ap_msg, &func_code, &domain);
@@ -1532,6 +1541,7 @@ static int zsecsendcprb_ioctl(struct ap_perms *perms, unsigned long arg)
int rc;
struct ica_xcRB xcrb;
struct zcrypt_track tr;
+ u32 xflags = ZCRYPT_XFLAG_USERSPACE;
struct ica_xcRB __user *uxcrb = (void __user *)arg;
memset(&tr, 0, sizeof(tr));
@@ -1539,13 +1549,13 @@ static int zsecsendcprb_ioctl(struct ap_perms *perms, unsigned long arg)
return -EFAULT;
do {
- rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb);
+ rc = _zcrypt_send_cprb(xflags, perms, &tr, &xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
/* on ENODEV failure: retry once again after a requested rescan */
if (rc == -ENODEV && zcrypt_process_rescan())
do {
- rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb);
+ rc = _zcrypt_send_cprb(xflags, perms, &tr, &xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
@@ -1562,6 +1572,7 @@ static int zsendep11cprb_ioctl(struct ap_perms *perms, unsigned long arg)
int rc;
struct ep11_urb xcrb;
struct zcrypt_track tr;
+ u32 xflags = ZCRYPT_XFLAG_USERSPACE;
struct ep11_urb __user *uxcrb = (void __user *)arg;
memset(&tr, 0, sizeof(tr));
@@ -1569,13 +1580,13 @@ static int zsendep11cprb_ioctl(struct ap_perms *perms, unsigned long arg)
return -EFAULT;
do {
- rc = _zcrypt_send_ep11_cprb(true, perms, &tr, &xcrb);
+ rc = _zcrypt_send_ep11_cprb(xflags, perms, &tr, &xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
/* on ENODEV failure: retry once again after a requested rescan */
if (rc == -ENODEV && zcrypt_process_rescan())
do {
- rc = _zcrypt_send_ep11_cprb(true, perms, &tr, &xcrb);
+ rc = _zcrypt_send_ep11_cprb(xflags, perms, &tr, &xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
@@ -1836,6 +1847,7 @@ static long trans_xcrb32(struct ap_perms *perms, struct file *filp,
unsigned int cmd, unsigned long arg)
{
struct compat_ica_xcrb __user *uxcrb32 = compat_ptr(arg);
+ u32 xflags = ZCRYPT_XFLAG_USERSPACE;
struct compat_ica_xcrb xcrb32;
struct zcrypt_track tr;
struct ica_xcRB xcrb64;
@@ -1865,13 +1877,13 @@ static long trans_xcrb32(struct ap_perms *perms, struct file *filp,
xcrb64.priority_window = xcrb32.priority_window;
xcrb64.status = xcrb32.status;
do {
- rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb64);
+ rc = _zcrypt_send_cprb(xflags, perms, &tr, &xcrb64);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
/* on ENODEV failure: retry once again after a requested rescan */
if (rc == -ENODEV && zcrypt_process_rescan())
do {
- rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb64);
+ rc = _zcrypt_send_cprb(xflags, perms, &tr, &xcrb64);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h
index 4ed481df57ca..8550a1eceb05 100644
--- a/drivers/s390/crypto/zcrypt_api.h
+++ b/drivers/s390/crypto/zcrypt_api.h
@@ -76,17 +76,29 @@ struct zcrypt_track {
#define TRACK_AGAIN_CARD_WEIGHT_PENALTY 1000
#define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY 10000
+/*
+ * xflags - to be used with zcrypt_send_cprb() and
+ * zcrypt_send_ep11_cprb() for the xflags parameter.
+ */
+#define ZCRYPT_XFLAG_USERSPACE 0x0001 /* data ptrs address userspace */
+#define ZCRYPT_XFLAG_NOMEMALLOC 0x0002 /* do not allocate fresh memory */
+
struct zcrypt_ops {
- long (*rsa_modexpo)(struct zcrypt_queue *, struct ica_rsa_modexpo *,
- struct ap_message *);
- long (*rsa_modexpo_crt)(struct zcrypt_queue *,
- struct ica_rsa_modexpo_crt *,
- struct ap_message *);
- long (*send_cprb)(bool userspace, struct zcrypt_queue *, struct ica_xcRB *,
- struct ap_message *);
- long (*send_ep11_cprb)(bool userspace, struct zcrypt_queue *, struct ep11_urb *,
- struct ap_message *);
- long (*rng)(struct zcrypt_queue *, char *, struct ap_message *);
+ long (*rsa_modexpo)(struct zcrypt_queue *zq,
+ struct ica_rsa_modexpo *icamodexp,
+ struct ap_message *apmsg);
+ long (*rsa_modexpo_crt)(struct zcrypt_queue *zq,
+ struct ica_rsa_modexpo_crt *icacrt,
+ struct ap_message *apmsg);
+ long (*send_cprb)(struct zcrypt_queue *zq,
+ struct ica_xcRB *icaxcrb,
+ struct ap_message *apmsg);
+ long (*send_ep11_cprb)(struct zcrypt_queue *zq,
+ struct ep11_urb *ep11urb,
+ struct ap_message *apmsg);
+ long (*rng)(struct zcrypt_queue *zq,
+ char *buffer,
+ struct ap_message *apmsg);
struct list_head list; /* zcrypt ops list. */
struct module *owner;
int variant;
@@ -161,8 +173,8 @@ void zcrypt_msgtype_unregister(struct zcrypt_ops *);
struct zcrypt_ops *zcrypt_msgtype(unsigned char *, int);
int zcrypt_api_init(void);
void zcrypt_api_exit(void);
-long zcrypt_send_cprb(struct ica_xcRB *xcRB);
-long zcrypt_send_ep11_cprb(struct ep11_urb *urb);
+long zcrypt_send_cprb(struct ica_xcRB *xcRB, u32 xflags);
+long zcrypt_send_ep11_cprb(struct ep11_urb *urb, u32 xflags);
void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus);
int zcrypt_device_status_ext(int card, int queue,
struct zcrypt_device_status_ext *devstatus);
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
index 43a27cb3db84..521baaea06ff 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.c
+++ b/drivers/s390/crypto/zcrypt_ccamisc.c
@@ -379,7 +379,7 @@ int cca_genseckey(u16 cardnr, u16 domain,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb);
+ rc = zcrypt_send_cprb(&xcrb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, errno %d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -517,7 +517,7 @@ int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb);
+ rc = zcrypt_send_cprb(&xcrb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -644,7 +644,7 @@ int cca_sec2protkey(u16 cardnr, u16 domain,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb);
+ rc = zcrypt_send_cprb(&xcrb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -872,7 +872,7 @@ int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb);
+ rc = zcrypt_send_cprb(&xcrb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -1038,7 +1038,7 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb);
+ rc = zcrypt_send_cprb(&xcrb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -1249,7 +1249,7 @@ int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb);
+ rc = zcrypt_send_cprb(&xcrb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -1412,7 +1412,7 @@ int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb);
+ rc = zcrypt_send_cprb(&xcrb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -1526,7 +1526,7 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb);
+ rc = zcrypt_send_cprb(&xcrb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
index cb7e6da43602..b60e262bcaa3 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.c
+++ b/drivers/s390/crypto/zcrypt_ep11misc.c
@@ -636,7 +636,7 @@ static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
req, sizeof(*req) + sizeof(*req_pl),
rep, sizeof(*rep) + sizeof(*rep_pl) + buflen);
- rc = zcrypt_send_ep11_cprb(urb);
+ rc = zcrypt_send_ep11_cprb(urb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -892,7 +892,7 @@ static int _ep11_genaeskey(u16 card, u16 domain,
req, sizeof(*req) + req_pl_size,
rep, sizeof(*rep) + sizeof(*rep_pl));
- rc = zcrypt_send_ep11_cprb(urb);
+ rc = zcrypt_send_ep11_cprb(urb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
__func__, (int)card, (int)domain, rc);
@@ -1049,7 +1049,7 @@ static int ep11_cryptsingle(u16 card, u16 domain,
req, sizeof(*req) + req_pl_size,
rep, sizeof(*rep) + rep_pl_size);
- rc = zcrypt_send_ep11_cprb(urb);
+ rc = zcrypt_send_ep11_cprb(urb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
__func__, (int)card, (int)domain, rc);
@@ -1212,7 +1212,7 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
req, sizeof(*req) + req_pl_size,
rep, sizeof(*rep) + sizeof(*rep_pl));
- rc = zcrypt_send_ep11_cprb(urb);
+ rc = zcrypt_send_ep11_cprb(urb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
__func__, (int)card, (int)domain, rc);
@@ -1372,7 +1372,7 @@ static int _ep11_wrapkey(u16 card, u16 domain,
req, sizeof(*req) + req_pl_size,
rep, sizeof(*rep) + sizeof(*rep_pl));
- rc = zcrypt_send_ep11_cprb(urb);
+ rc = zcrypt_send_ep11_cprb(urb, 0);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
__func__, (int)card, (int)domain, rc);
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
index 76972027edfd..8ffe7505b994 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -1057,11 +1057,12 @@ static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue *zq,
* ap_msg->bufsize is available within ap_msg. Also the caller has
* to make sure ap_release_apmsg() is always called even on failure.
*/
-int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
+int prep_cca_ap_msg(struct ica_xcRB *xcrb,
struct ap_message *ap_msg,
unsigned int *func_code, unsigned short **dom)
{
struct ap_response_type *resp_type = &ap_msg->response;
+ bool userspace = ap_msg->flags & AP_MSG_FLAG_USERSPACE;
ap_msg->receive = zcrypt_msgtype6_receive;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
@@ -1077,11 +1078,12 @@ int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
* CEXxC device to the request distributor
* @xcrb: pointer to the send_cprb request buffer
*/
-static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
+static long zcrypt_msgtype6_send_cprb(struct zcrypt_queue *zq,
struct ica_xcRB *xcrb,
struct ap_message *ap_msg)
{
struct ap_response_type *resp_type = &ap_msg->response;
+ bool userspace = ap_msg->flags & AP_MSG_FLAG_USERSPACE;
struct {
struct type6_hdr hdr;
struct CPRBX cprbx;
@@ -1147,11 +1149,12 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
* ap_msg->bufsize is available within ap_msg. Also the caller has
* to make sure ap_release_apmsg() is always called even on failure.
*/
-int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
+int prep_ep11_ap_msg(struct ep11_urb *xcrb,
struct ap_message *ap_msg,
unsigned int *func_code, unsigned int *domain)
{
struct ap_response_type *resp_type = &ap_msg->response;
+ bool userspace = ap_msg->flags & AP_MSG_FLAG_USERSPACE;
ap_msg->receive = zcrypt_msgtype6_receive_ep11;
ap_msg->psmid = (((unsigned long)current->pid) << 32) +
@@ -1168,12 +1171,13 @@ int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
* CEX4P device to the request distributor
* @xcrb: pointer to the ep11 user request block
*/
-static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *zq,
+static long zcrypt_msgtype6_send_ep11_cprb(struct zcrypt_queue *zq,
struct ep11_urb *xcrb,
struct ap_message *ap_msg)
{
int rc;
unsigned int lfmt;
+ bool userspace = ap_msg->flags & AP_MSG_FLAG_USERSPACE;
struct ap_response_type *resp_type = &ap_msg->response;
struct {
struct type6_hdr hdr;
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.h b/drivers/s390/crypto/zcrypt_msgtype6.h
index 6f5ced8d6cda..b2944f5b2d18 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.h
+++ b/drivers/s390/crypto/zcrypt_msgtype6.h
@@ -94,10 +94,10 @@ struct type86_fmt2_ext {
unsigned int offset4; /* 0x00000000 */
} __packed;
-int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
+int prep_cca_ap_msg(struct ica_xcRB *xcrb,
struct ap_message *ap_msg,
unsigned int *fc, unsigned short **dom);
-int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
+int prep_ep11_ap_msg(struct ep11_urb *xcrb,
struct ap_message *ap_msg,
unsigned int *fc, unsigned int *dom);
int prep_rng_ap_msg(struct ap_message *ap_msg,
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 05/20] s390/zcrypt: Introduce cprb mempool for cca misc functions
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (3 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 04/20] s390/ap/zcrypt: New xflag parameter and extension of the ap msg flags Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-18 14:16 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 06/20] s390/zcrypt: Introduce cprb mempool for ep11 " Harald Freudenberger
` (15 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Introduce a cprb mempool for the zcrypt cca misc functions
(zcrypt_ccamisc.*) do some preparation rework to support
a do-not-allocate path through some zcrypt cca misc functions.
The mempool is by default space for 4 cprbs with each 16KB.
For CCA a CPRB needs to hold the request and the reply, so
the pool items only support requests/replies with a limit of
about 8KB. The minimal number of items in the mempool can get
adjusted via module parameter zcrypt.cca_cprbpool_min_items
on module load.
This is only part of an rework to support a new xflag
ZCRYPT_XFLAG_NOMEMALLOC but not yet complete.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/zcrypt_api.c | 13 ++-
drivers/s390/crypto/zcrypt_api.h | 2 +
drivers/s390/crypto/zcrypt_ccamisc.c | 116 ++++++++++++++++++++-------
drivers/s390/crypto/zcrypt_ccamisc.h | 1 +
4 files changed, 101 insertions(+), 31 deletions(-)
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 659fe7afb67e..d7915c3fe3c0 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -50,6 +50,10 @@ MODULE_DESCRIPTION("Cryptographic Coprocessor interface, " \
"Copyright IBM Corp. 2001, 2012");
MODULE_LICENSE("GPL");
+unsigned int zcrypt_cca_cprbpool_min_items = 4;
+module_param_named(cca_cprbpool_min_items, zcrypt_cca_cprbpool_min_items, uint, 0440);
+MODULE_PARM_DESC(cca_cprbpool_min_items, "CCA CPRB pool minimal items.");
+
/*
* zcrypt tracepoint functions
*/
@@ -2159,7 +2163,11 @@ int __init zcrypt_api_init(void)
rc = zcdn_init();
if (rc)
- goto out;
+ goto out_zcdn_init_failed;
+
+ rc = zcrypt_ccamisc_init();
+ if (rc)
+ goto out_ccamisc_init_failed;
/* Register the request sprayer. */
rc = misc_register(&zcrypt_misc_device);
@@ -2172,7 +2180,10 @@ int __init zcrypt_api_init(void)
return 0;
out_misc_register_failed:
+ zcrypt_ccamisc_exit();
+out_ccamisc_init_failed:
zcdn_exit();
+out_zcdn_init_failed:
zcrypt_debug_exit();
out:
return rc;
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h
index 8550a1eceb05..d2640ea5d080 100644
--- a/drivers/s390/crypto/zcrypt_api.h
+++ b/drivers/s390/crypto/zcrypt_api.h
@@ -144,6 +144,8 @@ extern atomic_t zcrypt_rescan_req;
extern spinlock_t zcrypt_list_lock;
extern struct list_head zcrypt_card_list;
+extern unsigned int zcrypt_cca_cprbpool_min_items;
+
#define for_each_zcrypt_card(_zc) \
list_for_each_entry(_zc, &zcrypt_card_list, list)
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
index 521baaea06ff..2c2ca2d67e2d 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.c
+++ b/drivers/s390/crypto/zcrypt_ccamisc.c
@@ -11,6 +11,7 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/init.h>
+#include <linux/mempool.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/random.h>
@@ -40,6 +41,16 @@ struct cca_info_list_entry {
static LIST_HEAD(cca_info_list);
static DEFINE_SPINLOCK(cca_info_list_lock);
+/*
+ * Cprb memory pool held for urgent cases where no memory
+ * can be allocated via kmalloc. This pool is only used
+ * when alloc_and_prep_cprbmem() is called with the xflag
+ * ZCRYPT_XFLAG_NOMEMALLOC. The cprb memory needs to hold
+ * space for request AND reply!
+ */
+#define CPRB_MEMPOOL_ITEM_SIZE (16 * 1024)
+static mempool_t *cprb_mempool;
+
/*
* Simple check if the token is a valid CCA secure AES data key
* token. If keybitsize is given, the bitsize of the key is
@@ -219,9 +230,10 @@ EXPORT_SYMBOL(cca_check_sececckeytoken);
static int alloc_and_prep_cprbmem(size_t paramblen,
u8 **p_cprb_mem,
struct CPRBX **p_req_cprb,
- struct CPRBX **p_rep_cprb)
+ struct CPRBX **p_rep_cprb,
+ u32 xflags)
{
- u8 *cprbmem;
+ u8 *cprbmem = NULL;
size_t cprbplusparamblen = sizeof(struct CPRBX) + paramblen;
struct CPRBX *preqcblk, *prepcblk;
@@ -229,7 +241,15 @@ static int alloc_and_prep_cprbmem(size_t paramblen,
* allocate consecutive memory for request CPRB, request param
* block, reply CPRB and reply param block
*/
- cprbmem = kcalloc(2, cprbplusparamblen, GFP_KERNEL);
+ if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
+ if (cprb_mempool &&
+ 2 * cprbplusparamblen <= CPRB_MEMPOOL_ITEM_SIZE) {
+ cprbmem = mempool_alloc_preallocated(cprb_mempool);
+ memset(cprbmem, 0, 2 * cprbplusparamblen);
+ }
+ } else {
+ cprbmem = kcalloc(2, cprbplusparamblen, GFP_KERNEL);
+ }
if (!cprbmem)
return -ENOMEM;
@@ -261,11 +281,15 @@ static int alloc_and_prep_cprbmem(size_t paramblen,
* with zeros before freeing (useful if there was some
* clear key material in there).
*/
-static void free_cprbmem(void *mem, size_t paramblen, int scrub)
+static void free_cprbmem(void *mem, size_t paramblen, bool scrub, u32 xflags)
{
if (scrub)
memzero_explicit(mem, 2 * (sizeof(struct CPRBX) + paramblen));
- kfree(mem);
+
+ if (xflags & ZCRYPT_XFLAG_NOMEMALLOC)
+ mempool_free(mem, cprb_mempool);
+ else
+ kfree(mem);
}
/*
@@ -330,9 +354,11 @@ int cca_genseckey(u16 cardnr, u16 domain,
} keyblock;
} lv3;
} __packed * prepparm;
+ const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
- rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
+ rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
+ &preqcblk, &prepcblk, xflags);
if (rc)
return rc;
@@ -379,7 +405,7 @@ int cca_genseckey(u16 cardnr, u16 domain,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb, 0);
+ rc = zcrypt_send_cprb(&xcrb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, errno %d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -424,7 +450,7 @@ int cca_genseckey(u16 cardnr, u16 domain,
memcpy(seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE);
out:
- free_cprbmem(mem, PARMBSIZE, 0);
+ free_cprbmem(mem, PARMBSIZE, false, xflags);
return rc;
}
EXPORT_SYMBOL(cca_genseckey);
@@ -471,9 +497,11 @@ int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
} keyblock;
} lv3;
} __packed * prepparm;
+ const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
- rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
+ rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
+ &preqcblk, &prepcblk, xflags);
if (rc)
return rc;
@@ -517,7 +545,7 @@ int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb, 0);
+ rc = zcrypt_send_cprb(&xcrb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -563,7 +591,7 @@ int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
memcpy(seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE);
out:
- free_cprbmem(mem, PARMBSIZE, 1);
+ free_cprbmem(mem, PARMBSIZE, true, xflags);
return rc;
}
EXPORT_SYMBOL(cca_clr2seckey);
@@ -617,9 +645,11 @@ int cca_sec2protkey(u16 cardnr, u16 domain,
} ckb;
} lv3;
} __packed * prepparm;
+ const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
- rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
+ rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
+ &preqcblk, &prepcblk, xflags);
if (rc)
return rc;
@@ -644,7 +674,7 @@ int cca_sec2protkey(u16 cardnr, u16 domain,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb, 0);
+ rc = zcrypt_send_cprb(&xcrb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -712,7 +742,7 @@ int cca_sec2protkey(u16 cardnr, u16 domain,
*protkeylen = prepparm->lv3.ckb.len;
out:
- free_cprbmem(mem, PARMBSIZE, 0);
+ free_cprbmem(mem, PARMBSIZE, true, xflags);
return rc;
}
EXPORT_SYMBOL(cca_sec2protkey);
@@ -811,9 +841,11 @@ int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
} kb;
} __packed * prepparm;
struct cipherkeytoken *t;
+ const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
- rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
+ rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
+ &preqcblk, &prepcblk, xflags);
if (rc)
return rc;
@@ -872,7 +904,7 @@ int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb, 0);
+ rc = zcrypt_send_cprb(&xcrb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -923,7 +955,7 @@ int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
*keybufsize = t->len;
out:
- free_cprbmem(mem, PARMBSIZE, 0);
+ free_cprbmem(mem, PARMBSIZE, false, xflags);
return rc;
}
EXPORT_SYMBOL(cca_gencipherkey);
@@ -987,9 +1019,11 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
} __packed * prepparm;
struct cipherkeytoken *t;
int complete = strncmp(rule_array_2, "COMPLETE", 8) ? 0 : 1;
+ const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
- rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
+ rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
+ &preqcblk, &prepcblk, xflags);
if (rc)
return rc;
@@ -1038,7 +1072,7 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb, 0);
+ rc = zcrypt_send_cprb(&xcrb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -1077,7 +1111,7 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
*key_token_size = t->len;
out:
- free_cprbmem(mem, PARMBSIZE, 0);
+ free_cprbmem(mem, PARMBSIZE, false, xflags);
return rc;
}
@@ -1217,9 +1251,11 @@ int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
} kb;
} __packed * prepparm;
int keytoklen = ((struct cipherkeytoken *)ckey)->len;
+ const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
- rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
+ rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
+ &preqcblk, &prepcblk, xflags);
if (rc)
return rc;
@@ -1249,7 +1285,7 @@ int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb, 0);
+ rc = zcrypt_send_cprb(&xcrb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -1323,7 +1359,7 @@ int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
*protkeylen = prepparm->vud.ckb.keylen;
out:
- free_cprbmem(mem, PARMBSIZE, 0);
+ free_cprbmem(mem, PARMBSIZE, true, xflags);
return rc;
}
EXPORT_SYMBOL(cca_cipher2protkey);
@@ -1380,9 +1416,11 @@ int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
/* followed by a key block */
} __packed * prepparm;
int keylen = ((struct eccprivkeytoken *)key)->len;
+ const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
- rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
+ rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
+ &preqcblk, &prepcblk, xflags);
if (rc)
return rc;
@@ -1412,7 +1450,7 @@ int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb, 0);
+ rc = zcrypt_send_cprb(&xcrb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -1470,7 +1508,7 @@ int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
*protkeytype = PKEY_KEYTYPE_ECC;
out:
- free_cprbmem(mem, PARMBSIZE, 0);
+ free_cprbmem(mem, PARMBSIZE, true, xflags);
return rc;
}
EXPORT_SYMBOL(cca_ecc2protkey);
@@ -1503,9 +1541,11 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
u8 subfunc_code[2];
u8 lvdata[];
} __packed * prepparm;
+ const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
- rc = alloc_and_prep_cprbmem(parmbsize, &mem, &preqcblk, &prepcblk);
+ rc = alloc_and_prep_cprbmem(parmbsize, &mem,
+ &preqcblk, &prepcblk, xflags);
if (rc)
return rc;
@@ -1526,7 +1566,7 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
/* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
- rc = zcrypt_send_cprb(&xcrb, 0);
+ rc = zcrypt_send_cprb(&xcrb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -1573,7 +1613,7 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
}
out:
- free_cprbmem(mem, parmbsize, 0);
+ free_cprbmem(mem, parmbsize, false, xflags);
return rc;
}
EXPORT_SYMBOL(cca_query_crypto_facility);
@@ -1959,7 +1999,23 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
}
EXPORT_SYMBOL(cca_findcard2);
-void __exit zcrypt_ccamisc_exit(void)
+int __init zcrypt_ccamisc_init(void)
+{
+ /* Pre-allocate a small memory pool for cca cprbs. */
+ cprb_mempool = mempool_create_kmalloc_pool(zcrypt_cca_cprbpool_min_items,
+ CPRB_MEMPOOL_ITEM_SIZE);
+ if (IS_ERR(cprb_mempool)) {
+ ZCRYPT_DBF_ERR("%s mempool_create(%d,%d) failed: %ld\n",
+ __func__, zcrypt_cca_cprbpool_min_items,
+ CPRB_MEMPOOL_ITEM_SIZE, PTR_ERR(cprb_mempool));
+ cprb_mempool = NULL;
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+void zcrypt_ccamisc_exit(void)
{
mkvp_cache_free();
+ mempool_destroy(cprb_mempool);
}
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.h b/drivers/s390/crypto/zcrypt_ccamisc.h
index 26bdca702523..273edf2bb036 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.h
+++ b/drivers/s390/crypto/zcrypt_ccamisc.h
@@ -272,6 +272,7 @@ struct cca_info {
*/
int cca_get_info(u16 card, u16 dom, struct cca_info *ci, int verify);
+int zcrypt_ccamisc_init(void);
void zcrypt_ccamisc_exit(void);
#endif /* _ZCRYPT_CCAMISC_H_ */
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 06/20] s390/zcrypt: Introduce cprb mempool for ep11 misc functions
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (4 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 05/20] s390/zcrypt: Introduce cprb mempool for cca misc functions Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-18 15:16 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 07/20] s390/zcrypt: Rework zcrypt function zcrypt_device_status_mask_ext Harald Freudenberger
` (14 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Introduce a cprb mempool for the zcrypt ep11 misc functions
(zcrypt_ep11misc.*) do some preparation rework to support
a do-not-allocate path through some zcrypt cca misc functions.
The mempool is by default space for 8 cprbs with each 8KB.
For EP11 a CPRB either holds the request or the reply. So for
a request/reply there is always a couple of cprb buffers
needed. The minimal number of items in the mempool can get
adjusted via module parameter zcrypt.ep11_cprbpool_min_items
on module load.
This is only part of an rework to support a new xflag
ZCRYPT_XFLAG_NOMEMALLOC but not yet complete.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/zcrypt_api.c | 10 ++
drivers/s390/crypto/zcrypt_api.h | 1 +
drivers/s390/crypto/zcrypt_ep11misc.c | 158 ++++++++++++++++----------
drivers/s390/crypto/zcrypt_ep11misc.h | 1 +
4 files changed, 109 insertions(+), 61 deletions(-)
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index d7915c3fe3c0..62cc05881b13 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -54,6 +54,10 @@ unsigned int zcrypt_cca_cprbpool_min_items = 4;
module_param_named(cca_cprbpool_min_items, zcrypt_cca_cprbpool_min_items, uint, 0440);
MODULE_PARM_DESC(cca_cprbpool_min_items, "CCA CPRB pool minimal items.");
+unsigned int zcrypt_ep11_cprbpool_min_items = 8;
+module_param_named(ep11_cprbpool_min_items, zcrypt_ep11_cprbpool_min_items, uint, 0440);
+MODULE_PARM_DESC(ep11_cprbpool_min_items, "EP11 CPRB pool minimal items.");
+
/*
* zcrypt tracepoint functions
*/
@@ -2169,6 +2173,10 @@ int __init zcrypt_api_init(void)
if (rc)
goto out_ccamisc_init_failed;
+ rc = zcrypt_ep11misc_init();
+ if (rc)
+ goto out_ep11misc_init_failed;
+
/* Register the request sprayer. */
rc = misc_register(&zcrypt_misc_device);
if (rc < 0)
@@ -2180,6 +2188,8 @@ int __init zcrypt_api_init(void)
return 0;
out_misc_register_failed:
+ zcrypt_ep11misc_exit();
+out_ep11misc_init_failed:
zcrypt_ccamisc_exit();
out_ccamisc_init_failed:
zcdn_exit();
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h
index d2640ea5d080..25a339ef52c3 100644
--- a/drivers/s390/crypto/zcrypt_api.h
+++ b/drivers/s390/crypto/zcrypt_api.h
@@ -145,6 +145,7 @@ extern spinlock_t zcrypt_list_lock;
extern struct list_head zcrypt_card_list;
extern unsigned int zcrypt_cca_cprbpool_min_items;
+extern unsigned int zcrypt_ep11_cprbpool_min_items;
#define for_each_zcrypt_card(_zc) \
list_for_each_entry(_zc, &zcrypt_card_list, list)
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
index b60e262bcaa3..86578a95b140 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.c
+++ b/drivers/s390/crypto/zcrypt_ep11misc.c
@@ -10,9 +10,10 @@
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/init.h>
+#include <linux/mempool.h>
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/random.h>
+#include <linux/slab.h>
#include <asm/zcrypt.h>
#include <asm/pkey.h>
#include <crypto/aes.h>
@@ -30,6 +31,14 @@
static const u8 def_iv[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
+/*
+ * Cprb memory pool held for urgent cases where no memory
+ * can be allocated via kmalloc. This pool is only used when
+ * alloc_cprbmem() is called with the xflag ZCRYPT_XFLAG_NOMEMALLOC.
+ */
+#define CPRB_MEMPOOL_ITEM_SIZE (8 * 1024)
+static mempool_t *cprb_mempool;
+
/* ep11 card info cache */
struct card_list_entry {
struct list_head list;
@@ -411,12 +420,19 @@ EXPORT_SYMBOL(ep11_check_aes_key);
/*
* Allocate and prepare ep11 cprb plus additional payload.
*/
-static inline struct ep11_cprb *alloc_cprb(size_t payload_len)
+static void *alloc_cprbmem(size_t payload_len, u32 xflags)
{
size_t len = sizeof(struct ep11_cprb) + payload_len;
- struct ep11_cprb *cprb;
+ struct ep11_cprb *cprb = NULL;
- cprb = kzalloc(len, GFP_KERNEL);
+ if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
+ if (cprb_mempool && len <= CPRB_MEMPOOL_ITEM_SIZE) {
+ cprb = mempool_alloc_preallocated(cprb_mempool);
+ memset(cprb, 0, len);
+ }
+ } else {
+ cprb = kzalloc(len, GFP_KERNEL);
+ }
if (!cprb)
return NULL;
@@ -429,6 +445,20 @@ static inline struct ep11_cprb *alloc_cprb(size_t payload_len)
return cprb;
}
+/*
+ * Free ep11 cprb buffer space.
+ */
+static void free_cprbmem(void *mem, size_t payload_len, bool scrub, u32 xflags)
+{
+ if (scrub)
+ memzero_explicit(mem, sizeof(struct ep11_cprb) + payload_len);
+
+ if (xflags & ZCRYPT_XFLAG_NOMEMALLOC)
+ mempool_free(mem, cprb_mempool);
+ else
+ kfree(mem);
+}
+
/*
* Some helper functions related to ASN1 encoding.
* Limited to length info <= 2 byte.
@@ -605,11 +635,12 @@ static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
} __packed * rep_pl;
struct ep11_cprb *req = NULL, *rep = NULL;
struct ep11_target_dev target;
- struct ep11_urb *urb = NULL;
+ struct ep11_urb urb;
int api = EP11_API_V1, rc = -ENOMEM;
+ const u32 xflags = 0;
/* request cprb and payload */
- req = alloc_cprb(sizeof(struct ep11_info_req_pl));
+ req = alloc_cprbmem(sizeof(struct ep11_info_req_pl), xflags);
if (!req)
goto out;
req_pl = (struct ep11_info_req_pl *)(((u8 *)req) + sizeof(*req));
@@ -621,22 +652,20 @@ static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
req_pl->query_subtype_len = sizeof(u32);
/* reply cprb and payload */
- rep = alloc_cprb(sizeof(struct ep11_info_rep_pl) + buflen);
+ rep = alloc_cprbmem(sizeof(struct ep11_info_rep_pl) + buflen, xflags);
if (!rep)
goto out;
rep_pl = (struct ep11_info_rep_pl *)(((u8 *)rep) + sizeof(*rep));
/* urb and target */
- urb = kmalloc(sizeof(*urb), GFP_KERNEL);
- if (!urb)
- goto out;
+ memset(&urb, 0, sizeof(urb));
target.ap_id = cardnr;
target.dom_id = domain;
- prep_urb(urb, &target, 1,
+ prep_urb(&urb, &target, 1,
req, sizeof(*req) + sizeof(*req_pl),
rep, sizeof(*rep) + sizeof(*rep_pl) + buflen);
- rc = zcrypt_send_ep11_cprb(urb, 0);
+ rc = zcrypt_send_ep11_cprb(&urb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
__func__, (int)cardnr, (int)domain, rc);
@@ -667,9 +696,8 @@ static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
memcpy(buf, ((u8 *)rep_pl) + sizeof(*rep_pl), rep_pl->data_len);
out:
- kfree(req);
- kfree(rep);
- kfree(urb);
+ free_cprbmem(req, 0, false, xflags);
+ free_cprbmem(rep, 0, false, xflags);
return rc;
}
@@ -823,9 +851,10 @@ static int _ep11_genaeskey(u16 card, u16 domain,
struct ep11_cprb *req = NULL, *rep = NULL;
size_t req_pl_size, pinblob_size = 0;
struct ep11_target_dev target;
- struct ep11_urb *urb = NULL;
+ struct ep11_urb urb;
int api, rc = -ENOMEM;
u8 *p;
+ const u32 xflags = 0;
switch (keybitsize) {
case 128:
@@ -851,7 +880,7 @@ static int _ep11_genaeskey(u16 card, u16 domain,
pinblob_size = EP11_PINBLOB_V1_BYTES;
}
req_pl_size = sizeof(struct keygen_req_pl) + ASN1TAGLEN(pinblob_size);
- req = alloc_cprb(req_pl_size);
+ req = alloc_cprbmem(req_pl_size, xflags);
if (!req)
goto out;
req_pl = (struct keygen_req_pl *)(((u8 *)req) + sizeof(*req));
@@ -877,22 +906,20 @@ static int _ep11_genaeskey(u16 card, u16 domain,
*p++ = pinblob_size;
/* reply cprb and payload */
- rep = alloc_cprb(sizeof(struct keygen_rep_pl));
+ rep = alloc_cprbmem(sizeof(struct keygen_rep_pl), xflags);
if (!rep)
goto out;
rep_pl = (struct keygen_rep_pl *)(((u8 *)rep) + sizeof(*rep));
/* urb and target */
- urb = kmalloc(sizeof(*urb), GFP_KERNEL);
- if (!urb)
- goto out;
+ memset(&urb, 0, sizeof(urb));
target.ap_id = card;
target.dom_id = domain;
- prep_urb(urb, &target, 1,
+ prep_urb(&urb, &target, 1,
req, sizeof(*req) + req_pl_size,
rep, sizeof(*rep) + sizeof(*rep_pl));
- rc = zcrypt_send_ep11_cprb(urb, 0);
+ rc = zcrypt_send_ep11_cprb(&urb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
__func__, (int)card, (int)domain, rc);
@@ -925,9 +952,8 @@ static int _ep11_genaeskey(u16 card, u16 domain,
*keybufsize = rep_pl->data_len;
out:
- kfree(req);
- kfree(rep);
- kfree(urb);
+ free_cprbmem(req, 0, false, xflags);
+ free_cprbmem(rep, sizeof(struct keygen_rep_pl), true, xflags);
return rc;
}
@@ -1000,10 +1026,11 @@ static int ep11_cryptsingle(u16 card, u16 domain,
} __packed * rep_pl;
struct ep11_cprb *req = NULL, *rep = NULL;
struct ep11_target_dev target;
- struct ep11_urb *urb = NULL;
+ struct ep11_urb urb;
size_t req_pl_size, rep_pl_size;
int n, api = EP11_API_V1, rc = -ENOMEM;
u8 *p;
+ const u32 xflags = 0;
/* the simple asn1 coding used has length limits */
if (keysize > 0xFFFF || inbufsize > 0xFFFF)
@@ -1012,7 +1039,7 @@ static int ep11_cryptsingle(u16 card, u16 domain,
/* request cprb and payload */
req_pl_size = sizeof(struct crypt_req_pl) + (iv ? 16 : 0)
+ ASN1TAGLEN(keysize) + ASN1TAGLEN(inbufsize);
- req = alloc_cprb(req_pl_size);
+ req = alloc_cprbmem(req_pl_size, xflags);
if (!req)
goto out;
req_pl = (struct crypt_req_pl *)(((u8 *)req) + sizeof(*req));
@@ -1034,22 +1061,20 @@ static int ep11_cryptsingle(u16 card, u16 domain,
/* reply cprb and payload, assume out data size <= in data size + 32 */
rep_pl_size = sizeof(struct crypt_rep_pl) + ASN1TAGLEN(inbufsize + 32);
- rep = alloc_cprb(rep_pl_size);
+ rep = alloc_cprbmem(rep_pl_size, xflags);
if (!rep)
goto out;
rep_pl = (struct crypt_rep_pl *)(((u8 *)rep) + sizeof(*rep));
/* urb and target */
- urb = kmalloc(sizeof(*urb), GFP_KERNEL);
- if (!urb)
- goto out;
+ memset(&urb, 0, sizeof(urb));
target.ap_id = card;
target.dom_id = domain;
- prep_urb(urb, &target, 1,
+ prep_urb(&urb, &target, 1,
req, sizeof(*req) + req_pl_size,
rep, sizeof(*rep) + rep_pl_size);
- rc = zcrypt_send_ep11_cprb(urb, 0);
+ rc = zcrypt_send_ep11_cprb(&urb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
__func__, (int)card, (int)domain, rc);
@@ -1095,9 +1120,8 @@ static int ep11_cryptsingle(u16 card, u16 domain,
*outbufsize = n;
out:
- kfree(req);
- kfree(rep);
- kfree(urb);
+ free_cprbmem(req, req_pl_size, true, xflags);
+ free_cprbmem(rep, rep_pl_size, true, xflags);
return rc;
}
@@ -1143,9 +1167,10 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
struct ep11_cprb *req = NULL, *rep = NULL;
size_t req_pl_size, pinblob_size = 0;
struct ep11_target_dev target;
- struct ep11_urb *urb = NULL;
+ struct ep11_urb urb;
int api, rc = -ENOMEM;
u8 *p;
+ const u32 xflags = 0;
/* request cprb and payload */
api = (!keygenflags || keygenflags & 0x00200000) ?
@@ -1161,7 +1186,7 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
req_pl_size = sizeof(struct uw_req_pl) + (iv ? 16 : 0)
+ ASN1TAGLEN(keksize) + ASN1TAGLEN(0)
+ ASN1TAGLEN(pinblob_size) + ASN1TAGLEN(enckeysize);
- req = alloc_cprb(req_pl_size);
+ req = alloc_cprbmem(req_pl_size, xflags);
if (!req)
goto out;
req_pl = (struct uw_req_pl *)(((u8 *)req) + sizeof(*req));
@@ -1197,22 +1222,20 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
p += asn1tag_write(p, 0x04, enckey, enckeysize);
/* reply cprb and payload */
- rep = alloc_cprb(sizeof(struct uw_rep_pl));
+ rep = alloc_cprbmem(sizeof(struct uw_rep_pl), xflags);
if (!rep)
goto out;
rep_pl = (struct uw_rep_pl *)(((u8 *)rep) + sizeof(*rep));
/* urb and target */
- urb = kmalloc(sizeof(*urb), GFP_KERNEL);
- if (!urb)
- goto out;
+ memset(&urb, 0, sizeof(urb));
target.ap_id = card;
target.dom_id = domain;
- prep_urb(urb, &target, 1,
+ prep_urb(&urb, &target, 1,
req, sizeof(*req) + req_pl_size,
rep, sizeof(*rep) + sizeof(*rep_pl));
- rc = zcrypt_send_ep11_cprb(urb, 0);
+ rc = zcrypt_send_ep11_cprb(&urb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
__func__, (int)card, (int)domain, rc);
@@ -1245,9 +1268,8 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
*keybufsize = rep_pl->data_len;
out:
- kfree(req);
- kfree(rep);
- kfree(urb);
+ free_cprbmem(req, req_pl_size, true, xflags);
+ free_cprbmem(rep, sizeof(struct uw_rep_pl), true, xflags);
return rc;
}
@@ -1319,15 +1341,16 @@ static int _ep11_wrapkey(u16 card, u16 domain,
} __packed * rep_pl;
struct ep11_cprb *req = NULL, *rep = NULL;
struct ep11_target_dev target;
- struct ep11_urb *urb = NULL;
+ struct ep11_urb urb;
size_t req_pl_size;
int api, rc = -ENOMEM;
u8 *p;
+ const u32 xflags = 0;
/* request cprb and payload */
req_pl_size = sizeof(struct wk_req_pl) + (iv ? 16 : 0)
+ ASN1TAGLEN(keysize) + 4;
- req = alloc_cprb(req_pl_size);
+ req = alloc_cprbmem(req_pl_size, xflags);
if (!req)
goto out;
if (!mech || mech == 0x80060001)
@@ -1357,22 +1380,20 @@ static int _ep11_wrapkey(u16 card, u16 domain,
*p++ = 0;
/* reply cprb and payload */
- rep = alloc_cprb(sizeof(struct wk_rep_pl));
+ rep = alloc_cprbmem(sizeof(struct wk_rep_pl), xflags);
if (!rep)
goto out;
rep_pl = (struct wk_rep_pl *)(((u8 *)rep) + sizeof(*rep));
/* urb and target */
- urb = kmalloc(sizeof(*urb), GFP_KERNEL);
- if (!urb)
- goto out;
+ memset(&urb, 0, sizeof(urb));
target.ap_id = card;
target.dom_id = domain;
- prep_urb(urb, &target, 1,
+ prep_urb(&urb, &target, 1,
req, sizeof(*req) + req_pl_size,
rep, sizeof(*rep) + sizeof(*rep_pl));
- rc = zcrypt_send_ep11_cprb(urb, 0);
+ rc = zcrypt_send_ep11_cprb(&urb, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
__func__, (int)card, (int)domain, rc);
@@ -1405,9 +1426,8 @@ static int _ep11_wrapkey(u16 card, u16 domain,
*datasize = rep_pl->data_len;
out:
- kfree(req);
- kfree(rep);
- kfree(urb);
+ free_cprbmem(req, req_pl_size, true, xflags);
+ free_cprbmem(rep, sizeof(struct wk_rep_pl), true, xflags);
return rc;
}
@@ -1459,7 +1479,7 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
encbuf, encbuflen, 0, def_iv,
keybitsize, 0, keybuf, keybufsize, keytype);
if (rc) {
- ZCRYPT_DBF_ERR("%s importing key value as new key failed,, rc=%d\n",
+ ZCRYPT_DBF_ERR("%s importing key value as new key failed, rc=%d\n",
__func__, rc);
goto out;
}
@@ -1658,7 +1678,23 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
}
EXPORT_SYMBOL(ep11_findcard2);
-void __exit zcrypt_ep11misc_exit(void)
+int __init zcrypt_ep11misc_init(void)
+{
+ /* Pre-allocate a small memory pool for ep11 cprbs. */
+ cprb_mempool = mempool_create_kmalloc_pool(zcrypt_ep11_cprbpool_min_items,
+ CPRB_MEMPOOL_ITEM_SIZE);
+ if (IS_ERR(cprb_mempool)) {
+ ZCRYPT_DBF_ERR("%s mempool_create(%d,%d) failed: %ld\n",
+ __func__, zcrypt_ep11_cprbpool_min_items,
+ CPRB_MEMPOOL_ITEM_SIZE, PTR_ERR(cprb_mempool));
+ cprb_mempool = NULL;
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+void zcrypt_ep11misc_exit(void)
{
card_cache_free();
+ mempool_destroy(cprb_mempool);
}
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h b/drivers/s390/crypto/zcrypt_ep11misc.h
index 9f1bdffdec68..a4b98eca8431 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.h
+++ b/drivers/s390/crypto/zcrypt_ep11misc.h
@@ -152,6 +152,7 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
int ep11_kblob2protkey(u16 card, u16 dom, const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+int zcrypt_ep11misc_init(void);
void zcrypt_ep11misc_exit(void);
#endif /* _ZCRYPT_EP11MISC_H_ */
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 07/20] s390/zcrypt: Rework zcrypt function zcrypt_device_status_mask_ext
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (5 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 06/20] s390/zcrypt: Introduce cprb mempool for ep11 " Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-19 11:03 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 08/20] s390/zcrypt: Introduce pre-allocated device status array for cca misc Harald Freudenberger
` (13 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Rework the existing function zcrypt_device_status_mask_ext():
* Add two new parameters to provide upper limits for
cards and queues. The existing implementation needed an
array of 256 * 256 * 4 = 256 KB which is really huge. The
reworked function is more flexible in the sense that the
caller can decide the upper limit for cards and domains to
be stored into the status array. So for example a caller may
decide to only query for cards 0...127 and queues 0...127
and thus only an array of size 128 * 128 * 4 = 64 KB is needed.
* Instead of void the reworked function now returns an int.
The currently only way to have the function return != 0
is by providing card or domains limits beyond 256.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/zcrypt_api.c | 20 +++++++++++++++-----
drivers/s390/crypto/zcrypt_api.h | 3 ++-
drivers/s390/crypto/zcrypt_ccamisc.c | 22 +++++++++++++++++-----
drivers/s390/crypto/zcrypt_ep11misc.c | 14 ++++++++++----
4 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 62cc05881b13..bd2738e3792a 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -1317,19 +1317,25 @@ static void zcrypt_device_status_mask(struct zcrypt_device_status *devstatus)
spin_unlock(&zcrypt_list_lock);
}
-void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus)
+int zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus,
+ int maxcard, int maxqueue)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
struct zcrypt_device_status_ext *stat;
int card, queue;
+ if (maxcard > MAX_ZDEV_CARDIDS_EXT || maxqueue > MAX_ZDEV_DOMAINS_EXT)
+ return -EINVAL;
+
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
card = AP_QID_CARD(zq->queue->qid);
queue = AP_QID_QUEUE(zq->queue->qid);
- stat = &devstatus[card * AP_DOMAINS + queue];
+ if (card >= maxcard || queue >= maxqueue)
+ continue;
+ stat = &devstatus[card * maxqueue + queue];
stat->hwtype = zc->card->ap_dev.device_type;
stat->functions = zc->card->hwinfo.fac >> 26;
stat->qid = zq->queue->qid;
@@ -1337,6 +1343,8 @@ void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus)
}
}
spin_unlock(&zcrypt_list_lock);
+
+ return 0;
}
EXPORT_SYMBOL(zcrypt_device_status_mask_ext);
@@ -1635,9 +1643,11 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
GFP_KERNEL);
if (!device_status)
return -ENOMEM;
- zcrypt_device_status_mask_ext(device_status);
- if (copy_to_user((char __user *)arg, device_status,
- total_size))
+ rc = zcrypt_device_status_mask_ext(device_status,
+ MAX_ZDEV_CARDIDS_EXT,
+ MAX_ZDEV_DOMAINS_EXT);
+ if (!rc && copy_to_user((char __user *)arg, device_status,
+ total_size))
rc = -EFAULT;
kvfree(device_status);
return rc;
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h
index 25a339ef52c3..3b57e7437f3d 100644
--- a/drivers/s390/crypto/zcrypt_api.h
+++ b/drivers/s390/crypto/zcrypt_api.h
@@ -178,7 +178,8 @@ int zcrypt_api_init(void);
void zcrypt_api_exit(void);
long zcrypt_send_cprb(struct ica_xcRB *xcRB, u32 xflags);
long zcrypt_send_ep11_cprb(struct ep11_urb *urb, u32 xflags);
-void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus);
+int zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus,
+ int maxcard, int maxqueue);
int zcrypt_device_status_ext(int card, int queue,
struct zcrypt_device_status_ext *devstatus);
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
index 2c2ca2d67e2d..420895df70f0 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.c
+++ b/drivers/s390/crypto/zcrypt_ccamisc.c
@@ -1807,7 +1807,12 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
GFP_KERNEL);
if (!device_status)
return -ENOMEM;
- zcrypt_device_status_mask_ext(device_status);
+
+ rc = zcrypt_device_status_mask_ext(device_status,
+ MAX_ZDEV_CARDIDS_EXT,
+ MAX_ZDEV_DOMAINS_EXT);
+ if (rc)
+ goto out;
/* walk through all crypto cards */
for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
@@ -1875,6 +1880,7 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
rc = -ENODEV;
}
+out:
kvfree(device_status);
return rc;
}
@@ -1914,7 +1920,7 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
{
struct zcrypt_device_status_ext *device_status;
u32 *_apqns = NULL, _nr_apqns = 0;
- int i, card, dom, curmatch, oldmatch, rc = 0;
+ int i, card, dom, curmatch, oldmatch, rc;
struct cca_info ci;
/* fetch status of all crypto cards */
@@ -1923,13 +1929,18 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
GFP_KERNEL);
if (!device_status)
return -ENOMEM;
- zcrypt_device_status_mask_ext(device_status);
+
+ rc = zcrypt_device_status_mask_ext(device_status,
+ MAX_ZDEV_CARDIDS_EXT,
+ MAX_ZDEV_DOMAINS_EXT);
+ if (rc)
+ goto out;
/* allocate 1k space for up to 256 apqns */
_apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
if (!_apqns) {
- kvfree(device_status);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto out;
}
/* walk through all the crypto apqnss */
@@ -1994,6 +2005,7 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
rc = 0;
}
+out:
kvfree(device_status);
return rc;
}
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
index 86578a95b140..df16294eff9e 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.c
+++ b/drivers/s390/crypto/zcrypt_ep11misc.c
@@ -1603,7 +1603,7 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
{
struct zcrypt_device_status_ext *device_status;
u32 *_apqns = NULL, _nr_apqns = 0;
- int i, card, dom, rc = -ENOMEM;
+ int i, card, dom, rc;
struct ep11_domain_info edi;
struct ep11_card_info eci;
@@ -1613,13 +1613,18 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
GFP_KERNEL);
if (!device_status)
return -ENOMEM;
- zcrypt_device_status_mask_ext(device_status);
+
+ rc = zcrypt_device_status_mask_ext(device_status,
+ MAX_ZDEV_CARDIDS_EXT,
+ MAX_ZDEV_DOMAINS_EXT);
+ if (rc)
+ goto out;
/* allocate 1k space for up to 256 apqns */
_apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
if (!_apqns) {
- kvfree(device_status);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto out;
}
/* walk through all the crypto apqnss */
@@ -1673,6 +1678,7 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
rc = 0;
}
+out:
kvfree(device_status);
return rc;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 08/20] s390/zcrypt: Introduce pre-allocated device status array for cca misc
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (6 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 07/20] s390/zcrypt: Rework zcrypt function zcrypt_device_status_mask_ext Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-19 14:31 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 09/20] s390/zcrypt: Introduce pre-allocated device status array for ep11 misc Harald Freudenberger
` (12 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Introduce a pre-allocated device status array memory together with
a mutex controlling the occupation to be used by the two findcard()
functions. Limit the device status array to max 128 cards and max
128 domains to reduce the size of this pre-allocated memory to 64 KB.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/zcrypt_ccamisc.c | 78 +++++++++++++++++++---------
1 file changed, 53 insertions(+), 25 deletions(-)
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
index 420895df70f0..65b4cdb9b478 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.c
+++ b/drivers/s390/crypto/zcrypt_ccamisc.c
@@ -51,6 +51,22 @@ static DEFINE_SPINLOCK(cca_info_list_lock);
#define CPRB_MEMPOOL_ITEM_SIZE (16 * 1024)
static mempool_t *cprb_mempool;
+/*
+ * This is a pre-allocated memory for the device status array
+ * used within the findcard() functions. It is currently
+ * 128 * 128 * 4 bytes = 64 KB big. Usage of this memory is
+ * controlled via dev_status_mem_mutex. Needs adaption if more
+ * than 128 cards or domains to be are supported.
+ */
+#define ZCRYPT_DEV_STATUS_CARD_MAX 128
+#define ZCRYPT_DEV_STATUS_QUEUE_MAX 128
+#define ZCRYPT_DEV_STATUS_ENTRIES (ZCRYPT_DEV_STATUS_CARD_MAX * \
+ ZCRYPT_DEV_STATUS_QUEUE_MAX)
+#define ZCRYPT_DEV_STATUS_EXT_SIZE (ZCRYPT_DEV_STATUS_ENTRIES * \
+ sizeof(struct zcrypt_device_status_ext))
+static void *dev_status_mem;
+static DEFINE_MUTEX(dev_status_mem_mutex);
+
/*
* Simple check if the token is a valid CCA secure AES data key
* token. If keybitsize is given, the bitsize of the key is
@@ -1801,21 +1817,20 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
if (mkvp == 0 || minhwtype < 0)
return -EINVAL;
- /* fetch status of all crypto cards */
- device_status = kvcalloc(MAX_ZDEV_ENTRIES_EXT,
- sizeof(struct zcrypt_device_status_ext),
- GFP_KERNEL);
- if (!device_status)
- return -ENOMEM;
+ /* occupy the device status memory */
+ mutex_lock(&dev_status_mem_mutex);
+ memset(dev_status_mem, 0, ZCRYPT_DEV_STATUS_EXT_SIZE);
+ device_status = (struct zcrypt_device_status_ext *)dev_status_mem;
+ /* fetch crypto device status into this struct */
rc = zcrypt_device_status_mask_ext(device_status,
- MAX_ZDEV_CARDIDS_EXT,
- MAX_ZDEV_DOMAINS_EXT);
+ ZCRYPT_DEV_STATUS_CARD_MAX,
+ ZCRYPT_DEV_STATUS_QUEUE_MAX);
if (rc)
goto out;
/* walk through all crypto cards */
- for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
+ for (i = 0; i < ZCRYPT_DEV_STATUS_ENTRIES; i++) {
card = AP_QID_CARD(device_status[i].qid);
dom = AP_QID_QUEUE(device_status[i].qid);
if (device_status[i].online &&
@@ -1842,9 +1857,9 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
cca_info_cache_scrub(card, dom);
}
}
- if (i >= MAX_ZDEV_ENTRIES_EXT) {
+ if (i >= ZCRYPT_DEV_STATUS_ENTRIES) {
/* nothing found, so this time without cache */
- for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
+ for (i = 0; i < ZCRYPT_DEV_STATUS_ENTRIES; i++) {
if (!(device_status[i].online &&
device_status[i].functions & 0x04))
continue;
@@ -1864,24 +1879,26 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
oi = i;
}
}
- if (i >= MAX_ZDEV_ENTRIES_EXT && oi >= 0) {
+ if (i >= ZCRYPT_DEV_STATUS_ENTRIES && oi >= 0) {
/* old mkvp matched, use this card then */
card = AP_QID_CARD(device_status[oi].qid);
dom = AP_QID_QUEUE(device_status[oi].qid);
}
}
- if (i < MAX_ZDEV_ENTRIES_EXT || oi >= 0) {
+ if (i < ZCRYPT_DEV_STATUS_ENTRIES || oi >= 0) {
if (pcardnr)
*pcardnr = card;
if (pdomain)
*pdomain = dom;
- rc = (i < MAX_ZDEV_ENTRIES_EXT ? 0 : 1);
+ rc = (i < ZCRYPT_DEV_STATUS_ENTRIES ? 0 : 1);
} else {
rc = -ENODEV;
}
out:
- kvfree(device_status);
+ /* release the device status memory */
+ mutex_unlock(&dev_status_mem_mutex);
+
return rc;
}
@@ -1923,16 +1940,15 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
int i, card, dom, curmatch, oldmatch, rc;
struct cca_info ci;
- /* fetch status of all crypto cards */
- device_status = kvcalloc(MAX_ZDEV_ENTRIES_EXT,
- sizeof(struct zcrypt_device_status_ext),
- GFP_KERNEL);
- if (!device_status)
- return -ENOMEM;
+ /* occupy the device status memory */
+ mutex_lock(&dev_status_mem_mutex);
+ memset(dev_status_mem, 0, ZCRYPT_DEV_STATUS_EXT_SIZE);
+ device_status = (struct zcrypt_device_status_ext *)dev_status_mem;
+ /* fetch crypto device status into this struct */
rc = zcrypt_device_status_mask_ext(device_status,
- MAX_ZDEV_CARDIDS_EXT,
- MAX_ZDEV_DOMAINS_EXT);
+ ZCRYPT_DEV_STATUS_CARD_MAX,
+ ZCRYPT_DEV_STATUS_QUEUE_MAX);
if (rc)
goto out;
@@ -1944,7 +1960,7 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
}
/* walk through all the crypto apqnss */
- for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
+ for (i = 0; i < ZCRYPT_DEV_STATUS_ENTRIES; i++) {
card = AP_QID_CARD(device_status[i].qid);
dom = AP_QID_QUEUE(device_status[i].qid);
/* check online state */
@@ -2006,7 +2022,9 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
}
out:
- kvfree(device_status);
+ /* release the device status memory */
+ mutex_unlock(&dev_status_mem_mutex);
+
return rc;
}
EXPORT_SYMBOL(cca_findcard2);
@@ -2023,11 +2041,21 @@ int __init zcrypt_ccamisc_init(void)
cprb_mempool = NULL;
return -ENOMEM;
}
+
+ /* Pre-allocate one crypto status card struct used in findcard() */
+ dev_status_mem = kvmalloc(ZCRYPT_DEV_STATUS_EXT_SIZE, GFP_KERNEL);
+ if (!dev_status_mem) {
+ ZCRYPT_DBF_ERR("%s allocation of dev_status_mem failed\n", __func__);
+ mempool_destroy(cprb_mempool);
+ return -ENOMEM;
+ }
+
return 0;
}
void zcrypt_ccamisc_exit(void)
{
mkvp_cache_free();
+ kvfree(dev_status_mem);
mempool_destroy(cprb_mempool);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 09/20] s390/zcrypt: Introduce pre-allocated device status array for ep11 misc
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (7 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 08/20] s390/zcrypt: Introduce pre-allocated device status array for cca misc Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-19 18:02 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 10/20] s390/zcrypt/pkey: Rework cca findcard() implementation and callers Harald Freudenberger
` (11 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Introduce a pre-allocated device status array memory together with
a mutex controlling the occupation to be used by the findcard()
function. Limit the device status array to max 128 cards and max
128 domains to reduce the size of this pre-allocated memory to 64 KB.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/zcrypt_ep11misc.c | 46 +++++++++++++++++++++------
1 file changed, 36 insertions(+), 10 deletions(-)
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
index df16294eff9e..04153b476168 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.c
+++ b/drivers/s390/crypto/zcrypt_ep11misc.c
@@ -39,6 +39,22 @@ static const u8 def_iv[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
#define CPRB_MEMPOOL_ITEM_SIZE (8 * 1024)
static mempool_t *cprb_mempool;
+/*
+ * This is a pre-allocated memory for the device status array
+ * used within the findcard() functions. It is currently
+ * 128 * 128 * 4 bytes = 64 KB big. Usage of this memory is
+ * controlled via dev_status_mem_mutex. Needs adaption if more
+ * than 128 cards or domains to be are supported.
+ */
+#define ZCRYPT_DEV_STATUS_CARD_MAX 128
+#define ZCRYPT_DEV_STATUS_QUEUE_MAX 128
+#define ZCRYPT_DEV_STATUS_ENTRIES (ZCRYPT_DEV_STATUS_CARD_MAX * \
+ ZCRYPT_DEV_STATUS_QUEUE_MAX)
+#define ZCRYPT_DEV_STATUS_EXT_SIZE (ZCRYPT_DEV_STATUS_ENTRIES * \
+ sizeof(struct zcrypt_device_status_ext))
+static void *dev_status_mem;
+static DEFINE_MUTEX(dev_status_mem_mutex);
+
/* ep11 card info cache */
struct card_list_entry {
struct list_head list;
@@ -1607,16 +1623,15 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
struct ep11_domain_info edi;
struct ep11_card_info eci;
- /* fetch status of all crypto cards */
- device_status = kvcalloc(MAX_ZDEV_ENTRIES_EXT,
- sizeof(struct zcrypt_device_status_ext),
- GFP_KERNEL);
- if (!device_status)
- return -ENOMEM;
+ /* occupy the device status memory */
+ mutex_lock(&dev_status_mem_mutex);
+ memset(dev_status_mem, 0, ZCRYPT_DEV_STATUS_EXT_SIZE);
+ device_status = (struct zcrypt_device_status_ext *)dev_status_mem;
+ /* fetch crypto device status into this struct */
rc = zcrypt_device_status_mask_ext(device_status,
- MAX_ZDEV_CARDIDS_EXT,
- MAX_ZDEV_DOMAINS_EXT);
+ ZCRYPT_DEV_STATUS_CARD_MAX,
+ ZCRYPT_DEV_STATUS_QUEUE_MAX);
if (rc)
goto out;
@@ -1628,7 +1643,7 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
}
/* walk through all the crypto apqnss */
- for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
+ for (i = 0; i < ZCRYPT_DEV_STATUS_ENTRIES; i++) {
card = AP_QID_CARD(device_status[i].qid);
dom = AP_QID_QUEUE(device_status[i].qid);
/* check online state */
@@ -1679,7 +1694,8 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
}
out:
- kvfree(device_status);
+ mutex_unlock(&dev_status_mem_mutex);
+
return rc;
}
EXPORT_SYMBOL(ep11_findcard2);
@@ -1696,11 +1712,21 @@ int __init zcrypt_ep11misc_init(void)
cprb_mempool = NULL;
return -ENOMEM;
}
+
+ /* Pre-allocate one crypto status card struct used in findcard() */
+ dev_status_mem = kvmalloc(ZCRYPT_DEV_STATUS_EXT_SIZE, GFP_KERNEL);
+ if (!dev_status_mem) {
+ ZCRYPT_DBF_ERR("%s allocation of dev_status_mem failed\n", __func__);
+ mempool_destroy(cprb_mempool);
+ return -ENOMEM;
+ }
+
return 0;
}
void zcrypt_ep11misc_exit(void)
{
card_cache_free();
+ kvfree(dev_status_mem);
mempool_destroy(cprb_mempool);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 10/20] s390/zcrypt/pkey: Rework cca findcard() implementation and callers
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (8 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 09/20] s390/zcrypt: Introduce pre-allocated device status array for ep11 misc Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-19 17:58 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 11/20] s390/zcrypt/pkey: Rework ep11 " Harald Freudenberger
` (10 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Rework the memory usage of the cca findcard() implementation:
- findcard does not allocate memory for the list of apqns
any more.
- the callers are now responsible to provide an array of
apqns to store the matching apqns into.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/pkey_cca.c | 25 +++++++++++--------------
drivers/s390/crypto/zcrypt_ccamisc.c | 18 ++++--------------
drivers/s390/crypto/zcrypt_ccamisc.h | 12 +++++-------
3 files changed, 20 insertions(+), 35 deletions(-)
diff --git a/drivers/s390/crypto/pkey_cca.c b/drivers/s390/crypto/pkey_cca.c
index cda22db31f6c..8c9a0c5ca630 100644
--- a/drivers/s390/crypto/pkey_cca.c
+++ b/drivers/s390/crypto/pkey_cca.c
@@ -73,7 +73,7 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
- u32 _nr_apqns, *_apqns = NULL;
+ u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns);
int rc;
if (!flags)
@@ -107,7 +107,7 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
/* unknown CCA internal token type */
return -EINVAL;
}
- rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+ rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
minhwtype, AES_MK_SET,
cur_mkvp, old_mkvp, 1);
if (rc)
@@ -126,7 +126,7 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
/* unknown CCA internal 2 token type */
return -EINVAL;
}
- rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+ rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
ZCRYPT_CEX7, APKA_MK_SET,
cur_mkvp, old_mkvp, 1);
if (rc)
@@ -147,7 +147,6 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
*nr_apqns = _nr_apqns;
out:
- kfree(_apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -156,7 +155,7 @@ static int cca_apqns4type(enum pkey_key_type ktype,
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns)
{
- u32 _nr_apqns, *_apqns = NULL;
+ u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns);
int rc;
zcrypt_wait_api_operational();
@@ -171,7 +170,7 @@ static int cca_apqns4type(enum pkey_key_type ktype,
old_mkvp = *((u64 *)alt_mkvp);
if (ktype == PKEY_TYPE_CCA_CIPHER)
minhwtype = ZCRYPT_CEX6;
- rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+ rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
minhwtype, AES_MK_SET,
cur_mkvp, old_mkvp, 1);
if (rc)
@@ -184,7 +183,7 @@ static int cca_apqns4type(enum pkey_key_type ktype,
cur_mkvp = *((u64 *)cur_mkvp);
if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
old_mkvp = *((u64 *)alt_mkvp);
- rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+ rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
ZCRYPT_CEX7, APKA_MK_SET,
cur_mkvp, old_mkvp, 1);
if (rc)
@@ -205,7 +204,6 @@ static int cca_apqns4type(enum pkey_key_type ktype,
*nr_apqns = _nr_apqns;
out:
- kfree(_apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -461,7 +459,7 @@ static int cca_verifykey(const u8 *key, u32 keylen,
u32 *keytype, u32 *keybitsize, u32 *flags)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
- u32 nr_apqns, *apqns = NULL;
+ u32 apqns[MAXAPQNSINLIST], nr_apqns = ARRAY_SIZE(apqns);
int rc;
if (keylen < sizeof(*hdr))
@@ -478,13 +476,13 @@ static int cca_verifykey(const u8 *key, u32 keylen,
goto out;
*keytype = PKEY_TYPE_CCA_DATA;
*keybitsize = t->bitsize;
- rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
+ rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX3C, AES_MK_SET,
t->mkvp, 0, 1);
if (!rc)
*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
if (rc == -ENODEV) {
- rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
+ rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX3C, AES_MK_SET,
0, t->mkvp, 1);
if (!rc)
@@ -511,13 +509,13 @@ static int cca_verifykey(const u8 *key, u32 keylen,
*keybitsize = PKEY_SIZE_AES_192;
else if (!t->plfver && t->wpllen == 640)
*keybitsize = PKEY_SIZE_AES_256;
- rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
+ rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX6, AES_MK_SET,
t->mkvp0, 0, 1);
if (!rc)
*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
if (rc == -ENODEV) {
- rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
+ rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX6, AES_MK_SET,
0, t->mkvp0, 1);
if (!rc)
@@ -535,7 +533,6 @@ static int cca_verifykey(const u8 *key, u32 keylen,
}
out:
- kfree(apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
index 65b4cdb9b478..d3b093dcdf30 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.c
+++ b/drivers/s390/crypto/zcrypt_ccamisc.c
@@ -1931,14 +1931,14 @@ int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify)
}
EXPORT_SYMBOL(cca_findcard);
-int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
+int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
int verify)
{
struct zcrypt_device_status_ext *device_status;
- u32 *_apqns = NULL, _nr_apqns = 0;
int i, card, dom, curmatch, oldmatch, rc;
struct cca_info ci;
+ u32 _nr_apqns = 0;
/* occupy the device status memory */
mutex_lock(&dev_status_mem_mutex);
@@ -1952,13 +1952,6 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
if (rc)
goto out;
- /* allocate 1k space for up to 256 apqns */
- _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
- if (!_apqns) {
- rc = -ENOMEM;
- goto out;
- }
-
/* walk through all the crypto apqnss */
for (i = 0; i < ZCRYPT_DEV_STATUS_ENTRIES; i++) {
card = AP_QID_CARD(device_status[i].qid);
@@ -2006,17 +1999,14 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
continue;
}
/* apqn passed all filtering criterons, add to the array */
- if (_nr_apqns < 256)
- _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
+ if (_nr_apqns < *nr_apqns)
+ apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
}
/* nothing found ? */
if (!_nr_apqns) {
- kfree(_apqns);
rc = -ENODEV;
} else {
- /* no re-allocation, simple return the _apqns array */
- *apqns = _apqns;
*nr_apqns = _nr_apqns;
rc = 0;
}
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.h b/drivers/s390/crypto/zcrypt_ccamisc.h
index 273edf2bb036..bed647a42eb2 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.h
+++ b/drivers/s390/crypto/zcrypt_ccamisc.h
@@ -229,14 +229,12 @@ int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify);
* cur_mkvp or old_mkvp values of the apqn are used.
* The mktype determines which set of master keys to use:
* 0 = AES_MK_SET - AES MK set, 1 = APKA MK_SET - APKA MK set
- * The array of apqn entries is allocated with kmalloc and returned in *apqns;
- * the number of apqns stored into the list is returned in *nr_apqns. One apqn
- * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and
- * may be casted to struct pkey_apqn. The return value is either 0 for success
- * or a negative errno value. If no apqn meeting the criteria is found,
- * -ENODEV is returned.
+ * The caller should set *nr_apqns to the nr of elements available in *apqns.
+ * On return *nr_apqns is then updated with the nr of apqns filled into *apqns.
+ * The return value is either 0 for success or a negative errno value.
+ * If no apqn meeting the criteria is found, -ENODEV is returned.
*/
-int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
+int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
int verify);
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 11/20] s390/zcrypt/pkey: Rework ep11 findcard() implementation and callers
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (9 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 10/20] s390/zcrypt/pkey: Rework cca findcard() implementation and callers Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-20 8:30 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 12/20] s390/zcrypt: Rework cca misc functions kmallocs to use the cprb mempool Harald Freudenberger
` (9 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Rework the memory usage of the ep11 findcard() implementation:
- findcard does not allocate memory for the list of apqns
any more.
- the callers are now responsible to provide an array of
apqns to store the matching apqns into.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/pkey_ep11.c | 19 ++++++++-----------
drivers/s390/crypto/zcrypt_ep11misc.c | 18 ++++--------------
drivers/s390/crypto/zcrypt_ep11misc.h | 12 +++++-------
3 files changed, 17 insertions(+), 32 deletions(-)
diff --git a/drivers/s390/crypto/pkey_ep11.c b/drivers/s390/crypto/pkey_ep11.c
index 5b033ca3e828..b970f0be84be 100644
--- a/drivers/s390/crypto/pkey_ep11.c
+++ b/drivers/s390/crypto/pkey_ep11.c
@@ -73,7 +73,7 @@ static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
- u32 _nr_apqns, *_apqns = NULL;
+ u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns);
int rc;
if (!flags)
@@ -98,7 +98,7 @@ static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
minhwtype = ZCRYPT_CEX7;
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
}
- rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+ rc = ep11_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
minhwtype, api, kb->wkvp);
if (rc)
goto out;
@@ -115,7 +115,7 @@ static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
minhwtype = ZCRYPT_CEX7;
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
}
- rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+ rc = ep11_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
minhwtype, api, kb->wkvp);
if (rc)
goto out;
@@ -135,7 +135,6 @@ static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
*nr_apqns = _nr_apqns;
out:
- kfree(_apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -144,7 +143,7 @@ static int ep11_apqns4type(enum pkey_key_type ktype,
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
struct pkey_apqn *apqns, size_t *nr_apqns)
{
- u32 _nr_apqns, *_apqns = NULL;
+ u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns);
int rc;
zcrypt_wait_api_operational();
@@ -158,7 +157,7 @@ static int ep11_apqns4type(enum pkey_key_type ktype,
if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
wkvp = cur_mkvp;
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
- rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+ rc = ep11_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
ZCRYPT_CEX7, api, wkvp);
if (rc)
goto out;
@@ -178,7 +177,6 @@ static int ep11_apqns4type(enum pkey_key_type ktype,
*nr_apqns = _nr_apqns;
out:
- kfree(_apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -423,7 +421,7 @@ static int ep11_verifykey(const u8 *key, u32 keylen,
u32 *keytype, u32 *keybitsize, u32 *flags)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
- u32 nr_apqns, *apqns = NULL;
+ u32 apqns[MAXAPQNSINLIST], nr_apqns = ARRAY_SIZE(apqns);
int rc;
if (keylen < sizeof(*hdr))
@@ -443,7 +441,7 @@ static int ep11_verifykey(const u8 *key, u32 keylen,
*keybitsize = kb->head.bitlen;
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
- rc = ep11_findcard2(&apqns, &nr_apqns, *card, *dom,
+ rc = ep11_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX7, api,
ep11_kb_wkvp(key, keylen));
if (rc)
@@ -467,7 +465,7 @@ static int ep11_verifykey(const u8 *key, u32 keylen,
*keybitsize = kh->bitlen;
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
- rc = ep11_findcard2(&apqns, &nr_apqns, *card, *dom,
+ rc = ep11_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX7, api,
ep11_kb_wkvp(key, keylen));
if (rc)
@@ -484,7 +482,6 @@ static int ep11_verifykey(const u8 *key, u32 keylen,
}
out:
- kfree(apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
index 04153b476168..6005ef79c001 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.c
+++ b/drivers/s390/crypto/zcrypt_ep11misc.c
@@ -1614,14 +1614,14 @@ int ep11_kblob2protkey(u16 card, u16 dom,
}
EXPORT_SYMBOL(ep11_kblob2protkey);
-int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
+int ep11_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
int minhwtype, int minapi, const u8 *wkvp)
{
struct zcrypt_device_status_ext *device_status;
- u32 *_apqns = NULL, _nr_apqns = 0;
int i, card, dom, rc;
struct ep11_domain_info edi;
struct ep11_card_info eci;
+ u32 _nr_apqns = 0;
/* occupy the device status memory */
mutex_lock(&dev_status_mem_mutex);
@@ -1635,13 +1635,6 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
if (rc)
goto out;
- /* allocate 1k space for up to 256 apqns */
- _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
- if (!_apqns) {
- rc = -ENOMEM;
- goto out;
- }
-
/* walk through all the crypto apqnss */
for (i = 0; i < ZCRYPT_DEV_STATUS_ENTRIES; i++) {
card = AP_QID_CARD(device_status[i].qid);
@@ -1678,17 +1671,14 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
continue;
}
/* apqn passed all filtering criterons, add to the array */
- if (_nr_apqns < 256)
- _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
+ if (_nr_apqns < *nr_apqns)
+ apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
}
/* nothing found ? */
if (!_nr_apqns) {
- kfree(_apqns);
rc = -ENODEV;
} else {
- /* no re-allocation, simple return the _apqns array */
- *apqns = _apqns;
*nr_apqns = _nr_apqns;
rc = 0;
}
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h b/drivers/s390/crypto/zcrypt_ep11misc.h
index a4b98eca8431..cbd615547bc2 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.h
+++ b/drivers/s390/crypto/zcrypt_ep11misc.h
@@ -136,14 +136,12 @@ int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
* key for this domain. When a wkvp is given there will always be a re-fetch
* of the domain info for the potential apqn - so this triggers an request
* reply to each apqn eligible.
- * The array of apqn entries is allocated with kmalloc and returned in *apqns;
- * the number of apqns stored into the list is returned in *nr_apqns. One apqn
- * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and
- * may be casted to struct pkey_apqn. The return value is either 0 for success
- * or a negative errno value. If no apqn meeting the criteria is found,
- * -ENODEV is returned.
+ * The caller should set *nr_apqns to the nr of elements available in *apqns.
+ * On return *nr_apqns is then updated with the nr of apqns filled into *apqns.
+ * The return value is either 0 for success or a negative errno value.
+ * If no apqn meeting the criteria is found, -ENODEV is returned.
*/
-int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
+int ep11_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
int minhwtype, int minapi, const u8 *wkvp);
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 12/20] s390/zcrypt: Rework cca misc functions kmallocs to use the cprb mempool
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (10 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 11/20] s390/zcrypt/pkey: Rework ep11 " Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-20 9:31 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 13/20] s390/zcrypt: Add small mempool for cca info list entries Harald Freudenberger
` (8 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Rework two places in the zcrypt cca misc code using kmalloc() for
ephemeral memory allocation. As there is anyway now a cprb mempool
let's use this pool instead to satisfy these short term memory
allocations.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/zcrypt_api.c | 2 +-
drivers/s390/crypto/zcrypt_ccamisc.c | 42 +++++++++++++++++++---------
2 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index bd2738e3792a..d4e60d89cdce 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -50,7 +50,7 @@ MODULE_DESCRIPTION("Cryptographic Coprocessor interface, " \
"Copyright IBM Corp. 2001, 2012");
MODULE_LICENSE("GPL");
-unsigned int zcrypt_cca_cprbpool_min_items = 4;
+unsigned int zcrypt_cca_cprbpool_min_items = 6;
module_param_named(cca_cprbpool_min_items, zcrypt_cca_cprbpool_min_items, uint, 0440);
MODULE_PARM_DESC(cca_cprbpool_min_items, "CCA CPRB pool minimal items.");
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
index d3b093dcdf30..ff7ba2622484 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.c
+++ b/drivers/s390/crypto/zcrypt_ccamisc.c
@@ -1138,20 +1138,29 @@ int cca_clr2cipherkey(u16 card, u16 dom, u32 keybitsize, u32 keygenflags,
const u8 *clrkey, u8 *keybuf, u32 *keybufsize)
{
int rc;
- u8 *token;
+ void *mem;
int tokensize;
- u8 exorbuf[32];
+ u8 *token, exorbuf[32];
struct cipherkeytoken *t;
+ u32 xflags = 0;
/* fill exorbuf with random data */
get_random_bytes(exorbuf, sizeof(exorbuf));
- /* allocate space for the key token to build */
- token = kmalloc(MAXCCAVLSCTOKENSIZE, GFP_KERNEL);
- if (!token)
+ /*
+ * Allocate space for the key token to build.
+ * Also we only need up to MAXCCAVLSCTOKENSIZE bytes for this
+ * we use the already existing cprb mempool to solve this
+ * short term memory requirement.
+ */
+ mem = (xflags & ZCRYPT_XFLAG_NOMEMALLOC) ?
+ mempool_alloc_preallocated(cprb_mempool) :
+ mempool_alloc(cprb_mempool, GFP_KERNEL);
+ if (!mem)
return -ENOMEM;
/* prepare the token with the key skeleton */
+ token = (u8 *)mem;
tokensize = SIZEOF_SKELETON;
memcpy(token, aes_cipher_key_skeleton, tokensize);
@@ -1208,7 +1217,7 @@ int cca_clr2cipherkey(u16 card, u16 dom, u32 keybitsize, u32 keygenflags,
*keybufsize = tokensize;
out:
- kfree(token);
+ mempool_free(mem, cprb_mempool);
return rc;
}
EXPORT_SYMBOL(cca_clr2cipherkey);
@@ -1714,10 +1723,12 @@ static void __exit mkvp_cache_free(void)
*/
static int fetch_cca_info(u16 cardnr, u16 domain, struct cca_info *ci)
{
+ void *mem;
int rc, found = 0;
size_t rlen, vlen;
- u8 *rarray, *varray, *pg;
+ u8 *rarray, *varray;
struct zcrypt_device_status_ext devstat;
+ u32 xflags = 0;
memset(ci, 0, sizeof(*ci));
@@ -1727,12 +1738,17 @@ static int fetch_cca_info(u16 cardnr, u16 domain, struct cca_info *ci)
return rc;
ci->hwtype = devstat.hwtype;
- /* prep page for rule array and var array use */
- pg = (u8 *)__get_free_page(GFP_KERNEL);
- if (!pg)
+ /*
+ * Prep memory for rule array and var array use.
+ * Use the cprb mempool for this.
+ */
+ mem = (xflags & ZCRYPT_XFLAG_NOMEMALLOC) ?
+ mempool_alloc_preallocated(cprb_mempool) :
+ mempool_alloc(cprb_mempool, GFP_KERNEL);
+ if (!mem)
return -ENOMEM;
- rarray = pg;
- varray = pg + PAGE_SIZE / 2;
+ rarray = (u8 *)mem;
+ varray = (u8 *)mem + PAGE_SIZE / 2;
rlen = vlen = PAGE_SIZE / 2;
/* QF for this card/domain */
@@ -1779,7 +1795,7 @@ static int fetch_cca_info(u16 cardnr, u16 domain, struct cca_info *ci)
}
out:
- free_page((unsigned long)pg);
+ mempool_free(mem, cprb_mempool);
return found == 2 ? 0 : -ENOENT;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 13/20] s390/zcrypt: Add small mempool for cca info list entries
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (11 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 12/20] s390/zcrypt: Rework cca misc functions kmallocs to use the cprb mempool Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-20 14:34 ` Holger Dengler
2025-03-20 16:05 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 14/20] s390/zcrypt: Locate ep11_domain_query_info onto the stack instead of kmalloc Harald Freudenberger
` (7 subsequent siblings)
20 siblings, 2 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Add a small memory pool for (pre-)allocating cca info list
entries. These entries are rather small and the pool is a simple
way to support the xflag ZCRYPT_XFLAG_NOMEMALLOC to avoid mallocs.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/zcrypt_ccamisc.c | 67 ++++++++++++++++++++--------
drivers/s390/crypto/zcrypt_ccamisc.h | 3 +-
drivers/s390/crypto/zcrypt_cex4.c | 4 +-
3 files changed, 53 insertions(+), 21 deletions(-)
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
index ff7ba2622484..e4ec922aae0d 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.c
+++ b/drivers/s390/crypto/zcrypt_ccamisc.c
@@ -41,6 +41,10 @@ struct cca_info_list_entry {
static LIST_HEAD(cca_info_list);
static DEFINE_SPINLOCK(cca_info_list_lock);
+/* memory pool for cca_info_list entries */
+#define INFO_ENTRY_MEMPOOL_MIN_ITEMS 8
+static mempool_t *info_mempool;
+
/*
* Cprb memory pool held for urgent cases where no memory
* can be allocated via kmalloc. This pool is only used
@@ -1662,7 +1666,7 @@ static int cca_info_cache_fetch(u16 cardnr, u16 domain, struct cca_info *ci)
}
static void cca_info_cache_update(u16 cardnr, u16 domain,
- const struct cca_info *ci)
+ const struct cca_info *ci, u32 xflags)
{
int found = 0;
struct cca_info_list_entry *ptr;
@@ -1677,7 +1681,9 @@ static void cca_info_cache_update(u16 cardnr, u16 domain,
}
}
if (!found) {
- ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC);
+ ptr = (xflags & ZCRYPT_XFLAG_NOMEMALLOC) ?
+ mempool_alloc_preallocated(info_mempool) :
+ mempool_alloc(info_mempool, GFP_ATOMIC);
if (!ptr) {
spin_unlock_bh(&cca_info_list_lock);
return;
@@ -1699,7 +1705,7 @@ static void cca_info_cache_scrub(u16 cardnr, u16 domain)
if (ptr->cardnr == cardnr &&
ptr->domain == domain) {
list_del(&ptr->list);
- kfree(ptr);
+ mempool_free(ptr, info_mempool);
break;
}
}
@@ -1713,7 +1719,7 @@ static void __exit mkvp_cache_free(void)
spin_lock_bh(&cca_info_list_lock);
list_for_each_entry_safe(ptr, pnext, &cca_info_list, list) {
list_del(&ptr->list);
- kfree(ptr);
+ mempool_free(ptr, info_mempool);
}
spin_unlock_bh(&cca_info_list_lock);
}
@@ -1721,14 +1727,14 @@ static void __exit mkvp_cache_free(void)
/*
* Fetch cca_info values via query_crypto_facility from adapter.
*/
-static int fetch_cca_info(u16 cardnr, u16 domain, struct cca_info *ci)
+static int fetch_cca_info(u16 cardnr, u16 domain,
+ struct cca_info *ci, u32 xflags)
{
void *mem;
int rc, found = 0;
size_t rlen, vlen;
u8 *rarray, *varray;
struct zcrypt_device_status_ext devstat;
- u32 xflags = 0;
memset(ci, 0, sizeof(*ci));
@@ -1802,15 +1808,15 @@ static int fetch_cca_info(u16 cardnr, u16 domain, struct cca_info *ci)
/*
* Fetch cca information about a CCA queue.
*/
-int cca_get_info(u16 card, u16 dom, struct cca_info *ci, int verify)
+int cca_get_info(u16 card, u16 dom, struct cca_info *ci, int verify, u32 xflags)
{
int rc;
rc = cca_info_cache_fetch(card, dom, ci);
if (rc || verify) {
- rc = fetch_cca_info(card, dom, ci);
+ rc = fetch_cca_info(card, dom, ci, xflags);
if (rc == 0)
- cca_info_cache_update(card, dom, ci);
+ cca_info_cache_update(card, dom, ci, xflags);
}
return rc;
@@ -1828,6 +1834,7 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
u16 card, dom;
struct cca_info ci;
int i, rc, oi = -1;
+ u32 xflg = 0; /* xflags */
/* mkvp must not be zero, minhwtype needs to be >= 0 */
if (mkvp == 0 || minhwtype < 0)
@@ -1859,8 +1866,8 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
if (!verify)
break;
/* verify: refresh card info */
- if (fetch_cca_info(card, dom, &ci) == 0) {
- cca_info_cache_update(card, dom, &ci);
+ if (fetch_cca_info(card, dom, &ci, xflg) == 0) {
+ cca_info_cache_update(card, dom, &ci, xflg);
if (ci.hwtype >= minhwtype &&
ci.cur_aes_mk_state == '2' &&
ci.cur_aes_mkvp == mkvp)
@@ -1882,8 +1889,8 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
card = AP_QID_CARD(device_status[i].qid);
dom = AP_QID_QUEUE(device_status[i].qid);
/* fresh fetch mkvp from adapter */
- if (fetch_cca_info(card, dom, &ci) == 0) {
- cca_info_cache_update(card, dom, &ci);
+ if (fetch_cca_info(card, dom, &ci, xflg) == 0) {
+ cca_info_cache_update(card, dom, &ci, xflg);
if (ci.hwtype >= minhwtype &&
ci.cur_aes_mk_state == '2' &&
ci.cur_aes_mkvp == mkvp)
@@ -1955,6 +1962,7 @@ int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
int i, card, dom, curmatch, oldmatch, rc;
struct cca_info ci;
u32 _nr_apqns = 0;
+ u32 xflags = 0;
/* occupy the device status memory */
mutex_lock(&dev_status_mem_mutex);
@@ -1985,7 +1993,7 @@ int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
if (domain != 0xFFFF && dom != domain)
continue;
/* get cca info on this apqn */
- if (cca_get_info(card, dom, &ci, verify))
+ if (cca_get_info(card, dom, &ci, verify, xflags))
continue;
/* current master key needs to be valid */
if (mktype == AES_MK_SET && ci.cur_aes_mk_state != '2')
@@ -2037,6 +2045,8 @@ EXPORT_SYMBOL(cca_findcard2);
int __init zcrypt_ccamisc_init(void)
{
+ int rc = -ENOMEM;
+
/* Pre-allocate a small memory pool for cca cprbs. */
cprb_mempool = mempool_create_kmalloc_pool(zcrypt_cca_cprbpool_min_items,
CPRB_MEMPOOL_ITEM_SIZE);
@@ -2044,19 +2054,39 @@ int __init zcrypt_ccamisc_init(void)
ZCRYPT_DBF_ERR("%s mempool_create(%d,%d) failed: %ld\n",
__func__, zcrypt_cca_cprbpool_min_items,
CPRB_MEMPOOL_ITEM_SIZE, PTR_ERR(cprb_mempool));
+ rc = PTR_ERR(cprb_mempool);
cprb_mempool = NULL;
- return -ENOMEM;
+ goto out;
+ }
+
+ /* Pre-allocate a small memory pool for cca info list entries */
+ info_mempool = mempool_create_kmalloc_pool(INFO_ENTRY_MEMPOOL_MIN_ITEMS,
+ sizeof(struct cca_info_list_entry));
+ if (IS_ERR(info_mempool)) {
+ ZCRYPT_DBF_ERR("%s info entry mempool_create(%d,%d) failed: %ld\n",
+ __func__, INFO_ENTRY_MEMPOOL_MIN_ITEMS,
+ (int)sizeof(struct cca_info_list_entry),
+ PTR_ERR(info_mempool));
+ rc = PTR_ERR(info_mempool);
+ info_mempool = NULL;
+ goto out;
}
/* Pre-allocate one crypto status card struct used in findcard() */
dev_status_mem = kvmalloc(ZCRYPT_DEV_STATUS_EXT_SIZE, GFP_KERNEL);
if (!dev_status_mem) {
ZCRYPT_DBF_ERR("%s allocation of dev_status_mem failed\n", __func__);
- mempool_destroy(cprb_mempool);
- return -ENOMEM;
+ goto out;
}
- return 0;
+ rc = 0;
+
+out:
+ if (rc) {
+ mempool_destroy(cprb_mempool);
+ mempool_destroy(info_mempool);
+ }
+ return rc;
}
void zcrypt_ccamisc_exit(void)
@@ -2064,4 +2094,5 @@ void zcrypt_ccamisc_exit(void)
mkvp_cache_free();
kvfree(dev_status_mem);
mempool_destroy(cprb_mempool);
+ mempool_destroy(info_mempool);
}
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.h b/drivers/s390/crypto/zcrypt_ccamisc.h
index bed647a42eb2..966f0eaf3c4c 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.h
+++ b/drivers/s390/crypto/zcrypt_ccamisc.h
@@ -268,7 +268,8 @@ struct cca_info {
/*
* Fetch cca information about an CCA queue.
*/
-int cca_get_info(u16 card, u16 dom, struct cca_info *ci, int verify);
+int cca_get_info(u16 card, u16 dom, struct cca_info *ci,
+ int verify, u32 xflags);
int zcrypt_ccamisc_init(void);
void zcrypt_ccamisc_exit(void);
diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c
index 64df7d2f6266..49a638d373fa 100644
--- a/drivers/s390/crypto/zcrypt_cex4.c
+++ b/drivers/s390/crypto/zcrypt_cex4.c
@@ -86,7 +86,7 @@ static ssize_t cca_serialnr_show(struct device *dev,
memset(&ci, 0, sizeof(ci));
if (ap_domain_index >= 0)
- cca_get_info(ac->id, ap_domain_index, &ci, zc->online);
+ cca_get_info(ac->id, ap_domain_index, &ci, zc->online, 0);
return sysfs_emit(buf, "%s\n", ci.serial);
}
@@ -120,7 +120,7 @@ static ssize_t cca_mkvps_show(struct device *dev,
cca_get_info(AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid),
- &ci, zq->online);
+ &ci, zq->online, 0);
if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3')
n += sysfs_emit_at(buf, n, "AES NEW: %s 0x%016llx\n",
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 14/20] s390/zcrypt: Locate ep11_domain_query_info onto the stack instead of kmalloc
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (12 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 13/20] s390/zcrypt: Add small mempool for cca info list entries Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-20 14:41 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 15/20] s390/zcrypt: Rework ep11 misc functions to use cprb mempool Harald Freudenberger
` (6 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Locate the relative small struct ep11_domain_query_info variable
onto the stack instead of kmalloc()/kfree().
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/zcrypt_ep11misc.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
index 6005ef79c001..7fb55be3e943 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.c
+++ b/drivers/s390/crypto/zcrypt_ep11misc.c
@@ -790,36 +790,31 @@ int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info)
u8 new_WK_VP[32];
u32 dom_flags;
u64 op_mode;
- } __packed * p_dom_info;
-
- p_dom_info = kmalloc(sizeof(*p_dom_info), GFP_KERNEL);
- if (!p_dom_info)
- return -ENOMEM;
+ } __packed dom_query_info;
rc = ep11_query_info(card, domain, 0x03 /* domain info query */,
- sizeof(*p_dom_info), (u8 *)p_dom_info);
+ sizeof(dom_query_info), (u8 *)&dom_query_info);
if (rc)
goto out;
memset(info, 0, sizeof(*info));
info->cur_wk_state = '0';
info->new_wk_state = '0';
- if (p_dom_info->dom_flags & 0x10 /* left imprint mode */) {
- if (p_dom_info->dom_flags & 0x02 /* cur wk valid */) {
+ if (dom_query_info.dom_flags & 0x10 /* left imprint mode */) {
+ if (dom_query_info.dom_flags & 0x02 /* cur wk valid */) {
info->cur_wk_state = '1';
- memcpy(info->cur_wkvp, p_dom_info->cur_WK_VP, 32);
+ memcpy(info->cur_wkvp, dom_query_info.cur_WK_VP, 32);
}
- if (p_dom_info->dom_flags & 0x04 || /* new wk present */
- p_dom_info->dom_flags & 0x08 /* new wk committed */) {
+ if (dom_query_info.dom_flags & 0x04 || /* new wk present */
+ dom_query_info.dom_flags & 0x08 /* new wk committed */) {
info->new_wk_state =
- p_dom_info->dom_flags & 0x08 ? '2' : '1';
- memcpy(info->new_wkvp, p_dom_info->new_WK_VP, 32);
+ dom_query_info.dom_flags & 0x08 ? '2' : '1';
+ memcpy(info->new_wkvp, dom_query_info.new_WK_VP, 32);
}
}
- info->op_mode = p_dom_info->op_mode;
+ info->op_mode = dom_query_info.op_mode;
out:
- kfree(p_dom_info);
return rc;
}
EXPORT_SYMBOL(ep11_get_domain_info);
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 15/20] s390/zcrypt: Rework ep11 misc functions to use cprb mempool
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (13 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 14/20] s390/zcrypt: Locate ep11_domain_query_info onto the stack instead of kmalloc Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-20 15:18 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 16/20] s390/zcrypt: Add small mempool for ep11 card info list entries Harald Freudenberger
` (5 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
There are two places in the ep11 misc code where a short term
memory buffer is needed. Rework this code to use the cprb mempool
to satisfy this ephemeral memory requirements.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/pkey_ep11.c | 3 +-
drivers/s390/crypto/zcrypt_cex4.c | 12 +--
drivers/s390/crypto/zcrypt_ep11misc.c | 104 ++++++++++++++++----------
drivers/s390/crypto/zcrypt_ep11misc.h | 8 +-
4 files changed, 78 insertions(+), 49 deletions(-)
diff --git a/drivers/s390/crypto/pkey_ep11.c b/drivers/s390/crypto/pkey_ep11.c
index b970f0be84be..38aa0c7807c2 100644
--- a/drivers/s390/crypto/pkey_ep11.c
+++ b/drivers/s390/crypto/pkey_ep11.c
@@ -280,6 +280,7 @@ static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
{
struct pkey_apqn *local_apqns = NULL;
int i, len, rc;
+ const u32 xflags = 0;
/* check keytype, subtype, keybitsize */
switch (keytype) {
@@ -328,7 +329,7 @@ static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
rc = ep11_genaeskey(apqns[i].card, apqns[i].domain,
keybitsize, flags,
- keybuf, keybuflen, subtype);
+ keybuf, keybuflen, subtype, xflags);
}
out:
diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c
index 49a638d373fa..83e277d18844 100644
--- a/drivers/s390/crypto/zcrypt_cex4.c
+++ b/drivers/s390/crypto/zcrypt_cex4.c
@@ -216,7 +216,7 @@ static ssize_t ep11_api_ordinalnr_show(struct device *dev,
memset(&ci, 0, sizeof(ci));
- ep11_get_card_info(ac->id, &ci, zc->online);
+ ep11_get_card_info(ac->id, &ci, zc->online, 0);
if (ci.API_ord_nr > 0)
return sysfs_emit(buf, "%u\n", ci.API_ord_nr);
@@ -237,7 +237,7 @@ static ssize_t ep11_fw_version_show(struct device *dev,
memset(&ci, 0, sizeof(ci));
- ep11_get_card_info(ac->id, &ci, zc->online);
+ ep11_get_card_info(ac->id, &ci, zc->online, 0);
if (ci.FW_version > 0)
return sysfs_emit(buf, "%d.%d\n",
@@ -260,7 +260,7 @@ static ssize_t ep11_serialnr_show(struct device *dev,
memset(&ci, 0, sizeof(ci));
- ep11_get_card_info(ac->id, &ci, zc->online);
+ ep11_get_card_info(ac->id, &ci, zc->online, 0);
if (ci.serial[0])
return sysfs_emit(buf, "%16.16s\n", ci.serial);
@@ -298,7 +298,7 @@ static ssize_t ep11_card_op_modes_show(struct device *dev,
memset(&ci, 0, sizeof(ci));
- ep11_get_card_info(ac->id, &ci, zc->online);
+ ep11_get_card_info(ac->id, &ci, zc->online, 0);
for (i = 0; ep11_op_modes[i].mode_txt; i++) {
if (ci.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {
@@ -348,7 +348,7 @@ static ssize_t ep11_mkvps_show(struct device *dev,
if (zq->online)
ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid),
- &di);
+ &di, 0);
if (di.cur_wk_state == '0') {
n = sysfs_emit(buf, "WK CUR: %s -\n",
@@ -395,7 +395,7 @@ static ssize_t ep11_queue_op_modes_show(struct device *dev,
if (zq->online)
ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid),
- &di);
+ &di, 0);
for (i = 0; ep11_op_modes[i].mode_txt; i++) {
if (di.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) {
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
index 7fb55be3e943..af59d66bff33 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.c
+++ b/drivers/s390/crypto/zcrypt_ep11misc.c
@@ -629,7 +629,7 @@ static int check_reply_cprb(const struct ep11_cprb *rep, const char *func)
* Helper function which does an ep11 query with given query type.
*/
static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
- size_t buflen, u8 *buf)
+ size_t buflen, u8 *buf, u32 xflags)
{
struct ep11_info_req_pl {
struct pl_head head;
@@ -653,7 +653,6 @@ static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
struct ep11_target_dev target;
struct ep11_urb urb;
int api = EP11_API_V1, rc = -ENOMEM;
- const u32 xflags = 0;
/* request cprb and payload */
req = alloc_cprbmem(sizeof(struct ep11_info_req_pl), xflags);
@@ -720,7 +719,8 @@ static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
/*
* Provide information about an EP11 card.
*/
-int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify)
+int ep11_get_card_info(u16 card, struct ep11_card_info *info,
+ int verify, u32 xflags)
{
int rc;
struct ep11_module_query_info {
@@ -752,12 +752,15 @@ int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify)
rc = card_cache_fetch(card, info);
if (rc || verify) {
- pmqi = kmalloc(sizeof(*pmqi), GFP_KERNEL);
+ /* use the cprb mempool to satisfy this short term mem alloc */
+ pmqi = (xflags & ZCRYPT_XFLAG_NOMEMALLOC) ?
+ mempool_alloc_preallocated(cprb_mempool) :
+ mempool_alloc(cprb_mempool, GFP_KERNEL);
if (!pmqi)
return -ENOMEM;
rc = ep11_query_info(card, AUTOSEL_DOM,
0x01 /* module info query */,
- sizeof(*pmqi), (u8 *)pmqi);
+ sizeof(*pmqi), (u8 *)pmqi, xflags);
if (rc) {
if (rc == -ENODEV)
card_cache_scrub(card);
@@ -773,7 +776,7 @@ int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify)
}
out:
- kfree(pmqi);
+ mempool_free(pmqi, cprb_mempool);
return rc;
}
EXPORT_SYMBOL(ep11_get_card_info);
@@ -781,7 +784,8 @@ EXPORT_SYMBOL(ep11_get_card_info);
/*
* Provide information about a domain within an EP11 card.
*/
-int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info)
+int ep11_get_domain_info(u16 card, u16 domain,
+ struct ep11_domain_info *info, u32 xflags)
{
int rc;
struct ep11_domain_query_info {
@@ -793,7 +797,8 @@ int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info)
} __packed dom_query_info;
rc = ep11_query_info(card, domain, 0x03 /* domain info query */,
- sizeof(dom_query_info), (u8 *)&dom_query_info);
+ sizeof(dom_query_info), (u8 *)&dom_query_info,
+ xflags);
if (rc)
goto out;
@@ -827,7 +832,7 @@ EXPORT_SYMBOL(ep11_get_domain_info);
static int _ep11_genaeskey(u16 card, u16 domain,
u32 keybitsize, u32 keygenflags,
- u8 *keybuf, size_t *keybufsize)
+ u8 *keybuf, size_t *keybufsize, u32 xflags)
{
struct keygen_req_pl {
struct pl_head head;
@@ -865,7 +870,6 @@ static int _ep11_genaeskey(u16 card, u16 domain,
struct ep11_urb urb;
int api, rc = -ENOMEM;
u8 *p;
- const u32 xflags = 0;
switch (keybitsize) {
case 128:
@@ -969,7 +973,7 @@ static int _ep11_genaeskey(u16 card, u16 domain,
}
int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
- u8 *keybuf, u32 *keybufsize, u32 keybufver)
+ u8 *keybuf, u32 *keybufsize, u32 keybufver, u32 xflags)
{
struct ep11kblob_header *hdr;
size_t hdr_size, pl_size;
@@ -990,7 +994,7 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
return rc;
rc = _ep11_genaeskey(card, domain, keybitsize, keygenflags,
- pl, &pl_size);
+ pl, &pl_size, xflags);
if (rc)
return rc;
@@ -1010,7 +1014,8 @@ static int ep11_cryptsingle(u16 card, u16 domain,
u16 mode, u32 mech, const u8 *iv,
const u8 *key, size_t keysize,
const u8 *inbuf, size_t inbufsize,
- u8 *outbuf, size_t *outbufsize)
+ u8 *outbuf, size_t *outbufsize,
+ u32 xflags)
{
struct crypt_req_pl {
struct pl_head head;
@@ -1041,7 +1046,6 @@ static int ep11_cryptsingle(u16 card, u16 domain,
size_t req_pl_size, rep_pl_size;
int n, api = EP11_API_V1, rc = -ENOMEM;
u8 *p;
- const u32 xflags = 0;
/* the simple asn1 coding used has length limits */
if (keysize > 0xFFFF || inbufsize > 0xFFFF)
@@ -1141,7 +1145,7 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
const u8 *enckey, size_t enckeysize,
u32 mech, const u8 *iv,
u32 keybitsize, u32 keygenflags,
- u8 *keybuf, size_t *keybufsize)
+ u8 *keybuf, size_t *keybufsize, u32 xflags)
{
struct uw_req_pl {
struct pl_head head;
@@ -1181,7 +1185,6 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
struct ep11_urb urb;
int api, rc = -ENOMEM;
u8 *p;
- const u32 xflags = 0;
/* request cprb and payload */
api = (!keygenflags || keygenflags & 0x00200000) ?
@@ -1290,7 +1293,7 @@ static int ep11_unwrapkey(u16 card, u16 domain,
u32 mech, const u8 *iv,
u32 keybitsize, u32 keygenflags,
u8 *keybuf, u32 *keybufsize,
- u8 keybufver)
+ u8 keybufver, u32 xflags)
{
struct ep11kblob_header *hdr;
size_t hdr_size, pl_size;
@@ -1304,7 +1307,7 @@ static int ep11_unwrapkey(u16 card, u16 domain,
rc = _ep11_unwrapkey(card, domain, kek, keksize, enckey, enckeysize,
mech, iv, keybitsize, keygenflags,
- pl, &pl_size);
+ pl, &pl_size, xflags);
if (rc)
return rc;
@@ -1323,7 +1326,7 @@ static int ep11_unwrapkey(u16 card, u16 domain,
static int _ep11_wrapkey(u16 card, u16 domain,
const u8 *key, size_t keysize,
u32 mech, const u8 *iv,
- u8 *databuf, size_t *datasize)
+ u8 *databuf, size_t *datasize, u32 xflags)
{
struct wk_req_pl {
struct pl_head head;
@@ -1356,7 +1359,6 @@ static int _ep11_wrapkey(u16 card, u16 domain,
size_t req_pl_size;
int api, rc = -ENOMEM;
u8 *p;
- const u32 xflags = 0;
/* request cprb and payload */
req_pl_size = sizeof(struct wk_req_pl) + (iv ? 16 : 0)
@@ -1447,8 +1449,10 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
u32 keytype)
{
int rc;
- u8 encbuf[64], *kek = NULL;
+ void *mem;
+ u8 encbuf[64], *kek;
size_t clrkeylen, keklen, encbuflen = sizeof(encbuf);
+ const u32 xflags = 0;
if (keybitsize == 128 || keybitsize == 192 || keybitsize == 256) {
clrkeylen = keybitsize / 8;
@@ -1458,18 +1462,24 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
return -EINVAL;
}
- /* allocate memory for the temp kek */
+ /*
+ * Allocate space for the temp kek.
+ * Also we only need up to MAXEP11AESKEYBLOBSIZE bytes for this
+ * we use the already existing cprb mempool to solve this
+ * short term memory requirement.
+ */
+ mem = (xflags & ZCRYPT_XFLAG_NOMEMALLOC) ?
+ mempool_alloc_preallocated(cprb_mempool) :
+ mempool_alloc(cprb_mempool, GFP_KERNEL);
+ if (!mem)
+ return -ENOMEM;
+ kek = (u8 *)mem;
keklen = MAXEP11AESKEYBLOBSIZE;
- kek = kmalloc(keklen, GFP_ATOMIC);
- if (!kek) {
- rc = -ENOMEM;
- goto out;
- }
/* Step 1: generate AES 256 bit random kek key */
rc = _ep11_genaeskey(card, domain, 256,
0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */
- kek, &keklen);
+ kek, &keklen, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s generate kek key failed, rc=%d\n",
__func__, rc);
@@ -1478,7 +1488,7 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
/* Step 2: encrypt clear key value with the kek key */
rc = ep11_cryptsingle(card, domain, 0, 0, def_iv, kek, keklen,
- clrkey, clrkeylen, encbuf, &encbuflen);
+ clrkey, clrkeylen, encbuf, &encbuflen, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s encrypting key value with kek key failed, rc=%d\n",
__func__, rc);
@@ -1488,7 +1498,7 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
/* Step 3: import the encrypted key value as a new key */
rc = ep11_unwrapkey(card, domain, kek, keklen,
encbuf, encbuflen, 0, def_iv,
- keybitsize, 0, keybuf, keybufsize, keytype);
+ keybitsize, 0, keybuf, keybufsize, keytype, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s importing key value as new key failed, rc=%d\n",
__func__, rc);
@@ -1496,7 +1506,7 @@ int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
}
out:
- kfree(kek);
+ mempool_free(mem, cprb_mempool);
return rc;
}
EXPORT_SYMBOL(ep11_clr2keyblob);
@@ -1519,6 +1529,7 @@ int ep11_kblob2protkey(u16 card, u16 dom,
} __packed * wki;
u8 *wkbuf = NULL;
int rc = -EIO;
+ const u32 xflags = 0;
if (ep11_kb_decode((u8 *)keyblob, keybloblen, &hdr, NULL, &key, &keylen))
return -EINVAL;
@@ -1529,15 +1540,29 @@ int ep11_kblob2protkey(u16 card, u16 dom,
}
/* !!! hdr is no longer a valid header !!! */
- /* alloc temp working buffer */
+ /* need a temp working buffer */
wkbuflen = (keylen + AES_BLOCK_SIZE) & (~(AES_BLOCK_SIZE - 1));
- wkbuf = kmalloc(wkbuflen, GFP_ATOMIC);
- if (!wkbuf)
- return -ENOMEM;
+ if (wkbuflen > CPRB_MEMPOOL_ITEM_SIZE) {
+ /* this should never happen */
+ rc = -ENOMEM;
+ ZCRYPT_DBF_ERR("%s wkbuflen %d > cprb mempool item size %d, rc=%d\n",
+ __func__, (int)wkbuflen, CPRB_MEMPOOL_ITEM_SIZE, rc);
+ return rc;
+ }
+ /* use the cprb mempool to satisfy this short term mem allocation */
+ wkbuf = (xflags & ZCRYPT_XFLAG_NOMEMALLOC) ?
+ mempool_alloc_preallocated(cprb_mempool) :
+ mempool_alloc(cprb_mempool, GFP_ATOMIC);
+ if (!wkbuf) {
+ rc = -ENOMEM;
+ ZCRYPT_DBF_ERR("%s allocating tmp buffer via cprb mempool failed, rc=%d\n",
+ __func__, rc);
+ return rc;
+ }
/* ep11 secure key -> protected key + info */
rc = _ep11_wrapkey(card, dom, (u8 *)key, keylen,
- 0, def_iv, wkbuf, &wkbuflen);
+ 0, def_iv, wkbuf, &wkbuflen, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s rewrapping ep11 key to pkey failed, rc=%d\n",
__func__, rc);
@@ -1604,7 +1629,7 @@ int ep11_kblob2protkey(u16 card, u16 dom,
*protkeylen = wki->pkeysize;
out:
- kfree(wkbuf);
+ mempool_free(wkbuf, cprb_mempool);
return rc;
}
EXPORT_SYMBOL(ep11_kblob2protkey);
@@ -1617,6 +1642,7 @@ int ep11_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
struct ep11_domain_info edi;
struct ep11_card_info eci;
u32 _nr_apqns = 0;
+ const u32 xflags = 0;
/* occupy the device status memory */
mutex_lock(&dev_status_mem_mutex);
@@ -1651,14 +1677,14 @@ int ep11_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
continue;
/* check min api version if given */
if (minapi > 0) {
- if (ep11_get_card_info(card, &eci, 0))
+ if (ep11_get_card_info(card, &eci, 0, xflags))
continue;
if (minapi > eci.API_ord_nr)
continue;
}
/* check wkvp if given */
if (wkvp) {
- if (ep11_get_domain_info(card, dom, &edi))
+ if (ep11_get_domain_info(card, dom, &edi, xflags))
continue;
if (edi.cur_wk_state != '1')
continue;
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h b/drivers/s390/crypto/zcrypt_ep11misc.h
index cbd615547bc2..7ef036759dc8 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.h
+++ b/drivers/s390/crypto/zcrypt_ep11misc.h
@@ -104,18 +104,20 @@ struct ep11_domain_info {
/*
* Provide information about an EP11 card.
*/
-int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify);
+int ep11_get_card_info(u16 card, struct ep11_card_info *info,
+ int verify, u32 xflags);
/*
* Provide information about a domain within an EP11 card.
*/
-int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info);
+int ep11_get_domain_info(u16 card, u16 domain,
+ struct ep11_domain_info *info, u32 xflags);
/*
* Generate (random) EP11 AES secure key.
*/
int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
- u8 *keybuf, u32 *keybufsize, u32 keybufver);
+ u8 *keybuf, u32 *keybufsize, u32 keybufver, u32 xflags);
/*
* Generate EP11 AES secure key with given clear key value.
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 16/20] s390/zcrypt: Add small mempool for ep11 card info list entries
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (14 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 15/20] s390/zcrypt: Rework ep11 misc functions to use cprb mempool Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-20 16:09 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 17/20] s390/pkey: Rework CCA pkey handler to use stack for small memory allocs Harald Freudenberger
` (4 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Add a small memory pool for (pre-)allocating ep11 card info list
entries. These entries are rather small and the pool is a simple
way to support the xflag ZCRYPT_XFLAG_NOMEMALLOC to avoid mallocs.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/zcrypt_ep11misc.c | 48 ++++++++++++++++++++++-----
1 file changed, 39 insertions(+), 9 deletions(-)
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
index af59d66bff33..a9a6fdc32464 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.c
+++ b/drivers/s390/crypto/zcrypt_ep11misc.c
@@ -64,6 +64,10 @@ struct card_list_entry {
static LIST_HEAD(card_list);
static DEFINE_SPINLOCK(card_list_lock);
+/* memory pool for card_list_entry entries */
+#define INFO_ENTRY_MEMPOOL_MIN_ITEMS 4
+static mempool_t *info_mempool;
+
static int card_cache_fetch(u16 cardnr, struct ep11_card_info *ci)
{
int rc = -ENOENT;
@@ -82,7 +86,8 @@ static int card_cache_fetch(u16 cardnr, struct ep11_card_info *ci)
return rc;
}
-static void card_cache_update(u16 cardnr, const struct ep11_card_info *ci)
+static void card_cache_update(u16 cardnr, const struct ep11_card_info *ci,
+ u32 xflags)
{
int found = 0;
struct card_list_entry *ptr;
@@ -96,7 +101,9 @@ static void card_cache_update(u16 cardnr, const struct ep11_card_info *ci)
}
}
if (!found) {
- ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC);
+ ptr = (xflags & ZCRYPT_XFLAG_NOMEMALLOC) ?
+ mempool_alloc_preallocated(info_mempool) :
+ mempool_alloc(info_mempool, GFP_ATOMIC);
if (!ptr) {
spin_unlock_bh(&card_list_lock);
return;
@@ -116,7 +123,7 @@ static void card_cache_scrub(u16 cardnr)
list_for_each_entry(ptr, &card_list, list) {
if (ptr->cardnr == cardnr) {
list_del(&ptr->list);
- kfree(ptr);
+ mempool_free(ptr, info_mempool);
break;
}
}
@@ -130,7 +137,7 @@ static void __exit card_cache_free(void)
spin_lock_bh(&card_list_lock);
list_for_each_entry_safe(ptr, pnext, &card_list, list) {
list_del(&ptr->list);
- kfree(ptr);
+ mempool_free(ptr, info_mempool);
}
spin_unlock_bh(&card_list_lock);
}
@@ -772,7 +779,7 @@ int ep11_get_card_info(u16 card, struct ep11_card_info *info,
(pmqi->FW_major_vers << 8) + pmqi->FW_minor_vers;
memcpy(info->serial, pmqi->serial, sizeof(info->serial));
info->op_mode = pmqi->op_mode;
- card_cache_update(card, info);
+ card_cache_update(card, info, xflags);
}
out:
@@ -1713,6 +1720,8 @@ EXPORT_SYMBOL(ep11_findcard2);
int __init zcrypt_ep11misc_init(void)
{
+ int rc = -ENOMEM;
+
/* Pre-allocate a small memory pool for ep11 cprbs. */
cprb_mempool = mempool_create_kmalloc_pool(zcrypt_ep11_cprbpool_min_items,
CPRB_MEMPOOL_ITEM_SIZE);
@@ -1720,19 +1729,39 @@ int __init zcrypt_ep11misc_init(void)
ZCRYPT_DBF_ERR("%s mempool_create(%d,%d) failed: %ld\n",
__func__, zcrypt_ep11_cprbpool_min_items,
CPRB_MEMPOOL_ITEM_SIZE, PTR_ERR(cprb_mempool));
+ rc = PTR_ERR(cprb_mempool);
cprb_mempool = NULL;
- return -ENOMEM;
+ goto out;
+ }
+
+ /* Pre-allocate a very small memory pool for card info entries */
+ info_mempool = mempool_create_kmalloc_pool(INFO_ENTRY_MEMPOOL_MIN_ITEMS,
+ sizeof(struct card_list_entry));
+ if (IS_ERR(info_mempool)) {
+ ZCRYPT_DBF_ERR("%s card info entry mempool_create(%d,%d) failed: %ld\n",
+ __func__, INFO_ENTRY_MEMPOOL_MIN_ITEMS,
+ (int)sizeof(struct card_list_entry),
+ PTR_ERR(info_mempool));
+ rc = PTR_ERR(info_mempool);
+ info_mempool = NULL;
+ goto out;
}
/* Pre-allocate one crypto status card struct used in findcard() */
dev_status_mem = kvmalloc(ZCRYPT_DEV_STATUS_EXT_SIZE, GFP_KERNEL);
if (!dev_status_mem) {
ZCRYPT_DBF_ERR("%s allocation of dev_status_mem failed\n", __func__);
- mempool_destroy(cprb_mempool);
- return -ENOMEM;
+ goto out;
}
- return 0;
+ rc = 0;
+
+out:
+ if (rc) {
+ mempool_destroy(cprb_mempool);
+ mempool_destroy(info_mempool);
+ }
+ return rc;
}
void zcrypt_ep11misc_exit(void)
@@ -1740,4 +1769,5 @@ void zcrypt_ep11misc_exit(void)
card_cache_free();
kvfree(dev_status_mem);
mempool_destroy(cprb_mempool);
+ mempool_destroy(info_mempool);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 17/20] s390/pkey: Rework CCA pkey handler to use stack for small memory allocs
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (15 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 16/20] s390/zcrypt: Add small mempool for ep11 card info list entries Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-21 9:05 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 18/20] s390/pkey: Rework EP11 " Harald Freudenberger
` (3 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
There have been some places in the CCA handler code where relatively
small amounts of memory have been allocated an freed at the end
of the function. This code has been reworked to use the stack instead.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/pkey_cca.c | 43 ++++++++--------------------------
1 file changed, 10 insertions(+), 33 deletions(-)
diff --git a/drivers/s390/crypto/pkey_cca.c b/drivers/s390/crypto/pkey_cca.c
index 8c9a0c5ca630..619d134b028d 100644
--- a/drivers/s390/crypto/pkey_cca.c
+++ b/drivers/s390/crypto/pkey_cca.c
@@ -213,7 +213,7 @@ static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
u8 *protkey, u32 *protkeylen, u32 *protkeytype)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
- struct pkey_apqn *local_apqns = NULL;
+ struct pkey_apqn _apqns[MAXAPQNSINLIST];
int i, rc;
if (keylen < sizeof(*hdr))
@@ -251,14 +251,10 @@ static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
- GFP_KERNEL);
- if (!local_apqns)
- return -ENOMEM;
- rc = cca_apqns4key(key, keylen, 0, local_apqns, &nr_apqns);
+ rc = cca_apqns4key(key, keylen, 0, _apqns, &nr_apqns);
if (rc)
goto out;
- apqns = local_apqns;
+ apqns = _apqns;
}
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -283,7 +279,6 @@ static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
}
out:
- kfree(local_apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -302,7 +297,7 @@ static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keybitsize, u32 flags,
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
{
- struct pkey_apqn *local_apqns = NULL;
+ struct pkey_apqn _apqns[MAXAPQNSINLIST];
int i, len, rc;
/* check keytype, subtype, keybitsize */
@@ -338,15 +333,10 @@ static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
- GFP_KERNEL);
- if (!local_apqns)
- return -ENOMEM;
- rc = cca_apqns4type(subtype, NULL, NULL, 0,
- local_apqns, &nr_apqns);
+ rc = cca_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
if (rc)
goto out;
- apqns = local_apqns;
+ apqns = _apqns;
}
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -363,7 +353,6 @@ static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
}
out:
- kfree(local_apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -383,7 +372,7 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
const u8 *clrkey, u32 clrkeylen,
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
{
- struct pkey_apqn *local_apqns = NULL;
+ struct pkey_apqn _apqns[MAXAPQNSINLIST];
int i, len, rc;
/* check keytype, subtype, clrkeylen, keybitsize */
@@ -424,15 +413,10 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
- GFP_KERNEL);
- if (!local_apqns)
- return -ENOMEM;
- rc = cca_apqns4type(subtype, NULL, NULL, 0,
- local_apqns, &nr_apqns);
+ rc = cca_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
if (rc)
goto out;
- apqns = local_apqns;
+ apqns = _apqns;
}
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -449,7 +433,6 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
}
out:
- kfree(local_apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -552,8 +535,8 @@ static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
{
const struct keytoken_header *hdr = (const struct keytoken_header *)key;
const struct clearkeytoken *t = (const struct clearkeytoken *)key;
+ u8 tmpbuf[SECKEYBLOBSIZE]; /* 64 bytes */
u32 tmplen, keysize = 0;
- u8 *tmpbuf;
int i, rc;
if (keylen < sizeof(*hdr))
@@ -565,11 +548,6 @@ static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
if (!keysize || t->len != keysize)
return -EINVAL;
- /* alloc tmp key buffer */
- tmpbuf = kmalloc(SECKEYBLOBSIZE, GFP_ATOMIC);
- if (!tmpbuf)
- return -ENOMEM;
-
/* try two times in case of failure */
for (i = 0, rc = -ENODEV; i < 2 && rc; i++) {
tmplen = SECKEYBLOBSIZE;
@@ -584,7 +562,6 @@ static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
pr_debug("cca_key2protkey()=%d\n", rc);
}
- kfree(tmpbuf);
pr_debug("rc=%d\n", rc);
return rc;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 18/20] s390/pkey: Rework EP11 pkey handler to use stack for small memory allocs
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (16 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 17/20] s390/pkey: Rework CCA pkey handler to use stack for small memory allocs Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-21 9:06 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 19/20] s390/zcrypt/pkey: Provide and pass xflags within pkey and zcrypt layers Harald Freudenberger
` (2 subsequent siblings)
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
There have been some places in the EP11 handler code where relatively
small amounts of memory have been allocated an freed at the end
of the function. This code has been reworked to use the stack instead.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/pkey_ep11.c | 43 ++++++++-------------------------
1 file changed, 10 insertions(+), 33 deletions(-)
diff --git a/drivers/s390/crypto/pkey_ep11.c b/drivers/s390/crypto/pkey_ep11.c
index 38aa0c7807c2..429c08facbfe 100644
--- a/drivers/s390/crypto/pkey_ep11.c
+++ b/drivers/s390/crypto/pkey_ep11.c
@@ -186,7 +186,7 @@ static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
u8 *protkey, u32 *protkeylen, u32 *protkeytype)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
- struct pkey_apqn *local_apqns = NULL;
+ struct pkey_apqn _apqns[MAXAPQNSINLIST];
int i, rc;
if (keylen < sizeof(*hdr))
@@ -223,14 +223,10 @@ static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
- GFP_KERNEL);
- if (!local_apqns)
- return -ENOMEM;
- rc = ep11_apqns4key(key, keylen, 0, local_apqns, &nr_apqns);
+ rc = ep11_apqns4key(key, keylen, 0, _apqns, &nr_apqns);
if (rc)
goto out;
- apqns = local_apqns;
+ apqns = _apqns;
}
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -259,7 +255,6 @@ static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
}
out:
- kfree(local_apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -278,7 +273,7 @@ static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keybitsize, u32 flags,
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
{
- struct pkey_apqn *local_apqns = NULL;
+ struct pkey_apqn _apqns[MAXAPQNSINLIST];
int i, len, rc;
const u32 xflags = 0;
@@ -315,15 +310,10 @@ static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
- GFP_KERNEL);
- if (!local_apqns)
- return -ENOMEM;
- rc = ep11_apqns4type(subtype, NULL, NULL, 0,
- local_apqns, &nr_apqns);
+ rc = ep11_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
if (rc)
goto out;
- apqns = local_apqns;
+ apqns = _apqns;
}
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -333,7 +323,6 @@ static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
}
out:
- kfree(local_apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -353,7 +342,7 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
const u8 *clrkey, u32 clrkeylen,
u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
{
- struct pkey_apqn *local_apqns = NULL;
+ struct pkey_apqn _apqns[MAXAPQNSINLIST];
int i, len, rc;
/* check keytype, subtype, clrkeylen, keybitsize */
@@ -394,15 +383,10 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
- GFP_KERNEL);
- if (!local_apqns)
- return -ENOMEM;
- rc = ep11_apqns4type(subtype, NULL, NULL, 0,
- local_apqns, &nr_apqns);
+ rc = ep11_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
if (rc)
goto out;
- apqns = local_apqns;
+ apqns = _apqns;
}
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
@@ -412,7 +396,6 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
}
out:
- kfree(local_apqns);
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -502,8 +485,8 @@ static int ep11_slowpath_key2protkey(const struct pkey_apqn *apqns,
{
const struct keytoken_header *hdr = (const struct keytoken_header *)key;
const struct clearkeytoken *t = (const struct clearkeytoken *)key;
+ u8 tmpbuf[MAXEP11AESKEYBLOBSIZE]; /* 336 bytes */
u32 tmplen, keysize = 0;
- u8 *tmpbuf;
int i, rc;
if (keylen < sizeof(*hdr))
@@ -515,11 +498,6 @@ static int ep11_slowpath_key2protkey(const struct pkey_apqn *apqns,
if (!keysize || t->len != keysize)
return -EINVAL;
- /* alloc tmp key buffer */
- tmpbuf = kmalloc(MAXEP11AESKEYBLOBSIZE, GFP_ATOMIC);
- if (!tmpbuf)
- return -ENOMEM;
-
/* try two times in case of failure */
for (i = 0, rc = -ENODEV; i < 2 && rc; i++) {
tmplen = MAXEP11AESKEYBLOBSIZE;
@@ -534,7 +512,6 @@ static int ep11_slowpath_key2protkey(const struct pkey_apqn *apqns,
pr_debug("ep11_key2protkey()=%d\n", rc);
}
- kfree(tmpbuf);
pr_debug("rc=%d\n", rc);
return rc;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 19/20] s390/zcrypt/pkey: Provide and pass xflags within pkey and zcrypt layers
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (17 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 18/20] s390/pkey: Rework EP11 " Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-20 16:30 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 20/20] s390/pkey/crypto: Introduce xflags param for pkey in-kernel API Harald Freudenberger
2025-03-20 16:40 ` [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Holger Dengler
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Provide and pass the xflag parameter from pkey ioctls through
the pkey handler and further down to the implementations
(CCA, EP11, PCKMO and UV). So all the code is now prepared
and ready to support the currently only xflag ("execution flag"):
* ZCRYPT_XFLAG_NOMEMALLOC - If this flag is set, no memory
allocations which may trigger any IO operations are done.
The in-kernel pkey API still does not provide this xflag param.
That's intended to come with another patch which more or less
only enables this functionality.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
drivers/s390/crypto/pkey_api.c | 49 +++++++++++-----------
drivers/s390/crypto/pkey_base.c | 34 ++++++++-------
drivers/s390/crypto/pkey_base.h | 37 ++++++++++-------
drivers/s390/crypto/pkey_cca.c | 59 +++++++++++++++------------
drivers/s390/crypto/pkey_ep11.c | 49 ++++++++++++----------
drivers/s390/crypto/pkey_pckmo.c | 9 ++--
drivers/s390/crypto/pkey_sysfs.c | 4 +-
drivers/s390/crypto/pkey_uv.c | 16 +++++++-
drivers/s390/crypto/zcrypt_ccamisc.c | 53 +++++++++++-------------
drivers/s390/crypto/zcrypt_ccamisc.h | 25 +++++++-----
drivers/s390/crypto/zcrypt_ep11misc.c | 10 ++---
drivers/s390/crypto/zcrypt_ep11misc.h | 7 ++--
12 files changed, 196 insertions(+), 156 deletions(-)
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 3a39e167bdbf..55a4e70b866b 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -24,7 +24,8 @@
*/
static int key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
const u8 *key, size_t keylen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags)
{
int rc;
@@ -32,14 +33,14 @@ static int key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
rc = pkey_handler_key_to_protkey(apqns, nr_apqns,
key, keylen,
protkey, protkeylen,
- protkeytype);
+ protkeytype, xflags);
/* if this did not work, try the slowpath way */
if (rc == -ENODEV) {
rc = pkey_handler_slowpath_key_to_protkey(apqns, nr_apqns,
key, keylen,
protkey, protkeylen,
- protkeytype);
+ protkeytype, xflags);
if (rc)
rc = -ENODEV;
}
@@ -55,13 +56,14 @@ int pkey_key2protkey(const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen, u32 *protkeytype)
{
int rc;
+ const u32 xflags = 0;
rc = key2protkey(NULL, 0, key, keylen,
- protkey, protkeylen, protkeytype);
+ protkey, protkeylen, protkeytype, xflags);
if (rc == -ENODEV) {
pkey_handler_request_modules();
rc = key2protkey(NULL, 0, key, keylen,
- protkey, protkeylen, protkeytype);
+ protkey, protkeylen, protkeytype, xflags);
}
return rc;
@@ -103,7 +105,7 @@ static int pkey_ioctl_genseck(struct pkey_genseck __user *ugs)
keybuflen = sizeof(kgs.seckey.seckey);
rc = pkey_handler_gen_key(&apqn, 1,
kgs.keytype, PKEY_TYPE_CCA_DATA, 0, 0,
- kgs.seckey.seckey, &keybuflen, NULL);
+ kgs.seckey.seckey, &keybuflen, NULL, 0);
pr_debug("gen_key()=%d\n", rc);
if (!rc && copy_to_user(ugs, &kgs, sizeof(kgs)))
rc = -EFAULT;
@@ -129,7 +131,7 @@ static int pkey_ioctl_clr2seck(struct pkey_clr2seck __user *ucs)
kcs.keytype, PKEY_TYPE_CCA_DATA, 0, 0,
kcs.clrkey.clrkey,
pkey_keytype_aes_to_size(kcs.keytype),
- kcs.seckey.seckey, &keybuflen, NULL);
+ kcs.seckey.seckey, &keybuflen, NULL, 0);
pr_debug("clr_to_key()=%d\n", rc);
if (!rc && copy_to_user(ucs, &kcs, sizeof(kcs)))
rc = -EFAULT;
@@ -154,7 +156,8 @@ static int pkey_ioctl_sec2protk(struct pkey_sec2protk __user *usp)
ksp.seckey.seckey,
sizeof(ksp.seckey.seckey),
ksp.protkey.protkey,
- &ksp.protkey.len, &ksp.protkey.type);
+ &ksp.protkey.len, &ksp.protkey.type,
+ 0);
pr_debug("key_to_protkey()=%d\n", rc);
if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
rc = -EFAULT;
@@ -198,7 +201,7 @@ static int pkey_ioctl_clr2protk(struct pkey_clr2protk __user *ucp)
rc = key2protkey(NULL, 0,
tmpbuf, sizeof(*t) + keylen,
kcp.protkey.protkey,
- &kcp.protkey.len, &kcp.protkey.type);
+ &kcp.protkey.len, &kcp.protkey.type, 0);
pr_debug("key2protkey()=%d\n", rc);
kfree_sensitive(tmpbuf);
@@ -228,12 +231,12 @@ static int pkey_ioctl_findcard(struct pkey_findcard __user *ufc)
rc = pkey_handler_apqns_for_key(kfc.seckey.seckey,
sizeof(kfc.seckey.seckey),
PKEY_FLAGS_MATCH_CUR_MKVP,
- apqns, &nr_apqns);
+ apqns, &nr_apqns, 0);
if (rc == -ENODEV)
rc = pkey_handler_apqns_for_key(kfc.seckey.seckey,
sizeof(kfc.seckey.seckey),
PKEY_FLAGS_MATCH_ALT_MKVP,
- apqns, &nr_apqns);
+ apqns, &nr_apqns, 0);
pr_debug("apqns_for_key()=%d\n", rc);
if (rc) {
kfree(apqns);
@@ -262,7 +265,7 @@ static int pkey_ioctl_skey2pkey(struct pkey_skey2pkey __user *usp)
sizeof(ksp.seckey.seckey),
ksp.protkey.protkey,
&ksp.protkey.len,
- &ksp.protkey.type);
+ &ksp.protkey.type, 0);
pr_debug("key_to_protkey()=%d\n", rc);
if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
rc = -EFAULT;
@@ -285,7 +288,7 @@ static int pkey_ioctl_verifykey(struct pkey_verifykey __user *uvk)
rc = pkey_handler_verify_key(kvk.seckey.seckey,
sizeof(kvk.seckey.seckey),
&kvk.cardnr, &kvk.domain,
- &keytype, &keybitsize, &flags);
+ &keytype, &keybitsize, &flags, 0);
pr_debug("verify_key()=%d\n", rc);
if (!rc && keytype != PKEY_TYPE_CCA_DATA)
rc = -EINVAL;
@@ -312,7 +315,7 @@ static int pkey_ioctl_genprotk(struct pkey_genprotk __user *ugp)
rc = pkey_handler_gen_key(NULL, 0, kgp.keytype,
PKEY_TYPE_PROTKEY, 0, 0,
kgp.protkey.protkey, &kgp.protkey.len,
- &kgp.protkey.type);
+ &kgp.protkey.type, 0);
pr_debug("gen_key()=%d\n", rc);
if (!rc && copy_to_user(ugp, &kgp, sizeof(kgp)))
rc = -EFAULT;
@@ -354,7 +357,7 @@ static int pkey_ioctl_verifyprotk(struct pkey_verifyprotk __user *uvp)
memcpy(t->protkey, kvp.protkey.protkey, kvp.protkey.len);
rc = pkey_handler_verify_key(tmpbuf, sizeof(*t),
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL, 0);
pr_debug("verify_key()=%d\n", rc);
kfree_sensitive(tmpbuf);
@@ -377,7 +380,7 @@ static int pkey_ioctl_kblob2protk(struct pkey_kblob2pkey __user *utp)
ktp.protkey.len = sizeof(ktp.protkey.protkey);
rc = key2protkey(NULL, 0, kkey, ktp.keylen,
ktp.protkey.protkey, &ktp.protkey.len,
- &ktp.protkey.type);
+ &ktp.protkey.type, 0);
pr_debug("key2protkey()=%d\n", rc);
kfree_sensitive(kkey);
if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
@@ -414,7 +417,7 @@ static int pkey_ioctl_genseck2(struct pkey_genseck2 __user *ugs)
}
rc = pkey_handler_gen_key(apqns, kgs.apqn_entries,
u, kgs.type, kgs.size, kgs.keygenflags,
- kkey, &klen, NULL);
+ kkey, &klen, NULL, 0);
pr_debug("gen_key()=%d\n", rc);
kfree(apqns);
if (rc) {
@@ -471,7 +474,7 @@ static int pkey_ioctl_clr2seck2(struct pkey_clr2seck2 __user *ucs)
rc = pkey_handler_clr_to_key(apqns, kcs.apqn_entries,
u, kcs.type, kcs.size, kcs.keygenflags,
kcs.clrkey.clrkey, kcs.size / 8,
- kkey, &klen, NULL);
+ kkey, &klen, NULL, 0);
pr_debug("clr_to_key()=%d\n", rc);
kfree(apqns);
if (rc) {
@@ -514,7 +517,7 @@ static int pkey_ioctl_verifykey2(struct pkey_verifykey2 __user *uvk)
rc = pkey_handler_verify_key(kkey, kvk.keylen,
&kvk.cardnr, &kvk.domain,
- &kvk.type, &kvk.size, &kvk.flags);
+ &kvk.type, &kvk.size, &kvk.flags, 0);
pr_debug("verify_key()=%d\n", rc);
kfree_sensitive(kkey);
@@ -544,7 +547,7 @@ static int pkey_ioctl_kblob2protk2(struct pkey_kblob2pkey2 __user *utp)
ktp.protkey.len = sizeof(ktp.protkey.protkey);
rc = key2protkey(apqns, ktp.apqn_entries, kkey, ktp.keylen,
ktp.protkey.protkey, &ktp.protkey.len,
- &ktp.protkey.type);
+ &ktp.protkey.type, 0);
pr_debug("key2protkey()=%d\n", rc);
kfree(apqns);
kfree_sensitive(kkey);
@@ -579,7 +582,7 @@ static int pkey_ioctl_apqns4k(struct pkey_apqns4key __user *uak)
return PTR_ERR(kkey);
}
rc = pkey_handler_apqns_for_key(kkey, kak.keylen, kak.flags,
- apqns, &nr_apqns);
+ apqns, &nr_apqns, 0);
pr_debug("apqns_for_key()=%d\n", rc);
kfree_sensitive(kkey);
if (rc && rc != -ENOSPC) {
@@ -626,7 +629,7 @@ static int pkey_ioctl_apqns4kt(struct pkey_apqns4keytype __user *uat)
}
rc = pkey_handler_apqns_for_keytype(kat.type,
kat.cur_mkvp, kat.alt_mkvp,
- kat.flags, apqns, &nr_apqns);
+ kat.flags, apqns, &nr_apqns, 0);
pr_debug("apqns_for_keytype()=%d\n", rc);
if (rc && rc != -ENOSPC) {
kfree(apqns);
@@ -678,7 +681,7 @@ static int pkey_ioctl_kblob2protk3(struct pkey_kblob2pkey3 __user *utp)
return -ENOMEM;
}
rc = key2protkey(apqns, ktp.apqn_entries, kkey, ktp.keylen,
- protkey, &protkeylen, &ktp.pkeytype);
+ protkey, &protkeylen, &ktp.pkeytype, 0);
pr_debug("key2protkey()=%d\n", rc);
kfree(apqns);
kfree_sensitive(kkey);
diff --git a/drivers/s390/crypto/pkey_base.c b/drivers/s390/crypto/pkey_base.c
index 64a376501d26..9e6f319acc63 100644
--- a/drivers/s390/crypto/pkey_base.c
+++ b/drivers/s390/crypto/pkey_base.c
@@ -150,7 +150,8 @@ EXPORT_SYMBOL(pkey_handler_put);
int pkey_handler_key_to_protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags)
{
const struct pkey_handler *h;
int rc = -ENODEV;
@@ -159,7 +160,7 @@ int pkey_handler_key_to_protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
if (h && h->key_to_protkey) {
rc = h->key_to_protkey(apqns, nr_apqns, key, keylen,
protkey, protkeylen,
- protkeytype);
+ protkeytype, xflags);
}
pkey_handler_put(h);
@@ -177,7 +178,7 @@ int pkey_handler_slowpath_key_to_protkey(const struct pkey_apqn *apqns,
size_t nr_apqns,
const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen,
- u32 *protkeytype)
+ u32 *protkeytype, u32 xflags)
{
const struct pkey_handler *h, *htmp[10];
int i, n = 0, rc = -ENODEV;
@@ -199,7 +200,7 @@ int pkey_handler_slowpath_key_to_protkey(const struct pkey_apqn *apqns,
rc = h->slowpath_key_to_protkey(apqns, nr_apqns,
key, keylen,
protkey, protkeylen,
- protkeytype);
+ protkeytype, xflags);
module_put(h->module);
}
@@ -210,7 +211,7 @@ EXPORT_SYMBOL(pkey_handler_slowpath_key_to_protkey);
int pkey_handler_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keytype, u32 keysubtype,
u32 keybitsize, u32 flags,
- u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
+ u8 *keybuf, u32 *keybuflen, u32 *keyinfo, u32 xflags)
{
const struct pkey_handler *h;
int rc = -ENODEV;
@@ -219,7 +220,7 @@ int pkey_handler_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (h && h->gen_key) {
rc = h->gen_key(apqns, nr_apqns, keytype, keysubtype,
keybitsize, flags,
- keybuf, keybuflen, keyinfo);
+ keybuf, keybuflen, keyinfo, xflags);
}
pkey_handler_put(h);
@@ -231,7 +232,8 @@ int pkey_handler_clr_to_key(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keytype, u32 keysubtype,
u32 keybitsize, u32 flags,
const u8 *clrkey, u32 clrkeylen,
- u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
+ u8 *keybuf, u32 *keybuflen, u32 *keyinfo,
+ u32 xflags)
{
const struct pkey_handler *h;
int rc = -ENODEV;
@@ -240,7 +242,7 @@ int pkey_handler_clr_to_key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (h && h->clr_to_key) {
rc = h->clr_to_key(apqns, nr_apqns, keytype, keysubtype,
keybitsize, flags, clrkey, clrkeylen,
- keybuf, keybuflen, keyinfo);
+ keybuf, keybuflen, keyinfo, xflags);
}
pkey_handler_put(h);
@@ -250,7 +252,8 @@ EXPORT_SYMBOL(pkey_handler_clr_to_key);
int pkey_handler_verify_key(const u8 *key, u32 keylen,
u16 *card, u16 *dom,
- u32 *keytype, u32 *keybitsize, u32 *flags)
+ u32 *keytype, u32 *keybitsize, u32 *flags,
+ u32 xflags)
{
const struct pkey_handler *h;
int rc = -ENODEV;
@@ -258,7 +261,7 @@ int pkey_handler_verify_key(const u8 *key, u32 keylen,
h = pkey_handler_get_keybased(key, keylen);
if (h && h->verify_key) {
rc = h->verify_key(key, keylen, card, dom,
- keytype, keybitsize, flags);
+ keytype, keybitsize, flags, xflags);
}
pkey_handler_put(h);
@@ -267,14 +270,16 @@ int pkey_handler_verify_key(const u8 *key, u32 keylen,
EXPORT_SYMBOL(pkey_handler_verify_key);
int pkey_handler_apqns_for_key(const u8 *key, u32 keylen, u32 flags,
- struct pkey_apqn *apqns, size_t *nr_apqns)
+ struct pkey_apqn *apqns, size_t *nr_apqns,
+ u32 xflags)
{
const struct pkey_handler *h;
int rc = -ENODEV;
h = pkey_handler_get_keybased(key, keylen);
if (h && h->apqns_for_key)
- rc = h->apqns_for_key(key, keylen, flags, apqns, nr_apqns);
+ rc = h->apqns_for_key(key, keylen, flags, apqns, nr_apqns,
+ xflags);
pkey_handler_put(h);
return rc;
@@ -283,7 +288,8 @@ EXPORT_SYMBOL(pkey_handler_apqns_for_key);
int pkey_handler_apqns_for_keytype(enum pkey_key_type keysubtype,
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
- struct pkey_apqn *apqns, size_t *nr_apqns)
+ struct pkey_apqn *apqns, size_t *nr_apqns,
+ u32 xflags)
{
const struct pkey_handler *h;
int rc = -ENODEV;
@@ -292,7 +298,7 @@ int pkey_handler_apqns_for_keytype(enum pkey_key_type keysubtype,
if (h && h->apqns_for_keytype) {
rc = h->apqns_for_keytype(keysubtype,
cur_mkvp, alt_mkvp, flags,
- apqns, nr_apqns);
+ apqns, nr_apqns, xflags);
}
pkey_handler_put(h);
diff --git a/drivers/s390/crypto/pkey_base.h b/drivers/s390/crypto/pkey_base.h
index 7347647dfaa7..9cdb3e74477f 100644
--- a/drivers/s390/crypto/pkey_base.h
+++ b/drivers/s390/crypto/pkey_base.h
@@ -159,29 +159,33 @@ struct pkey_handler {
bool (*is_supported_keytype)(enum pkey_key_type);
int (*key_to_protkey)(const struct pkey_apqn *apqns, size_t nr_apqns,
const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags);
int (*slowpath_key_to_protkey)(const struct pkey_apqn *apqns,
size_t nr_apqns,
const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen,
- u32 *protkeytype);
+ u32 *protkeytype, u32 xflags);
int (*gen_key)(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keytype, u32 keysubtype,
u32 keybitsize, u32 flags,
- u8 *keybuf, u32 *keybuflen, u32 *keyinfo);
+ u8 *keybuf, u32 *keybuflen, u32 *keyinfo, u32 xflags);
int (*clr_to_key)(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keytype, u32 keysubtype,
u32 keybitsize, u32 flags,
const u8 *clrkey, u32 clrkeylen,
- u8 *keybuf, u32 *keybuflen, u32 *keyinfo);
+ u8 *keybuf, u32 *keybuflen, u32 *keyinfo, u32 xflags);
int (*verify_key)(const u8 *key, u32 keylen,
u16 *card, u16 *dom,
- u32 *keytype, u32 *keybitsize, u32 *flags);
+ u32 *keytype, u32 *keybitsize, u32 *flags,
+ u32 xflags);
int (*apqns_for_key)(const u8 *key, u32 keylen, u32 flags,
- struct pkey_apqn *apqns, size_t *nr_apqns);
+ struct pkey_apqn *apqns, size_t *nr_apqns,
+ u32 xflags);
int (*apqns_for_keytype)(enum pkey_key_type ktype,
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
- struct pkey_apqn *apqns, size_t *nr_apqns);
+ struct pkey_apqn *apqns, size_t *nr_apqns,
+ u32 xflags);
/* used internal by pkey base */
struct list_head list;
};
@@ -199,29 +203,34 @@ void pkey_handler_put(const struct pkey_handler *handler);
int pkey_handler_key_to_protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags);
int pkey_handler_slowpath_key_to_protkey(const struct pkey_apqn *apqns,
size_t nr_apqns,
const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen,
- u32 *protkeytype);
+ u32 *protkeytype, u32 xflags);
int pkey_handler_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keytype, u32 keysubtype,
u32 keybitsize, u32 flags,
- u8 *keybuf, u32 *keybuflen, u32 *keyinfo);
+ u8 *keybuf, u32 *keybuflen, u32 *keyinfo, u32 xflags);
int pkey_handler_clr_to_key(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keytype, u32 keysubtype,
u32 keybitsize, u32 flags,
const u8 *clrkey, u32 clrkeylen,
- u8 *keybuf, u32 *keybuflen, u32 *keyinfo);
+ u8 *keybuf, u32 *keybuflen, u32 *keyinfo,
+ u32 xflags);
int pkey_handler_verify_key(const u8 *key, u32 keylen,
u16 *card, u16 *dom,
- u32 *keytype, u32 *keybitsize, u32 *flags);
+ u32 *keytype, u32 *keybitsize, u32 *flags,
+ u32 xflags);
int pkey_handler_apqns_for_key(const u8 *key, u32 keylen, u32 flags,
- struct pkey_apqn *apqns, size_t *nr_apqns);
+ struct pkey_apqn *apqns, size_t *nr_apqns,
+ u32 xflags);
int pkey_handler_apqns_for_keytype(enum pkey_key_type ktype,
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
- struct pkey_apqn *apqns, size_t *nr_apqns);
+ struct pkey_apqn *apqns, size_t *nr_apqns,
+ u32 xflags);
/*
* Unconditional try to load all handler modules
diff --git a/drivers/s390/crypto/pkey_cca.c b/drivers/s390/crypto/pkey_cca.c
index 619d134b028d..8761e3822ef2 100644
--- a/drivers/s390/crypto/pkey_cca.c
+++ b/drivers/s390/crypto/pkey_cca.c
@@ -70,7 +70,7 @@ static bool is_cca_keytype(enum pkey_key_type key_type)
}
static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
- struct pkey_apqn *apqns, size_t *nr_apqns)
+ struct pkey_apqn *apqns, size_t *nr_apqns, u32 xflags)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns);
@@ -109,7 +109,7 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
}
rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
minhwtype, AES_MK_SET,
- cur_mkvp, old_mkvp, 1);
+ cur_mkvp, old_mkvp, 1, xflags);
if (rc)
goto out;
@@ -128,7 +128,7 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
}
rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
ZCRYPT_CEX7, APKA_MK_SET,
- cur_mkvp, old_mkvp, 1);
+ cur_mkvp, old_mkvp, 1, xflags);
if (rc)
goto out;
@@ -153,7 +153,8 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
static int cca_apqns4type(enum pkey_key_type ktype,
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
- struct pkey_apqn *apqns, size_t *nr_apqns)
+ struct pkey_apqn *apqns, size_t *nr_apqns,
+ u32 xflags)
{
u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns);
int rc;
@@ -172,7 +173,7 @@ static int cca_apqns4type(enum pkey_key_type ktype,
minhwtype = ZCRYPT_CEX6;
rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
minhwtype, AES_MK_SET,
- cur_mkvp, old_mkvp, 1);
+ cur_mkvp, old_mkvp, 1, xflags);
if (rc)
goto out;
@@ -185,7 +186,7 @@ static int cca_apqns4type(enum pkey_key_type ktype,
old_mkvp = *((u64 *)alt_mkvp);
rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
ZCRYPT_CEX7, APKA_MK_SET,
- cur_mkvp, old_mkvp, 1);
+ cur_mkvp, old_mkvp, 1, xflags);
if (rc)
goto out;
@@ -210,7 +211,8 @@ static int cca_apqns4type(enum pkey_key_type ktype,
static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
struct pkey_apqn _apqns[MAXAPQNSINLIST];
@@ -251,7 +253,7 @@ static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- rc = cca_apqns4key(key, keylen, 0, _apqns, &nr_apqns);
+ rc = cca_apqns4key(key, keylen, 0, _apqns, &nr_apqns, xflags);
if (rc)
goto out;
apqns = _apqns;
@@ -262,16 +264,17 @@ static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
hdr->version == TOKVER_CCA_AES) {
rc = cca_sec2protkey(apqns[i].card, apqns[i].domain,
key, protkey,
- protkeylen, protkeytype);
+ protkeylen, protkeytype, xflags);
} else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
hdr->version == TOKVER_CCA_VLSC) {
rc = cca_cipher2protkey(apqns[i].card, apqns[i].domain,
key, protkey,
- protkeylen, protkeytype);
+ protkeylen, protkeytype,
+ xflags);
} else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
rc = cca_ecc2protkey(apqns[i].card, apqns[i].domain,
key, protkey,
- protkeylen, protkeytype);
+ protkeylen, protkeytype, xflags);
} else {
rc = -EINVAL;
break;
@@ -295,7 +298,7 @@ static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keytype, u32 subtype,
u32 keybitsize, u32 flags,
- u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
+ u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 xflags)
{
struct pkey_apqn _apqns[MAXAPQNSINLIST];
int i, len, rc;
@@ -333,7 +336,8 @@ static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- rc = cca_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
+ rc = cca_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns,
+ xflags);
if (rc)
goto out;
apqns = _apqns;
@@ -343,11 +347,11 @@ static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (subtype == PKEY_TYPE_CCA_CIPHER) {
rc = cca_gencipherkey(apqns[i].card, apqns[i].domain,
keybitsize, flags,
- keybuf, keybuflen);
+ keybuf, keybuflen, xflags);
} else {
/* PKEY_TYPE_CCA_DATA */
rc = cca_genseckey(apqns[i].card, apqns[i].domain,
- keybitsize, keybuf);
+ keybitsize, keybuf, xflags);
*keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
}
}
@@ -370,7 +374,7 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keytype, u32 subtype,
u32 keybitsize, u32 flags,
const u8 *clrkey, u32 clrkeylen,
- u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
+ u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 xflags)
{
struct pkey_apqn _apqns[MAXAPQNSINLIST];
int i, len, rc;
@@ -413,7 +417,8 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- rc = cca_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
+ rc = cca_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns,
+ xflags);
if (rc)
goto out;
apqns = _apqns;
@@ -423,11 +428,11 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (subtype == PKEY_TYPE_CCA_CIPHER) {
rc = cca_clr2cipherkey(apqns[i].card, apqns[i].domain,
keybitsize, flags, clrkey,
- keybuf, keybuflen);
+ keybuf, keybuflen, xflags);
} else {
/* PKEY_TYPE_CCA_DATA */
rc = cca_clr2seckey(apqns[i].card, apqns[i].domain,
- keybitsize, clrkey, keybuf);
+ keybitsize, clrkey, keybuf, xflags);
*keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
}
}
@@ -439,7 +444,7 @@ static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
static int cca_verifykey(const u8 *key, u32 keylen,
u16 *card, u16 *dom,
- u32 *keytype, u32 *keybitsize, u32 *flags)
+ u32 *keytype, u32 *keybitsize, u32 *flags, u32 xflags)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
u32 apqns[MAXAPQNSINLIST], nr_apqns = ARRAY_SIZE(apqns);
@@ -461,13 +466,13 @@ static int cca_verifykey(const u8 *key, u32 keylen,
*keybitsize = t->bitsize;
rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX3C, AES_MK_SET,
- t->mkvp, 0, 1);
+ t->mkvp, 0, 1, xflags);
if (!rc)
*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
if (rc == -ENODEV) {
rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX3C, AES_MK_SET,
- 0, t->mkvp, 1);
+ 0, t->mkvp, 1, xflags);
if (!rc)
*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
}
@@ -494,13 +499,13 @@ static int cca_verifykey(const u8 *key, u32 keylen,
*keybitsize = PKEY_SIZE_AES_256;
rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX6, AES_MK_SET,
- t->mkvp0, 0, 1);
+ t->mkvp0, 0, 1, xflags);
if (!rc)
*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
if (rc == -ENODEV) {
rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX6, AES_MK_SET,
- 0, t->mkvp0, 1);
+ 0, t->mkvp0, 1, xflags);
if (!rc)
*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
}
@@ -531,7 +536,7 @@ static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
size_t nr_apqns,
const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen,
- u32 *protkeytype)
+ u32 *protkeytype, u32 xflags)
{
const struct keytoken_header *hdr = (const struct keytoken_header *)key;
const struct clearkeytoken *t = (const struct clearkeytoken *)key;
@@ -553,12 +558,12 @@ static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
tmplen = SECKEYBLOBSIZE;
rc = cca_clr2key(NULL, 0, t->keytype, PKEY_TYPE_CCA_DATA,
8 * keysize, 0, t->clearkey, t->len,
- tmpbuf, &tmplen, NULL);
+ tmpbuf, &tmplen, NULL, xflags);
pr_debug("cca_clr2key()=%d\n", rc);
if (rc)
continue;
rc = cca_key2protkey(NULL, 0, tmpbuf, tmplen,
- protkey, protkeylen, protkeytype);
+ protkey, protkeylen, protkeytype, xflags);
pr_debug("cca_key2protkey()=%d\n", rc);
}
diff --git a/drivers/s390/crypto/pkey_ep11.c b/drivers/s390/crypto/pkey_ep11.c
index 429c08facbfe..82b01fbf08ae 100644
--- a/drivers/s390/crypto/pkey_ep11.c
+++ b/drivers/s390/crypto/pkey_ep11.c
@@ -70,7 +70,7 @@ static bool is_ep11_keytype(enum pkey_key_type key_type)
}
static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
- struct pkey_apqn *apqns, size_t *nr_apqns)
+ struct pkey_apqn *apqns, size_t *nr_apqns, u32 xflags)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns);
@@ -99,7 +99,7 @@ static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
}
rc = ep11_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
- minhwtype, api, kb->wkvp);
+ minhwtype, api, kb->wkvp, xflags);
if (rc)
goto out;
@@ -116,7 +116,7 @@ static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
}
rc = ep11_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
- minhwtype, api, kb->wkvp);
+ minhwtype, api, kb->wkvp, xflags);
if (rc)
goto out;
@@ -141,7 +141,7 @@ static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,
static int ep11_apqns4type(enum pkey_key_type ktype,
u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
- struct pkey_apqn *apqns, size_t *nr_apqns)
+ struct pkey_apqn *apqns, size_t *nr_apqns, u32 xflags)
{
u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns);
int rc;
@@ -158,7 +158,7 @@ static int ep11_apqns4type(enum pkey_key_type ktype,
wkvp = cur_mkvp;
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
rc = ep11_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
- ZCRYPT_CEX7, api, wkvp);
+ ZCRYPT_CEX7, api, wkvp, xflags);
if (rc)
goto out;
@@ -183,7 +183,8 @@ static int ep11_apqns4type(enum pkey_key_type ktype,
static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
struct pkey_apqn _apqns[MAXAPQNSINLIST];
@@ -223,7 +224,7 @@ static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- rc = ep11_apqns4key(key, keylen, 0, _apqns, &nr_apqns);
+ rc = ep11_apqns4key(key, keylen, 0, _apqns, &nr_apqns, xflags);
if (rc)
goto out;
apqns = _apqns;
@@ -235,19 +236,22 @@ static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {
rc = ep11_kblob2protkey(apqns[i].card, apqns[i].domain,
key, hdr->len, protkey,
- protkeylen, protkeytype);
+ protkeylen, protkeytype,
+ xflags);
} else if (hdr->type == TOKTYPE_NON_CCA &&
hdr->version == TOKVER_EP11_ECC_WITH_HEADER &&
is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {
rc = ep11_kblob2protkey(apqns[i].card, apqns[i].domain,
key, hdr->len, protkey,
- protkeylen, protkeytype);
+ protkeylen, protkeytype,
+ xflags);
} else if (hdr->type == TOKTYPE_NON_CCA &&
hdr->version == TOKVER_EP11_AES &&
is_ep11_keyblob(key)) {
rc = ep11_kblob2protkey(apqns[i].card, apqns[i].domain,
key, hdr->len, protkey,
- protkeylen, protkeytype);
+ protkeylen, protkeytype,
+ xflags);
} else {
rc = -EINVAL;
break;
@@ -271,11 +275,10 @@ static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keytype, u32 subtype,
u32 keybitsize, u32 flags,
- u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
+ u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 xflags)
{
struct pkey_apqn _apqns[MAXAPQNSINLIST];
int i, len, rc;
- const u32 xflags = 0;
/* check keytype, subtype, keybitsize */
switch (keytype) {
@@ -310,7 +313,8 @@ static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- rc = ep11_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
+ rc = ep11_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns,
+ xflags);
if (rc)
goto out;
apqns = _apqns;
@@ -340,7 +344,7 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
u32 keytype, u32 subtype,
u32 keybitsize, u32 flags,
const u8 *clrkey, u32 clrkeylen,
- u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
+ u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 xflags)
{
struct pkey_apqn _apqns[MAXAPQNSINLIST];
int i, len, rc;
@@ -383,7 +387,8 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
if (!apqns || (nr_apqns == 1 &&
apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
nr_apqns = MAXAPQNSINLIST;
- rc = ep11_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns);
+ rc = ep11_apqns4type(subtype, NULL, NULL, 0, _apqns, &nr_apqns,
+ xflags);
if (rc)
goto out;
apqns = _apqns;
@@ -392,7 +397,7 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
rc = ep11_clr2keyblob(apqns[i].card, apqns[i].domain,
keybitsize, flags, clrkey,
- keybuf, keybuflen, subtype);
+ keybuf, keybuflen, subtype, xflags);
}
out:
@@ -402,7 +407,7 @@ static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
static int ep11_verifykey(const u8 *key, u32 keylen,
u16 *card, u16 *dom,
- u32 *keytype, u32 *keybitsize, u32 *flags)
+ u32 *keytype, u32 *keybitsize, u32 *flags, u32 xflags)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
u32 apqns[MAXAPQNSINLIST], nr_apqns = ARRAY_SIZE(apqns);
@@ -427,7 +432,7 @@ static int ep11_verifykey(const u8 *key, u32 keylen,
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
rc = ep11_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX7, api,
- ep11_kb_wkvp(key, keylen));
+ ep11_kb_wkvp(key, keylen), xflags);
if (rc)
goto out;
@@ -451,7 +456,7 @@ static int ep11_verifykey(const u8 *key, u32 keylen,
api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;
rc = ep11_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX7, api,
- ep11_kb_wkvp(key, keylen));
+ ep11_kb_wkvp(key, keylen), xflags);
if (rc)
goto out;
@@ -481,7 +486,7 @@ static int ep11_slowpath_key2protkey(const struct pkey_apqn *apqns,
size_t nr_apqns,
const u8 *key, u32 keylen,
u8 *protkey, u32 *protkeylen,
- u32 *protkeytype)
+ u32 *protkeytype, u32 xflags)
{
const struct keytoken_header *hdr = (const struct keytoken_header *)key;
const struct clearkeytoken *t = (const struct clearkeytoken *)key;
@@ -503,12 +508,12 @@ static int ep11_slowpath_key2protkey(const struct pkey_apqn *apqns,
tmplen = MAXEP11AESKEYBLOBSIZE;
rc = ep11_clr2key(NULL, 0, t->keytype, PKEY_TYPE_EP11,
8 * keysize, 0, t->clearkey, t->len,
- tmpbuf, &tmplen, NULL);
+ tmpbuf, &tmplen, NULL, xflags);
pr_debug("ep11_clr2key()=%d\n", rc);
if (rc)
continue;
rc = ep11_key2protkey(NULL, 0, tmpbuf, tmplen,
- protkey, protkeylen, protkeytype);
+ protkey, protkeylen, protkeytype, xflags);
pr_debug("ep11_key2protkey()=%d\n", rc);
}
diff --git a/drivers/s390/crypto/pkey_pckmo.c b/drivers/s390/crypto/pkey_pckmo.c
index 835d59f4fbc5..00aabb1b3e18 100644
--- a/drivers/s390/crypto/pkey_pckmo.c
+++ b/drivers/s390/crypto/pkey_pckmo.c
@@ -406,7 +406,8 @@ static int pckmo_verify_key(const u8 *key, u32 keylen)
static int pkey_pckmo_key2protkey(const struct pkey_apqn *_apqns,
size_t _nr_apqns,
const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *keyinfo)
+ u8 *protkey, u32 *protkeylen, u32 *keyinfo,
+ u32 _xflags)
{
return pckmo_key2protkey(key, keylen,
protkey, protkeylen, keyinfo);
@@ -415,7 +416,8 @@ static int pkey_pckmo_key2protkey(const struct pkey_apqn *_apqns,
static int pkey_pckmo_gen_key(const struct pkey_apqn *_apqns, size_t _nr_apqns,
u32 keytype, u32 keysubtype,
u32 _keybitsize, u32 _flags,
- u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
+ u8 *keybuf, u32 *keybuflen, u32 *keyinfo,
+ u32 _xflags)
{
return pckmo_gen_protkey(keytype, keysubtype,
keybuf, keybuflen, keyinfo);
@@ -423,7 +425,8 @@ static int pkey_pckmo_gen_key(const struct pkey_apqn *_apqns, size_t _nr_apqns,
static int pkey_pckmo_verifykey(const u8 *key, u32 keylen,
u16 *_card, u16 *_dom,
- u32 *_keytype, u32 *_keybitsize, u32 *_flags)
+ u32 *_keytype, u32 *_keybitsize,
+ u32 *_flags, u32 _xflags)
{
return pckmo_verify_key(key, keylen);
}
diff --git a/drivers/s390/crypto/pkey_sysfs.c b/drivers/s390/crypto/pkey_sysfs.c
index 57edc97bafd2..cea772973649 100644
--- a/drivers/s390/crypto/pkey_sysfs.c
+++ b/drivers/s390/crypto/pkey_sysfs.c
@@ -29,13 +29,13 @@ static int sys_pkey_handler_gen_key(u32 keytype, u32 keysubtype,
rc = pkey_handler_gen_key(NULL, 0,
keytype, keysubtype,
keybitsize, flags,
- keybuf, keybuflen, keyinfo);
+ keybuf, keybuflen, keyinfo, 0);
if (rc == -ENODEV) {
pkey_handler_request_modules();
rc = pkey_handler_gen_key(NULL, 0,
keytype, keysubtype,
keybitsize, flags,
- keybuf, keybuflen, keyinfo);
+ keybuf, keybuflen, keyinfo, 0);
}
return rc;
diff --git a/drivers/s390/crypto/pkey_uv.c b/drivers/s390/crypto/pkey_uv.c
index 805817b14354..f36ff7531213 100644
--- a/drivers/s390/crypto/pkey_uv.c
+++ b/drivers/s390/crypto/pkey_uv.c
@@ -172,13 +172,19 @@ static int uv_get_size_and_type(u16 secret_type, u32 *pkeysize, u32 *pkeytype)
static int uv_key2protkey(const struct pkey_apqn *_apqns __always_unused,
size_t _nr_apqns __always_unused,
const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *keyinfo)
+ u8 *protkey, u32 *protkeylen, u32 *keyinfo,
+ u32 xflags)
{
struct uvsecrettoken *t = (struct uvsecrettoken *)key;
u32 pkeysize, pkeytype;
u16 secret_type;
int rc;
+ if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
+
rc = uv_get_size_and_type(t->secret_type, &pkeysize, &pkeytype);
if (rc)
goto out;
@@ -214,13 +220,19 @@ static int uv_key2protkey(const struct pkey_apqn *_apqns __always_unused,
static int uv_verifykey(const u8 *key, u32 keylen,
u16 *_card __always_unused,
u16 *_dom __always_unused,
- u32 *keytype, u32 *keybitsize, u32 *flags)
+ u32 *keytype, u32 *keybitsize, u32 *flags,
+ u32 xflags)
{
struct uvsecrettoken *t = (struct uvsecrettoken *)key;
struct uv_secret_list_item_hdr secret_meta_data;
u32 pkeysize, pkeytype, bitsize;
int rc;
+ if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
+
rc = uv_get_size_and_type(t->secret_type, &pkeysize, &pkeytype);
if (rc)
goto out;
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
index e4ec922aae0d..3b80ce605192 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.c
+++ b/drivers/s390/crypto/zcrypt_ccamisc.c
@@ -334,7 +334,7 @@ static inline void prep_xcrb(struct ica_xcRB *pxcrb,
* Generate (random) CCA AES DATA secure key.
*/
int cca_genseckey(u16 cardnr, u16 domain,
- u32 keybitsize, u8 *seckey)
+ u32 keybitsize, u8 *seckey, u32 xflags)
{
int i, rc, keysize;
int seckeysize;
@@ -374,7 +374,6 @@ int cca_genseckey(u16 cardnr, u16 domain,
} keyblock;
} lv3;
} __packed * prepparm;
- const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
@@ -479,7 +478,7 @@ EXPORT_SYMBOL(cca_genseckey);
* Generate an CCA AES DATA secure key with given key value.
*/
int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
- const u8 *clrkey, u8 *seckey)
+ const u8 *clrkey, u8 *seckey, u32 xflags)
{
int rc, keysize, seckeysize;
u8 *mem, *ptr;
@@ -517,7 +516,6 @@ int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
} keyblock;
} lv3;
} __packed * prepparm;
- const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
@@ -621,7 +619,7 @@ EXPORT_SYMBOL(cca_clr2seckey);
*/
int cca_sec2protkey(u16 cardnr, u16 domain,
const u8 *seckey, u8 *protkey, u32 *protkeylen,
- u32 *protkeytype)
+ u32 *protkeytype, u32 xflags)
{
int rc;
u8 *mem, *ptr;
@@ -665,7 +663,6 @@ int cca_sec2protkey(u16 cardnr, u16 domain,
} ckb;
} lv3;
} __packed * prepparm;
- const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
@@ -787,7 +784,7 @@ static const u8 aes_cipher_key_skeleton[] = {
* Generate (random) CCA AES CIPHER secure key.
*/
int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
- u8 *keybuf, u32 *keybufsize)
+ u8 *keybuf, u32 *keybufsize, u32 xflags)
{
int rc;
u8 *mem, *ptr;
@@ -861,7 +858,6 @@ int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
} kb;
} __packed * prepparm;
struct cipherkeytoken *t;
- const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
@@ -990,7 +986,8 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
const u8 *clr_key_value,
int clr_key_bit_size,
u8 *key_token,
- int *key_token_size)
+ int *key_token_size,
+ u32 xflags)
{
int rc, n;
u8 *mem, *ptr;
@@ -1039,7 +1036,6 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
} __packed * prepparm;
struct cipherkeytoken *t;
int complete = strncmp(rule_array_2, "COMPLETE", 8) ? 0 : 1;
- const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
@@ -1139,14 +1135,13 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
* Build CCA AES CIPHER secure key with a given clear key value.
*/
int cca_clr2cipherkey(u16 card, u16 dom, u32 keybitsize, u32 keygenflags,
- const u8 *clrkey, u8 *keybuf, u32 *keybufsize)
+ const u8 *clrkey, u8 *keybuf, u32 *keybufsize, u32 xflags)
{
int rc;
void *mem;
int tokensize;
u8 *token, exorbuf[32];
struct cipherkeytoken *t;
- u32 xflags = 0;
/* fill exorbuf with random data */
get_random_bytes(exorbuf, sizeof(exorbuf));
@@ -1183,28 +1178,28 @@ int cca_clr2cipherkey(u16 card, u16 dom, u32 keybitsize, u32 keygenflags,
* 4/4 COMPLETE the secure cipher key import
*/
rc = _ip_cprb_helper(card, dom, "AES ", "FIRST ", "MIN3PART",
- exorbuf, keybitsize, token, &tokensize);
+ exorbuf, keybitsize, token, &tokensize, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s clear key import 1/4 with CSNBKPI2 failed, rc=%d\n",
__func__, rc);
goto out;
}
rc = _ip_cprb_helper(card, dom, "AES ", "ADD-PART", NULL,
- clrkey, keybitsize, token, &tokensize);
+ clrkey, keybitsize, token, &tokensize, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s clear key import 2/4 with CSNBKPI2 failed, rc=%d\n",
__func__, rc);
goto out;
}
rc = _ip_cprb_helper(card, dom, "AES ", "ADD-PART", NULL,
- exorbuf, keybitsize, token, &tokensize);
+ exorbuf, keybitsize, token, &tokensize, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s clear key import 3/4 with CSNBKPI2 failed, rc=%d\n",
__func__, rc);
goto out;
}
rc = _ip_cprb_helper(card, dom, "AES ", "COMPLETE", NULL,
- NULL, keybitsize, token, &tokensize);
+ NULL, keybitsize, token, &tokensize, xflags);
if (rc) {
ZCRYPT_DBF_ERR("%s clear key import 4/4 with CSNBKPI2 failed, rc=%d\n",
__func__, rc);
@@ -1230,7 +1225,8 @@ EXPORT_SYMBOL(cca_clr2cipherkey);
* Derive proteced key from CCA AES cipher secure key.
*/
int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags)
{
int rc;
u8 *mem, *ptr;
@@ -1280,7 +1276,6 @@ int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
} kb;
} __packed * prepparm;
int keytoklen = ((struct cipherkeytoken *)ckey)->len;
- const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
@@ -1397,7 +1392,7 @@ EXPORT_SYMBOL(cca_cipher2protkey);
* Derive protected key from CCA ECC secure private key.
*/
int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype, u32 xflags)
{
int rc;
u8 *mem, *ptr;
@@ -1445,7 +1440,6 @@ int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
/* followed by a key block */
} __packed * prepparm;
int keylen = ((struct eccprivkeytoken *)key)->len;
- const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem,
@@ -1548,7 +1542,8 @@ EXPORT_SYMBOL(cca_ecc2protkey);
int cca_query_crypto_facility(u16 cardnr, u16 domain,
const char *keyword,
u8 *rarray, size_t *rarraylen,
- u8 *varray, size_t *varraylen)
+ u8 *varray, size_t *varraylen,
+ u32 xflags)
{
int rc;
u16 len;
@@ -1570,7 +1565,6 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
u8 subfunc_code[2];
u8 lvdata[];
} __packed * prepparm;
- const u32 xflags = 0;
/* get already prepared memory for 2 cprbs with param block each */
rc = alloc_and_prep_cprbmem(parmbsize, &mem,
@@ -1759,7 +1753,7 @@ static int fetch_cca_info(u16 cardnr, u16 domain,
/* QF for this card/domain */
rc = cca_query_crypto_facility(cardnr, domain, "STATICSA",
- rarray, &rlen, varray, &vlen);
+ rarray, &rlen, varray, &vlen, xflags);
if (rc == 0 && rlen >= 10 * 8 && vlen >= 204) {
memcpy(ci->serial, rarray, 8);
ci->new_asym_mk_state = (char)rarray[4 * 8];
@@ -1786,7 +1780,7 @@ static int fetch_cca_info(u16 cardnr, u16 domain,
goto out;
rlen = vlen = PAGE_SIZE / 2;
rc = cca_query_crypto_facility(cardnr, domain, "STATICSB",
- rarray, &rlen, varray, &vlen);
+ rarray, &rlen, varray, &vlen, xflags);
if (rc == 0 && rlen >= 13 * 8 && vlen >= 240) {
ci->new_apka_mk_state = (char)rarray[10 * 8];
ci->cur_apka_mk_state = (char)rarray[11 * 8];
@@ -1828,13 +1822,12 @@ EXPORT_SYMBOL(cca_get_info);
* Master Key Verification Pattern given.
*/
static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
- int verify, int minhwtype)
+ int verify, int minhwtype, u32 xflg)
{
struct zcrypt_device_status_ext *device_status;
u16 card, dom;
struct cca_info ci;
int i, rc, oi = -1;
- u32 xflg = 0; /* xflags */
/* mkvp must not be zero, minhwtype needs to be >= 0 */
if (mkvp == 0 || minhwtype < 0)
@@ -1929,7 +1922,8 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
* Search for a matching crypto card based on the Master Key
* Verification Pattern provided inside a secure key token.
*/
-int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify)
+int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain,
+ int verify, u32 xflags)
{
u64 mkvp;
int minhwtype = 0;
@@ -1950,19 +1944,18 @@ int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify)
return -EINVAL;
}
- return findcard(mkvp, pcardnr, pdomain, verify, minhwtype);
+ return findcard(mkvp, pcardnr, pdomain, verify, minhwtype, xflags);
}
EXPORT_SYMBOL(cca_findcard);
int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
- int verify)
+ int verify, u32 xflags)
{
struct zcrypt_device_status_ext *device_status;
int i, card, dom, curmatch, oldmatch, rc;
struct cca_info ci;
u32 _nr_apqns = 0;
- u32 xflags = 0;
/* occupy the device status memory */
mutex_lock(&dev_status_mem_mutex);
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.h b/drivers/s390/crypto/zcrypt_ccamisc.h
index 966f0eaf3c4c..0dd4c336abab 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.h
+++ b/drivers/s390/crypto/zcrypt_ccamisc.h
@@ -160,44 +160,47 @@ int cca_check_sececckeytoken(debug_info_t *dbg, int dbflvl,
/*
* Generate (random) CCA AES DATA secure key.
*/
-int cca_genseckey(u16 cardnr, u16 domain, u32 keybitsize, u8 *seckey);
+int cca_genseckey(u16 cardnr, u16 domain, u32 keybitsize, u8 *seckey,
+ u32 xflags);
/*
* Generate CCA AES DATA secure key with given clear key value.
*/
int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
- const u8 *clrkey, u8 *seckey);
+ const u8 *clrkey, u8 *seckey, u32 xflags);
/*
* Derive proteced key from an CCA AES DATA secure key.
*/
int cca_sec2protkey(u16 cardnr, u16 domain,
const u8 *seckey, u8 *protkey, u32 *protkeylen,
- u32 *protkeytype);
+ u32 *protkeytype, u32 xflags);
/*
* Generate (random) CCA AES CIPHER secure key.
*/
int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
- u8 *keybuf, u32 *keybufsize);
+ u8 *keybuf, u32 *keybufsize, u32 xflags);
/*
* Derive proteced key from CCA AES cipher secure key.
*/
int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags);
/*
* Build CCA AES CIPHER secure key with a given clear key value.
*/
int cca_clr2cipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
- const u8 *clrkey, u8 *keybuf, u32 *keybufsize);
+ const u8 *clrkey, u8 *keybuf, u32 *keybufsize,
+ u32 xflags);
/*
* Derive proteced key from CCA ECC secure private key.
*/
int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype, u32 xflags);
/*
* Query cryptographic facility from CCA adapter
@@ -205,7 +208,8 @@ int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
int cca_query_crypto_facility(u16 cardnr, u16 domain,
const char *keyword,
u8 *rarray, size_t *rarraylen,
- u8 *varray, size_t *varraylen);
+ u8 *varray, size_t *varraylen,
+ u32 xflags);
/*
* Search for a matching crypto card based on the Master Key
@@ -214,7 +218,8 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
* Returns < 0 on failure, 0 if CURRENT MKVP matches and
* 1 if OLD MKVP matches.
*/
-int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify);
+int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain,
+ int verify, u32 xflags);
/*
* Build a list of cca apqns meeting the following constrains:
@@ -236,7 +241,7 @@ int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify);
*/
int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
- int verify);
+ int verify, u32 xflags);
#define AES_MK_SET 0
#define APKA_MK_SET 1
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
index a9a6fdc32464..fd87cb1c266b 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.c
+++ b/drivers/s390/crypto/zcrypt_ep11misc.c
@@ -1453,13 +1453,12 @@ static int _ep11_wrapkey(u16 card, u16 domain,
int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
const u8 *clrkey, u8 *keybuf, u32 *keybufsize,
- u32 keytype)
+ u32 keytype, u32 xflags)
{
int rc;
void *mem;
u8 encbuf[64], *kek;
size_t clrkeylen, keklen, encbuflen = sizeof(encbuf);
- const u32 xflags = 0;
if (keybitsize == 128 || keybitsize == 192 || keybitsize == 256) {
clrkeylen = keybitsize / 8;
@@ -1520,7 +1519,8 @@ EXPORT_SYMBOL(ep11_clr2keyblob);
int ep11_kblob2protkey(u16 card, u16 dom,
const u8 *keyblob, u32 keybloblen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags)
{
struct ep11kblob_header *hdr;
struct ep11keyblob *key;
@@ -1536,7 +1536,6 @@ int ep11_kblob2protkey(u16 card, u16 dom,
} __packed * wki;
u8 *wkbuf = NULL;
int rc = -EIO;
- const u32 xflags = 0;
if (ep11_kb_decode((u8 *)keyblob, keybloblen, &hdr, NULL, &key, &keylen))
return -EINVAL;
@@ -1642,14 +1641,13 @@ int ep11_kblob2protkey(u16 card, u16 dom,
EXPORT_SYMBOL(ep11_kblob2protkey);
int ep11_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
- int minhwtype, int minapi, const u8 *wkvp)
+ int minhwtype, int minapi, const u8 *wkvp, u32 xflags)
{
struct zcrypt_device_status_ext *device_status;
int i, card, dom, rc;
struct ep11_domain_info edi;
struct ep11_card_info eci;
u32 _nr_apqns = 0;
- const u32 xflags = 0;
/* occupy the device status memory */
mutex_lock(&dev_status_mem_mutex);
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h b/drivers/s390/crypto/zcrypt_ep11misc.h
index 7ef036759dc8..34b47522a893 100644
--- a/drivers/s390/crypto/zcrypt_ep11misc.h
+++ b/drivers/s390/crypto/zcrypt_ep11misc.h
@@ -124,7 +124,7 @@ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
*/
int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
const u8 *clrkey, u8 *keybuf, u32 *keybufsize,
- u32 keytype);
+ u32 keytype, u32 xflags);
/*
* Build a list of ep11 apqns meeting the following constrains:
@@ -144,13 +144,14 @@ int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
* If no apqn meeting the criteria is found, -ENODEV is returned.
*/
int ep11_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
- int minhwtype, int minapi, const u8 *wkvp);
+ int minhwtype, int minapi, const u8 *wkvp, u32 xflags);
/*
* Derive proteced key from EP11 key blob (AES and ECC keys).
*/
int ep11_kblob2protkey(u16 card, u16 dom, const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags);
int zcrypt_ep11misc_init(void);
void zcrypt_ep11misc_exit(void);
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* [PATCH v2 20/20] s390/pkey/crypto: Introduce xflags param for pkey in-kernel API
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (18 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 19/20] s390/zcrypt/pkey: Provide and pass xflags within pkey and zcrypt layers Harald Freudenberger
@ 2025-03-04 17:21 ` Harald Freudenberger
2025-03-20 16:34 ` Holger Dengler
2025-03-20 16:40 ` [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Holger Dengler
20 siblings, 1 reply; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-04 17:21 UTC (permalink / raw)
To: dengler, ifranzki, fcallies, hca, gor, agordeev; +Cc: linux-s390, herbert
Add a new parameter xflags to the in-kernel API function
pkey_key2protkey(). Currently there is only one flag supported:
* PKEY_XFLAG_NOMEMALLOC:
If this flag is given in the xflags parameter, the pkey implementation
is not allowed to allocate memory but instead should fall back to use
preallocated memory or simple fail with -ENOMEM.
This flag is for protected key derive within a cipher or similar
which must not allocate memory which would cause io operations - see
also the CRYPTO_ALG_ALLOCATES_MEMORY flag in crypto.h.
The one and only user of this in-kernel API - the skcipher
implementations PAES in paes_s390.c set this flag upon request
to derive a protected key from the given raw key material.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
---
arch/s390/crypto/paes_s390.c | 2 +-
arch/s390/include/asm/pkey.h | 15 ++++++++++++++-
drivers/s390/crypto/pkey_api.c | 11 +++++++----
3 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/arch/s390/crypto/paes_s390.c b/arch/s390/crypto/paes_s390.c
index 511093713a6f..646cbbf0678d 100644
--- a/arch/s390/crypto/paes_s390.c
+++ b/arch/s390/crypto/paes_s390.c
@@ -189,7 +189,7 @@ static inline int __paes_keyblob2pkey(const u8 *key, unsigned int keylen,
return -EINTR;
}
rc = pkey_key2protkey(key, keylen, pk->protkey, &pk->len,
- &pk->type);
+ &pk->type, PKEY_XFLAG_NOMEMALLOC);
}
return rc;
diff --git a/arch/s390/include/asm/pkey.h b/arch/s390/include/asm/pkey.h
index 5dca1a46a9f6..c0e7f8c25e9f 100644
--- a/arch/s390/include/asm/pkey.h
+++ b/arch/s390/include/asm/pkey.h
@@ -20,9 +20,22 @@
* @param key pointer to a buffer containing the key blob
* @param keylen size of the key blob in bytes
* @param protkey pointer to buffer receiving the protected key
+ * @param xflags additional execution flags (see PKEY_XFLAG_* definitions below)
+ * As of now the only supported flag is PKEY_XFLAG_NOMEMALLOC.
* @return 0 on success, negative errno value on failure
*/
int pkey_key2protkey(const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype,
+ u32 xflags);
+
+/*
+ * If this flag is given in the xflags parameter, the pkey implementation
+ * is not allowed to allocate memory but instead should fall back to use
+ * preallocated memory or simple fail with -ENOMEM.
+ * This flag is for protected key derive within a cipher or similar
+ * which must not allocate memory which would cause io operations - see
+ * also the CRYPTO_ALG_ALLOCATES_MEMORY flag in crypto.h.
+ */
+#define PKEY_XFLAG_NOMEMALLOC 0x0001
#endif /* _KAPI_PKEY_H */
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 55a4e70b866b..c46b57001550 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -53,17 +53,20 @@ static int key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
* In-Kernel function: Transform a key blob (of any type) into a protected key
*/
int pkey_key2protkey(const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype, u32 xflags)
{
+ u32 flags;
int rc;
- const u32 xflags = 0;
+
+ /* as of now only the NOMEMALLOC flag is supported */
+ flags = xflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
rc = key2protkey(NULL, 0, key, keylen,
- protkey, protkeylen, protkeytype, xflags);
+ protkey, protkeylen, protkeytype, flags);
if (rc == -ENODEV) {
pkey_handler_request_modules();
rc = key2protkey(NULL, 0, key, keylen,
- protkey, protkeylen, protkeytype, xflags);
+ protkey, protkeylen, protkeytype, flags);
}
return rc;
--
2.43.0
^ permalink raw reply related [flat|nested] 55+ messages in thread
* Re: [PATCH v2 01/20] s390/ap: Move response_type struct into ap_msg struct
2025-03-04 17:20 ` [PATCH v2 01/20] s390/ap: Move response_type struct into ap_msg struct Harald Freudenberger
@ 2025-03-17 9:38 ` Holger Dengler
2025-03-24 14:34 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-17 9:38 UTC (permalink / raw)
To: Harald Freudenberger
Cc: linux-s390, herbert, ifranzki, fcallies, hca, gor, agordeev
On 04/03/2025 18:20, Harald Freudenberger wrote:
> Move the very small response_type struct into struct ap_msg.
> So there is no need to kmalloc this tiny struct with each
> ap message preparation.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
See my comment below. Beside that
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
> ---
> drivers/s390/crypto/ap_bus.h | 8 ++-
> drivers/s390/crypto/zcrypt_msgtype50.c | 16 ++----
> drivers/s390/crypto/zcrypt_msgtype6.c | 74 ++++++++++----------------
> 3 files changed, 38 insertions(+), 60 deletions(-)
[...]
> diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
> index b64c9d9fc613..521cc0b39990 100644
> --- a/drivers/s390/crypto/zcrypt_msgtype6.c
> +++ b/drivers/s390/crypto/zcrypt_msgtype6.c
> @@ -31,10 +31,7 @@
>
> #define CEIL4(x) ((((x) + 3) / 4) * 4)
>
> -struct response_type {
> - struct completion work;
> - int type;
> -};
> +struct response_type;
This struct is only defined, but not used. Remove it.
>
> #define CEXXC_RESPONSE_TYPE_ICA 0
> #define CEXXC_RESPONSE_TYPE_XCRB 1
[...]
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 02/20] s390/ap/zcrypt: Rework AP message buffer allocation
2025-03-04 17:20 ` [PATCH v2 02/20] s390/ap/zcrypt: Rework AP message buffer allocation Harald Freudenberger
@ 2025-03-17 13:57 ` Holger Dengler
0 siblings, 0 replies; 55+ messages in thread
From: Holger Dengler @ 2025-03-17 13:57 UTC (permalink / raw)
To: Harald Freudenberger
Cc: linux-s390, herbert, ifranzki, fcallies, hca, gor, agordeev
On 04/03/2025 18:20, Harald Freudenberger wrote:
> Slight rework on the way how AP message buffers are allocated.
> Instead of having multiple places with kmalloc() calls all
> the AP message buffers are now allocated and freed on exactly
> one place: ap_init_apmsg() allocates the current AP bus max
> limit of ap_max_msg_size (defaults to 12KB). The AP message
> buffer is then freed in ap_release_apmsg().
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
> ---
> drivers/s390/crypto/ap_bus.c | 30 ++++++++++++++++
> drivers/s390/crypto/ap_bus.h | 21 ++---------
> drivers/s390/crypto/zcrypt_api.c | 49 +++++++++++++++-----------
> drivers/s390/crypto/zcrypt_msgtype50.c | 20 ++++++-----
> drivers/s390/crypto/zcrypt_msgtype6.c | 35 +++++++++---------
> 5 files changed, 90 insertions(+), 65 deletions(-)
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 03/20] s390/ap: Introduce ap message buffer pool
2025-03-04 17:20 ` [PATCH v2 03/20] s390/ap: Introduce ap message buffer pool Harald Freudenberger
@ 2025-03-17 16:14 ` Holger Dengler
2025-03-24 14:41 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-17 16:14 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:20, Harald Freudenberger wrote:
> 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).
typo: urgent
> * 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>
With the typo and the changed indent (see comment below)
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
> ---
> drivers/s390/crypto/ap_bus.c | 57 ++++++++++++++++++++++++++++----
> drivers/s390/crypto/ap_bus.h | 9 ++---
> drivers/s390/crypto/zcrypt_api.c | 10 +++---
> 3 files changed, 60 insertions(+), 16 deletions(-)
>
[...]
> diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
> index 483231bcdea6..a7bd44e5cc76 100644
> --- a/drivers/s390/crypto/ap_bus.h
> +++ b/drivers/s390/crypto/ap_bus.h
> @@ -233,11 +233,12 @@ struct ap_message {
> 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_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 from mempool */
Please do not change the indent here. The change is not required, but it makes the life of reviewers much harder.
>
> -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);
[...]
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 04/20] s390/ap/zcrypt: New xflag parameter and extension of the ap msg flags
2025-03-04 17:21 ` [PATCH v2 04/20] s390/ap/zcrypt: New xflag parameter and extension of the ap msg flags Harald Freudenberger
@ 2025-03-18 12:16 ` Holger Dengler
2025-03-24 15:52 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-18 12:16 UTC (permalink / raw)
To: Harald Freudenberger
Cc: linux-s390, herbert, ifranzki, fcallies, hca, gor, agordeev
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Introduce a new flag parameter for the both cprb send functions
> zcrypt_send_cprb() and zcrypt_send_ep11_cprb(). This new
> xflags parameter ("execution flags") shall be used to provide
> execution hints and flags for this crypto request.
>
> There are two flags implemented to be used with these functions:
> * ZCRYPT_XFLAG_USERSPACE - indicates to the lower layers that
> all the ptrs address userspace. So when construction the ap msg
> copy_from_user() is to be used. If this flag is NOT set, the ptrs
> address kernel memory and thus memcpy() is to be used.
> * ZCRYPT_XFLAG_NOMEMALLOC - indicates that this task must not
> allocate memory which may be allocated with io operations.
> For the zcrypt layer this limits the number of EP11 targets
> to 16 APQNs. But as this flag is passed down the stack, it
> may induce further restrictions.
>
> For the AP bus and zcrypt message layer this means:
> * The ZCRYPT_XFLAG_USERSPACE is mapped to the AP flag
> AP_MSG_FLAG_USERSPACE stored into the flags field of each
> ap message in the ap_message struct. This replaces the extra
> function parameter "userspace" and makes some function
> invocations simpler.
> * The ZCRYPT_XFLAG_NOMEMALLOC causes the AP message buffer to
> use buffer space from the AP message mempool instead of
> allocating memory via kmalloc. Note that the buffer space
> from the AP message mem pool is limited to 12KB per item.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
The boolean parameter `userspace` should only be merged with the xflags in functions, which has the need to handle ZCRYPT_XFLAG_USERSPACE and ZCRYPT_XFLAG_NOMEMALLOC, e.g _zcrypt_send_cprb(). Functions, which either only take one or the other flag may stay with the boolean parameter. There is also no need for a definition of AP_MSG_FLAG_USERSPACE, as the AP layer does not care about userspace pointers at all, only the zcrypt layer is affected by this flag. See my comments below.
> ---
> drivers/s390/crypto/ap_bus.c | 6 +-
> drivers/s390/crypto/ap_bus.h | 11 ++--
> drivers/s390/crypto/zcrypt_api.c | 90 +++++++++++++++------------
> drivers/s390/crypto/zcrypt_api.h | 36 +++++++----
> drivers/s390/crypto/zcrypt_ccamisc.c | 16 ++---
> drivers/s390/crypto/zcrypt_ep11misc.c | 10 +--
> drivers/s390/crypto/zcrypt_msgtype6.c | 12 ++--
> drivers/s390/crypto/zcrypt_msgtype6.h | 4 +-
> 8 files changed, 107 insertions(+), 78 deletions(-)
>
[...]
> diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
> index a7bd44e5cc76..5581fb13af73 100644
> --- a/drivers/s390/crypto/ap_bus.h
> +++ b/drivers/s390/crypto/ap_bus.h
> @@ -233,12 +233,13 @@ struct ap_message {
> 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 from mempool */
> +#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 from mempool */
> +#define AP_MSG_FLAG_USERSPACE 0x0010 /* pointers address userspace memory */
Do we really need this flag in the AP layer? IIRC it has only meaning in the zcrypt layer. If this is correct, please remove it.
>
> -int ap_init_apmsg(struct ap_message *ap_msg, bool use_mempool);
> +int ap_init_apmsg(struct ap_message *ap_msg, u32 flags);
> 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 ad09c5306e28..659fe7afb67e 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, false);
> + rc = ap_init_apmsg(&ap_msg, AP_MSG_FLAG_USERSPACE);
use_mempool == false should be changed to 0, not AP_MSG_FLAG_USERSPACE.
rc = ap_init_apmsg(&ap_msg, 0);
> 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, false);
> + rc = ap_init_apmsg(&ap_msg, AP_MSG_FLAG_USERSPACE);
Same here.
rc = ap_init_apmsg(&ap_msg, 0);
> if (rc)
> goto out;
>
[...]
> @@ -856,16 +856,19 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
> unsigned short *domain, tdom;
> int cpen, qpen, qid = 0, rc;
> struct module *mod;
> + u32 flags;
>
> trace_s390_zcrypt_req(xcrb, TB_ZSECSENDCPRB);
>
> xcrb->status = 0;
>
> - rc = ap_init_apmsg(&ap_msg, false);
> + flags = (xflags & ZCRYPT_XFLAG_USERSPACE ? AP_MSG_FLAG_USERSPACE : 0) |
> + (xflags & ZCRYPT_XFLAG_NOMEMALLOC ? AP_MSG_FLAG_MEMPOOL : 0);
> + rc = ap_init_apmsg(&ap_msg, flags);
There is no need to translate ZCRYPT_XFLAG_USERSPACE to ap-msg flags, the AP layer should not care about userspace/kernelspace pointer.
rc = ap_init_apmsg(&ap_msg, xflags & ZCRYPT_XFLAG_NOMEMALLOC ? AP_MSG_FLAG_MEMPOOL : 0);
> if (rc)
> goto out;
>
> - rc = prep_cca_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);
> + rc = prep_cca_ap_msg(xcrb, &ap_msg, &func_code, &domain);
The prep_cca_ap_msg() - and all functions below - can stay with the bool parameter.
rc = prep_cca_ap_msg((xflags & ZCRYPT_XFLAG_USERSPACE), xcrb, &ap_msg, &func_code, &domain);
> if (rc)
> goto out;
> print_hex_dump_debug("ccareq: ", DUMP_PREFIX_ADDRESS, 16, 1,
> @@ -956,7 +959,7 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
> if (*domain == AUTOSEL_DOM)
> *domain = AP_QID_QUEUE(qid);
>
> - rc = pref_zq->ops->send_cprb(userspace, pref_zq, xcrb, &ap_msg);
> + rc = pref_zq->ops->send_cprb(pref_zq, xcrb, &ap_msg);
Here as well, stay with the bool parameter userspace in the callback.
rc = pref_zq->ops->send_cprb((xflags & ZCRYPT_XFLAG_USERSPACE), pref_zq, xcrb, &ap_msg);
> if (!rc) {
> print_hex_dump_debug("ccarpl: ", DUMP_PREFIX_ADDRESS, 16, 1,
> ap_msg.msg, ap_msg.len, false);
[...]
> @@ -1029,52 +1032,58 @@ static bool is_desired_ep11_queue(unsigned int dev_qid,
> return false;
> }
>
> -static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
> +static long _zcrypt_send_ep11_cprb(u32 xflags, struct ap_perms *perms,
> struct zcrypt_track *tr,
> struct ep11_urb *xcrb)
> {
> struct zcrypt_card *zc, *pref_zc;
> struct zcrypt_queue *zq, *pref_zq;
> - struct ep11_target_dev *targets;
> + struct ep11_target_dev targetbuf[16], *targets = NULL;
> unsigned short target_num;
> unsigned int wgt = 0, pref_wgt = 0;
> unsigned int func_code = 0, domain;
> struct ap_message ap_msg;
> int cpen, qpen, qid = 0, rc;
> struct module *mod;
> + u32 flags;
>
> trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB);
>
> - rc = ap_init_apmsg(&ap_msg, false);
> + flags = (xflags & ZCRYPT_XFLAG_USERSPACE ? AP_MSG_FLAG_USERSPACE : 0) |
> + (xflags & ZCRYPT_XFLAG_NOMEMALLOC ? AP_MSG_FLAG_MEMPOOL : 0);
> + rc = ap_init_apmsg(&ap_msg, flags);
The AP layer does not care about the userspace flag. Please remove it.
rc = ap_init_apmsg(&ap_msg, xflags & ZCRYPT_XFLAG_NOMEMALLOC ? AP_MSG_FLAG_MEMPOOL : 0);
> if (rc)
> goto out;
>
> target_num = (unsigned short)xcrb->targets_num;
>
> /* empty list indicates autoselect (all available targets) */
> - targets = NULL;
> + rc = -ENOMEM;
> if (target_num != 0) {
> struct ep11_target_dev __user *uptr;
>
> - targets = kcalloc(target_num, sizeof(*targets), GFP_KERNEL);
> - if (!targets) {
> - func_code = 0;
> - rc = -ENOMEM;
> + if (target_num <= ARRAY_SIZE(targetbuf)) {
> + targets = targetbuf;
> + } else if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
> goto out;
> + } else {
> + targets = kcalloc(target_num,
> + sizeof(*targets), GFP_KERNEL);
> + if (!targets)
> + goto out;
> }
>
> uptr = (struct ep11_target_dev __force __user *)xcrb->targets;
> - if (z_copy_from_user(userspace, targets, uptr,
> - target_num * sizeof(*targets))) {
> - func_code = 0;
> + if (z_copy_from_user(xflags & ZCRYPT_XFLAG_USERSPACE, targets,
> + uptr, target_num * sizeof(*targets))) {
> rc = -EFAULT;
> - goto out_free;
> + goto out;
> }
> }
>
> - rc = prep_ep11_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);
> + rc = prep_ep11_ap_msg(xcrb, &ap_msg, &func_code, &domain);
Stay here with the boolean parameter for userspace.
> if (rc)
> - goto out_free;
> + goto out;
> print_hex_dump_debug("ep11req: ", DUMP_PREFIX_ADDRESS, 16, 1,
> ap_msg.msg, ap_msg.len, false);
>
[...]
> @@ -1154,11 +1163,11 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
> pr_debug("no match for address ff.ffff => ENODEV\n");
> }
> rc = -ENODEV;
> - goto out_free;
> + goto out;
> }
>
> qid = pref_zq->queue->qid;
> - rc = pref_zq->ops->send_ep11_cprb(userspace, pref_zq, xcrb, &ap_msg);
> + rc = pref_zq->ops->send_ep11_cprb(pref_zq, xcrb, &ap_msg);
Keep the boolean parameter for userspace here as well.
> if (!rc) {
> print_hex_dump_debug("ep11rpl: ", DUMP_PREFIX_ADDRESS, 16, 1,
> ap_msg.msg, ap_msg.len, false);
[...]
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 05/20] s390/zcrypt: Introduce cprb mempool for cca misc functions
2025-03-04 17:21 ` [PATCH v2 05/20] s390/zcrypt: Introduce cprb mempool for cca misc functions Harald Freudenberger
@ 2025-03-18 14:16 ` Holger Dengler
2025-03-25 8:26 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-18 14:16 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Introduce a cprb mempool for the zcrypt cca misc functions
> (zcrypt_ccamisc.*) do some preparation rework to support
> a do-not-allocate path through some zcrypt cca misc functions.
>
> The mempool is by default space for 4 cprbs with each 16KB.
> For CCA a CPRB needs to hold the request and the reply, so
> the pool items only support requests/replies with a limit of
> about 8KB. The minimal number of items in the mempool can get
> adjusted via module parameter zcrypt.cca_cprbpool_min_items
> on module load.
>
> This is only part of an rework to support a new xflag
> ZCRYPT_XFLAG_NOMEMALLOC but not yet complete.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
One minor comment below. Beside that
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
> ---
> drivers/s390/crypto/zcrypt_api.c | 13 ++-
> drivers/s390/crypto/zcrypt_api.h | 2 +
> drivers/s390/crypto/zcrypt_ccamisc.c | 116 ++++++++++++++++++++-------
> drivers/s390/crypto/zcrypt_ccamisc.h | 1 +
> 4 files changed, 101 insertions(+), 31 deletions(-)
>
[...]
> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
> index 521baaea06ff..2c2ca2d67e2d 100644
> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
[...]
> @@ -229,7 +241,15 @@ static int alloc_and_prep_cprbmem(size_t paramblen,
> * allocate consecutive memory for request CPRB, request param
> * block, reply CPRB and reply param block
> */
> - cprbmem = kcalloc(2, cprbplusparamblen, GFP_KERNEL);
> + if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
> + if (cprb_mempool &&
> + 2 * cprbplusparamblen <= CPRB_MEMPOOL_ITEM_SIZE) {
> + cprbmem = mempool_alloc_preallocated(cprb_mempool);
> + memset(cprbmem, 0, 2 * cprbplusparamblen);
> + }
> + } else {
Just a nit: let the compiler decide, if code should be duplicated or not.
if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
size_t len = 2 * cprbplusparamblen;
if (cprb_mempool && len <= CPRB_MEMPOOL_ITEM_SIZE) {
cprbmem = mempool_alloc_preallocated(cprb_mempool);
memset(cprbmem, 0, len);
}
} else {
> + cprbmem = kcalloc(2, cprbplusparamblen, GFP_KERNEL);
> + }
> if (!cprbmem)
> return -ENOMEM;
>
[...]
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 06/20] s390/zcrypt: Introduce cprb mempool for ep11 misc functions
2025-03-04 17:21 ` [PATCH v2 06/20] s390/zcrypt: Introduce cprb mempool for ep11 " Harald Freudenberger
@ 2025-03-18 15:16 ` Holger Dengler
2025-03-25 8:36 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-18 15:16 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Introduce a cprb mempool for the zcrypt ep11 misc functions
> (zcrypt_ep11misc.*) do some preparation rework to support
> a do-not-allocate path through some zcrypt cca misc functions.
>
> The mempool is by default space for 8 cprbs with each 8KB.
> For EP11 a CPRB either holds the request or the reply. So for
> a request/reply there is always a couple of cprb buffers
> needed. The minimal number of items in the mempool can get
> adjusted via module parameter zcrypt.ep11_cprbpool_min_items
> on module load.
>
> This is only part of an rework to support a new xflag
> ZCRYPT_XFLAG_NOMEMALLOC but not yet complete.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
With the minor change (see comment below)
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
> ---
> drivers/s390/crypto/zcrypt_api.c | 10 ++
> drivers/s390/crypto/zcrypt_api.h | 1 +
> drivers/s390/crypto/zcrypt_ep11misc.c | 158 ++++++++++++++++----------
> drivers/s390/crypto/zcrypt_ep11misc.h | 1 +
> 4 files changed, 109 insertions(+), 61 deletions(-)
>
[...]
> diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
> index b60e262bcaa3..86578a95b140 100644
> --- a/drivers/s390/crypto/zcrypt_ep11misc.c
> +++ b/drivers/s390/crypto/zcrypt_ep11misc.c
[...]
> @@ -621,22 +652,20 @@ static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
> req_pl->query_subtype_len = sizeof(u32);
>
> /* reply cprb and payload */
> - rep = alloc_cprb(sizeof(struct ep11_info_rep_pl) + buflen);
> + rep = alloc_cprbmem(sizeof(struct ep11_info_rep_pl) + buflen, xflags);
> if (!rep)
> goto out;
> rep_pl = (struct ep11_info_rep_pl *)(((u8 *)rep) + sizeof(*rep));
>
> /* urb and target */
> - urb = kmalloc(sizeof(*urb), GFP_KERNEL);
> - if (!urb)
> - goto out;
> + memset(&urb, 0, sizeof(urb));
The memset is done each time before a prep_urb() call. Please do the memset inside the prep_urb() function and remove the other ones.
> target.ap_id = cardnr;
> target.dom_id = domain;
> - prep_urb(urb, &target, 1,
> + prep_urb(&urb, &target, 1,
> req, sizeof(*req) + sizeof(*req_pl),
> rep, sizeof(*rep) + sizeof(*rep_pl) + buflen);
>
> - rc = zcrypt_send_ep11_cprb(urb, 0);
> + rc = zcrypt_send_ep11_cprb(&urb, xflags);
> if (rc) {
> ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
> __func__, (int)cardnr, (int)domain, rc);
[...]
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 07/20] s390/zcrypt: Rework zcrypt function zcrypt_device_status_mask_ext
2025-03-04 17:21 ` [PATCH v2 07/20] s390/zcrypt: Rework zcrypt function zcrypt_device_status_mask_ext Harald Freudenberger
@ 2025-03-19 11:03 ` Holger Dengler
2025-03-25 9:24 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-19 11:03 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Rework the existing function zcrypt_device_status_mask_ext():
> * Add two new parameters to provide upper limits for
> cards and queues. The existing implementation needed an
> array of 256 * 256 * 4 = 256 KB which is really huge. The
> reworked function is more flexible in the sense that the
> caller can decide the upper limit for cards and domains to
> be stored into the status array. So for example a caller may
> decide to only query for cards 0...127 and queues 0...127
> and thus only an array of size 128 * 128 * 4 = 64 KB is needed.
> * Instead of void the reworked function now returns an int.
> The currently only way to have the function return != 0
> is by providing card or domains limits beyond 256.
I would prefer to stay with a void function and limit the card and domain values to the current maximum. Details below.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
> ---
> drivers/s390/crypto/zcrypt_api.c | 20 +++++++++++++++-----
> drivers/s390/crypto/zcrypt_api.h | 3 ++-
> drivers/s390/crypto/zcrypt_ccamisc.c | 22 +++++++++++++++++-----
> drivers/s390/crypto/zcrypt_ep11misc.c | 14 ++++++++++----
> 4 files changed, 44 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
> index 62cc05881b13..bd2738e3792a 100644
> --- a/drivers/s390/crypto/zcrypt_api.c
> +++ b/drivers/s390/crypto/zcrypt_api.c
> @@ -1317,19 +1317,25 @@ static void zcrypt_device_status_mask(struct zcrypt_device_status *devstatus)
> spin_unlock(&zcrypt_list_lock);
> }
>
> -void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus)
> +int zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus,
> + int maxcard, int maxqueue)
Keep void and ...
> {
> struct zcrypt_card *zc;
> struct zcrypt_queue *zq;
> struct zcrypt_device_status_ext *stat;
> int card, queue;
>
> + if (maxcard > MAX_ZDEV_CARDIDS_EXT || maxqueue > MAX_ZDEV_DOMAINS_EXT)
> + return -EINVAL;
> +
... limit maxcard/maxqueue to the maximum supported values. In my opinion, it does not make any sense to call this function with higher values than the maximum.
maxcard = MIN(maxcard, MAX_ZDEV_CARDIDS_EXT);
maxqueue = MIN(maxqueue, MAX_ZDEV_DOMAINS_EXT);
As a side effect, it keeps the caller code much simpler.
> spin_lock(&zcrypt_list_lock);
> for_each_zcrypt_card(zc) {
> for_each_zcrypt_queue(zq, zc) {
> card = AP_QID_CARD(zq->queue->qid);
> queue = AP_QID_QUEUE(zq->queue->qid);
> - stat = &devstatus[card * AP_DOMAINS + queue];
> + if (card >= maxcard || queue >= maxqueue)
> + continue;
> + stat = &devstatus[card * maxqueue + queue];
> stat->hwtype = zc->card->ap_dev.device_type;
> stat->functions = zc->card->hwinfo.fac >> 26;
> stat->qid = zq->queue->qid;
[...]
> @@ -1635,9 +1643,11 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
> GFP_KERNEL);
> if (!device_status)
> return -ENOMEM;
> - zcrypt_device_status_mask_ext(device_status);
> - if (copy_to_user((char __user *)arg, device_status,
> - total_size))
> + rc = zcrypt_device_status_mask_ext(device_status,
> + MAX_ZDEV_CARDIDS_EXT,
> + MAX_ZDEV_DOMAINS_EXT);
> + if (!rc && copy_to_user((char __user *)arg, device_status,
> + total_size))
With the change above, you can stay with the current error handling. Only the addition parameters for zcrypt_device_status_mask_ext() need to be added.
> rc = -EFAULT;
> kvfree(device_status);
> return rc;
[...]
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 08/20] s390/zcrypt: Introduce pre-allocated device status array for cca misc
2025-03-04 17:21 ` [PATCH v2 08/20] s390/zcrypt: Introduce pre-allocated device status array for cca misc Harald Freudenberger
@ 2025-03-19 14:31 ` Holger Dengler
2025-03-25 10:51 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-19 14:31 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Introduce a pre-allocated device status array memory together with
> a mutex controlling the occupation to be used by the two findcard()
> functions. Limit the device status array to max 128 cards and max
As far as I can see, cca_findcard() (and also the static findcard()) are no longer used. If this is the case, I would prefer to remove this unused variant, either in this patch (with a hint in the commit message) or in a separate one (in the order prior to this patch).
> 128 domains to reduce the size of this pre-allocated memory to 64 KB.
I'm a bit unhappy about introducing a synchronization with this single piece of memory.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
> ---
> drivers/s390/crypto/zcrypt_ccamisc.c | 78 +++++++++++++++++++---------
> 1 file changed, 53 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
> index 420895df70f0..65b4cdb9b478 100644
> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
[...]
> @@ -1801,21 +1817,20 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
As mentioned above, please check for users of findcard() and cca_findcard(). If there are no users anymore, please remove the obsolete code.
[...]
> @@ -2023,11 +2041,21 @@ int __init zcrypt_ccamisc_init(void)
> cprb_mempool = NULL;
> return -ENOMEM;
> }
> +
> + /* Pre-allocate one crypto status card struct used in findcard() */
> + dev_status_mem = kvmalloc(ZCRYPT_DEV_STATUS_EXT_SIZE, GFP_KERNEL);
The alloc of dev_status_mem should be protected by the mutex as well.
> + if (!dev_status_mem) {
> + ZCRYPT_DBF_ERR("%s allocation of dev_status_mem failed\n", __func__);
> + mempool_destroy(cprb_mempool);
> + return -ENOMEM;
> + }
> +
> return 0;
> }
>
> void zcrypt_ccamisc_exit(void)
> {
> mkvp_cache_free();
> + kvfree(dev_status_mem);
Same here: please lock the mutex before releasing dev_status_mem.
> mempool_destroy(cprb_mempool);
> }
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 10/20] s390/zcrypt/pkey: Rework cca findcard() implementation and callers
2025-03-04 17:21 ` [PATCH v2 10/20] s390/zcrypt/pkey: Rework cca findcard() implementation and callers Harald Freudenberger
@ 2025-03-19 17:58 ` Holger Dengler
2025-03-25 13:02 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-19 17:58 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Rework the memory usage of the cca findcard() implementation:
> - findcard does not allocate memory for the list of apqns
> any more.
> - the callers are now responsible to provide an array of
> apqns to store the matching apqns into.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
See my comments below.
> ---
> drivers/s390/crypto/pkey_cca.c | 25 +++++++++++--------------
> drivers/s390/crypto/zcrypt_ccamisc.c | 18 ++++--------------
> drivers/s390/crypto/zcrypt_ccamisc.h | 12 +++++-------
> 3 files changed, 20 insertions(+), 35 deletions(-)
>
[...]
> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
> index 65b4cdb9b478..d3b093dcdf30 100644
> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
[...]
> @@ -2006,17 +1999,14 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
> continue;
> }
> /* apqn passed all filtering criterons, add to the array */
> - if (_nr_apqns < 256)
> - _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
> + if (_nr_apqns < *nr_apqns)
> + apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
> }
>
> /* nothing found ? */
> if (!_nr_apqns) {
> - kfree(_apqns);
> rc = -ENODEV;
In my opinion, the -ENODEV return value can be completely dropped. For the caller it should be sufficient to check for nr_apqns == 0.
> } else {
> - /* no re-allocation, simple return the _apqns array */
> - *apqns = _apqns;
> *nr_apqns = _nr_apqns;
Please update *nr_apqns unconditionally.
> rc = 0;
> }
> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.h b/drivers/s390/crypto/zcrypt_ccamisc.h
> index 273edf2bb036..bed647a42eb2 100644
> --- a/drivers/s390/crypto/zcrypt_ccamisc.h
> +++ b/drivers/s390/crypto/zcrypt_ccamisc.h
> @@ -229,14 +229,12 @@ int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify);
> * cur_mkvp or old_mkvp values of the apqn are used.
> * The mktype determines which set of master keys to use:
> * 0 = AES_MK_SET - AES MK set, 1 = APKA MK_SET - APKA MK set
> - * The array of apqn entries is allocated with kmalloc and returned in *apqns;
> - * the number of apqns stored into the list is returned in *nr_apqns. One apqn
> - * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and
> - * may be casted to struct pkey_apqn. The return value is either 0 for success
> - * or a negative errno value. If no apqn meeting the criteria is found,
> - * -ENODEV is returned.
> + * The caller should set *nr_apqns to the nr of elements available in *apqns.
> + * On return *nr_apqns is then updated with the nr of apqns filled into *apqns.
> + * The return value is either 0 for success or a negative errno value.
> + * If no apqn meeting the criteria is found, -ENODEV is returned.
Why not just return nr_apqns == 0 to indicate, that no matching device has been found? Anyhow, even if you would stay with the -ENODEV return value, *nr_apqns should be updated in any case.
> */
> -int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
> +int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
> int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
> int verify);
>
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 09/20] s390/zcrypt: Introduce pre-allocated device status array for ep11 misc
2025-03-04 17:21 ` [PATCH v2 09/20] s390/zcrypt: Introduce pre-allocated device status array for ep11 misc Harald Freudenberger
@ 2025-03-19 18:02 ` Holger Dengler
2025-03-25 11:09 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-19 18:02 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Introduce a pre-allocated device status array memory together with
> a mutex controlling the occupation to be used by the findcard()
> function. Limit the device status array to max 128 cards and max
> 128 domains to reduce the size of this pre-allocated memory to 64 KB.
I have the same concerns as for patch 8/20. Please think about an alternative to the dev_status_mem sharing, because it synchronizes all findcard() calls.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
> ---
> drivers/s390/crypto/zcrypt_ep11misc.c | 46 +++++++++++++++++++++------
> 1 file changed, 36 insertions(+), 10 deletions(-)
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 11/20] s390/zcrypt/pkey: Rework ep11 findcard() implementation and callers
2025-03-04 17:21 ` [PATCH v2 11/20] s390/zcrypt/pkey: Rework ep11 " Harald Freudenberger
@ 2025-03-20 8:30 ` Holger Dengler
2025-03-25 13:12 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-20 8:30 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Rework the memory usage of the ep11 findcard() implementation:
> - findcard does not allocate memory for the list of apqns
> any more.
> - the callers are now responsible to provide an array of
> apqns to store the matching apqns into.
See my comments below.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
> ---
> drivers/s390/crypto/pkey_ep11.c | 19 ++++++++-----------
> drivers/s390/crypto/zcrypt_ep11misc.c | 18 ++++--------------
> drivers/s390/crypto/zcrypt_ep11misc.h | 12 +++++-------
> 3 files changed, 17 insertions(+), 32 deletions(-)
>
[...]
> diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
> index 04153b476168..6005ef79c001 100644
> --- a/drivers/s390/crypto/zcrypt_ep11misc.c
> +++ b/drivers/s390/crypto/zcrypt_ep11misc.c
[...]
> @@ -1678,17 +1671,14 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
> continue;
> }
> /* apqn passed all filtering criterons, add to the array */
> - if (_nr_apqns < 256)
> - _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
> + if (_nr_apqns < *nr_apqns)
> + apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
> }
>
> /* nothing found ? */
> if (!_nr_apqns) {
> - kfree(_apqns);
> rc = -ENODEV;
> } else {
> - /* no re-allocation, simple return the _apqns array */
> - *apqns = _apqns;
Please update *apqns unconditionally.
> *nr_apqns = _nr_apqns;
> rc = 0;
> }
> diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h b/drivers/s390/crypto/zcrypt_ep11misc.h
> index a4b98eca8431..cbd615547bc2 100644
> --- a/drivers/s390/crypto/zcrypt_ep11misc.h
> +++ b/drivers/s390/crypto/zcrypt_ep11misc.h
> @@ -136,14 +136,12 @@ int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
> * key for this domain. When a wkvp is given there will always be a re-fetch
> * of the domain info for the potential apqn - so this triggers an request
> * reply to each apqn eligible.
> - * The array of apqn entries is allocated with kmalloc and returned in *apqns;
> - * the number of apqns stored into the list is returned in *nr_apqns. One apqn
> - * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and
> - * may be casted to struct pkey_apqn. The return value is either 0 for success
> - * or a negative errno value. If no apqn meeting the criteria is found,
> - * -ENODEV is returned.
> + * The caller should set *nr_apqns to the nr of elements available in *apqns.
> + * On return *nr_apqns is then updated with the nr of apqns filled into *apqns.
> + * The return value is either 0 for success or a negative errno value.
> + * If no apqn meeting the criteria is found, -ENODEV is returned.
As mentioned in my comment to patch 10/20: please update nr_apqns in any case. If -ENODEV should be dropped for cca, than also drop it here.
> */
> -int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
> +int ep11_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
> int minhwtype, int minapi, const u8 *wkvp);
>
> /*
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 12/20] s390/zcrypt: Rework cca misc functions kmallocs to use the cprb mempool
2025-03-04 17:21 ` [PATCH v2 12/20] s390/zcrypt: Rework cca misc functions kmallocs to use the cprb mempool Harald Freudenberger
@ 2025-03-20 9:31 ` Holger Dengler
0 siblings, 0 replies; 55+ messages in thread
From: Holger Dengler @ 2025-03-20 9:31 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Rework two places in the zcrypt cca misc code using kmalloc() for
> ephemeral memory allocation. As there is anyway now a cprb mempool
> let's use this pool instead to satisfy these short term memory
> allocations.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 13/20] s390/zcrypt: Add small mempool for cca info list entries
2025-03-04 17:21 ` [PATCH v2 13/20] s390/zcrypt: Add small mempool for cca info list entries Harald Freudenberger
@ 2025-03-20 14:34 ` Holger Dengler
2025-03-25 13:32 ` Harald Freudenberger
2025-03-20 16:05 ` Holger Dengler
1 sibling, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-20 14:34 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Add a small memory pool for (pre-)allocating cca info list
> entries. These entries are rather small and the pool is a simple
> way to support the xflag ZCRYPT_XFLAG_NOMEMALLOC to avoid mallocs.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
With the requested change,
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
> ---
> drivers/s390/crypto/zcrypt_ccamisc.c | 67 ++++++++++++++++++++--------
> drivers/s390/crypto/zcrypt_ccamisc.h | 3 +-
> drivers/s390/crypto/zcrypt_cex4.c | 4 +-
> 3 files changed, 53 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
> index ff7ba2622484..e4ec922aae0d 100644
> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
[...]
> @@ -1828,6 +1834,7 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
> u16 card, dom;
> struct cca_info ci;
> int i, rc, oi = -1;
> + u32 xflg = 0; /* xflags */
I'm confused. Why not just calling it xflags? Anyhow, as mentioned earlier: findcard() has no consumers, so please remove it completely.
>
> /* mkvp must not be zero, minhwtype needs to be >= 0 */
> if (mkvp == 0 || minhwtype < 0)
> @@ -1859,8 +1866,8 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
> if (!verify)
> break;
> /* verify: refresh card info */
> - if (fetch_cca_info(card, dom, &ci) == 0) {
> - cca_info_cache_update(card, dom, &ci);
> + if (fetch_cca_info(card, dom, &ci, xflg) == 0) {
> + cca_info_cache_update(card, dom, &ci, xflg);
> if (ci.hwtype >= minhwtype &&
> ci.cur_aes_mk_state == '2' &&
> ci.cur_aes_mkvp == mkvp)
> @@ -1882,8 +1889,8 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
> card = AP_QID_CARD(device_status[i].qid);
> dom = AP_QID_QUEUE(device_status[i].qid);
> /* fresh fetch mkvp from adapter */
> - if (fetch_cca_info(card, dom, &ci) == 0) {
> - cca_info_cache_update(card, dom, &ci);
> + if (fetch_cca_info(card, dom, &ci, xflg) == 0) {
> + cca_info_cache_update(card, dom, &ci, xflg);
> if (ci.hwtype >= minhwtype &&
> ci.cur_aes_mk_state == '2' &&
> ci.cur_aes_mkvp == mkvp)
[...]
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 14/20] s390/zcrypt: Locate ep11_domain_query_info onto the stack instead of kmalloc
2025-03-04 17:21 ` [PATCH v2 14/20] s390/zcrypt: Locate ep11_domain_query_info onto the stack instead of kmalloc Harald Freudenberger
@ 2025-03-20 14:41 ` Holger Dengler
2025-03-25 14:04 ` Harald Freudenberger
0 siblings, 1 reply; 55+ messages in thread
From: Holger Dengler @ 2025-03-20 14:41 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Locate the relative small struct ep11_domain_query_info variable
> onto the stack instead of kmalloc()/kfree().
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
One minor comment.
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
> ---
> drivers/s390/crypto/zcrypt_ep11misc.c | 25 ++++++++++---------------
> 1 file changed, 10 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
> index 6005ef79c001..7fb55be3e943 100644
> --- a/drivers/s390/crypto/zcrypt_ep11misc.c
> +++ b/drivers/s390/crypto/zcrypt_ep11misc.c
> @@ -790,36 +790,31 @@ int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info)
> u8 new_WK_VP[32];
> u32 dom_flags;
> u64 op_mode;
> - } __packed * p_dom_info;
> -
> - p_dom_info = kmalloc(sizeof(*p_dom_info), GFP_KERNEL);
> - if (!p_dom_info)
> - return -ENOMEM;
> + } __packed dom_query_info;
Why is dom_query_info a typed struct? The struct type is not used and an untyped struct can be used as well.
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 15/20] s390/zcrypt: Rework ep11 misc functions to use cprb mempool
2025-03-04 17:21 ` [PATCH v2 15/20] s390/zcrypt: Rework ep11 misc functions to use cprb mempool Harald Freudenberger
@ 2025-03-20 15:18 ` Holger Dengler
0 siblings, 0 replies; 55+ messages in thread
From: Holger Dengler @ 2025-03-20 15:18 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> There are two places in the ep11 misc code where a short term
> memory buffer is needed. Rework this code to use the cprb mempool
> to satisfy this ephemeral memory requirements.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
> ---
> drivers/s390/crypto/pkey_ep11.c | 3 +-
> drivers/s390/crypto/zcrypt_cex4.c | 12 +--
> drivers/s390/crypto/zcrypt_ep11misc.c | 104 ++++++++++++++++----------
> drivers/s390/crypto/zcrypt_ep11misc.h | 8 +-
> 4 files changed, 78 insertions(+), 49 deletions(-)
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 13/20] s390/zcrypt: Add small mempool for cca info list entries
2025-03-04 17:21 ` [PATCH v2 13/20] s390/zcrypt: Add small mempool for cca info list entries Harald Freudenberger
2025-03-20 14:34 ` Holger Dengler
@ 2025-03-20 16:05 ` Holger Dengler
1 sibling, 0 replies; 55+ messages in thread
From: Holger Dengler @ 2025-03-20 16:05 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Add a small memory pool for (pre-)allocating cca info list
> entries. These entries are rather small and the pool is a simple
> way to support the xflag ZCRYPT_XFLAG_NOMEMALLOC to avoid mallocs.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Sorry, I forgot one aspect, see comment below.
> ---
> drivers/s390/crypto/zcrypt_ccamisc.c | 67 ++++++++++++++++++++--------
> drivers/s390/crypto/zcrypt_ccamisc.h | 3 +-
> drivers/s390/crypto/zcrypt_cex4.c | 4 +-
> 3 files changed, 53 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
> index ff7ba2622484..e4ec922aae0d 100644
> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
> @@ -41,6 +41,10 @@ struct cca_info_list_entry {
> static LIST_HEAD(cca_info_list);
> static DEFINE_SPINLOCK(cca_info_list_lock);
>
> +/* memory pool for cca_info_list entries */
> +#define INFO_ENTRY_MEMPOOL_MIN_ITEMS 8
> +static mempool_t *info_mempool;
> +
The minimal elements in all smaller mempools should also be configurable via a module parameter, if this is required to process a larger number of NOMEMALLOC requests in parallel. There should be one parameter per module, which configures the minimal number of all mempools of this module. I also would prefer the same parameter name across all modules (e.g. "mempool_threshold").
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 16/20] s390/zcrypt: Add small mempool for ep11 card info list entries
2025-03-04 17:21 ` [PATCH v2 16/20] s390/zcrypt: Add small mempool for ep11 card info list entries Harald Freudenberger
@ 2025-03-20 16:09 ` Holger Dengler
0 siblings, 0 replies; 55+ messages in thread
From: Holger Dengler @ 2025-03-20 16:09 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Add a small memory pool for (pre-)allocating ep11 card info list
> entries. These entries are rather small and the pool is a simple
> way to support the xflag ZCRYPT_XFLAG_NOMEMALLOC to avoid mallocs.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
With the change below,
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
> ---
> drivers/s390/crypto/zcrypt_ep11misc.c | 48 ++++++++++++++++++++++-----
> 1 file changed, 39 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
> index af59d66bff33..a9a6fdc32464 100644
> --- a/drivers/s390/crypto/zcrypt_ep11misc.c
> +++ b/drivers/s390/crypto/zcrypt_ep11misc.c
> @@ -64,6 +64,10 @@ struct card_list_entry {
> static LIST_HEAD(card_list);
> static DEFINE_SPINLOCK(card_list_lock);
>
> +/* memory pool for card_list_entry entries */
> +#define INFO_ENTRY_MEMPOOL_MIN_ITEMS 4
> +static mempool_t *info_mempool;
> +
The minimal elements in all smaller mempools should also be configurable via a module parameter, if this is required to process a larger number of NOMEMALLOC requests in parallel. There should be one parameter per module, which configures the minimal number of all mempools of this module. I also would prefer the same parameter name across all modules (e.g. "mempool_threshold"). There is no need to state the card type in the module parameter again.
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 19/20] s390/zcrypt/pkey: Provide and pass xflags within pkey and zcrypt layers
2025-03-04 17:21 ` [PATCH v2 19/20] s390/zcrypt/pkey: Provide and pass xflags within pkey and zcrypt layers Harald Freudenberger
@ 2025-03-20 16:30 ` Holger Dengler
0 siblings, 0 replies; 55+ messages in thread
From: Holger Dengler @ 2025-03-20 16:30 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Provide and pass the xflag parameter from pkey ioctls through
> the pkey handler and further down to the implementations
> (CCA, EP11, PCKMO and UV). So all the code is now prepared
> and ready to support the currently only xflag ("execution flag"):
>
> * ZCRYPT_XFLAG_NOMEMALLOC - If this flag is set, no memory
> allocations which may trigger any IO operations are done.
>
> The in-kernel pkey API still does not provide this xflag param.
> That's intended to come with another patch which more or less
> only enables this functionality.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Without the findcard() function or with a changed parameter name according to my comment
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
> ---
> drivers/s390/crypto/pkey_api.c | 49 +++++++++++-----------
> drivers/s390/crypto/pkey_base.c | 34 ++++++++-------
> drivers/s390/crypto/pkey_base.h | 37 ++++++++++-------
> drivers/s390/crypto/pkey_cca.c | 59 +++++++++++++++------------
> drivers/s390/crypto/pkey_ep11.c | 49 ++++++++++++----------
> drivers/s390/crypto/pkey_pckmo.c | 9 ++--
> drivers/s390/crypto/pkey_sysfs.c | 4 +-
> drivers/s390/crypto/pkey_uv.c | 16 +++++++-
> drivers/s390/crypto/zcrypt_ccamisc.c | 53 +++++++++++-------------
> drivers/s390/crypto/zcrypt_ccamisc.h | 25 +++++++-----
> drivers/s390/crypto/zcrypt_ep11misc.c | 10 ++---
> drivers/s390/crypto/zcrypt_ep11misc.h | 7 ++--
> 12 files changed, 196 insertions(+), 156 deletions(-)
>
[...]
> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
> index e4ec922aae0d..3b80ce605192 100644
> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
[...]
> @@ -1828,13 +1822,12 @@ EXPORT_SYMBOL(cca_get_info);
> * Master Key Verification Pattern given.
> */
> static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
> - int verify, int minhwtype)
> + int verify, int minhwtype, u32 xflg)
> {
> struct zcrypt_device_status_ext *device_status;
> u16 card, dom;
> struct cca_info ci;
> int i, rc, oi = -1;
> - u32 xflg = 0; /* xflags */
If you keep findcard() please name the parameter `xflags` instead of `xflg`.
>
> /* mkvp must not be zero, minhwtype needs to be >= 0 */
> if (mkvp == 0 || minhwtype < 0)
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 20/20] s390/pkey/crypto: Introduce xflags param for pkey in-kernel API
2025-03-04 17:21 ` [PATCH v2 20/20] s390/pkey/crypto: Introduce xflags param for pkey in-kernel API Harald Freudenberger
@ 2025-03-20 16:34 ` Holger Dengler
0 siblings, 0 replies; 55+ messages in thread
From: Holger Dengler @ 2025-03-20 16:34 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> Add a new parameter xflags to the in-kernel API function
> pkey_key2protkey(). Currently there is only one flag supported:
>
> * PKEY_XFLAG_NOMEMALLOC:
> If this flag is given in the xflags parameter, the pkey implementation
> is not allowed to allocate memory but instead should fall back to use
> preallocated memory or simple fail with -ENOMEM.
> This flag is for protected key derive within a cipher or similar
> which must not allocate memory which would cause io operations - see
> also the CRYPTO_ALG_ALLOCATES_MEMORY flag in crypto.h.
>
> The one and only user of this in-kernel API - the skcipher
> implementations PAES in paes_s390.c set this flag upon request
> to derive a protected key from the given raw key material.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
` (19 preceding siblings ...)
2025-03-04 17:21 ` [PATCH v2 20/20] s390/pkey/crypto: Introduce xflags param for pkey in-kernel API Harald Freudenberger
@ 2025-03-20 16:40 ` Holger Dengler
20 siblings, 0 replies; 55+ messages in thread
From: Holger Dengler @ 2025-03-20 16:40 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:20, Harald Freudenberger wrote:
> This series of patches has the goal to open up a do-not-allocate
> memory path from the callers of the pkey in-kernel api down to
> the crypto cards and back.
>
> The asynch in-kernel cipher implementations (and the s390 PAES
> cipher implementations are one of them) may be called in a
> context where memory allocations which trigger IO is not acceptable.
>
> So this patch series reworks the AP bus code, the zcrypt layer,
> the pkey layer and the pkey handlers to respect this situation
> by processing a new parameter xflags (execution hints flags).
> There is a flag PKEY_XFLAG_NOMEMALLOC which tells the code to
> not allocate memory which may lead to IO operations.
>
> To reach this goal, the actual code changes have been differed.
> The zcrypt misc functions which need memory for cprb build
> use a pre allocated memory pool for this purpose. The findcard()
> functions have one temp memory area preallocated and protected
> with a mutex. Some smaller data is not allocated any more but went
> to the stack instead. The AP bus also uses a pre-allocated
> memory pool for building AP message requests.
Please check in all affected modules: the parameter for the minimal number of element in all meempools of the module should be configurable with the same module parameter. Please also use the same module parameter name (e.g. mempool_threshold) in all modules. This makes it easier for users to syncronize the mempool thresholds accross modules.
>
> Note that the PAES implementation still needs to get reworked
> to run the protected key derivation in a real asynchronous way.
> However, this rework of AP bus, zcrypt and pkey is the base work
> required before reconsidering the PAES implementation.
>
> The patch series starts bottom (AP bus) and goes up the call
> chain (PKEY). At any time in the patch stack it should compile.
> For easier review I tried to have one logic code change by
> each patch and thus keep the patches "small". For the upstream
> version I intend to fold them together into only a few commits.
>
> Changelog:
> v1: initial version
> v2: - Rework on patch 0001 and 0002 based on feedback from Holger.
> Also there was one place in zcrypt_msgtype50.c where still
> an ap msg buffer was alloacated.
> - Rework on patch 0003 - fixed feedback from Holger. Also the
> min poolitems is now a module parameter and defaults to 8.
> - Rework on patch 0004 - as suggested by Holger the "userspace"
> parameter is now included into the ap msg flags.
> - Rework on patch 0005 - nr of cca cprbs in the mempool is now
> a module parameter.
> - Rework on patch 0006 - nr of ep11 cprbs in the mempool is now
> a module parameter.
> - Rework on patch 0007 - as suggested by Holger instead of
> implementing a copy-and-pasted new function
> zcrypt_device_status_mask_ext2() use and extend the existing
> the existing function to avoid code duplication.
> - The rest of the patch series needed adaptions but there is
> no functional change compared to v1.
Please pick my R-b tags of this review for v3.
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 17/20] s390/pkey: Rework CCA pkey handler to use stack for small memory allocs
2025-03-04 17:21 ` [PATCH v2 17/20] s390/pkey: Rework CCA pkey handler to use stack for small memory allocs Harald Freudenberger
@ 2025-03-21 9:05 ` Holger Dengler
0 siblings, 0 replies; 55+ messages in thread
From: Holger Dengler @ 2025-03-21 9:05 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> There have been some places in the CCA handler code where relatively
> small amounts of memory have been allocated an freed at the end
> of the function. This code has been reworked to use the stack instead.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 18/20] s390/pkey: Rework EP11 pkey handler to use stack for small memory allocs
2025-03-04 17:21 ` [PATCH v2 18/20] s390/pkey: Rework EP11 " Harald Freudenberger
@ 2025-03-21 9:06 ` Holger Dengler
0 siblings, 0 replies; 55+ messages in thread
From: Holger Dengler @ 2025-03-21 9:06 UTC (permalink / raw)
To: Harald Freudenberger, ifranzki, fcallies, hca, gor, agordeev
Cc: linux-s390, herbert
On 04/03/2025 18:21, Harald Freudenberger wrote:
> There have been some places in the EP11 handler code where relatively
> small amounts of memory have been allocated an freed at the end
> of the function. This code has been reworked to use the stack instead.
>
> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
--
Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
dengler@linux.ibm.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 01/20] s390/ap: Move response_type struct into ap_msg struct
2025-03-17 9:38 ` Holger Dengler
@ 2025-03-24 14:34 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-24 14:34 UTC (permalink / raw)
To: Holger Dengler
Cc: linux-s390, herbert, ifranzki, fcallies, hca, gor, agordeev
On 2025-03-17 10:38, Holger Dengler wrote:
> On 04/03/2025 18:20, Harald Freudenberger wrote:
>> Move the very small response_type struct into struct ap_msg.
>> So there is no need to kmalloc this tiny struct with each
>> ap message preparation.
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>
> See my comment below. Beside that
> Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
>
>> ---
>> drivers/s390/crypto/ap_bus.h | 8 ++-
>> drivers/s390/crypto/zcrypt_msgtype50.c | 16 ++----
>> drivers/s390/crypto/zcrypt_msgtype6.c | 74
>> ++++++++++----------------
>> 3 files changed, 38 insertions(+), 60 deletions(-)
> [...]
>> diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c
>> b/drivers/s390/crypto/zcrypt_msgtype6.c
>> index b64c9d9fc613..521cc0b39990 100644
>> --- a/drivers/s390/crypto/zcrypt_msgtype6.c
>> +++ b/drivers/s390/crypto/zcrypt_msgtype6.c
>> @@ -31,10 +31,7 @@
>>
>> #define CEIL4(x) ((((x) + 3) / 4) * 4)
>>
>> -struct response_type {
>> - struct completion work;
>> - int type;
>> -};
>> +struct response_type;
>
> This struct is only defined, but not used. Remove it.
>
done -> see v3 (coming soon)
>>
>> #define CEXXC_RESPONSE_TYPE_ICA 0
>> #define CEXXC_RESPONSE_TYPE_XCRB 1
> [...]
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 03/20] s390/ap: Introduce ap message buffer pool
2025-03-17 16:14 ` Holger Dengler
@ 2025-03-24 14:41 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-24 14:41 UTC (permalink / raw)
To: Holger Dengler
Cc: ifranzki, fcallies, hca, gor, agordeev, linux-s390, herbert
On 2025-03-17 17:14, Holger Dengler wrote:
> On 04/03/2025 18:20, Harald Freudenberger wrote:
>> 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).
>
> typo: urgent
>
done -> v3
>> * 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>
>
> With the typo and the changed indent (see comment below)
> Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
>
>> ---
>> drivers/s390/crypto/ap_bus.c | 57
>> ++++++++++++++++++++++++++++----
>> drivers/s390/crypto/ap_bus.h | 9 ++---
>> drivers/s390/crypto/zcrypt_api.c | 10 +++---
>> 3 files changed, 60 insertions(+), 16 deletions(-)
>>
> [...]
>> diff --git a/drivers/s390/crypto/ap_bus.h
>> b/drivers/s390/crypto/ap_bus.h
>> index 483231bcdea6..a7bd44e5cc76 100644
>> --- a/drivers/s390/crypto/ap_bus.h
>> +++ b/drivers/s390/crypto/ap_bus.h
>> @@ -233,11 +233,12 @@ struct ap_message {
>> 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_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 from
>> mempool */
>
> Please do not change the indent here. The change is not required, but
> it makes the life of reviewers much harder.
>
corrected -> v3
>>
>> -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);
> [...]
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 04/20] s390/ap/zcrypt: New xflag parameter and extension of the ap msg flags
2025-03-18 12:16 ` Holger Dengler
@ 2025-03-24 15:52 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-24 15:52 UTC (permalink / raw)
To: Holger Dengler
Cc: linux-s390, herbert, ifranzki, fcallies, hca, gor, agordeev
On 2025-03-18 13:16, Holger Dengler wrote:
> On 04/03/2025 18:21, Harald Freudenberger wrote:
>> Introduce a new flag parameter for the both cprb send functions
>> zcrypt_send_cprb() and zcrypt_send_ep11_cprb(). This new
>> xflags parameter ("execution flags") shall be used to provide
>> execution hints and flags for this crypto request.
>>
>> There are two flags implemented to be used with these functions:
>> * ZCRYPT_XFLAG_USERSPACE - indicates to the lower layers that
>> all the ptrs address userspace. So when construction the ap msg
>> copy_from_user() is to be used. If this flag is NOT set, the ptrs
>> address kernel memory and thus memcpy() is to be used.
>> * ZCRYPT_XFLAG_NOMEMALLOC - indicates that this task must not
>> allocate memory which may be allocated with io operations.
>> For the zcrypt layer this limits the number of EP11 targets
>> to 16 APQNs. But as this flag is passed down the stack, it
>> may induce further restrictions.
>>
>> For the AP bus and zcrypt message layer this means:
>> * The ZCRYPT_XFLAG_USERSPACE is mapped to the AP flag
>> AP_MSG_FLAG_USERSPACE stored into the flags field of each
>> ap message in the ap_message struct. This replaces the extra
>> function parameter "userspace" and makes some function
>> invocations simpler.
>> * The ZCRYPT_XFLAG_NOMEMALLOC causes the AP message buffer to
>> use buffer space from the AP message mempool instead of
>> allocating memory via kmalloc. Note that the buffer space
>> from the AP message mem pool is limited to 12KB per item.
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>
> The boolean parameter `userspace` should only be merged with the
> xflags in functions, which has the need to handle
> ZCRYPT_XFLAG_USERSPACE and ZCRYPT_XFLAG_NOMEMALLOC, e.g
> _zcrypt_send_cprb(). Functions, which either only take one or the
> other flag may stay with the boolean parameter. There is also no need
> for a definition of AP_MSG_FLAG_USERSPACE, as the AP layer does not
> care about userspace pointers at all, only the zcrypt layer is
> affected by this flag. See my comments below.
>
>> ---
>> drivers/s390/crypto/ap_bus.c | 6 +-
>> drivers/s390/crypto/ap_bus.h | 11 ++--
>> drivers/s390/crypto/zcrypt_api.c | 90
>> +++++++++++++++------------
>> drivers/s390/crypto/zcrypt_api.h | 36 +++++++----
>> drivers/s390/crypto/zcrypt_ccamisc.c | 16 ++---
>> drivers/s390/crypto/zcrypt_ep11misc.c | 10 +--
>> drivers/s390/crypto/zcrypt_msgtype6.c | 12 ++--
>> drivers/s390/crypto/zcrypt_msgtype6.h | 4 +-
>> 8 files changed, 107 insertions(+), 78 deletions(-)
>>
> [...]
>> diff --git a/drivers/s390/crypto/ap_bus.h
>> b/drivers/s390/crypto/ap_bus.h
>> index a7bd44e5cc76..5581fb13af73 100644
>> --- a/drivers/s390/crypto/ap_bus.h
>> +++ b/drivers/s390/crypto/ap_bus.h
>> @@ -233,12 +233,13 @@ struct ap_message {
>> 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 from
>> mempool */
>> +#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
>> from mempool */
>> +#define AP_MSG_FLAG_USERSPACE 0x0010 /* pointers address userspace
>> memory */
>
> Do we really need this flag in the AP layer? IIRC it has only meaning
> in the zcrypt layer. If this is correct, please remove it.
>
>>
>> -int ap_init_apmsg(struct ap_message *ap_msg, bool use_mempool);
>> +int ap_init_apmsg(struct ap_message *ap_msg, u32 flags);
>> 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 ad09c5306e28..659fe7afb67e 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, false);
>> + rc = ap_init_apmsg(&ap_msg, AP_MSG_FLAG_USERSPACE);
>
> use_mempool == false should be changed to 0, not AP_MSG_FLAG_USERSPACE.
> rc = ap_init_apmsg(&ap_msg, 0);
>
>> 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, false);
>> + rc = ap_init_apmsg(&ap_msg, AP_MSG_FLAG_USERSPACE);
>
> Same here.
> rc = ap_init_apmsg(&ap_msg, 0);
>
>> if (rc)
>> goto out;
>>
> [...]
>> @@ -856,16 +856,19 @@ static long _zcrypt_send_cprb(bool userspace,
>> struct ap_perms *perms,
>> unsigned short *domain, tdom;
>> int cpen, qpen, qid = 0, rc;
>> struct module *mod;
>> + u32 flags;
>>
>> trace_s390_zcrypt_req(xcrb, TB_ZSECSENDCPRB);
>>
>> xcrb->status = 0;
>>
>> - rc = ap_init_apmsg(&ap_msg, false);
>> + flags = (xflags & ZCRYPT_XFLAG_USERSPACE ? AP_MSG_FLAG_USERSPACE :
>> 0) |
>> + (xflags & ZCRYPT_XFLAG_NOMEMALLOC ? AP_MSG_FLAG_MEMPOOL : 0);
>> + rc = ap_init_apmsg(&ap_msg, flags);
>
> There is no need to translate ZCRYPT_XFLAG_USERSPACE to ap-msg flags,
> the AP layer should not care about userspace/kernelspace pointer.
> rc = ap_init_apmsg(&ap_msg, xflags & ZCRYPT_XFLAG_NOMEMALLOC ?
> AP_MSG_FLAG_MEMPOOL : 0);
>
>> if (rc)
>> goto out;
>>
>> - rc = prep_cca_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);
>> + rc = prep_cca_ap_msg(xcrb, &ap_msg, &func_code, &domain);
>
> The prep_cca_ap_msg() - and all functions below - can stay with the
> bool parameter.
> rc = prep_cca_ap_msg((xflags & ZCRYPT_XFLAG_USERSPACE), xcrb, &ap_msg,
> &func_code, &domain);
>
>> if (rc)
>> goto out;
>> print_hex_dump_debug("ccareq: ", DUMP_PREFIX_ADDRESS, 16, 1,
>> @@ -956,7 +959,7 @@ static long _zcrypt_send_cprb(bool userspace,
>> struct ap_perms *perms,
>> if (*domain == AUTOSEL_DOM)
>> *domain = AP_QID_QUEUE(qid);
>>
>> - rc = pref_zq->ops->send_cprb(userspace, pref_zq, xcrb, &ap_msg);
>> + rc = pref_zq->ops->send_cprb(pref_zq, xcrb, &ap_msg);
>
> Here as well, stay with the bool parameter userspace in the callback.
> rc = pref_zq->ops->send_cprb((xflags & ZCRYPT_XFLAG_USERSPACE),
> pref_zq, xcrb, &ap_msg);
>
>> if (!rc) {
>> print_hex_dump_debug("ccarpl: ", DUMP_PREFIX_ADDRESS, 16, 1,
>> ap_msg.msg, ap_msg.len, false);
> [...]
>> @@ -1029,52 +1032,58 @@ static bool is_desired_ep11_queue(unsigned int
>> dev_qid,
>> return false;
>> }
>>
>> -static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms
>> *perms,
>> +static long _zcrypt_send_ep11_cprb(u32 xflags, struct ap_perms
>> *perms,
>> struct zcrypt_track *tr,
>> struct ep11_urb *xcrb)
>> {
>> struct zcrypt_card *zc, *pref_zc;
>> struct zcrypt_queue *zq, *pref_zq;
>> - struct ep11_target_dev *targets;
>> + struct ep11_target_dev targetbuf[16], *targets = NULL;
>> unsigned short target_num;
>> unsigned int wgt = 0, pref_wgt = 0;
>> unsigned int func_code = 0, domain;
>> struct ap_message ap_msg;
>> int cpen, qpen, qid = 0, rc;
>> struct module *mod;
>> + u32 flags;
>>
>> trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB);
>>
>> - rc = ap_init_apmsg(&ap_msg, false);
>> + flags = (xflags & ZCRYPT_XFLAG_USERSPACE ? AP_MSG_FLAG_USERSPACE :
>> 0) |
>> + (xflags & ZCRYPT_XFLAG_NOMEMALLOC ? AP_MSG_FLAG_MEMPOOL : 0);
>> + rc = ap_init_apmsg(&ap_msg, flags);
>
> The AP layer does not care about the userspace flag. Please remove it.
> rc = ap_init_apmsg(&ap_msg, xflags & ZCRYPT_XFLAG_NOMEMALLOC ?
> AP_MSG_FLAG_MEMPOOL : 0);
>
>> if (rc)
>> goto out;
>>
>> target_num = (unsigned short)xcrb->targets_num;
>>
>> /* empty list indicates autoselect (all available targets) */
>> - targets = NULL;
>> + rc = -ENOMEM;
>> if (target_num != 0) {
>> struct ep11_target_dev __user *uptr;
>>
>> - targets = kcalloc(target_num, sizeof(*targets), GFP_KERNEL);
>> - if (!targets) {
>> - func_code = 0;
>> - rc = -ENOMEM;
>> + if (target_num <= ARRAY_SIZE(targetbuf)) {
>> + targets = targetbuf;
>> + } else if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
>> goto out;
>> + } else {
>> + targets = kcalloc(target_num,
>> + sizeof(*targets), GFP_KERNEL);
>> + if (!targets)
>> + goto out;
>> }
>>
>> uptr = (struct ep11_target_dev __force __user *)xcrb->targets;
>> - if (z_copy_from_user(userspace, targets, uptr,
>> - target_num * sizeof(*targets))) {
>> - func_code = 0;
>> + if (z_copy_from_user(xflags & ZCRYPT_XFLAG_USERSPACE, targets,
>> + uptr, target_num * sizeof(*targets))) {
>> rc = -EFAULT;
>> - goto out_free;
>> + goto out;
>> }
>> }
>>
>> - rc = prep_ep11_ap_msg(userspace, xcrb, &ap_msg, &func_code,
>> &domain);
>> + rc = prep_ep11_ap_msg(xcrb, &ap_msg, &func_code, &domain);
>
> Stay here with the boolean parameter for userspace.
>
>> if (rc)
>> - goto out_free;
>> + goto out;
>> print_hex_dump_debug("ep11req: ", DUMP_PREFIX_ADDRESS, 16, 1,
>> ap_msg.msg, ap_msg.len, false);
>>
> [...]
>> @@ -1154,11 +1163,11 @@ static long _zcrypt_send_ep11_cprb(bool
>> userspace, struct ap_perms *perms,
>> pr_debug("no match for address ff.ffff => ENODEV\n");
>> }
>> rc = -ENODEV;
>> - goto out_free;
>> + goto out;
>> }
>>
>> qid = pref_zq->queue->qid;
>> - rc = pref_zq->ops->send_ep11_cprb(userspace, pref_zq, xcrb,
>> &ap_msg);
>> + rc = pref_zq->ops->send_ep11_cprb(pref_zq, xcrb, &ap_msg);
>
> Keep the boolean parameter for userspace here as well.
>
>> if (!rc) {
>> print_hex_dump_debug("ep11rpl: ", DUMP_PREFIX_ADDRESS, 16, 1,
>> ap_msg.msg, ap_msg.len, false);
> [...]
I've picked all your suggestions. See v3 (coming soon).
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 05/20] s390/zcrypt: Introduce cprb mempool for cca misc functions
2025-03-18 14:16 ` Holger Dengler
@ 2025-03-25 8:26 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-25 8:26 UTC (permalink / raw)
To: Holger Dengler
Cc: ifranzki, fcallies, hca, gor, agordeev, linux-s390, herbert
On 2025-03-18 15:16, Holger Dengler wrote:
> On 04/03/2025 18:21, Harald Freudenberger wrote:
>> Introduce a cprb mempool for the zcrypt cca misc functions
>> (zcrypt_ccamisc.*) do some preparation rework to support
>> a do-not-allocate path through some zcrypt cca misc functions.
>>
>> The mempool is by default space for 4 cprbs with each 16KB.
>> For CCA a CPRB needs to hold the request and the reply, so
>> the pool items only support requests/replies with a limit of
>> about 8KB. The minimal number of items in the mempool can get
>> adjusted via module parameter zcrypt.cca_cprbpool_min_items
>> on module load.
>>
>> This is only part of an rework to support a new xflag
>> ZCRYPT_XFLAG_NOMEMALLOC but not yet complete.
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>
> One minor comment below. Beside that
> Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
>
>> ---
>> drivers/s390/crypto/zcrypt_api.c | 13 ++-
>> drivers/s390/crypto/zcrypt_api.h | 2 +
>> drivers/s390/crypto/zcrypt_ccamisc.c | 116
>> ++++++++++++++++++++-------
>> drivers/s390/crypto/zcrypt_ccamisc.h | 1 +
>> 4 files changed, 101 insertions(+), 31 deletions(-)
>>
> [...]
>> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c
>> b/drivers/s390/crypto/zcrypt_ccamisc.c
>> index 521baaea06ff..2c2ca2d67e2d 100644
>> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
>> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
> [...]
>> @@ -229,7 +241,15 @@ static int alloc_and_prep_cprbmem(size_t
>> paramblen,
>> * allocate consecutive memory for request CPRB, request param
>> * block, reply CPRB and reply param block
>> */
>> - cprbmem = kcalloc(2, cprbplusparamblen, GFP_KERNEL);
>> + if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
>> + if (cprb_mempool &&
>> + 2 * cprbplusparamblen <= CPRB_MEMPOOL_ITEM_SIZE) {
>> + cprbmem = mempool_alloc_preallocated(cprb_mempool);
>> + memset(cprbmem, 0, 2 * cprbplusparamblen);
>> + }
>> + } else {
>
> Just a nit: let the compiler decide, if code should be duplicated or
> not.
>
> if (xflags & ZCRYPT_XFLAG_NOMEMALLOC) {
> size_t len = 2 * cprbplusparamblen;
>
> if (cprb_mempool && len <= CPRB_MEMPOOL_ITEM_SIZE) {
> cprbmem = mempool_alloc_preallocated(cprb_mempool);
> memset(cprbmem, 0, len);
> }
> } else {
>
>> + cprbmem = kcalloc(2, cprbplusparamblen, GFP_KERNEL);
>> + }
>> if (!cprbmem)
>> return -ENOMEM;
>>
> [...]
It was not my intention to outsmart the compier when writing this code.
However, changed to your suggestion -> v3
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 06/20] s390/zcrypt: Introduce cprb mempool for ep11 misc functions
2025-03-18 15:16 ` Holger Dengler
@ 2025-03-25 8:36 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-25 8:36 UTC (permalink / raw)
To: Holger Dengler
Cc: ifranzki, fcallies, hca, gor, agordeev, linux-s390, herbert
On 2025-03-18 16:16, Holger Dengler wrote:
> On 04/03/2025 18:21, Harald Freudenberger wrote:
>> Introduce a cprb mempool for the zcrypt ep11 misc functions
>> (zcrypt_ep11misc.*) do some preparation rework to support
>> a do-not-allocate path through some zcrypt cca misc functions.
>>
>> The mempool is by default space for 8 cprbs with each 8KB.
>> For EP11 a CPRB either holds the request or the reply. So for
>> a request/reply there is always a couple of cprb buffers
>> needed. The minimal number of items in the mempool can get
>> adjusted via module parameter zcrypt.ep11_cprbpool_min_items
>> on module load.
>>
>> This is only part of an rework to support a new xflag
>> ZCRYPT_XFLAG_NOMEMALLOC but not yet complete.
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>
> With the minor change (see comment below)
> Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
>
>> ---
>> drivers/s390/crypto/zcrypt_api.c | 10 ++
>> drivers/s390/crypto/zcrypt_api.h | 1 +
>> drivers/s390/crypto/zcrypt_ep11misc.c | 158
>> ++++++++++++++++----------
>> drivers/s390/crypto/zcrypt_ep11misc.h | 1 +
>> 4 files changed, 109 insertions(+), 61 deletions(-)
>>
> [...]
>> diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c
>> b/drivers/s390/crypto/zcrypt_ep11misc.c
>> index b60e262bcaa3..86578a95b140 100644
>> --- a/drivers/s390/crypto/zcrypt_ep11misc.c
>> +++ b/drivers/s390/crypto/zcrypt_ep11misc.c
> [...]
>> @@ -621,22 +652,20 @@ static int ep11_query_info(u16 cardnr, u16
>> domain, u32 query_type,
>> req_pl->query_subtype_len = sizeof(u32);
>>
>> /* reply cprb and payload */
>> - rep = alloc_cprb(sizeof(struct ep11_info_rep_pl) + buflen);
>> + rep = alloc_cprbmem(sizeof(struct ep11_info_rep_pl) + buflen,
>> xflags);
>> if (!rep)
>> goto out;
>> rep_pl = (struct ep11_info_rep_pl *)(((u8 *)rep) + sizeof(*rep));
>>
>> /* urb and target */
>> - urb = kmalloc(sizeof(*urb), GFP_KERNEL);
>> - if (!urb)
>> - goto out;
>> + memset(&urb, 0, sizeof(urb));
>
> The memset is done each time before a prep_urb() call. Please do the
> memset inside the prep_urb() function and remove the other ones.
>
done -> v3
>> target.ap_id = cardnr;
>> target.dom_id = domain;
>> - prep_urb(urb, &target, 1,
>> + prep_urb(&urb, &target, 1,
>> req, sizeof(*req) + sizeof(*req_pl),
>> rep, sizeof(*rep) + sizeof(*rep_pl) + buflen);
>>
>> - rc = zcrypt_send_ep11_cprb(urb, 0);
>> + rc = zcrypt_send_ep11_cprb(&urb, xflags);
>> if (rc) {
>> ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed,
>> rc=%d\n",
>> __func__, (int)cardnr, (int)domain, rc);
> [...]
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 07/20] s390/zcrypt: Rework zcrypt function zcrypt_device_status_mask_ext
2025-03-19 11:03 ` Holger Dengler
@ 2025-03-25 9:24 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-25 9:24 UTC (permalink / raw)
To: Holger Dengler
Cc: ifranzki, fcallies, hca, gor, agordeev, linux-s390, herbert
On 2025-03-19 12:03, Holger Dengler wrote:
> On 04/03/2025 18:21, Harald Freudenberger wrote:
>> Rework the existing function zcrypt_device_status_mask_ext():
>> * Add two new parameters to provide upper limits for
>> cards and queues. The existing implementation needed an
>> array of 256 * 256 * 4 = 256 KB which is really huge. The
>> reworked function is more flexible in the sense that the
>> caller can decide the upper limit for cards and domains to
>> be stored into the status array. So for example a caller may
>> decide to only query for cards 0...127 and queues 0...127
>> and thus only an array of size 128 * 128 * 4 = 64 KB is needed.
>> * Instead of void the reworked function now returns an int.
>> The currently only way to have the function return != 0
>> is by providing card or domains limits beyond 256.
>
> I would prefer to stay with a void function and limit the card and
> domain values to the current maximum. Details below.
>
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>> ---
>> drivers/s390/crypto/zcrypt_api.c | 20 +++++++++++++++-----
>> drivers/s390/crypto/zcrypt_api.h | 3 ++-
>> drivers/s390/crypto/zcrypt_ccamisc.c | 22 +++++++++++++++++-----
>> drivers/s390/crypto/zcrypt_ep11misc.c | 14 ++++++++++----
>> 4 files changed, 44 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/s390/crypto/zcrypt_api.c
>> b/drivers/s390/crypto/zcrypt_api.c
>> index 62cc05881b13..bd2738e3792a 100644
>> --- a/drivers/s390/crypto/zcrypt_api.c
>> +++ b/drivers/s390/crypto/zcrypt_api.c
>> @@ -1317,19 +1317,25 @@ static void zcrypt_device_status_mask(struct
>> zcrypt_device_status *devstatus)
>> spin_unlock(&zcrypt_list_lock);
>> }
>>
>> -void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext
>> *devstatus)
>> +int zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext
>> *devstatus,
>> + int maxcard, int maxqueue)
>
> Keep void and ...
>
>> {
>> struct zcrypt_card *zc;
>> struct zcrypt_queue *zq;
>> struct zcrypt_device_status_ext *stat;
>> int card, queue;
>>
>> + if (maxcard > MAX_ZDEV_CARDIDS_EXT || maxqueue >
>> MAX_ZDEV_DOMAINS_EXT)
>> + return -EINVAL;
>> +
>
> ... limit maxcard/maxqueue to the maximum supported values. In my
> opinion, it does not make any sense to call this function with higher
> values than the maximum.
>
> maxcard = MIN(maxcard, MAX_ZDEV_CARDIDS_EXT);
> maxqueue = MIN(maxqueue, MAX_ZDEV_DOMAINS_EXT);
>
> As a side effect, it keeps the caller code much simpler.
>
>> spin_lock(&zcrypt_list_lock);
>> for_each_zcrypt_card(zc) {
>> for_each_zcrypt_queue(zq, zc) {
>> card = AP_QID_CARD(zq->queue->qid);
>> queue = AP_QID_QUEUE(zq->queue->qid);
>> - stat = &devstatus[card * AP_DOMAINS + queue];
>> + if (card >= maxcard || queue >= maxqueue)
>> + continue;
>> + stat = &devstatus[card * maxqueue + queue];
>> stat->hwtype = zc->card->ap_dev.device_type;
>> stat->functions = zc->card->hwinfo.fac >> 26;
>> stat->qid = zq->queue->qid;
> [...]
>> @@ -1635,9 +1643,11 @@ static long zcrypt_unlocked_ioctl(struct file
>> *filp, unsigned int cmd,
>> GFP_KERNEL);
>> if (!device_status)
>> return -ENOMEM;
>> - zcrypt_device_status_mask_ext(device_status);
>> - if (copy_to_user((char __user *)arg, device_status,
>> - total_size))
>> + rc = zcrypt_device_status_mask_ext(device_status,
>> + MAX_ZDEV_CARDIDS_EXT,
>> + MAX_ZDEV_DOMAINS_EXT);
>> + if (!rc && copy_to_user((char __user *)arg, device_status,
>> + total_size))
>
> With the change above, you can stay with the current error handling.
> Only the addition parameters for zcrypt_device_status_mask_ext() need
> to be added.
>
>> rc = -EFAULT;
>> kvfree(device_status);
>> return rc;
> [...]
Done as suggested - only I used typed min (min_t()) instead of MIN.
-> v3
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 08/20] s390/zcrypt: Introduce pre-allocated device status array for cca misc
2025-03-19 14:31 ` Holger Dengler
@ 2025-03-25 10:51 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-25 10:51 UTC (permalink / raw)
To: Holger Dengler
Cc: ifranzki, fcallies, hca, gor, agordeev, linux-s390, herbert
On 2025-03-19 15:31, Holger Dengler wrote:
> On 04/03/2025 18:21, Harald Freudenberger wrote:
>> Introduce a pre-allocated device status array memory together with
>> a mutex controlling the occupation to be used by the two findcard()
>> functions. Limit the device status array to max 128 cards and max
>
> As far as I can see, cca_findcard() (and also the static findcard())
> are no longer used. If this is the case, I would prefer to remove this
> unused variant, either in this patch (with a hint in the commit
> message) or in a separate one (in the order prior to this patch).
>
>> 128 domains to reduce the size of this pre-allocated memory to 64 KB.
>
> I'm a bit unhappy about introducing a synchronization with this single
> piece of memory.
>
Any other ideas ?
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>> ---
>> drivers/s390/crypto/zcrypt_ccamisc.c | 78
>> +++++++++++++++++++---------
>> 1 file changed, 53 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c
>> b/drivers/s390/crypto/zcrypt_ccamisc.c
>> index 420895df70f0..65b4cdb9b478 100644
>> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
>> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
> [...]
>> @@ -1801,21 +1817,20 @@ static int findcard(u64 mkvp, u16 *pcardnr,
>> u16 *pdomain,
>
> As mentioned above, please check for users of findcard() and
> cca_findcard(). If there are no users anymore, please remove the
> obsolete code.
>
Seems you are right - findcard() and cca_findcard() are no longer used.
So I'll introduce another patch before this one which removes the unused
functions. -> v3
> [...]
>> @@ -2023,11 +2041,21 @@ int __init zcrypt_ccamisc_init(void)
>> cprb_mempool = NULL;
>> return -ENOMEM;
>> }
>> +
>> + /* Pre-allocate one crypto status card struct used in findcard() */
>> + dev_status_mem = kvmalloc(ZCRYPT_DEV_STATUS_EXT_SIZE, GFP_KERNEL);
>
> The alloc of dev_status_mem should be protected by the mutex as well.
>
No, init() is supposed to be executed exactly once and there is nothing
running which may somehow occupy this memory already.
>> + if (!dev_status_mem) {
>> + ZCRYPT_DBF_ERR("%s allocation of dev_status_mem failed\n",
>> __func__);
>> + mempool_destroy(cprb_mempool);
>> + return -ENOMEM;
>> + }
>> +
>> return 0;
>> }
>>
>> void zcrypt_ccamisc_exit(void)
>> {
>> mkvp_cache_free();
>> + kvfree(dev_status_mem);
>
> Same here: please lock the mutex before releasing dev_status_mem.
>
Agreed - the free call should be delayed in cases where the memory
is currently occupied by a caller. So I'll lock the mutex before
calling free() -> v3
>> mempool_destroy(cprb_mempool);
>> }
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 09/20] s390/zcrypt: Introduce pre-allocated device status array for ep11 misc
2025-03-19 18:02 ` Holger Dengler
@ 2025-03-25 11:09 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-25 11:09 UTC (permalink / raw)
To: Holger Dengler
Cc: ifranzki, fcallies, hca, gor, agordeev, linux-s390, herbert
On 2025-03-19 19:02, Holger Dengler wrote:
> On 04/03/2025 18:21, Harald Freudenberger wrote:
>> Introduce a pre-allocated device status array memory together with
>> a mutex controlling the occupation to be used by the findcard()
>> function. Limit the device status array to max 128 cards and max
>> 128 domains to reduce the size of this pre-allocated memory to 64 KB.
>
> I have the same concerns as for patch 8/20. Please think about an
> alternative to the dev_status_mem sharing, because it synchronizes all
> findcard() calls.
>
There are not so many findcard() calls in parallel. And the lock is only
during running the findcard itself. Ok, the function may need a couple
of milliseconds and during this time block other callers but as I wrote,
I do not expect this to have impact on any load.
I could think of giving this function a ptr to memory from the caller.
So then all ioctl calls could alloc some work mem and pass it down
to findcard(). On the other side exactly these callers have time and
a short delay because of the mutex does no harm. The real issue is
with a pkey request coming via in-kernel pkey API. The pkey_cca handler
could hold some memory for this purpose - but with that I am only
moving the mem + mutex one level up. I have no other idea.
Btw. the exit() function now locks the mutex before freeing the memory.
-> v3
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>> ---
>> drivers/s390/crypto/zcrypt_ep11misc.c | 46
>> +++++++++++++++++++++------
>> 1 file changed, 36 insertions(+), 10 deletions(-)
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 10/20] s390/zcrypt/pkey: Rework cca findcard() implementation and callers
2025-03-19 17:58 ` Holger Dengler
@ 2025-03-25 13:02 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-25 13:02 UTC (permalink / raw)
To: Holger Dengler
Cc: ifranzki, fcallies, hca, gor, agordeev, linux-s390, herbert
On 2025-03-19 18:58, Holger Dengler wrote:
> On 04/03/2025 18:21, Harald Freudenberger wrote:
>> Rework the memory usage of the cca findcard() implementation:
>> - findcard does not allocate memory for the list of apqns
>> any more.
>> - the callers are now responsible to provide an array of
>> apqns to store the matching apqns into.
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>
> See my comments below.
>
>> ---
>> drivers/s390/crypto/pkey_cca.c | 25 +++++++++++--------------
>> drivers/s390/crypto/zcrypt_ccamisc.c | 18 ++++--------------
>> drivers/s390/crypto/zcrypt_ccamisc.h | 12 +++++-------
>> 3 files changed, 20 insertions(+), 35 deletions(-)
>>
> [...]
>> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c
>> b/drivers/s390/crypto/zcrypt_ccamisc.c
>> index 65b4cdb9b478..d3b093dcdf30 100644
>> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
>> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
> [...]
>> @@ -2006,17 +1999,14 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns,
>> u16 cardnr, u16 domain,
>> continue;
>> }
>> /* apqn passed all filtering criterons, add to the array */
>> - if (_nr_apqns < 256)
>> - _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
>> + if (_nr_apqns < *nr_apqns)
>> + apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
>> }
>>
>> /* nothing found ? */
>> if (!_nr_apqns) {
>> - kfree(_apqns);
>> rc = -ENODEV;
>
> In my opinion, the -ENODEV return value can be completely dropped. For
> the caller it should be sufficient to check for nr_apqns == 0.
>
>> } else {
>> - /* no re-allocation, simple return the _apqns array */
>> - *apqns = _apqns;
>> *nr_apqns = _nr_apqns;
>
> Please update *nr_apqns unconditionally.
>
>> rc = 0;
>> }
>> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.h
>> b/drivers/s390/crypto/zcrypt_ccamisc.h
>> index 273edf2bb036..bed647a42eb2 100644
>> --- a/drivers/s390/crypto/zcrypt_ccamisc.h
>> +++ b/drivers/s390/crypto/zcrypt_ccamisc.h
>> @@ -229,14 +229,12 @@ int cca_findcard(const u8 *key, u16 *pcardnr,
>> u16 *pdomain, int verify);
>> * cur_mkvp or old_mkvp values of the apqn are used.
>> * The mktype determines which set of master keys to use:
>> * 0 = AES_MK_SET - AES MK set, 1 = APKA MK_SET - APKA MK set
>> - * The array of apqn entries is allocated with kmalloc and returned
>> in *apqns;
>> - * the number of apqns stored into the list is returned in *nr_apqns.
>> One apqn
>> - * entry is simple a 32 bit value with 16 bit cardnr and 16 bit
>> domain nr and
>> - * may be casted to struct pkey_apqn. The return value is either 0
>> for success
>> - * or a negative errno value. If no apqn meeting the criteria is
>> found,
>> - * -ENODEV is returned.
>> + * The caller should set *nr_apqns to the nr of elements available in
>> *apqns.
>> + * On return *nr_apqns is then updated with the nr of apqns filled
>> into *apqns.
>> + * The return value is either 0 for success or a negative errno
>> value.
>> + * If no apqn meeting the criteria is found, -ENODEV is returned.
>
> Why not just return nr_apqns == 0 to indicate, that no matching device
> has been found? Anyhow, even if you would stay with the -ENODEV return
> value, *nr_apqns should be updated in any case.
>
>> */
>> -int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
>> +int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
>> int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
>> int verify);
>>
I changed this to unconditionally always update *nr_apqns.
But I'd like to stay with the -ENODEV in case 0 apqns have been found.
There is code using this returncode (which then also would need
reworked).
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 11/20] s390/zcrypt/pkey: Rework ep11 findcard() implementation and callers
2025-03-20 8:30 ` Holger Dengler
@ 2025-03-25 13:12 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-25 13:12 UTC (permalink / raw)
To: Holger Dengler
Cc: ifranzki, fcallies, hca, gor, agordeev, linux-s390, herbert
On 2025-03-20 09:30, Holger Dengler wrote:
> On 04/03/2025 18:21, Harald Freudenberger wrote:
>> Rework the memory usage of the ep11 findcard() implementation:
>> - findcard does not allocate memory for the list of apqns
>> any more.
>> - the callers are now responsible to provide an array of
>> apqns to store the matching apqns into.
>
> See my comments below.
>
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>> ---
>> drivers/s390/crypto/pkey_ep11.c | 19 ++++++++-----------
>> drivers/s390/crypto/zcrypt_ep11misc.c | 18 ++++--------------
>> drivers/s390/crypto/zcrypt_ep11misc.h | 12 +++++-------
>> 3 files changed, 17 insertions(+), 32 deletions(-)
>>
> [...]
>> diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c
>> b/drivers/s390/crypto/zcrypt_ep11misc.c
>> index 04153b476168..6005ef79c001 100644
>> --- a/drivers/s390/crypto/zcrypt_ep11misc.c
>> +++ b/drivers/s390/crypto/zcrypt_ep11misc.c
> [...]
>> @@ -1678,17 +1671,14 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns,
>> u16 cardnr, u16 domain,
>> continue;
>> }
>> /* apqn passed all filtering criterons, add to the array */
>> - if (_nr_apqns < 256)
>> - _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
>> + if (_nr_apqns < *nr_apqns)
>> + apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);
>> }
>>
>> /* nothing found ? */
>> if (!_nr_apqns) {
>> - kfree(_apqns);
>> rc = -ENODEV;
>> } else {
>> - /* no re-allocation, simple return the _apqns array */
>> - *apqns = _apqns;
>
> Please update *apqns unconditionally.
>
>> *nr_apqns = _nr_apqns;
>> rc = 0;
>> }
>> diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h
>> b/drivers/s390/crypto/zcrypt_ep11misc.h
>> index a4b98eca8431..cbd615547bc2 100644
>> --- a/drivers/s390/crypto/zcrypt_ep11misc.h
>> +++ b/drivers/s390/crypto/zcrypt_ep11misc.h
>> @@ -136,14 +136,12 @@ int ep11_clr2keyblob(u16 cardnr, u16 domain, u32
>> keybitsize, u32 keygenflags,
>> * key for this domain. When a wkvp is given there will always be a
>> re-fetch
>> * of the domain info for the potential apqn - so this triggers an
>> request
>> * reply to each apqn eligible.
>> - * The array of apqn entries is allocated with kmalloc and returned
>> in *apqns;
>> - * the number of apqns stored into the list is returned in *nr_apqns.
>> One apqn
>> - * entry is simple a 32 bit value with 16 bit cardnr and 16 bit
>> domain nr and
>> - * may be casted to struct pkey_apqn. The return value is either 0
>> for success
>> - * or a negative errno value. If no apqn meeting the criteria is
>> found,
>> - * -ENODEV is returned.
>> + * The caller should set *nr_apqns to the nr of elements available in
>> *apqns.
>> + * On return *nr_apqns is then updated with the nr of apqns filled
>> into *apqns.
>> + * The return value is either 0 for success or a negative errno
>> value.
>> + * If no apqn meeting the criteria is found, -ENODEV is returned.
>
> As mentioned in my comment to patch 10/20: please update nr_apqns in
> any case. If -ENODEV should be dropped for cca, than also drop it
> here.
>
>> */
>> -int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16
>> domain,
>> +int ep11_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
>> int minhwtype, int minapi, const u8 *wkvp);
>>
>> /*
The *nr_apqns is now unconditional updated. But I keep the behavior with
the -ENODEV as there is code relaying on that.
-> v3
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 13/20] s390/zcrypt: Add small mempool for cca info list entries
2025-03-20 14:34 ` Holger Dengler
@ 2025-03-25 13:32 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-25 13:32 UTC (permalink / raw)
To: Holger Dengler
Cc: ifranzki, fcallies, hca, gor, agordeev, linux-s390, herbert
On 2025-03-20 15:34, Holger Dengler wrote:
> On 04/03/2025 18:21, Harald Freudenberger wrote:
>> Add a small memory pool for (pre-)allocating cca info list
>> entries. These entries are rather small and the pool is a simple
>> way to support the xflag ZCRYPT_XFLAG_NOMEMALLOC to avoid mallocs.
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>
> With the requested change,
> Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
>
>> ---
>> drivers/s390/crypto/zcrypt_ccamisc.c | 67
>> ++++++++++++++++++++--------
>> drivers/s390/crypto/zcrypt_ccamisc.h | 3 +-
>> drivers/s390/crypto/zcrypt_cex4.c | 4 +-
>> 3 files changed, 53 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c
>> b/drivers/s390/crypto/zcrypt_ccamisc.c
>> index ff7ba2622484..e4ec922aae0d 100644
>> --- a/drivers/s390/crypto/zcrypt_ccamisc.c
>> +++ b/drivers/s390/crypto/zcrypt_ccamisc.c
> [...]
>> @@ -1828,6 +1834,7 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16
>> *pdomain,
>> u16 card, dom;
>> struct cca_info ci;
>> int i, rc, oi = -1;
>> + u32 xflg = 0; /* xflags */
>
> I'm confused. Why not just calling it xflags? Anyhow, as mentioned
> earlier: findcard() has no consumers, so please remove it completely.
findcard() does not exist any more. :-)
>
>>
>> /* mkvp must not be zero, minhwtype needs to be >= 0 */
>> if (mkvp == 0 || minhwtype < 0)
>> @@ -1859,8 +1866,8 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16
>> *pdomain,
>> if (!verify)
>> break;
>> /* verify: refresh card info */
>> - if (fetch_cca_info(card, dom, &ci) == 0) {
>> - cca_info_cache_update(card, dom, &ci);
>> + if (fetch_cca_info(card, dom, &ci, xflg) == 0) {
>> + cca_info_cache_update(card, dom, &ci, xflg);
>> if (ci.hwtype >= minhwtype &&
>> ci.cur_aes_mk_state == '2' &&
>> ci.cur_aes_mkvp == mkvp)
>> @@ -1882,8 +1889,8 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16
>> *pdomain,
>> card = AP_QID_CARD(device_status[i].qid);
>> dom = AP_QID_QUEUE(device_status[i].qid);
>> /* fresh fetch mkvp from adapter */
>> - if (fetch_cca_info(card, dom, &ci) == 0) {
>> - cca_info_cache_update(card, dom, &ci);
>> + if (fetch_cca_info(card, dom, &ci, xflg) == 0) {
>> + cca_info_cache_update(card, dom, &ci, xflg);
>> if (ci.hwtype >= minhwtype &&
>> ci.cur_aes_mk_state == '2' &&
>> ci.cur_aes_mkvp == mkvp)
> [...]
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH v2 14/20] s390/zcrypt: Locate ep11_domain_query_info onto the stack instead of kmalloc
2025-03-20 14:41 ` Holger Dengler
@ 2025-03-25 14:04 ` Harald Freudenberger
0 siblings, 0 replies; 55+ messages in thread
From: Harald Freudenberger @ 2025-03-25 14:04 UTC (permalink / raw)
To: Holger Dengler
Cc: ifranzki, fcallies, hca, gor, agordeev, linux-s390, herbert
On 2025-03-20 15:41, Holger Dengler wrote:
> On 04/03/2025 18:21, Harald Freudenberger wrote:
>> Locate the relative small struct ep11_domain_query_info variable
>> onto the stack instead of kmalloc()/kfree().
>>
>> Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
>
> One minor comment.
> Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
>
>> ---
>> drivers/s390/crypto/zcrypt_ep11misc.c | 25 ++++++++++---------------
>> 1 file changed, 10 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c
>> b/drivers/s390/crypto/zcrypt_ep11misc.c
>> index 6005ef79c001..7fb55be3e943 100644
>> --- a/drivers/s390/crypto/zcrypt_ep11misc.c
>> +++ b/drivers/s390/crypto/zcrypt_ep11misc.c
>> @@ -790,36 +790,31 @@ int ep11_get_domain_info(u16 card, u16 domain,
>> struct ep11_domain_info *info)
>> u8 new_WK_VP[32];
>> u32 dom_flags;
>> u64 op_mode;
>> - } __packed * p_dom_info;
>> -
>> - p_dom_info = kmalloc(sizeof(*p_dom_info), GFP_KERNEL);
>> - if (!p_dom_info)
>> - return -ENOMEM;
>> + } __packed dom_query_info;
>
> Why is dom_query_info a typed struct? The struct type is not used and
> an untyped struct can be used as well.
You are right - this struct and the relevant struct for card info
are only function local and would not need a naming. However, I'll
keep these names - I think the idea was to easily copy this code
to file scope. The compiler removes it anyway.
^ permalink raw reply [flat|nested] 55+ messages in thread
end of thread, other threads:[~2025-03-25 14:04 UTC | newest]
Thread overview: 55+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-04 17:20 [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Harald Freudenberger
2025-03-04 17:20 ` [PATCH v2 01/20] s390/ap: Move response_type struct into ap_msg struct Harald Freudenberger
2025-03-17 9:38 ` Holger Dengler
2025-03-24 14:34 ` Harald Freudenberger
2025-03-04 17:20 ` [PATCH v2 02/20] s390/ap/zcrypt: Rework AP message buffer allocation Harald Freudenberger
2025-03-17 13:57 ` Holger Dengler
2025-03-04 17:20 ` [PATCH v2 03/20] s390/ap: Introduce ap message buffer pool Harald Freudenberger
2025-03-17 16:14 ` Holger Dengler
2025-03-24 14:41 ` Harald Freudenberger
2025-03-04 17:21 ` [PATCH v2 04/20] s390/ap/zcrypt: New xflag parameter and extension of the ap msg flags Harald Freudenberger
2025-03-18 12:16 ` Holger Dengler
2025-03-24 15:52 ` Harald Freudenberger
2025-03-04 17:21 ` [PATCH v2 05/20] s390/zcrypt: Introduce cprb mempool for cca misc functions Harald Freudenberger
2025-03-18 14:16 ` Holger Dengler
2025-03-25 8:26 ` Harald Freudenberger
2025-03-04 17:21 ` [PATCH v2 06/20] s390/zcrypt: Introduce cprb mempool for ep11 " Harald Freudenberger
2025-03-18 15:16 ` Holger Dengler
2025-03-25 8:36 ` Harald Freudenberger
2025-03-04 17:21 ` [PATCH v2 07/20] s390/zcrypt: Rework zcrypt function zcrypt_device_status_mask_ext Harald Freudenberger
2025-03-19 11:03 ` Holger Dengler
2025-03-25 9:24 ` Harald Freudenberger
2025-03-04 17:21 ` [PATCH v2 08/20] s390/zcrypt: Introduce pre-allocated device status array for cca misc Harald Freudenberger
2025-03-19 14:31 ` Holger Dengler
2025-03-25 10:51 ` Harald Freudenberger
2025-03-04 17:21 ` [PATCH v2 09/20] s390/zcrypt: Introduce pre-allocated device status array for ep11 misc Harald Freudenberger
2025-03-19 18:02 ` Holger Dengler
2025-03-25 11:09 ` Harald Freudenberger
2025-03-04 17:21 ` [PATCH v2 10/20] s390/zcrypt/pkey: Rework cca findcard() implementation and callers Harald Freudenberger
2025-03-19 17:58 ` Holger Dengler
2025-03-25 13:02 ` Harald Freudenberger
2025-03-04 17:21 ` [PATCH v2 11/20] s390/zcrypt/pkey: Rework ep11 " Harald Freudenberger
2025-03-20 8:30 ` Holger Dengler
2025-03-25 13:12 ` Harald Freudenberger
2025-03-04 17:21 ` [PATCH v2 12/20] s390/zcrypt: Rework cca misc functions kmallocs to use the cprb mempool Harald Freudenberger
2025-03-20 9:31 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 13/20] s390/zcrypt: Add small mempool for cca info list entries Harald Freudenberger
2025-03-20 14:34 ` Holger Dengler
2025-03-25 13:32 ` Harald Freudenberger
2025-03-20 16:05 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 14/20] s390/zcrypt: Locate ep11_domain_query_info onto the stack instead of kmalloc Harald Freudenberger
2025-03-20 14:41 ` Holger Dengler
2025-03-25 14:04 ` Harald Freudenberger
2025-03-04 17:21 ` [PATCH v2 15/20] s390/zcrypt: Rework ep11 misc functions to use cprb mempool Harald Freudenberger
2025-03-20 15:18 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 16/20] s390/zcrypt: Add small mempool for ep11 card info list entries Harald Freudenberger
2025-03-20 16:09 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 17/20] s390/pkey: Rework CCA pkey handler to use stack for small memory allocs Harald Freudenberger
2025-03-21 9:05 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 18/20] s390/pkey: Rework EP11 " Harald Freudenberger
2025-03-21 9:06 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 19/20] s390/zcrypt/pkey: Provide and pass xflags within pkey and zcrypt layers Harald Freudenberger
2025-03-20 16:30 ` Holger Dengler
2025-03-04 17:21 ` [PATCH v2 20/20] s390/pkey/crypto: Introduce xflags param for pkey in-kernel API Harald Freudenberger
2025-03-20 16:34 ` Holger Dengler
2025-03-20 16:40 ` [PATCH v2 00/20] AP bus/zcrypt/pkey/paes no-mem-alloc patches Holger Dengler
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox