Skip to content

Commit 4603037

Browse files
hfreudehcahca
authored andcommitted
s390/ap: Restrict driver_override versus apmask and aqmask use
Introduce a restriction for the driver_override feature versus apmask and aqmask: - driver_override is only allowed when the apmask and aqmask values both are default (=0xffff..ffff). - apmask and aqmask modifications are only allowed when there is no driver_override on any AP device active. So in the end the user is restricted to choose to either use apmask/apmask to divide the AP devices into host owned and vfio owned or use the driver_override feature but not mix these two approaches. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Holger Dengler <dengler@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent 8babcc2 commit 4603037

3 files changed

Lines changed: 56 additions & 6 deletions

File tree

drivers/s390/crypto/ap_bus.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,13 @@ DEFINE_SPINLOCK(ap_queues_lock);
8686
/* Default permissions (ioctl, card and domain masking) */
8787
struct ap_perms ap_perms;
8888
EXPORT_SYMBOL(ap_perms);
89+
/* true if apmask and/or aqmask are NOT default */
90+
bool ap_apmask_aqmask_in_use;
91+
/* counter for how many driver_overrides are currently active */
92+
int ap_driver_override_ctr;
8993
/*
90-
* Mutex for consistent read and write of the ap_perms struct
94+
* Mutex for consistent read and write of the ap_perms struct,
95+
* ap_apmask_aqmask_in_use, ap_driver_override_ctr
9196
* and the ap bus sysfs attributes apmask and aqmask.
9297
*/
9398
DEFINE_MUTEX(ap_attr_mutex);
@@ -1542,18 +1547,31 @@ static int apmask_commit(unsigned long *newapm)
15421547

15431548
memcpy(ap_perms.apm, newapm, APMASKSIZE);
15441549

1550+
/*
1551+
* Update ap_apmask_aqmask_in_use. Note that the
1552+
* ap_attr_mutex has to be obtained here.
1553+
*/
1554+
ap_apmask_aqmask_in_use =
1555+
bitmap_full(ap_perms.apm, AP_DEVICES) &&
1556+
bitmap_full(ap_perms.aqm, AP_DOMAINS) ?
1557+
false : true;
1558+
15451559
return 0;
15461560
}
15471561

15481562
static ssize_t apmask_store(const struct bus_type *bus, const char *buf,
15491563
size_t count)
15501564
{
1551-
int rc, changes = 0;
15521565
DECLARE_BITMAP(newapm, AP_DEVICES);
1566+
int rc = -EINVAL, changes = 0;
15531567

15541568
if (mutex_lock_interruptible(&ap_attr_mutex))
15551569
return -ERESTARTSYS;
15561570

1571+
/* Do not allow apmask/aqmask if driver override is active */
1572+
if (ap_driver_override_ctr)
1573+
goto done;
1574+
15571575
rc = ap_parse_bitmap_str(buf, ap_perms.apm, AP_DEVICES, newapm);
15581576
if (rc)
15591577
goto done;
@@ -1636,18 +1654,31 @@ static int aqmask_commit(unsigned long *newaqm)
16361654

16371655
memcpy(ap_perms.aqm, newaqm, AQMASKSIZE);
16381656

1657+
/*
1658+
* Update ap_apmask_aqmask_in_use. Note that the
1659+
* ap_attr_mutex has to be obtained here.
1660+
*/
1661+
ap_apmask_aqmask_in_use =
1662+
bitmap_full(ap_perms.apm, AP_DEVICES) &&
1663+
bitmap_full(ap_perms.aqm, AP_DOMAINS) ?
1664+
false : true;
1665+
16391666
return 0;
16401667
}
16411668

16421669
static ssize_t aqmask_store(const struct bus_type *bus, const char *buf,
16431670
size_t count)
16441671
{
1645-
int rc, changes = 0;
16461672
DECLARE_BITMAP(newaqm, AP_DOMAINS);
1673+
int rc = -EINVAL, changes = 0;
16471674

16481675
if (mutex_lock_interruptible(&ap_attr_mutex))
16491676
return -ERESTARTSYS;
16501677

1678+
/* Do not allow apmask/aqmask if driver override is active */
1679+
if (ap_driver_override_ctr)
1680+
goto done;
1681+
16511682
rc = ap_parse_bitmap_str(buf, ap_perms.aqm, AP_DOMAINS, newaqm);
16521683
if (rc)
16531684
goto done;

drivers/s390/crypto/ap_bus.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ struct ap_perms {
281281
};
282282

283283
extern struct ap_perms ap_perms;
284+
extern bool ap_apmask_aqmask_in_use;
285+
extern int ap_driver_override_ctr;
284286
extern struct mutex ap_attr_mutex;
285287

286288
/*

drivers/s390/crypto/ap_queue.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -755,13 +755,30 @@ static ssize_t driver_override_store(struct device *dev,
755755
{
756756
struct ap_queue *aq = to_ap_queue(dev);
757757
struct ap_device *ap_dev = &aq->ap_dev;
758-
int rc;
758+
int rc = -EINVAL;
759+
bool old_value;
760+
761+
if (mutex_lock_interruptible(&ap_attr_mutex))
762+
return -ERESTARTSYS;
763+
764+
/* Do not allow driver override if apmask/aqmask is in use */
765+
if (ap_apmask_aqmask_in_use)
766+
goto out;
759767

768+
old_value = ap_dev->driver_override ? true : false;
760769
rc = driver_set_override(dev, &ap_dev->driver_override, buf, count);
761770
if (rc)
762-
return rc;
771+
goto out;
772+
if (old_value && !ap_dev->driver_override)
773+
--ap_driver_override_ctr;
774+
else if (!old_value && ap_dev->driver_override)
775+
++ap_driver_override_ctr;
763776

764-
return count;
777+
rc = count;
778+
779+
out:
780+
mutex_unlock(&ap_attr_mutex);
781+
return rc;
765782
}
766783

767784
static DEVICE_ATTR_RW(driver_override);

0 commit comments

Comments
 (0)