cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

zcrypt_queue.c (5531B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 *  Copyright IBM Corp. 2001, 2012
      4 *  Author(s): Robert Burroughs
      5 *	       Eric Rossman (edrossma@us.ibm.com)
      6 *	       Cornelia Huck <cornelia.huck@de.ibm.com>
      7 *
      8 *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
      9 *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
     10 *				  Ralph Wuerthner <rwuerthn@de.ibm.com>
     11 *  MSGTYPE restruct:		  Holger Dengler <hd@linux.vnet.ibm.com>
     12 */
     13
     14#include <linux/module.h>
     15#include <linux/init.h>
     16#include <linux/interrupt.h>
     17#include <linux/miscdevice.h>
     18#include <linux/fs.h>
     19#include <linux/proc_fs.h>
     20#include <linux/seq_file.h>
     21#include <linux/compat.h>
     22#include <linux/slab.h>
     23#include <linux/atomic.h>
     24#include <linux/uaccess.h>
     25#include <linux/hw_random.h>
     26#include <linux/debugfs.h>
     27#include <asm/debug.h>
     28
     29#include "zcrypt_debug.h"
     30#include "zcrypt_api.h"
     31
     32#include "zcrypt_msgtype6.h"
     33#include "zcrypt_msgtype50.h"
     34
     35/*
     36 * Device attributes common for all crypto queue devices.
     37 */
     38
     39static ssize_t online_show(struct device *dev,
     40			   struct device_attribute *attr,
     41			   char *buf)
     42{
     43	struct zcrypt_queue *zq = dev_get_drvdata(dev);
     44	struct ap_queue *aq = to_ap_queue(dev);
     45	int online = aq->config && zq->online ? 1 : 0;
     46
     47	return scnprintf(buf, PAGE_SIZE, "%d\n", online);
     48}
     49
     50static ssize_t online_store(struct device *dev,
     51			    struct device_attribute *attr,
     52			    const char *buf, size_t count)
     53{
     54	struct zcrypt_queue *zq = dev_get_drvdata(dev);
     55	struct ap_queue *aq = to_ap_queue(dev);
     56	struct zcrypt_card *zc = zq->zcard;
     57	int online;
     58
     59	if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1)
     60		return -EINVAL;
     61
     62	if (online && (!aq->config || !aq->card->config))
     63		return -ENODEV;
     64	if (online && !zc->online)
     65		return -EINVAL;
     66	zq->online = online;
     67
     68	ZCRYPT_DBF_INFO("%s queue=%02x.%04x online=%d\n",
     69			__func__, AP_QID_CARD(zq->queue->qid),
     70			AP_QID_QUEUE(zq->queue->qid), online);
     71
     72	ap_send_online_uevent(&aq->ap_dev, online);
     73
     74	if (!online)
     75		ap_flush_queue(zq->queue);
     76	return count;
     77}
     78
     79static DEVICE_ATTR_RW(online);
     80
     81static ssize_t load_show(struct device *dev,
     82			 struct device_attribute *attr,
     83			 char *buf)
     84{
     85	struct zcrypt_queue *zq = dev_get_drvdata(dev);
     86
     87	return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zq->load));
     88}
     89
     90static DEVICE_ATTR_RO(load);
     91
     92static struct attribute *zcrypt_queue_attrs[] = {
     93	&dev_attr_online.attr,
     94	&dev_attr_load.attr,
     95	NULL,
     96};
     97
     98static const struct attribute_group zcrypt_queue_attr_group = {
     99	.attrs = zcrypt_queue_attrs,
    100};
    101
    102bool zcrypt_queue_force_online(struct zcrypt_queue *zq, int online)
    103{
    104	if (!!zq->online != !!online) {
    105		zq->online = online;
    106		if (!online)
    107			ap_flush_queue(zq->queue);
    108		return true;
    109	}
    110	return false;
    111}
    112
    113struct zcrypt_queue *zcrypt_queue_alloc(size_t reply_buf_size)
    114{
    115	struct zcrypt_queue *zq;
    116
    117	zq = kzalloc(sizeof(*zq), GFP_KERNEL);
    118	if (!zq)
    119		return NULL;
    120	zq->reply.msg = kmalloc(reply_buf_size, GFP_KERNEL);
    121	if (!zq->reply.msg)
    122		goto out_free;
    123	zq->reply.bufsize = reply_buf_size;
    124	INIT_LIST_HEAD(&zq->list);
    125	kref_init(&zq->refcount);
    126	return zq;
    127
    128out_free:
    129	kfree(zq);
    130	return NULL;
    131}
    132EXPORT_SYMBOL(zcrypt_queue_alloc);
    133
    134void zcrypt_queue_free(struct zcrypt_queue *zq)
    135{
    136	kfree(zq->reply.msg);
    137	kfree(zq);
    138}
    139EXPORT_SYMBOL(zcrypt_queue_free);
    140
    141static void zcrypt_queue_release(struct kref *kref)
    142{
    143	struct zcrypt_queue *zq =
    144		container_of(kref, struct zcrypt_queue, refcount);
    145	zcrypt_queue_free(zq);
    146}
    147
    148void zcrypt_queue_get(struct zcrypt_queue *zq)
    149{
    150	kref_get(&zq->refcount);
    151}
    152EXPORT_SYMBOL(zcrypt_queue_get);
    153
    154int zcrypt_queue_put(struct zcrypt_queue *zq)
    155{
    156	return kref_put(&zq->refcount, zcrypt_queue_release);
    157}
    158EXPORT_SYMBOL(zcrypt_queue_put);
    159
    160/**
    161 * zcrypt_queue_register() - Register a crypto queue device.
    162 * @zq: Pointer to a crypto queue device
    163 *
    164 * Register a crypto queue device. Returns 0 if successful.
    165 */
    166int zcrypt_queue_register(struct zcrypt_queue *zq)
    167{
    168	struct zcrypt_card *zc;
    169	int rc;
    170
    171	spin_lock(&zcrypt_list_lock);
    172	zc = dev_get_drvdata(&zq->queue->card->ap_dev.device);
    173	zcrypt_card_get(zc);
    174	zq->zcard = zc;
    175	zq->online = 1;	/* New devices are online by default. */
    176
    177	ZCRYPT_DBF_INFO("%s queue=%02x.%04x register online=1\n",
    178			__func__, AP_QID_CARD(zq->queue->qid),
    179			AP_QID_QUEUE(zq->queue->qid));
    180
    181	list_add_tail(&zq->list, &zc->zqueues);
    182	spin_unlock(&zcrypt_list_lock);
    183
    184	rc = sysfs_create_group(&zq->queue->ap_dev.device.kobj,
    185				&zcrypt_queue_attr_group);
    186	if (rc)
    187		goto out;
    188
    189	if (zq->ops->rng) {
    190		rc = zcrypt_rng_device_add();
    191		if (rc)
    192			goto out_unregister;
    193	}
    194	return 0;
    195
    196out_unregister:
    197	sysfs_remove_group(&zq->queue->ap_dev.device.kobj,
    198			   &zcrypt_queue_attr_group);
    199out:
    200	spin_lock(&zcrypt_list_lock);
    201	list_del_init(&zq->list);
    202	spin_unlock(&zcrypt_list_lock);
    203	zcrypt_card_put(zc);
    204	return rc;
    205}
    206EXPORT_SYMBOL(zcrypt_queue_register);
    207
    208/**
    209 * zcrypt_queue_unregister(): Unregister a crypto queue device.
    210 * @zq: Pointer to crypto queue device
    211 *
    212 * Unregister a crypto queue device.
    213 */
    214void zcrypt_queue_unregister(struct zcrypt_queue *zq)
    215{
    216	struct zcrypt_card *zc;
    217
    218	ZCRYPT_DBF_INFO("%s queue=%02x.%04x unregister\n",
    219			__func__, AP_QID_CARD(zq->queue->qid),
    220			AP_QID_QUEUE(zq->queue->qid));
    221
    222	zc = zq->zcard;
    223	spin_lock(&zcrypt_list_lock);
    224	list_del_init(&zq->list);
    225	spin_unlock(&zcrypt_list_lock);
    226	if (zq->ops->rng)
    227		zcrypt_rng_device_remove();
    228	sysfs_remove_group(&zq->queue->ap_dev.device.kobj,
    229			   &zcrypt_queue_attr_group);
    230	zcrypt_card_put(zc);
    231	zcrypt_queue_put(zq);
    232}
    233EXPORT_SYMBOL(zcrypt_queue_unregister);