mirror of https://github.com/torvalds/linux.git
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>
This commit is contained in:
parent
8babcc2b6a
commit
46030379f1
|
|
@ -86,8 +86,13 @@ DEFINE_SPINLOCK(ap_queues_lock);
|
|||
/* Default permissions (ioctl, card and domain masking) */
|
||||
struct ap_perms ap_perms;
|
||||
EXPORT_SYMBOL(ap_perms);
|
||||
/* true if apmask and/or aqmask are NOT default */
|
||||
bool ap_apmask_aqmask_in_use;
|
||||
/* counter for how many driver_overrides are currently active */
|
||||
int ap_driver_override_ctr;
|
||||
/*
|
||||
* Mutex for consistent read and write of the ap_perms struct
|
||||
* Mutex for consistent read and write of the ap_perms struct,
|
||||
* ap_apmask_aqmask_in_use, ap_driver_override_ctr
|
||||
* and the ap bus sysfs attributes apmask and aqmask.
|
||||
*/
|
||||
DEFINE_MUTEX(ap_attr_mutex);
|
||||
|
|
@ -1542,18 +1547,31 @@ static int apmask_commit(unsigned long *newapm)
|
|||
|
||||
memcpy(ap_perms.apm, newapm, APMASKSIZE);
|
||||
|
||||
/*
|
||||
* Update ap_apmask_aqmask_in_use. Note that the
|
||||
* ap_attr_mutex has to be obtained here.
|
||||
*/
|
||||
ap_apmask_aqmask_in_use =
|
||||
bitmap_full(ap_perms.apm, AP_DEVICES) &&
|
||||
bitmap_full(ap_perms.aqm, AP_DOMAINS) ?
|
||||
false : true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t apmask_store(const struct bus_type *bus, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
int rc, changes = 0;
|
||||
DECLARE_BITMAP(newapm, AP_DEVICES);
|
||||
int rc = -EINVAL, changes = 0;
|
||||
|
||||
if (mutex_lock_interruptible(&ap_attr_mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
/* Do not allow apmask/aqmask if driver override is active */
|
||||
if (ap_driver_override_ctr)
|
||||
goto done;
|
||||
|
||||
rc = ap_parse_bitmap_str(buf, ap_perms.apm, AP_DEVICES, newapm);
|
||||
if (rc)
|
||||
goto done;
|
||||
|
|
@ -1636,18 +1654,31 @@ static int aqmask_commit(unsigned long *newaqm)
|
|||
|
||||
memcpy(ap_perms.aqm, newaqm, AQMASKSIZE);
|
||||
|
||||
/*
|
||||
* Update ap_apmask_aqmask_in_use. Note that the
|
||||
* ap_attr_mutex has to be obtained here.
|
||||
*/
|
||||
ap_apmask_aqmask_in_use =
|
||||
bitmap_full(ap_perms.apm, AP_DEVICES) &&
|
||||
bitmap_full(ap_perms.aqm, AP_DOMAINS) ?
|
||||
false : true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t aqmask_store(const struct bus_type *bus, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
int rc, changes = 0;
|
||||
DECLARE_BITMAP(newaqm, AP_DOMAINS);
|
||||
int rc = -EINVAL, changes = 0;
|
||||
|
||||
if (mutex_lock_interruptible(&ap_attr_mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
/* Do not allow apmask/aqmask if driver override is active */
|
||||
if (ap_driver_override_ctr)
|
||||
goto done;
|
||||
|
||||
rc = ap_parse_bitmap_str(buf, ap_perms.aqm, AP_DOMAINS, newaqm);
|
||||
if (rc)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -281,6 +281,8 @@ struct ap_perms {
|
|||
};
|
||||
|
||||
extern struct ap_perms ap_perms;
|
||||
extern bool ap_apmask_aqmask_in_use;
|
||||
extern int ap_driver_override_ctr;
|
||||
extern struct mutex ap_attr_mutex;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -755,13 +755,30 @@ static ssize_t driver_override_store(struct device *dev,
|
|||
{
|
||||
struct ap_queue *aq = to_ap_queue(dev);
|
||||
struct ap_device *ap_dev = &aq->ap_dev;
|
||||
int rc;
|
||||
int rc = -EINVAL;
|
||||
bool old_value;
|
||||
|
||||
if (mutex_lock_interruptible(&ap_attr_mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
/* Do not allow driver override if apmask/aqmask is in use */
|
||||
if (ap_apmask_aqmask_in_use)
|
||||
goto out;
|
||||
|
||||
old_value = ap_dev->driver_override ? true : false;
|
||||
rc = driver_set_override(dev, &ap_dev->driver_override, buf, count);
|
||||
if (rc)
|
||||
return rc;
|
||||
goto out;
|
||||
if (old_value && !ap_dev->driver_override)
|
||||
--ap_driver_override_ctr;
|
||||
else if (!old_value && ap_dev->driver_override)
|
||||
++ap_driver_override_ctr;
|
||||
|
||||
return count;
|
||||
rc = count;
|
||||
|
||||
out:
|
||||
mutex_unlock(&ap_attr_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(driver_override);
|
||||
|
|
|
|||
Loading…
Reference in New Issue