OpenCloudOS-Kernel/drivers/s390/crypto/zcrypt_api.c

2294 lines
59 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0+
/*
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
* Copyright IBM Corp. 2001, 2018
* Author(s): Robert Burroughs
* Eric Rossman (edrossma@us.ibm.com)
* Cornelia Huck <cornelia.huck@de.ibm.com>
*
* Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
* Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
* Ralph Wuerthner <rwuerthn@de.ibm.com>
* MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com>
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
* Multiple device nodes: Harald Freudenberger <freude@linux.ibm.com>
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/compat.h>
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h percpu.h is included by sched.h and module.h and thus ends up being included when building most .c files. percpu.h includes slab.h which in turn includes gfp.h making everything defined by the two files universally available and complicating inclusion dependencies. percpu.h -> slab.h dependency is about to be removed. Prepare for this change by updating users of gfp and slab facilities include those headers directly instead of assuming availability. As this conversion needs to touch large number of source files, the following script is used as the basis of conversion. http://userweb.kernel.org/~tj/misc/slabh-sweep.py The script does the followings. * Scan files for gfp and slab usages and update includes such that only the necessary includes are there. ie. if only gfp is used, gfp.h, if slab is used, slab.h. * When the script inserts a new include, it looks at the include blocks and try to put the new include such that its order conforms to its surrounding. It's put in the include block which contains core kernel includes, in the same order that the rest are ordered - alphabetical, Christmas tree, rev-Xmas-tree or at the end if there doesn't seem to be any matching order. * If the script can't find a place to put a new include (mostly because the file doesn't have fitting include block), it prints out an error message indicating which .h file needs to be added to the file. The conversion was done in the following steps. 1. The initial automatic conversion of all .c files updated slightly over 4000 files, deleting around 700 includes and adding ~480 gfp.h and ~3000 slab.h inclusions. The script emitted errors for ~400 files. 2. Each error was manually checked. Some didn't need the inclusion, some needed manual addition while adding it to implementation .h or embedding .c file was more appropriate for others. This step added inclusions to around 150 files. 3. The script was run again and the output was compared to the edits from #2 to make sure no file was left behind. 4. Several build tests were done and a couple of problems were fixed. e.g. lib/decompress_*.c used malloc/free() wrappers around slab APIs requiring slab.h to be added manually. 5. The script was run on all .h files but without automatically editing them as sprinkling gfp.h and slab.h inclusions around .h files could easily lead to inclusion dependency hell. Most gfp.h inclusion directives were ignored as stuff from gfp.h was usually wildly available and often used in preprocessor macros. Each slab.h inclusion directive was examined and added manually as necessary. 6. percpu.h was updated not to include slab.h. 7. Build test were done on the following configurations and failures were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my distributed build env didn't work with gcov compiles) and a few more options had to be turned off depending on archs to make things build (like ipr on powerpc/64 which failed due to missing writeq). * x86 and x86_64 UP and SMP allmodconfig and a custom test config. * powerpc and powerpc64 SMP allmodconfig * sparc and sparc64 SMP allmodconfig * ia64 SMP allmodconfig * s390 SMP allmodconfig * alpha SMP allmodconfig * um on x86_64 SMP allmodconfig 8. percpu.h modifications were reverted so that it could be applied as a separate patch and serve as bisection point. Given the fact that I had only a couple of failures from tests on step 6, I'm fairly confident about the coverage of this conversion patch. If there is a breakage, it's likely to be something in one of the arch headers which should be easily discoverable easily on most builds of the specific arch. Signed-off-by: Tejun Heo <tj@kernel.org> Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 16:04:11 +08:00
#include <linux/slab.h>
#include <linux/atomic.h>
#include <linux/uaccess.h>
#include <linux/hw_random.h>
#include <linux/debugfs.h>
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
#include <linux/cdev.h>
#include <linux/ctype.h>
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#include <linux/capability.h>
#include <asm/debug.h>
#define CREATE_TRACE_POINTS
#include <asm/trace/zcrypt.h>
#include "zcrypt_api.h"
#include "zcrypt_debug.h"
#include "zcrypt_msgtype6.h"
#include "zcrypt_msgtype50.h"
#include "zcrypt_ccamisc.h"
#include "zcrypt_ep11misc.h"
/*
* Module description.
*/
MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("Cryptographic Coprocessor interface, " \
"Copyright IBM Corp. 2001, 2012");
MODULE_LICENSE("GPL");
/*
* zcrypt tracepoint functions
*/
EXPORT_TRACEPOINT_SYMBOL(s390_zcrypt_req);
EXPORT_TRACEPOINT_SYMBOL(s390_zcrypt_rep);
static int zcrypt_hwrng_seed = 1;
module_param_named(hwrng_seed, zcrypt_hwrng_seed, int, 0440);
MODULE_PARM_DESC(hwrng_seed, "Turn on/off hwrng auto seed, default is 1 (on).");
DEFINE_SPINLOCK(zcrypt_list_lock);
LIST_HEAD(zcrypt_card_list);
static atomic_t zcrypt_open_count = ATOMIC_INIT(0);
static atomic_t zcrypt_rescan_count = ATOMIC_INIT(0);
atomic_t zcrypt_rescan_req = ATOMIC_INIT(0);
EXPORT_SYMBOL(zcrypt_rescan_req);
static LIST_HEAD(zcrypt_ops_list);
/* Zcrypt related debug feature stuff. */
debug_info_t *zcrypt_dbf_info;
/*
* Process a rescan of the transport layer.
*
* Returns 1, if the rescan has been processed, otherwise 0.
*/
static inline int zcrypt_process_rescan(void)
{
if (atomic_read(&zcrypt_rescan_req)) {
atomic_set(&zcrypt_rescan_req, 0);
atomic_inc(&zcrypt_rescan_count);
ap_bus_force_rescan();
ZCRYPT_DBF_INFO("%s rescan count=%07d\n", __func__,
atomic_inc_return(&zcrypt_rescan_count));
return 1;
}
return 0;
}
void zcrypt_msgtype_register(struct zcrypt_ops *zops)
{
s390/zcrypt: Fix initialisation when zcrypt is built-in ap_bus and zcrypt_api assumed module information to always be present and initialisation to be done in module loading order (symbol dependencies). These assumptions don't hold if zcrypt is built-in; THIS_MODULE will be NULL in this case and init call order is linker order, i.e. Makefile order. Fix initialisation order by ordering the object files in the Makefile according to their dependencies, like the module loader would do. Fix message type registration by using a dedicated "name" field rather than piggy-backing on the module ("owner") information. There's no change to the requirement that module name and msgtype name are identical. The existing name macros are used. We don't need any special code for dealing with the drivers being built-in; the generic module support code already does the right thing. Test results: 1. CONFIG_MODULES=y, CONFIG_ZCRYPT=y KVM: boots, no /sys/bus/ap (expected) LPAR with CEX5: boots, /sys/bus/ap/devices/card*/type present 2. CONFIG_MODULES=y, CONFIG_ZCRYPT=m=: KVM: boots, loading zcrypt_cex4 (and ap) fails (expected) LPAR with CEX5: boots, loading =zcrypt_cex4= succeeds, /sys/bus/ap/devices/card*/type present after explicit module loading 3. CONFIG_MODULES unset, CONFIG_ZCRYPT=y: KVM: boots, no /sys/bus/ap (expected) LPAR with CEX5: boots, /sys/bus/ap/devices/card*/type present No further testing (user-space functionality) was done. Fixes: 3b6245fd303f ("s390/zcrypt: Separate msgtype implementation from card modules.") Signed-off-by: Sascha Silbe <silbe@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2015-10-28 18:06:08 +08:00
list_add_tail(&zops->list, &zcrypt_ops_list);
}
void zcrypt_msgtype_unregister(struct zcrypt_ops *zops)
{
list_del_init(&zops->list);
}
struct zcrypt_ops *zcrypt_msgtype(unsigned char *name, int variant)
{
struct zcrypt_ops *zops;
list_for_each_entry(zops, &zcrypt_ops_list, list)
if (zops->variant == variant &&
(!strncmp(zops->name, name, sizeof(zops->name))))
return zops;
return NULL;
}
EXPORT_SYMBOL(zcrypt_msgtype);
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
/*
* Multi device nodes extension functions.
*/
#ifdef CONFIG_ZCRYPT_MULTIDEVNODES
struct zcdn_device;
static struct class *zcrypt_class;
static dev_t zcrypt_devt;
static struct cdev zcrypt_cdev;
struct zcdn_device {
struct device device;
struct ap_perms perms;
};
#define to_zcdn_dev(x) container_of((x), struct zcdn_device, device)
#define ZCDN_MAX_NAME 32
static int zcdn_create(const char *name);
static int zcdn_destroy(const char *name);
/*
* Find zcdn device by name.
* Returns reference to the zcdn device which needs to be released
* with put_device() after use.
*/
static inline struct zcdn_device *find_zcdndev_by_name(const char *name)
{
struct device *dev = class_find_device_by_name(zcrypt_class, name);
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
return dev ? to_zcdn_dev(dev) : NULL;
}
/*
* Find zcdn device by devt value.
* Returns reference to the zcdn device which needs to be released
* with put_device() after use.
*/
static inline struct zcdn_device *find_zcdndev_by_devt(dev_t devt)
{
struct device *dev = class_find_device_by_devt(zcrypt_class, devt);
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
return dev ? to_zcdn_dev(dev) : NULL;
}
static ssize_t ioctlmask_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int i, rc;
struct zcdn_device *zcdndev = to_zcdn_dev(dev);
if (mutex_lock_interruptible(&ap_perms_mutex))
return -ERESTARTSYS;
buf[0] = '0';
buf[1] = 'x';
for (i = 0; i < sizeof(zcdndev->perms.ioctlm) / sizeof(long); i++)
snprintf(buf + 2 + 2 * i * sizeof(long),
PAGE_SIZE - 2 - 2 * i * sizeof(long),
"%016lx", zcdndev->perms.ioctlm[i]);
buf[2 + 2 * i * sizeof(long)] = '\n';
buf[2 + 2 * i * sizeof(long) + 1] = '\0';
rc = 2 + 2 * i * sizeof(long) + 1;
mutex_unlock(&ap_perms_mutex);
return rc;
}
static ssize_t ioctlmask_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int rc;
struct zcdn_device *zcdndev = to_zcdn_dev(dev);
rc = ap_parse_mask_str(buf, zcdndev->perms.ioctlm,
AP_IOCTLS, &ap_perms_mutex);
if (rc)
return rc;
return count;
}
static DEVICE_ATTR_RW(ioctlmask);
static ssize_t apmask_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int i, rc;
struct zcdn_device *zcdndev = to_zcdn_dev(dev);
if (mutex_lock_interruptible(&ap_perms_mutex))
return -ERESTARTSYS;
buf[0] = '0';
buf[1] = 'x';
for (i = 0; i < sizeof(zcdndev->perms.apm) / sizeof(long); i++)
snprintf(buf + 2 + 2 * i * sizeof(long),
PAGE_SIZE - 2 - 2 * i * sizeof(long),
"%016lx", zcdndev->perms.apm[i]);
buf[2 + 2 * i * sizeof(long)] = '\n';
buf[2 + 2 * i * sizeof(long) + 1] = '\0';
rc = 2 + 2 * i * sizeof(long) + 1;
mutex_unlock(&ap_perms_mutex);
return rc;
}
static ssize_t apmask_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int rc;
struct zcdn_device *zcdndev = to_zcdn_dev(dev);
rc = ap_parse_mask_str(buf, zcdndev->perms.apm,
AP_DEVICES, &ap_perms_mutex);
if (rc)
return rc;
return count;
}
static DEVICE_ATTR_RW(apmask);
static ssize_t aqmask_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int i, rc;
struct zcdn_device *zcdndev = to_zcdn_dev(dev);
if (mutex_lock_interruptible(&ap_perms_mutex))
return -ERESTARTSYS;
buf[0] = '0';
buf[1] = 'x';
for (i = 0; i < sizeof(zcdndev->perms.aqm) / sizeof(long); i++)
snprintf(buf + 2 + 2 * i * sizeof(long),
PAGE_SIZE - 2 - 2 * i * sizeof(long),
"%016lx", zcdndev->perms.aqm[i]);
buf[2 + 2 * i * sizeof(long)] = '\n';
buf[2 + 2 * i * sizeof(long) + 1] = '\0';
rc = 2 + 2 * i * sizeof(long) + 1;
mutex_unlock(&ap_perms_mutex);
return rc;
}
static ssize_t aqmask_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int rc;
struct zcdn_device *zcdndev = to_zcdn_dev(dev);
rc = ap_parse_mask_str(buf, zcdndev->perms.aqm,
AP_DOMAINS, &ap_perms_mutex);
if (rc)
return rc;
return count;
}
static DEVICE_ATTR_RW(aqmask);
static ssize_t admask_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int i, rc;
struct zcdn_device *zcdndev = to_zcdn_dev(dev);
if (mutex_lock_interruptible(&ap_perms_mutex))
return -ERESTARTSYS;
buf[0] = '0';
buf[1] = 'x';
for (i = 0; i < sizeof(zcdndev->perms.adm) / sizeof(long); i++)
snprintf(buf + 2 + 2 * i * sizeof(long),
PAGE_SIZE - 2 - 2 * i * sizeof(long),
"%016lx", zcdndev->perms.adm[i]);
buf[2 + 2 * i * sizeof(long)] = '\n';
buf[2 + 2 * i * sizeof(long) + 1] = '\0';
rc = 2 + 2 * i * sizeof(long) + 1;
mutex_unlock(&ap_perms_mutex);
return rc;
}
static ssize_t admask_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int rc;
struct zcdn_device *zcdndev = to_zcdn_dev(dev);
rc = ap_parse_mask_str(buf, zcdndev->perms.adm,
AP_DOMAINS, &ap_perms_mutex);
if (rc)
return rc;
return count;
}
static DEVICE_ATTR_RW(admask);
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
static struct attribute *zcdn_dev_attrs[] = {
&dev_attr_ioctlmask.attr,
&dev_attr_apmask.attr,
&dev_attr_aqmask.attr,
&dev_attr_admask.attr,
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
NULL
};
static struct attribute_group zcdn_dev_attr_group = {
.attrs = zcdn_dev_attrs
};
static const struct attribute_group *zcdn_dev_attr_groups[] = {
&zcdn_dev_attr_group,
NULL
};
static ssize_t zcdn_create_store(struct class *class,
struct class_attribute *attr,
const char *buf, size_t count)
{
int rc;
char name[ZCDN_MAX_NAME];
strncpy(name, skip_spaces(buf), sizeof(name));
name[sizeof(name) - 1] = '\0';
rc = zcdn_create(strim(name));
return rc ? rc : count;
}
static const struct class_attribute class_attr_zcdn_create =
__ATTR(create, 0600, NULL, zcdn_create_store);
static ssize_t zcdn_destroy_store(struct class *class,
struct class_attribute *attr,
const char *buf, size_t count)
{
int rc;
char name[ZCDN_MAX_NAME];
strncpy(name, skip_spaces(buf), sizeof(name));
name[sizeof(name) - 1] = '\0';
rc = zcdn_destroy(strim(name));
return rc ? rc : count;
}
static const struct class_attribute class_attr_zcdn_destroy =
__ATTR(destroy, 0600, NULL, zcdn_destroy_store);
static void zcdn_device_release(struct device *dev)
{
struct zcdn_device *zcdndev = to_zcdn_dev(dev);
ZCRYPT_DBF_INFO("%s releasing zcdn device %d:%d\n",
__func__, MAJOR(dev->devt), MINOR(dev->devt));
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
kfree(zcdndev);
}
static int zcdn_create(const char *name)
{
dev_t devt;
int i, rc = 0;
char nodename[ZCDN_MAX_NAME];
struct zcdn_device *zcdndev;
if (mutex_lock_interruptible(&ap_perms_mutex))
return -ERESTARTSYS;
/* check if device node with this name already exists */
if (name[0]) {
zcdndev = find_zcdndev_by_name(name);
if (zcdndev) {
put_device(&zcdndev->device);
rc = -EEXIST;
goto unlockout;
}
}
/* find an unused minor number */
for (i = 0; i < ZCRYPT_MAX_MINOR_NODES; i++) {
devt = MKDEV(MAJOR(zcrypt_devt), MINOR(zcrypt_devt) + i);
zcdndev = find_zcdndev_by_devt(devt);
if (zcdndev)
put_device(&zcdndev->device);
else
break;
}
if (i == ZCRYPT_MAX_MINOR_NODES) {
rc = -ENOSPC;
goto unlockout;
}
/* alloc and prepare a new zcdn device */
zcdndev = kzalloc(sizeof(*zcdndev), GFP_KERNEL);
if (!zcdndev) {
rc = -ENOMEM;
goto unlockout;
}
zcdndev->device.release = zcdn_device_release;
zcdndev->device.class = zcrypt_class;
zcdndev->device.devt = devt;
zcdndev->device.groups = zcdn_dev_attr_groups;
if (name[0])
strncpy(nodename, name, sizeof(nodename));
else
snprintf(nodename, sizeof(nodename),
ZCRYPT_NAME "_%d", (int)MINOR(devt));
nodename[sizeof(nodename) - 1] = '\0';
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
if (dev_set_name(&zcdndev->device, nodename)) {
rc = -EINVAL;
goto unlockout;
}
rc = device_register(&zcdndev->device);
if (rc) {
put_device(&zcdndev->device);
goto unlockout;
}
ZCRYPT_DBF_INFO("%s created zcdn device %d:%d\n",
__func__, MAJOR(devt), MINOR(devt));
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
unlockout:
mutex_unlock(&ap_perms_mutex);
return rc;
}
static int zcdn_destroy(const char *name)
{
int rc = 0;
struct zcdn_device *zcdndev;
if (mutex_lock_interruptible(&ap_perms_mutex))
return -ERESTARTSYS;
/* try to find this zcdn device */
zcdndev = find_zcdndev_by_name(name);
if (!zcdndev) {
rc = -ENOENT;
goto unlockout;
}
/*
* The zcdn device is not hard destroyed. It is subject to
* reference counting and thus just needs to be unregistered.
*/
put_device(&zcdndev->device);
device_unregister(&zcdndev->device);
unlockout:
mutex_unlock(&ap_perms_mutex);
return rc;
}
static void zcdn_destroy_all(void)
{
int i;
dev_t devt;
struct zcdn_device *zcdndev;
mutex_lock(&ap_perms_mutex);
for (i = 0; i < ZCRYPT_MAX_MINOR_NODES; i++) {
devt = MKDEV(MAJOR(zcrypt_devt), MINOR(zcrypt_devt) + i);
zcdndev = find_zcdndev_by_devt(devt);
if (zcdndev) {
put_device(&zcdndev->device);
device_unregister(&zcdndev->device);
}
}
mutex_unlock(&ap_perms_mutex);
}
#endif
/*
* zcrypt_read (): Not supported beyond zcrypt 1.3.1.
*
* This function is not supported beyond zcrypt 1.3.1.
*/
static ssize_t zcrypt_read(struct file *filp, char __user *buf,
size_t count, loff_t *f_pos)
{
return -EPERM;
}
/*
* zcrypt_write(): Not allowed.
*
* Write is not allowed
*/
static ssize_t zcrypt_write(struct file *filp, const char __user *buf,
size_t count, loff_t *f_pos)
{
return -EPERM;
}
/*
* zcrypt_open(): Count number of users.
*
* Device open function to count number of users.
*/
static int zcrypt_open(struct inode *inode, struct file *filp)
{
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
struct ap_perms *perms = &ap_perms;
#ifdef CONFIG_ZCRYPT_MULTIDEVNODES
if (filp->f_inode->i_cdev == &zcrypt_cdev) {
struct zcdn_device *zcdndev;
if (mutex_lock_interruptible(&ap_perms_mutex))
return -ERESTARTSYS;
zcdndev = find_zcdndev_by_devt(filp->f_inode->i_rdev);
/* find returns a reference, no get_device() needed */
mutex_unlock(&ap_perms_mutex);
if (zcdndev)
perms = &zcdndev->perms;
}
#endif
filp->private_data = (void *)perms;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
atomic_inc(&zcrypt_open_count);
*: convert stream-like files from nonseekable_open -> stream_open Using scripts/coccinelle/api/stream_open.cocci added in 10dce8af3422 ("fs: stream_open - opener for stream-like files so that read and write can run simultaneously without deadlock"), search and convert to stream_open all in-kernel nonseekable_open users for which read and write actually do not depend on ppos and where there is no other methods in file_operations which assume @offset access. I've verified each generated change manually - that it is correct to convert - and each other nonseekable_open instance left - that it is either not correct to convert there, or that it is not converted due to current stream_open.cocci limitations. The script also does not convert files that should be valid to convert, but that currently have .llseek = noop_llseek or generic_file_llseek for unknown reason despite file being opened with nonseekable_open (e.g. drivers/input/mousedev.c) Among cases converted 14 were potentially vulnerable to read vs write deadlock (see details in 10dce8af3422): drivers/char/pcmcia/cm4000_cs.c:1685:7-23: ERROR: cm4000_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/gnss/core.c:45:1-17: ERROR: gnss_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/hid/uhid.c:635:1-17: ERROR: uhid_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/infiniband/core/user_mad.c:988:1-17: ERROR: umad_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/input/evdev.c:527:1-17: ERROR: evdev_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/input/misc/uinput.c:401:1-17: ERROR: uinput_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/isdn/capi/capi.c:963:8-24: ERROR: capi_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/leds/uleds.c:77:1-17: ERROR: uleds_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/media/rc/lirc_dev.c:198:1-17: ERROR: lirc_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/s390/char/fs3270.c:488:1-17: ERROR: fs3270_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/usb/misc/ldusb.c:310:1-17: ERROR: ld_usb_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. drivers/xen/evtchn.c:667:8-24: ERROR: evtchn_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. net/batman-adv/icmp_socket.c:80:1-17: ERROR: batadv_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. net/rfkill/core.c:1146:8-24: ERROR: rfkill_fops: .read() can deadlock .write(); change nonseekable_open -> stream_open to fix. and the rest were just safe to convert to stream_open because their read and write do not use ppos at all and corresponding file_operations do not have methods that assume @offset file access(*): arch/powerpc/platforms/52xx/mpc52xx_gpt.c:631:8-24: WARNING: mpc52xx_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_ibox_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_ibox_stat_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_mbox_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_mbox_stat_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_wbox_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. arch/powerpc/platforms/cell/spufs/file.c:591:8-24: WARNING: spufs_wbox_stat_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. arch/um/drivers/harddog_kern.c:88:8-24: WARNING: harddog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. arch/x86/kernel/cpu/microcode/core.c:430:33-49: WARNING: microcode_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/char/ds1620.c:215:8-24: WARNING: ds1620_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/char/dtlk.c:301:1-17: WARNING: dtlk_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/char/ipmi/ipmi_watchdog.c:840:9-25: WARNING: ipmi_wdog_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/char/pcmcia/scr24x_cs.c:95:8-24: WARNING: scr24x_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/char/tb0219.c:246:9-25: WARNING: tb0219_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/firewire/nosy.c:306:8-24: WARNING: nosy_ops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/hwmon/fschmd.c:840:8-24: WARNING: watchdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/hwmon/w83793.c:1344:8-24: WARNING: watchdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/infiniband/core/ucma.c:1747:8-24: WARNING: ucma_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/infiniband/core/ucm.c:1178:8-24: WARNING: ucm_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/infiniband/core/uverbs_main.c:1086:8-24: WARNING: uverbs_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/input/joydev.c:282:1-17: WARNING: joydev_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/pci/switch/switchtec.c:393:1-17: WARNING: switchtec_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/platform/chrome/cros_ec_debugfs.c:135:8-24: WARNING: cros_ec_console_log_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/rtc/rtc-ds1374.c:470:9-25: WARNING: ds1374_wdt_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/rtc/rtc-m41t80.c:805:9-25: WARNING: wdt_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/s390/char/tape_char.c:293:2-18: WARNING: tape_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/s390/char/zcore.c:194:8-24: WARNING: zcore_reipl_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/s390/crypto/zcrypt_api.c:528:8-24: WARNING: zcrypt_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/spi/spidev.c:594:1-17: WARNING: spidev_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/staging/pi433/pi433_if.c:974:1-17: WARNING: pi433_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/acquirewdt.c:203:8-24: WARNING: acq_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/advantechwdt.c:202:8-24: WARNING: advwdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/alim1535_wdt.c:252:8-24: WARNING: ali_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/alim7101_wdt.c:217:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/ar7_wdt.c:166:8-24: WARNING: ar7_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/at91rm9200_wdt.c:113:8-24: WARNING: at91wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/ath79_wdt.c:135:8-24: WARNING: ath79_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/bcm63xx_wdt.c:119:8-24: WARNING: bcm63xx_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/cpu5wdt.c:143:8-24: WARNING: cpu5wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/cpwd.c:397:8-24: WARNING: cpwd_fops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/eurotechwdt.c:319:8-24: WARNING: eurwdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/f71808e_wdt.c:528:8-24: WARNING: watchdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/gef_wdt.c:232:8-24: WARNING: gef_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/geodewdt.c:95:8-24: WARNING: geodewdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/ib700wdt.c:241:8-24: WARNING: ibwdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/ibmasr.c:326:8-24: WARNING: asr_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/indydog.c:80:8-24: WARNING: indydog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/intel_scu_watchdog.c:307:8-24: WARNING: intel_scu_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/iop_wdt.c:104:8-24: WARNING: iop_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/it8712f_wdt.c:330:8-24: WARNING: it8712f_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/ixp4xx_wdt.c:68:8-24: WARNING: ixp4xx_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/ks8695_wdt.c:145:8-24: WARNING: ks8695wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/m54xx_wdt.c:88:8-24: WARNING: m54xx_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/machzwd.c:336:8-24: WARNING: zf_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/mixcomwd.c:153:8-24: WARNING: mixcomwd_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/mtx-1_wdt.c:121:8-24: WARNING: mtx1_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/mv64x60_wdt.c:136:8-24: WARNING: mv64x60_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/nuc900_wdt.c:134:8-24: WARNING: nuc900wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/nv_tco.c:164:8-24: WARNING: nv_tco_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/pc87413_wdt.c:289:8-24: WARNING: pc87413_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/pcwd.c:698:8-24: WARNING: pcwd_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/pcwd.c:737:8-24: WARNING: pcwd_temp_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/pcwd_pci.c:581:8-24: WARNING: pcipcwd_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/pcwd_pci.c:623:8-24: WARNING: pcipcwd_temp_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/pcwd_usb.c:488:8-24: WARNING: usb_pcwd_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/pcwd_usb.c:527:8-24: WARNING: usb_pcwd_temperature_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/pika_wdt.c:121:8-24: WARNING: pikawdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/pnx833x_wdt.c:119:8-24: WARNING: pnx833x_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/rc32434_wdt.c:153:8-24: WARNING: rc32434_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/rdc321x_wdt.c:145:8-24: WARNING: rdc321x_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/riowd.c:79:1-17: WARNING: riowd_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/sa1100_wdt.c:62:8-24: WARNING: sa1100dog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/sbc60xxwdt.c:211:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/sbc7240_wdt.c:139:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/sbc8360.c:274:8-24: WARNING: sbc8360_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/sbc_epx_c3.c:81:8-24: WARNING: epx_c3_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/sbc_fitpc2_wdt.c:78:8-24: WARNING: fitpc2_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/sb_wdog.c:108:1-17: WARNING: sbwdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/sc1200wdt.c:181:8-24: WARNING: sc1200wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/sc520_wdt.c:261:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/sch311x_wdt.c:319:8-24: WARNING: sch311x_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/scx200_wdt.c:105:8-24: WARNING: scx200_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/smsc37b787_wdt.c:369:8-24: WARNING: wb_smsc_wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/w83877f_wdt.c:227:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/w83977f_wdt.c:301:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/wafer5823wdt.c:200:8-24: WARNING: wafwdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/watchdog_dev.c:828:8-24: WARNING: watchdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/wdrtas.c:379:8-24: WARNING: wdrtas_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/wdrtas.c:445:8-24: WARNING: wdrtas_temp_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/wdt285.c:104:1-17: WARNING: watchdog_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/wdt977.c:276:8-24: WARNING: wdt977_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/wdt.c:424:8-24: WARNING: wdt_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/wdt.c:484:8-24: WARNING: wdt_temp_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/wdt_pci.c:464:8-24: WARNING: wdtpci_fops: .write() has stream semantic; safe to change nonseekable_open -> stream_open. drivers/watchdog/wdt_pci.c:527:8-24: WARNING: wdtpci_temp_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. net/batman-adv/log.c:105:1-17: WARNING: batadv_log_fops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. sound/core/control.c:57:7-23: WARNING: snd_ctl_f_ops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. sound/core/rawmidi.c:385:7-23: WARNING: snd_rawmidi_f_ops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. sound/core/seq/seq_clientmgr.c:310:7-23: WARNING: snd_seq_f_ops: .read() and .write() have stream semantic; safe to change nonseekable_open -> stream_open. sound/core/timer.c:1428:7-23: WARNING: snd_timer_f_ops: .read() has stream semantic; safe to change nonseekable_open -> stream_open. One can also recheck/review the patch via generating it with explanation comments included via $ make coccicheck MODE=patch COCCI=scripts/coccinelle/api/stream_open.cocci SPFLAGS="-D explain" (*) This second group also contains cases with read/write deadlocks that stream_open.cocci don't yet detect, but which are still valid to convert to stream_open since ppos is not used. For example drivers/pci/switch/switchtec.c calls wait_for_completion_interruptible() in its .read, but stream_open.cocci currently detects only "wait_event*" as blocking. Cc: Michael Kerrisk <mtk.manpages@gmail.com> Cc: Yongzhi Pan <panyongzhi@gmail.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: David Vrabel <david.vrabel@citrix.com> Cc: Juergen Gross <jgross@suse.com> Cc: Miklos Szeredi <miklos@szeredi.hu> Cc: Tejun Heo <tj@kernel.org> Cc: Kirill Tkhai <ktkhai@virtuozzo.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Christoph Hellwig <hch@lst.de> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Julia Lawall <Julia.Lawall@lip6.fr> Cc: Nikolaus Rath <Nikolaus@rath.org> Cc: Han-Wen Nienhuys <hanwen@google.com> Cc: Anatolij Gustschin <agust@denx.de> Cc: Jeff Dike <jdike@addtoit.com> Cc: Richard Weinberger <richard@nod.at> Cc: Anton Ivanov <anton.ivanov@cambridgegreys.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "James R. Van Zandt" <jrv@vanzandt.mv.com> Cc: Corey Minyard <minyard@acm.org> Cc: Harald Welte <laforge@gnumonks.org> Acked-by: Lubomir Rintel <lkundrak@v3.sk> [scr24x_cs] Cc: Stefan Richter <stefanr@s5r6.in-berlin.de> Cc: Johan Hovold <johan@kernel.org> Cc: David Herrmann <dh.herrmann@googlemail.com> Cc: Jiri Kosina <jikos@kernel.org> Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com> Cc: Jean Delvare <jdelvare@suse.com> Acked-by: Guenter Roeck <linux@roeck-us.net> [watchdog/* hwmon/*] Cc: Rudolf Marek <r.marek@assembler.cz> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com> Cc: Karsten Keil <isdn@linux-pingi.de> Cc: Jacek Anaszewski <jacek.anaszewski@gmail.com> Cc: Pavel Machek <pavel@ucw.cz> Cc: Mauro Carvalho Chehab <mchehab@kernel.org> Cc: Kurt Schwemmer <kurt.schwemmer@microsemi.com> Acked-by: Logan Gunthorpe <logang@deltatee.com> [drivers/pci/switch/switchtec] Acked-by: Bjorn Helgaas <bhelgaas@google.com> [drivers/pci/switch/switchtec] Cc: Benson Leung <bleung@chromium.org> Acked-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> [platform/chrome] Cc: Alessandro Zummo <a.zummo@towertech.it> Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com> [rtc/*] Cc: Mark Brown <broonie@kernel.org> Cc: Wim Van Sebroeck <wim@linux-watchdog.org> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: bcm-kernel-feedback-list@broadcom.com Cc: Wan ZongShun <mcuos.com@gmail.com> Cc: Zwane Mwaikambo <zwanem@gmail.com> Cc: Marek Lindner <mareklindner@neomailbox.ch> Cc: Simon Wunderlich <sw@simonwunderlich.de> Cc: Antonio Quartulli <a@unstable.cc> Cc: "David S. Miller" <davem@davemloft.net> Cc: Johannes Berg <johannes@sipsolutions.net> Cc: Jaroslav Kysela <perex@perex.cz> Cc: Takashi Iwai <tiwai@suse.com> Signed-off-by: Kirill Smelkov <kirr@nexedi.com>
2019-03-27 04:51:19 +08:00
return stream_open(inode, filp);
}
/*
* zcrypt_release(): Count number of users.
*
* Device close function to count number of users.
*/
static int zcrypt_release(struct inode *inode, struct file *filp)
{
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
#ifdef CONFIG_ZCRYPT_MULTIDEVNODES
if (filp->f_inode->i_cdev == &zcrypt_cdev) {
struct zcdn_device *zcdndev;
mutex_lock(&ap_perms_mutex);
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
zcdndev = find_zcdndev_by_devt(filp->f_inode->i_rdev);
mutex_unlock(&ap_perms_mutex);
if (zcdndev) {
/* 2 puts here: one for find, one for open */
put_device(&zcdndev->device);
put_device(&zcdndev->device);
}
}
#endif
atomic_dec(&zcrypt_open_count);
return 0;
}
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
static inline int zcrypt_check_ioctl(struct ap_perms *perms,
unsigned int cmd)
{
int rc = -EPERM;
int ioctlnr = (cmd & _IOC_NRMASK) >> _IOC_NRSHIFT;
if (ioctlnr > 0 && ioctlnr < AP_IOCTLS) {
if (test_bit_inv(ioctlnr, perms->ioctlm))
rc = 0;
}
if (rc)
ZCRYPT_DBF_WARN("%s ioctl check failed: ioctlnr=0x%04x rc=%d\n",
__func__, ioctlnr, rc);
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
return rc;
}
static inline bool zcrypt_check_card(struct ap_perms *perms, int card)
{
return test_bit_inv(card, perms->apm) ? true : false;
}
static inline bool zcrypt_check_queue(struct ap_perms *perms, int queue)
{
return test_bit_inv(queue, perms->aqm) ? true : false;
}
static inline struct zcrypt_queue *zcrypt_pick_queue(struct zcrypt_card *zc,
struct zcrypt_queue *zq,
s390/zcrypt: revisit ap device remove procedure Working with the vfio-ap driver let to some revisit of the way how an ap (queue) device is removed from the driver. With the current implementation all the cleanup was done before the driver even got notified about the removal. Now the ap queue removal is done in 3 steps: 1) A preparation step, all ap messages within the queue are flushed and so the driver does 'receive' them. Also a new state AP_STATE_REMOVE assigned to the queue makes sure there are no new messages queued in. 2) Now the driver's remove function is invoked and the driver should do the job of cleaning up it's internal administration lists or whatever. After 2) is done it is guaranteed, that the driver is not invoked any more. On the other hand the driver has to make sure that the APQN is not accessed any more after step 2 is complete. 3) Now the ap bus code does the job of total cleanup of the APQN. A reset with zero is triggered and the state of the queue goes to AP_STATE_UNBOUND. After step 3) is complete, the ap queue has no pending messages and the APQN is cleared and so there are no requests and replies lingering around in the firmware queue for this APQN. Also the interrupts are disabled. After these remove steps the ap queue device may be assigned to another driver. Stress testing this remove/probe procedure showed a problem with the correct module reference counting. The actual receive of an reply in the driver is done asynchronous with completions. So with a driver change on an ap queue the message flush triggers completions but the threads waiting for the completions may run at a time where the queue already has the new driver assigned. So the module_put() at receive time needs to be done on the driver module which queued the ap message. This change is also part of this patch. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2019-02-23 00:24:11 +08:00
struct module **pmod,
unsigned int weight)
{
if (!zq || !try_module_get(zq->queue->ap_dev.device.driver->owner))
return NULL;
zcrypt_queue_get(zq);
get_device(&zq->queue->ap_dev.device);
atomic_add(weight, &zc->load);
atomic_add(weight, &zq->load);
zq->request_count++;
*pmod = zq->queue->ap_dev.device.driver->owner;
return zq;
}
static inline void zcrypt_drop_queue(struct zcrypt_card *zc,
struct zcrypt_queue *zq,
s390/zcrypt: revisit ap device remove procedure Working with the vfio-ap driver let to some revisit of the way how an ap (queue) device is removed from the driver. With the current implementation all the cleanup was done before the driver even got notified about the removal. Now the ap queue removal is done in 3 steps: 1) A preparation step, all ap messages within the queue are flushed and so the driver does 'receive' them. Also a new state AP_STATE_REMOVE assigned to the queue makes sure there are no new messages queued in. 2) Now the driver's remove function is invoked and the driver should do the job of cleaning up it's internal administration lists or whatever. After 2) is done it is guaranteed, that the driver is not invoked any more. On the other hand the driver has to make sure that the APQN is not accessed any more after step 2 is complete. 3) Now the ap bus code does the job of total cleanup of the APQN. A reset with zero is triggered and the state of the queue goes to AP_STATE_UNBOUND. After step 3) is complete, the ap queue has no pending messages and the APQN is cleared and so there are no requests and replies lingering around in the firmware queue for this APQN. Also the interrupts are disabled. After these remove steps the ap queue device may be assigned to another driver. Stress testing this remove/probe procedure showed a problem with the correct module reference counting. The actual receive of an reply in the driver is done asynchronous with completions. So with a driver change on an ap queue the message flush triggers completions but the threads waiting for the completions may run at a time where the queue already has the new driver assigned. So the module_put() at receive time needs to be done on the driver module which queued the ap message. This change is also part of this patch. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2019-02-23 00:24:11 +08:00
struct module *mod,
unsigned int weight)
{
zq->request_count--;
atomic_sub(weight, &zc->load);
atomic_sub(weight, &zq->load);
put_device(&zq->queue->ap_dev.device);
zcrypt_queue_put(zq);
module_put(mod);
}
static inline bool zcrypt_card_compare(struct zcrypt_card *zc,
struct zcrypt_card *pref_zc,
unsigned int weight,
unsigned int pref_weight)
{
if (!pref_zc)
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
return true;
weight += atomic_read(&zc->load);
pref_weight += atomic_read(&pref_zc->load);
if (weight == pref_weight)
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
return atomic64_read(&zc->card->total_request_count) <
atomic64_read(&pref_zc->card->total_request_count);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
return weight < pref_weight;
}
static inline bool zcrypt_queue_compare(struct zcrypt_queue *zq,
struct zcrypt_queue *pref_zq,
unsigned int weight,
unsigned int pref_weight)
{
if (!pref_zq)
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
return true;
weight += atomic_read(&zq->load);
pref_weight += atomic_read(&pref_zq->load);
if (weight == pref_weight)
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
return zq->queue->total_request_count <
pref_zq->queue->total_request_count;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
return weight < pref_weight;
}
/*
* zcrypt ioctls.
*/
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
static long zcrypt_rsa_modexpo(struct ap_perms *perms,
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
struct zcrypt_track *tr,
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
struct ica_rsa_modexpo *mex)
{
struct zcrypt_card *zc, *pref_zc;
struct zcrypt_queue *zq, *pref_zq;
struct ap_message ap_msg;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
unsigned int wgt = 0, pref_wgt = 0;
unsigned int func_code;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
int cpen, qpen, qid = 0, rc = -ENODEV;
s390/zcrypt: revisit ap device remove procedure Working with the vfio-ap driver let to some revisit of the way how an ap (queue) device is removed from the driver. With the current implementation all the cleanup was done before the driver even got notified about the removal. Now the ap queue removal is done in 3 steps: 1) A preparation step, all ap messages within the queue are flushed and so the driver does 'receive' them. Also a new state AP_STATE_REMOVE assigned to the queue makes sure there are no new messages queued in. 2) Now the driver's remove function is invoked and the driver should do the job of cleaning up it's internal administration lists or whatever. After 2) is done it is guaranteed, that the driver is not invoked any more. On the other hand the driver has to make sure that the APQN is not accessed any more after step 2 is complete. 3) Now the ap bus code does the job of total cleanup of the APQN. A reset with zero is triggered and the state of the queue goes to AP_STATE_UNBOUND. After step 3) is complete, the ap queue has no pending messages and the APQN is cleared and so there are no requests and replies lingering around in the firmware queue for this APQN. Also the interrupts are disabled. After these remove steps the ap queue device may be assigned to another driver. Stress testing this remove/probe procedure showed a problem with the correct module reference counting. The actual receive of an reply in the driver is done asynchronous with completions. So with a driver change on an ap queue the message flush triggers completions but the threads waiting for the completions may run at a time where the queue already has the new driver assigned. So the module_put() at receive time needs to be done on the driver module which queued the ap message. This change is also part of this patch. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2019-02-23 00:24:11 +08:00
struct module *mod;
trace_s390_zcrypt_req(mex, TP_ICARSAMODEXPO);
ap_init_message(&ap_msg);
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (tr && tr->fi.cmd)
ap_msg.fi.cmd = tr->fi.cmd;
#endif
if (mex->outputdatalength < mex->inputdatalength) {
func_code = 0;
rc = -EINVAL;
goto out;
}
/*
* As long as outputdatalength is big enough, we can set the
* outputdatalength equal to the inputdatalength, since that is the
* number of bytes we will copy in any case
*/
mex->outputdatalength = mex->inputdatalength;
rc = get_rsa_modex_fc(mex, &func_code);
if (rc)
goto out;
pref_zc = NULL;
pref_zq = NULL;
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
/* Check for usable accelarator or CCA card */
if (!zc->online || !zc->card->config || zc->card->chkstop ||
!(zc->card->functions & 0x18000000))
continue;
/* Check for size limits */
if (zc->min_mod_size > mex->inputdatalength ||
zc->max_mod_size < mex->inputdatalength)
continue;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
/* check if device node has admission for this card */
if (!zcrypt_check_card(perms, zc->card->id))
continue;
/* get weight index of the card device */
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
wgt = zc->speed_rating[func_code];
/* penalty if this msg was previously sent via this card */
cpen = (tr && tr->again_counter && tr->last_qid &&
AP_QID_CARD(tr->last_qid) == zc->card->id) ?
TRACK_AGAIN_CARD_WEIGHT_PENALTY : 0;
if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt))
continue;
for_each_zcrypt_queue(zq, zc) {
/* check if device is usable and eligible */
if (!zq->online || !zq->ops->rsa_modexpo ||
!zq->queue->config || zq->queue->chkstop)
continue;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
/* check if device node has admission for this queue */
if (!zcrypt_check_queue(perms,
AP_QID_QUEUE(zq->queue->qid)))
continue;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
/* penalty if the msg was previously sent at this qid */
qpen = (tr && tr->again_counter && tr->last_qid &&
tr->last_qid == zq->queue->qid) ?
TRACK_AGAIN_QUEUE_WEIGHT_PENALTY : 0;
if (!zcrypt_queue_compare(zq, pref_zq,
wgt + cpen + qpen, pref_wgt))
continue;
pref_zc = zc;
pref_zq = zq;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
pref_wgt = wgt + cpen + qpen;
}
}
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, wgt);
spin_unlock(&zcrypt_list_lock);
if (!pref_zq) {
ZCRYPT_DBF_DBG("%s no matching queue found => ENODEV\n",
__func__);
rc = -ENODEV;
goto out;
}
qid = pref_zq->queue->qid;
rc = pref_zq->ops->rsa_modexpo(pref_zq, mex, &ap_msg);
spin_lock(&zcrypt_list_lock);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt);
spin_unlock(&zcrypt_list_lock);
out:
ap_release_message(&ap_msg);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
if (tr) {
tr->last_rc = rc;
tr->last_qid = qid;
}
trace_s390_zcrypt_rep(mex, func_code, rc,
AP_QID_CARD(qid), AP_QID_QUEUE(qid));
return rc;
}
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
static long zcrypt_rsa_crt(struct ap_perms *perms,
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
struct zcrypt_track *tr,
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
struct ica_rsa_modexpo_crt *crt)
{
struct zcrypt_card *zc, *pref_zc;
struct zcrypt_queue *zq, *pref_zq;
struct ap_message ap_msg;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
unsigned int wgt = 0, pref_wgt = 0;
unsigned int func_code;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
int cpen, qpen, qid = 0, rc = -ENODEV;
s390/zcrypt: revisit ap device remove procedure Working with the vfio-ap driver let to some revisit of the way how an ap (queue) device is removed from the driver. With the current implementation all the cleanup was done before the driver even got notified about the removal. Now the ap queue removal is done in 3 steps: 1) A preparation step, all ap messages within the queue are flushed and so the driver does 'receive' them. Also a new state AP_STATE_REMOVE assigned to the queue makes sure there are no new messages queued in. 2) Now the driver's remove function is invoked and the driver should do the job of cleaning up it's internal administration lists or whatever. After 2) is done it is guaranteed, that the driver is not invoked any more. On the other hand the driver has to make sure that the APQN is not accessed any more after step 2 is complete. 3) Now the ap bus code does the job of total cleanup of the APQN. A reset with zero is triggered and the state of the queue goes to AP_STATE_UNBOUND. After step 3) is complete, the ap queue has no pending messages and the APQN is cleared and so there are no requests and replies lingering around in the firmware queue for this APQN. Also the interrupts are disabled. After these remove steps the ap queue device may be assigned to another driver. Stress testing this remove/probe procedure showed a problem with the correct module reference counting. The actual receive of an reply in the driver is done asynchronous with completions. So with a driver change on an ap queue the message flush triggers completions but the threads waiting for the completions may run at a time where the queue already has the new driver assigned. So the module_put() at receive time needs to be done on the driver module which queued the ap message. This change is also part of this patch. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2019-02-23 00:24:11 +08:00
struct module *mod;
trace_s390_zcrypt_req(crt, TP_ICARSACRT);
ap_init_message(&ap_msg);
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (tr && tr->fi.cmd)
ap_msg.fi.cmd = tr->fi.cmd;
#endif
if (crt->outputdatalength < crt->inputdatalength) {
func_code = 0;
rc = -EINVAL;
goto out;
}
/*
* As long as outputdatalength is big enough, we can set the
* outputdatalength equal to the inputdatalength, since that is the
* number of bytes we will copy in any case
*/
crt->outputdatalength = crt->inputdatalength;
rc = get_rsa_crt_fc(crt, &func_code);
if (rc)
goto out;
pref_zc = NULL;
pref_zq = NULL;
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
/* Check for usable accelarator or CCA card */
if (!zc->online || !zc->card->config || zc->card->chkstop ||
!(zc->card->functions & 0x18000000))
continue;
/* Check for size limits */
if (zc->min_mod_size > crt->inputdatalength ||
zc->max_mod_size < crt->inputdatalength)
continue;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
/* check if device node has admission for this card */
if (!zcrypt_check_card(perms, zc->card->id))
continue;
/* get weight index of the card device */
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
wgt = zc->speed_rating[func_code];
/* penalty if this msg was previously sent via this card */
cpen = (tr && tr->again_counter && tr->last_qid &&
AP_QID_CARD(tr->last_qid) == zc->card->id) ?
TRACK_AGAIN_CARD_WEIGHT_PENALTY : 0;
if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt))
continue;
for_each_zcrypt_queue(zq, zc) {
/* check if device is usable and eligible */
if (!zq->online || !zq->ops->rsa_modexpo_crt ||
!zq->queue->config || zq->queue->chkstop)
continue;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
/* check if device node has admission for this queue */
if (!zcrypt_check_queue(perms,
AP_QID_QUEUE(zq->queue->qid)))
continue;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
/* penalty if the msg was previously sent at this qid */
qpen = (tr && tr->again_counter && tr->last_qid &&
tr->last_qid == zq->queue->qid) ?
TRACK_AGAIN_QUEUE_WEIGHT_PENALTY : 0;
if (!zcrypt_queue_compare(zq, pref_zq,
wgt + cpen + qpen, pref_wgt))
continue;
pref_zc = zc;
pref_zq = zq;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
pref_wgt = wgt + cpen + qpen;
}
}
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, wgt);
spin_unlock(&zcrypt_list_lock);
if (!pref_zq) {
ZCRYPT_DBF_DBG("%s no matching queue found => ENODEV\n",
__func__);
rc = -ENODEV;
goto out;
}
qid = pref_zq->queue->qid;
rc = pref_zq->ops->rsa_modexpo_crt(pref_zq, crt, &ap_msg);
spin_lock(&zcrypt_list_lock);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt);
spin_unlock(&zcrypt_list_lock);
out:
ap_release_message(&ap_msg);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
if (tr) {
tr->last_rc = rc;
tr->last_qid = qid;
}
trace_s390_zcrypt_rep(crt, func_code, rc,
AP_QID_CARD(qid), AP_QID_QUEUE(qid));
return rc;
}
static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
struct zcrypt_track *tr,
struct ica_xcRB *xcrb)
{
struct zcrypt_card *zc, *pref_zc;
struct zcrypt_queue *zq, *pref_zq;
struct ap_message ap_msg;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
unsigned int wgt = 0, pref_wgt = 0;
unsigned int func_code;
unsigned short *domain, tdom;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
int cpen, qpen, qid = 0, rc = -ENODEV;
s390/zcrypt: revisit ap device remove procedure Working with the vfio-ap driver let to some revisit of the way how an ap (queue) device is removed from the driver. With the current implementation all the cleanup was done before the driver even got notified about the removal. Now the ap queue removal is done in 3 steps: 1) A preparation step, all ap messages within the queue are flushed and so the driver does 'receive' them. Also a new state AP_STATE_REMOVE assigned to the queue makes sure there are no new messages queued in. 2) Now the driver's remove function is invoked and the driver should do the job of cleaning up it's internal administration lists or whatever. After 2) is done it is guaranteed, that the driver is not invoked any more. On the other hand the driver has to make sure that the APQN is not accessed any more after step 2 is complete. 3) Now the ap bus code does the job of total cleanup of the APQN. A reset with zero is triggered and the state of the queue goes to AP_STATE_UNBOUND. After step 3) is complete, the ap queue has no pending messages and the APQN is cleared and so there are no requests and replies lingering around in the firmware queue for this APQN. Also the interrupts are disabled. After these remove steps the ap queue device may be assigned to another driver. Stress testing this remove/probe procedure showed a problem with the correct module reference counting. The actual receive of an reply in the driver is done asynchronous with completions. So with a driver change on an ap queue the message flush triggers completions but the threads waiting for the completions may run at a time where the queue already has the new driver assigned. So the module_put() at receive time needs to be done on the driver module which queued the ap message. This change is also part of this patch. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2019-02-23 00:24:11 +08:00
struct module *mod;
trace_s390_zcrypt_req(xcrb, TB_ZSECSENDCPRB);
xcrb->status = 0;
ap_init_message(&ap_msg);
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (tr && tr->fi.cmd)
ap_msg.fi.cmd = tr->fi.cmd;
if (tr && tr->fi.action == AP_FI_ACTION_CCA_AGENT_FF) {
ZCRYPT_DBF_WARN("%s fi cmd 0x%04x: forcing invalid agent_ID 'FF'\n",
__func__, tr->fi.cmd);
xcrb->agent_ID = 0x4646;
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
}
#endif
rc = prep_cca_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);
if (rc)
goto out;
tdom = *domain;
if (perms != &ap_perms && tdom < AP_DOMAINS) {
if (ap_msg.flags & AP_MSG_FLAG_ADMIN) {
if (!test_bit_inv(tdom, perms->adm)) {
rc = -ENODEV;
goto out;
}
} else if ((ap_msg.flags & AP_MSG_FLAG_USAGE) == 0) {
rc = -EOPNOTSUPP;
goto out;
}
}
/*
* 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;
pref_zc = NULL;
pref_zq = NULL;
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
/* Check for usable CCA card */
if (!zc->online || !zc->card->config || zc->card->chkstop ||
!(zc->card->functions & 0x10000000))
continue;
/* Check for user selected CCA card */
if (xcrb->user_defined != AUTOSELECT &&
xcrb->user_defined != zc->card->id)
continue;
s390/AP: support new dynamic AP bus size limit This patch provides support for new dynamic AP bus message limit with the existing zcrypt device driver and AP bus core code. There is support for a new field 'ml' from TAPQ query. The field gives if != 0 the AP bus limit for this card in 4k chunk units. The actual message size limit per card is shown as a new read-only sysfs attribute. The sysfs attribute /sys/devices/ap/cardxx/max_msg_size shows the upper limit in bytes used by the AP bus and zcrypt device driver for requests and replies send to and received from this card. Currently up to CEX7 support only max 12kB msg size and thus the field shows 12288 meaning the upper limit of a valid msg for this card is 12kB. Please note that the usable payload is somewhat lower and depends on the msg type and thus the header struct which is to be prepended by the zcrypt dd. The dispatcher responsible for choosing the right card and queue is aware of the individual card AP bus message limit. So a request is only assigned to a queue of a card which is able to handle the size of the request (e.g. a 14kB request will never go to a max 12kB card). If no such card is found the ioctl will fail with ENODEV. The reply buffer held by the device driver is determined by the ml field of the TAPQ for this card. If a response from the card exceeds this limit however, the response is not truncated but the ioctl for this request will fail with errno EMSGSIZE to indicate that the device driver has dropped the response because it would overflow the buffer limit. If the request size does not indicate to the dispatcher that an adapter with extended limit is to be used, a random card will be chosen when no specific card is addressed (ANY addressing). This may result in an ioctl failure when the reply size needs an adapter with extended limit but the randomly chosen one is not capable of handling the broader reply size. The user space application needs to use dedicated addressing to forward such a request only to suitable cards to get requests like this processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Tuchscherer <ingo.tuchscherer@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2021-06-25 18:29:46 +08:00
/* check if request size exceeds card max msg size */
if (ap_msg.len > zc->card->maxmsgsize)
continue;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
/* check if device node has admission for this card */
if (!zcrypt_check_card(perms, zc->card->id))
continue;
/* get weight index of the card device */
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
wgt = speed_idx_cca(func_code) * zc->speed_rating[SECKEY];
/* penalty if this msg was previously sent via this card */
cpen = (tr && tr->again_counter && tr->last_qid &&
AP_QID_CARD(tr->last_qid) == zc->card->id) ?
TRACK_AGAIN_CARD_WEIGHT_PENALTY : 0;
if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt))
continue;
for_each_zcrypt_queue(zq, zc) {
/* check for device usable and eligible */
if (!zq->online || !zq->ops->send_cprb ||
!zq->queue->config || zq->queue->chkstop ||
(tdom != AUTOSEL_DOM &&
tdom != AP_QID_QUEUE(zq->queue->qid)))
continue;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
/* check if device node has admission for this queue */
if (!zcrypt_check_queue(perms,
AP_QID_QUEUE(zq->queue->qid)))
continue;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
/* penalty if the msg was previously sent at this qid */
qpen = (tr && tr->again_counter && tr->last_qid &&
tr->last_qid == zq->queue->qid) ?
TRACK_AGAIN_QUEUE_WEIGHT_PENALTY : 0;
if (!zcrypt_queue_compare(zq, pref_zq,
wgt + cpen + qpen, pref_wgt))
continue;
pref_zc = zc;
pref_zq = zq;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
pref_wgt = wgt + cpen + qpen;
}
}
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, wgt);
spin_unlock(&zcrypt_list_lock);
if (!pref_zq) {
ZCRYPT_DBF_DBG("%s no match for address %02x.%04x => ENODEV\n",
__func__, 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);
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (tr && tr->fi.action == AP_FI_ACTION_CCA_DOM_INVAL) {
ZCRYPT_DBF_WARN("%s fi cmd 0x%04x: forcing invalid domain\n",
__func__, tr->fi.cmd);
*domain = 99;
}
#endif
rc = pref_zq->ops->send_cprb(userspace, pref_zq, xcrb, &ap_msg);
spin_lock(&zcrypt_list_lock);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt);
spin_unlock(&zcrypt_list_lock);
out:
ap_release_message(&ap_msg);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
if (tr) {
tr->last_rc = rc;
tr->last_qid = qid;
}
trace_s390_zcrypt_rep(xcrb, func_code, rc,
AP_QID_CARD(qid), AP_QID_QUEUE(qid));
return rc;
}
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
long zcrypt_send_cprb(struct ica_xcRB *xcrb)
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
{
return _zcrypt_send_cprb(false, &ap_perms, NULL, xcrb);
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
}
EXPORT_SYMBOL(zcrypt_send_cprb);
static bool is_desired_ep11_card(unsigned int dev_id,
unsigned short target_num,
struct ep11_target_dev *targets)
{
while (target_num-- > 0) {
if (targets->ap_id == dev_id || targets->ap_id == AUTOSEL_AP)
return true;
targets++;
}
return false;
}
static bool is_desired_ep11_queue(unsigned int dev_qid,
unsigned short target_num,
struct ep11_target_dev *targets)
{
int card = AP_QID_CARD(dev_qid), dom = AP_QID_QUEUE(dev_qid);
while (target_num-- > 0) {
if ((targets->ap_id == card || targets->ap_id == AUTOSEL_AP) &&
(targets->dom_id == dom || targets->dom_id == AUTOSEL_DOM))
return true;
targets++;
}
return false;
}
static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
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;
unsigned short target_num;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
unsigned int wgt = 0, pref_wgt = 0;
unsigned int func_code, domain;
struct ap_message ap_msg;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
int cpen, qpen, qid = 0, rc = -ENODEV;
s390/zcrypt: revisit ap device remove procedure Working with the vfio-ap driver let to some revisit of the way how an ap (queue) device is removed from the driver. With the current implementation all the cleanup was done before the driver even got notified about the removal. Now the ap queue removal is done in 3 steps: 1) A preparation step, all ap messages within the queue are flushed and so the driver does 'receive' them. Also a new state AP_STATE_REMOVE assigned to the queue makes sure there are no new messages queued in. 2) Now the driver's remove function is invoked and the driver should do the job of cleaning up it's internal administration lists or whatever. After 2) is done it is guaranteed, that the driver is not invoked any more. On the other hand the driver has to make sure that the APQN is not accessed any more after step 2 is complete. 3) Now the ap bus code does the job of total cleanup of the APQN. A reset with zero is triggered and the state of the queue goes to AP_STATE_UNBOUND. After step 3) is complete, the ap queue has no pending messages and the APQN is cleared and so there are no requests and replies lingering around in the firmware queue for this APQN. Also the interrupts are disabled. After these remove steps the ap queue device may be assigned to another driver. Stress testing this remove/probe procedure showed a problem with the correct module reference counting. The actual receive of an reply in the driver is done asynchronous with completions. So with a driver change on an ap queue the message flush triggers completions but the threads waiting for the completions may run at a time where the queue already has the new driver assigned. So the module_put() at receive time needs to be done on the driver module which queued the ap message. This change is also part of this patch. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2019-02-23 00:24:11 +08:00
struct module *mod;
trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB);
ap_init_message(&ap_msg);
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (tr && tr->fi.cmd)
ap_msg.fi.cmd = tr->fi.cmd;
#endif
target_num = (unsigned short)xcrb->targets_num;
/* empty list indicates autoselect (all available targets) */
targets = NULL;
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;
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;
rc = -EFAULT;
goto out_free;
}
}
rc = prep_ep11_ap_msg(userspace, xcrb, &ap_msg, &func_code, &domain);
if (rc)
goto out_free;
if (perms != &ap_perms && domain < AUTOSEL_DOM) {
if (ap_msg.flags & AP_MSG_FLAG_ADMIN) {
if (!test_bit_inv(domain, perms->adm)) {
rc = -ENODEV;
goto out_free;
}
} else if ((ap_msg.flags & AP_MSG_FLAG_USAGE) == 0) {
rc = -EOPNOTSUPP;
goto out_free;
}
}
pref_zc = NULL;
pref_zq = NULL;
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
/* Check for usable EP11 card */
if (!zc->online || !zc->card->config || zc->card->chkstop ||
!(zc->card->functions & 0x04000000))
continue;
/* Check for user selected EP11 card */
if (targets &&
!is_desired_ep11_card(zc->card->id, target_num, targets))
continue;
s390/AP: support new dynamic AP bus size limit This patch provides support for new dynamic AP bus message limit with the existing zcrypt device driver and AP bus core code. There is support for a new field 'ml' from TAPQ query. The field gives if != 0 the AP bus limit for this card in 4k chunk units. The actual message size limit per card is shown as a new read-only sysfs attribute. The sysfs attribute /sys/devices/ap/cardxx/max_msg_size shows the upper limit in bytes used by the AP bus and zcrypt device driver for requests and replies send to and received from this card. Currently up to CEX7 support only max 12kB msg size and thus the field shows 12288 meaning the upper limit of a valid msg for this card is 12kB. Please note that the usable payload is somewhat lower and depends on the msg type and thus the header struct which is to be prepended by the zcrypt dd. The dispatcher responsible for choosing the right card and queue is aware of the individual card AP bus message limit. So a request is only assigned to a queue of a card which is able to handle the size of the request (e.g. a 14kB request will never go to a max 12kB card). If no such card is found the ioctl will fail with ENODEV. The reply buffer held by the device driver is determined by the ml field of the TAPQ for this card. If a response from the card exceeds this limit however, the response is not truncated but the ioctl for this request will fail with errno EMSGSIZE to indicate that the device driver has dropped the response because it would overflow the buffer limit. If the request size does not indicate to the dispatcher that an adapter with extended limit is to be used, a random card will be chosen when no specific card is addressed (ANY addressing). This may result in an ioctl failure when the reply size needs an adapter with extended limit but the randomly chosen one is not capable of handling the broader reply size. The user space application needs to use dedicated addressing to forward such a request only to suitable cards to get requests like this processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Tuchscherer <ingo.tuchscherer@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2021-06-25 18:29:46 +08:00
/* check if request size exceeds card max msg size */
if (ap_msg.len > zc->card->maxmsgsize)
continue;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
/* check if device node has admission for this card */
if (!zcrypt_check_card(perms, zc->card->id))
continue;
/* get weight index of the card device */
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
wgt = speed_idx_ep11(func_code) * zc->speed_rating[SECKEY];
/* penalty if this msg was previously sent via this card */
cpen = (tr && tr->again_counter && tr->last_qid &&
AP_QID_CARD(tr->last_qid) == zc->card->id) ?
TRACK_AGAIN_CARD_WEIGHT_PENALTY : 0;
if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt))
continue;
for_each_zcrypt_queue(zq, zc) {
/* check if device is usable and eligible */
if (!zq->online || !zq->ops->send_ep11_cprb ||
!zq->queue->config || zq->queue->chkstop ||
(targets &&
!is_desired_ep11_queue(zq->queue->qid,
target_num, targets)))
continue;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
/* check if device node has admission for this queue */
if (!zcrypt_check_queue(perms,
AP_QID_QUEUE(zq->queue->qid)))
continue;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
/* penalty if the msg was previously sent at this qid */
qpen = (tr && tr->again_counter && tr->last_qid &&
tr->last_qid == zq->queue->qid) ?
TRACK_AGAIN_QUEUE_WEIGHT_PENALTY : 0;
if (!zcrypt_queue_compare(zq, pref_zq,
wgt + cpen + qpen, pref_wgt))
continue;
pref_zc = zc;
pref_zq = zq;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
pref_wgt = wgt + cpen + qpen;
}
}
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, wgt);
spin_unlock(&zcrypt_list_lock);
if (!pref_zq) {
if (targets && target_num == 1) {
ZCRYPT_DBF_DBG("%s no match for address %02x.%04x => ENODEV\n",
__func__, (int)targets->ap_id,
(int)targets->dom_id);
} else if (targets) {
ZCRYPT_DBF_DBG("%s no match for %d target addrs => ENODEV\n",
__func__, (int)target_num);
} else {
ZCRYPT_DBF_DBG("%s no match for address ff.ffff => ENODEV\n",
__func__);
}
rc = -ENODEV;
goto out_free;
}
qid = pref_zq->queue->qid;
rc = pref_zq->ops->send_ep11_cprb(userspace, pref_zq, xcrb, &ap_msg);
spin_lock(&zcrypt_list_lock);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt);
spin_unlock(&zcrypt_list_lock);
out_free:
kfree(targets);
out:
ap_release_message(&ap_msg);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
if (tr) {
tr->last_rc = rc;
tr->last_qid = qid;
}
trace_s390_zcrypt_rep(xcrb, func_code, rc,
AP_QID_CARD(qid), AP_QID_QUEUE(qid));
return rc;
}
long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
{
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
return _zcrypt_send_ep11_cprb(false, &ap_perms, NULL, xcrb);
}
EXPORT_SYMBOL(zcrypt_send_ep11_cprb);
static long zcrypt_rng(char *buffer)
{
struct zcrypt_card *zc, *pref_zc;
struct zcrypt_queue *zq, *pref_zq;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
unsigned int wgt = 0, pref_wgt = 0;
unsigned int func_code;
struct ap_message ap_msg;
unsigned int domain;
int qid = 0, rc = -ENODEV;
s390/zcrypt: revisit ap device remove procedure Working with the vfio-ap driver let to some revisit of the way how an ap (queue) device is removed from the driver. With the current implementation all the cleanup was done before the driver even got notified about the removal. Now the ap queue removal is done in 3 steps: 1) A preparation step, all ap messages within the queue are flushed and so the driver does 'receive' them. Also a new state AP_STATE_REMOVE assigned to the queue makes sure there are no new messages queued in. 2) Now the driver's remove function is invoked and the driver should do the job of cleaning up it's internal administration lists or whatever. After 2) is done it is guaranteed, that the driver is not invoked any more. On the other hand the driver has to make sure that the APQN is not accessed any more after step 2 is complete. 3) Now the ap bus code does the job of total cleanup of the APQN. A reset with zero is triggered and the state of the queue goes to AP_STATE_UNBOUND. After step 3) is complete, the ap queue has no pending messages and the APQN is cleared and so there are no requests and replies lingering around in the firmware queue for this APQN. Also the interrupts are disabled. After these remove steps the ap queue device may be assigned to another driver. Stress testing this remove/probe procedure showed a problem with the correct module reference counting. The actual receive of an reply in the driver is done asynchronous with completions. So with a driver change on an ap queue the message flush triggers completions but the threads waiting for the completions may run at a time where the queue already has the new driver assigned. So the module_put() at receive time needs to be done on the driver module which queued the ap message. This change is also part of this patch. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2019-02-23 00:24:11 +08:00
struct module *mod;
trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB);
ap_init_message(&ap_msg);
rc = prep_rng_ap_msg(&ap_msg, &func_code, &domain);
if (rc)
goto out;
pref_zc = NULL;
pref_zq = NULL;
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
/* Check for usable CCA card */
if (!zc->online || !zc->card->config || zc->card->chkstop ||
!(zc->card->functions & 0x10000000))
continue;
/* get weight index of the card device */
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
wgt = zc->speed_rating[func_code];
if (!zcrypt_card_compare(zc, pref_zc, wgt, pref_wgt))
continue;
for_each_zcrypt_queue(zq, zc) {
/* check if device is usable and eligible */
if (!zq->online || !zq->ops->rng ||
!zq->queue->config || zq->queue->chkstop)
continue;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
if (!zcrypt_queue_compare(zq, pref_zq, wgt, pref_wgt))
continue;
pref_zc = zc;
pref_zq = zq;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
pref_wgt = wgt;
}
}
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, wgt);
spin_unlock(&zcrypt_list_lock);
if (!pref_zq) {
ZCRYPT_DBF_DBG("%s no matching queue found => ENODEV\n",
__func__);
rc = -ENODEV;
goto out;
}
qid = pref_zq->queue->qid;
rc = pref_zq->ops->rng(pref_zq, buffer, &ap_msg);
spin_lock(&zcrypt_list_lock);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt);
spin_unlock(&zcrypt_list_lock);
out:
ap_release_message(&ap_msg);
trace_s390_zcrypt_rep(buffer, func_code, rc,
AP_QID_CARD(qid), AP_QID_QUEUE(qid));
return rc;
}
static void zcrypt_device_status_mask(struct zcrypt_device_status *devstatus)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
struct zcrypt_device_status *stat;
int card, queue;
memset(devstatus, 0, MAX_ZDEV_ENTRIES
* sizeof(struct zcrypt_device_status));
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
card = AP_QID_CARD(zq->queue->qid);
if (card >= MAX_ZDEV_CARDIDS)
continue;
queue = AP_QID_QUEUE(zq->queue->qid);
stat = &devstatus[card * AP_DOMAINS + queue];
stat->hwtype = zc->card->ap_dev.device_type;
stat->functions = zc->card->functions >> 26;
stat->qid = zq->queue->qid;
stat->online = zq->online ? 0x01 : 0x00;
}
}
spin_unlock(&zcrypt_list_lock);
}
void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
struct zcrypt_device_status_ext *stat;
int card, queue;
memset(devstatus, 0, MAX_ZDEV_ENTRIES_EXT
* sizeof(struct zcrypt_device_status_ext));
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];
stat->hwtype = zc->card->ap_dev.device_type;
stat->functions = zc->card->functions >> 26;
stat->qid = zq->queue->qid;
stat->online = zq->online ? 0x01 : 0x00;
}
}
spin_unlock(&zcrypt_list_lock);
}
EXPORT_SYMBOL(zcrypt_device_status_mask_ext);
int zcrypt_device_status_ext(int card, int queue,
struct zcrypt_device_status_ext *devstat)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
memset(devstat, 0, sizeof(*devstat));
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
if (card == AP_QID_CARD(zq->queue->qid) &&
queue == AP_QID_QUEUE(zq->queue->qid)) {
devstat->hwtype = zc->card->ap_dev.device_type;
devstat->functions = zc->card->functions >> 26;
devstat->qid = zq->queue->qid;
devstat->online = zq->online ? 0x01 : 0x00;
spin_unlock(&zcrypt_list_lock);
return 0;
}
}
}
spin_unlock(&zcrypt_list_lock);
return -ENODEV;
}
EXPORT_SYMBOL(zcrypt_device_status_ext);
static void zcrypt_status_mask(char status[], size_t max_adapters)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
int card;
memset(status, 0, max_adapters);
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
card = AP_QID_CARD(zq->queue->qid);
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index ||
card >= max_adapters)
continue;
status[card] = zc->online ? zc->user_space_type : 0x0d;
}
}
spin_unlock(&zcrypt_list_lock);
}
static void zcrypt_qdepth_mask(char qdepth[], size_t max_adapters)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
int card;
memset(qdepth, 0, max_adapters);
spin_lock(&zcrypt_list_lock);
local_bh_disable();
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
card = AP_QID_CARD(zq->queue->qid);
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index ||
card >= max_adapters)
continue;
spin_lock(&zq->queue->lock);
qdepth[card] =
zq->queue->pendingq_count +
zq->queue->requestq_count;
spin_unlock(&zq->queue->lock);
}
}
local_bh_enable();
spin_unlock(&zcrypt_list_lock);
}
static void zcrypt_perdev_reqcnt(u32 reqcnt[], size_t max_adapters)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
int card;
u64 cnt;
memset(reqcnt, 0, sizeof(int) * max_adapters);
spin_lock(&zcrypt_list_lock);
local_bh_disable();
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
card = AP_QID_CARD(zq->queue->qid);
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index ||
card >= max_adapters)
continue;
spin_lock(&zq->queue->lock);
cnt = zq->queue->total_request_count;
spin_unlock(&zq->queue->lock);
reqcnt[card] = (cnt < UINT_MAX) ? (u32)cnt : UINT_MAX;
}
}
local_bh_enable();
spin_unlock(&zcrypt_list_lock);
}
static int zcrypt_pendingq_count(void)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
int pendingq_count;
pendingq_count = 0;
spin_lock(&zcrypt_list_lock);
local_bh_disable();
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
continue;
spin_lock(&zq->queue->lock);
pendingq_count += zq->queue->pendingq_count;
spin_unlock(&zq->queue->lock);
}
}
local_bh_enable();
spin_unlock(&zcrypt_list_lock);
return pendingq_count;
}
static int zcrypt_requestq_count(void)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
int requestq_count;
requestq_count = 0;
spin_lock(&zcrypt_list_lock);
local_bh_disable();
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
continue;
spin_lock(&zq->queue->lock);
requestq_count += zq->queue->requestq_count;
spin_unlock(&zq->queue->lock);
}
}
local_bh_enable();
spin_unlock(&zcrypt_list_lock);
return requestq_count;
}
static int icarsamodexpo_ioctl(struct ap_perms *perms, unsigned long arg)
{
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
int rc;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
struct zcrypt_track tr;
struct ica_rsa_modexpo mex;
struct ica_rsa_modexpo __user *umex = (void __user *)arg;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
memset(&tr, 0, sizeof(tr));
if (copy_from_user(&mex, umex, sizeof(mex)))
return -EFAULT;
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (mex.inputdatalength & (1U << 31)) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
tr.fi.cmd = (u16)(mex.inputdatalength >> 16);
}
mex.inputdatalength &= 0x0000FFFF;
#endif
do {
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
rc = zcrypt_rsa_modexpo(perms, &tr, &mex);
if (rc == -EAGAIN)
tr.again_counter++;
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (rc == -EAGAIN && (tr.fi.flags & AP_FI_FLAG_NO_RETRY))
break;
#endif
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
/* on failure: retry once again after a requested rescan */
if ((rc == -ENODEV) && (zcrypt_process_rescan()))
do {
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
rc = zcrypt_rsa_modexpo(perms, &tr, &mex);
if (rc == -EAGAIN)
tr.again_counter++;
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
if (rc) {
ZCRYPT_DBF_DBG("ioctl ICARSAMODEXPO rc=%d\n", rc);
return rc;
}
return put_user(mex.outputdatalength, &umex->outputdatalength);
}
static int icarsacrt_ioctl(struct ap_perms *perms, unsigned long arg)
{
int rc;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
struct zcrypt_track tr;
struct ica_rsa_modexpo_crt crt;
struct ica_rsa_modexpo_crt __user *ucrt = (void __user *)arg;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
memset(&tr, 0, sizeof(tr));
if (copy_from_user(&crt, ucrt, sizeof(crt)))
return -EFAULT;
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (crt.inputdatalength & (1U << 31)) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
tr.fi.cmd = (u16)(crt.inputdatalength >> 16);
}
crt.inputdatalength &= 0x0000FFFF;
#endif
do {
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
rc = zcrypt_rsa_crt(perms, &tr, &crt);
if (rc == -EAGAIN)
tr.again_counter++;
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (rc == -EAGAIN && (tr.fi.flags & AP_FI_FLAG_NO_RETRY))
break;
#endif
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
/* on failure: retry once again after a requested rescan */
if ((rc == -ENODEV) && (zcrypt_process_rescan()))
do {
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
rc = zcrypt_rsa_crt(perms, &tr, &crt);
if (rc == -EAGAIN)
tr.again_counter++;
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
if (rc) {
ZCRYPT_DBF_DBG("ioctl ICARSACRT rc=%d\n", rc);
return rc;
}
return put_user(crt.outputdatalength, &ucrt->outputdatalength);
}
static int zsecsendcprb_ioctl(struct ap_perms *perms, unsigned long arg)
{
int rc;
struct ica_xcRB xcrb;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
struct zcrypt_track tr;
struct ica_xcRB __user *uxcrb = (void __user *)arg;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
memset(&tr, 0, sizeof(tr));
if (copy_from_user(&xcrb, uxcrb, sizeof(xcrb)))
return -EFAULT;
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if ((xcrb.status & 0x8000FFFF) == 0x80004649 /* 'FI' */) {
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
tr.fi.cmd = (u16)(xcrb.status >> 16);
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
}
xcrb.status = 0;
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#endif
do {
rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
if (rc == -EAGAIN)
tr.again_counter++;
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (rc == -EAGAIN && (tr.fi.flags & AP_FI_FLAG_NO_RETRY))
break;
#endif
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
/* on failure: retry once again after a requested rescan */
if ((rc == -ENODEV) && (zcrypt_process_rescan()))
do {
rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
if (rc == -EAGAIN)
tr.again_counter++;
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
if (rc)
ZCRYPT_DBF_DBG("ioctl ZSENDCPRB rc=%d status=0x%x\n",
rc, xcrb.status);
if (copy_to_user(uxcrb, &xcrb, sizeof(xcrb)))
return -EFAULT;
return rc;
}
static int zsendep11cprb_ioctl(struct ap_perms *perms, unsigned long arg)
{
int rc;
struct ep11_urb xcrb;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
struct zcrypt_track tr;
struct ep11_urb __user *uxcrb = (void __user *)arg;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
memset(&tr, 0, sizeof(tr));
if (copy_from_user(&xcrb, uxcrb, sizeof(xcrb)))
return -EFAULT;
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (xcrb.req_len & (1ULL << 63)) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
tr.fi.cmd = (u16)(xcrb.req_len >> 48);
}
xcrb.req_len &= 0x0000FFFFFFFFFFFFULL;
#endif
do {
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
rc = _zcrypt_send_ep11_cprb(true, perms, &tr, &xcrb);
if (rc == -EAGAIN)
tr.again_counter++;
s390/zcrypt: Introduce Failure Injection feature Introduce a way to specify additional debug flags with an crpyto request to be able to trigger certain failures within the zcrypt device drivers and/or ap core code. This failure injection possibility is only enabled with a kernel debug build CONFIG_ZCRYPT_DEBUG) and should never be available on a regular kernel running in production environment. Details: * The ioctl(ICARSAMODEXPO) get's a struct ica_rsa_modexpo. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ICARSACRT) get's a struct ica_rsa_modexpo_crt. If the leftmost bit of the 32 bit unsigned int inputdatalength field is set, the uppermost 16 bits are separated and used als debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSECSENDCPRB) used to send CCA CPRBs get's a struct ica_xcRB. If the leftmost bit of the 32 bit unsigned int status field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. * The ioctl(ZSENDEP11CPRB) used to send EP11 CPRBs get's a struct ep11_urb. If the leftmost bit of the 64 bit unsigned int req_len field is set, the uppermost 16 bits of this field are used as debug flag value. The process is checked to have the CAP_SYS_ADMIN capability enabled or EPERM is returned. So it is possible to send an additional 16 bit value to the zcrypt API to be used to carry a failure injection command which may trigger special behavior within the zcrypt API and layers below. This 16 bit value is for the rest of the test referred as 'fi command' for Failure Injection. The lower 8 bits of the fi command construct a numerical argument in the range of 1-255 and is the 'fi action' to be performed with the request or the resulting reply: * 0x00 (all requests): No failure injection action but flags may be provided which may affect the processing of the request or reply. * 0x01 (only CCA CPRBs): The CPRB's agent_ID field is set to 'FF'. This results in an reply code 0x90 (Transport-Protocol Failure). * 0x02 (only CCA CPRBs): After the APQN to send to has been chosen, the domain field within the CPRB is overwritten with value 99 to enforce an reply with RY 0x8A. * 0x03 (all requests): At NQAP invocation the invalid qid value 0xFF00 is used causing an response code of 0x01 (AP queue not valid). The upper 8 bits of the fi command may carry bit flags which may influence the processing of an request or response: * 0x01: No retry. If this bit is set, the usual loop in the zcrypt API which retries an CPRB up to 10 times when the lower layers return with EAGAIN is abandoned after the first attempt to send the CPRB. * 0x02: Toggle special. Toggles the special bit on this request. This should result in an reply code RY~0x41 and result in an ioctl failure with errno EINVAL. This failure injection possibilities may get some further extensions in the future. As of now this is a starting point for Continuous Test and Integration to trigger some failures and watch for the reaction of the ap bus and zcrypt device driver code. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-09-29 22:07:22 +08:00
#ifdef CONFIG_ZCRYPT_DEBUG
if (rc == -EAGAIN && (tr.fi.flags & AP_FI_FLAG_NO_RETRY))
break;
#endif
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
/* on failure: retry once again after a requested rescan */
if ((rc == -ENODEV) && (zcrypt_process_rescan()))
do {
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
rc = _zcrypt_send_ep11_cprb(true, perms, &tr, &xcrb);
if (rc == -EAGAIN)
tr.again_counter++;
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
if (rc)
ZCRYPT_DBF_DBG("ioctl ZSENDEP11CPRB rc=%d\n", rc);
if (copy_to_user(uxcrb, &xcrb, sizeof(xcrb)))
return -EFAULT;
return rc;
}
static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
int rc;
struct ap_perms *perms =
(struct ap_perms *)filp->private_data;
rc = zcrypt_check_ioctl(perms, cmd);
if (rc)
return rc;
switch (cmd) {
case ICARSAMODEXPO:
return icarsamodexpo_ioctl(perms, arg);
case ICARSACRT:
return icarsacrt_ioctl(perms, arg);
case ZSECSENDCPRB:
return zsecsendcprb_ioctl(perms, arg);
case ZSENDEP11CPRB:
return zsendep11cprb_ioctl(perms, arg);
case ZCRYPT_DEVICE_STATUS: {
struct zcrypt_device_status_ext *device_status;
size_t total_size = MAX_ZDEV_ENTRIES_EXT
* sizeof(struct zcrypt_device_status_ext);
device_status = kzalloc(total_size, 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 = -EFAULT;
kfree(device_status);
return rc;
}
case ZCRYPT_STATUS_MASK: {
char status[AP_DEVICES];
zcrypt_status_mask(status, AP_DEVICES);
if (copy_to_user((char __user *)arg, status, sizeof(status)))
return -EFAULT;
return 0;
}
case ZCRYPT_QDEPTH_MASK: {
char qdepth[AP_DEVICES];
zcrypt_qdepth_mask(qdepth, AP_DEVICES);
if (copy_to_user((char __user *)arg, qdepth, sizeof(qdepth)))
return -EFAULT;
return 0;
}
case ZCRYPT_PERDEV_REQCNT: {
u32 *reqcnt;
reqcnt = kcalloc(AP_DEVICES, sizeof(u32), GFP_KERNEL);
if (!reqcnt)
return -ENOMEM;
zcrypt_perdev_reqcnt(reqcnt, AP_DEVICES);
if (copy_to_user((int __user *)arg, reqcnt,
sizeof(u32) * AP_DEVICES))
rc = -EFAULT;
kfree(reqcnt);
return rc;
}
case Z90STAT_REQUESTQ_COUNT:
return put_user(zcrypt_requestq_count(), (int __user *)arg);
case Z90STAT_PENDINGQ_COUNT:
return put_user(zcrypt_pendingq_count(), (int __user *)arg);
case Z90STAT_TOTALOPEN_COUNT:
return put_user(atomic_read(&zcrypt_open_count),
(int __user *)arg);
case Z90STAT_DOMAIN_INDEX:
return put_user(ap_domain_index, (int __user *)arg);
/*
* Deprecated ioctls
*/
case ZDEVICESTATUS: {
/* the old ioctl supports only 64 adapters */
struct zcrypt_device_status *device_status;
size_t total_size = MAX_ZDEV_ENTRIES
* sizeof(struct zcrypt_device_status);
device_status = kzalloc(total_size, GFP_KERNEL);
if (!device_status)
return -ENOMEM;
zcrypt_device_status_mask(device_status);
if (copy_to_user((char __user *)arg, device_status,
total_size))
rc = -EFAULT;
kfree(device_status);
return rc;
}
case Z90STAT_STATUS_MASK: {
/* the old ioctl supports only 64 adapters */
char status[MAX_ZDEV_CARDIDS];
zcrypt_status_mask(status, MAX_ZDEV_CARDIDS);
if (copy_to_user((char __user *)arg, status, sizeof(status)))
return -EFAULT;
return 0;
}
case Z90STAT_QDEPTH_MASK: {
/* the old ioctl supports only 64 adapters */
char qdepth[MAX_ZDEV_CARDIDS];
zcrypt_qdepth_mask(qdepth, MAX_ZDEV_CARDIDS);
if (copy_to_user((char __user *)arg, qdepth, sizeof(qdepth)))
return -EFAULT;
return 0;
}
case Z90STAT_PERDEV_REQCNT: {
/* the old ioctl supports only 64 adapters */
u32 reqcnt[MAX_ZDEV_CARDIDS];
zcrypt_perdev_reqcnt(reqcnt, MAX_ZDEV_CARDIDS);
if (copy_to_user((int __user *)arg, reqcnt, sizeof(reqcnt)))
return -EFAULT;
return 0;
}
/* unknown ioctl number */
default:
ZCRYPT_DBF_DBG("unknown ioctl 0x%08x\n", cmd);
return -ENOIOCTLCMD;
}
}
#ifdef CONFIG_COMPAT
/*
* ioctl32 conversion routines
*/
struct compat_ica_rsa_modexpo {
compat_uptr_t inputdata;
unsigned int inputdatalength;
compat_uptr_t outputdata;
unsigned int outputdatalength;
compat_uptr_t b_key;
compat_uptr_t n_modulus;
};
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
static long trans_modexpo32(struct ap_perms *perms, struct file *filp,
unsigned int cmd, unsigned long arg)
{
struct compat_ica_rsa_modexpo __user *umex32 = compat_ptr(arg);
struct compat_ica_rsa_modexpo mex32;
struct ica_rsa_modexpo mex64;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
struct zcrypt_track tr;
long rc;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
memset(&tr, 0, sizeof(tr));
if (copy_from_user(&mex32, umex32, sizeof(mex32)))
return -EFAULT;
mex64.inputdata = compat_ptr(mex32.inputdata);
mex64.inputdatalength = mex32.inputdatalength;
mex64.outputdata = compat_ptr(mex32.outputdata);
mex64.outputdatalength = mex32.outputdatalength;
mex64.b_key = compat_ptr(mex32.b_key);
mex64.n_modulus = compat_ptr(mex32.n_modulus);
do {
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
rc = zcrypt_rsa_modexpo(perms, &tr, &mex64);
if (rc == -EAGAIN)
tr.again_counter++;
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
/* on failure: retry once again after a requested rescan */
if ((rc == -ENODEV) && (zcrypt_process_rescan()))
do {
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
rc = zcrypt_rsa_modexpo(perms, &tr, &mex64);
if (rc == -EAGAIN)
tr.again_counter++;
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
if (rc)
return rc;
return put_user(mex64.outputdatalength,
&umex32->outputdatalength);
}
struct compat_ica_rsa_modexpo_crt {
compat_uptr_t inputdata;
unsigned int inputdatalength;
compat_uptr_t outputdata;
unsigned int outputdatalength;
compat_uptr_t bp_key;
compat_uptr_t bq_key;
compat_uptr_t np_prime;
compat_uptr_t nq_prime;
compat_uptr_t u_mult_inv;
};
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
static long trans_modexpo_crt32(struct ap_perms *perms, struct file *filp,
unsigned int cmd, unsigned long arg)
{
struct compat_ica_rsa_modexpo_crt __user *ucrt32 = compat_ptr(arg);
struct compat_ica_rsa_modexpo_crt crt32;
struct ica_rsa_modexpo_crt crt64;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
struct zcrypt_track tr;
long rc;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
memset(&tr, 0, sizeof(tr));
if (copy_from_user(&crt32, ucrt32, sizeof(crt32)))
return -EFAULT;
crt64.inputdata = compat_ptr(crt32.inputdata);
crt64.inputdatalength = crt32.inputdatalength;
crt64.outputdata = compat_ptr(crt32.outputdata);
crt64.outputdatalength = crt32.outputdatalength;
crt64.bp_key = compat_ptr(crt32.bp_key);
crt64.bq_key = compat_ptr(crt32.bq_key);
crt64.np_prime = compat_ptr(crt32.np_prime);
crt64.nq_prime = compat_ptr(crt32.nq_prime);
crt64.u_mult_inv = compat_ptr(crt32.u_mult_inv);
do {
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
rc = zcrypt_rsa_crt(perms, &tr, &crt64);
if (rc == -EAGAIN)
tr.again_counter++;
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
/* on failure: retry once again after a requested rescan */
if ((rc == -ENODEV) && (zcrypt_process_rescan()))
do {
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
rc = zcrypt_rsa_crt(perms, &tr, &crt64);
if (rc == -EAGAIN)
tr.again_counter++;
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
if (rc)
return rc;
return put_user(crt64.outputdatalength,
&ucrt32->outputdatalength);
}
struct compat_ica_xcrb {
unsigned short agent_ID;
unsigned int user_defined;
unsigned short request_ID;
unsigned int request_control_blk_length;
unsigned char padding1[16 - sizeof(compat_uptr_t)];
compat_uptr_t request_control_blk_addr;
unsigned int request_data_length;
char padding2[16 - sizeof(compat_uptr_t)];
compat_uptr_t request_data_address;
unsigned int reply_control_blk_length;
char padding3[16 - sizeof(compat_uptr_t)];
compat_uptr_t reply_control_blk_addr;
unsigned int reply_data_length;
char padding4[16 - sizeof(compat_uptr_t)];
compat_uptr_t reply_data_addr;
unsigned short priority_window;
unsigned int status;
} __packed;
static long trans_xcrb32(struct ap_perms *perms, struct file *filp,
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
unsigned int cmd, unsigned long arg)
{
struct compat_ica_xcrb __user *uxcrb32 = compat_ptr(arg);
struct compat_ica_xcrb xcrb32;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
struct zcrypt_track tr;
struct ica_xcRB xcrb64;
long rc;
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
memset(&tr, 0, sizeof(tr));
if (copy_from_user(&xcrb32, uxcrb32, sizeof(xcrb32)))
return -EFAULT;
xcrb64.agent_ID = xcrb32.agent_ID;
xcrb64.user_defined = xcrb32.user_defined;
xcrb64.request_ID = xcrb32.request_ID;
xcrb64.request_control_blk_length =
xcrb32.request_control_blk_length;
xcrb64.request_control_blk_addr =
compat_ptr(xcrb32.request_control_blk_addr);
xcrb64.request_data_length =
xcrb32.request_data_length;
xcrb64.request_data_address =
compat_ptr(xcrb32.request_data_address);
xcrb64.reply_control_blk_length =
xcrb32.reply_control_blk_length;
xcrb64.reply_control_blk_addr =
compat_ptr(xcrb32.reply_control_blk_addr);
xcrb64.reply_data_length = xcrb32.reply_data_length;
xcrb64.reply_data_addr =
compat_ptr(xcrb32.reply_data_addr);
xcrb64.priority_window = xcrb32.priority_window;
xcrb64.status = xcrb32.status;
do {
rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb64);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
if (rc == -EAGAIN)
tr.again_counter++;
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
/* on failure: retry once again after a requested rescan */
if ((rc == -ENODEV) && (zcrypt_process_rescan()))
do {
rc = _zcrypt_send_cprb(true, perms, &tr, &xcrb64);
s390/zcrypt: introduce msg tracking in zcrypt functions Introduce a new internal struct zcrypt_track with an retry counter field and a last return code field. Fill and update these fields at certain points during processing of an request/reply. This tracking info is then used to - avoid trying to resend the message forever. Now each message is tried to be send TRACK_AGAIN_MAX (currently 10) times and then the ioctl returns to userspace with errno EAGAIN. - avoid trying to resend the message on the very same card/domain. If possible (more than one APQN with same quality) don't use the very same qid as the previous attempt when again scheduling the request. This is done by adding penalty weight values when the dispatching takes place. There is a penalty TRACK_AGAIN_CARD_WEIGHT_PENALTY for using the same card as previously and another penalty define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY to be considered when the same qid as the previous sent attempt is calculated. Both values make it harder to choose the very same card/domain but not impossible. For example when only one APQN is available a resend can only address the very same APQN. There are some more ideas for the future to extend the use of this tracking information. For example the last response code at NQAP and DQAP could be stored there, giving the possibility to extended tracing and debugging about requests failing to get processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2020-07-02 17:10:11 +08:00
if (rc == -EAGAIN)
tr.again_counter++;
} while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
xcrb32.reply_control_blk_length = xcrb64.reply_control_blk_length;
xcrb32.reply_data_length = xcrb64.reply_data_length;
xcrb32.status = xcrb64.status;
if (copy_to_user(uxcrb32, &xcrb32, sizeof(xcrb32)))
return -EFAULT;
return rc;
}
static long zcrypt_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
int rc;
struct ap_perms *perms =
(struct ap_perms *)filp->private_data;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
rc = zcrypt_check_ioctl(perms, cmd);
if (rc)
return rc;
if (cmd == ICARSAMODEXPO)
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
return trans_modexpo32(perms, filp, cmd, arg);
if (cmd == ICARSACRT)
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
return trans_modexpo_crt32(perms, filp, cmd, arg);
if (cmd == ZSECSENDCPRB)
return trans_xcrb32(perms, filp, cmd, arg);
return zcrypt_unlocked_ioctl(filp, cmd, arg);
}
#endif
/*
* Misc device file operations.
*/
static const struct file_operations zcrypt_fops = {
.owner = THIS_MODULE,
.read = zcrypt_read,
.write = zcrypt_write,
.unlocked_ioctl = zcrypt_unlocked_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = zcrypt_compat_ioctl,
#endif
.open = zcrypt_open,
llseek: automatically add .llseek fop All file_operations should get a .llseek operation so we can make nonseekable_open the default for future file operations without a .llseek pointer. The three cases that we can automatically detect are no_llseek, seq_lseek and default_llseek. For cases where we can we can automatically prove that the file offset is always ignored, we use noop_llseek, which maintains the current behavior of not returning an error from a seek. New drivers should normally not use noop_llseek but instead use no_llseek and call nonseekable_open at open time. Existing drivers can be converted to do the same when the maintainer knows for certain that no user code relies on calling seek on the device file. The generated code is often incorrectly indented and right now contains comments that clarify for each added line why a specific variant was chosen. In the version that gets submitted upstream, the comments will be gone and I will manually fix the indentation, because there does not seem to be a way to do that using coccinelle. Some amount of new code is currently sitting in linux-next that should get the same modifications, which I will do at the end of the merge window. Many thanks to Julia Lawall for helping me learn to write a semantic patch that does all this. ===== begin semantic patch ===== // This adds an llseek= method to all file operations, // as a preparation for making no_llseek the default. // // The rules are // - use no_llseek explicitly if we do nonseekable_open // - use seq_lseek for sequential files // - use default_llseek if we know we access f_pos // - use noop_llseek if we know we don't access f_pos, // but we still want to allow users to call lseek // @ open1 exists @ identifier nested_open; @@ nested_open(...) { <+... nonseekable_open(...) ...+> } @ open exists@ identifier open_f; identifier i, f; identifier open1.nested_open; @@ int open_f(struct inode *i, struct file *f) { <+... ( nonseekable_open(...) | nested_open(...) ) ...+> } @ read disable optional_qualifier exists @ identifier read_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; expression E; identifier func; @@ ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off) { <+... ( *off = E | *off += E | func(..., off, ...) | E = *off ) ...+> } @ read_no_fpos disable optional_qualifier exists @ identifier read_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; @@ ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off) { ... when != off } @ write @ identifier write_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; expression E; identifier func; @@ ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off) { <+... ( *off = E | *off += E | func(..., off, ...) | E = *off ) ...+> } @ write_no_fpos @ identifier write_f; identifier f, p, s, off; type ssize_t, size_t, loff_t; @@ ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off) { ... when != off } @ fops0 @ identifier fops; @@ struct file_operations fops = { ... }; @ has_llseek depends on fops0 @ identifier fops0.fops; identifier llseek_f; @@ struct file_operations fops = { ... .llseek = llseek_f, ... }; @ has_read depends on fops0 @ identifier fops0.fops; identifier read_f; @@ struct file_operations fops = { ... .read = read_f, ... }; @ has_write depends on fops0 @ identifier fops0.fops; identifier write_f; @@ struct file_operations fops = { ... .write = write_f, ... }; @ has_open depends on fops0 @ identifier fops0.fops; identifier open_f; @@ struct file_operations fops = { ... .open = open_f, ... }; // use no_llseek if we call nonseekable_open //////////////////////////////////////////// @ nonseekable1 depends on !has_llseek && has_open @ identifier fops0.fops; identifier nso ~= "nonseekable_open"; @@ struct file_operations fops = { ... .open = nso, ... +.llseek = no_llseek, /* nonseekable */ }; @ nonseekable2 depends on !has_llseek @ identifier fops0.fops; identifier open.open_f; @@ struct file_operations fops = { ... .open = open_f, ... +.llseek = no_llseek, /* open uses nonseekable */ }; // use seq_lseek for sequential files ///////////////////////////////////// @ seq depends on !has_llseek @ identifier fops0.fops; identifier sr ~= "seq_read"; @@ struct file_operations fops = { ... .read = sr, ... +.llseek = seq_lseek, /* we have seq_read */ }; // use default_llseek if there is a readdir /////////////////////////////////////////// @ fops1 depends on !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier readdir_e; @@ // any other fop is used that changes pos struct file_operations fops = { ... .readdir = readdir_e, ... +.llseek = default_llseek, /* readdir is present */ }; // use default_llseek if at least one of read/write touches f_pos ///////////////////////////////////////////////////////////////// @ fops2 depends on !fops1 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier read.read_f; @@ // read fops use offset struct file_operations fops = { ... .read = read_f, ... +.llseek = default_llseek, /* read accesses f_pos */ }; @ fops3 depends on !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier write.write_f; @@ // write fops use offset struct file_operations fops = { ... .write = write_f, ... + .llseek = default_llseek, /* write accesses f_pos */ }; // Use noop_llseek if neither read nor write accesses f_pos /////////////////////////////////////////////////////////// @ fops4 depends on !fops1 && !fops2 && !fops3 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier read_no_fpos.read_f; identifier write_no_fpos.write_f; @@ // write fops use offset struct file_operations fops = { ... .write = write_f, .read = read_f, ... +.llseek = noop_llseek, /* read and write both use no f_pos */ }; @ depends on has_write && !has_read && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier write_no_fpos.write_f; @@ struct file_operations fops = { ... .write = write_f, ... +.llseek = noop_llseek, /* write uses no f_pos */ }; @ depends on has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; identifier read_no_fpos.read_f; @@ struct file_operations fops = { ... .read = read_f, ... +.llseek = noop_llseek, /* read uses no f_pos */ }; @ depends on !has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @ identifier fops0.fops; @@ struct file_operations fops = { ... +.llseek = noop_llseek, /* no read or write fn */ }; ===== End semantic patch ===== Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Julia Lawall <julia@diku.dk> Cc: Christoph Hellwig <hch@infradead.org>
2010-08-16 00:52:59 +08:00
.release = zcrypt_release,
.llseek = no_llseek,
};
/*
* Misc device.
*/
static struct miscdevice zcrypt_misc_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "z90crypt",
.fops = &zcrypt_fops,
};
static int zcrypt_rng_device_count;
static u32 *zcrypt_rng_buffer;
static int zcrypt_rng_buffer_index;
static DEFINE_MUTEX(zcrypt_rng_mutex);
static int zcrypt_rng_data_read(struct hwrng *rng, u32 *data)
{
int rc;
/*
* We don't need locking here because the RNG API guarantees serialized
* read method calls.
*/
if (zcrypt_rng_buffer_index == 0) {
rc = zcrypt_rng((char *)zcrypt_rng_buffer);
/* on failure: retry once again after a requested rescan */
if ((rc == -ENODEV) && (zcrypt_process_rescan()))
rc = zcrypt_rng((char *)zcrypt_rng_buffer);
if (rc < 0)
return -EIO;
zcrypt_rng_buffer_index = rc / sizeof(*data);
}
*data = zcrypt_rng_buffer[--zcrypt_rng_buffer_index];
return sizeof(*data);
}
static struct hwrng zcrypt_rng_dev = {
.name = "zcrypt",
.data_read = zcrypt_rng_data_read,
.quality = 990,
};
int zcrypt_rng_device_add(void)
{
int rc = 0;
mutex_lock(&zcrypt_rng_mutex);
if (zcrypt_rng_device_count == 0) {
zcrypt_rng_buffer = (u32 *)get_zeroed_page(GFP_KERNEL);
if (!zcrypt_rng_buffer) {
rc = -ENOMEM;
goto out;
}
zcrypt_rng_buffer_index = 0;
if (!zcrypt_hwrng_seed)
zcrypt_rng_dev.quality = 0;
rc = hwrng_register(&zcrypt_rng_dev);
if (rc)
goto out_free;
zcrypt_rng_device_count = 1;
} else {
zcrypt_rng_device_count++;
}
mutex_unlock(&zcrypt_rng_mutex);
return 0;
out_free:
free_page((unsigned long)zcrypt_rng_buffer);
out:
mutex_unlock(&zcrypt_rng_mutex);
return rc;
}
void zcrypt_rng_device_remove(void)
{
mutex_lock(&zcrypt_rng_mutex);
zcrypt_rng_device_count--;
if (zcrypt_rng_device_count == 0) {
hwrng_unregister(&zcrypt_rng_dev);
free_page((unsigned long)zcrypt_rng_buffer);
}
mutex_unlock(&zcrypt_rng_mutex);
}
/*
* Wait until the zcrypt api is operational.
* The AP bus scan and the binding of ap devices to device drivers is
* an asynchronous job. This function waits until these initial jobs
* are done and so the zcrypt api should be ready to serve crypto
* requests - if there are resources available. The function uses an
* internal timeout of 60s. The very first caller will either wait for
* ap bus bindings complete or the timeout happens. This state will be
* remembered for further callers which will only be blocked until a
* decision is made (timeout or bindings complete).
* On timeout -ETIME is returned, on success the return value is 0.
*/
int zcrypt_wait_api_operational(void)
{
static DEFINE_MUTEX(zcrypt_wait_api_lock);
static int zcrypt_wait_api_state;
int rc;
rc = mutex_lock_interruptible(&zcrypt_wait_api_lock);
if (rc)
return rc;
switch (zcrypt_wait_api_state) {
case 0:
/* initial state, invoke wait for the ap bus complete */
rc = ap_wait_init_apqn_bindings_complete(
msecs_to_jiffies(60 * 1000));
switch (rc) {
case 0:
/* ap bus bindings are complete */
zcrypt_wait_api_state = 1;
break;
case -EINTR:
/* interrupted, go back to caller */
break;
case -ETIME:
/* timeout */
ZCRYPT_DBF_WARN("%s ap_wait_init_apqn_bindings_complete()=ETIME\n",
__func__);
zcrypt_wait_api_state = -ETIME;
break;
default:
/* other failure */
ZCRYPT_DBF_DBG("%s ap_wait_init_apqn_bindings_complete()=%d\n",
__func__, rc);
break;
}
break;
case 1:
/* a previous caller already found ap bus bindings complete */
rc = 0;
break;
default:
/* a previous caller had timeout or other failure */
rc = zcrypt_wait_api_state;
break;
}
mutex_unlock(&zcrypt_wait_api_lock);
return rc;
}
EXPORT_SYMBOL(zcrypt_wait_api_operational);
int __init zcrypt_debug_init(void)
{
zcrypt_dbf_info = debug_register("zcrypt", 2, 1,
DBF_MAX_SPRINTF_ARGS * sizeof(long));
debug_register_view(zcrypt_dbf_info, &debug_sprintf_view);
debug_set_level(zcrypt_dbf_info, DBF_ERR);
return 0;
}
void zcrypt_debug_exit(void)
{
debug_unregister(zcrypt_dbf_info);
}
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
#ifdef CONFIG_ZCRYPT_MULTIDEVNODES
static int __init zcdn_init(void)
{
int rc;
/* create a new class 'zcrypt' */
zcrypt_class = class_create(THIS_MODULE, ZCRYPT_NAME);
if (IS_ERR(zcrypt_class)) {
rc = PTR_ERR(zcrypt_class);
goto out_class_create_failed;
}
zcrypt_class->dev_release = zcdn_device_release;
/* alloc device minor range */
rc = alloc_chrdev_region(&zcrypt_devt,
0, ZCRYPT_MAX_MINOR_NODES,
ZCRYPT_NAME);
if (rc)
goto out_alloc_chrdev_failed;
cdev_init(&zcrypt_cdev, &zcrypt_fops);
zcrypt_cdev.owner = THIS_MODULE;
rc = cdev_add(&zcrypt_cdev, zcrypt_devt, ZCRYPT_MAX_MINOR_NODES);
if (rc)
goto out_cdev_add_failed;
/* need some class specific sysfs attributes */
rc = class_create_file(zcrypt_class, &class_attr_zcdn_create);
if (rc)
goto out_class_create_file_1_failed;
rc = class_create_file(zcrypt_class, &class_attr_zcdn_destroy);
if (rc)
goto out_class_create_file_2_failed;
return 0;
out_class_create_file_2_failed:
class_remove_file(zcrypt_class, &class_attr_zcdn_create);
out_class_create_file_1_failed:
cdev_del(&zcrypt_cdev);
out_cdev_add_failed:
unregister_chrdev_region(zcrypt_devt, ZCRYPT_MAX_MINOR_NODES);
out_alloc_chrdev_failed:
class_destroy(zcrypt_class);
out_class_create_failed:
return rc;
}
static void zcdn_exit(void)
{
class_remove_file(zcrypt_class, &class_attr_zcdn_create);
class_remove_file(zcrypt_class, &class_attr_zcdn_destroy);
zcdn_destroy_all();
cdev_del(&zcrypt_cdev);
unregister_chrdev_region(zcrypt_devt, ZCRYPT_MAX_MINOR_NODES);
class_destroy(zcrypt_class);
}
#endif
/*
* zcrypt_api_init(): Module initialization.
*
* The module initialization code.
*/
int __init zcrypt_api_init(void)
{
int rc;
rc = zcrypt_debug_init();
if (rc)
goto out;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
#ifdef CONFIG_ZCRYPT_MULTIDEVNODES
rc = zcdn_init();
if (rc)
goto out;
#endif
/* Register the request sprayer. */
rc = misc_register(&zcrypt_misc_device);
if (rc < 0)
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
goto out_misc_register_failed;
zcrypt_msgtype6_init();
zcrypt_msgtype50_init();
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
return 0;
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
out_misc_register_failed:
#ifdef CONFIG_ZCRYPT_MULTIDEVNODES
zcdn_exit();
#endif
zcrypt_debug_exit();
out:
return rc;
}
/*
* zcrypt_api_exit(): Module termination.
*
* The module termination code.
*/
void __exit zcrypt_api_exit(void)
{
s390/zcrypt: multiple zcrypt device nodes support This patch is an extension to the zcrypt device driver to provide, support and maintain multiple zcrypt device nodes. The individual zcrypt device nodes can be restricted in terms of crypto cards, domains and available ioctls. Such a device node can be used as a base for container solutions like docker to control and restrict the access to crypto resources. The handling is done with a new sysfs subdir /sys/class/zcrypt. Echoing a name (or an empty sting) into the attribute "create" creates a new zcrypt device node. In /sys/class/zcrypt a new link will appear which points to the sysfs device tree of this new device. The attribute files "ioctlmask", "apmask" and "aqmask" in this directory are used to customize this new zcrypt device node instance. Finally the zcrypt device node can be destroyed by echoing the name into /sys/class/zcrypt/destroy. The internal structs holding the device info are reference counted - so a destroy will not hard remove a device but only marks it as removable when the reference counter drops to zero. The mask values are bitmaps in big endian order starting with bit 0. So adapter number 0 is the leftmost bit, mask is 0x8000... The sysfs attributes accept 2 different formats: * Absolute hex string starting with 0x like "0x12345678" does set the mask starting from left to right. If the given string is shorter than the mask it is padded with 0s on the right. If the string is longer than the mask an error comes back (EINVAL). * Relative format - a concatenation (done with ',') of the terms +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]. <bitnr> may be any valid number (hex, decimal or octal) in the range 0...255. Here are some examples: "+0-15,+32,-128,-0xFF" "-0-255,+1-16,+0x128" "+1,+2,+3,+4,-5,-7-10" A simple usage examples: # create new zcrypt device 'my_zcrypt': echo "my_zcrypt" >/sys/class/zcrypt/create # go into the device dir of this new device echo "my_zcrypt" >create cd my_zcrypt/ ls -l total 0 -rw-r--r-- 1 root root 4096 Jul 20 15:23 apmask -rw-r--r-- 1 root root 4096 Jul 20 15:23 aqmask -r--r--r-- 1 root root 4096 Jul 20 15:23 dev -rw-r--r-- 1 root root 4096 Jul 20 15:23 ioctlmask lrwxrwxrwx 1 root root 0 Jul 20 15:23 subsystem -> ../../../../class/zcrypt ... # customize this zcrypt node clone # enable only adapter 0 and 2 echo "0xa0" >apmask # enable only domain 6 echo "+6" >aqmask # enable all 256 ioctls echo "+0-255" >ioctls # now the /dev/my_zcrypt may be used # finally destroy it echo "my_zcrypt" >/sys/class/zcrypt/destroy Please note that a very similar 'filtering behavior' also applies to the parent z90crypt device. The two mask attributes apmask and aqmask in /sys/bus/ap act the very same for the z90crypt device node. However the implementation here is totally different as the ap bus acts on bind/unbind of queue devices and associated drivers but the effect is still the same. So there are two filters active for each additional zcrypt device node: The adapter/domain needs to be enabled on the ap bus level and it needs to be active on the zcrypt device node level. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
2018-09-17 22:18:41 +08:00
#ifdef CONFIG_ZCRYPT_MULTIDEVNODES
zcdn_exit();
#endif
misc_deregister(&zcrypt_misc_device);
zcrypt_msgtype6_exit();
zcrypt_msgtype50_exit();
zcrypt_ccamisc_exit();
zcrypt_ep11misc_exit();
zcrypt_debug_exit();
}
module_init(zcrypt_api_init);
module_exit(zcrypt_api_exit);