linux/drivers/s390/crypto/zcrypt_cex4.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *  Copyright IBM Corp. 2012, 2019
   4 *  Author(s): Holger Dengler <hd@linux.vnet.ibm.com>
   5 */
   6
   7#include <linux/module.h>
   8#include <linux/slab.h>
   9#include <linux/init.h>
  10#include <linux/err.h>
  11#include <linux/atomic.h>
  12#include <linux/uaccess.h>
  13#include <linux/mod_devicetable.h>
  14
  15#include "ap_bus.h"
  16#include "zcrypt_api.h"
  17#include "zcrypt_msgtype6.h"
  18#include "zcrypt_msgtype50.h"
  19#include "zcrypt_error.h"
  20#include "zcrypt_cex4.h"
  21#include "zcrypt_ccamisc.h"
  22
  23#define CEX4A_MIN_MOD_SIZE        1     /*    8 bits    */
  24#define CEX4A_MAX_MOD_SIZE_2K   256     /* 2048 bits    */
  25#define CEX4A_MAX_MOD_SIZE_4K   512     /* 4096 bits    */
  26
  27#define CEX4C_MIN_MOD_SIZE       16     /*  256 bits    */
  28#define CEX4C_MAX_MOD_SIZE      512     /* 4096 bits    */
  29
  30#define CEX4A_MAX_MESSAGE_SIZE  MSGTYPE50_CRB3_MAX_MSG_SIZE
  31#define CEX4C_MAX_MESSAGE_SIZE  MSGTYPE06_MAX_MSG_SIZE
  32
  33/* Waiting time for requests to be processed.
  34 * Currently there are some types of request which are not deterministic.
  35 * But the maximum time limit managed by the stomper code is set to 60sec.
  36 * Hence we have to wait at least that time period.
  37 */
  38#define CEX4_CLEANUP_TIME       (900*HZ)
  39
  40MODULE_AUTHOR("IBM Corporation");
  41MODULE_DESCRIPTION("CEX4/CEX5/CEX6/CEX7 Cryptographic Card device driver, " \
  42                   "Copyright IBM Corp. 2019");
  43MODULE_LICENSE("GPL");
  44
  45static struct ap_device_id zcrypt_cex4_card_ids[] = {
  46        { .dev_type = AP_DEVICE_TYPE_CEX4,
  47          .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
  48        { .dev_type = AP_DEVICE_TYPE_CEX5,
  49          .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
  50        { .dev_type = AP_DEVICE_TYPE_CEX6,
  51          .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
  52        { .dev_type = AP_DEVICE_TYPE_CEX7,
  53          .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
  54        { /* end of list */ },
  55};
  56
  57MODULE_DEVICE_TABLE(ap, zcrypt_cex4_card_ids);
  58
  59static struct ap_device_id zcrypt_cex4_queue_ids[] = {
  60        { .dev_type = AP_DEVICE_TYPE_CEX4,
  61          .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
  62        { .dev_type = AP_DEVICE_TYPE_CEX5,
  63          .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
  64        { .dev_type = AP_DEVICE_TYPE_CEX6,
  65          .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
  66        { .dev_type = AP_DEVICE_TYPE_CEX7,
  67          .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
  68        { /* end of list */ },
  69};
  70
  71MODULE_DEVICE_TABLE(ap, zcrypt_cex4_queue_ids);
  72
  73/*
  74 * CCA card addditional device attributes
  75 */
  76static ssize_t serialnr_show(struct device *dev,
  77                             struct device_attribute *attr,
  78                             char *buf)
  79{
  80        struct cca_info ci;
  81        struct ap_card *ac = to_ap_card(dev);
  82        struct zcrypt_card *zc = ac->private;
  83
  84        memset(&ci, 0, sizeof(ci));
  85
  86        if (ap_domain_index >= 0)
  87                cca_get_info(ac->id, ap_domain_index, &ci, zc->online);
  88
  89        return snprintf(buf, PAGE_SIZE, "%s\n", ci.serial);
  90}
  91static DEVICE_ATTR_RO(serialnr);
  92
  93static struct attribute *cca_card_attrs[] = {
  94        &dev_attr_serialnr.attr,
  95        NULL,
  96};
  97
  98static const struct attribute_group cca_card_attr_group = {
  99        .attrs = cca_card_attrs,
 100};
 101
 102/*
 103 * CCA queue addditional device attributes
 104 */
 105static ssize_t mkvps_show(struct device *dev,
 106                          struct device_attribute *attr,
 107                          char *buf)
 108{
 109        int n = 0;
 110        struct cca_info ci;
 111        struct zcrypt_queue *zq = to_ap_queue(dev)->private;
 112        static const char * const cao_state[] = { "invalid", "valid" };
 113        static const char * const new_state[] = { "empty", "partial", "full" };
 114
 115        memset(&ci, 0, sizeof(ci));
 116
 117        cca_get_info(AP_QID_CARD(zq->queue->qid),
 118                     AP_QID_QUEUE(zq->queue->qid),
 119                     &ci, zq->online);
 120
 121        if (ci.new_mk_state >= '1' && ci.new_mk_state <= '3')
 122                n = snprintf(buf, PAGE_SIZE, "AES NEW: %s 0x%016llx\n",
 123                             new_state[ci.new_mk_state - '1'], ci.new_mkvp);
 124        else
 125                n = snprintf(buf, PAGE_SIZE, "AES NEW: - -\n");
 126
 127        if (ci.cur_mk_state >= '1' && ci.cur_mk_state <= '2')
 128                n += snprintf(buf + n, PAGE_SIZE - n, "AES CUR: %s 0x%016llx\n",
 129                              cao_state[ci.cur_mk_state - '1'], ci.cur_mkvp);
 130        else
 131                n += snprintf(buf + n, PAGE_SIZE - n, "AES CUR: - -\n");
 132
 133        if (ci.old_mk_state >= '1' && ci.old_mk_state <= '2')
 134                n += snprintf(buf + n, PAGE_SIZE - n, "AES OLD: %s 0x%016llx\n",
 135                              cao_state[ci.old_mk_state - '1'], ci.old_mkvp);
 136        else
 137                n += snprintf(buf + n, PAGE_SIZE - n, "AES OLD: - -\n");
 138
 139        return n;
 140}
 141static DEVICE_ATTR_RO(mkvps);
 142
 143static struct attribute *cca_queue_attrs[] = {
 144        &dev_attr_mkvps.attr,
 145        NULL,
 146};
 147
 148static const struct attribute_group cca_queue_attr_group = {
 149        .attrs = cca_queue_attrs,
 150};
 151
 152/**
 153 * Probe function for CEX4/CEX5/CEX6/CEX7 card device. It always
 154 * accepts the AP device since the bus_match already checked
 155 * the hardware type.
 156 * @ap_dev: pointer to the AP device.
 157 */
 158static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
 159{
 160        /*
 161         * Normalized speed ratings per crypto adapter
 162         * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
 163         */
 164        static const int CEX4A_SPEED_IDX[] = {
 165                 14,  19, 249, 42, 228, 1458, 0, 0};
 166        static const int CEX5A_SPEED_IDX[] = {
 167                  8,   9,  20, 18,  66,  458, 0, 0};
 168        static const int CEX6A_SPEED_IDX[] = {
 169                  6,   9,  20, 17,  65,  438, 0, 0};
 170        static const int CEX7A_SPEED_IDX[] = {
 171                  6,   8,  17, 15,  54,  362, 0, 0};
 172
 173        static const int CEX4C_SPEED_IDX[] = {
 174                 59,  69, 308, 83, 278, 2204, 209, 40};
 175        static const int CEX5C_SPEED_IDX[] = {
 176                 24,  31,  50, 37,  90,  479,  27, 10};
 177        static const int CEX6C_SPEED_IDX[] = {
 178                 16,  20,  32, 27,  77,  455,  24,  9};
 179        static const int CEX7C_SPEED_IDX[] = {
 180                 14,  16,  26, 23,  64,  376,  23,  8};
 181
 182        static const int CEX4P_SPEED_IDX[] = {
 183                  0,   0,   0,   0,   0,   0,   0,  50};
 184        static const int CEX5P_SPEED_IDX[] = {
 185                  0,   0,   0,   0,   0,   0,   0,  10};
 186        static const int CEX6P_SPEED_IDX[] = {
 187                  0,   0,   0,   0,   0,   0,   0,   9};
 188        static const int CEX7P_SPEED_IDX[] = {
 189                  0,   0,   0,   0,   0,   0,   0,   8};
 190
 191        struct ap_card *ac = to_ap_card(&ap_dev->device);
 192        struct zcrypt_card *zc;
 193        int rc = 0;
 194
 195        zc = zcrypt_card_alloc();
 196        if (!zc)
 197                return -ENOMEM;
 198        zc->card = ac;
 199        ac->private = zc;
 200        if (ap_test_bit(&ac->functions, AP_FUNC_ACCEL)) {
 201                if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
 202                        zc->type_string = "CEX4A";
 203                        zc->user_space_type = ZCRYPT_CEX4;
 204                        memcpy(zc->speed_rating, CEX4A_SPEED_IDX,
 205                               sizeof(CEX4A_SPEED_IDX));
 206                } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
 207                        zc->type_string = "CEX5A";
 208                        zc->user_space_type = ZCRYPT_CEX5;
 209                        memcpy(zc->speed_rating, CEX5A_SPEED_IDX,
 210                               sizeof(CEX5A_SPEED_IDX));
 211                } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
 212                        zc->type_string = "CEX6A";
 213                        zc->user_space_type = ZCRYPT_CEX6;
 214                        memcpy(zc->speed_rating, CEX6A_SPEED_IDX,
 215                               sizeof(CEX6A_SPEED_IDX));
 216                } else {
 217                        zc->type_string = "CEX7A";
 218                        /* wrong user space type, just for compatibility
 219                         * with the ZCRYPT_STATUS_MASK ioctl.
 220                         */
 221                        zc->user_space_type = ZCRYPT_CEX6;
 222                        memcpy(zc->speed_rating, CEX7A_SPEED_IDX,
 223                               sizeof(CEX7A_SPEED_IDX));
 224                }
 225                zc->min_mod_size = CEX4A_MIN_MOD_SIZE;
 226                if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) &&
 227                    ap_test_bit(&ac->functions, AP_FUNC_CRT4K)) {
 228                        zc->max_mod_size = CEX4A_MAX_MOD_SIZE_4K;
 229                        zc->max_exp_bit_length =
 230                                CEX4A_MAX_MOD_SIZE_4K;
 231                } else {
 232                        zc->max_mod_size = CEX4A_MAX_MOD_SIZE_2K;
 233                        zc->max_exp_bit_length =
 234                                CEX4A_MAX_MOD_SIZE_2K;
 235                }
 236        } else if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) {
 237                if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
 238                        zc->type_string = "CEX4C";
 239                        /* wrong user space type, must be CEX4
 240                         * just keep it for cca compatibility
 241                         */
 242                        zc->user_space_type = ZCRYPT_CEX3C;
 243                        memcpy(zc->speed_rating, CEX4C_SPEED_IDX,
 244                               sizeof(CEX4C_SPEED_IDX));
 245                } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
 246                        zc->type_string = "CEX5C";
 247                        /* wrong user space type, must be CEX5
 248                         * just keep it for cca compatibility
 249                         */
 250                        zc->user_space_type = ZCRYPT_CEX3C;
 251                        memcpy(zc->speed_rating, CEX5C_SPEED_IDX,
 252                               sizeof(CEX5C_SPEED_IDX));
 253                } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
 254                        zc->type_string = "CEX6C";
 255                        /* wrong user space type, must be CEX6
 256                         * just keep it for cca compatibility
 257                         */
 258                        zc->user_space_type = ZCRYPT_CEX3C;
 259                        memcpy(zc->speed_rating, CEX6C_SPEED_IDX,
 260                               sizeof(CEX6C_SPEED_IDX));
 261                } else {
 262                        zc->type_string = "CEX7C";
 263                        /* wrong user space type, must be CEX7
 264                         * just keep it for cca compatibility
 265                         */
 266                        zc->user_space_type = ZCRYPT_CEX3C;
 267                        memcpy(zc->speed_rating, CEX7C_SPEED_IDX,
 268                               sizeof(CEX7C_SPEED_IDX));
 269                }
 270                zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
 271                zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
 272                zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
 273        } else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) {
 274                if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) {
 275                        zc->type_string = "CEX4P";
 276                        zc->user_space_type = ZCRYPT_CEX4;
 277                        memcpy(zc->speed_rating, CEX4P_SPEED_IDX,
 278                               sizeof(CEX4P_SPEED_IDX));
 279                } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) {
 280                        zc->type_string = "CEX5P";
 281                        zc->user_space_type = ZCRYPT_CEX5;
 282                        memcpy(zc->speed_rating, CEX5P_SPEED_IDX,
 283                               sizeof(CEX5P_SPEED_IDX));
 284                } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) {
 285                        zc->type_string = "CEX6P";
 286                        zc->user_space_type = ZCRYPT_CEX6;
 287                        memcpy(zc->speed_rating, CEX6P_SPEED_IDX,
 288                               sizeof(CEX6P_SPEED_IDX));
 289                } else {
 290                        zc->type_string = "CEX7P";
 291                        /* wrong user space type, just for compatibility
 292                         * with the ZCRYPT_STATUS_MASK ioctl.
 293                         */
 294                        zc->user_space_type = ZCRYPT_CEX6;
 295                        memcpy(zc->speed_rating, CEX7P_SPEED_IDX,
 296                               sizeof(CEX7P_SPEED_IDX));
 297                }
 298                zc->min_mod_size = CEX4C_MIN_MOD_SIZE;
 299                zc->max_mod_size = CEX4C_MAX_MOD_SIZE;
 300                zc->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
 301        } else {
 302                zcrypt_card_free(zc);
 303                return -ENODEV;
 304        }
 305        zc->online = 1;
 306
 307        rc = zcrypt_card_register(zc);
 308        if (rc) {
 309                ac->private = NULL;
 310                zcrypt_card_free(zc);
 311                goto out;
 312        }
 313
 314        if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) {
 315                rc = sysfs_create_group(&ap_dev->device.kobj,
 316                                        &cca_card_attr_group);
 317                if (rc)
 318                        zcrypt_card_unregister(zc);
 319        }
 320
 321out:
 322        return rc;
 323}
 324
 325/**
 326 * This is called to remove the CEX4/CEX5/CEX6/CEX7 card driver
 327 * information if an AP card device is removed.
 328 */
 329static void zcrypt_cex4_card_remove(struct ap_device *ap_dev)
 330{
 331        struct ap_card *ac = to_ap_card(&ap_dev->device);
 332        struct zcrypt_card *zc = ac->private;
 333
 334        if (ap_test_bit(&ac->functions, AP_FUNC_COPRO))
 335                sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_group);
 336        if (zc)
 337                zcrypt_card_unregister(zc);
 338}
 339
 340static struct ap_driver zcrypt_cex4_card_driver = {
 341        .probe = zcrypt_cex4_card_probe,
 342        .remove = zcrypt_cex4_card_remove,
 343        .ids = zcrypt_cex4_card_ids,
 344        .flags = AP_DRIVER_FLAG_DEFAULT,
 345};
 346
 347/**
 348 * Probe function for CEX4/CEX5/CEX6/CEX7 queue device. It always
 349 * accepts the AP device since the bus_match already checked
 350 * the hardware type.
 351 * @ap_dev: pointer to the AP device.
 352 */
 353static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev)
 354{
 355        struct ap_queue *aq = to_ap_queue(&ap_dev->device);
 356        struct zcrypt_queue *zq;
 357        int rc;
 358
 359        if (ap_test_bit(&aq->card->functions, AP_FUNC_ACCEL)) {
 360                zq = zcrypt_queue_alloc(CEX4A_MAX_MESSAGE_SIZE);
 361                if (!zq)
 362                        return -ENOMEM;
 363                zq->ops = zcrypt_msgtype(MSGTYPE50_NAME,
 364                                         MSGTYPE50_VARIANT_DEFAULT);
 365        } else if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) {
 366                zq = zcrypt_queue_alloc(CEX4C_MAX_MESSAGE_SIZE);
 367                if (!zq)
 368                        return -ENOMEM;
 369                zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
 370                                         MSGTYPE06_VARIANT_DEFAULT);
 371        } else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) {
 372                zq = zcrypt_queue_alloc(CEX4C_MAX_MESSAGE_SIZE);
 373                if (!zq)
 374                        return -ENOMEM;
 375                zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
 376                                         MSGTYPE06_VARIANT_EP11);
 377        } else {
 378                return -ENODEV;
 379        }
 380
 381        zq->queue = aq;
 382        zq->online = 1;
 383        atomic_set(&zq->load, 0);
 384        ap_queue_init_reply(aq, &zq->reply);
 385        aq->request_timeout = CEX4_CLEANUP_TIME,
 386        aq->private = zq;
 387        rc = zcrypt_queue_register(zq);
 388        if (rc) {
 389                aq->private = NULL;
 390                zcrypt_queue_free(zq);
 391                goto out;
 392        }
 393
 394        if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) {
 395                rc = sysfs_create_group(&ap_dev->device.kobj,
 396                                        &cca_queue_attr_group);
 397                if (rc)
 398                        zcrypt_queue_unregister(zq);
 399        }
 400
 401out:
 402        return rc;
 403}
 404
 405/**
 406 * This is called to remove the CEX4/CEX5/CEX6/CEX7 queue driver
 407 * information if an AP queue device is removed.
 408 */
 409static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)
 410{
 411        struct ap_queue *aq = to_ap_queue(&ap_dev->device);
 412        struct zcrypt_queue *zq = aq->private;
 413
 414        if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO))
 415                sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_group);
 416        if (zq)
 417                zcrypt_queue_unregister(zq);
 418}
 419
 420static struct ap_driver zcrypt_cex4_queue_driver = {
 421        .probe = zcrypt_cex4_queue_probe,
 422        .remove = zcrypt_cex4_queue_remove,
 423        .suspend = ap_queue_suspend,
 424        .resume = ap_queue_resume,
 425        .ids = zcrypt_cex4_queue_ids,
 426        .flags = AP_DRIVER_FLAG_DEFAULT,
 427};
 428
 429int __init zcrypt_cex4_init(void)
 430{
 431        int rc;
 432
 433        rc = ap_driver_register(&zcrypt_cex4_card_driver,
 434                                THIS_MODULE, "cex4card");
 435        if (rc)
 436                return rc;
 437
 438        rc = ap_driver_register(&zcrypt_cex4_queue_driver,
 439                                THIS_MODULE, "cex4queue");
 440        if (rc)
 441                ap_driver_unregister(&zcrypt_cex4_card_driver);
 442
 443        return rc;
 444}
 445
 446void __exit zcrypt_cex4_exit(void)
 447{
 448        ap_driver_unregister(&zcrypt_cex4_queue_driver);
 449        ap_driver_unregister(&zcrypt_cex4_card_driver);
 450}
 451
 452module_init(zcrypt_cex4_init);
 453module_exit(zcrypt_cex4_exit);
 454