Commit 75c0b0e1 authored by Arnd Bergmann's avatar Arnd Bergmann

compat_ioctl: scsi: handle HDIO commands from drivers

The ata_sas_scsi_ioctl() function implements a number of HDIO_* commands
for SCSI devices, it is used by all libata drivers as well as a few
drivers that support SAS attached SATA drives.

The only command that is not safe for compat ioctls here is
HDIO_GET_32BIT. Change the implementation to check for in_compat_syscall()
in order to do both cases correctly, and change all callers to use it
as both native and compat callback pointers, including the indirect
callers through sas_ioctl and ata_scsi_ioctl.
Reviewed-by: default avatarBen Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 64cbfa96
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* - http://www.t13.org/ * - http://www.t13.org/
*/ */
#include <linux/compat.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
...@@ -761,6 +762,10 @@ static int ata_ioc32(struct ata_port *ap) ...@@ -761,6 +762,10 @@ static int ata_ioc32(struct ata_port *ap)
return 0; return 0;
} }
/*
* This handles both native and compat commands, so anything added
* here must have a compatible argument, or check in_compat_syscall()
*/
int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev, int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
unsigned int cmd, void __user *arg) unsigned int cmd, void __user *arg)
{ {
...@@ -773,6 +778,10 @@ int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev, ...@@ -773,6 +778,10 @@ int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
spin_lock_irqsave(ap->lock, flags); spin_lock_irqsave(ap->lock, flags);
val = ata_ioc32(ap); val = ata_ioc32(ap);
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
#ifdef CONFIG_COMPAT
if (in_compat_syscall())
return put_user(val, (compat_ulong_t __user *)arg);
#endif
return put_user(val, (unsigned long __user *)arg); return put_user(val, (unsigned long __user *)arg);
case HDIO_SET_32BIT: case HDIO_SET_32BIT:
......
...@@ -54,6 +54,9 @@ static struct scsi_host_template aic94xx_sht = { ...@@ -54,6 +54,9 @@ static struct scsi_host_template aic94xx_sht = {
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,
.ioctl = sas_ioctl, .ioctl = sas_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = sas_ioctl,
#endif
.track_queue_depth = 1, .track_queue_depth = 1,
}; };
......
...@@ -1772,6 +1772,9 @@ static struct scsi_host_template sht_v1_hw = { ...@@ -1772,6 +1772,9 @@ static struct scsi_host_template sht_v1_hw = {
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,
.ioctl = sas_ioctl, .ioctl = sas_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = sas_ioctl,
#endif
.shost_attrs = host_attrs_v1_hw, .shost_attrs = host_attrs_v1_hw,
.host_reset = hisi_sas_host_reset, .host_reset = hisi_sas_host_reset,
}; };
......
...@@ -3551,6 +3551,9 @@ static struct scsi_host_template sht_v2_hw = { ...@@ -3551,6 +3551,9 @@ static struct scsi_host_template sht_v2_hw = {
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,
.ioctl = sas_ioctl, .ioctl = sas_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = sas_ioctl,
#endif
.shost_attrs = host_attrs_v2_hw, .shost_attrs = host_attrs_v2_hw,
.host_reset = hisi_sas_host_reset, .host_reset = hisi_sas_host_reset,
}; };
......
...@@ -3075,6 +3075,9 @@ static struct scsi_host_template sht_v3_hw = { ...@@ -3075,6 +3075,9 @@ static struct scsi_host_template sht_v3_hw = {
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,
.ioctl = sas_ioctl, .ioctl = sas_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = sas_ioctl,
#endif
.shost_attrs = host_attrs_v3_hw, .shost_attrs = host_attrs_v3_hw,
.tag_alloc_policy = BLK_TAG_ALLOC_RR, .tag_alloc_policy = BLK_TAG_ALLOC_RR,
.host_reset = hisi_sas_host_reset, .host_reset = hisi_sas_host_reset,
......
...@@ -6727,6 +6727,9 @@ static struct scsi_host_template driver_template = { ...@@ -6727,6 +6727,9 @@ static struct scsi_host_template driver_template = {
.name = "IPR", .name = "IPR",
.info = ipr_ioa_info, .info = ipr_ioa_info,
.ioctl = ipr_ioctl, .ioctl = ipr_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ipr_ioctl,
#endif
.queuecommand = ipr_queuecommand, .queuecommand = ipr_queuecommand,
.eh_abort_handler = ipr_eh_abort, .eh_abort_handler = ipr_eh_abort,
.eh_device_reset_handler = ipr_eh_dev_reset, .eh_device_reset_handler = ipr_eh_dev_reset,
......
...@@ -168,6 +168,9 @@ static struct scsi_host_template isci_sht = { ...@@ -168,6 +168,9 @@ static struct scsi_host_template isci_sht = {
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,
.ioctl = sas_ioctl, .ioctl = sas_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = sas_ioctl,
#endif
.shost_attrs = isci_host_attrs, .shost_attrs = isci_host_attrs,
.track_queue_depth = 1, .track_queue_depth = 1,
}; };
......
...@@ -47,6 +47,9 @@ static struct scsi_host_template mvs_sht = { ...@@ -47,6 +47,9 @@ static struct scsi_host_template mvs_sht = {
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,
.ioctl = sas_ioctl, .ioctl = sas_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = sas_ioctl,
#endif
.shost_attrs = mvst_host_attrs, .shost_attrs = mvst_host_attrs,
.track_queue_depth = 1, .track_queue_depth = 1,
}; };
......
...@@ -101,6 +101,9 @@ static struct scsi_host_template pm8001_sht = { ...@@ -101,6 +101,9 @@ static struct scsi_host_template pm8001_sht = {
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,
.ioctl = sas_ioctl, .ioctl = sas_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = sas_ioctl,
#endif
.shost_attrs = pm8001_host_attrs, .shost_attrs = pm8001_host_attrs,
.track_queue_depth = 1, .track_queue_depth = 1,
}; };
......
...@@ -1109,6 +1109,11 @@ extern void ata_host_init(struct ata_host *, struct device *, struct ata_port_op ...@@ -1109,6 +1109,11 @@ extern void ata_host_init(struct ata_host *, struct device *, struct ata_port_op
extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_detect(struct scsi_host_template *sht);
extern int ata_scsi_ioctl(struct scsi_device *dev, unsigned int cmd, extern int ata_scsi_ioctl(struct scsi_device *dev, unsigned int cmd,
void __user *arg); void __user *arg);
#ifdef CONFIG_COMPAT
#define ATA_SCSI_COMPAT_IOCTL .compat_ioctl = ata_scsi_ioctl,
#else
#define ATA_SCSI_COMPAT_IOCTL /* empty */
#endif
extern int ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd); extern int ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd);
extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev, extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
unsigned int cmd, void __user *arg); unsigned int cmd, void __user *arg);
...@@ -1341,6 +1346,7 @@ extern struct device_attribute *ata_common_sdev_attrs[]; ...@@ -1341,6 +1346,7 @@ extern struct device_attribute *ata_common_sdev_attrs[];
.module = THIS_MODULE, \ .module = THIS_MODULE, \
.name = drv_name, \ .name = drv_name, \
.ioctl = ata_scsi_ioctl, \ .ioctl = ata_scsi_ioctl, \
ATA_SCSI_COMPAT_IOCTL \
.queuecommand = ata_scsi_queuecmd, \ .queuecommand = ata_scsi_queuecmd, \
.can_queue = ATA_DEF_QUEUE, \ .can_queue = ATA_DEF_QUEUE, \
.tag_alloc_policy = BLK_TAG_ALLOC_RR, \ .tag_alloc_policy = BLK_TAG_ALLOC_RR, \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment