git: 8c5c57212566 - main - LinuxKPI: Add DEFINE_DEBUGFS_ATTRIBUTE_SIGNED to linux/debugfs.h

From: Vladimir Kondratyev <wulf_at_FreeBSD.org>
Date: Wed, 26 Jun 2024 20:54:47 UTC
The branch main has been updated by wulf:

URL: https://cgit.FreeBSD.org/src/commit/?id=8c5c572125665e3fd8a033d1a8b0a370e5a43e24

commit 8c5c572125665e3fd8a033d1a8b0a370e5a43e24
Author:     Vladimir Kondratyev <wulf@FreeBSD.org>
AuthorDate: 2024-06-26 20:51:34 +0000
Commit:     Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2024-06-26 20:51:34 +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
---
 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 a28d5bf97121..9c763168b0f4 100644
--- a/sys/compat/linuxkpi/common/include/linux/fs.h
+++ b/sys/compat/linuxkpi/common/include/linux/fs.h
@@ -374,7 +374,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)			\
 {									\
@@ -385,10 +385,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);
@@ -399,4 +404,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 1bdacd7c1491..8cc9ec7ecbc9 100644
--- a/sys/compat/linuxkpi/common/src/linux_simple_attr.c
+++ b/sys/compat/linuxkpi/common/src/linux_simple_attr.c
@@ -138,12 +138,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.
@@ -153,8 +154,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;
@@ -172,7 +174,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;
 
@@ -186,3 +191,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));
+}