From: Kazimierz Krosman <k.krosman@samsung.com>
To: akpm@linux-foundation.org, peter@hurleysoftware.com,
tj@kernel.org, vvs@virtuozzo.com, corbet@lwn.net, arnd@arndb.de,
pmladek@suse.cz, gregkh@linuxfoundation.org, daniel@zonque.org,
kay.sievers@vrfy.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, linux-api@vger.kernel.org
Cc: k.lewandowsk@samsung.com, k.krosman@samsung.com,
m.niesluchow@samsung.com, richard.weinberger@gmail.com,
b.zolnierkie@samsung.com, luto@amacapital.net,
knhoon.baik@samsung.com
Subject: [PATCH v6 6/8] kmsg: add ioctl for adding and deleting kmsg* devices
Date: Wed, 24 Feb 2016 12:53:19 +0100 [thread overview]
Message-ID: <1456314801-32738-7-git-send-email-k.krosman@samsung.com> (raw)
In-Reply-To: <1456314801-32738-1-git-send-email-k.krosman@samsung.com>
From: Marcin Niesluchowski <m.niesluchow@samsung.com>
There is no possibility to add/delete kmsg* buffers from userspace.
Adds following ioctl for main kmsg device adding and deleting
additional kmsg devices:
* KMSG_CMD_BUFFER_ADD
* KMSG_CMD_BUFFER_DEL
Signed-off-by: Marcin Niesluchowski <m.niesluchow@samsung.com>
Signed-off-by: Paul Osmialowski <p.osmialowsk@samsung.com>
[Fixed bug that allow adding more buffers than available minors]
Signed-off-by: Kazimierz Krosman <k.krosman@samsung.com>
---
Documentation/ioctl/ioctl-number.txt | 1 +
drivers/char/mem.c | 2 +-
include/linux/printk.h | 7 ++
include/uapi/linux/Kbuild | 1 +
include/uapi/linux/kmsg_ioctl.h | 30 +++++++++
kernel/printk/kmsg.c | 124 ++++++++++++++++++++++++++++++++++-
kernel/printk/printk.h | 1 +
7 files changed, 164 insertions(+), 2 deletions(-)
create mode 100644 include/uapi/linux/kmsg_ioctl.h
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 91261a3..4949aac 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -319,6 +319,7 @@ Code Seq#(hex) Include File Comments
<mailto:vgo@ratio.de>
0xB1 00-1F PPPoX <mailto:mostrows@styx.uwaterloo.ca>
0xB3 00 linux/mmc/ioctl.h
+0xBB 00-02 uapi/linux/kmsg_ioctl.h
0xC0 00-0F linux/usb/iowarrior.h
0xCA 00-0F uapi/misc/cxl.h
0xCA 80-8F uapi/scsi/cxlflash_ioctl.h
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index aa68923..4b63acd 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -808,7 +808,7 @@ static int memory_open(struct inode *inode, struct file *filp)
minor = iminor(inode);
if (minor >= ARRAY_SIZE(devlist))
- return kmsg_memory_open(inode, filp);
+ return kmsg_memory_open_ext(inode, filp);
dev = &devlist[minor];
if (!dev->fops)
diff --git a/include/linux/printk.h b/include/linux/printk.h
index c146ee4..c204cdc 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -427,9 +427,11 @@ struct inode;
extern struct class *mem_class;
extern const struct file_operations kmsg_fops;
+extern const struct file_operations kmsg_fops_ext;
extern struct device *init_kmsg(int minor, umode_t mode);
extern int kmsg_memory_open(struct inode *inode, struct file *filp);
+extern int kmsg_memory_open_ext(struct inode *inode, struct file *filp);
extern int kmsg_mode(int minor, umode_t *mode);
extern int kmsg_sys_buffer_add(size_t size, umode_t mode);
extern void kmsg_sys_buffer_del(int minor);
@@ -446,6 +448,11 @@ static inline int kmsg_memory_open(struct inode *inode, struct file *filp)
return -ENXIO;
}
+static inline int kmsg_memory_open_ext(struct inode *inode, struct file *filp)
+{
+ return -ENXIO;
+}
+
static inline int kmsg_mode(int minor, umode_t *mode)
{
return -ENXIO;
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index ebd10e6..8a6b3ec 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -226,6 +226,7 @@ header-y += kernel-page-flags.h
header-y += kexec.h
header-y += keyboard.h
header-y += keyctl.h
+header-y += kmsg_ioctl.h
ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm.h \
$(srctree)/arch/$(SRCARCH)/include/asm/kvm.h),)
diff --git a/include/uapi/linux/kmsg_ioctl.h b/include/uapi/linux/kmsg_ioctl.h
new file mode 100644
index 0000000..96e7930
--- /dev/null
+++ b/include/uapi/linux/kmsg_ioctl.h
@@ -0,0 +1,30 @@
+/*
+ * This is ioctl include for kmsg* devices
+ */
+
+#ifndef _KMSG_IOCTL_H_
+#define _KMSG_IOCTL_H_
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+struct kmsg_cmd_buffer_add {
+ __u64 size;
+ __u32 mode;
+ __u32 minor;
+};
+
+#define KMSG_IOCTL_MAGIC 0xBB
+
+/*
+ * A ioctl interface for kmsg device.
+ *
+ * KMSG_CMD_BUFFER_ADD: Creates additional kmsg device based on its size
+ * and mode. Minor of created device is put.
+ * KMSG_CMD_BUFFER_DEL: Removes additional kmsg device based on its minor
+ */
+#define KMSG_CMD_BUFFER_ADD _IOWR(KMSG_IOCTL_MAGIC, 0x00, \
+ struct kmsg_cmd_buffer_add)
+#define KMSG_CMD_BUFFER_DEL _IOW(KMSG_IOCTL_MAGIC, 0x01, int)
+
+#endif
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 82bc282..4bf36cd 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -23,8 +23,12 @@
#include <asm/uaccess.h>
+#include <uapi/linux/kmsg_ioctl.h>
+
#include "printk.h"
+#define KMSG_MAX_MINOR_LEN 20
+
/* /dev/kmsg - userspace message inject/listen interface */
struct devkmsg_user {
u64 seq;
@@ -408,6 +412,117 @@ const struct file_operations kmsg_fops = {
.release = devkmsg_release,
};
+static int kmsg_open_ext(struct inode *inode, struct file *file)
+{
+ return kmsg_fops.open(inode, file);
+}
+
+static ssize_t kmsg_write_iter_ext(struct kiocb *iocb, struct iov_iter *from)
+{
+ return kmsg_fops.write_iter(iocb, from);
+}
+
+static ssize_t kmsg_read_ext(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return kmsg_fops.read(file, buf, count, ppos);
+}
+
+static loff_t kmsg_llseek_ext(struct file *file, loff_t offset, int whence)
+{
+ return kmsg_fops.llseek(file, offset, whence);
+}
+
+static unsigned int kmsg_poll_ext(struct file *file,
+ struct poll_table_struct *wait)
+{
+ return kmsg_fops.poll(file, wait);
+}
+
+static long kmsg_ioctl_buffers(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ struct kmsg_cmd_buffer_add cmd_buffer_add;
+ char name[4 + KMSG_MAX_MINOR_LEN + 1];
+ struct device *dev;
+ int minor;
+
+ if (iminor(file->f_inode) != log_buf.minor)
+ return -ENOTTY;
+
+ switch (cmd) {
+ case KMSG_CMD_BUFFER_ADD:
+ if (copy_from_user(&cmd_buffer_add, argp,
+ sizeof(struct kmsg_cmd_buffer_add)))
+ return -EFAULT;
+ minor = kmsg_sys_buffer_add(cmd_buffer_add.size,
+ cmd_buffer_add.mode);
+ if (minor < 0)
+ return minor;
+ sprintf(name, "kmsg%d", minor);
+ dev = device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
+ NULL, name);
+ if (IS_ERR(dev)) {
+ kmsg_sys_buffer_del(minor);
+ return PTR_ERR(dev);
+ }
+ cmd_buffer_add.minor = minor;
+ if (copy_to_user(argp, &cmd_buffer_add,
+ sizeof(struct kmsg_cmd_buffer_add))) {
+ device_destroy(mem_class, MKDEV(MEM_MAJOR, minor));
+ kmsg_sys_buffer_del(minor);
+ return -EFAULT;
+ }
+ return 0;
+ case KMSG_CMD_BUFFER_DEL:
+ if (copy_from_user(&minor, argp, sizeof(minor)))
+ return -EFAULT;
+ if (minor <= log_buf.minor)
+ return -EINVAL;
+ device_destroy(mem_class, MKDEV(MEM_MAJOR, minor));
+ kmsg_sys_buffer_del(minor);
+ return 0;
+ }
+ return -ENOTTY;
+}
+
+static long kmsg_unlocked_ioctl_ext(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ long ret = kmsg_ioctl_buffers(file, cmd, arg);
+
+ if (ret == -ENOTTY)
+ return kmsg_fops.unlocked_ioctl(file, cmd, arg);
+ return ret;
+}
+
+static long kmsg_compat_ioctl_ext(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ long ret = kmsg_ioctl_buffers(file, cmd, arg);
+
+ if (ret == -ENOTTY)
+ return kmsg_fops.compat_ioctl(file, cmd, arg);
+ return ret;
+}
+
+static int kmsg_release_ext(struct inode *inode, struct file *file)
+{
+ return kmsg_fops.release(inode, file);
+}
+
+const struct file_operations kmsg_fops_ext = {
+ .open = kmsg_open_ext,
+ .read = kmsg_read_ext,
+ .write_iter = kmsg_write_iter_ext,
+ .llseek = kmsg_llseek_ext,
+ .poll = kmsg_poll_ext,
+ .unlocked_ioctl = kmsg_unlocked_ioctl_ext,
+ .compat_ioctl = kmsg_compat_ioctl_ext,
+ .release = kmsg_release_ext,
+};
+
/* Should be used for device registration */
struct device *init_kmsg(int minor, umode_t mode)
{
@@ -424,6 +539,13 @@ int kmsg_memory_open(struct inode *inode, struct file *filp)
return kmsg_fops.open(inode, filp);
}
+int kmsg_memory_open_ext(struct inode *inode, struct file *filp)
+{
+ filp->f_op = &kmsg_fops_ext;
+
+ return kmsg_fops_ext.open(inode, filp);
+}
+
int kmsg_mode(int minor, umode_t *mode)
{
int ret = -ENXIO;
@@ -486,7 +608,7 @@ int kmsg_sys_buffer_add(size_t size, umode_t mode)
minor = log_b->minor;
}
- if (!(minor & MINORMASK)) {
+ if (!(minor & MINORMASK) || (minor & MINORMASK) >= KMSG_NUM_MAX) {
kref_put(&log_b->refcount, log_buf_release);
spin_unlock_irqrestore(&kmsg_sys_list_lock, flags);
return -ERANGE;
diff --git a/kernel/printk/printk.h b/kernel/printk/printk.h
index a873c27..141f536 100644
--- a/kernel/printk/printk.h
+++ b/kernel/printk/printk.h
@@ -11,6 +11,7 @@
#define PREFIX_MAX 32
#define LOG_LINE_MAX (1024 - PREFIX_MAX)
+#define KMSG_NUM_MAX 255
#define LOG_LEVEL(v) ((v) & 0x07)
#define LOG_FACILITY(v) ((v) >> 3 & 0xff)
--
1.9.1
next prev parent reply other threads:[~2016-02-24 11:54 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-24 11:53 [PATCH v6 0/8] Additional kmsg devices Kazimierz Krosman
2016-02-24 11:53 ` [PATCH v6 1/8] printk: extract kmsg-related routines from printk.c to kmsg.c Kazimierz Krosman
2016-02-24 11:53 ` [PATCH v6 2/8] printk: add one function for storing log in proper format Kazimierz Krosman
2016-02-24 11:53 ` [PATCH v6 3/8] kmsg: introduce additional kmsg devices support Kazimierz Krosman
2016-02-26 14:05 ` Petr Mladek
2016-02-24 11:53 ` [PATCH v6 4/8] kmsg: add additional buffers support to memory class Kazimierz Krosman
2016-02-24 11:53 ` [PATCH v6 5/8] kmsg: add function for adding and deleting additional buffers Kazimierz Krosman
2016-02-24 11:53 ` Kazimierz Krosman [this message]
2016-02-24 11:53 ` [PATCH v6 7/8] kmsg: add ioctl for kmsg* devices operating on buffers Kazimierz Krosman
2016-02-24 11:53 ` [PATCH v6 8/8] kmsg: selftests Kazimierz Krosman
2016-02-25 21:47 ` [PATCH v6 0/8] Additional kmsg devices Tejun Heo
2016-02-26 13:22 ` Kazimierz Krosman
2016-02-26 14:47 ` Petr Mladek
2016-02-27 11:54 ` Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1456314801-32738-7-git-send-email-k.krosman@samsung.com \
--to=k.krosman@samsung.com \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=b.zolnierkie@samsung.com \
--cc=corbet@lwn.net \
--cc=daniel@zonque.org \
--cc=gregkh@linuxfoundation.org \
--cc=k.lewandowsk@samsung.com \
--cc=kay.sievers@vrfy.org \
--cc=knhoon.baik@samsung.com \
--cc=linux-api@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=m.niesluchow@samsung.com \
--cc=peter@hurleysoftware.com \
--cc=pmladek@suse.cz \
--cc=richard.weinberger@gmail.com \
--cc=tj@kernel.org \
--cc=vvs@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®