+int debugfs_doint(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ int rc;
+
+ if (!*lenp || *ppos) {
+ *lenp = 0;
+ return 0;
+ }
+
+ if (write) {
+ char *kbuf = memdup_user_nul(buffer, *lenp);
+ int val;
+
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
+
+ rc = kstrtoint(kbuf, 0, &val);
+ kfree(kbuf);
+ if (!rc) {
+ if (table->extra1 && val < *(int *)table->extra1)
+ val = *(int *)table->extra1;
+ if (table->extra2 && val > *(int *)table->extra2)
+ val = *(int *)table->extra2;
+ *(int *)table->data = val;
+ }
+ *ppos += *lenp;
+ } else {
+ char kbuf[64/3+3];
+
+ rc = scnprintf(kbuf, sizeof(kbuf), "%u\n", *(int *)table->data);
+ if (copy_to_user(buffer, kbuf, rc))
+ rc = -EFAULT;
+ else {
+ *lenp = rc;
+ *ppos += rc;
+ }
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL(debugfs_doint);
+
+static int debugfs_dou64(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ int rc;
+
+ if (!*lenp || *ppos) {
+ *lenp = 0;
+ return 0;
+ }
+
+ if (write) {
+ char *kbuf = memdup_user_nul(buffer, *lenp);
+ unsigned long long val;
+
+ if (IS_ERR(kbuf))
+ return PTR_ERR(kbuf);
+
+ rc = kstrtoull(kbuf, 0, &val);
+ kfree(kbuf);
+ if (!rc)
+ *(u64 *)table->data = val;
+ *ppos += *lenp;
+ } else {
+ char kbuf[64/3+3];
+
+ rc = scnprintf(kbuf, sizeof(kbuf), "%llu\n",
+ (unsigned long long)*(u64 *)table->data);
+ if (copy_to_user(buffer, kbuf, rc))
+ rc = -EFAULT;
+ else {
+ *lenp = rc;
+ *ppos += rc;
+ }
+ }
+
+ return rc;
+}
+
+static int debugfs_dostring(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ int len = *lenp;
+ char *kbuf = table->data;
+
+ if (!len || *ppos) {
+ *lenp = 0;
+ return 0;
+ }
+ if (len > table->maxlen)
+ len = table->maxlen;
+ if (write) {
+ if (copy_from_user(kbuf, buffer, len))
+ return -EFAULT;
+ memset(kbuf+len, 0, table->maxlen - len);
+ *ppos = *lenp;
+ } else {
+ len = strnlen(kbuf, len);
+ if (copy_to_user(buffer, kbuf, len))
+ return -EFAULT;
+ if (len < *lenp) {
+ if (copy_to_user(buffer+len, "\n", 1))
+ return -EFAULT;
+ len += 1;
+ }
+ *ppos += len;
+ *lenp -= len;
+ }
+ return len;
+}
+