]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
s390/zcrypt: Rework domain processing within zcrypt device driver
authorHarald Freudenberger <freude@linux.ibm.com>
Wed, 18 Mar 2026 16:41:29 +0000 (17:41 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 24 Mar 2026 20:00:41 +0000 (21:00 +0100)
Slight rework of the domain handling within the zcrypt dd:
Remove this curious construct to give a pointer to the
domain field within the CPRB struct to the zcrypt API and
later fill in the target domain via this pointer.
Now the domain is filled in with the send function when
the ready constructed AP message is about to be pushed
down into the software queue for AP queue processing.
So now the domain handling for CCA, EP11 and (internal) rng
CPRBs is the same. With this comes a slight reshuffle of the
code related to domain processing in the zcrypt API and the
message type 60 protocol implementation code.

Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
drivers/s390/crypto/zcrypt_api.c
drivers/s390/crypto/zcrypt_msgtype6.c
drivers/s390/crypto/zcrypt_msgtype6.h

index 023ea279361f65131c2f2458673a967b039424a0..d1b7c93b017bf95342b81fa67af914f63447d092 100644 (file)
@@ -854,13 +854,12 @@ static long _zcrypt_send_cprb(u32 xflags, struct ap_perms *perms,
                              struct ica_xcRB *xcrb)
 {
        bool userspace = xflags & ZCRYPT_XFLAG_USERSPACE;
-       struct zcrypt_card *zc, *pref_zc;
-       struct zcrypt_queue *zq, *pref_zq;
-       struct ap_message ap_msg;
+       unsigned int domain, func_code = 0;
        unsigned int wgt = 0, pref_wgt = 0;
-       unsigned int func_code = 0;
-       unsigned short *domain, tdom;
+       struct zcrypt_queue *zq, *pref_zq;
+       struct zcrypt_card *zc, *pref_zc;
        int cpen, qpen, qid = 0, rc;
+       struct ap_message ap_msg;
        struct module *mod;
 
        trace_s390_zcrypt_req(xcrb, TB_ZSECSENDCPRB);
@@ -878,10 +877,9 @@ static long _zcrypt_send_cprb(u32 xflags, struct ap_perms *perms,
        print_hex_dump_debug("ccareq: ", DUMP_PREFIX_ADDRESS, 16, 1,
                             ap_msg.msg, ap_msg.len, false);
 
-       tdom = *domain;
-       if (perms != &ap_perms && tdom < AP_DOMAINS) {
+       if (perms != &ap_perms && domain < AP_DOMAINS) {
                if (ap_msg.flags & AP_MSG_FLAG_ADMIN) {
-                       if (!test_bit_inv(tdom, perms->adm)) {
+                       if (!test_bit_inv(domain, perms->adm)) {
                                rc = -ENODEV;
                                goto out;
                        }
@@ -894,10 +892,10 @@ static long _zcrypt_send_cprb(u32 xflags, struct ap_perms *perms,
         * If a valid target domain is set and this domain is NOT a usage
         * domain but a control only domain, autoselect target domain.
         */
-       if (tdom < AP_DOMAINS &&
-           !ap_test_config_usage_domain(tdom) &&
-           ap_test_config_ctrl_domain(tdom))
-               tdom = AUTOSEL_DOM;
+       if (domain < AP_DOMAINS &&
+           !ap_test_config_usage_domain(domain) &&
+           ap_test_config_ctrl_domain(domain))
+               domain = AUTOSEL_DOM;
 
        pref_zc = NULL;
        pref_zq = NULL;
@@ -929,8 +927,8 @@ static long _zcrypt_send_cprb(u32 xflags, struct ap_perms *perms,
                        /* check for device usable and eligible */
                        if (!zq->online || !zq->ops->send_cprb ||
                            !ap_queue_usable(zq->queue) ||
-                           (tdom != AUTOSEL_DOM &&
-                            tdom != AP_QID_QUEUE(zq->queue->qid)))
+                           (domain != AUTOSEL_DOM &&
+                            domain != AP_QID_QUEUE(zq->queue->qid)))
                                continue;
                        /* check if device node has admission for this queue */
                        if (!zcrypt_check_queue(perms,
@@ -953,16 +951,11 @@ static long _zcrypt_send_cprb(u32 xflags, struct ap_perms *perms,
 
        if (!pref_zq) {
                pr_debug("no match for address %02x.%04x => ENODEV\n",
-                        xcrb->user_defined, *domain);
+                        xcrb->user_defined, domain);
                rc = -ENODEV;
                goto out;
        }
 
-       /* in case of auto select, provide the correct domain */
-       qid = pref_zq->queue->qid;
-       if (*domain == AUTOSEL_DOM)
-               *domain = AP_QID_QUEUE(qid);
-
        rc = pref_zq->ops->send_cprb(userspace, pref_zq, xcrb, &ap_msg);
        if (!rc) {
                print_hex_dump_debug("ccarpl: ", DUMP_PREFIX_ADDRESS, 16, 1,
@@ -1220,7 +1213,6 @@ static long zcrypt_rng(char *buffer)
        unsigned int wgt = 0, pref_wgt = 0;
        unsigned int func_code = 0;
        struct ap_message ap_msg;
-       unsigned int domain;
        int qid = 0, rc = -ENODEV;
        struct module *mod;
 
@@ -1229,7 +1221,7 @@ static long zcrypt_rng(char *buffer)
        rc = ap_init_apmsg(&ap_msg, 0);
        if (rc)
                goto out;
-       rc = prep_rng_ap_msg(&ap_msg, &func_code, &domain);
+       rc = prep_rng_ap_msg(&ap_msg, &func_code, NULL);
        if (rc)
                goto out;
 
index e30f1c2947cf4a28cf28f8bf1c92ec6d4c0e101f..3bd24bceebd442578c52dd6601c6febccdb9617c 100644 (file)
@@ -328,7 +328,7 @@ struct type86_fmt2_msg {
 static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg,
                                      struct ica_xcRB *xcrb,
                                      unsigned int *fcode,
-                                     unsigned short **dom)
+                                     unsigned int *domain)
 {
        static struct type6_hdr static_type6_hdrX = {
                .type           =  0x06,
@@ -412,7 +412,8 @@ static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg,
               sizeof(msg->hdr.function_code));
 
        *fcode = (msg->hdr.function_code[0] << 8) | msg->hdr.function_code[1];
-       *dom = (unsigned short *)&msg->cprbx.domain;
+       if (domain)
+               *domain = msg->cprbx.domain;
 
        /* check subfunction, US and AU need special flag with NQAP */
        if (memcmp(function_code, "US", 2) == 0 ||
@@ -529,7 +530,8 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap
        else
                ap_msg->flags |= AP_MSG_FLAG_USAGE;
 
-       *domain = msg->cprbx.target_id;
+       if (domain)
+               *domain = msg->cprbx.target_id;
 
        return 0;
 }
@@ -1056,7 +1058,7 @@ out_free:
  */
 int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
                    struct ap_message *ap_msg,
-                   unsigned int *func_code, unsigned short **dom)
+                   unsigned int *func_code, unsigned int *domain)
 {
        struct ap_response_type *resp_type = &ap_msg->response;
 
@@ -1064,7 +1066,8 @@ int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
        ap_msg->psmid = (((unsigned long)current->pid) << 32) +
                                atomic_inc_return(&zcrypt_step);
        resp_type->type = CEXXC_RESPONSE_TYPE_XCRB;
-       return xcrb_msg_to_type6cprb_msgx(userspace, ap_msg, xcrb, func_code, dom);
+       return xcrb_msg_to_type6cprb_msgx(userspace, ap_msg,
+                                         xcrb, func_code, domain);
 }
 
 /*
@@ -1109,6 +1112,9 @@ static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
                msg->hdr.fromcardlen1 -= delta;
        }
 
+       /* update domain field within the CPRB struct */
+       msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid);
+
        init_completion(&resp_type->work);
        rc = ap_queue_message(zq->queue, ap_msg);
        if (rc)
@@ -1214,8 +1220,7 @@ static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *
                        lfmt = 1; /* length format #1 */
                }
                payload_hdr = (struct pld_hdr *)((&msg->pld_lenfmt) + lfmt);
-               payload_hdr->dom_val = (unsigned int)
-                                       AP_QID_QUEUE(zq->queue->qid);
+               payload_hdr->dom_val = AP_QID_QUEUE(zq->queue->qid);
        }
 
        /*
@@ -1296,7 +1301,8 @@ static inline void rng_type6cprb_msgx(struct ap_message *ap_msg,
        msg->verb_length = 0x02;
        msg->key_length = 0x02;
        ap_msg->len = sizeof(*msg);
-       *domain = (unsigned short)msg->cprbx.domain;
+       if (domain)
+               *domain = msg->cprbx.domain;
 }
 
 /*
index 9f7510019bc453ca60f9a668c1a146254524c690..9cbe6e2b2d33c6858ad32656dd428d7269d4055e 100644 (file)
@@ -96,7 +96,7 @@ struct type86_fmt2_ext {
 
 int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
                    struct ap_message *ap_msg,
-                   unsigned int *fc, unsigned short **dom);
+                   unsigned int *fc, unsigned int *dom);
 int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
                     struct ap_message *ap_msg,
                     unsigned int *fc, unsigned int *dom);