scsi: hisi_sas: Limit users changing debugfs BIST count value
authorXiang Chen <chenxiang66@hisilicon.com>
Thu, 24 Feb 2022 11:51:28 +0000 (19:51 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Apr 2022 18:59:07 +0000 (20:59 +0200)
[ Upstream commit 286ce4c65fbdf5eb9d4d5f4e4997c4e32bf1b073 ]

Add a file operation for "cnt" file under bist directory, so users can only
read "cnt" or clear "cnt" to zero, but cannot randomly modify.

Link: https://lore.kernel.org/r/1645703489-87194-6-git-send-email-john.garry@huawei.com
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: Qi Liu <liuqi115@huawei.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c

index 6010aca..1f5e068 100644 (file)
@@ -3968,6 +3968,54 @@ static const struct file_operations debugfs_bist_phy_v3_hw_fops = {
        .owner = THIS_MODULE,
 };
 
+static ssize_t debugfs_bist_cnt_v3_hw_write(struct file *filp,
+                                       const char __user *buf,
+                                       size_t count, loff_t *ppos)
+{
+       struct seq_file *m = filp->private_data;
+       struct hisi_hba *hisi_hba = m->private;
+       unsigned int cnt;
+       int val;
+
+       if (hisi_hba->debugfs_bist_enable)
+               return -EPERM;
+
+       val = kstrtouint_from_user(buf, count, 0, &cnt);
+       if (val)
+               return val;
+
+       if (cnt)
+               return -EINVAL;
+
+       hisi_hba->debugfs_bist_cnt = 0;
+       return count;
+}
+
+static int debugfs_bist_cnt_v3_hw_show(struct seq_file *s, void *p)
+{
+       struct hisi_hba *hisi_hba = s->private;
+
+       seq_printf(s, "%u\n", hisi_hba->debugfs_bist_cnt);
+
+       return 0;
+}
+
+static int debugfs_bist_cnt_v3_hw_open(struct inode *inode,
+                                         struct file *filp)
+{
+       return single_open(filp, debugfs_bist_cnt_v3_hw_show,
+                          inode->i_private);
+}
+
+static const struct file_operations debugfs_bist_cnt_v3_hw_ops = {
+       .open = debugfs_bist_cnt_v3_hw_open,
+       .read = seq_read,
+       .write = debugfs_bist_cnt_v3_hw_write,
+       .llseek = seq_lseek,
+       .release = single_release,
+       .owner = THIS_MODULE,
+};
+
 static const struct {
        int             value;
        char            *name;
@@ -4605,8 +4653,8 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba)
        debugfs_create_file("phy_id", 0600, hisi_hba->debugfs_bist_dentry,
                            hisi_hba, &debugfs_bist_phy_v3_hw_fops);
 
-       debugfs_create_u32("cnt", 0600, hisi_hba->debugfs_bist_dentry,
-                          &hisi_hba->debugfs_bist_cnt);
+       debugfs_create_file("cnt", 0600, hisi_hba->debugfs_bist_dentry,
+                           hisi_hba, &debugfs_bist_cnt_v3_hw_ops);
 
        debugfs_create_file("loopback_mode", 0600,
                            hisi_hba->debugfs_bist_dentry,