aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Freudenberger <freude@linux.ibm.com>2018-07-20 02:36:53 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-08-20 10:02:12 -0400
commit7e0bdbe5c21cb8316a694e46ad5aad339f6894a6 (patch)
treebfcf85497ea85cbbdf009b9797c8136012f12a73
parentac2b96f351d7d222c46e524feca03005f3fa8d75 (diff)
s390/zcrypt: AP bus support for alternate driver(s)
The current AP bus, AP devices and AP device drivers implementation uses a clearly defined mapping for binding AP devices to AP device drivers. So for example a CEX6C queue will always be bound to the cex4queue device driver. The Linux Device Driver model has no sensitivity for more than one device driver eligible for one device type. If there exist more than one drivers matching to the device type, simple all drivers are tried consecutively. There is no way to determine and influence the probing order of the drivers. With KVM there is a need to provide additional device drivers matching to the very same type of AP devices. With a simple implementation the KVM drivers run in competition to the regular drivers. Whichever 'wins' a device depends on build order and implementation details within the common Linux Device Driver Model and is not deterministic. However, a userspace process could figure out which device should be bound to which driver and sort out the correct binding by manipulating attributes in the sysfs. If for security reasons a AP device must not get bound to the 'wrong' device driver the sorting out has to be done within the Linux kernel by the AP bus code. This patch modifies the behavior of the AP bus for probing drivers for devices in a way that two sets of drivers are usable. Two new bitmasks 'apmask' and 'aqmask' are used to mark a subset of the APQN range for 'usable by the ap bus and the default drivers' or 'not usable by the default drivers and thus available for alternate drivers like vfio-xxx'. So an APQN which is addressed by this masking only the default drivers will be probed. In contrary an APQN which is not addressed by the masks will never be probed and bound to default drivers but onny to alternate drivers. Eventually the two masks give a way to divide the range of APQNs into two pools: one pool of APQNs used by the AP bus and the default drivers and thus via zcrypt drivers available to the userspace of the system. And another pool where no zcrypt drivers are bound to and which can be used by alternate drivers (like vfio-xxx) for their needs. This division is hot-plug save and makes sure a APQN assigned to an alternate driver is at no time somehow exploitable by the wrong party. The two masks are located in sysfs at /sys/bus/ap/apmask and /sys/bus/ap/aqmask. The mask syntax is exactly the same as the already existing mask attributes in the /sys/bus/ap directory (for example ap_usage_domain_mask and ap_control_domain_mask). By default all APQNs belong to the ap bus and the default drivers: cat /sys/bus/ap/apmask 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff cat /sys/bus/ap/aqmask 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff The masks can be changed at boot time with the kernel command line like this: ... ap.apmask=0xffff ap.aqmask=0x40 This would give these two pools: default drivers pool: adapter 0 - 15, domain 1 alternate drivers pool: adapter 0 - 15, all but domain 1 adapter 16-255, all domains The sysfs attributes for this two masks are writeable and an administrator is able to reconfigure the assignements on the fly by writing new mask values into. With changing the mask(s) a revision of the existing queue to driver bindings is done. So all APQNs which are bound to the 'wrong' driver are reprobed via kernel function device_reprobe() and thus the new correct driver will be assigned with respect of the changed apmask and aqmask bits. 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). - '+' or '-' followed by a numerical value. Valid examples are "+1", "-13", "+0x41", "-0xff" and even "+0" and "-0". Only the addressed bit in the mask is switched on ('+') or off ('-'). This patch will also be the base for an upcoming extension to the zcrypt drivers to be able to provide additional zcrypt device nodes with filtering based on ap and aq masks. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/crypto/ap_bus.c288
-rw-r--r--drivers/s390/crypto/ap_bus.h32
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c2
-rw-r--r--drivers/s390/crypto/zcrypt_cex4.c2
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c2
5 files changed, 322 insertions, 4 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index bf720ae74d61..30d7898910ea 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -34,6 +34,7 @@
34#include <linux/crypto.h> 34#include <linux/crypto.h>
35#include <linux/mod_devicetable.h> 35#include <linux/mod_devicetable.h>
36#include <linux/debugfs.h> 36#include <linux/debugfs.h>
37#include <linux/ctype.h>
37 38
38#include "ap_bus.h" 39#include "ap_bus.h"
39#include "ap_debug.h" 40#include "ap_debug.h"
@@ -51,11 +52,26 @@ static int ap_thread_flag;
51module_param_named(poll_thread, ap_thread_flag, int, 0440); 52module_param_named(poll_thread, ap_thread_flag, int, 0440);
52MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off)."); 53MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
53 54
55static char *apm_str;
56module_param_named(apmask, apm_str, charp, 0440);
57MODULE_PARM_DESC(apmask, "AP bus adapter mask.");
58
59static char *aqm_str;
60module_param_named(aqmask, aqm_str, charp, 0440);
61MODULE_PARM_DESC(aqmask, "AP bus domain mask.");
62
54static struct device *ap_root_device; 63static struct device *ap_root_device;
55 64
56DEFINE_SPINLOCK(ap_list_lock); 65DEFINE_SPINLOCK(ap_list_lock);
57LIST_HEAD(ap_card_list); 66LIST_HEAD(ap_card_list);
58 67
68/* Default permissions (card and domain masking) */
69static struct ap_perms {
70 DECLARE_BITMAP(apm, AP_DEVICES);
71 DECLARE_BITMAP(aqm, AP_DOMAINS);
72} ap_perms;
73static DEFINE_MUTEX(ap_perms_mutex);
74
59static struct ap_config_info *ap_configuration; 75static struct ap_config_info *ap_configuration;
60static bool initialised; 76static bool initialised;
61 77
@@ -670,11 +686,97 @@ static struct bus_type ap_bus_type = {
670 .pm = &ap_bus_pm_ops, 686 .pm = &ap_bus_pm_ops,
671}; 687};
672 688
689static int __ap_revise_reserved(struct device *dev, void *dummy)
690{
691 int rc, card, queue, devres, drvres;
692
693 if (is_queue_dev(dev)) {
694 card = AP_QID_CARD(to_ap_queue(dev)->qid);
695 queue = AP_QID_QUEUE(to_ap_queue(dev)->qid);
696 mutex_lock(&ap_perms_mutex);
697 devres = test_bit_inv(card, ap_perms.apm)
698 && test_bit_inv(queue, ap_perms.aqm);
699 mutex_unlock(&ap_perms_mutex);
700 drvres = to_ap_drv(dev->driver)->flags
701 & AP_DRIVER_FLAG_DEFAULT;
702 if (!!devres != !!drvres) {
703 AP_DBF(DBF_DEBUG, "reprobing queue=%02x.%04x\n",
704 card, queue);
705 rc = device_reprobe(dev);
706 }
707 }
708
709 return 0;
710}
711
712static void ap_bus_revise_bindings(void)
713{
714 bus_for_each_dev(&ap_bus_type, NULL, NULL, __ap_revise_reserved);
715}
716
717int ap_owned_by_def_drv(int card, int queue)
718{
719 int rc = 0;
720
721 if (card < 0 || card >= AP_DEVICES || queue < 0 || queue >= AP_DOMAINS)
722 return -EINVAL;
723
724 mutex_lock(&ap_perms_mutex);
725
726 if (test_bit_inv(card, ap_perms.apm)
727 && test_bit_inv(queue, ap_perms.aqm))
728 rc = 1;
729
730 mutex_unlock(&ap_perms_mutex);
731
732 return rc;
733}
734EXPORT_SYMBOL(ap_owned_by_def_drv);
735
736int ap_apqn_in_matrix_owned_by_def_drv(unsigned long *apm,
737 unsigned long *aqm)
738{
739 int card, queue, rc = 0;
740
741 mutex_lock(&ap_perms_mutex);
742
743 for (card = 0; !rc && card < AP_DEVICES; card++)
744 if (test_bit_inv(card, apm) &&
745 test_bit_inv(card, ap_perms.apm))
746 for (queue = 0; !rc && queue < AP_DOMAINS; queue++)
747 if (test_bit_inv(queue, aqm) &&
748 test_bit_inv(queue, ap_perms.aqm))
749 rc = 1;
750
751 mutex_unlock(&ap_perms_mutex);
752
753 return rc;
754}
755EXPORT_SYMBOL(ap_apqn_in_matrix_owned_by_def_drv);
756
673static int ap_device_probe(struct device *dev) 757static int ap_device_probe(struct device *dev)
674{ 758{
675 struct ap_device *ap_dev = to_ap_dev(dev); 759 struct ap_device *ap_dev = to_ap_dev(dev);
676 struct ap_driver *ap_drv = to_ap_drv(dev->driver); 760 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
677 int rc; 761 int card, queue, devres, drvres, rc;
762
763 if (is_queue_dev(dev)) {
764 /*
765 * If the apqn is marked as reserved/used by ap bus and
766 * default drivers, only probe with drivers with the default
767 * flag set. If it is not marked, only probe with drivers
768 * with the default flag not set.
769 */
770 card = AP_QID_CARD(to_ap_queue(dev)->qid);
771 queue = AP_QID_QUEUE(to_ap_queue(dev)->qid);
772 mutex_lock(&ap_perms_mutex);
773 devres = test_bit_inv(card, ap_perms.apm)
774 && test_bit_inv(queue, ap_perms.aqm);
775 mutex_unlock(&ap_perms_mutex);
776 drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT;
777 if (!!devres != !!drvres)
778 return -ENODEV;
779 }
678 780
679 /* Add queue/card to list of active queues/cards */ 781 /* Add queue/card to list of active queues/cards */
680 spin_lock_bh(&ap_list_lock); 782 spin_lock_bh(&ap_list_lock);
@@ -757,6 +859,36 @@ EXPORT_SYMBOL(ap_bus_force_rescan);
757/* 859/*
758 * AP bus attributes. 860 * AP bus attributes.
759 */ 861 */
862
863static int hex2bitmap(const char *str, unsigned long *bitmap, int bits)
864{
865 int i, n, b;
866
867 /* bits needs to be a multiple of 8 */
868 if (bits & 0x07)
869 return -EINVAL;
870
871 memset(bitmap, 0, bits / 8);
872
873 if (str[0] == '0' && str[1] == 'x')
874 str++;
875 if (*str == 'x')
876 str++;
877
878 for (i = 0; isxdigit(*str) && i < bits; str++) {
879 b = hex_to_bin(*str);
880 for (n = 0; n < 4; n++)
881 if (b & (0x08 >> n))
882 set_bit_inv(i + n, bitmap);
883 i += 4;
884 }
885
886 if (i < 4 || isxdigit(*str))
887 return -EINVAL;
888
889 return 0;
890}
891
760static ssize_t ap_domain_show(struct bus_type *bus, char *buf) 892static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
761{ 893{
762 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index); 894 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
@@ -768,7 +900,8 @@ static ssize_t ap_domain_store(struct bus_type *bus,
768 int domain; 900 int domain;