git: 88ca9c822616 - stable/14 - LinuxKPI: Add DEFINE_DEBUGFS_ATTRIBUTE_SIGNED to linux/debugfs.h

From: Vladimir Kondratyev <wulf_at_FreeBSD.org>
Date: Thu, 01 Aug 2024 22:27:54 UTC
The branch stable/14 has been updated by wulf:

URL: https://cgit.FreeBSD.org/src/commit/?id=88ca9c8226165e31991c25a246d825706c8ec2e7

commit 88ca9c8226165e31991c25a246d825706c8ec2e7
Author:     Vladimir Kondratyev <wulf@FreeBSD.org>
AuthorDate: 2024-06-26 20:51:34 +0000
Commit:     Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2024-08-01 21:09:41 +0000

    LinuxKPI: Add DEFINE_DEBUGFS_ATTRIBUTE_SIGNED to linux/debugfs.h
    
    Sponsored by:   Serenity CyberSecurity, LLC
    MFC after:      1 week
    Reviewed by:    manu
    Differential Revision:  https://reviews.freebsd.org/D45615
    
    (cherry picked from commit 8c5c572125665e3fd8a033d1a8b0a370e5a43e24)
---
 sys/compat/linuxkpi/common/include/linux/debugfs.h |  2 ++
 sys/compat/linuxkpi/common/include/linux/fs.h      | 12 ++++++++--
 sys/compat/linuxkpi/common/src/linux_simple_attr.c | 27 ++++++++++++++++++----
 3 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/debugfs.h b/sys/compat/linuxkpi/common/include/linux/debugfs.h
index 470b50cb730c..13186334d75c 100644
--- a/sys/compat/linuxkpi/common/include/linux/debugfs.h
+++ b/sys/compat/linuxkpi/common/include/linux/debugfs.h
@@ -88,6 +88,8 @@ void debugfs_remove_recursive(struct dentry *dentry);
 
 #define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt) \
 	DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)
+#define DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt) \
+	DEFINE_SIMPLE_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt)
 
 void debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent,
     bool *value);
diff --git a/sys/compat/linuxkpi/common/include/linux/fs.h b/sys/compat/linuxkpi/common/include/linux/fs.h
index ebe262926e97..74288f9cd461 100644
--- a/sys/compat/linuxkpi/common/include/linux/fs.h
+++ b/sys/compat/linuxkpi/common/include/linux/fs.h
@@ -375,7 +375,7 @@ simple_read_from_buffer(void __user *dest, size_t read_size, loff_t *ppos,
 
 MALLOC_DECLARE(M_LSATTR);
 
-#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)		\
+#define	__DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt, __wrfunc)\
 static inline int							\
 __fops ## _open(struct inode *inode, struct file *filp)			\
 {									\
@@ -386,10 +386,15 @@ static const struct file_operations __fops = {				\
 	.open	 = __fops ## _open,					\
 	.release = simple_attr_release,					\
 	.read	 = simple_attr_read,					\
-	.write	 = simple_attr_write,					\
+	.write	 = __wrfunc,						\
 	.llseek	 = no_llseek						\
 }
 
+#define	DEFINE_SIMPLE_ATTRIBUTE(fops, get, set, fmt)			\
+	__DEFINE_SIMPLE_ATTRIBUTE(fops, get, set, fmt, simple_attr_write)
+#define	DEFINE_SIMPLE_ATTRIBUTE_SIGNED(fops, get, set, fmt)		\
+	__DEFINE_SIMPLE_ATTRIBUTE(fops, get, set, fmt, simple_attr_write_signed)
+
 int simple_attr_open(struct inode *inode, struct file *filp,
     int (*get)(void *, uint64_t *), int (*set)(void *, uint64_t),
     const char *fmt);
@@ -400,4 +405,7 @@ ssize_t simple_attr_read(struct file *filp, char *buf, size_t read_size, loff_t
 
 ssize_t simple_attr_write(struct file *filp, const char *buf, size_t write_size, loff_t *ppos);
 
+ssize_t simple_attr_write_signed(struct file *filp, const char *buf,
+	    size_t write_size, loff_t *ppos);
+
 #endif /* _LINUXKPI_LINUX_FS_H_ */
diff --git a/sys/compat/linuxkpi/common/src/linux_simple_attr.c b/sys/compat/linuxkpi/common/src/linux_simple_attr.c
index 27dc7beb8707..ecd1e135026c 100644
--- a/sys/compat/linuxkpi/common/src/linux_simple_attr.c
+++ b/sys/compat/linuxkpi/common/src/linux_simple_attr.c
@@ -139,12 +139,13 @@ unlock:
 }
 
 /*
- * simple_attr_write: write contents of buffer into simple attribute file
+ * simple_attr_write_common: write contents of buffer into simple attribute file
  *
  * @filp: file pointer
  * @buf: kernel space buffer
  * @write_size: number bytes to be transferred
  * @ppos: starting pointer position for transfer
+ * @is_signed: signedness of data in @buf
  *
  * The simple_attr structure is stored in filp->private_data.
  * Convert the @buf string to unsigned long long.
@@ -154,8 +155,9 @@ unlock:
  * On success, number of bytes written to simple attr
  * On failure, negative signed ERRNO
  */
-ssize_t
-simple_attr_write(struct file *filp, const char *buf, size_t write_size, loff_t *ppos)
+static ssize_t
+simple_attr_write_common(struct file *filp, const char *buf, size_t write_size,
+    loff_t *ppos, bool is_signed)
 {
 	struct simple_attr *sattr;
 	unsigned long long data;
@@ -173,7 +175,10 @@ simple_attr_write(struct file *filp, const char *buf, size_t write_size, loff_t
 
 	mutex_lock(&sattr->mutex);
 
-	ret = kstrtoull(buf + *ppos, 0, &data);
+	if (is_signed)
+		ret = kstrtoll(buf + *ppos, 0, &data);
+	else
+		ret = kstrtoull(buf + *ppos, 0, &data);
 	if (ret)
 		goto unlock;
 
@@ -187,3 +192,17 @@ unlock:
 	mutex_unlock(&sattr->mutex);
 	return (ret);
 }
+
+ssize_t
+simple_attr_write(struct file *filp, const char *buf, size_t write_size,
+    loff_t *ppos)
+{
+	return (simple_attr_write_common(filp, buf,  write_size, ppos, false));
+}
+
+ssize_t
+simple_attr_write_signed(struct file *filp, const char *buf, size_t write_size,
+    loff_t *ppos)
+{
+	return (simple_attr_write_common(filp, buf,  write_size, ppos, true));
+}