[RFC v5 3/8] kmsg: introduce additional kmsg devices support

2015-10-27 Thread Paul Osmialowski
From: Marcin Niesluchowski 

kmsg device provides operations on cyclic logging buffer used mainly
by kernel but also in userspace by privileged processes.

Additional kmsg devices keep the same log format but may be added
dynamically with custom size.

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 fs/proc/kmsg.c |   4 +-
 kernel/printk/kmsg.c   | 301 --
 kernel/printk/printk.c | 317 ++---
 kernel/printk/printk.h |  69 +++
 4 files changed, 431 insertions(+), 260 deletions(-)

diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 05f8dcd..0d354e4 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -17,7 +17,7 @@
 #include 
 #include 
 
-extern wait_queue_head_t log_wait;
+extern wait_queue_head_t *log_wait;
 
 static int kmsg_open(struct inode * inode, struct file * file)
 {
@@ -41,7 +41,7 @@ static ssize_t kmsg_read(struct file *file, char __user *buf,
 
 static unsigned int kmsg_poll(struct file *file, poll_table *wait)
 {
-   poll_wait(file, &log_wait, wait);
+   poll_wait(file, log_wait, wait);
if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC))
return POLLIN | POLLRDNORM;
return 0;
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 02981a7..42e784bd 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -30,6 +30,34 @@ struct devkmsg_user {
char buf[CONSOLE_EXT_LOG_MAX];
 };
 
+static int kmsg_sys_write(int minor, int level, const char *fmt, ...)
+{
+   va_list args;
+   int ret = -ENXIO;
+   struct log_buffer *log_b;
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(log_b, &log_buf.list, list) {
+   if (log_b->minor != minor)
+   continue;
+
+   raw_spin_lock(&log_b->lock);
+
+   va_start(args, fmt);
+   log_format_and_store(log_b, 1 /* LOG_USER */, level,
+NULL, 0, fmt, args);
+   va_end(args);
+   wake_up_interruptible(&log_b->wait);
+
+   raw_spin_unlock(&log_b->lock);
+
+   ret = 0;
+   break;
+   }
+   rcu_read_unlock();
+   return ret;
+}
+
 static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)
 {
char *buf, *line;
@@ -38,6 +66,7 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
int facility = 1;   /* LOG_USER */
size_t len = iov_iter_count(from);
ssize_t ret = len;
+   int minor = iminor(iocb->ki_filp->f_inode);
 
if (len > LOG_LINE_MAX)
return -EINVAL;
@@ -75,51 +104,57 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
}
}
 
-   printk_emit(facility, level, NULL, 0, "%s", line);
+   if (minor == log_buf.minor) {
+   printk_emit(facility, level, NULL, 0, "%s", line);
+   } else {
+   int error = kmsg_sys_write(minor, level, "%s", line);
+
+   if (error)
+   ret = error;
+   }
+
kfree(buf);
return ret;
 }
 
-static ssize_t devkmsg_read(struct file *file, char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t kmsg_read(struct log_buffer *log_b, struct file *file,
+char __user *buf, size_t count, loff_t *ppos)
 {
struct devkmsg_user *user = file->private_data;
struct printk_log *msg;
size_t len;
ssize_t ret;
 
-   if (!user)
-   return -EBADF;
-
ret = mutex_lock_interruptible(&user->lock);
if (ret)
return ret;
-   raw_spin_lock_irq(&logbuf_lock);
-   while (user->seq == log_next_seq) {
+
+   raw_spin_lock_irq(&log_b->lock);
+   while (user->seq == log_b->next_seq) {
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
-   raw_spin_unlock_irq(&logbuf_lock);
+   raw_spin_unlock_irq(&log_b->lock);
goto out;
}
 
-   raw_spin_unlock_irq(&logbuf_lock);
-   ret = wait_event_interruptible(log_wait,
-  user->seq != log_next_seq);
+   raw_spin_unlock_irq(&log_b->lock);
+   ret = wait_event_interruptible(log_b->wait,
+  user->seq != log_b->next_seq);
if (ret)
goto out;
-   raw_spin_lock_irq(&logbuf_lock);
+   raw_spin_lock_irq(&log_b->lock);
}
 
-   if (user->seq < log_first_seq) {
+   if (user->seq < log_b->first

[RFC v5 1/8] printk: extract kmsg-related routines from printk.c to kmsg.c

2015-10-27 Thread Paul Osmialowski
Following suggestions regarding printk.c code bloat, I prepared this
patch which moves kmsg-related routines to new file, kmsg.c

This is premilinary step needed for an attempt to extent kmsg interface
with ability to dynamically create (and destroy) kmsg-like devices.

Signed-off-by: Paul Osmialowski 
---
 kernel/printk/Makefile |   1 +
 kernel/printk/kmsg.c   | 575 ++
 kernel/printk/printk.c | 739 +
 kernel/printk/printk.h | 230 +++
 4 files changed, 820 insertions(+), 725 deletions(-)
 create mode 100644 kernel/printk/kmsg.c
 create mode 100644 kernel/printk/printk.h

diff --git a/kernel/printk/Makefile b/kernel/printk/Makefile
index 85405bd..bd6a4ec 100644
--- a/kernel/printk/Makefile
+++ b/kernel/printk/Makefile
@@ -1,2 +1,3 @@
 obj-y  = printk.o
+obj-$(CONFIG_PRINTK)   += kmsg.o
 obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
new file mode 100644
index 000..02981a7
--- /dev/null
+++ b/kernel/printk/kmsg.c
@@ -0,0 +1,575 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "printk.h"
+
+/* /dev/kmsg - userspace message inject/listen interface */
+struct devkmsg_user {
+   u64 seq;
+   u32 idx;
+   enum log_flags prev;
+   struct mutex lock;
+   char buf[CONSOLE_EXT_LOG_MAX];
+};
+
+static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)
+{
+   char *buf, *line;
+   int i;
+   int level = default_message_loglevel;
+   int facility = 1;   /* LOG_USER */
+   size_t len = iov_iter_count(from);
+   ssize_t ret = len;
+
+   if (len > LOG_LINE_MAX)
+   return -EINVAL;
+   buf = kmalloc(len+1, GFP_KERNEL);
+   if (buf == NULL)
+   return -ENOMEM;
+
+   buf[len] = '\0';
+   if (copy_from_iter(buf, len, from) != len) {
+   kfree(buf);
+   return -EFAULT;
+   }
+
+   /*
+* Extract and skip the syslog prefix <[0-9]*>. Coming from userspace
+* the decimal value represents 32bit, the lower 3 bit are the log
+* level, the rest are the log facility.
+*
+* If no prefix or no userspace facility is specified, we
+* enforce LOG_USER, to be able to reliably distinguish
+* kernel-generated messages from userspace-injected ones.
+*/
+   line = buf;
+   if (line[0] == '<') {
+   char *endp = NULL;
+
+   i = simple_strtoul(line+1, &endp, 10);
+   if (endp && endp[0] == '>') {
+   level = i & 7;
+   if (i >> 3)
+   facility = i >> 3;
+   endp++;
+   len -= endp - line;
+   line = endp;
+   }
+   }
+
+   printk_emit(facility, level, NULL, 0, "%s", line);
+   kfree(buf);
+   return ret;
+}
+
+static ssize_t devkmsg_read(struct file *file, char __user *buf,
+   size_t count, loff_t *ppos)
+{
+   struct devkmsg_user *user = file->private_data;
+   struct printk_log *msg;
+   size_t len;
+   ssize_t ret;
+
+   if (!user)
+   return -EBADF;
+
+   ret = mutex_lock_interruptible(&user->lock);
+   if (ret)
+   return ret;
+   raw_spin_lock_irq(&logbuf_lock);
+   while (user->seq == log_next_seq) {
+   if (file->f_flags & O_NONBLOCK) {
+   ret = -EAGAIN;
+   raw_spin_unlock_irq(&logbuf_lock);
+   goto out;
+   }
+
+   raw_spin_unlock_irq(&logbuf_lock);
+   ret = wait_event_interruptible(log_wait,
+  user->seq != log_next_seq);
+   if (ret)
+   goto out;
+   raw_spin_lock_irq(&logbuf_lock);
+   }
+
+   if (user->seq < log_first_seq) {
+   /* our last seen message is gone, return error and reset */
+   user->idx = log_first_idx;
+   user->seq = log_first_seq;
+   ret = -EPIPE;
+   raw_spin_unlock_irq(&logbuf_lock);
+   goto out;
+   }
+
+   msg = log_from_idx(user->idx);
+   len = msg_print_ext_header(user->buf, sizeof(user->buf),
+  msg, user->seq, user->prev);
+   len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len,
+ log_dict(msg), msg->dict_len,
+ 

[RFC v5 0/8] Additional kmsg devices

2015-10-27 Thread Paul Osmialowski
Dear All,

This is the fifth iteration of Marcin Niesluchowski's serie of patches
extending kmsg interface with ability to dynamically create (and destroy)
kmsg-like devices which can be used by userspace for logging.

This iteration introduces two changes:

1. selftests are rearranged to use kselftest.h API

2. A disputed  patch "add predefined _PID, _TID, _COMM keywords to kmsg*
   log dict" is removed - no chance it will be ever accepted. It is not
   critical for this patchset as a whole.

Best regards,
Paul

Marcin Niesluchowski (6):
  printk: add one function for storing log in proper format
  kmsg: introduce additional kmsg devices support
  kmsg: add additional buffers support to memory class
  kmsg: add function for adding and deleting additional buffers
  kmsg: add ioctl for adding and deleting kmsg* devices
  kmsg: add ioctl for kmsg* devices operating on buffers

Paul Osmialowski (2):
  printk: extract kmsg-related routines from printk.c to kmsg.c
  kmsg: selftests

 Documentation/ioctl/ioctl-number.txt   |1 +
 drivers/char/mem.c |   27 +-
 fs/proc/kmsg.c |4 +-
 include/linux/printk.h |   48 +
 include/uapi/linux/Kbuild  |1 +
 include/uapi/linux/kmsg_ioctl.h|   45 +
 kernel/printk/Makefile |1 +
 kernel/printk/kmsg.c   | 1022 
 kernel/printk/printk.c | 1251 +---
 kernel/printk/printk.h |  256 
 samples/kmsg/kmsg-api.h|   44 +
 tools/testing/selftests/Makefile   |1 +
 tools/testing/selftests/kmsg/.gitignore|1 +
 tools/testing/selftests/kmsg/Makefile  |   30 +
 tools/testing/selftests/kmsg/kmsg-test.c   |  344 ++
 tools/testing/selftests/kmsg/kmsg-test.h   |   28 +
 tools/testing/selftests/kmsg/test-buffer-add-del.c |   78 ++
 .../kmsg/test-buffer-add-write-read-del.c  |  163 +++
 .../kmsg/test-buffer-buf-multithreaded-torture.c   |  201 
 .../selftests/kmsg/test-buffer-buf-torture.c   |  141 +++
 20 files changed, 2722 insertions(+), 965 deletions(-)
 create mode 100644 include/uapi/linux/kmsg_ioctl.h
 create mode 100644 kernel/printk/kmsg.c
 create mode 100644 kernel/printk/printk.h
 create mode 100644 samples/kmsg/kmsg-api.h
 create mode 100644 tools/testing/selftests/kmsg/.gitignore
 create mode 100644 tools/testing/selftests/kmsg/Makefile
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.c
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.h
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-add-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-add-write-read-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-buf-multithreaded-torture.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-buf-torture.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v5 4/8] kmsg: add additional buffers support to memory class

2015-10-27 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Memory class does not support additional kmsg buffers.

Add additional kmsg buffers support to:
* devnode() callback of "mem" class
* file operations of major "mem" character device

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 drivers/char/mem.c | 27 ---
 include/linux/printk.h | 32 
 kernel/printk/kmsg.c   | 42 ++
 kernel/printk/printk.c |  1 +
 kernel/printk/printk.h |  1 +
 5 files changed, 96 insertions(+), 7 deletions(-)

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 6b1721f..7d46234 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -799,9 +799,6 @@ static const struct memdev {
 [7] = { "full", 0666, &full_fops, 0 },
 [8] = { "random", 0666, &random_fops, 0 },
 [9] = { "urandom", 0666, &urandom_fops, 0 },
-#ifdef CONFIG_PRINTK
-   [11] = { "kmsg", 0644, &kmsg_fops, 0 },
-#endif
 };
 
 static int memory_open(struct inode *inode, struct file *filp)
@@ -811,7 +808,7 @@ static int memory_open(struct inode *inode, struct file 
*filp)
 
minor = iminor(inode);
if (minor >= ARRAY_SIZE(devlist))
-   return -ENXIO;
+   return kmsg_memory_open(inode, filp);
 
dev = &devlist[minor];
if (!dev->fops)
@@ -833,16 +830,28 @@ static const struct file_operations memory_fops = {
 
 static char *mem_devnode(struct device *dev, umode_t *mode)
 {
-   if (mode && devlist[MINOR(dev->devt)].mode)
-   *mode = devlist[MINOR(dev->devt)].mode;
+   int minor = MINOR(dev->devt);
+
+   if (!mode)
+   goto out;
+
+   if (minor >= ARRAY_SIZE(devlist)) {
+   kmsg_mode(minor, mode);
+   goto out;
+   }
+
+   if (devlist[minor].mode)
+   *mode = devlist[minor].mode;
+out:
return NULL;
 }
 
-static struct class *mem_class;
+struct class *mem_class;
 
 static int __init chr_dev_init(void)
 {
int minor;
+   struct device *kmsg;
 
if (register_chrdev(MEM_MAJOR, "mem", &memory_fops))
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
@@ -866,6 +875,10 @@ static int __init chr_dev_init(void)
  NULL, devlist[minor].name);
}
 
+   kmsg = init_kmsg(KMSG_MINOR, 0644);
+   if (IS_ERR(kmsg))
+   return PTR_ERR(kmsg);
+
return tty_init();
 }
 
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 9729565..0c4f9de 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -417,8 +417,40 @@ do {   
\
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
 #endif
 
+#define KMSG_MINOR 11
+
+struct file;
+struct inode;
+
+#ifdef CONFIG_PRINTK
+
+extern struct class *mem_class;
+
 extern const struct file_operations kmsg_fops;
 
+extern struct device *init_kmsg(int minor, umode_t mode);
+extern int kmsg_memory_open(struct inode *inode, struct file *filp);
+extern int kmsg_mode(int minor, umode_t *mode);
+
+#else
+
+static inline struct device *init_kmsg(int minor, umode_t mode)
+{
+   return NULL;
+}
+
+static inline int kmsg_memory_open(struct inode *inode, struct file *filp)
+{
+   return -ENXIO;
+}
+
+static inline int kmsg_mode(int minor, umode_t *mode)
+{
+   return -ENXIO;
+}
+
+#endif
+
 enum {
DUMP_PREFIX_NONE,
DUMP_PREFIX_ADDRESS,
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 42e784bd..726250f 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -16,6 +16,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #include 
 
@@ -386,6 +389,45 @@ const struct file_operations kmsg_fops = {
.release = devkmsg_release,
 };
 
+/* Should be used for device registration */
+struct device *init_kmsg(int minor, umode_t mode)
+{
+   log_buf.minor = minor;
+   log_buf.mode = mode;
+   return device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
+   NULL, "kmsg");
+}
+
+int kmsg_memory_open(struct inode *inode, struct file *filp)
+{
+   filp->f_op = &kmsg_fops;
+
+   return kmsg_fops.open(inode, filp);
+}
+
+int kmsg_mode(int minor, umode_t *mode)
+{
+   int ret = -ENXIO;
+   struct log_buffer *log_b;
+
+   if (minor == log_buf.minor) {
+   *mode = log_buf.mode;
+   return 0;
+   }
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(log_b, &log_buf.list, list) {
+   if (log_b->minor == minor) {
+   *mode = log_b->mode;
+   ret = 0;
+   break;
+   }
+   }
+   rcu_read_unlock();
+
+  

[RFC v5 7/8] kmsg: add ioctl for kmsg* devices operating on buffers

2015-10-27 Thread Paul Osmialowski
From: Marcin Niesluchowski 

There is no possibility to clear additional kmsg buffers,
get size of them or know what size should be passed to read
file operation (too small size causes it to retrun -EINVAL).

Add following ioctls which solve those issues:
* KMSG_CMD_GET_BUF_SIZE
* KMSG_CMD_GET_READ_SIZE_MAX
* KMSG_CMD_CLEAR

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 Documentation/ioctl/ioctl-number.txt |  2 +-
 include/uapi/linux/kmsg_ioctl.h  | 15 ++
 kernel/printk/kmsg.c | 57 ++--
 3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 76dec8b..d36bb04 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -319,7 +319,7 @@ Code  Seq#(hex) Include FileComments
<mailto:v...@ratio.de>
 0xB1   00-1F   PPPoX   <mailto:mostr...@styx.uwaterloo.ca>
 0xB3   00  linux/mmc/ioctl.h
-0xBB   00-02   uapi/linux/kmsg_ioctl.h
+0xBB   00-83   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/include/uapi/linux/kmsg_ioctl.h b/include/uapi/linux/kmsg_ioctl.h
index 96e7930..bfd9cd3 100644
--- a/include/uapi/linux/kmsg_ioctl.h
+++ b/include/uapi/linux/kmsg_ioctl.h
@@ -27,4 +27,19 @@ struct kmsg_cmd_buffer_add {
  struct kmsg_cmd_buffer_add)
 #define KMSG_CMD_BUFFER_DEL_IOW(KMSG_IOCTL_MAGIC, 0x01, int)
 
+/*
+ * A ioctl interface for kmsg* devices.
+ *
+ * KMSG_CMD_GET_BUF_SIZE:  Retrieve cyclic log buffer size associated with
+ * device.
+ * KMSG_CMD_GET_READ_SIZE_MAX: Retrieve max size of data read by kmsg read
+ * operation.
+ * KMSG_CMD_CLEAR: Clears cyclic log buffer. After that operation
+ * there is no data to read from buffer unless
+ * logs are written.
+ */
+#define KMSG_CMD_GET_BUF_SIZE  _IOR(KMSG_IOCTL_MAGIC, 0x80, __u32)
+#define KMSG_CMD_GET_READ_SIZE_MAX _IOR(KMSG_IOCTL_MAGIC, 0x81, __u32)
+#define KMSG_CMD_CLEAR _IO(KMSG_IOCTL_MAGIC, 0x82)
+
 #endif
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 62bb4d5..bcf0801 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -247,8 +247,9 @@ static loff_t kmsg_llseek(struct log_buffer *log_b, struct 
file *file,
}
/*
 * The first record after the last SYSLOG_ACTION_CLEAR,
-* like issued by 'dmesg -c'. Reading /dev/kmsg itself
-* changes no global state, and does not clear anything.
+* like issued by 'dmesg -c' or KMSG_CMD_CLEAR ioctl
+* command. Reading /dev/kmsg itself changes no global
+* state, and does not clear anything.
 */
user->idx = log_b->clear_idx;
user->seq = log_b->clear_seq;
@@ -391,6 +392,56 @@ static int devkmsg_open(struct inode *inode, struct file 
*file)
return ret;
 }
 
+static long kmsg_ioctl(struct log_buffer *log_b, unsigned int cmd,
+  unsigned long arg)
+{
+   void __user *argp = (void __user *)arg;
+   static const u32 read_size_max = CONSOLE_EXT_LOG_MAX;
+
+   switch (cmd) {
+   case KMSG_CMD_GET_BUF_SIZE:
+   if (copy_to_user(argp, &log_b->len, sizeof(u32)))
+   return -EFAULT;
+   break;
+   case KMSG_CMD_GET_READ_SIZE_MAX:
+   if (copy_to_user(argp, &read_size_max, sizeof(u32)))
+   return -EFAULT;
+   break;
+   case KMSG_CMD_CLEAR:
+   if (!capable(CAP_SYSLOG))
+   return -EPERM;
+   raw_spin_lock_irq(&log_b->lock);
+   log_b->clear_seq = log_b->next_seq;
+   log_b->clear_idx = log_b->next_idx;
+   raw_spin_unlock_irq(&log_b->lock);
+   break;
+   default:
+   return -ENOTTY;
+   }
+   return 0;
+}
+
+static long devkmsg_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+   long ret = -ENXIO;
+   int minor = iminor(file->f_inode);
+   struct log_buffer *log_b;
+
+   if (minor == log_buf.minor)
+   return kmsg_ioctl(&log_buf, cmd, arg);
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(log_b, &log_buf.list, list) {
+   if (log_b->minor == minor) {
+   ret = kmsg_ioctl(log_b, cmd, arg);
+   break;
+   }
+   }
+   rcu_read_unlock();
+   return 

[RFC v5 5/8] kmsg: add function for adding and deleting additional buffers

2015-10-27 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Additional kmsg buffers should be created and deleted dynamically.

Adding two functions
* kmsg_sys_buffer_add() creates additional kmsg buffer returning minor
* kmsg_sys_buffer_del() deletes one based on provided minor

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 include/linux/printk.h |   9 +
 kernel/printk/kmsg.c   | 107 +++--
 kernel/printk/printk.c |  12 ++
 kernel/printk/printk.h |   4 ++
 4 files changed, 129 insertions(+), 3 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 0c4f9de..513fa6f 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -431,6 +431,8 @@ extern const struct file_operations kmsg_fops;
 extern struct device *init_kmsg(int minor, umode_t mode);
 extern int kmsg_memory_open(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);
 
 #else
 
@@ -449,6 +451,13 @@ static inline int kmsg_mode(int minor, umode_t *mode)
return -ENXIO;
 }
 
+static inline int kmsg_sys_buffer_add(size_t size, umode_t mode)
+{
+   return -ENXIO;
+}
+
+static inline void kmsg_sys_buffer_del(int minor) {}
+
 #endif
 
 enum {
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 726250f..9222fdc 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -141,8 +142,20 @@ static ssize_t kmsg_read(struct log_buffer *log_b, struct 
file *file,
}
 
raw_spin_unlock_irq(&log_b->lock);
-   ret = wait_event_interruptible(log_b->wait,
-  user->seq != log_b->next_seq);
+   if (log_b == &log_buf) {
+   ret = wait_event_interruptible(log_b->wait,
+   user->seq != log_b->next_seq);
+   } else {
+   rcu_read_unlock();
+   kref_get(&log_b->refcount);
+   ret = wait_event_interruptible(log_b->wait,
+   user->seq != log_b->next_seq);
+   if (log_b->minor == -1)
+   ret = -ENXIO;
+   if (kref_put(&log_b->refcount, log_buf_release))
+   ret = -ENXIO;
+   rcu_read_lock();
+   }
if (ret)
goto out;
raw_spin_lock_irq(&log_b->lock);
@@ -311,8 +324,14 @@ static unsigned int devkmsg_poll(struct file *file, 
poll_table *wait)
rcu_read_lock();
list_for_each_entry_rcu(log_b, &log_buf.list, list) {
if (log_b->minor == minor) {
+   kref_get(&log_b->refcount);
+   rcu_read_unlock();
+
ret = kmsg_poll(log_b, file, wait);
-   break;
+
+   if (kref_put(&log_b->refcount, log_buf_release))
+   return POLLERR|POLLNVAL;
+   return ret;
}
}
rcu_read_unlock();
@@ -428,6 +447,88 @@ int kmsg_mode(int minor, umode_t *mode)
return ret;
 }
 
+static DEFINE_SPINLOCK(kmsg_sys_list_lock);
+
+int kmsg_sys_buffer_add(size_t size, umode_t mode)
+{
+   unsigned long flags;
+   int minor = log_buf.minor;
+   struct log_buffer *log_b;
+   struct log_buffer *log_b_new;
+
+   if (size < LOG_LINE_MAX + PREFIX_MAX)
+   return -EINVAL;
+
+   log_b_new = kzalloc(sizeof(struct log_buffer), GFP_KERNEL);
+   if (!log_b_new)
+   return -ENOMEM;
+
+   log_b_new->buf = kmalloc(size, GFP_KERNEL);
+   if (!log_b_new->buf) {
+   kfree(log_b_new);
+   return -ENOMEM;
+   }
+
+   log_b_new->len = size;
+   log_b_new->lock = __RAW_SPIN_LOCK_UNLOCKED(log_b_new->lock);
+   init_waitqueue_head(&log_b_new->wait);
+   kref_init(&log_b_new->refcount);
+   log_b_new->mode = mode;
+
+   kref_get(&log_b_new->refcount);
+
+   spin_lock_irqsave(&kmsg_sys_list_lock, flags);
+
+   list_for_each_entry(log_b, &log_buf.list, list) {
+   if (log_b->minor - minor > 1)
+   break;
+
+   minor = log_b->minor;
+   }
+
+   if (!(minor & MINORMASK)) {
+   kref_put(&log_b->refcount, log_buf_release);
+   spin_unlock_irqrestore(&kmsg_sys_list_lock, flags);
+   return -ERANGE;
+   }
+
+   minor += 1;
+   log_b_new->minor = minor;
+
+   list_add_tail_rcu

[RFC v5 8/8] kmsg: selftests

2015-10-27 Thread Paul Osmialowski
This patch adds selftests framework and four test scenarios for kmsg.

The framework shape and code was inspired by similar selftests framework
for kdbus.

Signed-off-by: Paul Osmialowski 
---
 samples/kmsg/kmsg-api.h|  44 +++
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/kmsg/.gitignore|   1 +
 tools/testing/selftests/kmsg/Makefile  |  30 ++
 tools/testing/selftests/kmsg/kmsg-test.c   | 344 +
 tools/testing/selftests/kmsg/kmsg-test.h   |  28 ++
 tools/testing/selftests/kmsg/test-buffer-add-del.c |  78 +
 .../kmsg/test-buffer-add-write-read-del.c  | 163 ++
 .../kmsg/test-buffer-buf-multithreaded-torture.c   | 201 
 .../selftests/kmsg/test-buffer-buf-torture.c   | 141 +
 10 files changed, 1031 insertions(+)
 create mode 100644 samples/kmsg/kmsg-api.h
 create mode 100644 tools/testing/selftests/kmsg/.gitignore
 create mode 100644 tools/testing/selftests/kmsg/Makefile
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.c
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.h
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-add-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-add-write-read-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-buf-multithreaded-torture.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-buf-torture.c

diff --git a/samples/kmsg/kmsg-api.h b/samples/kmsg/kmsg-api.h
new file mode 100644
index 000..9004acd
--- /dev/null
+++ b/samples/kmsg/kmsg-api.h
@@ -0,0 +1,44 @@
+#ifndef KMSG_API_H
+#define KMSG_API_H
+
+#include 
+#include 
+#include 
+#include 
+
+static inline int kmsg_cmd_buffer_add(int fd, struct kmsg_cmd_buffer_add *cmd)
+{
+   int ret = ioctl(fd, KMSG_CMD_BUFFER_ADD, cmd);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_buffer_del(int fd, int *minor)
+{
+   int ret = ioctl(fd, KMSG_CMD_BUFFER_DEL, minor);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_get_buf_size(int fd, uint32_t *size)
+{
+   int ret = ioctl(fd, KMSG_CMD_GET_BUF_SIZE, size);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_get_read_size_max(int fd, uint32_t *max_size)
+{
+   int ret = ioctl(fd, KMSG_CMD_GET_READ_SIZE_MAX, max_size);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_clear(int fd)
+{
+   int ret = ioctl(fd, KMSG_CMD_CLEAR);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+#endif /* KMSG_API_H */
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index bf4ece6..b7bdf58 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += ftrace
 TARGETS += futex
 TARGETS += kcmp
 TARGETS += kdbus
+TARGETS += kmsg
 TARGETS += lib
 TARGETS += membarrier
 TARGETS += memfd
diff --git a/tools/testing/selftests/kmsg/.gitignore 
b/tools/testing/selftests/kmsg/.gitignore
new file mode 100644
index 000..687d517
--- /dev/null
+++ b/tools/testing/selftests/kmsg/.gitignore
@@ -0,0 +1 @@
+kmsg-test
diff --git a/tools/testing/selftests/kmsg/Makefile 
b/tools/testing/selftests/kmsg/Makefile
new file mode 100644
index 000..cee2e2b
--- /dev/null
+++ b/tools/testing/selftests/kmsg/Makefile
@@ -0,0 +1,30 @@
+CFLAGS += -I../../../../usr/include/
+CFLAGS += -I../../../../samples/kmsg/
+CFLAGS += -I../../../../include/uapi/
+CFLAGS += -std=gnu99 -Wall
+CFLAGS += -DKBUILD_MODNAME=\"kmsg\" -D_GNU_SOURCE
+CFLAGS += -pthread
+LDLIBS += -pthread
+
+OBJS= \
+   kmsg-test.o \
+   test-buffer-add-del.o   \
+   test-buffer-add-write-read-del.o\
+   test-buffer-buf-torture.o   \
+   test-buffer-buf-multithreaded-torture.o
+
+all: kmsg-test
+
+include ../lib.mk
+
+%.o: %.c kmsg-test.h
+   $(CC) $(CFLAGS) -c $< -o $@
+
+kmsg-test: $(OBJS)
+   $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
+
+run_tests:
+   ./kmsg-test
+
+clean:
+   rm -f *.o kmsg-test
diff --git a/tools/testing/selftests/kmsg/kmsg-test.c 
b/tools/testing/selftests/kmsg/kmsg-test.c
new file mode 100644
index 000..282ec1f
--- /dev/null
+++ b/tools/testing/selftests/kmsg/kmsg-test.c
@@ -0,0 +1,344 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../kselftest.h"
+
+#include "kmsg-test.h"
+
+struct kmsg_test {
+   const char  *name;
+   const char  *desc;
+   int (*func)(const struct kmsg_test_args *args);
+};
+
+static const struct kmsg_test tests[] = {
+   {
+   .name   = "buffer-add-del",
+   

[RFC v5 2/8] printk: add one function for storing log in proper format

2015-10-27 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Preparation commit for future changes purpose.

Separate code responsible for storing log message in proper format
from operations on consoles by putting it in another function.

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 kernel/printk/printk.c | 222 ++---
 1 file changed, 119 insertions(+), 103 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index c1b7a79..518cbdf 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -181,6 +181,27 @@ static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
 static char *log_buf = __log_buf;
 static u32 log_buf_len = __LOG_BUF_LEN;
 
+/*
+ * Continuation lines are buffered, and not committed to the record buffer
+ * until the line is complete, or a race forces it. The line fragments
+ * though, are printed immediately to the consoles to ensure everything has
+ * reached the console in case of a kernel crash.
+ */
+static struct cont {
+   char buf[LOG_LINE_MAX];
+   size_t len; /* length == 0 means unused buffer */
+   size_t cons;/* bytes written to console */
+   struct task_struct *owner;  /* task of first print*/
+   u64 ts_nsec;/* time of first print */
+   u8 level;   /* log level of first message */
+   u8 facility;/* log facility of first message */
+   enum log_flags flags;   /* prefix, newline flags */
+   bool flushed:1; /* buffer sealed and committed */
+} cont;
+
+static void cont_flush(enum log_flags flags);
+static bool cont_add(int facility, int level, const char *text, size_t len);
+
 /* Return log buffer address */
 char *log_buf_addr_get(void)
 {
@@ -332,6 +353,102 @@ static int log_store(int facility, int level,
return msg->text_len;
 }
 
+static int log_format_and_store(int facility, int level,
+   const char *dict, size_t dictlen,
+   const char *fmt, va_list args)
+{
+   static char textbuf[LOG_LINE_MAX];
+   char *text = textbuf;
+   size_t text_len = 0;
+   enum log_flags lflags = 0;
+   int printed_len = 0;
+
+   /*
+* The printf needs to come first; we need the syslog
+* prefix which might be passed-in as a parameter.
+*/
+   text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
+
+   /* mark and strip a trailing newline */
+   if (text_len && text[text_len-1] == '\n') {
+   text_len--;
+   lflags |= LOG_NEWLINE;
+   }
+
+   /* strip kernel syslog prefix and extract log level or control flags */
+   if (facility == 0) {
+   int kern_level = printk_get_level(text);
+
+   if (kern_level) {
+   const char *end_of_header = printk_skip_level(text);
+
+   switch (kern_level) {
+   case '0' ... '7':
+   if (level == LOGLEVEL_DEFAULT)
+   level = kern_level - '0';
+   /* fallthrough */
+   case 'd':   /* KERN_DEFAULT */
+   lflags |= LOG_PREFIX;
+   }
+   /*
+* No need to check length here because vscnprintf
+* put '\0' at the end of the string. Only valid and
+* newly printed level is detected.
+*/
+   text_len -= end_of_header - text;
+   text = (char *)end_of_header;
+   }
+   }
+
+   if (level == LOGLEVEL_DEFAULT)
+   level = default_message_loglevel;
+
+   if (dict)
+   lflags |= LOG_PREFIX|LOG_NEWLINE;
+
+   if (!(lflags & LOG_NEWLINE)) {
+   /*
+* Flush the conflicting buffer. An earlier newline was missing,
+* or another task also prints continuation lines.
+*/
+   if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
+   cont_flush(LOG_NEWLINE);
+
+   /* buffer line if possible, otherwise store it right away */
+   if (cont_add(facility, level, text, text_len))
+   printed_len += text_len;
+   else
+   printed_len += log_store(facility, level,
+lflags | LOG_CONT, 0,
+dict, dictlen, text, text_len);
+   } else {
+   bool stored = false;
+
+   /*
+* If an earlier newline was missing and it was the same task,
+* eithe

[RFC v5 6/8] kmsg: add ioctl for adding and deleting kmsg* devices

2015-10-27 Thread Paul Osmialowski
From: Marcin Niesluchowski 

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 
Signed-off-by: Paul Osmialowski 
---
 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 | 122 +++
 6 files changed, 162 insertions(+), 1 deletion(-)
 create mode 100644 include/uapi/linux/kmsg_ioctl.h

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 43e6923..76dec8b 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -319,6 +319,7 @@ Code  Seq#(hex) Include FileComments
<mailto:v...@ratio.de>
 0xB1   00-1F   PPPoX   <mailto:mostr...@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 7d46234..ac824de 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 513fa6f..ebacfa6 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 e777078..d998999 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -225,6 +225,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 000..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 
+#include 
+
+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 9222fdc..62bb4d5 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -23,8 +23,12 @@
 
 #include 
 
+#include 
+
 #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(str

Re: [RFC v4 9/9] kmsg: selftests

2015-10-20 Thread Paul Osmialowski

Hi Shuah,

I'm attaching proposal version which makes use of inline 
functions from kselftest.h. I hope you'll like it.


Thanks,
Paul

On Tue, 20 Oct 2015, Paul Osmialowski wrote:


Hi Shuah,

Thanks for your comments,

On Mon, 19 Oct 2015, Shuah Khan wrote:


--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += ftrace
 TARGETS += futex
 TARGETS += kcmp
 TARGETS += kdbus


Doesn't look like this patch is based on linux-kselftest next
or Linus's latest. Please base your work on either one of the
above. Please make sure "make kselftest" from top level Makefile
doesn't break.


+TARGETS += kmsg


Any guidelines what such test should be implemented (apart from use of 
kselftest.h API)?



+kmsg-test: $(OBJS)
+   $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
+
+run_tests:
+   ./kmsg-test --tap


What does --tap do? Is this a longform option?
I don't see it in usage()



Should be removed - I copy-pasted parts of kdbus selftests Makefile not 
noticing that.


Best regards,
Paul

From a76287ad863edef0f497fbd808f2574f9fb14c79 Mon Sep 17 00:00:00 2001
From: Paul Osmialowski 
Date: Wed, 23 Sep 2015 18:04:13 +0200
Subject: [RFC v5 9/9] kmsg: selftests

This patch adds selftests framework and four test scenarios for kmsg.

The framework shape and code was inspired by similar selftests framework
for kdbus.

Signed-off-by: Paul Osmialowski 
---
 samples/kmsg/kmsg-api.h|  44 +++
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/kmsg/.gitignore|   1 +
 tools/testing/selftests/kmsg/Makefile  |  30 ++
 tools/testing/selftests/kmsg/kmsg-test.c   | 344 +
 tools/testing/selftests/kmsg/kmsg-test.h   |  28 ++
 tools/testing/selftests/kmsg/test-buffer-add-del.c |  78 +
 .../kmsg/test-buffer-add-write-read-del.c  | 163 ++
 .../kmsg/test-buffer-buf-multithreaded-torture.c   | 201 
 .../selftests/kmsg/test-buffer-buf-torture.c   | 141 +
 10 files changed, 1031 insertions(+)
 create mode 100644 samples/kmsg/kmsg-api.h
 create mode 100644 tools/testing/selftests/kmsg/.gitignore
 create mode 100644 tools/testing/selftests/kmsg/Makefile
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.c
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.h
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-add-del.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-add-write-read-del.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-buf-multithreaded-torture.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-buf-torture.c

diff --git a/samples/kmsg/kmsg-api.h b/samples/kmsg/kmsg-api.h
new file mode 100644
index 000..9004acd
--- /dev/null
+++ b/samples/kmsg/kmsg-api.h
@@ -0,0 +1,44 @@
+#ifndef KMSG_API_H
+#define KMSG_API_H
+
+#include 
+#include 
+#include 
+#include 
+
+static inline int kmsg_cmd_buffer_add(int fd, struct kmsg_cmd_buffer_add *cmd)
+{
+	int ret = ioctl(fd, KMSG_CMD_BUFFER_ADD, cmd);
+
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_buffer_del(int fd, int *minor)
+{
+	int ret = ioctl(fd, KMSG_CMD_BUFFER_DEL, minor);
+
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_get_buf_size(int fd, uint32_t *size)
+{
+	int ret = ioctl(fd, KMSG_CMD_GET_BUF_SIZE, size);
+
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_get_read_size_max(int fd, uint32_t *max_size)
+{
+	int ret = ioctl(fd, KMSG_CMD_GET_READ_SIZE_MAX, max_size);
+
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_clear(int fd)
+{
+	int ret = ioctl(fd, KMSG_CMD_CLEAR);
+
+	return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+#endif /* KMSG_API_H */
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index bf4ece6..b7bdf58 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += ftrace
 TARGETS += futex
 TARGETS += kcmp
 TARGETS += kdbus
+TARGETS += kmsg
 TARGETS += lib
 TARGETS += membarrier
 TARGETS += memfd
diff --git a/tools/testing/selftests/kmsg/.gitignore b/tools/testing/selftests/kmsg/.gitignore
new file mode 100644
index 000..687d517
--- /dev/null
+++ b/tools/testing/selftests/kmsg/.gitignore
@@ -0,0 +1 @@
+kmsg-test
diff --git a/tools/testing/selftests/kmsg/Makefile b/tools/testing/selftests/kmsg/Makefile
new file mode 100644
index 000..cee2e2b
--- /dev/null
+++ b/tools/testing/selftests/kmsg/Makefile
@@ -0,0 +1,30 @@
+CFLAGS += -I../../../../usr/include/
+CFLAGS += -I../../../../samples/kmsg/
+CFLAGS += -I../../../../include/uapi/
+CFLAGS += -std=gnu99 -Wall
+CFLAGS += -DKBUILD_MODNAME=\"kmsg\" -D_GNU_SOURCE
+CFLAGS += -pthread
+LDLIBS += -pthread
+
+OBJ

Re: [RFC v3 8/9] kmsg: add predefined _PID, _TID, _COMM keywords to kmsg* log dict

2015-10-20 Thread Paul Osmialowski

Hi Andy,

On Mon, 19 Oct 2015, Andy Lutomirski wrote:


On Mon, Oct 19, 2015 at 5:58 AM, Paul Osmialowski
 wrote:

From: Marcin Niesluchowski 

kmsg* devices write operation wrote no dict along with message
Due to usage of kmsg devices in userspace dict has been added
identifying pid, tid and comm of writing process.


Does this affect even the normal /dev/kmsg?


Yes.




-static int kmsg_sys_write(int minor, int level, const char *fmt, ...)
+static size_t set_kmsg_dict(char *buf)
+{
+   size_t len;
+
+   len = sprintf(buf, "_PID=%d", task_tgid_nr(current)) + 1;
+   len += sprintf(buf + len, "_TID=%d", task_pid_nr(current)) + 1;
+   memcpy(buf + len, "_COMM=", 6);
+   len += 6;
+   get_task_comm(buf + len, current);
+   while (buf[len] != '\0')
+   len++;


len += strlen(buf); ?

Is it obvious for some reason that this doesn't overflow buf?



KMSG_DICT_MAX_LEN sets architecture-intepentent max size.


Why is task_pid_nr acceptable here?  Isn't this intended for use in namespaces?



task_tgid_nr - process id (pid as seen in userspace),
task_pid_nr - thread id

Thanks,
Paul
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC v4 9/9] kmsg: selftests

2015-10-20 Thread Paul Osmialowski

Hi Shuah,

Thanks for your comments,

On Mon, 19 Oct 2015, Shuah Khan wrote:


--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += ftrace
 TARGETS += futex
 TARGETS += kcmp
 TARGETS += kdbus


Doesn't look like this patch is based on linux-kselftest next
or Linus's latest. Please base your work on either one of the
above. Please make sure "make kselftest" from top level Makefile
doesn't break.


+TARGETS += kmsg


Any guidelines what such test should be implemented (apart from use of 
kselftest.h API)?



+kmsg-test: $(OBJS)
+   $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
+
+run_tests:
+   ./kmsg-test --tap


What does --tap do? Is this a longform option?
I don't see it in usage()



Should be removed - I copy-pasted parts of kdbus selftests Makefile not 
noticing that.


Best regards,
Paul

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v4 2/9] printk: add one function for storing log in proper format

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Preparation commit for future changes purpose.

Separate code responsible for storing log message in proper format
from operations on consoles by putting it in another function.

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 kernel/printk/printk.c | 222 ++---
 1 file changed, 119 insertions(+), 103 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index c1b7a79..518cbdf 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -181,6 +181,27 @@ static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
 static char *log_buf = __log_buf;
 static u32 log_buf_len = __LOG_BUF_LEN;
 
+/*
+ * Continuation lines are buffered, and not committed to the record buffer
+ * until the line is complete, or a race forces it. The line fragments
+ * though, are printed immediately to the consoles to ensure everything has
+ * reached the console in case of a kernel crash.
+ */
+static struct cont {
+   char buf[LOG_LINE_MAX];
+   size_t len; /* length == 0 means unused buffer */
+   size_t cons;/* bytes written to console */
+   struct task_struct *owner;  /* task of first print*/
+   u64 ts_nsec;/* time of first print */
+   u8 level;   /* log level of first message */
+   u8 facility;/* log facility of first message */
+   enum log_flags flags;   /* prefix, newline flags */
+   bool flushed:1; /* buffer sealed and committed */
+} cont;
+
+static void cont_flush(enum log_flags flags);
+static bool cont_add(int facility, int level, const char *text, size_t len);
+
 /* Return log buffer address */
 char *log_buf_addr_get(void)
 {
@@ -332,6 +353,102 @@ static int log_store(int facility, int level,
return msg->text_len;
 }
 
+static int log_format_and_store(int facility, int level,
+   const char *dict, size_t dictlen,
+   const char *fmt, va_list args)
+{
+   static char textbuf[LOG_LINE_MAX];
+   char *text = textbuf;
+   size_t text_len = 0;
+   enum log_flags lflags = 0;
+   int printed_len = 0;
+
+   /*
+* The printf needs to come first; we need the syslog
+* prefix which might be passed-in as a parameter.
+*/
+   text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
+
+   /* mark and strip a trailing newline */
+   if (text_len && text[text_len-1] == '\n') {
+   text_len--;
+   lflags |= LOG_NEWLINE;
+   }
+
+   /* strip kernel syslog prefix and extract log level or control flags */
+   if (facility == 0) {
+   int kern_level = printk_get_level(text);
+
+   if (kern_level) {
+   const char *end_of_header = printk_skip_level(text);
+
+   switch (kern_level) {
+   case '0' ... '7':
+   if (level == LOGLEVEL_DEFAULT)
+   level = kern_level - '0';
+   /* fallthrough */
+   case 'd':   /* KERN_DEFAULT */
+   lflags |= LOG_PREFIX;
+   }
+   /*
+* No need to check length here because vscnprintf
+* put '\0' at the end of the string. Only valid and
+* newly printed level is detected.
+*/
+   text_len -= end_of_header - text;
+   text = (char *)end_of_header;
+   }
+   }
+
+   if (level == LOGLEVEL_DEFAULT)
+   level = default_message_loglevel;
+
+   if (dict)
+   lflags |= LOG_PREFIX|LOG_NEWLINE;
+
+   if (!(lflags & LOG_NEWLINE)) {
+   /*
+* Flush the conflicting buffer. An earlier newline was missing,
+* or another task also prints continuation lines.
+*/
+   if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
+   cont_flush(LOG_NEWLINE);
+
+   /* buffer line if possible, otherwise store it right away */
+   if (cont_add(facility, level, text, text_len))
+   printed_len += text_len;
+   else
+   printed_len += log_store(facility, level,
+lflags | LOG_CONT, 0,
+dict, dictlen, text, text_len);
+   } else {
+   bool stored = false;
+
+   /*
+* If an earlier newline was missing and it was the same task,
+* eithe

[RFC v4 1/9] printk: extract kmsg-related routines from printk.c to kmsg.c

2015-10-19 Thread Paul Osmialowski
Following suggestions regarding printk.c code bloat, I prepared this
patch which moves kmsg-related routines to new file, kmsg.c

This is premilinary step needed for an attempt to extent kmsg interface
with ability to dynamically create (and destroy) kmsg-like devices.

Signed-off-by: Paul Osmialowski 
---
 kernel/printk/Makefile |   1 +
 kernel/printk/kmsg.c   | 575 ++
 kernel/printk/printk.c | 739 +
 kernel/printk/printk.h | 230 +++
 4 files changed, 820 insertions(+), 725 deletions(-)
 create mode 100644 kernel/printk/kmsg.c
 create mode 100644 kernel/printk/printk.h

diff --git a/kernel/printk/Makefile b/kernel/printk/Makefile
index 85405bd..bd6a4ec 100644
--- a/kernel/printk/Makefile
+++ b/kernel/printk/Makefile
@@ -1,2 +1,3 @@
 obj-y  = printk.o
+obj-$(CONFIG_PRINTK)   += kmsg.o
 obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
new file mode 100644
index 000..02981a7
--- /dev/null
+++ b/kernel/printk/kmsg.c
@@ -0,0 +1,575 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "printk.h"
+
+/* /dev/kmsg - userspace message inject/listen interface */
+struct devkmsg_user {
+   u64 seq;
+   u32 idx;
+   enum log_flags prev;
+   struct mutex lock;
+   char buf[CONSOLE_EXT_LOG_MAX];
+};
+
+static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)
+{
+   char *buf, *line;
+   int i;
+   int level = default_message_loglevel;
+   int facility = 1;   /* LOG_USER */
+   size_t len = iov_iter_count(from);
+   ssize_t ret = len;
+
+   if (len > LOG_LINE_MAX)
+   return -EINVAL;
+   buf = kmalloc(len+1, GFP_KERNEL);
+   if (buf == NULL)
+   return -ENOMEM;
+
+   buf[len] = '\0';
+   if (copy_from_iter(buf, len, from) != len) {
+   kfree(buf);
+   return -EFAULT;
+   }
+
+   /*
+* Extract and skip the syslog prefix <[0-9]*>. Coming from userspace
+* the decimal value represents 32bit, the lower 3 bit are the log
+* level, the rest are the log facility.
+*
+* If no prefix or no userspace facility is specified, we
+* enforce LOG_USER, to be able to reliably distinguish
+* kernel-generated messages from userspace-injected ones.
+*/
+   line = buf;
+   if (line[0] == '<') {
+   char *endp = NULL;
+
+   i = simple_strtoul(line+1, &endp, 10);
+   if (endp && endp[0] == '>') {
+   level = i & 7;
+   if (i >> 3)
+   facility = i >> 3;
+   endp++;
+   len -= endp - line;
+   line = endp;
+   }
+   }
+
+   printk_emit(facility, level, NULL, 0, "%s", line);
+   kfree(buf);
+   return ret;
+}
+
+static ssize_t devkmsg_read(struct file *file, char __user *buf,
+   size_t count, loff_t *ppos)
+{
+   struct devkmsg_user *user = file->private_data;
+   struct printk_log *msg;
+   size_t len;
+   ssize_t ret;
+
+   if (!user)
+   return -EBADF;
+
+   ret = mutex_lock_interruptible(&user->lock);
+   if (ret)
+   return ret;
+   raw_spin_lock_irq(&logbuf_lock);
+   while (user->seq == log_next_seq) {
+   if (file->f_flags & O_NONBLOCK) {
+   ret = -EAGAIN;
+   raw_spin_unlock_irq(&logbuf_lock);
+   goto out;
+   }
+
+   raw_spin_unlock_irq(&logbuf_lock);
+   ret = wait_event_interruptible(log_wait,
+  user->seq != log_next_seq);
+   if (ret)
+   goto out;
+   raw_spin_lock_irq(&logbuf_lock);
+   }
+
+   if (user->seq < log_first_seq) {
+   /* our last seen message is gone, return error and reset */
+   user->idx = log_first_idx;
+   user->seq = log_first_seq;
+   ret = -EPIPE;
+   raw_spin_unlock_irq(&logbuf_lock);
+   goto out;
+   }
+
+   msg = log_from_idx(user->idx);
+   len = msg_print_ext_header(user->buf, sizeof(user->buf),
+  msg, user->seq, user->prev);
+   len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len,
+ log_dict(msg), msg->dict_len,
+ 

[RFC v4 9/9] kmsg: selftests

2015-10-19 Thread Paul Osmialowski
This patch adds selftests framework and four test scenarios for kmsg.

The framework shape and code was inspired by similar selftests framework
for kdbus.

Signed-off-by: Paul Osmialowski 
---
 samples/kmsg/kmsg-api.h|  44 +++
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/kmsg/.gitignore|   1 +
 tools/testing/selftests/kmsg/Makefile  |  30 ++
 tools/testing/selftests/kmsg/kmsg-test.c   | 329 +
 tools/testing/selftests/kmsg/kmsg-test.h   |  34 +++
 tools/testing/selftests/kmsg/test-buffer-add-del.c |  76 +
 .../kmsg/test-buffer-add-write-read-del.c  | 161 ++
 .../kmsg/test-buffer-buf-multithreaded-torture.c   | 199 +
 .../selftests/kmsg/test-buffer-buf-torture.c   | 139 +
 10 files changed, 1014 insertions(+)
 create mode 100644 samples/kmsg/kmsg-api.h
 create mode 100644 tools/testing/selftests/kmsg/.gitignore
 create mode 100644 tools/testing/selftests/kmsg/Makefile
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.c
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.h
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-add-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-add-write-read-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-buf-multithreaded-torture.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-buf-torture.c

diff --git a/samples/kmsg/kmsg-api.h b/samples/kmsg/kmsg-api.h
new file mode 100644
index 000..9004acd
--- /dev/null
+++ b/samples/kmsg/kmsg-api.h
@@ -0,0 +1,44 @@
+#ifndef KMSG_API_H
+#define KMSG_API_H
+
+#include 
+#include 
+#include 
+#include 
+
+static inline int kmsg_cmd_buffer_add(int fd, struct kmsg_cmd_buffer_add *cmd)
+{
+   int ret = ioctl(fd, KMSG_CMD_BUFFER_ADD, cmd);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_buffer_del(int fd, int *minor)
+{
+   int ret = ioctl(fd, KMSG_CMD_BUFFER_DEL, minor);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_get_buf_size(int fd, uint32_t *size)
+{
+   int ret = ioctl(fd, KMSG_CMD_GET_BUF_SIZE, size);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_get_read_size_max(int fd, uint32_t *max_size)
+{
+   int ret = ioctl(fd, KMSG_CMD_GET_READ_SIZE_MAX, max_size);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_clear(int fd)
+{
+   int ret = ioctl(fd, KMSG_CMD_CLEAR);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+#endif /* KMSG_API_H */
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index bf4ece6..b7bdf58 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += ftrace
 TARGETS += futex
 TARGETS += kcmp
 TARGETS += kdbus
+TARGETS += kmsg
 TARGETS += lib
 TARGETS += membarrier
 TARGETS += memfd
diff --git a/tools/testing/selftests/kmsg/.gitignore 
b/tools/testing/selftests/kmsg/.gitignore
new file mode 100644
index 000..687d517
--- /dev/null
+++ b/tools/testing/selftests/kmsg/.gitignore
@@ -0,0 +1 @@
+kmsg-test
diff --git a/tools/testing/selftests/kmsg/Makefile 
b/tools/testing/selftests/kmsg/Makefile
new file mode 100644
index 000..b4ba892
--- /dev/null
+++ b/tools/testing/selftests/kmsg/Makefile
@@ -0,0 +1,30 @@
+CFLAGS += -I../../../../usr/include/
+CFLAGS += -I../../../../samples/kmsg/
+CFLAGS += -I../../../../include/uapi/
+CFLAGS += -std=gnu99 -Wall
+CFLAGS += -DKBUILD_MODNAME=\"kmsg\" -D_GNU_SOURCE
+CFLAGS += -pthread
+LDLIBS += -pthread
+
+OBJS= \
+   kmsg-test.o \
+   test-buffer-add-del.o   \
+   test-buffer-add-write-read-del.o\
+   test-buffer-buf-torture.o   \
+   test-buffer-buf-multithreaded-torture.o
+
+all: kmsg-test
+
+include ../lib.mk
+
+%.o: %.c kmsg-test.h
+   $(CC) $(CFLAGS) -c $< -o $@
+
+kmsg-test: $(OBJS)
+   $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
+
+run_tests:
+   ./kmsg-test --tap
+
+clean:
+   rm -f *.o kmsg-test
diff --git a/tools/testing/selftests/kmsg/kmsg-test.c 
b/tools/testing/selftests/kmsg/kmsg-test.c
new file mode 100644
index 000..4f17b73
--- /dev/null
+++ b/tools/testing/selftests/kmsg/kmsg-test.c
@@ -0,0 +1,329 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "kmsg-test.h"
+
+struct kmsg_test {
+   const char  *name;
+   const char  *desc;
+   int (*func)(const struct kmsg_test_args *args);
+};
+
+static const struct kmsg_test tests[] = {
+   {
+   .name   = "buffer-add-del",
+   .desc   = "create and dele

[RFC v4 4/9] kmsg: add additional buffers support to memory class

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Memory class does not support additional kmsg buffers.

Add additional kmsg buffers support to:
* devnode() callback of "mem" class
* file operations of major "mem" character device

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 drivers/char/mem.c | 27 ---
 include/linux/printk.h | 32 
 kernel/printk/kmsg.c   | 42 ++
 kernel/printk/printk.c |  1 +
 kernel/printk/printk.h |  1 +
 5 files changed, 96 insertions(+), 7 deletions(-)

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 6b1721f..7d46234 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -799,9 +799,6 @@ static const struct memdev {
 [7] = { "full", 0666, &full_fops, 0 },
 [8] = { "random", 0666, &random_fops, 0 },
 [9] = { "urandom", 0666, &urandom_fops, 0 },
-#ifdef CONFIG_PRINTK
-   [11] = { "kmsg", 0644, &kmsg_fops, 0 },
-#endif
 };
 
 static int memory_open(struct inode *inode, struct file *filp)
@@ -811,7 +808,7 @@ static int memory_open(struct inode *inode, struct file 
*filp)
 
minor = iminor(inode);
if (minor >= ARRAY_SIZE(devlist))
-   return -ENXIO;
+   return kmsg_memory_open(inode, filp);
 
dev = &devlist[minor];
if (!dev->fops)
@@ -833,16 +830,28 @@ static const struct file_operations memory_fops = {
 
 static char *mem_devnode(struct device *dev, umode_t *mode)
 {
-   if (mode && devlist[MINOR(dev->devt)].mode)
-   *mode = devlist[MINOR(dev->devt)].mode;
+   int minor = MINOR(dev->devt);
+
+   if (!mode)
+   goto out;
+
+   if (minor >= ARRAY_SIZE(devlist)) {
+   kmsg_mode(minor, mode);
+   goto out;
+   }
+
+   if (devlist[minor].mode)
+   *mode = devlist[minor].mode;
+out:
return NULL;
 }
 
-static struct class *mem_class;
+struct class *mem_class;
 
 static int __init chr_dev_init(void)
 {
int minor;
+   struct device *kmsg;
 
if (register_chrdev(MEM_MAJOR, "mem", &memory_fops))
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
@@ -866,6 +875,10 @@ static int __init chr_dev_init(void)
  NULL, devlist[minor].name);
}
 
+   kmsg = init_kmsg(KMSG_MINOR, 0644);
+   if (IS_ERR(kmsg))
+   return PTR_ERR(kmsg);
+
return tty_init();
 }
 
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 9729565..0c4f9de 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -417,8 +417,40 @@ do {   
\
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
 #endif
 
+#define KMSG_MINOR 11
+
+struct file;
+struct inode;
+
+#ifdef CONFIG_PRINTK
+
+extern struct class *mem_class;
+
 extern const struct file_operations kmsg_fops;
 
+extern struct device *init_kmsg(int minor, umode_t mode);
+extern int kmsg_memory_open(struct inode *inode, struct file *filp);
+extern int kmsg_mode(int minor, umode_t *mode);
+
+#else
+
+static inline struct device *init_kmsg(int minor, umode_t mode)
+{
+   return NULL;
+}
+
+static inline int kmsg_memory_open(struct inode *inode, struct file *filp)
+{
+   return -ENXIO;
+}
+
+static inline int kmsg_mode(int minor, umode_t *mode)
+{
+   return -ENXIO;
+}
+
+#endif
+
 enum {
DUMP_PREFIX_NONE,
DUMP_PREFIX_ADDRESS,
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 42e784bd..726250f 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -16,6 +16,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #include 
 
@@ -386,6 +389,45 @@ const struct file_operations kmsg_fops = {
.release = devkmsg_release,
 };
 
+/* Should be used for device registration */
+struct device *init_kmsg(int minor, umode_t mode)
+{
+   log_buf.minor = minor;
+   log_buf.mode = mode;
+   return device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
+   NULL, "kmsg");
+}
+
+int kmsg_memory_open(struct inode *inode, struct file *filp)
+{
+   filp->f_op = &kmsg_fops;
+
+   return kmsg_fops.open(inode, filp);
+}
+
+int kmsg_mode(int minor, umode_t *mode)
+{
+   int ret = -ENXIO;
+   struct log_buffer *log_b;
+
+   if (minor == log_buf.minor) {
+   *mode = log_buf.mode;
+   return 0;
+   }
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(log_b, &log_buf.list, list) {
+   if (log_b->minor == minor) {
+   *mode = log_b->mode;
+   ret = 0;
+   break;
+   }
+   }
+   rcu_read_unlock();
+
+  

[RFC v4 5/9] kmsg: add function for adding and deleting additional buffers

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Additional kmsg buffers should be created and deleted dynamically.

Adding two functions
* kmsg_sys_buffer_add() creates additional kmsg buffer returning minor
* kmsg_sys_buffer_del() deletes one based on provided minor

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 include/linux/printk.h |   9 +
 kernel/printk/kmsg.c   | 107 +++--
 kernel/printk/printk.c |  12 ++
 kernel/printk/printk.h |   4 ++
 4 files changed, 129 insertions(+), 3 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 0c4f9de..513fa6f 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -431,6 +431,8 @@ extern const struct file_operations kmsg_fops;
 extern struct device *init_kmsg(int minor, umode_t mode);
 extern int kmsg_memory_open(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);
 
 #else
 
@@ -449,6 +451,13 @@ static inline int kmsg_mode(int minor, umode_t *mode)
return -ENXIO;
 }
 
+static inline int kmsg_sys_buffer_add(size_t size, umode_t mode)
+{
+   return -ENXIO;
+}
+
+static inline void kmsg_sys_buffer_del(int minor) {}
+
 #endif
 
 enum {
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 726250f..9222fdc 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -141,8 +142,20 @@ static ssize_t kmsg_read(struct log_buffer *log_b, struct 
file *file,
}
 
raw_spin_unlock_irq(&log_b->lock);
-   ret = wait_event_interruptible(log_b->wait,
-  user->seq != log_b->next_seq);
+   if (log_b == &log_buf) {
+   ret = wait_event_interruptible(log_b->wait,
+   user->seq != log_b->next_seq);
+   } else {
+   rcu_read_unlock();
+   kref_get(&log_b->refcount);
+   ret = wait_event_interruptible(log_b->wait,
+   user->seq != log_b->next_seq);
+   if (log_b->minor == -1)
+   ret = -ENXIO;
+   if (kref_put(&log_b->refcount, log_buf_release))
+   ret = -ENXIO;
+   rcu_read_lock();
+   }
if (ret)
goto out;
raw_spin_lock_irq(&log_b->lock);
@@ -311,8 +324,14 @@ static unsigned int devkmsg_poll(struct file *file, 
poll_table *wait)
rcu_read_lock();
list_for_each_entry_rcu(log_b, &log_buf.list, list) {
if (log_b->minor == minor) {
+   kref_get(&log_b->refcount);
+   rcu_read_unlock();
+
ret = kmsg_poll(log_b, file, wait);
-   break;
+
+   if (kref_put(&log_b->refcount, log_buf_release))
+   return POLLERR|POLLNVAL;
+   return ret;
}
}
rcu_read_unlock();
@@ -428,6 +447,88 @@ int kmsg_mode(int minor, umode_t *mode)
return ret;
 }
 
+static DEFINE_SPINLOCK(kmsg_sys_list_lock);
+
+int kmsg_sys_buffer_add(size_t size, umode_t mode)
+{
+   unsigned long flags;
+   int minor = log_buf.minor;
+   struct log_buffer *log_b;
+   struct log_buffer *log_b_new;
+
+   if (size < LOG_LINE_MAX + PREFIX_MAX)
+   return -EINVAL;
+
+   log_b_new = kzalloc(sizeof(struct log_buffer), GFP_KERNEL);
+   if (!log_b_new)
+   return -ENOMEM;
+
+   log_b_new->buf = kmalloc(size, GFP_KERNEL);
+   if (!log_b_new->buf) {
+   kfree(log_b_new);
+   return -ENOMEM;
+   }
+
+   log_b_new->len = size;
+   log_b_new->lock = __RAW_SPIN_LOCK_UNLOCKED(log_b_new->lock);
+   init_waitqueue_head(&log_b_new->wait);
+   kref_init(&log_b_new->refcount);
+   log_b_new->mode = mode;
+
+   kref_get(&log_b_new->refcount);
+
+   spin_lock_irqsave(&kmsg_sys_list_lock, flags);
+
+   list_for_each_entry(log_b, &log_buf.list, list) {
+   if (log_b->minor - minor > 1)
+   break;
+
+   minor = log_b->minor;
+   }
+
+   if (!(minor & MINORMASK)) {
+   kref_put(&log_b->refcount, log_buf_release);
+   spin_unlock_irqrestore(&kmsg_sys_list_lock, flags);
+   return -ERANGE;
+   }
+
+   minor += 1;
+   log_b_new->minor = minor;
+
+   list_add_tail_rcu

[RFC v4 8/9] kmsg: add predefined _PID, _TID, _COMM keywords to kmsg* log dict

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

kmsg* devices write operation wrote no dict along with message
Due to usage of kmsg devices in userspace dict has been added
identifying pid, tid and comm of writing process.

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 kernel/printk/kmsg.c | 40 
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index bcf0801..3bc83e9 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -29,6 +29,17 @@
 
 #define KMSG_MAX_MINOR_LEN 20
 
+#define MAX_PID_LEN20
+#define MAX_TID_LEN20
+/*
+ * Fromat below describes dict appended to message written from userspace:
+ * "_PID=\0_TID=\0_COMM="
+ * KMSG_DICT_MAX_LEN definition represents maximal length of this dict.
+ */
+#define KMSG_DICT_MAX_LEN  (5 + MAX_PID_LEN + 1 + \
+5 + MAX_TID_LEN + 1 + \
+6 + TASK_COMM_LEN)
+
 /* /dev/kmsg - userspace message inject/listen interface */
 struct devkmsg_user {
u64 seq;
@@ -38,7 +49,23 @@ struct devkmsg_user {
char buf[CONSOLE_EXT_LOG_MAX];
 };
 
-static int kmsg_sys_write(int minor, int level, const char *fmt, ...)
+static size_t set_kmsg_dict(char *buf)
+{
+   size_t len;
+
+   len = sprintf(buf, "_PID=%d", task_tgid_nr(current)) + 1;
+   len += sprintf(buf + len, "_TID=%d", task_pid_nr(current)) + 1;
+   memcpy(buf + len, "_COMM=", 6);
+   len += 6;
+   get_task_comm(buf + len, current);
+   while (buf[len] != '\0')
+   len++;
+   return len;
+}
+
+static int kmsg_sys_write(int minor, int level,
+ const char *dict, size_t dictlen,
+ const char *fmt, ...)
 {
va_list args;
int ret = -ENXIO;
@@ -53,7 +80,7 @@ static int kmsg_sys_write(int minor, int level, const char 
*fmt, ...)
 
va_start(args, fmt);
log_format_and_store(log_b, 1 /* LOG_USER */, level,
-NULL, 0, fmt, args);
+dict, dictlen, fmt, args);
va_end(args);
wake_up_interruptible(&log_b->wait);
 
@@ -73,6 +100,8 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
int level = default_message_loglevel;
int facility = 1;   /* LOG_USER */
size_t len = iov_iter_count(from);
+   char dict[KMSG_DICT_MAX_LEN] = "";
+   size_t dictlen;
ssize_t ret = len;
int minor = iminor(iocb->ki_filp->f_inode);
 
@@ -112,10 +141,13 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
}
}
 
+   dictlen = set_kmsg_dict(dict);
+
if (minor == log_buf.minor) {
-   printk_emit(facility, level, NULL, 0, "%s", line);
+   printk_emit(facility, level, dict, dictlen, "%s", line);
} else {
-   int error = kmsg_sys_write(minor, level, "%s", line);
+   int error = kmsg_sys_write(minor, level, dict, dictlen,
+  "%s", line);
 
if (error)
ret = error;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v4 6/9] kmsg: add ioctl for adding and deleting kmsg* devices

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

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 
Signed-off-by: Paul Osmialowski 
---
 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 | 122 +++
 6 files changed, 162 insertions(+), 1 deletion(-)
 create mode 100644 include/uapi/linux/kmsg_ioctl.h

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 43e6923..76dec8b 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -319,6 +319,7 @@ Code  Seq#(hex) Include FileComments
<mailto:v...@ratio.de>
 0xB1   00-1F   PPPoX   <mailto:mostr...@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 7d46234..ac824de 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 513fa6f..ebacfa6 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 e777078..d998999 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -225,6 +225,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 000..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 
+#include 
+
+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 9222fdc..62bb4d5 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -23,8 +23,12 @@
 
 #include 
 
+#include 
+
 #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(str

[RFC v4 3/9] kmsg: introduce additional kmsg devices support

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

kmsg device provides operations on cyclic logging buffer used mainly
by kernel but also in userspace by privileged processes.

Additional kmsg devices keep the same log format but may be added
dynamically with custom size.

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 fs/proc/kmsg.c |   4 +-
 kernel/printk/kmsg.c   | 301 --
 kernel/printk/printk.c | 317 ++---
 kernel/printk/printk.h |  69 +++
 4 files changed, 431 insertions(+), 260 deletions(-)

diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 05f8dcd..0d354e4 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -17,7 +17,7 @@
 #include 
 #include 
 
-extern wait_queue_head_t log_wait;
+extern wait_queue_head_t *log_wait;
 
 static int kmsg_open(struct inode * inode, struct file * file)
 {
@@ -41,7 +41,7 @@ static ssize_t kmsg_read(struct file *file, char __user *buf,
 
 static unsigned int kmsg_poll(struct file *file, poll_table *wait)
 {
-   poll_wait(file, &log_wait, wait);
+   poll_wait(file, log_wait, wait);
if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC))
return POLLIN | POLLRDNORM;
return 0;
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 02981a7..42e784bd 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -30,6 +30,34 @@ struct devkmsg_user {
char buf[CONSOLE_EXT_LOG_MAX];
 };
 
+static int kmsg_sys_write(int minor, int level, const char *fmt, ...)
+{
+   va_list args;
+   int ret = -ENXIO;
+   struct log_buffer *log_b;
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(log_b, &log_buf.list, list) {
+   if (log_b->minor != minor)
+   continue;
+
+   raw_spin_lock(&log_b->lock);
+
+   va_start(args, fmt);
+   log_format_and_store(log_b, 1 /* LOG_USER */, level,
+NULL, 0, fmt, args);
+   va_end(args);
+   wake_up_interruptible(&log_b->wait);
+
+   raw_spin_unlock(&log_b->lock);
+
+   ret = 0;
+   break;
+   }
+   rcu_read_unlock();
+   return ret;
+}
+
 static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)
 {
char *buf, *line;
@@ -38,6 +66,7 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
int facility = 1;   /* LOG_USER */
size_t len = iov_iter_count(from);
ssize_t ret = len;
+   int minor = iminor(iocb->ki_filp->f_inode);
 
if (len > LOG_LINE_MAX)
return -EINVAL;
@@ -75,51 +104,57 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
}
}
 
-   printk_emit(facility, level, NULL, 0, "%s", line);
+   if (minor == log_buf.minor) {
+   printk_emit(facility, level, NULL, 0, "%s", line);
+   } else {
+   int error = kmsg_sys_write(minor, level, "%s", line);
+
+   if (error)
+   ret = error;
+   }
+
kfree(buf);
return ret;
 }
 
-static ssize_t devkmsg_read(struct file *file, char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t kmsg_read(struct log_buffer *log_b, struct file *file,
+char __user *buf, size_t count, loff_t *ppos)
 {
struct devkmsg_user *user = file->private_data;
struct printk_log *msg;
size_t len;
ssize_t ret;
 
-   if (!user)
-   return -EBADF;
-
ret = mutex_lock_interruptible(&user->lock);
if (ret)
return ret;
-   raw_spin_lock_irq(&logbuf_lock);
-   while (user->seq == log_next_seq) {
+
+   raw_spin_lock_irq(&log_b->lock);
+   while (user->seq == log_b->next_seq) {
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
-   raw_spin_unlock_irq(&logbuf_lock);
+   raw_spin_unlock_irq(&log_b->lock);
goto out;
}
 
-   raw_spin_unlock_irq(&logbuf_lock);
-   ret = wait_event_interruptible(log_wait,
-  user->seq != log_next_seq);
+   raw_spin_unlock_irq(&log_b->lock);
+   ret = wait_event_interruptible(log_b->wait,
+  user->seq != log_b->next_seq);
if (ret)
goto out;
-   raw_spin_lock_irq(&logbuf_lock);
+   raw_spin_lock_irq(&log_b->lock);
}
 
-   if (user->seq < log_first_seq) {
+   if (user->seq < log_b->first

[RFC v4 7/9] kmsg: add ioctl for kmsg* devices operating on buffers

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

There is no possibility to clear additional kmsg buffers,
get size of them or know what size should be passed to read
file operation (too small size causes it to retrun -EINVAL).

Add following ioctls which solve those issues:
* KMSG_CMD_GET_BUF_SIZE
* KMSG_CMD_GET_READ_SIZE_MAX
* KMSG_CMD_CLEAR

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 Documentation/ioctl/ioctl-number.txt |  2 +-
 include/uapi/linux/kmsg_ioctl.h  | 15 ++
 kernel/printk/kmsg.c | 57 ++--
 3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 76dec8b..d36bb04 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -319,7 +319,7 @@ Code  Seq#(hex) Include FileComments
<mailto:v...@ratio.de>
 0xB1   00-1F   PPPoX   <mailto:mostr...@styx.uwaterloo.ca>
 0xB3   00  linux/mmc/ioctl.h
-0xBB   00-02   uapi/linux/kmsg_ioctl.h
+0xBB   00-83   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/include/uapi/linux/kmsg_ioctl.h b/include/uapi/linux/kmsg_ioctl.h
index 96e7930..bfd9cd3 100644
--- a/include/uapi/linux/kmsg_ioctl.h
+++ b/include/uapi/linux/kmsg_ioctl.h
@@ -27,4 +27,19 @@ struct kmsg_cmd_buffer_add {
  struct kmsg_cmd_buffer_add)
 #define KMSG_CMD_BUFFER_DEL_IOW(KMSG_IOCTL_MAGIC, 0x01, int)
 
+/*
+ * A ioctl interface for kmsg* devices.
+ *
+ * KMSG_CMD_GET_BUF_SIZE:  Retrieve cyclic log buffer size associated with
+ * device.
+ * KMSG_CMD_GET_READ_SIZE_MAX: Retrieve max size of data read by kmsg read
+ * operation.
+ * KMSG_CMD_CLEAR: Clears cyclic log buffer. After that operation
+ * there is no data to read from buffer unless
+ * logs are written.
+ */
+#define KMSG_CMD_GET_BUF_SIZE  _IOR(KMSG_IOCTL_MAGIC, 0x80, __u32)
+#define KMSG_CMD_GET_READ_SIZE_MAX _IOR(KMSG_IOCTL_MAGIC, 0x81, __u32)
+#define KMSG_CMD_CLEAR _IO(KMSG_IOCTL_MAGIC, 0x82)
+
 #endif
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 62bb4d5..bcf0801 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -247,8 +247,9 @@ static loff_t kmsg_llseek(struct log_buffer *log_b, struct 
file *file,
}
/*
 * The first record after the last SYSLOG_ACTION_CLEAR,
-* like issued by 'dmesg -c'. Reading /dev/kmsg itself
-* changes no global state, and does not clear anything.
+* like issued by 'dmesg -c' or KMSG_CMD_CLEAR ioctl
+* command. Reading /dev/kmsg itself changes no global
+* state, and does not clear anything.
 */
user->idx = log_b->clear_idx;
user->seq = log_b->clear_seq;
@@ -391,6 +392,56 @@ static int devkmsg_open(struct inode *inode, struct file 
*file)
return ret;
 }
 
+static long kmsg_ioctl(struct log_buffer *log_b, unsigned int cmd,
+  unsigned long arg)
+{
+   void __user *argp = (void __user *)arg;
+   static const u32 read_size_max = CONSOLE_EXT_LOG_MAX;
+
+   switch (cmd) {
+   case KMSG_CMD_GET_BUF_SIZE:
+   if (copy_to_user(argp, &log_b->len, sizeof(u32)))
+   return -EFAULT;
+   break;
+   case KMSG_CMD_GET_READ_SIZE_MAX:
+   if (copy_to_user(argp, &read_size_max, sizeof(u32)))
+   return -EFAULT;
+   break;
+   case KMSG_CMD_CLEAR:
+   if (!capable(CAP_SYSLOG))
+   return -EPERM;
+   raw_spin_lock_irq(&log_b->lock);
+   log_b->clear_seq = log_b->next_seq;
+   log_b->clear_idx = log_b->next_idx;
+   raw_spin_unlock_irq(&log_b->lock);
+   break;
+   default:
+   return -ENOTTY;
+   }
+   return 0;
+}
+
+static long devkmsg_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+   long ret = -ENXIO;
+   int minor = iminor(file->f_inode);
+   struct log_buffer *log_b;
+
+   if (minor == log_buf.minor)
+   return kmsg_ioctl(&log_buf, cmd, arg);
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(log_b, &log_buf.list, list) {
+   if (log_b->minor == minor) {
+   ret = kmsg_ioctl(log_b, cmd, arg);
+   break;
+   }
+   }
+   rcu_read_unlock();
+   return 

[RFC v4 0/9] Additional kmsg devices

2015-10-19 Thread Paul Osmialowski
Dear All,

This is the fourth iteration of Marcin Niesluchowski's serie of patches
extending kmsg interface with ability to dynamically create (and destroy)
kmsg-like devices which can be used by userspace for logging.

In this iteration, problems spotted by kbuild test robot are addressed.

Also problem with inproper use of copy_from_user() spotted by
Arnd Bergmanns is fixed (Thanks Arnd!).

I would like to apologize to Richard for omitting him in the CC. This was
unintended.

I do realise that there is a strong movement against putting into kernel
things that could be done in userpsace, however a large number of diverse
environments in which Linux can operate entails greater flexibility in our
perception of what should be in userspace and what should be (carefully)
embraced by the kernel.

Best regards,
Paul

Marcin Niesluchowski (7):
  printk: add one function for storing log in proper format
  kmsg: introduce additional kmsg devices support
  kmsg: add additional buffers support to memory class
  kmsg: add function for adding and deleting additional buffers
  kmsg: add ioctl for adding and deleting kmsg* devices
  kmsg: add ioctl for kmsg* devices operating on buffers
  kmsg: add predefined _PID, _TID, _COMM keywords to kmsg* log dict

Paul Osmialowski (2):
  printk: extract kmsg-related routines from printk.c to kmsg.c
  kmsg: selftests

 Documentation/ioctl/ioctl-number.txt   |1 +
 drivers/char/mem.c |   27 +-
 fs/proc/kmsg.c |4 +-
 include/linux/printk.h |   48 +
 include/uapi/linux/Kbuild  |1 +
 include/uapi/linux/kmsg_ioctl.h|   45 +
 kernel/printk/Makefile |1 +
 kernel/printk/kmsg.c   | 1054 +
 kernel/printk/printk.c | 1251 +---
 kernel/printk/printk.h |  256 
 samples/kmsg/kmsg-api.h|   44 +
 tools/testing/selftests/Makefile   |1 +
 tools/testing/selftests/kmsg/.gitignore|1 +
 tools/testing/selftests/kmsg/Makefile  |   30 +
 tools/testing/selftests/kmsg/kmsg-test.c   |  329 +
 tools/testing/selftests/kmsg/kmsg-test.h   |   34 +
 tools/testing/selftests/kmsg/test-buffer-add-del.c |   76 ++
 .../kmsg/test-buffer-add-write-read-del.c  |  161 +++
 .../kmsg/test-buffer-buf-multithreaded-torture.c   |  199 
 .../selftests/kmsg/test-buffer-buf-torture.c   |  139 +++
 20 files changed, 2737 insertions(+), 965 deletions(-)
 create mode 100644 include/uapi/linux/kmsg_ioctl.h
 create mode 100644 kernel/printk/kmsg.c
 create mode 100644 kernel/printk/printk.h
 create mode 100644 samples/kmsg/kmsg-api.h
 create mode 100644 tools/testing/selftests/kmsg/.gitignore
 create mode 100644 tools/testing/selftests/kmsg/Makefile
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.c
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.h
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-add-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-add-write-read-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-buf-multithreaded-torture.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-buf-torture.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v3 5/9] kmsg: add function for adding and deleting additional buffers

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Additional kmsg buffers should be created and deleted dynamically.

Adding two functions
* kmsg_sys_buffer_add() creates additional kmsg buffer returning minor
* kmsg_sys_buffer_del() deletes one based on provided minor

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 include/linux/printk.h |   9 +
 kernel/printk/kmsg.c   | 107 +++--
 kernel/printk/printk.c |  12 ++
 kernel/printk/printk.h |   4 ++
 4 files changed, 129 insertions(+), 3 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 67840e0..35111e8 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -431,6 +431,8 @@ extern const struct file_operations kmsg_fops;
 extern struct device *init_kmsg(int minor, umode_t mode);
 extern int kmsg_memory_open(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);
 
 #else
 
@@ -449,6 +451,13 @@ static inline int kmsg_mode(int minor, umode_t *mode)
return -ENXIO;
 }
 
+static inline int kmsg_sys_buffer_add(size_t size, umode_t mode)
+{
+   return -ENXIO;
+}
+
+static inline void kmsg_sys_buffer_del(int minor) {}
+
 #endif
 
 enum {
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 7fcd628..184575b 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -140,8 +141,20 @@ static ssize_t kmsg_read(struct log_buffer *log_b, struct 
file *file,
}
 
raw_spin_unlock_irq(&log_b->lock);
-   ret = wait_event_interruptible(log_b->wait,
-  user->seq != log_b->next_seq);
+   if (log_b == &log_buf) {
+   ret = wait_event_interruptible(log_b->wait,
+   user->seq != log_b->next_seq);
+   } else {
+   rcu_read_unlock();
+   kref_get(&log_b->refcount);
+   ret = wait_event_interruptible(log_b->wait,
+   user->seq != log_b->next_seq);
+   if (log_b->minor == -1)
+   ret = -ENXIO;
+   if (kref_put(&log_b->refcount, log_buf_release))
+   ret = -ENXIO;
+   rcu_read_lock();
+   }
if (ret)
goto out;
raw_spin_lock_irq(&log_b->lock);
@@ -310,8 +323,14 @@ static unsigned int devkmsg_poll(struct file *file, 
poll_table *wait)
rcu_read_lock();
list_for_each_entry_rcu(log_b, &log_buf.list, list) {
if (log_b->minor == minor) {
+   kref_get(&log_b->refcount);
+   rcu_read_unlock();
+
ret = kmsg_poll(log_b, file, wait);
-   break;
+
+   if (kref_put(&log_b->refcount, log_buf_release))
+   return POLLERR|POLLNVAL;
+   return ret;
}
}
rcu_read_unlock();
@@ -427,6 +446,88 @@ int kmsg_mode(int minor, umode_t *mode)
return ret;
 }
 
+static DEFINE_SPINLOCK(kmsg_sys_list_lock);
+
+int kmsg_sys_buffer_add(size_t size, umode_t mode)
+{
+   unsigned long flags;
+   int minor = log_buf.minor;
+   struct log_buffer *log_b;
+   struct log_buffer *log_b_new;
+
+   if (size < LOG_LINE_MAX + PREFIX_MAX)
+   return -EINVAL;
+
+   log_b_new = kzalloc(sizeof(struct log_buffer), GFP_KERNEL);
+   if (!log_b_new)
+   return -ENOMEM;
+
+   log_b_new->buf = kmalloc(size, GFP_KERNEL);
+   if (!log_b_new->buf) {
+   kfree(log_b_new);
+   return -ENOMEM;
+   }
+
+   log_b_new->len = size;
+   log_b_new->lock = __RAW_SPIN_LOCK_UNLOCKED(log_b_new->lock);
+   init_waitqueue_head(&log_b_new->wait);
+   kref_init(&log_b_new->refcount);
+   log_b_new->mode = mode;
+
+   kref_get(&log_b_new->refcount);
+
+   spin_lock_irqsave(&kmsg_sys_list_lock, flags);
+
+   list_for_each_entry(log_b, &log_buf.list, list) {
+   if (log_b->minor - minor > 1)
+   break;
+
+   minor = log_b->minor;
+   }
+
+   if (!(minor & MINORMASK)) {
+   kref_put(&log_b->refcount, log_buf_release);
+   spin_unlock_irqrestore(&kmsg_sys_list_lock, flags);
+   return -ERANGE;
+   }
+
+   minor += 1;
+   log_b_new->minor = minor;
+
+   list_add_tail_rcu

[RFC v3 3/9] kmsg: introduce additional kmsg devices support

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

kmsg device provides operations on cyclic logging buffer used mainly
by kernel but also in userspace by privileged processes.

Additional kmsg devices keep the same log format but may be added
dynamically with custom size.

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 fs/proc/kmsg.c |   4 +-
 kernel/printk/kmsg.c   | 301 --
 kernel/printk/printk.c | 317 ++---
 kernel/printk/printk.h |  69 +++
 4 files changed, 431 insertions(+), 260 deletions(-)

diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 05f8dcd..0d354e4 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -17,7 +17,7 @@
 #include 
 #include 
 
-extern wait_queue_head_t log_wait;
+extern wait_queue_head_t *log_wait;
 
 static int kmsg_open(struct inode * inode, struct file * file)
 {
@@ -41,7 +41,7 @@ static ssize_t kmsg_read(struct file *file, char __user *buf,
 
 static unsigned int kmsg_poll(struct file *file, poll_table *wait)
 {
-   poll_wait(file, &log_wait, wait);
+   poll_wait(file, log_wait, wait);
if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC))
return POLLIN | POLLRDNORM;
return 0;
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 260b2ee..23d4160 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -29,6 +29,34 @@ struct devkmsg_user {
char buf[CONSOLE_EXT_LOG_MAX];
 };
 
+static int kmsg_sys_write(int minor, int level, const char *fmt, ...)
+{
+   va_list args;
+   int ret = -ENXIO;
+   struct log_buffer *log_b;
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(log_b, &log_buf.list, list) {
+   if (log_b->minor != minor)
+   continue;
+
+   raw_spin_lock(&log_b->lock);
+
+   va_start(args, fmt);
+   log_format_and_store(log_b, 1 /* LOG_USER */, level,
+NULL, 0, fmt, args);
+   va_end(args);
+   wake_up_interruptible(&log_b->wait);
+
+   raw_spin_unlock(&log_b->lock);
+
+   ret = 0;
+   break;
+   }
+   rcu_read_unlock();
+   return ret;
+}
+
 static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)
 {
char *buf, *line;
@@ -37,6 +65,7 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
int facility = 1;   /* LOG_USER */
size_t len = iov_iter_count(from);
ssize_t ret = len;
+   int minor = iminor(iocb->ki_filp->f_inode);
 
if (len > LOG_LINE_MAX)
return -EINVAL;
@@ -74,51 +103,57 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
}
}
 
-   printk_emit(facility, level, NULL, 0, "%s", line);
+   if (minor == log_buf.minor) {
+   printk_emit(facility, level, NULL, 0, "%s", line);
+   } else {
+   int error = kmsg_sys_write(minor, level, "%s", line);
+
+   if (error)
+   ret = error;
+   }
+
kfree(buf);
return ret;
 }
 
-static ssize_t devkmsg_read(struct file *file, char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t kmsg_read(struct log_buffer *log_b, struct file *file,
+char __user *buf, size_t count, loff_t *ppos)
 {
struct devkmsg_user *user = file->private_data;
struct printk_log *msg;
size_t len;
ssize_t ret;
 
-   if (!user)
-   return -EBADF;
-
ret = mutex_lock_interruptible(&user->lock);
if (ret)
return ret;
-   raw_spin_lock_irq(&logbuf_lock);
-   while (user->seq == log_next_seq) {
+
+   raw_spin_lock_irq(&log_b->lock);
+   while (user->seq == log_b->next_seq) {
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
-   raw_spin_unlock_irq(&logbuf_lock);
+   raw_spin_unlock_irq(&log_b->lock);
goto out;
}
 
-   raw_spin_unlock_irq(&logbuf_lock);
-   ret = wait_event_interruptible(log_wait,
-  user->seq != log_next_seq);
+   raw_spin_unlock_irq(&log_b->lock);
+   ret = wait_event_interruptible(log_b->wait,
+  user->seq != log_b->next_seq);
if (ret)
goto out;
-   raw_spin_lock_irq(&logbuf_lock);
+   raw_spin_lock_irq(&log_b->lock);
}
 
-   if (user->seq < log_first_seq) {
+   if (user->seq < log_b->first

[RFC v3 2/9] printk: add one function for storing log in proper format

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Preparation commit for future changes purpose.

Separate code responsible for storing log message in proper format
from operations on consoles by putting it in another function.

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 kernel/printk/printk.c | 222 ++---
 1 file changed, 119 insertions(+), 103 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 50c48c7..ee80655 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -181,6 +181,27 @@ static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
 static char *log_buf = __log_buf;
 static u32 log_buf_len = __LOG_BUF_LEN;
 
+/*
+ * Continuation lines are buffered, and not committed to the record buffer
+ * until the line is complete, or a race forces it. The line fragments
+ * though, are printed immediately to the consoles to ensure everything has
+ * reached the console in case of a kernel crash.
+ */
+static struct cont {
+   char buf[LOG_LINE_MAX];
+   size_t len; /* length == 0 means unused buffer */
+   size_t cons;/* bytes written to console */
+   struct task_struct *owner;  /* task of first print*/
+   u64 ts_nsec;/* time of first print */
+   u8 level;   /* log level of first message */
+   u8 facility;/* log facility of first message */
+   enum log_flags flags;   /* prefix, newline flags */
+   bool flushed:1; /* buffer sealed and committed */
+} cont;
+
+static void cont_flush(enum log_flags flags);
+static bool cont_add(int facility, int level, const char *text, size_t len);
+
 /* Return log buffer address */
 char *log_buf_addr_get(void)
 {
@@ -332,6 +353,102 @@ static int log_store(int facility, int level,
return msg->text_len;
 }
 
+static int log_format_and_store(int facility, int level,
+   const char *dict, size_t dictlen,
+   const char *fmt, va_list args)
+{
+   static char textbuf[LOG_LINE_MAX];
+   char *text = textbuf;
+   size_t text_len = 0;
+   enum log_flags lflags = 0;
+   int printed_len = 0;
+
+   /*
+* The printf needs to come first; we need the syslog
+* prefix which might be passed-in as a parameter.
+*/
+   text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
+
+   /* mark and strip a trailing newline */
+   if (text_len && text[text_len-1] == '\n') {
+   text_len--;
+   lflags |= LOG_NEWLINE;
+   }
+
+   /* strip kernel syslog prefix and extract log level or control flags */
+   if (facility == 0) {
+   int kern_level = printk_get_level(text);
+
+   if (kern_level) {
+   const char *end_of_header = printk_skip_level(text);
+
+   switch (kern_level) {
+   case '0' ... '7':
+   if (level == LOGLEVEL_DEFAULT)
+   level = kern_level - '0';
+   /* fallthrough */
+   case 'd':   /* KERN_DEFAULT */
+   lflags |= LOG_PREFIX;
+   }
+   /*
+* No need to check length here because vscnprintf
+* put '\0' at the end of the string. Only valid and
+* newly printed level is detected.
+*/
+   text_len -= end_of_header - text;
+   text = (char *)end_of_header;
+   }
+   }
+
+   if (level == LOGLEVEL_DEFAULT)
+   level = default_message_loglevel;
+
+   if (dict)
+   lflags |= LOG_PREFIX|LOG_NEWLINE;
+
+   if (!(lflags & LOG_NEWLINE)) {
+   /*
+* Flush the conflicting buffer. An earlier newline was missing,
+* or another task also prints continuation lines.
+*/
+   if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
+   cont_flush(LOG_NEWLINE);
+
+   /* buffer line if possible, otherwise store it right away */
+   if (cont_add(facility, level, text, text_len))
+   printed_len += text_len;
+   else
+   printed_len += log_store(facility, level,
+lflags | LOG_CONT, 0,
+dict, dictlen, text, text_len);
+   } else {
+   bool stored = false;
+
+   /*
+* If an earlier newline was missing and it was the same task,
+* eithe

[RFC v3 0/9] Additional kmsg devices

2015-10-19 Thread Paul Osmialowski
Dear All,

This is the third iteration of Marcin Niesluchowski's serie of patches
extending kmsg interface with ability to dynamically create (and destroy)
kmsg-like devices which can be used by userspace for logging.

In this iteration, following Joe Perches's suggestion, I've extracted
kmsg related functions from printk.c to a new file, kmsg.c.

Best regards,
Paul

Marcin Niesluchowski (7):
  printk: add one function for storing log in proper format
  kmsg: introduce additional kmsg devices support
  kmsg: add additional buffers support to memory class
  kmsg: add function for adding and deleting additional buffers
  kmsg: add ioctl for adding and deleting kmsg* devices
  kmsg: add ioctl for kmsg* devices operating on buffers
  kmsg: add predefined _PID, _TID, _COMM keywords to kmsg* log dict

Paul Osmialowski (2):
  printk: extract kmsg-related routines from printk.c to kmsg.c
  kmsg: selftests

 Documentation/ioctl/ioctl-number.txt   |1 +
 drivers/char/mem.c |   27 +-
 fs/proc/kmsg.c |4 +-
 include/linux/printk.h |   48 +
 include/uapi/linux/Kbuild  |1 +
 include/uapi/linux/kmsg_ioctl.h|   45 +
 kernel/printk/Makefile |1 +
 kernel/printk/kmsg.c   | 1054 +
 kernel/printk/printk.c | 1250 +---
 kernel/printk/printk.h |  247 
 samples/kmsg/kmsg-api.h|   44 +
 tools/testing/selftests/Makefile   |1 +
 tools/testing/selftests/kmsg/.gitignore|1 +
 tools/testing/selftests/kmsg/Makefile  |   30 +
 tools/testing/selftests/kmsg/kmsg-test.c   |  329 ++
 tools/testing/selftests/kmsg/kmsg-test.h   |   34 +
 tools/testing/selftests/kmsg/test-buffer-add-del.c |   76 ++
 .../kmsg/test-buffer-add-write-read-del.c  |  161 +++
 .../kmsg/test-buffer-buf-multithreaded-torture.c   |  199 
 .../selftests/kmsg/test-buffer-buf-torture.c   |  139 +++
 20 files changed, 2729 insertions(+), 963 deletions(-)
 create mode 100644 include/uapi/linux/kmsg_ioctl.h
 create mode 100644 kernel/printk/kmsg.c
 create mode 100644 kernel/printk/printk.h
 create mode 100644 samples/kmsg/kmsg-api.h
 create mode 100644 tools/testing/selftests/kmsg/.gitignore
 create mode 100644 tools/testing/selftests/kmsg/Makefile
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.c
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.h
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-add-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-add-write-read-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-buf-multithreaded-torture.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-buf-torture.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v3 7/9] kmsg: add ioctl for kmsg* devices operating on buffers

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

There is no possibility to clear additional kmsg buffers,
get size of them or know what size should be passed to read
file operation (too small size causes it to retrun -EINVAL).

Add following ioctls which solve those issues:
* KMSG_CMD_GET_BUF_SIZE
* KMSG_CMD_GET_READ_SIZE_MAX
* KMSG_CMD_CLEAR

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 Documentation/ioctl/ioctl-number.txt |  2 +-
 include/uapi/linux/kmsg_ioctl.h  | 15 ++
 kernel/printk/kmsg.c | 57 ++--
 3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 76dec8b..d36bb04 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -319,7 +319,7 @@ Code  Seq#(hex) Include FileComments
<mailto:v...@ratio.de>
 0xB1   00-1F   PPPoX   <mailto:mostr...@styx.uwaterloo.ca>
 0xB3   00  linux/mmc/ioctl.h
-0xBB   00-02   uapi/linux/kmsg_ioctl.h
+0xBB   00-83   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/include/uapi/linux/kmsg_ioctl.h b/include/uapi/linux/kmsg_ioctl.h
index 89c0c61..2389d9f 100644
--- a/include/uapi/linux/kmsg_ioctl.h
+++ b/include/uapi/linux/kmsg_ioctl.h
@@ -27,4 +27,19 @@ struct kmsg_cmd_buffer_add {
  struct kmsg_cmd_buffer_add)
 #define KMSG_CMD_BUFFER_DEL_IOW(KMSG_IOCTL_MAGIC, 0x01, int)
 
+/*
+ * A ioctl interface for kmsg* devices.
+ *
+ * KMSG_CMD_GET_BUF_SIZE:  Retrieve cyclic log buffer size associated with
+ * device.
+ * KMSG_CMD_GET_READ_SIZE_MAX: Retrieve max size of data read by kmsg read
+ * operation.
+ * KMSG_CMD_CLEAR: Clears cyclic log buffer. After that operation
+ * there is no data to read from buffer unless
+ * logs are written.
+ */
+#define KMSG_CMD_GET_BUF_SIZE  _IOR(KMSG_IOCTL_MAGIC, 0x80, __u32)
+#define KMSG_CMD_GET_READ_SIZE_MAX _IOR(KMSG_IOCTL_MAGIC, 0x81, __u32)
+#define KMSG_CMD_CLEAR _IO(KMSG_IOCTL_MAGIC, 0x82)
+
 #endif
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index f91a64a..0f56fc9 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -246,8 +246,9 @@ static loff_t kmsg_llseek(struct log_buffer *log_b, struct 
file *file,
}
/*
 * The first record after the last SYSLOG_ACTION_CLEAR,
-* like issued by 'dmesg -c'. Reading /dev/kmsg itself
-* changes no global state, and does not clear anything.
+* like issued by 'dmesg -c' or KMSG_CMD_CLEAR ioctl
+* command. Reading /dev/kmsg itself changes no global
+* state, and does not clear anything.
 */
user->idx = log_b->clear_idx;
user->seq = log_b->clear_seq;
@@ -390,6 +391,56 @@ static int devkmsg_open(struct inode *inode, struct file 
*file)
return ret;
 }
 
+static long kmsg_ioctl(struct log_buffer *log_b, unsigned int cmd,
+  unsigned long arg)
+{
+   void __user *argp = (void __user *)arg;
+   static const u32 read_size_max = CONSOLE_EXT_LOG_MAX;
+
+   switch (cmd) {
+   case KMSG_CMD_GET_BUF_SIZE:
+   if (copy_to_user(argp, &log_b->len, sizeof(u32)))
+   return -EFAULT;
+   break;
+   case KMSG_CMD_GET_READ_SIZE_MAX:
+   if (copy_to_user(argp, &read_size_max, sizeof(u32)))
+   return -EFAULT;
+   break;
+   case KMSG_CMD_CLEAR:
+   if (!capable(CAP_SYSLOG))
+   return -EPERM;
+   raw_spin_lock_irq(&log_b->lock);
+   log_b->clear_seq = log_b->next_seq;
+   log_b->clear_idx = log_b->next_idx;
+   raw_spin_unlock_irq(&log_b->lock);
+   break;
+   default:
+   return -ENOTTY;
+   }
+   return 0;
+}
+
+static long devkmsg_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+   long ret = -ENXIO;
+   int minor = iminor(file->f_inode);
+   struct log_buffer *log_b;
+
+   if (minor == log_buf.minor)
+   return kmsg_ioctl(&log_buf, cmd, arg);
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(log_b, &log_buf.list, list) {
+   if (log_b->minor == minor) {
+   ret = kmsg_ioctl(log_b, cmd, arg);
+   break;
+   }
+   }
+   rcu_read_unlock();
+   return 

[RFC v3 9/9] kmsg: selftests

2015-10-19 Thread Paul Osmialowski
This patch adds selftests framework and four test scenarios for kmsg.

The framework shape and code was inspired by similar selftests framework
for kdbus.

Signed-off-by: Paul Osmialowski 
---
 samples/kmsg/kmsg-api.h|  44 +++
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/kmsg/.gitignore|   1 +
 tools/testing/selftests/kmsg/Makefile  |  30 ++
 tools/testing/selftests/kmsg/kmsg-test.c   | 329 +
 tools/testing/selftests/kmsg/kmsg-test.h   |  34 +++
 tools/testing/selftests/kmsg/test-buffer-add-del.c |  76 +
 .../kmsg/test-buffer-add-write-read-del.c  | 161 ++
 .../kmsg/test-buffer-buf-multithreaded-torture.c   | 199 +
 .../selftests/kmsg/test-buffer-buf-torture.c   | 139 +
 10 files changed, 1014 insertions(+)
 create mode 100644 samples/kmsg/kmsg-api.h
 create mode 100644 tools/testing/selftests/kmsg/.gitignore
 create mode 100644 tools/testing/selftests/kmsg/Makefile
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.c
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.h
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-add-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-add-write-read-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-buf-multithreaded-torture.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-buf-torture.c

diff --git a/samples/kmsg/kmsg-api.h b/samples/kmsg/kmsg-api.h
new file mode 100644
index 000..9004acd
--- /dev/null
+++ b/samples/kmsg/kmsg-api.h
@@ -0,0 +1,44 @@
+#ifndef KMSG_API_H
+#define KMSG_API_H
+
+#include 
+#include 
+#include 
+#include 
+
+static inline int kmsg_cmd_buffer_add(int fd, struct kmsg_cmd_buffer_add *cmd)
+{
+   int ret = ioctl(fd, KMSG_CMD_BUFFER_ADD, cmd);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_buffer_del(int fd, int *minor)
+{
+   int ret = ioctl(fd, KMSG_CMD_BUFFER_DEL, minor);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_get_buf_size(int fd, uint32_t *size)
+{
+   int ret = ioctl(fd, KMSG_CMD_GET_BUF_SIZE, size);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_get_read_size_max(int fd, uint32_t *max_size)
+{
+   int ret = ioctl(fd, KMSG_CMD_GET_READ_SIZE_MAX, max_size);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_clear(int fd)
+{
+   int ret = ioctl(fd, KMSG_CMD_CLEAR);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+#endif /* KMSG_API_H */
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index bf4ece6..b7bdf58 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += ftrace
 TARGETS += futex
 TARGETS += kcmp
 TARGETS += kdbus
+TARGETS += kmsg
 TARGETS += lib
 TARGETS += membarrier
 TARGETS += memfd
diff --git a/tools/testing/selftests/kmsg/.gitignore 
b/tools/testing/selftests/kmsg/.gitignore
new file mode 100644
index 000..687d517
--- /dev/null
+++ b/tools/testing/selftests/kmsg/.gitignore
@@ -0,0 +1 @@
+kmsg-test
diff --git a/tools/testing/selftests/kmsg/Makefile 
b/tools/testing/selftests/kmsg/Makefile
new file mode 100644
index 000..b4ba892
--- /dev/null
+++ b/tools/testing/selftests/kmsg/Makefile
@@ -0,0 +1,30 @@
+CFLAGS += -I../../../../usr/include/
+CFLAGS += -I../../../../samples/kmsg/
+CFLAGS += -I../../../../include/uapi/
+CFLAGS += -std=gnu99 -Wall
+CFLAGS += -DKBUILD_MODNAME=\"kmsg\" -D_GNU_SOURCE
+CFLAGS += -pthread
+LDLIBS += -pthread
+
+OBJS= \
+   kmsg-test.o \
+   test-buffer-add-del.o   \
+   test-buffer-add-write-read-del.o\
+   test-buffer-buf-torture.o   \
+   test-buffer-buf-multithreaded-torture.o
+
+all: kmsg-test
+
+include ../lib.mk
+
+%.o: %.c kmsg-test.h
+   $(CC) $(CFLAGS) -c $< -o $@
+
+kmsg-test: $(OBJS)
+   $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
+
+run_tests:
+   ./kmsg-test --tap
+
+clean:
+   rm -f *.o kmsg-test
diff --git a/tools/testing/selftests/kmsg/kmsg-test.c 
b/tools/testing/selftests/kmsg/kmsg-test.c
new file mode 100644
index 000..4f17b73
--- /dev/null
+++ b/tools/testing/selftests/kmsg/kmsg-test.c
@@ -0,0 +1,329 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "kmsg-test.h"
+
+struct kmsg_test {
+   const char  *name;
+   const char  *desc;
+   int (*func)(const struct kmsg_test_args *args);
+};
+
+static const struct kmsg_test tests[] = {
+   {
+   .name   = "buffer-add-del",
+   .desc   = "create and dele

[RFC v3 6/9] kmsg: add ioctl for adding and deleting kmsg* devices

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

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 
Signed-off-by: Paul Osmialowski 
---
 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 | 123 +++
 6 files changed, 163 insertions(+), 1 deletion(-)
 create mode 100644 include/uapi/linux/kmsg_ioctl.h

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 43e6923..76dec8b 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -319,6 +319,7 @@ Code  Seq#(hex) Include FileComments
<mailto:v...@ratio.de>
 0xB1   00-1F   PPPoX   <mailto:mostr...@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 7d46234..ac824de 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 35111e8..294adab 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -427,9 +427,11 @@ extern struct class *mem_class;
 #define KMSG_MINOR 11
 
 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 e777078..d998999 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -225,6 +225,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 000..89c0c61
--- /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 
+#include 
+
+struct kmsg_cmd_buffer_add {
+   size_t size;
+   unsigned short mode;
+   int minor;
+} __attribute__((packed));
+
+#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 184575b..f91a64a 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -22,8 +22,12 @@
 
 #include 
 
+#include 
+
 #include "printk.h"
 
+#define KMSG_MAX_MINOR_LEN 20
+
 /* /dev/kmsg - userspace message inject/listen interface */
 struct devkmsg_user {
u64 seq;
@@ -407,6 +411,118 @@ 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 s

[RFC v3 8/9] kmsg: add predefined _PID, _TID, _COMM keywords to kmsg* log dict

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

kmsg* devices write operation wrote no dict along with message
Due to usage of kmsg devices in userspace dict has been added
identifying pid, tid and comm of writing process.

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 kernel/printk/kmsg.c | 40 
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 0f56fc9..8c904fe 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -28,6 +28,17 @@
 
 #define KMSG_MAX_MINOR_LEN 20
 
+#define MAX_PID_LEN20
+#define MAX_TID_LEN20
+/*
+ * Fromat below describes dict appended to message written from userspace:
+ * "_PID=\0_TID=\0_COMM="
+ * KMSG_DICT_MAX_LEN definition represents maximal length of this dict.
+ */
+#define KMSG_DICT_MAX_LEN  (5 + MAX_PID_LEN + 1 + \
+5 + MAX_TID_LEN + 1 + \
+6 + TASK_COMM_LEN)
+
 /* /dev/kmsg - userspace message inject/listen interface */
 struct devkmsg_user {
u64 seq;
@@ -37,7 +48,23 @@ struct devkmsg_user {
char buf[CONSOLE_EXT_LOG_MAX];
 };
 
-static int kmsg_sys_write(int minor, int level, const char *fmt, ...)
+static size_t set_kmsg_dict(char *buf)
+{
+   size_t len;
+
+   len = sprintf(buf, "_PID=%d", task_tgid_nr(current)) + 1;
+   len += sprintf(buf + len, "_TID=%d", task_pid_nr(current)) + 1;
+   memcpy(buf + len, "_COMM=", 6);
+   len += 6;
+   get_task_comm(buf + len, current);
+   while (buf[len] != '\0')
+   len++;
+   return len;
+}
+
+static int kmsg_sys_write(int minor, int level,
+ const char *dict, size_t dictlen,
+ const char *fmt, ...)
 {
va_list args;
int ret = -ENXIO;
@@ -52,7 +79,7 @@ static int kmsg_sys_write(int minor, int level, const char 
*fmt, ...)
 
va_start(args, fmt);
log_format_and_store(log_b, 1 /* LOG_USER */, level,
-NULL, 0, fmt, args);
+dict, dictlen, fmt, args);
va_end(args);
wake_up_interruptible(&log_b->wait);
 
@@ -72,6 +99,8 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
int level = default_message_loglevel;
int facility = 1;   /* LOG_USER */
size_t len = iov_iter_count(from);
+   char dict[KMSG_DICT_MAX_LEN];
+   size_t dictlen;
ssize_t ret = len;
int minor = iminor(iocb->ki_filp->f_inode);
 
@@ -111,10 +140,13 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
}
}
 
+   dictlen = set_kmsg_dict(dict);
+
if (minor == log_buf.minor) {
-   printk_emit(facility, level, NULL, 0, "%s", line);
+   printk_emit(facility, level, dict, dictlen, "%s", line);
} else {
-   int error = kmsg_sys_write(minor, level, "%s", line);
+   int error = kmsg_sys_write(minor, level, dict, dictlen,
+  "%s", line);
 
if (error)
ret = error;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v3 1/9] printk: extract kmsg-related routines from printk.c to kmsg.c

2015-10-19 Thread Paul Osmialowski
Following suggestions regarding printk.c code bloat, I prepared this
patch which moves kmsg-related routines to new file, kmsg.c

This is premilinary step needed for an attempt to extent kmsg interface
with ability to dynamically create (and destroy) kmsg-like devices.

Signed-off-by: Paul Osmialowski 
---
 kernel/printk/Makefile |   1 +
 kernel/printk/kmsg.c   | 574 ++
 kernel/printk/printk.c | 736 +
 kernel/printk/printk.h | 221 +++
 4 files changed, 810 insertions(+), 722 deletions(-)
 create mode 100644 kernel/printk/kmsg.c
 create mode 100644 kernel/printk/printk.h

diff --git a/kernel/printk/Makefile b/kernel/printk/Makefile
index 85405bd..bd6a4ec 100644
--- a/kernel/printk/Makefile
+++ b/kernel/printk/Makefile
@@ -1,2 +1,3 @@
 obj-y  = printk.o
+obj-$(CONFIG_PRINTK)   += kmsg.o
 obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
new file mode 100644
index 000..260b2ee
--- /dev/null
+++ b/kernel/printk/kmsg.c
@@ -0,0 +1,574 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "printk.h"
+
+/* /dev/kmsg - userspace message inject/listen interface */
+struct devkmsg_user {
+   u64 seq;
+   u32 idx;
+   enum log_flags prev;
+   struct mutex lock;
+   char buf[CONSOLE_EXT_LOG_MAX];
+};
+
+static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from)
+{
+   char *buf, *line;
+   int i;
+   int level = default_message_loglevel;
+   int facility = 1;   /* LOG_USER */
+   size_t len = iov_iter_count(from);
+   ssize_t ret = len;
+
+   if (len > LOG_LINE_MAX)
+   return -EINVAL;
+   buf = kmalloc(len+1, GFP_KERNEL);
+   if (buf == NULL)
+   return -ENOMEM;
+
+   buf[len] = '\0';
+   if (copy_from_iter(buf, len, from) != len) {
+   kfree(buf);
+   return -EFAULT;
+   }
+
+   /*
+* Extract and skip the syslog prefix <[0-9]*>. Coming from userspace
+* the decimal value represents 32bit, the lower 3 bit are the log
+* level, the rest are the log facility.
+*
+* If no prefix or no userspace facility is specified, we
+* enforce LOG_USER, to be able to reliably distinguish
+* kernel-generated messages from userspace-injected ones.
+*/
+   line = buf;
+   if (line[0] == '<') {
+   char *endp = NULL;
+
+   i = simple_strtoul(line+1, &endp, 10);
+   if (endp && endp[0] == '>') {
+   level = i & 7;
+   if (i >> 3)
+   facility = i >> 3;
+   endp++;
+   len -= endp - line;
+   line = endp;
+   }
+   }
+
+   printk_emit(facility, level, NULL, 0, "%s", line);
+   kfree(buf);
+   return ret;
+}
+
+static ssize_t devkmsg_read(struct file *file, char __user *buf,
+   size_t count, loff_t *ppos)
+{
+   struct devkmsg_user *user = file->private_data;
+   struct printk_log *msg;
+   size_t len;
+   ssize_t ret;
+
+   if (!user)
+   return -EBADF;
+
+   ret = mutex_lock_interruptible(&user->lock);
+   if (ret)
+   return ret;
+   raw_spin_lock_irq(&logbuf_lock);
+   while (user->seq == log_next_seq) {
+   if (file->f_flags & O_NONBLOCK) {
+   ret = -EAGAIN;
+   raw_spin_unlock_irq(&logbuf_lock);
+   goto out;
+   }
+
+   raw_spin_unlock_irq(&logbuf_lock);
+   ret = wait_event_interruptible(log_wait,
+  user->seq != log_next_seq);
+   if (ret)
+   goto out;
+   raw_spin_lock_irq(&logbuf_lock);
+   }
+
+   if (user->seq < log_first_seq) {
+   /* our last seen message is gone, return error and reset */
+   user->idx = log_first_idx;
+   user->seq = log_first_seq;
+   ret = -EPIPE;
+   raw_spin_unlock_irq(&logbuf_lock);
+   goto out;
+   }
+
+   msg = log_from_idx(user->idx);
+   len = msg_print_ext_header(user->buf, sizeof(user->buf),
+  msg, user->seq, user->prev);
+   len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len,
+ log_dict(msg), msg->dict_len,
+ 

[RFC v3 4/9] kmsg: add additional buffers support to memory class

2015-10-19 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Memory class does not support additional kmsg buffers.

Add additional kmsg buffers support to:
* devnode() callback of "mem" class
* file operations of major "mem" character device

Signed-off-by: Marcin Niesluchowski 
Signed-off-by: Paul Osmialowski 
---
 drivers/char/mem.c | 27 ---
 include/linux/printk.h | 32 
 kernel/printk/kmsg.c   | 42 ++
 kernel/printk/printk.c |  1 +
 kernel/printk/printk.h |  1 +
 5 files changed, 96 insertions(+), 7 deletions(-)

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 6b1721f..7d46234 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -799,9 +799,6 @@ static const struct memdev {
 [7] = { "full", 0666, &full_fops, 0 },
 [8] = { "random", 0666, &random_fops, 0 },
 [9] = { "urandom", 0666, &urandom_fops, 0 },
-#ifdef CONFIG_PRINTK
-   [11] = { "kmsg", 0644, &kmsg_fops, 0 },
-#endif
 };
 
 static int memory_open(struct inode *inode, struct file *filp)
@@ -811,7 +808,7 @@ static int memory_open(struct inode *inode, struct file 
*filp)
 
minor = iminor(inode);
if (minor >= ARRAY_SIZE(devlist))
-   return -ENXIO;
+   return kmsg_memory_open(inode, filp);
 
dev = &devlist[minor];
if (!dev->fops)
@@ -833,16 +830,28 @@ static const struct file_operations memory_fops = {
 
 static char *mem_devnode(struct device *dev, umode_t *mode)
 {
-   if (mode && devlist[MINOR(dev->devt)].mode)
-   *mode = devlist[MINOR(dev->devt)].mode;
+   int minor = MINOR(dev->devt);
+
+   if (!mode)
+   goto out;
+
+   if (minor >= ARRAY_SIZE(devlist)) {
+   kmsg_mode(minor, mode);
+   goto out;
+   }
+
+   if (devlist[minor].mode)
+   *mode = devlist[minor].mode;
+out:
return NULL;
 }
 
-static struct class *mem_class;
+struct class *mem_class;
 
 static int __init chr_dev_init(void)
 {
int minor;
+   struct device *kmsg;
 
if (register_chrdev(MEM_MAJOR, "mem", &memory_fops))
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
@@ -866,6 +875,10 @@ static int __init chr_dev_init(void)
  NULL, devlist[minor].name);
}
 
+   kmsg = init_kmsg(KMSG_MINOR, 0644);
+   if (IS_ERR(kmsg))
+   return PTR_ERR(kmsg);
+
return tty_init();
 }
 
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 9729565..67840e0 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -417,8 +417,40 @@ do {   
\
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
 #endif
 
+struct file;
+struct inode;
+
+#ifdef CONFIG_PRINTK
+
+extern struct class *mem_class;
+
+#define KMSG_MINOR 11
+
 extern const struct file_operations kmsg_fops;
 
+extern struct device *init_kmsg(int minor, umode_t mode);
+extern int kmsg_memory_open(struct inode *inode, struct file *filp);
+extern int kmsg_mode(int minor, umode_t *mode);
+
+#else
+
+static inline struct device *init_kmsg(int minor, umode_t mode)
+{
+   return NULL;
+}
+
+static inline int kmsg_memory_open(struct inode *inode, struct file *filp)
+{
+   return -ENXIO;
+}
+
+static inline int kmsg_mode(int minor, umode_t *mode)
+{
+   return -ENXIO;
+}
+
+#endif
+
 enum {
DUMP_PREFIX_NONE,
DUMP_PREFIX_ADDRESS,
diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c
index 23d4160..7fcd628 100644
--- a/kernel/printk/kmsg.c
+++ b/kernel/printk/kmsg.c
@@ -15,6 +15,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #include 
 
@@ -385,6 +388,45 @@ const struct file_operations kmsg_fops = {
.release = devkmsg_release,
 };
 
+/* Should be used for device registration */
+struct device *init_kmsg(int minor, umode_t mode)
+{
+   log_buf.minor = minor;
+   log_buf.mode = mode;
+   return device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
+   NULL, "kmsg");
+}
+
+int kmsg_memory_open(struct inode *inode, struct file *filp)
+{
+   filp->f_op = &kmsg_fops;
+
+   return kmsg_fops.open(inode, filp);
+}
+
+int kmsg_mode(int minor, umode_t *mode)
+{
+   int ret = -ENXIO;
+   struct log_buffer *log_b;
+
+   if (minor == log_buf.minor) {
+   *mode = log_buf.mode;
+   return 0;
+   }
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(log_b, &log_buf.list, list) {
+   if (log_b->minor == minor) {
+   *mode = log_b->mode;
+   ret = 0;
+   break;
+   }
+   }
+   rcu_read_unlock();
+
+   return 

Re: [RFC v2 1/9] printk: move code regarding log message storing format

2015-10-13 Thread Paul Osmialowski

Hi Joe,

Thanks for your comment. I'll consider that.

Thanks,
Paul

On Mon, 12 Oct 2015, Joe Perches wrote:


On Mon, 2015-10-12 at 11:29 +0200, Paul Osmialowski wrote:

From: Marcin Niesluchowski 

Preparation commit for future changes purpose.

Moves some code responsible for storing log messages in proper format.


Perhaps better still would be to move the code into
a separate file to reduce the bulk and complexity
of printk.c



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v2 5/9] kmsg: add function for adding and deleting additional buffers

2015-10-12 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Additional kmsg buffers should be created and deleted dynamically.

Adding two functions
* kmsg_sys_buffer_add() creates additional kmsg buffer returning minor
* kmsg_sys_buffer_del() deletes one based on provided minor

Signed-off-by: Marcin Niesluchowski 
---
 include/linux/printk.h |   9 
 kernel/printk/printk.c | 120 +++--
 2 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/include/linux/printk.h b/include/linux/printk.h
index 67840e0..35111e8 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -431,6 +431,8 @@ extern const struct file_operations kmsg_fops;
 extern struct device *init_kmsg(int minor, umode_t mode);
 extern int kmsg_memory_open(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);
 
 #else
 
@@ -449,6 +451,13 @@ static inline int kmsg_mode(int minor, umode_t *mode)
return -ENXIO;
 }
 
+static inline int kmsg_sys_buffer_add(size_t size, umode_t mode)
+{
+   return -ENXIO;
+}
+
+static inline void kmsg_sys_buffer_del(int minor) {}
+
 #endif
 
 enum {
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 3157239..aac7ce8 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -47,6 +47,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 #include 
@@ -242,6 +244,7 @@ struct log_buffer {
char *buf;  /* cyclic log buffer */
u32 len;/* buffer length */
wait_queue_head_t wait; /* wait queue for kmsg buffer */
+   struct kref refcount;   /* refcount for kmsg_sys buffers */
 #endif
 /*
  * The lock protects kmsg buffer, indices, counters. This can be taken within
@@ -294,6 +297,7 @@ static struct log_buffer log_buf = {
.len= __LOG_BUF_K_LEN,
.lock   = __RAW_SPIN_LOCK_UNLOCKED(log_buf.lock),
.wait   = __WAIT_QUEUE_HEAD_INITIALIZER(log_buf.wait),
+   .refcount   = { .refcount = { .counter = 0 } },
.first_seq  = 0,
.first_idx  = 0,
.next_seq   = 0,
@@ -864,6 +868,15 @@ struct devkmsg_user {
char buf[CONSOLE_EXT_LOG_MAX];
 };
 
+void log_buf_release(struct kref *ref)
+{
+   struct log_buffer *log_b = container_of(ref, struct log_buffer,
+   refcount);
+
+   kfree(log_b->buf);
+   kfree(log_b);
+}
+
 static int kmsg_sys_write(int minor, int level, const char *fmt, ...)
 {
va_list args;
@@ -971,8 +984,21 @@ static ssize_t kmsg_read(struct log_buffer *log_b, struct 
file *file,
}
 
raw_spin_unlock_irq(&log_b->lock);
-   ret = wait_event_interruptible(log_b->wait,
-  user->seq != log_b->next_seq);
+
+   if (log_b == &log_buf) {
+   ret = wait_event_interruptible(log_b->wait,
+   user->seq != log_b->next_seq);
+   } else {
+   rcu_read_unlock();
+   kref_get(&log_b->refcount);
+   ret = wait_event_interruptible(log_b->wait,
+   user->seq != log_b->next_seq);
+   if (log_b->minor == -1)
+   ret = -ENXIO;
+   if (kref_put(&log_b->refcount, log_buf_release))
+   ret = -ENXIO;
+   rcu_read_lock();
+   }
if (ret)
goto out;
raw_spin_lock_irq(&log_b->lock);
@@ -1142,8 +1168,14 @@ static unsigned int devkmsg_poll(struct file *file, 
poll_table *wait)
rcu_read_lock();
list_for_each_entry_rcu(log_b, &log_buf.list, list) {
if (log_b->minor == minor) {
+   kref_get(&log_b->refcount);
+   rcu_read_unlock();
+
ret = kmsg_poll(log_b, file, wait);
-   break;
+
+   if (kref_put(&log_b->refcount, log_buf_release))
+   return POLLERR|POLLNVAL;
+   return ret;
}
}
rcu_read_unlock();
@@ -1259,6 +1291,88 @@ int kmsg_mode(int minor, umode_t *mode)
return ret;
 }
 
+static DEFINE_SPINLOCK(kmsg_sys_list_lock);
+
+int kmsg_sys_buffer_add(size_t size, umode_t mode)
+{
+   unsigned long flags;
+   int minor = log_buf.minor;
+   struct log_buffer *log_b;
+   struct log_buffer *log_b_new;
+
+   if (size < LOG_LINE_MAX + PREFIX_MAX)
+   return -EINVAL;
+
+   log_b_new = kzalloc(sizeof(struct log_buffer), GFP_KERNEL);
+   if (!log_b_new)
+   return -ENOMEM;
+
+   log_b_new->buf = kmallo

[RFC v2 4/9] kmsg: add additional buffers support to memory class

2015-10-12 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Memory class does not support additional kmsg buffers.

Add additional kmsg buffers support to:
* devnode() callback of "mem" class
* file operations of major "mem" character device

Signed-off-by: Marcin Niesluchowski 
---
 drivers/char/mem.c | 27 ---
 include/linux/printk.h | 32 
 kernel/printk/printk.c | 43 +++
 3 files changed, 95 insertions(+), 7 deletions(-)

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 6b1721f..7d46234 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -799,9 +799,6 @@ static const struct memdev {
 [7] = { "full", 0666, &full_fops, 0 },
 [8] = { "random", 0666, &random_fops, 0 },
 [9] = { "urandom", 0666, &urandom_fops, 0 },
-#ifdef CONFIG_PRINTK
-   [11] = { "kmsg", 0644, &kmsg_fops, 0 },
-#endif
 };
 
 static int memory_open(struct inode *inode, struct file *filp)
@@ -811,7 +808,7 @@ static int memory_open(struct inode *inode, struct file 
*filp)
 
minor = iminor(inode);
if (minor >= ARRAY_SIZE(devlist))
-   return -ENXIO;
+   return kmsg_memory_open(inode, filp);
 
dev = &devlist[minor];
if (!dev->fops)
@@ -833,16 +830,28 @@ static const struct file_operations memory_fops = {
 
 static char *mem_devnode(struct device *dev, umode_t *mode)
 {
-   if (mode && devlist[MINOR(dev->devt)].mode)
-   *mode = devlist[MINOR(dev->devt)].mode;
+   int minor = MINOR(dev->devt);
+
+   if (!mode)
+   goto out;
+
+   if (minor >= ARRAY_SIZE(devlist)) {
+   kmsg_mode(minor, mode);
+   goto out;
+   }
+
+   if (devlist[minor].mode)
+   *mode = devlist[minor].mode;
+out:
return NULL;
 }
 
-static struct class *mem_class;
+struct class *mem_class;
 
 static int __init chr_dev_init(void)
 {
int minor;
+   struct device *kmsg;
 
if (register_chrdev(MEM_MAJOR, "mem", &memory_fops))
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
@@ -866,6 +875,10 @@ static int __init chr_dev_init(void)
  NULL, devlist[minor].name);
}
 
+   kmsg = init_kmsg(KMSG_MINOR, 0644);
+   if (IS_ERR(kmsg))
+   return PTR_ERR(kmsg);
+
return tty_init();
 }
 
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 9729565..67840e0 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -417,8 +417,40 @@ do {   
\
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
 #endif
 
+struct file;
+struct inode;
+
+#ifdef CONFIG_PRINTK
+
+extern struct class *mem_class;
+
+#define KMSG_MINOR 11
+
 extern const struct file_operations kmsg_fops;
 
+extern struct device *init_kmsg(int minor, umode_t mode);
+extern int kmsg_memory_open(struct inode *inode, struct file *filp);
+extern int kmsg_mode(int minor, umode_t *mode);
+
+#else
+
+static inline struct device *init_kmsg(int minor, umode_t mode)
+{
+   return NULL;
+}
+
+static inline int kmsg_memory_open(struct inode *inode, struct file *filp)
+{
+   return -ENXIO;
+}
+
+static inline int kmsg_mode(int minor, umode_t *mode)
+{
+   return -ENXIO;
+}
+
+#endif
+
 enum {
DUMP_PREFIX_NONE,
DUMP_PREFIX_ADDRESS,
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 0d4d726..3157239 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -46,6 +46,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 
@@ -253,6 +255,7 @@ struct log_buffer {
u64 next_seq;
 #ifdef CONFIG_PRINTK
u32 next_idx;   /* index of the next record to store */
+   int mode;   /* mode of device */
int minor;  /* minor representing buffer device */
 #endif
 };
@@ -295,6 +298,7 @@ static struct log_buffer log_buf = {
.first_idx  = 0,
.next_seq   = 0,
.next_idx   = 0,
+   .mode   = 0,
.minor  = 0,
 };
 
@@ -1216,6 +1220,45 @@ const struct file_operations kmsg_fops = {
.release = devkmsg_release,
 };
 
+/* Should be used for device registration */
+struct device *init_kmsg(int minor, umode_t mode)
+{
+   log_buf.minor = minor;
+   log_buf.mode = mode;
+   return device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
+   NULL, "kmsg");
+}
+
+int kmsg_memory_open(struct inode *inode, struct file *filp)
+{
+   filp->f_op = &kmsg_fops;
+
+   return kmsg_fops.open(inode, filp);
+}
+
+int kmsg_mode(int minor, umode_t *mode)
+{
+   int ret = -ENXIO;
+   struct log_buffer *log_b;
+
+   if (minor == log_buf.minor) {
+   *mode = log_buf.mode;
+   return 0;
+   }
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(log_b, &l

[RFC v2 3/9] kmsg: introduce additional kmsg devices support

2015-10-12 Thread Paul Osmialowski
From: Marcin Niesluchowski 

kmsg device provides operations on cyclic logging buffer used mainly
by kernel but also in userspace by privileged processes.

Additional kmsg devices keep the same log format but may be added
dynamically with custom size.

Signed-off-by: Marcin Niesluchowski 
---
 fs/proc/kmsg.c |   4 +-
 kernel/printk/printk.c | 633 +++--
 2 files changed, 403 insertions(+), 234 deletions(-)

diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 05f8dcd..0d354e4 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -17,7 +17,7 @@
 #include 
 #include 
 
-extern wait_queue_head_t log_wait;
+extern wait_queue_head_t *log_wait;
 
 static int kmsg_open(struct inode * inode, struct file * file)
 {
@@ -41,7 +41,7 @@ static ssize_t kmsg_read(struct file *file, char __user *buf,
 
 static unsigned int kmsg_poll(struct file *file, poll_table *wait)
 {
-   poll_wait(file, &log_wait, wait);
+   poll_wait(file, log_wait, wait);
if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC))
return POLLIN | POLLRDNORM;
return 0;
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index e7b2a78..0d4d726 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -234,29 +234,36 @@ struct printk_log {
u8 level:3; /* syslog level */
 };
 
+struct log_buffer {
+#ifdef CONFIG_PRINTK
+   struct list_head list;  /* kmsg as head of the list */
+   char *buf;  /* cyclic log buffer */
+   u32 len;/* buffer length */
+   wait_queue_head_t wait; /* wait queue for kmsg buffer */
+#endif
 /*
- * The logbuf_lock protects kmsg buffer, indices, counters.  This can be taken
- * within the scheduler's rq lock. It must be released before calling
- * console_unlock() or anything else that might wake up a process.
+ * The lock protects kmsg buffer, indices, counters. This can be taken within
+ * the scheduler's rq lock. It must be released before calling console_unlock()
+ * or anything else that might wake up a process.
  */
-static DEFINE_RAW_SPINLOCK(logbuf_lock);
+   raw_spinlock_t lock;
+   u64 first_seq;  /* sequence number of the first record stored */
+   u32 first_idx;  /* index of the first record stored */
+/* sequence number of the next record to store */
+   u64 next_seq;
+#ifdef CONFIG_PRINTK
+   u32 next_idx;   /* index of the next record to store */
+   int minor;  /* minor representing buffer device */
+#endif
+};
 
 #ifdef CONFIG_PRINTK
-DECLARE_WAIT_QUEUE_HEAD(log_wait);
 /* the next printk record to read by syslog(READ) or /proc/kmsg */
 static u64 syslog_seq;
 static u32 syslog_idx;
 static enum log_flags syslog_prev;
 static size_t syslog_partial;
 
-/* index and sequence number of the first record stored in the buffer */
-static u64 log_first_seq;
-static u32 log_first_idx;
-
-/* index and sequence number of the next record to store in the buffer */
-static u64 log_next_seq;
-static u32 log_next_idx;
-
 /* the next printk record to write to the console */
 static u64 console_seq;
 static u32 console_idx;
@@ -275,21 +282,34 @@ static u32 clear_idx;
 #else
 #define LOG_ALIGN __alignof__(struct printk_log)
 #endif
-#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
-static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
-static char *log_buf = __log_buf;
-static u32 log_buf_len = __LOG_BUF_LEN;
+#define __LOG_BUF_K_LEN (1 << CONFIG_LOG_BUF_SHIFT)
+static char __log_buf_k[__LOG_BUF_K_LEN] __aligned(LOG_ALIGN);
+
+static struct log_buffer log_buf = {
+   .list   = LIST_HEAD_INIT(log_buf.list),
+   .buf= __log_buf_k,
+   .len= __LOG_BUF_K_LEN,
+   .lock   = __RAW_SPIN_LOCK_UNLOCKED(log_buf.lock),
+   .wait   = __WAIT_QUEUE_HEAD_INITIALIZER(log_buf.wait),
+   .first_seq  = 0,
+   .first_idx  = 0,
+   .next_seq   = 0,
+   .next_idx   = 0,
+   .minor  = 0,
+};
+
+wait_queue_head_t *log_wait = &log_buf.wait;
 
 /* Return log buffer address */
 char *log_buf_addr_get(void)
 {
-   return log_buf;
+   return log_buf.buf;
 }
 
 /* Return log buffer size */
 u32 log_buf_len_get(void)
 {
-   return log_buf_len;
+   return log_buf.len;
 }
 
 /* human readable text of the record */
@@ -305,23 +325,23 @@ static char *log_dict(const struct printk_log *msg)
 }
 
 /* get record by index; idx must point to valid msg */
-static struct printk_log *log_from_idx(u32 idx)
+static struct printk_log *log_from_idx(struct log_buffer *log_b, u32 idx)
 {
-   struct printk_log *msg = (struct printk_log *)(log_buf + idx);
+   struct printk_log *msg = (struct printk_log *)(log_b->buf + idx);
 
/*
 * A length == 0 record is the end of buffer marker. Wrap around and
 * read the message at the start of the buffer.
 */
if (!msg->len)
- 

[RFC v2 0/9] Additional kmsg devices

2015-10-12 Thread Paul Osmialowski
Dear All,

This is the second iteration of Marcin Niesluchowski's serie of patches
extending kmsg interface with ability to dynamically create (and destroy)
kmsg-like devices which can be used by userspace for logging.

Some changes were introduced in this iteration:

- all occurences of '#ifdef CONFIG_PRINTK' removed from drivers/char/mem.c

- printk related code moved to kernel/printk/printk.c

- use of VMCOREINFO_STRUCT_SIZE as suggested by Petr Mladek

- selftests for kmsg added (shape of testing infrastructure based on
  kdbus selftests)

Best regards,
Paul

Marcin Niesluchowski (8):
  printk: move code regarding log message storing format
  printk: add one function for storing log in proper format
  kmsg: introduce additional kmsg devices support
  kmsg: add additional buffers support to memory class
  kmsg: add function for adding and deleting additional buffers
  kmsg: add predefined _PID, _TID, _COMM keywords to kmsg* log dict
  kmsg: add ioctl for adding and deleting kmsg* devices
  kmsg: add ioctl for kmsg* devices operating on buffers

Paul Osmialowski (1):
  kmsg: selftests

 Documentation/ioctl/ioctl-number.txt   |1 +
 drivers/char/mem.c |   27 +-
 fs/proc/kmsg.c |4 +-
 include/linux/printk.h |   48 +
 include/uapi/linux/Kbuild  |1 +
 include/uapi/linux/kmsg_ioctl.h|   45 +
 kernel/printk/printk.c | 1500 +---
 samples/kmsg/kmsg-api.h|   44 +
 tools/testing/selftests/Makefile   |1 +
 tools/testing/selftests/kmsg/.gitignore|1 +
 tools/testing/selftests/kmsg/Makefile  |   30 +
 tools/testing/selftests/kmsg/kmsg-test.c   |  329 +
 tools/testing/selftests/kmsg/kmsg-test.h   |   34 +
 tools/testing/selftests/kmsg/test-buffer-add-del.c |   76 +
 .../kmsg/test-buffer-add-write-read-del.c  |  161 +++
 .../kmsg/test-buffer-buf-multithreaded-torture.c   |  199 +++
 .../selftests/kmsg/test-buffer-buf-torture.c   |  139 ++
 17 files changed, 2154 insertions(+), 486 deletions(-)
 create mode 100644 include/uapi/linux/kmsg_ioctl.h
 create mode 100644 samples/kmsg/kmsg-api.h
 create mode 100644 tools/testing/selftests/kmsg/.gitignore
 create mode 100644 tools/testing/selftests/kmsg/Makefile
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.c
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.h
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-add-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-add-write-read-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-buf-multithreaded-torture.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-buf-torture.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v2 7/9] kmsg: add ioctl for adding and deleting kmsg* devices

2015-10-12 Thread Paul Osmialowski
From: Marcin Niesluchowski 

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 
---
 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/printk.c   | 125 +++
 6 files changed, 165 insertions(+), 1 deletion(-)
 create mode 100644 include/uapi/linux/kmsg_ioctl.h

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 50b7374..a36dc46 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -316,6 +316,7 @@ Code  Seq#(hex) Include FileComments

 0xB1   00-1F   PPPoX   
 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 7d46234..ac824de 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 35111e8..294adab 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -427,9 +427,11 @@ extern struct class *mem_class;
 #define KMSG_MINOR 11
 
 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 e777078..d998999 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -225,6 +225,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 000..89c0c61
--- /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 
+#include 
+
+struct kmsg_cmd_buffer_add {
+   size_t size;
+   unsigned short mode;
+   int minor;
+} __attribute__((packed));
+
+#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/printk.c b/kernel/printk/printk.c
index c13ba89..be08aae 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -56,6 +56,10 @@
 #define CREATE_TRACE_POINTS
 #include 
 
+#ifdef CONFIG_PRINTK
+#include 
+#endif
+
 #include "console_cmdline.h"
 #include "braille.h"
 
@@ -1284,6 +1288,120 @@ const struct file_operations kmsg_fops = {
.release = devkmsg_release,
 };
 
+#define KMSG_MAX_MINOR_LEN 20
+
+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,
+  

[RFC v2 2/9] printk: add one function for storing log in proper format

2015-10-12 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Preparation commit for future changes purpose.

Separate code responsible for storing log message in proper format
from operations on consoles by putting it in another function.

Signed-off-by: Marcin Niesluchowski 
---
 kernel/printk/printk.c | 183 ++---
 1 file changed, 98 insertions(+), 85 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index d209072..e7b2a78 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -602,6 +602,102 @@ static size_t cont_print_text(char *text, size_t size)
return textlen;
 }
 
+static int log_format_and_store(int facility, int level,
+   const char *dict, size_t dictlen,
+   const char *fmt, va_list args)
+{
+   static char textbuf[LOG_LINE_MAX];
+   char *text = textbuf;
+   size_t text_len = 0;
+   enum log_flags lflags = 0;
+   int printed_len = 0;
+
+   /*
+* The printf needs to come first; we need the syslog
+* prefix which might be passed-in as a parameter.
+*/
+   text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
+
+   /* mark and strip a trailing newline */
+   if (text_len && text[text_len-1] == '\n') {
+   text_len--;
+   lflags |= LOG_NEWLINE;
+   }
+
+   /* strip kernel syslog prefix and extract log level or control flags */
+   if (facility == 0) {
+   int kern_level = printk_get_level(text);
+
+   if (kern_level) {
+   const char *end_of_header = printk_skip_level(text);
+
+   switch (kern_level) {
+   case '0' ... '7':
+   if (level == LOGLEVEL_DEFAULT)
+   level = kern_level - '0';
+   /* fallthrough */
+   case 'd':   /* KERN_DEFAULT */
+   lflags |= LOG_PREFIX;
+   }
+   /*
+* No need to check length here because vscnprintf
+* put '\0' at the end of the string. Only valid and
+* newly printed level is detected.
+*/
+   text_len -= end_of_header - text;
+   text = (char *)end_of_header;
+   }
+   }
+
+   if (level == LOGLEVEL_DEFAULT)
+   level = default_message_loglevel;
+
+   if (dict)
+   lflags |= LOG_PREFIX|LOG_NEWLINE;
+
+   if (!(lflags & LOG_NEWLINE)) {
+   /*
+* Flush the conflicting buffer. An earlier newline was missing,
+* or another task also prints continuation lines.
+*/
+   if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
+   cont_flush(LOG_NEWLINE);
+
+   /* buffer line if possible, otherwise store it right away */
+   if (cont_add(facility, level, text, text_len))
+   printed_len += text_len;
+   else
+   printed_len += log_store(facility, level,
+lflags | LOG_CONT, 0,
+dict, dictlen, text, text_len);
+   } else {
+   bool stored = false;
+
+   /*
+* If an earlier newline was missing and it was the same task,
+* either merge it with the current buffer and flush, or if
+* there was a race with interrupts (prefix == true) then just
+* flush it out and store this line separately.
+* If the preceding printk was from a different task and missed
+* a newline, flush and append the newline.
+*/
+   if (cont.len) {
+   if (cont.owner == current && !(lflags & LOG_PREFIX))
+   stored = cont_add(facility, level, text,
+ text_len);
+   cont_flush(LOG_NEWLINE);
+   }
+
+   if (stored)
+   printed_len += text_len;
+   else
+   printed_len += log_store(facility, level,
+lflags, 0, dict, dictlen,
+text, text_len);
+   }
+   return printed_len;
+}
+
 int dmesg_restrict = IS_ENABLED(CONFIG_SECURITY_DMESG_RESTRICT);
 
 static int syslog_action_restricted(int type)
@@ -1657,10 +1753,6 @@ asmlinkage int vprintk_emit(int facility, int level,
const char *fmt, va_list args)
 {
static int recursion_bug;
-   static char textbuf[LOG_LINE_MAX];
-   char *text = textbuf;
-   size_t text_

[RFC v2 6/9] kmsg: add predefined _PID, _TID, _COMM keywords to kmsg* log dict

2015-10-12 Thread Paul Osmialowski
From: Marcin Niesluchowski 

kmsg* devices write operation wrote no dict along with message
Due to usage of kmsg devices in userspace dict has been added
identifying pid, tid and comm of writing process.

Signed-off-by: Marcin Niesluchowski 
---
 kernel/printk/printk.c | 40 
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index aac7ce8..c13ba89 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -877,7 +877,34 @@ void log_buf_release(struct kref *ref)
kfree(log_b);
 }
 
-static int kmsg_sys_write(int minor, int level, const char *fmt, ...)
+#define MAX_PID_LEN20
+#define MAX_TID_LEN20
+/*
+ * Fromat below describes dict appended to message written from userspace:
+ * "_PID=\0_TID=\0_COMM="
+ * KMSG_DICT_MAX_LEN definition represents maximal length of this dict.
+ */
+#define KMSG_DICT_MAX_LEN  (5 + MAX_PID_LEN + 1 + \
+5 + MAX_TID_LEN + 1 + \
+6 + TASK_COMM_LEN)
+
+static size_t set_kmsg_dict(char *buf)
+{
+   size_t len;
+
+   len = sprintf(buf, "_PID=%d", task_tgid_nr(current)) + 1;
+   len += sprintf(buf + len, "_TID=%d", task_pid_nr(current)) + 1;
+   memcpy(buf + len, "_COMM=", 6);
+   len += 6;
+   get_task_comm(buf + len, current);
+   while (buf[len] != '\0')
+   len++;
+   return len;
+}
+
+static int kmsg_sys_write(int minor, int level,
+ const char *dict, size_t dictlen,
+ const char *fmt, ...)
 {
va_list args;
int ret = -ENXIO;
@@ -892,7 +919,7 @@ static int kmsg_sys_write(int minor, int level, const char 
*fmt, ...)
 
va_start(args, fmt);
log_format_and_store(log_b, 1 /* LOG_USER */, level,
-NULL, 0, fmt, args);
+dict, dictlen, fmt, args);
va_end(args);
wake_up_interruptible(&log_b->wait);
 
@@ -912,6 +939,8 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
int level = default_message_loglevel;
int facility = 1;   /* LOG_USER */
size_t len = iov_iter_count(from);
+   char dict[KMSG_DICT_MAX_LEN];
+   size_t dictlen;
ssize_t ret = len;
int minor = iminor(iocb->ki_filp->f_inode);
 
@@ -951,10 +980,13 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct 
iov_iter *from)
}
}
 
+   dictlen = set_kmsg_dict(dict);
+
if (minor == log_buf.minor) {
-   printk_emit(facility, level, NULL, 0, "%s", line);
+   printk_emit(facility, level, dict, dictlen, "%s", line);
} else {
-   int error = kmsg_sys_write(minor, level, "%s", line);
+   int error = kmsg_sys_write(minor, level, dict, dictlen,
+  "%s", line);
 
if (error)
ret = error;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v2 1/9] printk: move code regarding log message storing format

2015-10-12 Thread Paul Osmialowski
From: Marcin Niesluchowski 

Preparation commit for future changes purpose.

Moves some code responsible for storing log messages in proper format.

Signed-off-by: Marcin Niesluchowski 
---
 kernel/printk/printk.c | 254 -
 1 file changed, 127 insertions(+), 127 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 8f0324e..d209072 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -475,6 +475,133 @@ static int log_store(int facility, int level,
return msg->text_len;
 }
 
+static bool printk_time = IS_ENABLED(CONFIG_PRINTK_TIME);
+module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
+
+static size_t print_time(u64 ts, char *buf)
+{
+   unsigned long rem_nsec;
+
+   if (!printk_time)
+   return 0;
+
+   rem_nsec = do_div(ts, 10);
+
+   if (!buf)
+   return snprintf(NULL, 0, "[%5lu.00] ", (unsigned long)ts);
+
+   return sprintf(buf, "[%5lu.%06lu] ",
+  (unsigned long)ts, rem_nsec / 1000);
+}
+
+/*
+ * Continuation lines are buffered, and not committed to the record buffer
+ * until the line is complete, or a race forces it. The line fragments
+ * though, are printed immediately to the consoles to ensure everything has
+ * reached the console in case of a kernel crash.
+ */
+static struct cont {
+   char buf[LOG_LINE_MAX];
+   size_t len; /* length == 0 means unused buffer */
+   size_t cons;/* bytes written to console */
+   struct task_struct *owner;  /* task of first print*/
+   u64 ts_nsec;/* time of first print */
+   u8 level;   /* log level of first message */
+   u8 facility;/* log facility of first message */
+   enum log_flags flags;   /* prefix, newline flags */
+   bool flushed:1; /* buffer sealed and committed */
+} cont;
+
+static void cont_flush(enum log_flags flags)
+{
+   if (cont.flushed)
+   return;
+   if (cont.len == 0)
+   return;
+
+   if (cont.cons) {
+   /*
+* If a fragment of this line was directly flushed to the
+* console; wait for the console to pick up the rest of the
+* line. LOG_NOCONS suppresses a duplicated output.
+*/
+   log_store(cont.facility, cont.level, flags | LOG_NOCONS,
+ cont.ts_nsec, NULL, 0, cont.buf, cont.len);
+   cont.flags = flags;
+   cont.flushed = true;
+   } else {
+   /*
+* If no fragment of this line ever reached the console,
+* just submit it to the store and free the buffer.
+*/
+   log_store(cont.facility, cont.level, flags, 0,
+ NULL, 0, cont.buf, cont.len);
+   cont.len = 0;
+   }
+}
+
+static bool cont_add(int facility, int level, const char *text, size_t len)
+{
+   if (cont.len && cont.flushed)
+   return false;
+
+   /*
+* If ext consoles are present, flush and skip in-kernel
+* continuation.  See nr_ext_console_drivers definition.  Also, if
+* the line gets too long, split it up in separate records.
+*/
+   if (nr_ext_console_drivers || cont.len + len > sizeof(cont.buf)) {
+   cont_flush(LOG_CONT);
+   return false;
+   }
+
+   if (!cont.len) {
+   cont.facility = facility;
+   cont.level = level;
+   cont.owner = current;
+   cont.ts_nsec = local_clock();
+   cont.flags = 0;
+   cont.cons = 0;
+   cont.flushed = false;
+   }
+
+   memcpy(cont.buf + cont.len, text, len);
+   cont.len += len;
+
+   if (cont.len > (sizeof(cont.buf) * 80) / 100)
+   cont_flush(LOG_CONT);
+
+   return true;
+}
+
+static size_t cont_print_text(char *text, size_t size)
+{
+   size_t textlen = 0;
+   size_t len;
+
+   if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) {
+   textlen += print_time(cont.ts_nsec, text);
+   size -= textlen;
+   }
+
+   len = cont.len - cont.cons;
+   if (len > 0) {
+   if (len+1 > size)
+   len = size-1;
+   memcpy(text + textlen, cont.buf + cont.cons, len);
+   textlen += len;
+   cont.cons = cont.len;
+   }
+
+   if (cont.flushed) {
+   if (cont.flags & LOG_NEWLINE)
+   text[textlen++] = '\n';
+   /* got everything, release buffer */
+   cont.len = 0;
+   }
+   return textlen;
+}
+
 int dmesg_restrict = IS_ENABLED(CONFIG_SECURITY_DMESG_RESTRICT);
 
 static int syslog_action_restricted(int type)
@@ -1030,25 +1157,6 @@ static 

[RFC v2 9/9] kmsg: selftests

2015-10-12 Thread Paul Osmialowski
This patch adds selftests framework and four test scenarios for kmsg.

The framework shape and code was inspired by similar selftests framework
for kdbus.

Signed-off-by: Paul Osmialowski 
---
 samples/kmsg/kmsg-api.h|  44 +++
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/kmsg/.gitignore|   1 +
 tools/testing/selftests/kmsg/Makefile  |  30 ++
 tools/testing/selftests/kmsg/kmsg-test.c   | 329 +
 tools/testing/selftests/kmsg/kmsg-test.h   |  34 +++
 tools/testing/selftests/kmsg/test-buffer-add-del.c |  76 +
 .../kmsg/test-buffer-add-write-read-del.c  | 161 ++
 .../kmsg/test-buffer-buf-multithreaded-torture.c   | 199 +
 .../selftests/kmsg/test-buffer-buf-torture.c   | 139 +
 10 files changed, 1014 insertions(+)
 create mode 100644 samples/kmsg/kmsg-api.h
 create mode 100644 tools/testing/selftests/kmsg/.gitignore
 create mode 100644 tools/testing/selftests/kmsg/Makefile
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.c
 create mode 100644 tools/testing/selftests/kmsg/kmsg-test.h
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-add-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-add-write-read-del.c
 create mode 100644 
tools/testing/selftests/kmsg/test-buffer-buf-multithreaded-torture.c
 create mode 100644 tools/testing/selftests/kmsg/test-buffer-buf-torture.c

diff --git a/samples/kmsg/kmsg-api.h b/samples/kmsg/kmsg-api.h
new file mode 100644
index 000..9004acd
--- /dev/null
+++ b/samples/kmsg/kmsg-api.h
@@ -0,0 +1,44 @@
+#ifndef KMSG_API_H
+#define KMSG_API_H
+
+#include 
+#include 
+#include 
+#include 
+
+static inline int kmsg_cmd_buffer_add(int fd, struct kmsg_cmd_buffer_add *cmd)
+{
+   int ret = ioctl(fd, KMSG_CMD_BUFFER_ADD, cmd);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_buffer_del(int fd, int *minor)
+{
+   int ret = ioctl(fd, KMSG_CMD_BUFFER_DEL, minor);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_get_buf_size(int fd, uint32_t *size)
+{
+   int ret = ioctl(fd, KMSG_CMD_GET_BUF_SIZE, size);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_get_read_size_max(int fd, uint32_t *max_size)
+{
+   int ret = ioctl(fd, KMSG_CMD_GET_READ_SIZE_MAX, max_size);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+static inline int kmsg_cmd_clear(int fd)
+{
+   int ret = ioctl(fd, KMSG_CMD_CLEAR);
+
+   return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0;
+}
+
+#endif /* KMSG_API_H */
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index ac40ec9..4834ef8 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += ftrace
 TARGETS += futex
 TARGETS += kcmp
 TARGETS += kdbus
+TARGETS += kmsg
 TARGETS += membarrier
 TARGETS += memfd
 TARGETS += memory-hotplug
diff --git a/tools/testing/selftests/kmsg/.gitignore 
b/tools/testing/selftests/kmsg/.gitignore
new file mode 100644
index 000..687d517
--- /dev/null
+++ b/tools/testing/selftests/kmsg/.gitignore
@@ -0,0 +1 @@
+kmsg-test
diff --git a/tools/testing/selftests/kmsg/Makefile 
b/tools/testing/selftests/kmsg/Makefile
new file mode 100644
index 000..b4ba892
--- /dev/null
+++ b/tools/testing/selftests/kmsg/Makefile
@@ -0,0 +1,30 @@
+CFLAGS += -I../../../../usr/include/
+CFLAGS += -I../../../../samples/kmsg/
+CFLAGS += -I../../../../include/uapi/
+CFLAGS += -std=gnu99 -Wall
+CFLAGS += -DKBUILD_MODNAME=\"kmsg\" -D_GNU_SOURCE
+CFLAGS += -pthread
+LDLIBS += -pthread
+
+OBJS= \
+   kmsg-test.o \
+   test-buffer-add-del.o   \
+   test-buffer-add-write-read-del.o\
+   test-buffer-buf-torture.o   \
+   test-buffer-buf-multithreaded-torture.o
+
+all: kmsg-test
+
+include ../lib.mk
+
+%.o: %.c kmsg-test.h
+   $(CC) $(CFLAGS) -c $< -o $@
+
+kmsg-test: $(OBJS)
+   $(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
+
+run_tests:
+   ./kmsg-test --tap
+
+clean:
+   rm -f *.o kmsg-test
diff --git a/tools/testing/selftests/kmsg/kmsg-test.c 
b/tools/testing/selftests/kmsg/kmsg-test.c
new file mode 100644
index 000..4f17b73
--- /dev/null
+++ b/tools/testing/selftests/kmsg/kmsg-test.c
@@ -0,0 +1,329 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "kmsg-test.h"
+
+struct kmsg_test {
+   const char  *name;
+   const char  *desc;
+   int (*func)(const struct kmsg_test_args *args);
+};
+
+static const struct kmsg_test tests[] = {
+   {
+   .name   = "buffer-add-del",
+   .d

[RFC v2 8/9] kmsg: add ioctl for kmsg* devices operating on buffers

2015-10-12 Thread Paul Osmialowski
From: Marcin Niesluchowski 

There is no possibility to clear additional kmsg buffers,
get size of them or know what size should be passed to read
file operation (too small size causes it to retrun -EINVAL).

Add following ioctls which solve those issues:
* KMSG_CMD_GET_BUF_SIZE
* KMSG_CMD_GET_READ_SIZE_MAX
* KMSG_CMD_CLEAR

Signed-off-by: Marcin Niesluchowski 
---
 Documentation/ioctl/ioctl-number.txt |   2 +-
 include/uapi/linux/kmsg_ioctl.h  |  15 ++
 kernel/printk/printk.c   | 102 ++-
 3 files changed, 92 insertions(+), 27 deletions(-)

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index a36dc46..c55e49e 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -316,7 +316,7 @@ Code  Seq#(hex) Include FileComments

 0xB1   00-1F   PPPoX   
 0xB3   00  linux/mmc/ioctl.h
-0xBB   00-02   uapi/linux/kmsg_ioctl.h
+0xBB   00-83   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/include/uapi/linux/kmsg_ioctl.h b/include/uapi/linux/kmsg_ioctl.h
index 89c0c61..2389d9f 100644
--- a/include/uapi/linux/kmsg_ioctl.h
+++ b/include/uapi/linux/kmsg_ioctl.h
@@ -27,4 +27,19 @@ struct kmsg_cmd_buffer_add {
  struct kmsg_cmd_buffer_add)
 #define KMSG_CMD_BUFFER_DEL_IOW(KMSG_IOCTL_MAGIC, 0x01, int)
 
+/*
+ * A ioctl interface for kmsg* devices.
+ *
+ * KMSG_CMD_GET_BUF_SIZE:  Retrieve cyclic log buffer size associated with
+ * device.
+ * KMSG_CMD_GET_READ_SIZE_MAX: Retrieve max size of data read by kmsg read
+ * operation.
+ * KMSG_CMD_CLEAR: Clears cyclic log buffer. After that operation
+ * there is no data to read from buffer unless
+ * logs are written.
+ */
+#define KMSG_CMD_GET_BUF_SIZE  _IOR(KMSG_IOCTL_MAGIC, 0x80, __u32)
+#define KMSG_CMD_GET_READ_SIZE_MAX _IOR(KMSG_IOCTL_MAGIC, 0x81, __u32)
+#define KMSG_CMD_CLEAR _IO(KMSG_IOCTL_MAGIC, 0x82)
+
 #endif
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index be08aae..1bc4a31 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -262,6 +262,10 @@ struct log_buffer {
u64 next_seq;
 #ifdef CONFIG_PRINTK
u32 next_idx;   /* index of the next record to store */
+/* sequence number of the next record to read after last 'clear' command */
+   u64 clear_seq;
+/* index of the next record to read after last 'clear' command */
+   u32 clear_idx;
int mode;   /* mode of device */
int minor;  /* minor representing buffer device */
 #endif
@@ -279,10 +283,6 @@ static u64 console_seq;
 static u32 console_idx;
 static enum log_flags console_prev;
 
-/* the next printk record to read after the last 'clear' command */
-static u64 clear_seq;
-static u32 clear_idx;
-
 #define PREFIX_MAX 32
 #define LOG_LINE_MAX   (1024 - PREFIX_MAX)
 
@@ -306,6 +306,8 @@ static struct log_buffer log_buf = {
.first_idx  = 0,
.next_seq   = 0,
.next_idx   = 0,
+   .clear_seq  = 0,
+   .clear_idx  = 0,
.mode   = 0,
.minor  = 0,
 };
@@ -1116,18 +1118,14 @@ static loff_t kmsg_llseek(struct log_buffer *log_b, 
struct file *file,
user->seq = log_b->first_seq;
break;
case SEEK_DATA:
-   /* no clear index for kmsg_sys buffers */
-   if (log_b != &log_buf) {
-   ret = -EINVAL;
-   break;
-   }
/*
 * The first record after the last SYSLOG_ACTION_CLEAR,
-* like issued by 'dmesg -c'. Reading /dev/kmsg itself
-* changes no global state, and does not clear anything.
+* like issued by 'dmesg -c' or KMSG_CMD_CLEAR ioctl
+* command. Reading /dev/kmsg itself changes no global
+* state, and does not clear anything.
 */
-   user->idx = clear_idx;
-   user->seq = clear_seq;
+   user->idx = log_b->clear_idx;
+   user->seq = log_b->clear_seq;
break;
case SEEK_END:
/* after the last record */
@@ -1267,6 +1265,56 @@ static int devkmsg_open(struct inode *inode, struct file 
*file)
return ret;
 }
 
+static long kmsg_ioctl(struct log_buffer *log_b, unsigned int cmd,
+  unsigned long arg)
+{
+   void __user *argp = (void __user *)arg;
+   static const u32 read_size_max = CONSOLE_EXT_LOG_MAX;
+
+   switc

[PATCH v3] clk: add devm_of_clk_get() and devm_of_clk_get_by_name() functions

2015-10-01 Thread Paul Osmialowski
From: Paul Osmialowski 

These two functions are added to ease management of clocks obtained
from OF device nodes.

They are particulary useful while iterating over DT subnodes using e.g.
for_each_child_of_node(dev->of_node, child) in order do get resources
(i.e. clocks) for subdevices defined by these DT subnodes.

For example:

some_device {
compatible = "something"
#address-cells = <1>;
#size-cells = <1>;
ranges;

subdevice1: some_subdevice@some_address1 {
reg = <0xsome_address1 0xsome_size>
clocks = <&some_clock1>
}

subdevice2: some_subdevice@some_address2 {
reg = <0xsome_address2 0xsome_size>
clocks = <&some_clock2>
}
}

Normally, I'd have to use of_clk_get() on each subdevice node and then
worry about proper resource release myself.

IMHO using devres infrastructure for this is far better. This patch adds
missing functions needed to do it a better way.

Signed-off-by: Paul Osmialowski 
---
 Documentation/driver-model/devres.txt |  2 ++
 drivers/clk/clk-devres.c  | 46 +++
 include/linux/clk.h   | 46 +++
 3 files changed, 94 insertions(+)

diff --git a/Documentation/driver-model/devres.txt 
b/Documentation/driver-model/devres.txt
index 831a536..f3ad67a 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -235,6 +235,8 @@ certainly invest a bit more effort into libata core layer).
 
 CLOCK
   devm_clk_get()
+  devm_of_clk_get()
+  devm_of_clk_get_by_name()
   devm_clk_put()
 
 DMA
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 8f57154..71fcebc 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -34,6 +34,52 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
+
+struct clk *devm_of_clk_get(struct device *dev, struct device_node *np,
+   int index)
+{
+   struct clk **ptr, *clk;
+
+   ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+   if (!ptr)
+   return ERR_PTR(-ENOMEM);
+
+   clk = of_clk_get(np, index);
+   if (!IS_ERR(clk)) {
+   *ptr = clk;
+   devres_add(dev, ptr);
+   } else {
+   devres_free(ptr);
+   }
+
+   return clk;
+}
+EXPORT_SYMBOL(devm_of_clk_get);
+
+struct clk *devm_of_clk_get_by_name(struct device *dev, struct device_node *np,
+   const char *name)
+{
+   struct clk **ptr, *clk;
+
+   ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+   if (!ptr)
+   return ERR_PTR(-ENOMEM);
+
+   clk = of_clk_get_by_name(np, name);
+   if (!IS_ERR(clk)) {
+   *ptr = clk;
+   devres_add(dev, ptr);
+   } else {
+   devres_free(ptr);
+   }
+
+   return clk;
+}
+EXPORT_SYMBOL(devm_of_clk_get_by_name);
+
+#endif /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
+
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
struct clk **c = res;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 0df4a51..8f31f9a 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -504,4 +504,50 @@ static inline struct clk *of_clk_get_by_name(struct 
device_node *np,
 }
 #endif
 
+#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
+/**
+ * devm_of_clk_get - obtain a managed reference to a clock producer
+ *   from device tree node (by index).
+ * @dev: device for clock "consumer"
+ * @np: device tree node
+ * @index: clock consumer index (within the node)
+ *
+ * devm_of_clk_get should not be called from within interrupt context.
+ *
+ * The clock will automatically be freed when the device is unbound
+ * from the bus.
+ */
+struct clk *devm_of_clk_get(struct device *dev, struct device_node *np,
+   int index);
+
+/**
+ * devm_of_clk_get_by_name - obtain a managed reference to a clock producer
+ *   from device tree node (by name).
+ * @dev: device for clock "consumer"
+ * @np: device tree node
+ * @name: clock consumer name (within the node)
+ *
+ * devm_of_clk_get_by_name should not be called from within interrupt context.
+ *
+ * The clock will automatically be freed when the device is unbound
+ * from the bus.
+ */
+struct clk *devm_of_clk_get_by_name(struct device *dev, struct device_node *np,
+   const char *name);
+
+#else
+static inline struct clk *devm_of_clk_get(struct device *dev,
+ struct device_node *np,
+ int index)
+{
+   return ERR_PTR(-ENOENT);
+}
+static inline struct clk *devm_of_cl

Re: [PATCH 0/1] add devm_of_clk_get() and devm_of_clk_get_by_name() functions

2015-10-01 Thread Paul Osmialowski
Hi Stephen,

On Wed, 30 Sep 2015, Stephen Boyd wrote:

> In the pinctrl node we would have
> 
>   pinctrl {
>   compatible = "fsl,kenetis70-pinctrl";
>   reg = <0x40049000 0x2000>;
>   clocks = <&sim SIM_CLK_SCGC5_PORTA>, <&sim SIM_CLK_SCGC5_PORTB>;
> 
>   uart_default: uart_default {
>   mux {
>   pins = "porta_3", "portb_2";
>   function = "uart";
>   };
> 
>   rx {
>   bias-pull-pin-default;
>   };
>   };
>   };
> 
> And then in the uart node we would have
> 
>   uart@f0 {
>   compatible = "vendor,uart";
>   reg = <0xf0 0x100>;
>   pinctrl-names = "default";
>   pinctrl-0 = <&uart_default>;
>   };
> 

Seems like there's another thing I wanted to avoid. The correctness of 
these pin strings will not be checked until the runtime. They need to 
properly encode pin bank and pin number within the bank. No chances it can 
be validated at .dtb build time. But I guess this is proper way for 
generic pinctrl bindings. I mostly (but not completely) based my approach 
on rockchip examples (e.g. rk3288) but it looks like they are not entirely 
sane.

Thanks,
Paul
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] clk: add devm_of_clk_get() and devm_of_clk_get_by_name() functions

2015-09-30 Thread Paul Osmialowski
From: Paul Osmialowski 

These two functions are added to ease management of clocks obtained
from OF device nodes.

They are particulary useful while iterating over DT subnodes using e.g.
for_each_child_of_node(dev->of_node, child) in order do get resources
(i.e. clocks) for subdevices defined by these DT subnodes.

For example:

some_device {
compatible = "something"
#address-cells = <1>;
#size-cells = <1>;
ranges;

subdevice1: some_subdevice@some_address1 {
reg = <0xsome_address1 0xsome_size>
clocks = <&some_clock1>
}

subdevice2: some_subdevice@some_address2 {
reg = <0xsome_address2 0xsome_size>
clocks = <&some_clock2>
}
}

Normally, I'd have to use of_clk_get() on each subdevice node and then
worry about proper resource release myself.

IMHO using devres infrastructure for this is far better. This patch adds
missing functions needed to do it a better way.

Signed-off-by: Paul Osmialowski 
---
 Documentation/driver-model/devres.txt |  2 ++
 drivers/clk/clk-devres.c  | 46 +++
 include/linux/clk.h   | 46 +++
 3 files changed, 94 insertions(+)

diff --git a/Documentation/driver-model/devres.txt 
b/Documentation/driver-model/devres.txt
index 831a536..f3ad67a 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -235,6 +235,8 @@ certainly invest a bit more effort into libata core layer).
 
 CLOCK
   devm_clk_get()
+  devm_of_clk_get()
+  devm_of_clk_get_by_name()
   devm_clk_put()
 
 DMA
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 8f57154..197075a 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -34,6 +34,52 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+#ifdef CONFIG_OF
+
+struct clk *devm_of_clk_get(struct device *dev, struct device_node *np,
+   int index)
+{
+   struct clk **ptr, *clk;
+
+   ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+   if (!ptr)
+   return ERR_PTR(-ENOMEM);
+
+   clk = of_clk_get(np, index);
+   if (!IS_ERR(clk)) {
+   *ptr = clk;
+   devres_add(dev, ptr);
+   } else {
+   devres_free(ptr);
+   }
+
+   return clk;
+}
+EXPORT_SYMBOL(devm_of_clk_get);
+
+struct clk *devm_of_clk_get_by_name(struct device *dev, struct device_node *np,
+   const char *name)
+{
+   struct clk **ptr, *clk;
+
+   ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+   if (!ptr)
+   return ERR_PTR(-ENOMEM);
+
+   clk = of_clk_get_by_name(np, name);
+   if (!IS_ERR(clk)) {
+   *ptr = clk;
+   devres_add(dev, ptr);
+   } else {
+   devres_free(ptr);
+   }
+
+   return clk;
+}
+EXPORT_SYMBOL(devm_of_clk_get_by_name);
+
+#endif /* CONFIG_OF */
+
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
struct clk **c = res;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 0df4a51..8f31f9a 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -504,4 +504,50 @@ static inline struct clk *of_clk_get_by_name(struct 
device_node *np,
 }
 #endif
 
+#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
+/**
+ * devm_of_clk_get - obtain a managed reference to a clock producer
+ *   from device tree node (by index).
+ * @dev: device for clock "consumer"
+ * @np: device tree node
+ * @index: clock consumer index (within the node)
+ *
+ * devm_of_clk_get should not be called from within interrupt context.
+ *
+ * The clock will automatically be freed when the device is unbound
+ * from the bus.
+ */
+struct clk *devm_of_clk_get(struct device *dev, struct device_node *np,
+   int index);
+
+/**
+ * devm_of_clk_get_by_name - obtain a managed reference to a clock producer
+ *   from device tree node (by name).
+ * @dev: device for clock "consumer"
+ * @np: device tree node
+ * @name: clock consumer name (within the node)
+ *
+ * devm_of_clk_get_by_name should not be called from within interrupt context.
+ *
+ * The clock will automatically be freed when the device is unbound
+ * from the bus.
+ */
+struct clk *devm_of_clk_get_by_name(struct device *dev, struct device_node *np,
+   const char *name);
+
+#else
+static inline struct clk *devm_of_clk_get(struct device *dev,
+ struct device_node *np,
+ int index)
+{
+   return ERR_PTR(-ENOENT);
+}
+static inline struct clk *devm_of_clk_get_by_name(struct device *dev,
+ struct device_node 

[PATCH 0/1] add devm_of_clk_get() and devm_of_clk_get_by_name() functions

2015-09-30 Thread Paul Osmialowski
From: Paul Osmialowski 

While working on my pinctrl driver I've found lack of devres compatible
equivalent for of_clk_get() function. I'd like to use it for the following
(incomplete) piece of device tree configuration:

pinctrl: pinctrl {
compatible = "fsl,kinetis-pinctrl";
#address-cells = <1>;
#size-cells = <1>;
ranges;

port_a@40049000 {
compatible = "fsl,kinetis-pin-bank";
reg = <0x40049000 0x1000>;
clocks = <&sim SIM_CLK_SCGC5_PORTA>;
};

port_b@4004a000 {
compatible = "fsl,kinetis-pin-bank";
reg = <0x4004a000 0x1000>;
clocks = <&sim SIM_CLK_SCGC5_PORTB>;
};
...
};

In my pinconf-generic compatible fsl,kinetis-pinctrl driver, I'm iterating
over fsl,kinetis-pin-bank nodes using for_each_child_of_node(dev->of_node,
child) along with of_match_node() in order to grab resources (I/O base
address, clock gate).

Normally, I'd have to use of_clk_get() on each pin bank device_node and
then worry about proper resource release myself.

IMHO using devres infrastructure for this is far better. This patch adds
missing functions needed to do it that way.

Paul Osmialowski (1):
  clk: add devm_of_clk_get() and devm_of_clk_get_by_name() functions

 drivers/clk/clk-devres.c | 46 ++
 include/linux/clk.h  | 20 
 2 files changed, 66 insertions(+)

-- 
2.4.9

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/1] add devm_of_clk_get() and devm_of_clk_get_by_name() functions

2015-09-28 Thread Paul Osmialowski
Hi Stephen,

Thanks for all of your comments.

On Mon, 28 Sep 2015, Stephen Boyd wrote:

> I'd say your binding is wrong. Either the container node
> "pinctrl" is a software concept that contains the two devices for
> port_a and port_b or there's only one pinctrl device that happens
> to span some number of 0x1000 size banks. The former would be
> written as so
> 
>   pinctrl {
>   compatible = "fsl,kenetis-pinctrl";
>   reg = <0x40049000 0x2000>;
>   clocks = <&sim SIM_CLK_SCGC5_PORTA>, <&sim SIM_CLK_SCGC5_PORTB>;
>   };
>

I tried this and actually this looks similar to my first approach to this 
driver. I wasn't happy with the fact that pin banks are so loosely coupled 
with resources they use.

I thought that making pin controller a container for pin bank devices 
would create better coupling and simply look better in DT file.

With this first approach example pin definition would look like:

fsl,kinetis-pins =  ...

where the binding format is fsl,kinetis-pins = 

&pcfg_pull_pin_default is defined as:

pcfg_pull_pin_default: pcfg-pull-pin-default {
bias-pull-pin-default;
};

...and PORT_A would have to be defined as preprocessor macro in some 
header file:

#define PORT_A   0
#define PORT_B   1
#define PORT_C   2
#define PORT_D   3
#define PORT_E   4
#define PORT_F   5
#define PORT_NUM 6

That's another thing I'd want to avoid.

I wanted a DT file which driver could use to figure out how many pin banks 
there are, what clocks and IO ranges they use and how pins are associated 
with banks.

Now I see I pasted example from some old file (sorry for that), it differs 
in one small detail, so again:

pinctrl: pinctrl {
compatible = "fsl,kinetis-pinctrl";
#address-cells = <1>;
#size-cells = <1>;
ranges;

port_a: pin-bank@40049000 {
compatible = "fsl,kinetis-pin-bank";
reg = <0x40049000 0x1000>;
clocks = <&sim SIM_CLK_SCGC5_PORTA>;
};

port_b: pin-bank@4004a000 {
compatible = "fsl,kinetis-pin-bank";
reg = <0x4004a000 0x1000>;
clocks = <&sim SIM_CLK_SCGC5_PORTB>;
};
...
};

Now, assuming use of of_find_node_by_phandle(), example pin definition 
would look like:

fsl,kinetis-pins = <&port_a 0 1 &pcfg_pull_pin_default> ...

Things are getting connected together, no preprocessor definitions, no 
extra header file. What can be wrong with this design?

I'll prepare second iteration with updated documentation (and other 
smaller cleanups) soon.

Thanks,
Paul
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 3/3] kdbus: Ability to run kdbus test by executable binary name

2015-09-24 Thread Paul Osmialowski
With this applied, you can make a symlink (or copy) of kdbus-test
executable binary and name it according to given test name.

Useful for testing features introduced by previous patches.

Signed-off-by: Paul Osmialowski 
---
 tools/testing/selftests/kdbus/kdbus-test.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/tools/testing/selftests/kdbus/kdbus-test.c 
b/tools/testing/selftests/kdbus/kdbus-test.c
index 37f05bb..473cb1b 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.c
+++ b/tools/testing/selftests/kdbus/kdbus-test.c
@@ -834,6 +834,7 @@ int main(int argc, char *argv[])
ARG_UIDMAP,
ARG_GIDMAP,
};
+   char *exec = basename(argv[0]);
 
kdbus_args = malloc(sizeof(*kdbus_args));
if (!kdbus_args) {
@@ -863,6 +864,10 @@ int main(int argc, char *argv[])
 
srand(time(NULL));
 
+   if (strcmp(exec, "kdbus-test") != 0) {
+   kdbus_args->test = exec;
+   }
+
while ((t = getopt_long(argc, argv, "hxfm:r:t:b:w:a", options, NULL)) 
>= 0) {
switch (t) {
case 'x':
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 2/3] kdbus: selftests extended

2015-09-24 Thread Paul Osmialowski
The 'test-send' test case should connect to an already running test-daemon
which creates a bus with known name.

The main goal of this test case is to verify that messages as well as
file descriptors (opened with different open modes) can be transferred
properly.

In order to achieve its goals, this test case opens three files
(/tmp/kdbus-test-send.rd, /tmp/kdbus-test-send.wr,
/tmp/kdbus-test-send.rdwr) with three different open modes (O_RDONLY,
O_WRONLY, O_RDWR). If any of these files exists it is used 'as is',
otherwise it is created with some default content. Then this test tries
to send simple message followed by three messages each one of them
containing an array of opened file descriptors (single element array in the
first message, two element array in the second, three element array in the
third).

The ability to send array of file descriptors required changes in almost
all of the test case files.

Signed-off-by: Karol Lewandowski 
Signed-off-by: Paul Osmialowski 
---
 tools/testing/selftests/kdbus/Makefile   |  1 +
 tools/testing/selftests/kdbus/kdbus-test.c   | 11 +++-
 tools/testing/selftests/kdbus/kdbus-test.h   |  1 +
 tools/testing/selftests/kdbus/kdbus-util.c   | 20 --
 tools/testing/selftests/kdbus/kdbus-util.h   |  2 +-
 tools/testing/selftests/kdbus/test-activator.c   | 20 +++---
 tools/testing/selftests/kdbus/test-chat.c|  6 +-
 tools/testing/selftests/kdbus/test-connection.c  |  8 ++-
 tools/testing/selftests/kdbus/test-fd.c  |  2 +-
 tools/testing/selftests/kdbus/test-message.c | 69 
 tools/testing/selftests/kdbus/test-metadata-ns.c | 10 +--
 tools/testing/selftests/kdbus/test-monitor.c |  9 +--
 tools/testing/selftests/kdbus/test-policy-ns.c   |  8 +--
 tools/testing/selftests/kdbus/test-policy-priv.c | 48 --
 tools/testing/selftests/kdbus/test-send.c| 82 
 tools/testing/selftests/kdbus/test-sync.c|  2 +-
 tools/testing/selftests/kdbus/test-timeout.c |  2 +-
 17 files changed, 216 insertions(+), 85 deletions(-)
 create mode 100644 tools/testing/selftests/kdbus/test-send.c

diff --git a/tools/testing/selftests/kdbus/Makefile 
b/tools/testing/selftests/kdbus/Makefile
index 8f36cb5..f400756 100644
--- a/tools/testing/selftests/kdbus/Makefile
+++ b/tools/testing/selftests/kdbus/Makefile
@@ -27,6 +27,7 @@ OBJS= \
test-policy.o   \
test-policy-ns.o\
test-policy-priv.o  \
+   test-send.o \
test-sync.o \
test-timeout.o
 
diff --git a/tools/testing/selftests/kdbus/kdbus-test.c 
b/tools/testing/selftests/kdbus/kdbus-test.c
index bde4283..37f05bb 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.c
+++ b/tools/testing/selftests/kdbus/kdbus-test.c
@@ -25,6 +25,7 @@
 enum {
TEST_CREATE_BUS = 1 << 0,
TEST_CREATE_CONN= 1 << 1,
+   TEST_CREATE_CAN_FAIL= 1 << 2,
 };
 
 struct kdbus_test {
@@ -154,6 +155,12 @@ static const struct kdbus_test tests[] = {
.flags  = TEST_CREATE_BUS,
},
{
+   .name   = "send",
+   .desc   = "send",
+   .func   = kdbus_test_send,
+   .flags  = TEST_CREATE_CONN | TEST_CREATE_CAN_FAIL,
+   },
+   {
.name   = "sync-byebye",
.desc   = "synchronous replies vs. BYEBYE",
.func   = kdbus_test_sync_byebye,
@@ -307,7 +314,7 @@ static int test_prepare_env(const struct kdbus_test *t,
   args->busname ?: n,
   _KDBUS_ATTACH_ALL, &s);
free(n);
-   ASSERT_RETURN(ret == 0);
+   ASSERT_RETURN((ret == 0) || (t->flags & TEST_CREATE_CAN_FAIL));
 
asprintf(&env->buspath, "%s/%s/bus", args->root, s);
free(s);
@@ -336,7 +343,7 @@ static int test_prepare_env(const struct kdbus_test *t,
}
ASSERT_RETURN(env->buspath);
env->conn = kdbus_hello(env->buspath, 0, NULL, 0);
-   ASSERT_RETURN(env->conn);
+   ASSERT_RETURN(env->conn || (t->flags & TEST_CREATE_CAN_FAIL));
}
 
env->root = args->root;
diff --git a/tools/testing/selftests/kdbus/kdbus-test.h 
b/tools/testing/selftests/kdbus/kdbus-test.h
index ee937f9..041fa40 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.h
+++ b/tools/testing/selftests/kdbus/kdbus-test.h
@@ -76,6 +76,7 @@ int kdbus_test_name_takeover(struct kdbus_test_env *env);
 int kdbus_test_policy(struct kdbus_test_env *env);
 int kdbus_test_policy_ns(struct kdbus_test_env *env);
 int kdbus_test_policy_priv(struct kdbus_test_env *env);
+int kdbus_test_send(struct kdbus_test_env *env);
 int kdbus_test_sync_byebye(struct kdbus_tes

[RFC 1/3] kdbus: TEST_CREATE_CONN now does no depend on TEST_CREATE_BUS

2015-09-24 Thread Paul Osmialowski
Without this patch, it is impossible to specify test case able to
connect to a bus already created (e.g. by 'test-daemon' test case), you can
only specify:

1) TEST_CREATE_BUS which creates new bus, or
2) TEST_CREATE_CONN OR'ed with TEST_CREATE_BUS which creates new bus and
creates connection to it.

This patch adds the missing ability to specify TEST_CREATE_CONN alone.

It will be used by a new test case (will be added by separate commit) which
is supposed to connect to already started test-daemon case.

Signed-off-by: Paul Osmialowski 
---
 tools/testing/selftests/kdbus/kdbus-test.c | 21 +
 tools/testing/selftests/kdbus/kdbus-util.c | 18 +++---
 2 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/kdbus/kdbus-test.c 
b/tools/testing/selftests/kdbus/kdbus-test.c
index db57381..bde4283 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.c
+++ b/tools/testing/selftests/kdbus/kdbus-test.c
@@ -314,6 +314,27 @@ static int test_prepare_env(const struct kdbus_test *t,
}
 
if (t->flags & TEST_CREATE_CONN) {
+   if (!env->buspath) {
+   char *s = NULL;
+   char *n = NULL;
+   int ret;
+
+   if (!args->busname) {
+   n = unique_name("test-bus");
+   ASSERT_RETURN(n);
+   }
+
+   ret = kdbus_create_bus(-1,
+  args->busname ?: n,
+  0,
+  &s);
+   free(n);
+   ASSERT_RETURN(ret == 0);
+
+   asprintf(&env->buspath, "%s/%s/bus", args->root, s);
+   free(s);
+   }
+   ASSERT_RETURN(env->buspath);
env->conn = kdbus_hello(env->buspath, 0, NULL, 0);
ASSERT_RETURN(env->conn);
}
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c 
b/tools/testing/selftests/kdbus/kdbus-util.c
index 82fa89b..5129487 100644
--- a/tools/testing/selftests/kdbus/kdbus-util.c
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
@@ -140,7 +140,7 @@ int kdbus_create_bus(int control_fd, const char *name,
char str[64];
} name;
} bus_make;
-   int ret;
+   int ret = 0;
 
memset(&bus_make, 0, sizeof(bus_make));
bus_make.bp.size = sizeof(bus_make.bp);
@@ -165,13 +165,17 @@ int kdbus_create_bus(int control_fd, const char *name,
 bus_make.attach.size +
 bus_make.name.size;
 
-   kdbus_printf("Creating bus with name >%s< on control fd %d ...\n",
-name, control_fd);
+   if (control_fd != -1) {
+   kdbus_printf(
+   "Creating bus with name >%s< on control fd %d ...\n",
+   name, control_fd);
 
-   ret = kdbus_cmd_bus_make(control_fd, &bus_make.cmd);
-   if (ret < 0) {
-   kdbus_printf("--- error when making bus: %d (%m)\n", ret);
-   return ret;
+   ret = kdbus_cmd_bus_make(control_fd, &bus_make.cmd);
+   if (ret < 0) {
+   kdbus_printf("--- error when making bus: %d (%m)\n",
+ret);
+   return ret;
+   }
}
 
if (ret == 0 && path)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 0/3] kdbus: extend selftests

2015-09-24 Thread Paul Osmialowski
This serie extends kdbus selftests with following new features:

- ability to specify TEST_CREATE_CONN without TEST_CREATE_BUS
- the 'test-send' test case (by Karol Lewandowski)
- ability to run kdbus test by executable binary name

Paul Osmialowski (3):
  kdbus: TEST_CREATE_CONN now does no depend on TEST_CREATE_BUS
  kdbus: selftests extended
  kdbus: Ability to run kdbus test by executable binary name

 tools/testing/selftests/kdbus/Makefile   |  1 +
 tools/testing/selftests/kdbus/kdbus-test.c   | 37 ++-
 tools/testing/selftests/kdbus/kdbus-test.h   |  1 +
 tools/testing/selftests/kdbus/kdbus-util.c   | 38 +++
 tools/testing/selftests/kdbus/kdbus-util.h   |  2 +-
 tools/testing/selftests/kdbus/test-activator.c   | 20 +++---
 tools/testing/selftests/kdbus/test-chat.c|  6 +-
 tools/testing/selftests/kdbus/test-connection.c  |  8 ++-
 tools/testing/selftests/kdbus/test-fd.c  |  2 +-
 tools/testing/selftests/kdbus/test-message.c | 69 
 tools/testing/selftests/kdbus/test-metadata-ns.c | 10 +--
 tools/testing/selftests/kdbus/test-monitor.c |  9 +--
 tools/testing/selftests/kdbus/test-policy-ns.c   |  8 +--
 tools/testing/selftests/kdbus/test-policy-priv.c | 48 --
 tools/testing/selftests/kdbus/test-send.c| 82 
 tools/testing/selftests/kdbus/test-sync.c|  2 +-
 tools/testing/selftests/kdbus/test-timeout.c |  2 +-
 17 files changed, 253 insertions(+), 92 deletions(-)
 create mode 100644 tools/testing/selftests/kdbus/test-send.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/1] clk: add devm_of_clk_get() and devm_of_clk_get_by_name() functions

2015-09-24 Thread Paul Osmialowski
From: Paul Osmialowski 

These two functions were added to ease management of clocks obtained
from OF device nodes.

Signed-off-by: Paul Osmialowski 
---
 drivers/clk/clk-devres.c | 46 ++
 include/linux/clk.h  | 20 
 2 files changed, 66 insertions(+)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 8f57154..197075a 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -34,6 +34,52 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+#ifdef CONFIG_OF
+
+struct clk *devm_of_clk_get(struct device *dev, struct device_node *np,
+   int index)
+{
+   struct clk **ptr, *clk;
+
+   ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+   if (!ptr)
+   return ERR_PTR(-ENOMEM);
+
+   clk = of_clk_get(np, index);
+   if (!IS_ERR(clk)) {
+   *ptr = clk;
+   devres_add(dev, ptr);
+   } else {
+   devres_free(ptr);
+   }
+
+   return clk;
+}
+EXPORT_SYMBOL(devm_of_clk_get);
+
+struct clk *devm_of_clk_get_by_name(struct device *dev, struct device_node *np,
+   const char *name)
+{
+   struct clk **ptr, *clk;
+
+   ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+   if (!ptr)
+   return ERR_PTR(-ENOMEM);
+
+   clk = of_clk_get_by_name(np, name);
+   if (!IS_ERR(clk)) {
+   *ptr = clk;
+   devres_add(dev, ptr);
+   } else {
+   devres_free(ptr);
+   }
+
+   return clk;
+}
+EXPORT_SYMBOL(devm_of_clk_get_by_name);
+
+#endif /* CONFIG_OF */
+
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
struct clk **c = res;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 0df4a51..d7763f1 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -504,4 +504,24 @@ static inline struct clk *of_clk_get_by_name(struct 
device_node *np,
 }
 #endif
 
+#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) && 
defined(CONFIG_HAVE_CLK)
+struct clk *devm_of_clk_get(struct device *dev, struct device_node *np,
+   int index);
+struct clk *devm_of_clk_get_by_name(struct device *dev, struct device_node *np,
+   const char *name);
+#else
+static inline struct clk *devm_of_clk_get(struct device *dev,
+ struct device_node *np,
+ int index)
+{
+   return ERR_PTR(-ENOENT);
+}
+static inline struct clk *devm_of_clk_get_by_name(struct device *dev,
+ struct device_node *np,
+ const char *name)
+{
+   return ERR_PTR(-ENOENT);
+}
+#endif
+
 #endif
-- 
2.4.9

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/1] add devm_of_clk_get() and devm_of_clk_get_by_name() functions

2015-09-24 Thread Paul Osmialowski
From: Paul Osmialowski 

While working on my pinctrl driver I've found lack of devres compatible
equivalent for of_clk_get() function. I'd like to use it for the following
(incomplete) piece of device tree configuration:

pinctrl: pinctrl {
compatible = "fsl,kinetis-pinctrl";
#address-cells = <1>;
#size-cells = <1>;
ranges;

port_a@40049000 {
compatible = "fsl,kinetis-pin-bank";
reg = <0x40049000 0x1000>;
clocks = <&sim SIM_CLK_SCGC5_PORTA>;
};

port_b@4004a000 {
compatible = "fsl,kinetis-pin-bank";
reg = <0x4004a000 0x1000>;
clocks = <&sim SIM_CLK_SCGC5_PORTB>;
};
...
};

In my pinconf-generic compatible fsl,kinetis-pinctrl driver, I'm iterating
over fsl,kinetis-pin-bank nodes using for_each_child_of_node(dev->of_node,
child) along with of_match_node() in order to grab resources (I/O base
address, clock gate).

Normally, I'd have to use of_clk_get() on each pin bank device_node and
then worry about proper resource release myself.

IMHO using devres infrastructure for this is far better. This patch adds
missing functions needed to do it that way.

Paul Osmialowski (1):
  clk: add devm_of_clk_get() and devm_of_clk_get_by_name() functions

 drivers/clk/clk-devres.c | 46 ++
 include/linux/clk.h  | 20 
 2 files changed, 66 insertions(+)

-- 
2.4.9

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v2] kdbus: use LSM hooks to restrict ability to send file descriptors

2015-09-21 Thread Paul Osmialowski
The goal of this patch is to reproduce on kdbus the same behavior
that is expressed by Unix Domain Sockets when it comes to restricting
ability to pass opened file descriptors.

Signed-off-by: Paul Osmialowski 
---
 ipc/kdbus/message.c | 31 ++-
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/ipc/kdbus/message.c b/ipc/kdbus/message.c
index ae565cd..7f8aa35 100644
--- a/ipc/kdbus/message.c
+++ b/ipc/kdbus/message.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "bus.h"
@@ -150,13 +151,19 @@ int kdbus_gaps_install(struct kdbus_gaps *gaps, struct 
kdbus_pool_slice *slice,
for (i = 0; i < gaps->n_fds; ++i) {
int fd;
 
-   fd = get_unused_fd_flags(O_CLOEXEC);
-   if (fd < 0)
-   incomplete_fds = true;
-
WARN_ON(!gaps->fd_files[i]);
 
-   fds[n_fds++] = fd < 0 ? -1 : fd;
+   if (gaps->fd_files[i] &&
+   security_file_receive(gaps->fd_files[i])) {
+   incomplete_fds = true;
+   fds[n_fds++] = -1;
+   } else {
+   fd = get_unused_fd_flags(O_CLOEXEC);
+   if (fd < 0)
+   incomplete_fds = true;
+
+   fds[n_fds++] = fd < 0 ? -1 : fd;
+   }
}
 
/*
@@ -178,6 +185,16 @@ int kdbus_gaps_install(struct kdbus_gaps *gaps, struct 
kdbus_pool_slice *slice,
for (i = 0; i < gaps->n_memfds; ++i) {
int memfd;
 
+   WARN_ON(!gaps->memfd_offsets[i]);
+   WARN_ON(!gaps->memfd_files[i]);
+
+   if (gaps->memfd_files[i] &&
+   security_file_receive(gaps->memfd_files[i])) {
+   incomplete_fds = true;
+   fds[n_fds++] = -1;
+   continue;
+   }
+
memfd = get_unused_fd_flags(O_CLOEXEC);
if (memfd < 0) {
incomplete_fds = true;
@@ -193,10 +210,6 @@ int kdbus_gaps_install(struct kdbus_gaps *gaps, struct 
kdbus_pool_slice *slice,
 * as usually there is no need to send more than one memfd per
 * message.
 */
-
-   WARN_ON(!gaps->memfd_offsets[i]);
-   WARN_ON(!gaps->memfd_files[i]);
-
kvec.iov_base = &memfd;
kvec.iov_len = sizeof(memfd);
ret = kdbus_pool_slice_copy_kvec(slice, gaps->memfd_offsets[i],
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC] kdbus: use LSM hooks to restrict ability to send file descriptors

2015-09-18 Thread Paul Osmialowski
The goal of this patch is to reproduce on kdbus the same behavior
that is expressed by Unix Domain Sockets when it comes to restricting
ability to pass opened file descriptors.

Signed-off-by: Paul Osmialowski 
---
 ipc/kdbus/message.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/ipc/kdbus/message.c b/ipc/kdbus/message.c
index ae565cd..b083431 100644
--- a/ipc/kdbus/message.c
+++ b/ipc/kdbus/message.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "bus.h"
@@ -150,13 +151,19 @@ int kdbus_gaps_install(struct kdbus_gaps *gaps, struct 
kdbus_pool_slice *slice,
for (i = 0; i < gaps->n_fds; ++i) {
int fd;
 
-   fd = get_unused_fd_flags(O_CLOEXEC);
-   if (fd < 0)
+   if (gaps->fd_files[i] &&
+   security_file_receive(gaps->fd_files[i])) {
incomplete_fds = true;
+   fds[n_fds++] = -1;
+   } else {
+   fd = get_unused_fd_flags(O_CLOEXEC);
+   if (fd < 0)
+   incomplete_fds = true;
 
-   WARN_ON(!gaps->fd_files[i]);
+   WARN_ON(!gaps->fd_files[i]);
 
-   fds[n_fds++] = fd < 0 ? -1 : fd;
+   fds[n_fds++] = fd < 0 ? -1 : fd;
+   }
}
 
/*
@@ -178,6 +185,13 @@ int kdbus_gaps_install(struct kdbus_gaps *gaps, struct 
kdbus_pool_slice *slice,
for (i = 0; i < gaps->n_memfds; ++i) {
int memfd;
 
+   if (gaps->memfd_files[i] &&
+   security_file_receive(gaps->memfd_files[i])) {
+   incomplete_fds = true;
+   fds[n_fds++] = -1;
+   continue;
+   }
+
memfd = get_unused_fd_flags(O_CLOEXEC);
if (memfd < 0) {
incomplete_fds = true;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 01/01] kdbus: Eliminate warning caused by lack of uapi/linux/kdbus.h inclusion

2015-09-08 Thread Paul Osmialowski
metadata.h references struct kdbus_pids which is defined in
uapi/linux/kdbus.h

Normally, kdbus/metadata.h is included after many other headers
that eventually include uapi/linux/kdbus.h at some point (e.g. kdbus/bus.h
includes uapi/linux/kdbus.h), this prevents the warning.

When included alone, it causes warning. Also when kdbus/connection.h
is included alone, the same warning is shown since kdbus/connection.h
includes kdbus/metadata.h.

This patch adds missing inclusion.

Signed-off-by: Paul Osmialowski 
---
 ipc/kdbus/metadata.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ipc/kdbus/metadata.h b/ipc/kdbus/metadata.h
index dba7cc7..3f9ba38 100644
--- a/ipc/kdbus/metadata.h
+++ b/ipc/kdbus/metadata.h
@@ -16,6 +16,7 @@
 #define __KDBUS_METADATA_H
 
 #include 
+#include 
 
 struct kdbus_conn;
 struct kdbus_pool_slice;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 00/01] kdbus: Eliminate warning caused by lack of uapi/linux/kdbus.h inclusion

2015-09-08 Thread Paul Osmialowski
This is the patch that fixes problem with compiler warning message caused
by lack of header inclusion.

The problem does not occur during normal kernel build. It was uncovered
during my recent works on LSM hooks for KDBUS.

Without this patch my yet to be released patches produce warning message
during compilation.

Paul Osmialowski (1):
  kdbus: Eliminate warning caused by lack of uapi/linux/kdbus.h
inclusion

 ipc/kdbus/metadata.h | 1 +
 1 file changed, 1 insertion(+)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 7/9] arm: twr-k70f120m: IOMUX driver for Kinetis SoC

2015-09-08 Thread Paul Osmialowski
Hi Linus,

On Tue, 14 Jul 2015, Linus Walleij wrote:

> OK...
> 
> I want Shawn and Sascha to look at this as they worked with
> other Freescale pin controllers. Especially I want to know if this
> is a sibling to the other Freescale controllers or a separate hardware.
> 
> If it is *not* a sibling I will *insist* that it use more generic pin
> control bindings and move away from the older Freescale-specific
> stuff.

No one answered me about that. However, I looked at other Freescale 
pinctrl drivers and realised that no one of them (IMX, IMX1, MXS) is 
similar to what I need to do for Kinetis, also positions of configuration 
bits differ significantly.

> 
> There exist generic pin config bindings, see
> Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
> 
> I suggest to to function+group paring and then use generic pin config
> with this driver unless it is a very close sibling to the existing Freescale
> pin controllers.
> 
> Hint: if it is a sibling, it should share code with them.
> 
> There are several drivers doing generic pin control/pin config in the kernel
> tree.
> 

I tried to analyze few of the drivers (e.g. zynq family) and can't find 
how can I assing clock gate (clock device) to each port (PORTA, PORTB, 
PORTC,...) which is required for Kinetis. Is generic pin control capable 
to express that requirement or is it a time to desing my own pinctrl 
driver (maybe somewhat improved than the one I presented so far)?

This pinctrl component is somwehat critical part of BSP. Until it is not 
sorted, I don't see a point in releasing what was developed so far.

Best regards,
Paul
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-08-01 Thread Paul Osmialowski

Hi Mike,

On Fri, 31 Jul 2015, Michael Turquette wrote:

> Quoting Paul Osmialowski (2015-07-30 14:40:48)
> > Hi Mike,
> > 
> > I encountered some trouble while I tried to implement code fitting to DTS 
> > that you proposed. SIM_CLKDIVx are SIM device registers, not MCG. 
> > Therefore, in MCG device code I won't be able to figure out clock rate 
> > for outputed clocks unles I try to access SIM registers from MCG driver - 
> 
> Right, the MCG driver will only know the rates of the clocks that it
> outputs, namely:
> 
> MCGIRCLK
> MCGFFCLK
> MCGOUTCLK
> MCGFLLCLK
> MCGPLL0CLK
> MCGPLL1CLK
> 
> The naming scheme in the TRM is a bit unfortunate; it looks like some of
> the clock outputs coming out of SIM also retain the MCG* names.

I wonder if I really need to implement support for all of these clocks 
while to run Linux on this board reference 2.6 kernel uses only MCGOUTCLK 
(and for this, it never considers FLL as a source). 
I can also provide support for MCGPLL0CLK and MCGPLL1CLK as well since 
their rates are computed as a byproduct while determining rate of 
MCGOUTCLK. I may define constants for all of them in related header file, 
but I'm thinking about leaving most of implementations as TBD - otherwise 
I doubt I'll be ever able to test that my driver fully works.

> 
> Why is clock-cells zero? I think the MCG block outputs all of the clocks
> that I listed above? As such they should be addressable as <&mcg N> by
> any downstream users.
> 

Ok, will be 1, to distinguish between MCGOUTCLK, MCGPLL0CLK, MCGPLL1CLK.


> > reg = <0x40064000 0x14>;
> > clocks = <&osc0>, <&osc1>, <&rtc>;
> > clock-names = "osc0", "osc1", "rtc";
> 
> Are the oscN and rtc clocks modeled as fixed-rate clocks in DT?
> 

Yes, I skipped the part above soc during copy-paste.

> It looks like the SIM block should also consume:
> 
> MCGFLLCLK
> MCGIRCLK
> MCGFFCLK
> MCGPLL0CLK
> MCGPLL1CLK
> OSC0ERCLK
> OSC1ERCLK
> OSC032KCLK
> RTCCLK (I made that name up)
> 
> The mcg clocks should come out of the mcg node. It looks like you
> already modeled oscN and rtc clocks, which is great. There are some
> gates after these clocks (e.g. OSC0ERCLK). I wonder if those gates are
> actually in the osc IP block or if they actually live in SIM. More on
> that below...
> 
> Well they certainly can be exposed if you need them to be. If a device
> driver wants to get the core clock and set it's rate then it should be
> able to with something like <&sim CORE_CLK>.
> 

Ok, the user of the clock does not relly need to know whether it is clock 
device or a clock gate - fortunately, I already learnt how to implement 
such thing.

> > 
> > Also note that fec (ethernet device) driver is connected directly to osc0 
> > (though clock gate, you can see this CG attached to osc0 on the diagram 
> > too) - to control this gate I need to access SIM device registers, so it 
> > should be covered by the same fsl,kinetis-sim driver.
> 
> Do you mean the SIM_SOPT2 register? It looks like the connection is not
> "direct", as the osc0 signal feeds into the SIM block and the gate there
> controls it.  Perhaps the diagram is incorrect by placing the CG block
> inside osc0? It looks like you correctly modeled this relationship in
> the sim node.

In order to enable network device, bit 0 of SIM_SCGC2 must be set for RMII 
mode to work, and according to what I see on the page 228 of the reference
manual, it is osc0 clock behind this gate.

In the context of network device, I would need to read SIM_SOPT2 to 
determine clock source for IEEE 1588 timestamp while implementing PTP 
support - which currently I don't have in my plans, network device can do 
without it.

Thanks,
Paul

> 
> Besides my annoying questions above this binding is starting to shape up
> very well. Thanks for your patience!
> 
> Regards,
> Mike
> 
> > 
> > On Wed, 29 Jul 2015, Michael Turquette wrote:
> > 
> > > Quoting Paul Osmialowski (2015-07-28 13:30:17)
> > > > Hi Mike,
> > > > 
> > > > My trouble is that now I'm dealing with two conradictory opinions on 
> > > > how 
> > > > this driver should be written. The one you presented in your previous 
> > > > post 
> > > > assumes that there will be a header file with defines shared between 
> > > > the 
> > > > clock driver and DTS, also with clock gating details hidden behind some 
> > > > additional level of indirection, e.g.:
> > > > 
> > >

Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-07-30 Thread Paul Osmialowski
Hi Mike,

I encountered some trouble while I tried to implement code fitting to DTS 
that you proposed. SIM_CLKDIVx are SIM device registers, not MCG. 
Therefore, in MCG device code I won't be able to figure out clock rate 
for outputed clocks unles I try to access SIM registers from MCG driver - 
that's what we wanted to avoid. Looks like it's the mcgoutclk that we want 
to expose not core, bus and the others:

soc {
mcg: clock-controller@40064000 {
compatible = "fsl,kinetis-mcg";
clock-cells = <0>;
reg = <0x40064000 0x14>;
clocks = <&osc0>, <&osc1>, <&rtc>;
clock-names = "osc0", "osc1", "rtc";
};
sim: clock-controller@40047000 {
compatible = "fsl,kinetis-sim";
clock-cells = <1>;
reg = <0x40047000 0x1100>;
clocks = <&mcg>,
 <&osc0>;
clock-names = "mcgoutclk", "enet";
};

uart0: serial@4006a000 {
compatible = "fsl,kinetis-lpuart";
reg = <0x4006a000 0x1000>;
interrupts = <45>, <46>;
interrupt-names = "uart-stat", "uart-err";
clocks = <&sim SIM_SCGC4_UART0_CLK>;
clock-names = "ipg";
dmas = <&edma 0 2>;
dma-names = "rx";
status = "disabled";
};
};

Now fsl,kinetis-sim device will be responsible for clock gating and it 
will know about core, bus, flexbus and flash clocks only internally - 
none of them are exposed.

Also note that fec (ethernet device) driver is connected directly to osc0 
(though clock gate, you can see this CG attached to osc0 on the diagram 
too) - to control this gate I need to access SIM device registers, so it 
should be covered by the same fsl,kinetis-sim driver.

On Wed, 29 Jul 2015, Michael Turquette wrote:

> Quoting Paul Osmialowski (2015-07-28 13:30:17)
> > Hi Mike,
> > 
> > My trouble is that now I'm dealing with two conradictory opinions on how 
> > this driver should be written. The one you presented in your previous post 
> > assumes that there will be a header file with defines shared between the 
> > clock driver and DTS, also with clock gating details hidden behind some 
> > additional level of indirection, e.g.:
> > 
> > clocks = <&sim SIM_SCGC4_UART1_CLK>;
> > 
> > Note that I've been through this at the very beginning, though the names 
> > I used have been bit different, e.g.:
> > 
> > #define KINETIS_CG_UART1   KINETIS_MKCG(3, 11) /* SIM_SCGC4[11] */
> > 
> > This was rejected with a comment by Arnd:
> > 
> > Instead of using a triple indirection here, just put the tuples
> > in the DT directly using #clock-cells=<2>, and get rid of both this
> > header file and the dt-bindings/clock/kinetis-mcg.h file.
> 
> Arnd, are you OK with my type of binding description now that I
> explained it with some examples?
> 
> > 
> > So I dropped all of these includes and started to use magic numbers (as 
> > you put it). Now I need to go one way or another or even go the third way: 
> > extend #clock-cells to <3> and address it like: <&sim parent_clock_id 
> > scgc_register_number bit_index_number>.
> 
> Paul,
> 
> >From my understanding the DT folks do not like register-level or
> bit-level details going into DT. It is better to handle the clock
> signals as abstract resources and link a provider and consumer with a
> simple phandle plus an index representing that abstract resource (i.e.
> the clock output signal).
> 
> > 
> > Reading your previous post I'm starting to feel that it would bring me 
> > closer to final acceptance if I stick to what you proposed in that post 
> > (I'm really grateful to you for writting so huge chunk of DTS for me!), so 
> > I'll probably adopt that.
> > 
> > You're right about my "get things up and running" attitude - currently I 
> > want to develop things extensively (cover as much subsystems as 
> > possible) and then at some stage switch to intensive approach. This board 
> > is a somewhat huge monster (for a Cortex-M4 SoC) and there will be a lot 
> > of coding oppo

Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-07-28 Thread Paul Osmialowski
Hi Mike,

My trouble is that now I'm dealing with two conradictory opinions on how 
this driver should be written. The one you presented in your previous post 
assumes that there will be a header file with defines shared between the 
clock driver and DTS, also with clock gating details hidden behind some 
additional level of indirection, e.g.:

clocks = <&sim SIM_SCGC4_UART1_CLK>;

Note that I've been through this at the very beginning, though the names 
I used have been bit different, e.g.:

#define KINETIS_CG_UART1   KINETIS_MKCG(3, 11) /* SIM_SCGC4[11] */

This was rejected with a comment by Arnd:

Instead of using a triple indirection here, just put the tuples
in the DT directly using #clock-cells=<2>, and get rid of both this
header file and the dt-bindings/clock/kinetis-mcg.h file.

So I dropped all of these includes and started to use magic numbers (as 
you put it). Now I need to go one way or another or even go the third way: 
extend #clock-cells to <3> and address it like: <&sim parent_clock_id 
scgc_register_number bit_index_number>.

Reading your previous post I'm starting to feel that it would bring me 
closer to final acceptance if I stick to what you proposed in that post 
(I'm really grateful to you for writting so huge chunk of DTS for me!), so 
I'll probably adopt that.

You're right about my "get things up and running" attitude - currently I 
want to develop things extensively (cover as much subsystems as 
possible) and then at some stage switch to intensive approach. This board 
is a somewhat huge monster (for a Cortex-M4 SoC) and there will be a lot 
of coding opportunity in this field in the future.

Thanks,
Paul

On Tue, 28 Jul 2015, Michael Turquette wrote:

> Quoting Paul Osmialowski (2015-07-26 13:24:08)
> > Hi Mike,
> > 
> > Thank you for spending time on this and pointing me into the right 
> > direction. I'm wondering about going even further with it. Assuming that I 
> 
> Hi Paul,
> 
> No problem! And thanks for the quick turnaround on your patches so far.
> 
> > know everything about my board, I can skip run-time discovery phase (note 
> > that the original driver was designed for other Kinetis-based boards too) 
> > and move everything into DTS, somewhat like this:
> > 
> > / {
> > osc0: clock {
> > compatible = "fixed-clock";
> > #clock-cells = <0>;
> > clock-frequency = <5000>;
> > };
> > 
> > osc1: clock {
> > compatible = "fixed-clock";
> > #clock-cells = <0>;
> > clock-frequency = <1200>;
> > };
> > 
> > rtc: clock {
> > compatible = "fixed-clock";
> > #clock-cells = <0>;
> > clock-frequency = <32768>;
> > };
> > 
> > mcgout: clock {
> > compatible = "fixed-factor-clock";
> > #clock-cells = <0>;
> > clocks = <&osc0>;
> > clock-mult = <12>;
> > clock-div = <5>;
> > };
> 
> I think this is a step backwards.
> 
> Did you look at the qcom clock binding and read the email where I
> detailed how that binding works?
> 
> The point of that type of binding is to not shove per-clock data into
> DT, but instead to declare every clock controller IP block (e.g. the
> device) as well as every board-level clock (e.g. as osc that feeds into
> your mcu). Once these "clock providers" are enumerated in DT, then we
> create linkage between the clock providers and the clock consumers by
> using phandles + an index. Linux device drivers tap into this by using
> clk_get() and using the "clock-names" property from DT.
> 
> Put another way: we mostly use DT to model "devices". That is open to
> interpretation for but for clock-related stuff we typically interpret
> the clock controller as the device, not the individual clock outputs
> coming out of the controller.
> 
> Note that a clock controller IP block may be both a provider and a
> consumer.  I/O controllers are a very common type of consumer (e.g. USB
> host controller, MMC controller, GPU, etc).
> 
> Additionally, from my reading of the reference manual, mcgout is defined
> as:
> 
> """
> MCG output of either IRC, MCGFLLCLK MCGPLL0CLK,
> MCGPLL1CLK, or MCG's external reference clock that
> sources the core, system, bus, FlexBus, and flash clock. It is
> also an option for the debug trace clock.
> &q

Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-07-26 Thread Paul Osmialowski
Hi Mike,

Thank you for spending time on this and pointing me into the right 
direction. I'm wondering about going even further with it. Assuming that I 
know everything about my board, I can skip run-time discovery phase (note 
that the original driver was designed for other Kinetis-based boards too) 
and move everything into DTS, somewhat like this:

/ {
osc0: clock {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <5000>;
};

osc1: clock {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1200>;
};

rtc: clock {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
};

mcgout: clock {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clocks = <&osc0>;
clock-mult = <12>;
clock-div = <5>;
};

core: clock {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clocks = <&mcgout>;
clock-mult = <1>;
clock-div = <1>;
};

bus: clock {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clocks = <&mcgout>;
clock-mult = <1>;
clock-div = <2>;
};

soc {
cmu@0x40047000 {
compatible = "fsl,kinetis-gate-clock";
reg = <0x40047000 0x1100>;

mcg_core_gate: clock-gate {
clocks = <&core>;
#clock-cells = <2>;
};

mcg_bus_gate: clock-gate {
clocks = <&bus>;
#clock-cells = <2>;
};

osc0_erclk_gate: clock-gate {
clocks = <&osc0>;
#clock-cells = <2>;
};
};

uart0: serial@4006a000 {
compatible = "fsl,kinetis-lpuart";
reg = <0x4006a000 0x1000>;
interrupts = <45>, <46>;
interrupt-names = "uart-stat", "uart-err";
clocks = <&mcg_core_gate 3 10>;
clock-names = "ipg";
dmas = <&edma 0 2>;
dma-names = "rx";
status = "disabled";
};
    };
};

As you can see, mcg part is not required anymore.

I guess that the approach above would require split into soc-specific and 
board-specific part (as I said, dividers arrangement is something board 
specific), but I wonder what you thing about this proposal.

Thanks,
Paul

On Thu, 23 Jul 2015, Michael Turquette wrote:

> Quoting Paul Osmialowski (2015-07-04 14:50:03)
> > Hi Arnd,
> > 
> > I'm attaching excerpt from Kinetis reference manual that may make 
> > situation clearer.
> 
> Hi Paul,
> 
> Can you please post the patch in the body of the email instead of an
> attachment? It makes it easier to review. Another small nitpick is that
> the $SUBJECT for this patch might be better off as something like:
> 
> clk: mcg and sim clock drivers for twr-k70f120m Kinetis SoC
> 
> At least it helps me find the patch I care about when skimming the
> series ;-)
> 
> > 
> > These MCG and SIM registers are used only to determine configuration 
> > (clock fixed rates and clock signal origins) at run time.
> > 
> > Namely, the real MCGOUTCLK source (in the middle) which is the parent for 
> > core clock (CCLK) and peripheral clock (PCLK) is determined at run time by 
> > reading MCG registers, let me quote commit message from Emcraft git repo:
> > 
> >   * Determine in run-time what oscillator module (OSC0 or OSC1) is used
> >  as clock source for the main PLL.
> 
> According to [0] there are three options: a 32k RTC osc clock and osc0
> both feed into a mux. You should model this 32k clock with the
> fixed-rate binding.
> 
> >   * When OSC1 is selected, assume its frequency to be 12 MHz on all
> >  boards (there is a 12 MHz oscillator on XTAL1/EXTAL1 on K70-SOM and
> >  TWR-K70F120M boar

Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-07-15 Thread Paul Osmialowski
Hi Linus,

I had some discussion with an expert here and now I see drawbacks of using 
struct for regs, I'll turn it into defines as you suggested.

On Wed, 15 Jul 2015, Paul Osmialowski wrote:

> Hi Linus,
> 
> Thanks for all of your comments, I'll consider them during my works on the 
> next iteration. However, I have doubts about this one:
> 
> On Tue, 14 Jul 2015, Linus Walleij wrote:
> 
> > On Tue, Jun 30, 2015 at 2:27 PM, Paul Osmialowski  
> > wrote:
> > 
> > > Based on K70P256M150SF3RM.pdf K70 Sub-Family Reference Manual, Rev. 3.
> > >
> > > Signed-off-by: Paul Osmialowski 
> > (...)
> > > +struct kinetis_sim_regs {
> > > +   u32 sopt1;  /* System Options Register 1 */
> > > +   u32 rsv0[1024];
> > > +   u32 sopt2;  /* System Options Register 2 */
> > > +   u32 rsv1;
> > > +   u32 sopt4;  /* System Options Register 4 */
> > > +   u32 sopt5;  /* System Options Register 5 */
> > > +   u32 sopt6;  /* System Options Register 6 */
> > > +   u32 sopt7;  /* System Options Register 7 */
> > > +   u32 rsv2[2];
> > > +   u32 sdid;   /* System Device Identification Register */
> > > +   u32 scgc[KINETIS_SIM_CG_NUMREGS];   /* Clock Gating Regs 
> > > 1...7 */
> > > +   u32 clkdiv1;/* System Clock Divider Register 1 */
> > > +   u32 clkdiv2;/* System Clock Divider Register 2 */
> > > +   u32 fcfg1;  /* Flash Configuration Register 1 */
> > > +   u32 fcfg2;  /* Flash Configuration Register 2 */
> > > +   u32 uidh;   /* Unique Identification Register High */
> > > +   u32 uidmh;  /* Unique Identification Register Mid-High */
> > > +   u32 uidml;  /* Unique Identification Register Mid Low */
> > > +   u32 uidl;   /* Unique Identification Register Low */
> > > +   u32 clkdiv3;/* System Clock Divider Register 3 */
> > > +   u32 clkdiv4;/* System Clock Divider Register 4 */
> > > +   u32 mcr;/* Misc Control Register */
> > > +};
> > 
> > Now there is this design pattern where you copy the datasheet
> > register map to a struct again.
> > 
> > This is not good if there is a second revision of the hardware and some
> > registers are shuffled around. IMO it is better to just use #defines
> > for register
> > offsets, so you can do exceptions later. Else a new hardware revision
> > leads to a new struct with new accessor functions etc etc.
> > 
> 
> I don't see how replacing this structure with bunch of defines could make 
> anyones life easier. As registers are shuffled around due to updated 
> hardware revision they could be shuffled in this structure too. Doing 
> this with buch of defines would require eager and careful adaptation of 
> all the defines. I don't see how this could be easier.
> 
> Note that I'm not making any instances of the structure (it is used only 
> for casting), so shuffling its fields around should not affect the code 
> that follows.
> 
> After recent purge it is only used within this macro:
> 
> #define KINETIS_SIM_PTR(base, reg) \
> (&(((struct kinetis_sim_regs *)(base))->reg))
> 
> ...and used like this:
> 
> ioread32(KINETIS_SIM_PTR(sim, clkdiv1));
> 
> IMHO changing the struct internals does not require subsequent changes in 
> any of those.
> 
> Thanks,
> Paul
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-07-15 Thread Paul Osmialowski
Hi Linus,

Thanks for all of your comments, I'll consider them during my works on the 
next iteration. However, I have doubts about this one:

On Tue, 14 Jul 2015, Linus Walleij wrote:

> On Tue, Jun 30, 2015 at 2:27 PM, Paul Osmialowski  wrote:
> 
> > Based on K70P256M150SF3RM.pdf K70 Sub-Family Reference Manual, Rev. 3.
> >
> > Signed-off-by: Paul Osmialowski 
> (...)
> > +struct kinetis_sim_regs {
> > +   u32 sopt1;  /* System Options Register 1 */
> > +   u32 rsv0[1024];
> > +   u32 sopt2;  /* System Options Register 2 */
> > +   u32 rsv1;
> > +   u32 sopt4;  /* System Options Register 4 */
> > +   u32 sopt5;  /* System Options Register 5 */
> > +   u32 sopt6;  /* System Options Register 6 */
> > +   u32 sopt7;  /* System Options Register 7 */
> > +   u32 rsv2[2];
> > +   u32 sdid;   /* System Device Identification Register */
> > +   u32 scgc[KINETIS_SIM_CG_NUMREGS];   /* Clock Gating Regs 1...7 
> > */
> > +   u32 clkdiv1;/* System Clock Divider Register 1 */
> > +   u32 clkdiv2;/* System Clock Divider Register 2 */
> > +   u32 fcfg1;  /* Flash Configuration Register 1 */
> > +   u32 fcfg2;  /* Flash Configuration Register 2 */
> > +   u32 uidh;   /* Unique Identification Register High */
> > +   u32 uidmh;  /* Unique Identification Register Mid-High */
> > +   u32 uidml;  /* Unique Identification Register Mid Low */
> > +   u32 uidl;   /* Unique Identification Register Low */
> > +   u32 clkdiv3;/* System Clock Divider Register 3 */
> > +   u32 clkdiv4;/* System Clock Divider Register 4 */
> > +   u32 mcr;/* Misc Control Register */
> > +};
> 
> Now there is this design pattern where you copy the datasheet
> register map to a struct again.
> 
> This is not good if there is a second revision of the hardware and some
> registers are shuffled around. IMO it is better to just use #defines
> for register
> offsets, so you can do exceptions later. Else a new hardware revision
> leads to a new struct with new accessor functions etc etc.
> 

I don't see how replacing this structure with bunch of defines could make 
anyones life easier. As registers are shuffled around due to updated 
hardware revision they could be shuffled in this structure too. Doing 
this with buch of defines would require eager and careful adaptation of 
all the defines. I don't see how this could be easier.

Note that I'm not making any instances of the structure (it is used only 
for casting), so shuffling its fields around should not affect the code 
that follows.

After recent purge it is only used within this macro:

#define KINETIS_SIM_PTR(base, reg) \
(&(((struct kinetis_sim_regs *)(base))->reg))

...and used like this:

ioread32(KINETIS_SIM_PTR(sim, clkdiv1));

IMHO changing the struct internals does not require subsequent changes in 
any of those.

Thanks,
Paul
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 5/8] kdbus: use LSM hooks in kdbus code

2015-07-09 Thread Paul Osmialowski



On Thu, 9 Jul 2015, Sergei Zviagintsev wrote:


Hi,

On Wed, Jul 08, 2015 at 02:12:03PM +0200, Paul Osmialowski wrote:
[...]


+   ret = security_kdbus_bus_alloc(b);
+   if (ret) {
+   goto exit_unref;
+   }


checkpatch.pl will complain about this




It should but it didn't:

$ scripts/checkpatch.pl 0005-kdbus-use-LSM-hooks-in-kdbus-code.patch
total: 0 errors, 0 warnings, 365 lines checked

0005-kdbus-use-LSM-hooks-in-kdbus-code.patch has no obvious style problems 
and is ready for submission.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 8/8] kdbus: Ability to run kdbus test by executable binary name

2015-07-08 Thread Paul Osmialowski

Hi Greg,

Thanks for your comments,

On Wed, 8 Jul 2015, Greg Kroah-Hartman wrote:



Why not create symlinks automatically so this works without having to
manually run 'cp'?


It can be anything on which one can apply security label. Symlinks can do.


But really, is spelling out the command line option
really a big issue?


Maybe. I couldn't think about any easier (and easy to present) use case 
that could explain the purpose of this change.




thanks,

greg k-h


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 5/8] kdbus: use LSM hooks in kdbus code

2015-07-08 Thread Paul Osmialowski

You're right about it. To be fixed. Thanks for spotting this.

On Wed, 8 Jul 2015, Lukasz Pawelczyk wrote:


+   ret = -EPERM;
+   goto exit_unref;
+   }


Also, why aren't the error codes passed from LSM? LSM can return
anything, from EINVAL, to ENOMEM. Returning EPERM can be misleading.
From 9c37667302f104e0f412ba2727c4d3df81fb59da Mon Sep 17 00:00:00 2001
From: Paul Osmialowski 
Date: Tue, 26 May 2015 12:00:33 +0200
Subject: [RFC 5/8] kdbus: use LSM hooks in kdbus code

Originates from:

https://github.com/lmctl/kdbus.git (branch: kdbus-lsm-v4.for-systemd-v212)
commit: aa0885489d19be92fa41c6f0a71df28763228a40

Signed-off-by: Karol Lewandowski 
Signed-off-by: Paul Osmialowski 
---
 ipc/kdbus/bus.c| 11 ++-
 ipc/kdbus/bus.h|  5 +
 ipc/kdbus/connection.c | 48 
 ipc/kdbus/connection.h |  6 ++
 ipc/kdbus/domain.c |  9 -
 ipc/kdbus/domain.h |  4 
 ipc/kdbus/endpoint.c   | 10 ++
 ipc/kdbus/names.c  | 10 ++
 ipc/kdbus/queue.c  | 30 --
 9 files changed, 121 insertions(+), 12 deletions(-)

diff --git a/ipc/kdbus/bus.c b/ipc/kdbus/bus.c
index bbdf0f2..be7ed81 100644
--- a/ipc/kdbus/bus.c
+++ b/ipc/kdbus/bus.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "bus.h"
 #include "notify.h"
@@ -51,6 +52,7 @@ static void kdbus_bus_free(struct kdbus_node *node)
 	kdbus_domain_unref(bus->domain);
 	kdbus_policy_db_clear(&bus->policy_db);
 	kdbus_meta_proc_unref(bus->creator_meta);
+	security_kdbus_bus_free(bus);
 	kfree(bus);
 }
 
@@ -161,6 +163,11 @@ static struct kdbus_bus *kdbus_bus_new(struct kdbus_domain *domain,
 		goto exit_unref;
 	}
 
+	ret = security_kdbus_bus_alloc(b);
+	if (ret) {
+		goto exit_unref;
+	}
+
 	/*
 	 * Bus-limits of the creator are accounted on its real UID, just like
 	 * all other per-user limits.
@@ -169,11 +176,13 @@ static struct kdbus_bus *kdbus_bus_new(struct kdbus_domain *domain,
 	if (IS_ERR(b->creator)) {
 		ret = PTR_ERR(b->creator);
 		b->creator = NULL;
-		goto exit_unref;
+		goto exit_free_security;
 	}
 
 	return b;
 
+exit_free_security:
+	security_kdbus_bus_free(b);
 exit_unref:
 	kdbus_node_deactivate(&b->node);
 	kdbus_node_unref(&b->node);
diff --git a/ipc/kdbus/bus.h b/ipc/kdbus/bus.h
index 5bea5ef..521e692 100644
--- a/ipc/kdbus/bus.h
+++ b/ipc/kdbus/bus.h
@@ -53,6 +53,7 @@ struct kdbus_user;
  * @notify_list:	List of pending kernel-generated messages
  * @notify_lock:	Notification list lock
  * @notify_flush_lock:	Notification flushing lock
+ * @security:		LSM security blob
  */
 struct kdbus_bus {
 	struct kdbus_node node;
@@ -81,6 +82,10 @@ struct kdbus_bus {
 	struct list_head notify_list;
 	spinlock_t notify_lock;
 	struct mutex notify_flush_lock;
+
+#ifdef CONFIG_SECURITY
+	void *security;
+#endif
 };
 
 struct kdbus_bus *kdbus_bus_ref(struct kdbus_bus *bus);
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
index 9993753..4b9f0b6 100644
--- a/ipc/kdbus/connection.c
+++ b/ipc/kdbus/connection.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "bus.h"
 #include "connection.h"
@@ -73,6 +74,8 @@ static struct kdbus_conn *kdbus_conn_new(struct kdbus_ep *ep, bool privileged,
 	bool is_activator;
 	bool is_monitor;
 	struct kvec kvec;
+	u32 sid, len;
+	char *label;
 	int ret;
 
 	struct {
@@ -222,6 +225,13 @@ static struct kdbus_conn *kdbus_conn_new(struct kdbus_ep *ep, bool privileged,
 		}
 	}
 
+	security_task_getsecid(current, &sid);
+	security_secid_to_secctx(sid, &label, &len);
+	ret = security_kdbus_connect(conn, label, len);
+	if (ret) {
+		goto exit_unref;
+	}
+
 	if (atomic_inc_return(&conn->user->connections) > KDBUS_USER_MAX_CONN) {
 		/* decremented by destructor as conn->user is valid */
 		ret = -EMFILE;
@@ -276,6 +286,7 @@ static void __kdbus_conn_free(struct kref *kref)
 	kdbus_pool_free(conn->pool);
 	kdbus_ep_unref(conn->ep);
 	put_cred(conn->cred);
+	security_kdbus_conn_free(conn);
 	kfree(conn->description);
 	kfree(conn->quota);
 	kfree(conn);
@@ -1107,6 +1118,11 @@ static int kdbus_conn_reply(struct kdbus_conn *src, struct kdbus_kmsg *kmsg)
 	if (ret < 0)
 		goto exit;
 
+	ret = security_kdbus_talk(src, dst);
+	if (ret) {
+		goto exit;
+	}
+
 	mutex_lock(&dst->lock);
 	reply = kdbus_reply_find(src, dst, kmsg->msg.cookie_reply);
 	if (reply) {
@@ -1187,6 +1203,11 @@ static struct kdbus_reply *kdbus_conn_call(struct kdbus_conn *src,
 	if (ret < 0)
 		goto exit;
 
+	ret = security_kdbus_talk(src, dst);
+	if (ret) {
+		goto exit;
+	}
+
 	if (!kdbus_conn_policy_talk(src, current_cred(), dst)) {
 		ret = -EPERM;
 		goto exit;
@@ -1248,6 +1269,11 @@ static int kdbus_conn_unicast(struct kdbus_conn *src, struct kdbus_kmsg *kmsg)
 	if (ret < 0)
 		goto exit;
 
+	re

[RFC 2/8] lsm: smack: Make ipc/kdbus includes visible so smack callbacks could see them

2015-07-08 Thread Paul Osmialowski
Signed-off-by: Paul Osmialowski 
---
 security/smack/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/security/smack/Makefile b/security/smack/Makefile
index ee2ebd5..bd6927c 100644
--- a/security/smack/Makefile
+++ b/security/smack/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_SECURITY_SMACK) := smack.o
 
 smack-y := smack_lsm.o smack_access.o smackfs.o
 smack-$(CONFIG_SECURITY_SMACK_NETFILTER) += smack_netfilter.o
+
+ccflags-y += -Iipc
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 1/8] lsm: make security_file_receive available for external modules

2015-07-08 Thread Paul Osmialowski
From: Karol Lewandowski 

This is required for using filedesc related LSM hooks in kdbus code
if it is built as a module.

Signed-off-by: Karol Lewandowski 
---
 security/security.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/security/security.c b/security/security.c
index 595fffa..b1e935b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -837,6 +837,7 @@ int security_file_receive(struct file *file)
 {
return call_int_hook(file_receive, 0, file);
 }
+EXPORT_SYMBOL(security_file_receive);
 
 int security_file_open(struct file *file, const struct cred *cred)
 {
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 7/8] kdbus: selftests extended

2015-07-08 Thread Paul Osmialowski
The 'test-send' test case should connect to an already running test-daemon
which creates a bus with known name.

The main goal of this test case is to verify that messages as well as
file descriptors (opened with different open modes) can be transferred
properly.

In order to achieve its goals, this test case opens three files
(/tmp/kdbus-test-send.rd, /tmp/kdbus-test-send.wr,
/tmp/kdbus-test-send.rdwr) with three different open modes (O_RDONLY,
O_WRONLY, O_RDWR). If any of these files exists it is used 'as is',
otherwise it is created with some default content. Then this test tries
to send simple message followed by three messages each one of them
containing an array of opened file descriptors (single element array in the
first message, two element array in the second, three element array in the
third).

The ability to send array of file descriptors required changes in almost
all of the test case files.

Signed-off-by: Karol Lewandowski 
Signed-off-by: Paul Osmialowski 
---
 tools/testing/selftests/kdbus/Makefile   |  1 +
 tools/testing/selftests/kdbus/kdbus-test.c   | 11 +++-
 tools/testing/selftests/kdbus/kdbus-test.h   |  1 +
 tools/testing/selftests/kdbus/kdbus-util.c   | 19 --
 tools/testing/selftests/kdbus/kdbus-util.h   |  2 +-
 tools/testing/selftests/kdbus/test-activator.c   | 20 +++---
 tools/testing/selftests/kdbus/test-chat.c|  6 +-
 tools/testing/selftests/kdbus/test-connection.c  |  8 ++-
 tools/testing/selftests/kdbus/test-fd.c  |  2 +-
 tools/testing/selftests/kdbus/test-message.c | 69 +++
 tools/testing/selftests/kdbus/test-metadata-ns.c | 10 +--
 tools/testing/selftests/kdbus/test-monitor.c |  9 +--
 tools/testing/selftests/kdbus/test-policy-ns.c   |  8 +--
 tools/testing/selftests/kdbus/test-policy-priv.c | 48 --
 tools/testing/selftests/kdbus/test-send.c| 84 
 tools/testing/selftests/kdbus/test-sync.c|  2 +-
 tools/testing/selftests/kdbus/test-timeout.c |  2 +-
 17 files changed, 217 insertions(+), 85 deletions(-)
 create mode 100644 tools/testing/selftests/kdbus/test-send.c

diff --git a/tools/testing/selftests/kdbus/Makefile 
b/tools/testing/selftests/kdbus/Makefile
index 8f36cb5..f400756 100644
--- a/tools/testing/selftests/kdbus/Makefile
+++ b/tools/testing/selftests/kdbus/Makefile
@@ -27,6 +27,7 @@ OBJS= \
test-policy.o   \
test-policy-ns.o\
test-policy-priv.o  \
+   test-send.o \
test-sync.o \
test-timeout.o
 
diff --git a/tools/testing/selftests/kdbus/kdbus-test.c 
b/tools/testing/selftests/kdbus/kdbus-test.c
index d3a656f..5a296da 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.c
+++ b/tools/testing/selftests/kdbus/kdbus-test.c
@@ -25,6 +25,7 @@
 enum {
TEST_CREATE_BUS = 1 << 0,
TEST_CREATE_CONN= 1 << 1,
+   TEST_CREATE_CAN_FAIL= 1 << 2,
 };
 
 struct kdbus_test {
@@ -148,6 +149,12 @@ static const struct kdbus_test tests[] = {
.flags  = TEST_CREATE_BUS,
},
{
+   .name   = "send",
+   .desc   = "send",
+   .func   = kdbus_test_send,
+   .flags  = TEST_CREATE_CONN | TEST_CREATE_CAN_FAIL,
+   },
+   {
.name   = "sync-byebye",
.desc   = "synchronous replies vs. BYEBYE",
.func   = kdbus_test_sync_byebye,
@@ -302,7 +309,7 @@ static int test_prepare_env(const struct kdbus_test *t,
   _KDBUS_ATTACH_ALL,
   _KDBUS_ATTACH_ALL, &s);
free(n);
-   ASSERT_RETURN(ret == 0);
+   ASSERT_RETURN((ret == 0) || (t->flags & TEST_CREATE_CAN_FAIL));
 
asprintf(&env->buspath, "%s/%s/bus", args->root, s);
free(s);
@@ -331,7 +338,7 @@ static int test_prepare_env(const struct kdbus_test *t,
}
ASSERT_RETURN(env->buspath);
env->conn = kdbus_hello(env->buspath, 0, NULL, 0);
-   ASSERT_RETURN(env->conn);
+   ASSERT_RETURN(env->conn || (t->flags & TEST_CREATE_CAN_FAIL));
}
 
env->root = args->root;
diff --git a/tools/testing/selftests/kdbus/kdbus-test.h 
b/tools/testing/selftests/kdbus/kdbus-test.h
index a5c6ae8..604c25c 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.h
+++ b/tools/testing/selftests/kdbus/kdbus-test.h
@@ -75,6 +75,7 @@ int kdbus_test_name_queue(struct kdbus_test_env *env);
 int kdbus_test_policy(struct kdbus_test_env *env);
 int kdbus_test_policy_ns(struct kdbus_test_env *env);
 int kdbus_test_policy_priv(struct kdbus_test_env *env);
+int kdbus_test_send(struct kdbus_test_env *env);
 int kdbus_test_sync_byebye(struct kdbus_test_env *env)

[RFC 0/8] Introduce LSM to KDBUS

2015-07-08 Thread Paul Osmialowski
This patchset partially summarizes effects of collective work by
Karol Lewandowski and Paul Moore towards introduction of LSM into KDBUS.

These patches originate from following git repositories:

git://git.infradead.org/users/pcmoore/selinux (branch: working-kdbus)

https://github.com/lmctl/linux.git (branch: kdbus-lsm-v4.for-systemd-v212)

https://github.com/lmctl/kdbus.git (branch: kdbus-lsm-v4.for-systemd-v212)

Since kdbus made its way to linux-next tree, I was kindly asked by
Karol Lewandowski to fit his work into the current kdbus code existing
there.

As both kdbus and security related code changed a bit, so are my changes
quite substantial in places.

Note that SELinux kdbus access control patches are absent - only SMACK part
of original work is included.

I've also made some changes to kdbus test suite. In order to see LSM hooks
in action we need to be able to run tests from different executable
binaries holding different security labels.

Therefore I added ability to select execution of particular test by
executed binary name. This is essential for running newly added 'send' test
which should communicate with 'daemon' test running in another process.

Karol Lewandowski (1):
  lsm: make security_file_receive available for external modules

Paul Osmialowski (7):
  lsm: smack: Make ipc/kdbus includes visible so smack callbacks could
see them
  lsm: kdbus security hooks
  lsm: smack: smack callbacks for kdbus security hooks
  kdbus: use LSM hooks in kdbus code
  kdbus: TEST_CREATE_CONN now does no depend on TEST_CREATE_BUS
  kdbus: selftests extended
  kdbus: Ability to run kdbus test by executable binary name

 include/linux/lsm_hooks.h|  67 +
 include/linux/security.h |  99 +++
 ipc/kdbus/bus.c  |  12 ++-
 ipc/kdbus/bus.h  |   3 +
 ipc/kdbus/connection.c   |  54 +++
 ipc/kdbus/connection.h   |   4 +
 ipc/kdbus/domain.c   |   9 +-
 ipc/kdbus/domain.h   |   2 +
 ipc/kdbus/endpoint.c |  11 +++
 ipc/kdbus/names.c|  11 +++
 ipc/kdbus/queue.c|  30 --
 security/security.c  | 118 +++
 security/smack/Makefile  |   2 +
 security/smack/smack_lsm.c   |  68 +
 tools/testing/selftests/kdbus/Makefile   |   1 +
 tools/testing/selftests/kdbus/kdbus-test.c   |  37 ++-
 tools/testing/selftests/kdbus/kdbus-test.h   |   1 +
 tools/testing/selftests/kdbus/kdbus-util.c   |  37 ---
 tools/testing/selftests/kdbus/kdbus-util.h   |   2 +-
 tools/testing/selftests/kdbus/test-activator.c   |  20 ++--
 tools/testing/selftests/kdbus/test-chat.c|   6 +-
 tools/testing/selftests/kdbus/test-connection.c  |   8 +-
 tools/testing/selftests/kdbus/test-fd.c  |   2 +-
 tools/testing/selftests/kdbus/test-message.c |  69 -
 tools/testing/selftests/kdbus/test-metadata-ns.c |  10 +-
 tools/testing/selftests/kdbus/test-monitor.c |   9 +-
 tools/testing/selftests/kdbus/test-policy-ns.c   |   8 +-
 tools/testing/selftests/kdbus/test-policy-priv.c |  48 +
 tools/testing/selftests/kdbus/test-send.c|  84 
 tools/testing/selftests/kdbus/test-sync.c|   2 +-
 tools/testing/selftests/kdbus/test-timeout.c |   2 +-
 31 files changed, 732 insertions(+), 104 deletions(-)
 create mode 100644 tools/testing/selftests/kdbus/test-send.c

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 6/8] kdbus: TEST_CREATE_CONN now does no depend on TEST_CREATE_BUS

2015-07-08 Thread Paul Osmialowski
Without this patch, it is impossible to specify test case able to
connect to a bus already created (e.g. by 'test-daemon' test case), you can
only specify:

1) TEST_CREATE_BUS which creates new bus, or
2) TEST_CREATE_CONN OR'ed with TEST_CREATE_BUS which creates new bus and
creates connection to it.

This patch adds the missing ability to specify TEST_CREATE_CONN alone.

It will be used by a new test case (will be added by separate commit) which
is supposed to connect to already started test-daemon case.

Signed-off-by: Paul Osmialowski 
---
 tools/testing/selftests/kdbus/kdbus-test.c | 21 +
 tools/testing/selftests/kdbus/kdbus-util.c | 18 +++---
 2 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/kdbus/kdbus-test.c 
b/tools/testing/selftests/kdbus/kdbus-test.c
index 294e82a..d3a656f 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.c
+++ b/tools/testing/selftests/kdbus/kdbus-test.c
@@ -309,6 +309,27 @@ static int test_prepare_env(const struct kdbus_test *t,
}
 
if (t->flags & TEST_CREATE_CONN) {
+   if (!env->buspath) {
+   char *s = NULL;
+   char *n = NULL;
+   int ret;
+
+   if (!args->busname) {
+   n = unique_name("test-bus");
+   ASSERT_RETURN(n);
+   }
+
+   ret = kdbus_create_bus(-1,
+  args->busname ?: n,
+  0,
+  0, &s);
+   free(n);
+   ASSERT_RETURN(ret == 0);
+
+   asprintf(&env->buspath, "%s/%s/bus", args->root, s);
+   free(s);
+   }
+   ASSERT_RETURN(env->buspath);
env->conn = kdbus_hello(env->buspath, 0, NULL, 0);
ASSERT_RETURN(env->conn);
}
diff --git a/tools/testing/selftests/kdbus/kdbus-util.c 
b/tools/testing/selftests/kdbus/kdbus-util.c
index 29a0cb1..26104ca 100644
--- a/tools/testing/selftests/kdbus/kdbus-util.c
+++ b/tools/testing/selftests/kdbus/kdbus-util.c
@@ -141,7 +141,7 @@ int kdbus_create_bus(int control_fd, const char *name,
char str[64];
} name;
} bus_make;
-   int ret;
+   int ret = 0;
 
memset(&bus_make, 0, sizeof(bus_make));
bus_make.bp.size = sizeof(bus_make.bp);
@@ -171,13 +171,17 @@ int kdbus_create_bus(int control_fd, const char *name,
 bus_make.attach[1].size +
 bus_make.name.size;
 
-   kdbus_printf("Creating bus with name >%s< on control fd %d ...\n",
-name, control_fd);
+   if (control_fd != -1) {
+   kdbus_printf(
+   "Creating bus with name >%s< on control fd %d ...\n",
+   name, control_fd);
 
-   ret = kdbus_cmd_bus_make(control_fd, &bus_make.cmd);
-   if (ret < 0) {
-   kdbus_printf("--- error when making bus: %d (%m)\n", ret);
-   return ret;
+   ret = kdbus_cmd_bus_make(control_fd, &bus_make.cmd);
+   if (ret < 0) {
+   kdbus_printf("--- error when making bus: %d (%m)\n",
+ret);
+   return ret;
+   }
}
 
if (ret == 0 && path)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 5/8] kdbus: use LSM hooks in kdbus code

2015-07-08 Thread Paul Osmialowski
Originates from:

https://github.com/lmctl/kdbus.git (branch: kdbus-lsm-v4.for-systemd-v212)
commit: aa0885489d19be92fa41c6f0a71df28763228a40

Signed-off-by: Karol Lewandowski 
Signed-off-by: Paul Osmialowski 
---
 ipc/kdbus/bus.c| 12 ++-
 ipc/kdbus/bus.h|  3 +++
 ipc/kdbus/connection.c | 54 ++
 ipc/kdbus/connection.h |  4 
 ipc/kdbus/domain.c |  9 -
 ipc/kdbus/domain.h |  2 ++
 ipc/kdbus/endpoint.c   | 11 ++
 ipc/kdbus/names.c  | 11 ++
 ipc/kdbus/queue.c  | 30 ++--
 9 files changed, 124 insertions(+), 12 deletions(-)

diff --git a/ipc/kdbus/bus.c b/ipc/kdbus/bus.c
index bbdf0f2..9894895 100644
--- a/ipc/kdbus/bus.c
+++ b/ipc/kdbus/bus.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "bus.h"
 #include "notify.h"
@@ -51,6 +52,7 @@ static void kdbus_bus_free(struct kdbus_node *node)
kdbus_domain_unref(bus->domain);
kdbus_policy_db_clear(&bus->policy_db);
kdbus_meta_proc_unref(bus->creator_meta);
+   security_kdbus_bus_free(bus);
kfree(bus);
 }
 
@@ -161,6 +163,12 @@ static struct kdbus_bus *kdbus_bus_new(struct kdbus_domain 
*domain,
goto exit_unref;
}
 
+   ret = security_kdbus_bus_alloc(b);
+   if (ret) {
+   ret = -EPERM;
+   goto exit_unref;
+   }
+
/*
 * Bus-limits of the creator are accounted on its real UID, just like
 * all other per-user limits.
@@ -169,11 +177,13 @@ static struct kdbus_bus *kdbus_bus_new(struct 
kdbus_domain *domain,
if (IS_ERR(b->creator)) {
ret = PTR_ERR(b->creator);
b->creator = NULL;
-   goto exit_unref;
+   goto exit_free_security;
}
 
return b;
 
+exit_free_security:
+   security_kdbus_bus_free(b);
 exit_unref:
kdbus_node_deactivate(&b->node);
kdbus_node_unref(&b->node);
diff --git a/ipc/kdbus/bus.h b/ipc/kdbus/bus.h
index 5bea5ef..03e4a54 100644
--- a/ipc/kdbus/bus.h
+++ b/ipc/kdbus/bus.h
@@ -53,6 +53,7 @@ struct kdbus_user;
  * @notify_list:   List of pending kernel-generated messages
  * @notify_lock:   Notification list lock
  * @notify_flush_lock: Notification flushing lock
+ * @security:  LSM security blob
  */
 struct kdbus_bus {
struct kdbus_node node;
@@ -81,6 +82,8 @@ struct kdbus_bus {
struct list_head notify_list;
spinlock_t notify_lock;
struct mutex notify_flush_lock;
+
+   void *security;
 };
 
 struct kdbus_bus *kdbus_bus_ref(struct kdbus_bus *bus);
diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
index 9993753..b85cdc7 100644
--- a/ipc/kdbus/connection.c
+++ b/ipc/kdbus/connection.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "bus.h"
 #include "connection.h"
@@ -73,6 +74,8 @@ static struct kdbus_conn *kdbus_conn_new(struct kdbus_ep *ep, 
bool privileged,
bool is_activator;
bool is_monitor;
struct kvec kvec;
+   u32 sid, len;
+   char *label;
int ret;
 
struct {
@@ -222,6 +225,14 @@ static struct kdbus_conn *kdbus_conn_new(struct kdbus_ep 
*ep, bool privileged,
}
}
 
+   security_task_getsecid(current, &sid);
+   security_secid_to_secctx(sid, &label, &len);
+   ret = security_kdbus_connect(conn, label, len);
+   if (ret) {
+   ret = -EPERM;
+   goto exit_unref;
+   }
+
if (atomic_inc_return(&conn->user->connections) > KDBUS_USER_MAX_CONN) {
/* decremented by destructor as conn->user is valid */
ret = -EMFILE;
@@ -276,6 +287,7 @@ static void __kdbus_conn_free(struct kref *kref)
kdbus_pool_free(conn->pool);
kdbus_ep_unref(conn->ep);
put_cred(conn->cred);
+   security_kdbus_conn_free(conn);
kfree(conn->description);
kfree(conn->quota);
kfree(conn);
@@ -1107,6 +1119,12 @@ static int kdbus_conn_reply(struct kdbus_conn *src, 
struct kdbus_kmsg *kmsg)
if (ret < 0)
goto exit;
 
+   ret = security_kdbus_talk(src, dst);
+   if (ret) {
+   ret = -EPERM;
+   goto exit;
+   }
+
mutex_lock(&dst->lock);
reply = kdbus_reply_find(src, dst, kmsg->msg.cookie_reply);
if (reply) {
@@ -1187,6 +1205,12 @@ static struct kdbus_reply *kdbus_conn_call(struct 
kdbus_conn *src,
if (ret < 0)
goto exit;
 
+   ret = security_kdbus_talk(src, dst);
+   if (ret) {
+   ret = -EPERM;
+   goto exit;
+   }
+
if (!kdbus_conn_policy_talk(src, current_cred(), dst)) {
ret = -EPERM;
goto exit;
@@ -1248,6 +12

[RFC 3/8] lsm: kdbus security hooks

2015-07-08 Thread Paul Osmialowski
This is combination of the work by Karol Lewandowski and Paul Moore
on LSM hooks for kdbus.

Originates from:

git://git.infradead.org/users/pcmoore/selinux (branch: working-kdbus)
commit: 7050f206a79564886938d0edc4e1e9da5972c72d

https://github.com/lmctl/linux.git (branch: kdbus-lsm-v4.for-systemd-v212)
commit: a9fe4c33b6e5ab25a243e0590df406aabb6add12

Signed-off-by: Karol Lewandowski 
Signed-off-by: Paul Moore 
Signed-off-by: Paul Osmialowski 
---
 include/linux/lsm_hooks.h |  67 ++
 include/linux/security.h  |  99 +++
 security/security.c   | 117 ++
 3 files changed, 283 insertions(+)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 9429f05..2a8d8fc 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1297,6 +1297,36 @@
  * @inode we wish to get the security context of.
  * @ctx is a pointer in which to place the allocated security context.
  * @ctxlen points to the place to put the length of @ctx.
+ *
+ * @kdbus_domain_alloc:
+ * Allocate kdbus domain.
+ * @kdbus_domain_free:
+ * Deallocate kdbus domain.
+ * @kdbus_bus_alloc:
+ * Allocate kdbus bus.
+ * @kdbus_bus_free:
+ * Deallocate kdbus bus.
+ * @kdbus_send:
+ * Send message.
+ * @kdbus_recv:
+ * Receive message.
+ * @kdbus_name_acquire:
+ * Request a well-known bus name to associate with the connection.
+ * @kdbus_name_list:
+ * Retrieve the list of all currently registered well-known and unique
+ * names.
+ * @kdbus_ep_create:
+ * Endpoint create
+ * @kdbus_connect:
+ * Connect
+ * @kdbus_conn_free:
+ * Deallocate connection
+ * @kdbus_conn_info:
+ * Retrieve credentials and properties of the initial creator of the
+ * connection.
+ * @kdbus_talk:
+ * Talk to a given peer.
+ *
  * This is the main security structure.
  */
 
@@ -1520,6 +1550,29 @@ union security_list_options {
int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
 
+   int (*kdbus_domain_alloc)(struct kdbus_domain *domain);
+   void (*kdbus_domain_free)(struct kdbus_domain *domain);
+
+   int (*kdbus_bus_alloc)(struct kdbus_bus *bus);
+   void (*kdbus_bus_free)(struct kdbus_bus *bus);
+   int (*kdbus_send)(const struct kdbus_conn *conn,
+ const struct kdbus_bus *bus);
+   int (*kdbus_recv)(const struct kdbus_conn *conn,
+ const struct kdbus_bus *bus);
+   int (*kdbus_name_acquire)(const struct kdbus_conn *conn,
+ const char *name);
+   int (*kdbus_name_list)(const struct kdbus_bus *bus);
+
+   int (*kdbus_ep_create)(const struct kdbus_bus *bus);
+   int (*kdbus_ep_setpolicy)(const struct kdbus_bus *bus);
+
+   int (*kdbus_connect)(struct kdbus_conn *conn,
+const char *secctx, u32 seclen);
+   void (*kdbus_conn_free)(struct kdbus_conn *conn);
+   int (*kdbus_conn_info)(const struct kdbus_conn *conn);
+   int (*kdbus_talk)(const struct kdbus_conn *src,
+ const struct kdbus_conn *dst);
+
 #ifdef CONFIG_SECURITY_NETWORK
int (*unix_stream_connect)(struct sock *sock, struct sock *other,
struct sock *newsk);
@@ -1760,6 +1813,20 @@ struct security_hook_heads {
struct list_head inode_notifysecctx;
struct list_head inode_setsecctx;
struct list_head inode_getsecctx;
+   struct list_head kdbus_domain_alloc;
+   struct list_head kdbus_domain_free;
+   struct list_head kdbus_bus_alloc;
+   struct list_head kdbus_bus_free;
+   struct list_head kdbus_send;
+   struct list_head kdbus_recv;
+   struct list_head kdbus_name_acquire;
+   struct list_head kdbus_name_list;
+   struct list_head kdbus_ep_create;
+   struct list_head kdbus_ep_setpolicy;
+   struct list_head kdbus_connect;
+   struct list_head kdbus_conn_free;
+   struct list_head kdbus_conn_info;
+   struct list_head kdbus_talk;
 #ifdef CONFIG_SECURITY_NETWORK
struct list_head unix_stream_connect;
struct list_head unix_may_send;
diff --git a/include/linux/security.h b/include/linux/security.h
index 79d85dd..5f257b9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -53,6 +53,10 @@ struct msg_queue;
 struct xattr;
 struct xfrm_sec_ctx;
 struct mm_struct;
+struct kdbus_ep;
+struct kdbus_bus;
+struct kdbus_conn;
+struct kdbus_domain;
 
 /* If capable should audit the security request */
 #define SECURITY_CAP_NOAUDIT 0
@@ -356,6 +360,28 @@ void security_release_secctx(char *secdata, u32 seclen);
 int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
 int security_inode_getsecctx

[RFC 4/8] lsm: smack: smack callbacks for kdbus security hooks

2015-07-08 Thread Paul Osmialowski
This adds implementation of three smack callbacks sitting behind kdbus
security hooks as proposed by Karol Lewandowski.

Originates from:

git://git.infradead.org/users/pcmoore/selinux (branch: working-kdbus)
commit: fc3505d058c001fe72a6f66b833e0be5b2d118f3

https://github.com/lmctl/linux.git (branch: kdbus-lsm-v4.for-systemd-v212)
commit: 103c26fd27d1ec8c32d85dd3d85681f936ac66fb

Signed-off-by: Karol Lewandowski 
Signed-off-by: Paul Osmialowski 
---
 security/smack/smack_lsm.c | 68 ++
 1 file changed, 68 insertions(+)

diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index a143328..033b756 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "smack.h"
 
 #define TRANS_TRUE "TRUE"
@@ -3336,6 +3337,69 @@ static int smack_setprocattr(struct task_struct *p, char 
*name,
 }
 
 /**
+ * smack_kdbus_connect - Set the security blob for a KDBus connection
+ * @conn: the connection
+ * @secctx: smack label
+ * @seclen: smack label length
+ *
+ * Returns 0
+ */
+static int smack_kdbus_connect(struct kdbus_conn *conn,
+  const char *secctx, u32 seclen)
+{
+   struct smack_known *skp;
+
+   if (secctx && seclen > 0)
+   skp = smk_import_entry(secctx, seclen);
+   else
+   skp = smk_of_current();
+   conn->security = skp;
+
+   return 0;
+}
+
+/**
+ * smack_kdbus_conn_free - Clear the security blob for a KDBus connection
+ * @conn: the connection
+ *
+ * Clears the blob pointer
+ */
+static void smack_kdbus_conn_free(struct kdbus_conn *conn)
+{
+   conn->security = NULL;
+}
+
+/**
+ * smack_kdbus_talk - Smack access on KDBus
+ * @src: source kdbus connection
+ * @dst: destination kdbus connection
+ *
+ * Return 0 if a subject with the smack of sock could access
+ * an object with the smack of other, otherwise an error code
+ */
+static int smack_kdbus_talk(const struct kdbus_conn *src,
+   const struct kdbus_conn *dst)
+{
+   struct smk_audit_info ad;
+   struct smack_known *sskp = src->security;
+   struct smack_known *dskp = dst->security;
+   int ret;
+
+   BUG_ON(sskp == NULL);
+   BUG_ON(dskp == NULL);
+
+   if (smack_privileged(CAP_MAC_OVERRIDE))
+   return 0;
+
+   smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NONE);
+
+   ret = smk_access(sskp, dskp, MAY_WRITE, &ad);
+   if (ret)
+   return ret;
+   return 0;
+}
+
+/**
  * smack_unix_stream_connect - Smack access on UDS
  * @sock: one sock
  * @other: the other sock
@@ -4393,6 +4457,10 @@ struct security_hook_list smack_hooks[] = {
LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx),
+
+   LSM_HOOK_INIT(kdbus_connect, smack_kdbus_connect),
+   LSM_HOOK_INIT(kdbus_conn_free, smack_kdbus_conn_free),
+   LSM_HOOK_INIT(kdbus_talk, smack_kdbus_talk),
 };
 
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 8/8] kdbus: Ability to run kdbus test by executable binary name

2015-07-08 Thread Paul Osmialowski
With this applied, you can do following:

$ cp kdbus-test daemon
$ cp kdbus-test send

Then run 'daemon' in one shell session:

$ ./daemon --bus test

...and 'send' in another:

$ ./send --bus test

Useful for testing features introduced by previous patches.

Signed-off-by: Paul Osmialowski 
---
 tools/testing/selftests/kdbus/kdbus-test.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/tools/testing/selftests/kdbus/kdbus-test.c 
b/tools/testing/selftests/kdbus/kdbus-test.c
index 5a296da..9efbc5f 100644
--- a/tools/testing/selftests/kdbus/kdbus-test.c
+++ b/tools/testing/selftests/kdbus/kdbus-test.c
@@ -829,6 +829,7 @@ int main(int argc, char *argv[])
ARG_UIDMAP,
ARG_GIDMAP,
};
+   char *exec = basename(argv[0]);
 
kdbus_args = malloc(sizeof(*kdbus_args));
if (!kdbus_args) {
@@ -858,6 +859,10 @@ int main(int argc, char *argv[])
 
srand(time(NULL));
 
+   if (strcmp(exec, "kdbus-test") != 0) {
+   kdbus_args->test = exec;
+   }
+
while ((t = getopt_long(argc, argv, "hxfm:r:t:b:w:a", options, NULL)) 
>= 0) {
switch (t) {
case 'x':
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-07-06 Thread Paul Osmialowski

Hi Guys,

Let me share with you one more approach. I moved clocks back to 
sub-devices, so sharing the same resources (registers) is more obvious 
again. I like it better than previous approach. Can you look at this, 
please?


On Sat, 4 Jul 2015, Paul Osmialowski wrote:


Hi Arnd,

I'm attaching excerpt from Kinetis reference manual that may make situation 
clearer.


These MCG and SIM registers are used only to determine configuration (clock 
fixed rates and clock signal origins) at run time.


Namely, the real MCGOUTCLK source (in the middle) which is the parent for 
core clock (CCLK) and peripheral clock (PCLK) is determined at run time by 
reading MCG registers, let me quote commit message from Emcraft git repo:


* Determine in run-time what oscillator module (OSC0 or OSC1) is used
as clock source for the main PLL.
* When OSC1 is selected, assume its frequency to be 12 MHz on all
boards (there is a 12 MHz oscillator on XTAL1/EXTAL1 on K70-SOM and
TWR-K70F120M boards).

In my .dts I'm trying to possibly follow real clock hierarchy, but to go 
anywhere behind MCGOUTCLK would require ability to rewrite .dtb e.g. by 
U-boot. But that's too demanding for any potential users of this BSP. So 
let's asume that MCGOUTCLK is the root clock and a parent for CCLK and PCLK.


In my most recent version I added OSC0ERCLK explicitly as one more root 
clock, since it is also used directly (through CG reg. 1 bit 0) by Freescale 
fec network device whose in-tree driver I'm trying to make usable for 
Kinetis.


On Sat, 4 Jul 2015, Arnd Bergmann wrote:


 On Friday 03 July 2015 00:08:27 Thomas Gleixner wrote:
>  On Thu, 2 Jul 2015, Paul Osmialowski wrote:
> >  On Thu, 2 Jul 2015, Arnd Bergmann wrote:
> > 
> > >  I wonder if you could move out the fixed rate clocks into their own

> > >  nodes. Are they actually controlled by the same block? If they are
> > >  just fixed, you can use the normal binding for fixed rate clocks
> > >  and only describe the clocks that are related to the driver.
> > 
> >  In my view having these clocks grouped together looks more convincing. 
> >  After

> >  all, they all share the same I/O regs in order to read configuration.
> 
>  The fact that they share a register is not making them a group. That's

>  just a HW design decision and you need to deal with that by protecting
>  the register access, but not by trying to group them artificially at
>  the functional level.

 I'd disagree with that: The clock controller is the device that owns the
 registers and that should be one node in DT, as Paul's first version does.

 The part I'm still struggling with is understanding how the fixed-rate
 clocks are controlled through those registers. If they are indeed
 configured
 through the registers, the name is probably wrong and should be changed
 to whatever kind of non-fixed clock this is.

  Arnd

From 273fdc022a44e2c4ac94a8bc070dd42a8f299215 Mon Sep 17 00:00:00 2001
From: Paul Osmialowski 
Date: Mon, 29 Jun 2015 20:58:55 +0200
Subject: [PATCH 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

Based on K70P256M150SF3RM.pdf K70 Sub-Family Reference Manual, Rev. 3.

Signed-off-by: Paul Osmialowski 
---
 .../devicetree/bindings/clock/kinetis-clock.txt|  82 
 arch/arm/boot/dts/kinetis.dtsi |  43 ++
 drivers/clk/Makefile   |   1 +
 drivers/clk/clk-kinetis.c  | 532 +
 4 files changed, 658 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/kinetis-clock.txt
 create mode 100644 drivers/clk/clk-kinetis.c

diff --git a/Documentation/devicetree/bindings/clock/kinetis-clock.txt b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
new file mode 100644
index 000..d7c4ebf
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
@@ -0,0 +1,82 @@
+* Clock bindings for Freescale Kinetis SoC
+
+Required properties:
+- compatible: Should be "fsl,kinetis-cmu".
+- reg: Two address ranges:
+	- "mcg" for the Multipurpose Clock Genetator (MCG) register set.
+	- "sim" for System Integration Module (SIM) register set.
+- reg-names: Should name the address ranges ("mcg" and "sim" respectively).
+
+A set of clock sub-devices should be also provided. Each sub-device should be
+a fixed-rate clock or a clock gate.
+
+Required properties for sub-devices:
+- clocks: single element list of parent clocks (only for non-root clocks).
+- #clock-cells: For fixed rate clocks must be <0>,
+		for clock gates must be <2> (see below).
+
+For clock gate addresses see K70 Sub-Family Reference Manual, Rev. 3 pg. 341
+and later. Notice that addresses are zero-based, so SIM_SCGC1 has address 0,
+SIM_SCGC2 has address 1 and so on. The second address component is the bit

Re: [PATCH v2 6/9] arm: twr-k70f120m: extend Freescale eDMA driver with the ability to support Kinetis SoC

2015-07-05 Thread Paul Osmialowski
Hi Vinod,

You're right, this should be separate patchset. Having patchset too big
leads to huge list of maintainers and lack of focusing on details 
(on-error return values are total mess now!).

I plan to split it into three: 1) initial support (so the proof that 
platform is living could be read only on JTAG), 2) DMA support and 3) UART 
support.

Also in my view extending this DMA driver requires acceptance of initial
platform support first - there's no point in extending this driver without
having support for a platform for which we are extending it.

Thanks,
Paul

On Sun, 5 Jul 2015, Vinod Koul wrote:

> On Tue, Jun 30, 2015 at 02:27:27PM +0200, Paul Osmialowski wrote:
> The patch title is not per subsystem semantics, pls fix that
>
>> Surprisingly small amount of work was required in order to extend already
>> existing eDMA driver with the support for Kinetis SoC architecture.
> And this doesn't tell me the stuff you added/removed/fixed in current driver
> to extend to Kinetis. Our changelog should tell what changed and why
>
> Btw is this patch dependent upon the rest of the series?
>
>>
>>  static int
>> -fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine 
>> *fsl_edma)
>> +fsl_edma_irq_init(struct platform_device *pdev,
>> +  struct fsl_edma_engine *fsl_edma)
> please keep style changes in a separate patch
>
>>  {
>> +struct device_node *np = pdev->dev.of_node;
>> +int irq, errirq;
>>  int ret;
>>
>> -fsl_edma->txirq = platform_get_irq_byname(pdev, "edma-tx");
>> -if (fsl_edma->txirq < 0) {
>> -dev_err(&pdev->dev, "Can't get edma-tx irq.\n");
>> -return fsl_edma->txirq;
>> -}
>> -
>> -fsl_edma->errirq = platform_get_irq_byname(pdev, "edma-err");
>> -if (fsl_edma->errirq < 0) {
>> +errirq = platform_get_irq_byname(pdev, "edma-err");
>> +if (errirq < 0) {
>>  dev_err(&pdev->dev, "Can't get edma-err irq.\n");
>> -return fsl_edma->errirq;
>> +return irq;
> shouldn't this be errirq
>
>>  }
>>
>> -if (fsl_edma->txirq == fsl_edma->errirq) {
>> -ret = devm_request_irq(&pdev->dev, fsl_edma->txirq,
>> -fsl_edma_irq_handler, 0, "eDMA", fsl_edma);
>> -if (ret) {
>> -dev_err(&pdev->dev, "Can't register eDMA IRQ.\n");
>> - return  ret;
>> +if (fsl_edma->kinetis) {
>> +int i;
>> +int irqs = of_irq_count(np);
>> +
>> +if (irqs <= 1) {
>> +dev_err(&pdev->dev, "Wrong eDMA irq count %d\n", irqs);
>> +return -EINVAL;
> why not return irqs?
>
>>  }
>> -} else {
>> -ret = devm_request_irq(&pdev->dev, fsl_edma->txirq,
>> +
>> +for (i = 0; i < (irqs - 1); i++) {
>> +char irq_name[32];
>> +
>> +sprintf(irq_name, "edma-tx-%d,%d", i, 16 + i);
>> +irq = platform_get_irq_byname(pdev, irq_name);
>> +if (irq < 0) {
>> +dev_err(&pdev->dev, "Can't get %s irq.\n",
>> +irq_name);
>> +return irq;
>> +}
>> +
>> +ret = devm_request_irq(&pdev->dev, irq,
>>  fsl_edma_tx_handler, 0, "eDMA tx", fsl_edma);
>> -if (ret) {
>> -dev_err(&pdev->dev, "Can't register eDMA tx IRQ.\n");
>> -return  ret;
>> +if (ret) {
>> +dev_err(&pdev->dev, "Can't register %s IRQ.\n",
>> +irq_name);
>> +return  ret;
>> +}
>>  }
>>
>> -ret = devm_request_irq(&pdev->dev, fsl_edma->errirq,
>> -fsl_edma_err_handler, 0, "eDMA err", fsl_edma);
>> +ret = devm_request_irq(&pdev->dev, errirq,
>> +fsl_edma_err_handler, 0, "eDMA err", fsl_edma);
>&

Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-07-03 Thread Paul Osmialowski

Arnd, Thomas,

Thanks for your valuable input and for your patience.

I'm attaching yet another proposal for this clock driver. I've 
flattened the .dts and ensured register access protection. I've also added 
one more clock source (osc0er) and clock gate to it.


Can you comment this one too?

On Fri, 3 Jul 2015, Thomas Gleixner wrote:


On Thu, 2 Jul 2015, Paul Osmialowski wrote:

On Thu, 2 Jul 2015, Arnd Bergmann wrote:


I wonder if you could move out the fixed rate clocks into their own
nodes. Are they actually controlled by the same block? If they are
just fixed, you can use the normal binding for fixed rate clocks
and only describe the clocks that are related to the driver.


In my view having these clocks grouped together looks more convincing. After
all, they all share the same I/O regs in order to read configuration.


The fact that they share a register is not making them a group. That's
just a HW design decision and you need to deal with that by protecting
the register access, but not by trying to group them artificially at
the functional level.

Thanks,

tglx
From e05dcb772d47e4473914ac1e7703b361eb54db14 Mon Sep 17 00:00:00 2001
From: Paul Osmialowski 
Date: Mon, 29 Jun 2015 20:58:55 +0200
Subject: [PATCH 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

Based on K70P256M150SF3RM.pdf K70 Sub-Family Reference Manual, Rev. 3.

Signed-off-by: Paul Osmialowski 
---
 .../devicetree/bindings/clock/kinetis-clock.txt|  86 
 arch/arm/boot/dts/kinetis.dtsi |  51 +++
 drivers/clk/Makefile   |   1 +
 drivers/clk/clk-kinetis.c  | 502 +
 4 files changed, 640 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/kinetis-clock.txt
 create mode 100644 drivers/clk/clk-kinetis.c

diff --git a/Documentation/devicetree/bindings/clock/kinetis-clock.txt b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
new file mode 100644
index 000..507f91b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
@@ -0,0 +1,86 @@
+* Clock bindings for Freescale Kinetis SoC
+
+Required properties:
+- compatible: Should be "fsl,kinetis-cmu".
+- reg: For fixed rate clocks, two address ranges:
+	- one for the Multipurpose Clock Genetator (MCG)
+	- one for System Integration Module (SIM) register set.
+	For clock gates, one address range for System Integration Module (SIM)
+	register set.
+- clocks: single element list of parent clocks (only for non-root clocks).
+- #clock-cells: For fixed rate clocks must be <0>,
+	for clock gates must be <2> (see below).
+
+For clock gate addresses see K70 Sub-Family Reference Manual, Rev. 3 pg. 341
+and later. Notice that addresses are zero-based, so SIM_SCGC1 has address 0,
+SIM_SCGC2 has address 1 and so on. The second address component is the bit
+index.
+
+Notice that (non-gate) clock device names must be known to Kinetis CMU drivers.
+
+Currently these are:
+
+o fixed-rate-mcgout (root)
+o fixed-rate-osc0er (root)
+o fixed-rate-cclk (fixed-rate-mcgout child)
+o fixed-rate-pclk (fixed-rate-mcgout child)
+
+Example:
+
+mcg_outclk: fixed-rate-mcgout@40064000 {
+	compatible = "fsl,kinetis-cmu";
+	reg = <0x40064000 0x14>, <0x40047000 0x1100>;
+	#clock-cells = <0>;
+};
+
+mcg_cclk: fixed-rate-cclk@40064000 {
+	compatible = "fsl,kinetis-cmu";
+	reg = <0x40064000 0x14>, <0x40047000 0x1100>;
+	clocks = <&mcg_outclk>;
+	#clock-cells = <0>;
+};
+
+mcg_pclk: fixed-rate-pclk@40064000 {
+	compatible = "fsl,kinetis-cmu";
+	reg = <0x40064000 0x14>, <0x40047000 0x1100>;
+	clocks = <&mcg_outclk>;
+	#clock-cells = <0>;
+};
+
+mcg_cclk_gate: cclk-gate@40047000 {
+	compatible = "fsl,kinetis-cmu";
+	reg = <0x40047000 0x1100>;
+	clocks = <&mcg_cclk>;
+	#clock-cells = <2>;
+};
+
+mcg_pclk_gate: pclk-gate@40047000 {
+	compatible = "fsl,kinetis-cmu";
+	reg = <0x40047000 0x1100>;
+	clocks = <&mcg_pclk>;
+	#clock-cells = <2>;
+};
+
+osc0_erclk: fixed-rate-osc0er@40064000 {
+	compatible = "fsl,kinetis-cmu";
+	reg = <0x40064000 0x14>, <0x40047000 0x1100>;
+	#clock-cells = <0>;
+};
+
+osc0_erclk_gate: osc0-gate@40047000 {
+	compatible = "fsl,kinetis-cmu";
+	reg = <0x40047000 0x1100>;
+	clocks = <&osc0_erclk>;
+	#clock-cells = <2>;
+};
+
+uart1: serial@4006b000 {
+	compatible = "fsl,kinetis-lpuart";
+	reg = <0x4006b000 0x1000>;
+	interrupts = <47>, <48>;
+	interrupt-names = "uart-stat", "uart-err";
+	clocks = <&mcg_cclk_gate 3 11>;
+	clock-names = "ipg";
+	dmas = <&edma 0 4>;
+	dma-names = "rx";
+};
diff --git a/arch/arm/boot/dts/kinetis.dtsi b/arch/arm/boot/dts/kinetis.dtsi
index 93d2a8a..72eb941 100644
--- a

Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-07-02 Thread Paul Osmialowski

Hi Arnd,

On Thu, 2 Jul 2015, Arnd Bergmann wrote:


I wonder if you could move out the fixed rate clocks into their own
nodes. Are they actually controlled by the same block? If they are
just fixed, you can use the normal binding for fixed rate clocks
and only describe the clocks that are related to the driver.

Arnd



In my view having these clocks grouped together looks more convincing. 
After all, they all share the same I/O regs in order to read 
configuration.


Thanks,
Paul
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-07-02 Thread Paul Osmialowski
Nah, I've found this code hard to maintain. I'm attaching simplified 
version.


Thanks,
Paul

On Wed, 1 Jul 2015, Paul Osmialowski wrote:


Hi Arnd,

Can you look at attached candidate for the third iteration? Is it any better 
now?


Thanks,
Paul

On Tue, 30 Jun 2015, Arnd Bergmann wrote:


 On Tuesday 30 June 2015 14:27:24 Paul Osmialowski wrote:
>  Based on K70P256M150SF3RM.pdf K70 Sub-Family Reference Manual, Rev. 3.
> 
>  Signed-off-by: Paul Osmialowski 

>  ---
>   .../devicetree/bindings/clock/kinetis-clock.txt|  63 +++
>   arch/arm/boot/dts/kinetis.dtsi |  36 ++
>   drivers/clk/Makefile   |   1 +
>   drivers/clk/clk-kinetis.c  | 463 
>   +

>   4 files changed, 563 insertions(+)
>   create mode 100644 
>   Documentation/devicetree/bindings/clock/kinetis-clock.txt

>   create mode 100644 drivers/clk/clk-kinetis.c
> 
>  diff --git a/Documentation/devicetree/bindings/clock/kinetis-clock.txt 
>  b/Documentation/devicetree/bindings/clock/kinetis-clock.txt

>  new file mode 100644
>  index 000..63af6a5
>  --- /dev/null
>  +++ b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
>  @@ -0,0 +1,63 @@
>  +* Clock bindings for Freescale Kinetis SoC
>  +
>  +Required properties:
>  +- compatible: Should be "fsl,kinetis-cmu".
>  +- reg: Two address ranges, one for the Clock Genetator register set,
>  + one for System Integration Module register set.
>  +- Set of clock devices: one fixed-rate-root, fixed-rate clocks and 
>  clock-gates.

>  +
>  +For clock-gate addresses see K70 Sub-Family Reference Manual, Rev. 3 
>  pg. 341
>  +and later. Notice that addresses are zero-based, so SIM_SCGC1 has 
>  address 0,
>  +SIM_SCGC2 has address 1 and so on. The second address component is the 
>  bit

>  +index.

 Please document the sub-nodes that are allowed, and the format
 of the clock specifiers.

>  +
>  +Example:
>  +
>  +cmu@40064000 {
>  + compatible = "fsl,kinetis-cmu";
>  + reg = <0x40064000 0x14>, <0x40047000 0x1100>;
>  +
>  + mcg_outclk: fixed-rate-root@mcgout {
>  + device_type = "mcgout";
>  + #clock-cells = <0>;
>  + };
>  +
>  + mcg_cclk: fixed-rate@cclk {

 '@' is a reserved character here that is used before the address
 of the device, so this has to be a hexadecimal number without leading
 '0x', and it should match the 'reg' property of the device.

>  + device_type = "cclk";
>  + #clock-cells = <0>;
>  + clocks = <&mcg_outclk>;
>  + };

 The device_type property here is not a standard identifier,
 and you don't list it as an optional or mandatory property.

 Please remove it and instead use the compatible property, the
 name or the address.

  Arnd

From ae43dcd17eec3eb2c3ad4d7cd514295d935655fe Mon Sep 17 00:00:00 2001
From: Paul Osmialowski 
Date: Mon, 29 Jun 2015 20:58:55 +0200
Subject: [PATCH 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

Based on K70P256M150SF3RM.pdf K70 Sub-Family Reference Manual, Rev. 3.

Signed-off-by: Paul Osmialowski 
---
 .../devicetree/bindings/clock/kinetis-clock.txt|  65 +++
 arch/arm/boot/dts/kinetis.dtsi |  29 ++
 drivers/clk/Makefile   |   1 +
 drivers/clk/clk-kinetis.c  | 475 +
 4 files changed, 570 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/kinetis-clock.txt
 create mode 100644 drivers/clk/clk-kinetis.c

diff --git a/Documentation/devicetree/bindings/clock/kinetis-clock.txt b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
new file mode 100644
index 000..e6c1cfa
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
@@ -0,0 +1,65 @@
+* Clock bindings for Freescale Kinetis SoC
+
+Required properties:
+- compatible: Should be "fsl,kinetis-cmu".
+- reg: Two address ranges, one for the Multipurpose Clock Genetator (MCG)
+	register set, one for System Integration Module (SIM) register set.
+- Set of clock devices (obligatory):
+	- fixed-rate-mcgout
+		Required properties:
+		- #clock-cells: must be <0>.
+	- fixed-rate-cclk
+		Required properties:
+		- #clock-cells: must be <0>.
+	- fixed-rate-pclk
+		Required properties:
+		- #clock-cells: must be <0>.
+	- cclk-gate
+		Required properties:
+		- #clock-cells: must be <2> (see below).
+	- pclk-gate
+		Required properties:
+		- #clock-cells: must be <2> (see below).
+
+For clock gate addresses see K70 Sub-Family Reference Manual, Rev. 3 pg. 341
+and later. Notice that addresses are zero-based, so SIM_SCGC1 has address 0,
+SIM_SCGC2 has address 1 and so on. The second addr

Re: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-07-01 Thread Paul Osmialowski

Hi Arnd,

Can you look at attached candidate for the third iteration? Is it any 
better now?


Thanks,
Paul

On Tue, 30 Jun 2015, Arnd Bergmann wrote:


On Tuesday 30 June 2015 14:27:24 Paul Osmialowski wrote:

Based on K70P256M150SF3RM.pdf K70 Sub-Family Reference Manual, Rev. 3.

Signed-off-by: Paul Osmialowski 
---
 .../devicetree/bindings/clock/kinetis-clock.txt|  63 +++
 arch/arm/boot/dts/kinetis.dtsi |  36 ++
 drivers/clk/Makefile   |   1 +
 drivers/clk/clk-kinetis.c  | 463 +
 4 files changed, 563 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/kinetis-clock.txt
 create mode 100644 drivers/clk/clk-kinetis.c

diff --git a/Documentation/devicetree/bindings/clock/kinetis-clock.txt 
b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
new file mode 100644
index 000..63af6a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
@@ -0,0 +1,63 @@
+* Clock bindings for Freescale Kinetis SoC
+
+Required properties:
+- compatible: Should be "fsl,kinetis-cmu".
+- reg: Two address ranges, one for the Clock Genetator register set,
+   one for System Integration Module register set.
+- Set of clock devices: one fixed-rate-root, fixed-rate clocks and clock-gates.
+
+For clock-gate addresses see K70 Sub-Family Reference Manual, Rev. 3 pg. 341
+and later. Notice that addresses are zero-based, so SIM_SCGC1 has address 0,
+SIM_SCGC2 has address 1 and so on. The second address component is the bit
+index.


Please document the sub-nodes that are allowed, and the format
of the clock specifiers.


+
+Example:
+
+cmu@40064000 {
+   compatible = "fsl,kinetis-cmu";
+   reg = <0x40064000 0x14>, <0x40047000 0x1100>;
+
+   mcg_outclk: fixed-rate-root@mcgout {
+   device_type = "mcgout";
+   #clock-cells = <0>;
+   };
+
+   mcg_cclk: fixed-rate@cclk {


'@' is a reserved character here that is used before the address
of the device, so this has to be a hexadecimal number without leading
'0x', and it should match the 'reg' property of the device.


+   device_type = "cclk";
+   #clock-cells = <0>;
+   clocks = <&mcg_outclk>;
+   };


The device_type property here is not a standard identifier,
and you don't list it as an optional or mandatory property.

Please remove it and instead use the compatible property, the
name or the address.

Arnd
From 22e89bdbea639d8d4daba548927c661f39ff4551 Mon Sep 17 00:00:00 2001
From: Paul Osmialowski 
Date: Mon, 29 Jun 2015 20:58:55 +0200
Subject: [PATCH 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

Based on K70P256M150SF3RM.pdf K70 Sub-Family Reference Manual, Rev. 3.

Signed-off-by: Paul Osmialowski 
---
 .../devicetree/bindings/clock/kinetis-clock.txt|  65 +++
 arch/arm/boot/dts/kinetis.dtsi |  29 ++
 drivers/clk/Makefile   |   1 +
 drivers/clk/clk-kinetis.c  | 486 +
 4 files changed, 581 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/kinetis-clock.txt
 create mode 100644 drivers/clk/clk-kinetis.c

diff --git a/Documentation/devicetree/bindings/clock/kinetis-clock.txt b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
new file mode 100644
index 000..e6c1cfa
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
@@ -0,0 +1,65 @@
+* Clock bindings for Freescale Kinetis SoC
+
+Required properties:
+- compatible: Should be "fsl,kinetis-cmu".
+- reg: Two address ranges, one for the Multipurpose Clock Genetator (MCG)
+	register set, one for System Integration Module (SIM) register set.
+- Set of clock devices (obligatory):
+	- fixed-rate-mcgout
+		Required properties:
+		- #clock-cells: must be <0>.
+	- fixed-rate-cclk
+		Required properties:
+		- #clock-cells: must be <0>.
+	- fixed-rate-pclk
+		Required properties:
+		- #clock-cells: must be <0>.
+	- cclk-gate
+		Required properties:
+		- #clock-cells: must be <2> (see below).
+	- pclk-gate
+		Required properties:
+		- #clock-cells: must be <2> (see below).
+
+For clock gate addresses see K70 Sub-Family Reference Manual, Rev. 3 pg. 341
+and later. Notice that addresses are zero-based, so SIM_SCGC1 has address 0,
+SIM_SCGC2 has address 1 and so on. The second address component is the bit
+index.
+
+Example:
+
+cmu@40064000 {
+	compatible = "fsl,kinetis-cmu";
+	reg = <0x40064000 0x14>, <0x40047000 0x1100>;
+
+	mcg_outclk: fixed-rate-mcgout {
+		#clock-cells = <0>;
+	};
+
+	mcg_cclk: fixed-rate-cclk {
+		#clock-cells = <0>;
+	};
+
+	mcg_pclk: fixed-rate-pclk {
+		#clock-cells = <0>;
+	};
+
+	mcg_cclk_gate: cclk-gate {
+		#clock-cells = <2>;
+	};

Re: [PATCH v2 4/9] arm: twr-k70f120m: timer driver for Kinetis SoC

2015-07-01 Thread Paul Osmialowski



On Wed, 1 Jul 2015, Thomas Gleixner wrote:



As I removed this kinetis_pit_enable() line, the timer did not start,
therefore the system became unusable. What could be possible reason for that?


Well, you need to move both, the init and the enable into
set_periodic().



Indeed, something like this worked:

diff --git a/drivers/clocksource/timer-kinetis.c 
b/drivers/clocksource/timer-kinetis.c

index 1424308..41ef94f 100644
--- a/drivers/clocksource/timer-kinetis.c
+++ b/drivers/clocksource/timer-kinetis.c
@@ -61,6 +61,7 @@ struct kinetis_clock_event_ddata {
struct clock_event_device evtdev;
void __iomem *base;
void __iomem *mcr;
+   unsigned long rate;
spinlock_t lock;
 };

@@ -115,6 +116,7 @@ static int kinetis_clockevent_tmr_set_state_periodic(
struct kinetis_clock_event_ddata *pit =
container_of(evt, struct kinetis_clock_event_ddata, 
evtdev);


+   kinetis_pit_init(pit, (pit->rate / HZ) - 1);
kinetis_pit_enable(pit, 1);

return 0;
@@ -235,6 +237,7 @@ static void __init kinetis_clockevent_init(struct 
device_node *np)

kinetis_clockevent_tmr_set_state_oneshot;
kinetis_tmr->base = base;
kinetis_tmr->mcr = mcr;
+   kinetis_tmr->rate = rate;
spin_lock_init(&kinetis_tmr->lock);

/*
@@ -250,9 +253,6 @@ static void __init kinetis_clockevent_init(struct 
device_node *np)


clockevents_register_device(&kinetis_tmr->evtdev);

-   kinetis_pit_init(kinetis_tmr, (rate / HZ) - 1);
-   kinetis_pit_enable(kinetis_tmr, 1);
-
if (request_irq(irq, kinetis_clockevent_tmr_irq_handler,
IRQF_TIMER | IRQF_IRQPOLL,
"kinetis-timer",

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 4/9] arm: twr-k70f120m: timer driver for Kinetis SoC

2015-07-01 Thread Paul Osmialowski

Hi Arnd,

Again, thanks for your remarks. I'm attaching timer patch candidate for 
the third iteration.


Following your advices, I've changed following things:

- not abusing aliases (same goes to pinctrl driver)
- ranges for addressing particular timers (no change in code though, it's
  just up to the .dts implementor)
- *_RD and *_WR macros removed; whole this big-endian issue was a mistake,
  I guess I overdid it a bit trying to make my drivers as universal as
  fsl-edma driver...
- *_SET and *_RESET macros removed - they were giving false sense of
  security hiding potential race.

Any comments are welcome.

On Tue, 30 Jun 2015, Arnd Bergmann wrote:


On Tuesday 30 June 2015 14:27:25 Paul Osmialowski wrote:


+Example:
+
+aliases {
+   pit0 = &pit0;
+   pit1 = &pit1;
+   pit2 = &pit2;
+   pit3 = &pit3;
+};
+
+pit@40037000 {
+   compatible = "fsl,kinetis-pit-timer";
+   reg = <0x40037000 0x100>;
+   clocks = <&mcg_pclk_gate 5 23>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;


All the subnodes seem to fall inside of the device's own register
area, so I think it would be nicer to use a specific 'ranges'
property that only translates the registers in question.


 / {
+   aliases {
+   pit0 = &pit0;
+   pit1 = &pit1;
+   pit2 = &pit2;
+   pit3 = &pit3;
+   };
+
soc {
+   pit@40037000 {
+   compatible = "fsl,kinetis-pit-timer";
+   reg = <0x40037000 0x100>;
+   clocks = <&mcg_pclk_gate 5 23>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   pit0: timer@40037100 {
+   reg = <0x40037100 0x10>;
+   interrupts = <68>;
+   status = "disabled";
+   };


I don't think it's necessary to have both an alias
and a label here. What do you use the alias for?


+
+#define KINETIS_PITMCR_PTR(base, reg) \
+   (&(((struct kinetis_pit_mcr_regs *)(base))->reg))
+#define KINETIS_PITMCR_RD(be, base, reg) \
+   ((be) ? ioread32be(KINETIS_PITMCR_PTR(base, reg)) \
+ : ioread32(KINETIS_PITMCR_PTR(base, reg)))
+#define KINETIS_PITMCR_WR(be, base, reg, val) do { \
+   if (be) \
+   iowrite32be((val), KINETIS_PITMCR_PTR(base, reg)); \
+   else \
+   iowrite32((val), KINETIS_PITMCR_PTR(base, reg)); \
+   } while (0)


These should really be written as inline functions. Can you
explain why you need to deal with a big-endian version of this
hardware? Can you configure the endianess of this register block
and just set it to one of the two at boot time?


+#define KINETIS_PIT_PTR(base, reg) \
+   (&(((struct kinetis_pit_channel_regs *)(base))->reg))
+#define KINETIS_PIT_RD(be, base, reg) \
+   ((be) ? ioread32be(KINETIS_PIT_PTR(base, reg)) \
+ : ioread32(KINETIS_PIT_PTR(base, reg)))
+#define KINETIS_PIT_WR(be, base, reg, val) do { \
+   if (be) \
+   iowrite32be((val), KINETIS_PIT_PTR(base, reg)); \
+   else \
+   iowrite32((val), KINETIS_PIT_PTR(base, reg)); \
+   } while (0)
+#define KINETIS_PIT_SET(be, base, reg, mask) \
+   KINETIS_PIT_WR(be, base, reg, \
+   KINETIS_PIT_RD(be, base, reg) | (mask))
+#define KINETIS_PIT_RESET(be, base, reg, mask) \
+   KINETIS_PIT_WR(be, base, reg, \
+   KINETIS_PIT_RD(be, base, reg) & (~(mask)))



Functions again. Also, just pass a pointer to your own data structure
into the function, instead of the 'be' and 'base' values.

The 'set' and 'reset' functions look like they need a spinlock
to avoid races.

Arnd
From 562decc41dc7302c378bf6e4509a22561ff5a85e Mon Sep 17 00:00:00 2001
From: Paul Osmialowski 
Date: Mon, 29 Jun 2015 21:32:41 +0200
Subject: [PATCH 4/9] arm: twr-k70f120m: timer driver for Kinetis SoC

Based on legacy pre-OF code by Alexander Potashev 

Signed-off-by: Paul Osmialowski 
---
 .../bindings/timer/fsl,kinetis-pit-timer.txt   |  43 
 arch/arm/Kconfig   |   1 +
 arch/arm/boot/dts/kinetis-twr-k70f120m.dts |   4 +
 arch/arm/boot/dts/kinetis.dtsi |  33 +++
 drivers/clocksource/Kconfig|   5 +
 drivers/clocksource/Makefile   |   1 +
 drivers/clocksource/timer-kinetis.c| 280 +
 7 files changed, 367 insertions(+)
 create mode 100644 Documentation/devicetree/bi

Re: [PATCH v2 4/9] arm: twr-k70f120m: timer driver for Kinetis SoC

2015-07-01 Thread Paul Osmialowski

Hi Thomas,

On Wed, 1 Jul 2015, Thomas Gleixner wrote:


+   clockevents_register_device(
+   &kinetis_clockevent_tmrs[chan].evtdev);
+
+   kinetis_pit_init(&kinetis_clockevent_tmrs[chan],
+   (rate / HZ) - 1);
+   kinetis_pit_enable(&kinetis_clockevent_tmrs[chan], 1);


No point doing this. The core code has invoked the set_periodic call
back via clockevents_register_device() already.



As I removed this kinetis_pit_enable() line, the timer did not start, 
therefore the system became unusable. What could be possible reason for 
that?

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 7/9] arm: twr-k70f120m: use Freescale eDMA driver with Kinetis SoC

2015-06-30 Thread Paul Osmialowski

Hi Arnd,

Thanks for pointing this - dma-ranges seem to work properly. This makes 
the patch much simpler. To be included to the next iteration.


I also removed DMA_OF from Kconfig and CONFIG_DMA_OF from my defconfig and 
it was automatically added during preparation of .cofing for build.


On Tue, 30 Jun 2015, Arnd Bergmann wrote:


On Tuesday 30 June 2015 14:27:28 Paul Osmialowski wrote:

Note that  is needed (which is denoted by
CONFIG_NEED_MACH_MEMORY_H) as it provides macros required for proper
operation of DMA allocation functions.


You can't do this, it breaks compilation when multiple platforms
are enabled.


Signed-off-by: Paul Osmialowski 
---
 arch/arm/Kconfig|  4 ++
 arch/arm/boot/dts/kinetis.dtsi  | 34 
 arch/arm/mach-kinetis/include/mach/memory.h | 61 +
 3 files changed, 99 insertions(+)
 create mode 100644 arch/arm/mach-kinetis/include/mach/memory.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b21592b..8ccffee 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -971,6 +971,10 @@ config ARCH_KINETIS
select CLKSRC_KINETIS
select PINCTRL
select PINCTRL_KINETIS
+   select DMADEVICES
+   select FSL_EDMA
+   select DMA_OF
+   select NEED_MACH_MEMORY_H


I think DMA_OF is implied by dmaengine support in combination with CONFIG_OF


+
+#ifndef _MACH_KINETIS_MEMORY_H
+#define _MACH_KINETIS_MEMORY_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * On Kinetis K70, consistent DMA memory resides in a special
+ * DDRAM alias region (non-cacheable DDRAM at 0x8000).
+ *
+ */
+#define KINETIS_PHYS_DMA_OFFSET UL(0x8000)
+
+/*
+ * Mask of the field used to distinguish DDRAM aliases
+ */
+#define KINETIS_DRAM_ALIAS_MASK UL(0xf800)


This should be expressed using the 'dma-ranges' properties in the
bus nodes above any DMA master, the normal DMA mapping code will
then do the right thing.

Arnd
From e0b549151b3ee8d4419344a2b5ef461bad19b2af Mon Sep 17 00:00:00 2001
From: Paul Osmialowski 
Date: Mon, 29 Jun 2015 23:37:20 +0200
Subject: [PATCH 7/9] arm: twr-k70f120m: use Freescale eDMA driver with Kinetis
 SoC

Signed-off-by: Paul Osmialowski 
---
 arch/arm/Kconfig   |  2 ++
 arch/arm/boot/dts/kinetis.dtsi | 36 
 2 files changed, 38 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b21592b..81a6328 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -971,6 +971,8 @@ config ARCH_KINETIS
 	select CLKSRC_KINETIS
 	select PINCTRL
 	select PINCTRL_KINETIS
+	select DMADEVICES
+	select FSL_EDMA
 	help
 	  This enables support for the Freescale Kinetis MCUs
 
diff --git a/arch/arm/boot/dts/kinetis.dtsi b/arch/arm/boot/dts/kinetis.dtsi
index 5ff1d3b..75fc6d4 100644
--- a/arch/arm/boot/dts/kinetis.dtsi
+++ b/arch/arm/boot/dts/kinetis.dtsi
@@ -19,6 +19,42 @@
 	};
 
 	soc {
+		dma-ranges = <0x8000 0x 0x0800>;
+
+		edma: dma-controller@40008000 {
+			compatible = "fsl,kinetis-edma";
+			reg = <0x40008000 0x2000>, /* DMAC */
+<0x40021000 0x1000>, /* DMAMUX0 */
+<0x40022000 0x1000>; /* DMAMUX1 */
+			#dma-cells = <2>;
+			dma-channels = <32>;
+			interrupts =	 <0>,  <1>,  <2>,  <3>,
+	 <4>,  <5>,  <6>,  <7>,
+	 <8>,  <9>, <10>, <11>,
+	<12>, <13>, <14>, <15>,
+	<16>;
+			interrupt-names = "edma-tx-0,16",
+	  "edma-tx-1,17",
+	  "edma-tx-2,18",
+	  "edma-tx-3,19",
+	  "edma-tx-4,20",
+	  "edma-tx-5,21",
+	  "edma-tx-6,22",
+	  "edma-tx-7,23",
+	  "edma-tx-8,24",
+	  "edma-tx-9,25",
+	  "edma-tx-10,26",
+	  "edma-tx-11,27",
+	  "edma-tx-12,28",
+	  "edma-tx-13,29",
+	  "edma-tx-14,30",
+	  "edma-tx-15,31",
+	  "edma-err";
+			clocks = <&mcg_cclk_gate 6 1>,
+ <&mcg_pclk_gate 5 1>, <&mcg_pclk_gate 5 2>;
+			clock-names = "edma", "dmamux0", "dmamux1";
+		};
+
 		portA: pinmux@40049000 {
 			compatible = "fsl,kinetis-padconf";
 			reg = <0x40049000 0x1000>;
-- 
2.3.6



[PATCH v2 7/9] arm: twr-k70f120m: use Freescale eDMA driver with Kinetis SoC

2015-06-30 Thread Paul Osmialowski
Note that  is needed (which is denoted by
CONFIG_NEED_MACH_MEMORY_H) as it provides macros required for proper
operation of DMA allocation functions.

Signed-off-by: Paul Osmialowski 
---
 arch/arm/Kconfig|  4 ++
 arch/arm/boot/dts/kinetis.dtsi  | 34 
 arch/arm/mach-kinetis/include/mach/memory.h | 61 +
 3 files changed, 99 insertions(+)
 create mode 100644 arch/arm/mach-kinetis/include/mach/memory.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b21592b..8ccffee 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -971,6 +971,10 @@ config ARCH_KINETIS
select CLKSRC_KINETIS
select PINCTRL
select PINCTRL_KINETIS
+   select DMADEVICES
+   select FSL_EDMA
+   select DMA_OF
+   select NEED_MACH_MEMORY_H
help
  This enables support for the Freescale Kinetis MCUs
 
diff --git a/arch/arm/boot/dts/kinetis.dtsi b/arch/arm/boot/dts/kinetis.dtsi
index 5ff1d3b..c2861f5 100644
--- a/arch/arm/boot/dts/kinetis.dtsi
+++ b/arch/arm/boot/dts/kinetis.dtsi
@@ -19,6 +19,40 @@
};
 
soc {
+   edma: dma-controller@40008000 {
+   compatible = "fsl,kinetis-edma";
+   reg = <0x40008000 0x2000>, /* DMAC */
+   <0x40021000 0x1000>, /* DMAMUX0 */
+   <0x40022000 0x1000>; /* DMAMUX1 */
+   #dma-cells = <2>;
+   dma-channels = <32>;
+   interrupts = <0>,  <1>,  <2>,  <3>,
+<4>,  <5>,  <6>,  <7>,
+<8>,  <9>, <10>, <11>,
+   <12>, <13>, <14>, <15>,
+   <16>;
+   interrupt-names = "edma-tx-0,16",
+ "edma-tx-1,17",
+ "edma-tx-2,18",
+ "edma-tx-3,19",
+ "edma-tx-4,20",
+ "edma-tx-5,21",
+ "edma-tx-6,22",
+ "edma-tx-7,23",
+ "edma-tx-8,24",
+ "edma-tx-9,25",
+ "edma-tx-10,26",
+ "edma-tx-11,27",
+ "edma-tx-12,28",
+ "edma-tx-13,29",
+ "edma-tx-14,30",
+ "edma-tx-15,31",
+ "edma-err";
+   clocks = <&mcg_cclk_gate 6 1>,
+<&mcg_pclk_gate 5 1>, <&mcg_pclk_gate 5 2>;
+   clock-names = "edma", "dmamux0", "dmamux1";
+   };
+
portA: pinmux@40049000 {
compatible = "fsl,kinetis-padconf";
reg = <0x40049000 0x1000>;
diff --git a/arch/arm/mach-kinetis/include/mach/memory.h 
b/arch/arm/mach-kinetis/include/mach/memory.h
new file mode 100644
index 000..8bad034
--- /dev/null
+++ b/arch/arm/mach-kinetis/include/mach/memory.h
@@ -0,0 +1,61 @@
+/*
+ * Based on original code by Alexander Potashev 
+ *
+ * (C) Copyright 2011, 2012
+ * Emcraft Systems, 
+ * Alexander Potashev 
+ *
+ * Copyright (C) 2015 Paul Osmialowski 
+ *
+ * This program is free software; you can redistribute it and/or modify it 
under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#ifndef _MACH_KINETIS_MEMORY_H
+#define _MACH_KINETIS_MEMORY_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * On Kinetis K70, consistent DMA memory resides in a special
+ * DDRAM alias region (non-cacheable DDRAM at 0x8000).
+ *
+ */
+#define KINETIS_PHYS_DMA_OFFSET UL(0x8000)
+
+/*
+ * Mask of the field used to distinguish DDRAM aliases
+ */
+#define KINETIS_DRAM_ALIAS_MASK UL(0xf800)
+
+/*
+ * This macro converts an address in the kernel run-time memory
+ * to an alias in the non-cacheable memory region
+ */
+#define KINETIS_DMA_ALIAS_ADDR(addr)   \
+   (((unsigned long)(addr) & ~KINETIS_DRAM_ALIAS_MASK) |   \
+   (KINETIS_PHYS_DMA_OFFSET & KINETIS_DRAM_ALIAS_MASK))
+
+/*
+ * This macro converts an address in the kerne

[PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC

2015-06-30 Thread Paul Osmialowski
Based on K70P256M150SF3RM.pdf K70 Sub-Family Reference Manual, Rev. 3.

Signed-off-by: Paul Osmialowski 
---
 .../devicetree/bindings/clock/kinetis-clock.txt|  63 +++
 arch/arm/boot/dts/kinetis.dtsi |  36 ++
 drivers/clk/Makefile   |   1 +
 drivers/clk/clk-kinetis.c  | 463 +
 4 files changed, 563 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/kinetis-clock.txt
 create mode 100644 drivers/clk/clk-kinetis.c

diff --git a/Documentation/devicetree/bindings/clock/kinetis-clock.txt 
b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
new file mode 100644
index 000..63af6a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/kinetis-clock.txt
@@ -0,0 +1,63 @@
+* Clock bindings for Freescale Kinetis SoC
+
+Required properties:
+- compatible: Should be "fsl,kinetis-cmu".
+- reg: Two address ranges, one for the Clock Genetator register set,
+   one for System Integration Module register set.
+- Set of clock devices: one fixed-rate-root, fixed-rate clocks and clock-gates.
+
+For clock-gate addresses see K70 Sub-Family Reference Manual, Rev. 3 pg. 341
+and later. Notice that addresses are zero-based, so SIM_SCGC1 has address 0,
+SIM_SCGC2 has address 1 and so on. The second address component is the bit
+index.
+
+Example:
+
+cmu@40064000 {
+   compatible = "fsl,kinetis-cmu";
+   reg = <0x40064000 0x14>, <0x40047000 0x1100>;
+
+   mcg_outclk: fixed-rate-root@mcgout {
+   device_type = "mcgout";
+   #clock-cells = <0>;
+   };
+
+   mcg_cclk: fixed-rate@cclk {
+   device_type = "cclk";
+   #clock-cells = <0>;
+   clocks = <&mcg_outclk>;
+   };
+
+   mcg_pclk: fixed-rate@pclk {
+   device_type = "pclk";
+   #clock-cells = <0>;
+   clocks = <&mcg_outclk>;
+   };
+
+   mcg_cclk_gate: clock-gate@cclk {
+   #clock-cells = <2>;
+   clocks = <&mcg_cclk>;
+   };
+
+   mcg_pclk_gate: clock-gate@pclk {
+   #clock-cells = <2>;
+   clocks = <&mcg_pclk>;
+   };
+};
+
+mcg: cmu@40064000 {
+   compatible = "fsl,kinetis-cmu";
+   reg = <0x40064000 0x14>;
+   #clock-cells = <1>;
+};
+
+uart1: serial@4006b000 {
+   compatible = "fsl,kinetis-lpuart";
+   reg = <0x4006b000 0x1000>;
+   interrupts = <47>, <48>;
+   interrupt-names = "uart-stat", "uart-err";
+   clocks = <&mcg_cclk_gate 3 11>;
+   clock-names = "ipg";
+   dmas = <&edma 0 4>;
+   dma-names = "rx";
+};
diff --git a/arch/arm/boot/dts/kinetis.dtsi b/arch/arm/boot/dts/kinetis.dtsi
index 93d2a8a..ae0cf00 100644
--- a/arch/arm/boot/dts/kinetis.dtsi
+++ b/arch/arm/boot/dts/kinetis.dtsi
@@ -3,3 +3,39 @@
  *
  */
 #include "armv7-m.dtsi"
+
+/ {
+   soc {
+   cmu@40064000 {
+   compatible = "fsl,kinetis-cmu";
+   reg = <0x40064000 0x14>, <0x40047000 0x1100>;
+
+   mcg_outclk: fixed-rate-root@mcgout {
+   device_type = "mcgout";
+   #clock-cells = <0>;
+   };
+
+   mcg_cclk: fixed-rate@cclk {
+   device_type = "cclk";
+   #clock-cells = <0>;
+   clocks = <&mcg_outclk>;
+   };
+
+   mcg_pclk: fixed-rate@pclk {
+   device_type = "pclk";
+   #clock-cells = <0>;
+   clocks = <&mcg_outclk>;
+   };
+
+   mcg_cclk_gate: clock-gate@cclk {
+   #clock-cells = <2>;
+   clocks = <&mcg_cclk>;
+   };
+
+   mcg_pclk_gate: clock-gate@pclk {
+   #clock-cells = <2>;
+   clocks = <&mcg_pclk>;
+   };
+   };
+   };
+};
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 63418cf..412d76b 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE706)  += clk-cdce706.o
 obj-$(CONFIG_ARCH_CLPS711X)+= clk-clps711x.o
 obj-$(CONFIG_ARCH_EFM32)   += clk-efm32gg.o
 obj-$(CONFIG_ARCH_HIGHBANK)+= clk-highbank.o
+obj-$(CONFIG_ARCH_KINETIS) += clk-kinetis.o
 obj-$(CON

[PATCH v2 0/9] [New BSP] Add initial support for Freescale Kinetis TWR-K70F120M development kit

2015-06-30 Thread Paul Osmialowski
This is the second iteration of the patchset that adds a basic initial
support to TWR-K70F120M development kit which is based on ARM Cortex-M4
Freescale Kinetis K70 SoC.

Previous iteration met with a broad response for which I would like
to thank everyone involved.

Following is the change list:

1. First three ('controversial') patches are removed.

   As long as it doesn't hit platform stability, I don't use these Cortex-M
   compiler flags, it should not stop the whole of the patchset.

   The idle quirks issue is now addressed by adding idle.c which provides
   callback for arm_pm_idle.

   The infamous zlib patch was not needed at all - I didn't really check
   what it was protecting against.

2. include/mach/idle.h file removed.

3. kinetis_platform.c renamed to kinetis.c, obj-$(CONFIG_MACH_KINETIS)
   changed to obj-y, CONFIG_MACH_KINETIS not needed anymore, removed with
   the whole of the Kconfig file in mach-kinetis directory.

4. Assuming that fsl-edma and fsl-lpuart drivers handle big-endian properly,
   pinctrl, clk and timer drivers now support big-endian the same way
   ("big-endian" option in .dts).

5. All addresses based on KINETIS_AIPS0PERIPH_BASE and
   KINETIS_AIPS1PERIPH_BASE are moved to DT. The struct kinetis_sim_regs
   is moved to clk-kinetis.c. As a result whole include/mach/kinetis.h is
   now removed.

6. Removed kinetis_map_io() from kinetis.c (formerly kinetis_platform.c).

7. Removed kinetis_init() function along with a call to
   of_platform_populate().

8. Removed MACH_KINETIS from arch/arm/tools/mach-types, removed inclusion
   of asm/mach-types.h in kinetis.c (formerly kinetis_platform.c).

9. Removed inclusion of linux/clk.h from clk-kinetis.c.

10. Clock and timer drivers are in separate patches now.

11. '&& ARM' removed from drivers/clocksource/Kconfig.

12. s/clk/evt/ in timer-kinetis.c (actually, the affected *_set_mode()
function is replaced by a set of *_set_state_*() functions).

13. Removed pointless raw_local_irq_save/restore() from timer-kinetis.c.

14. Removed overhead () from each of the &(.) from timer-kinetis.c.

15. Removed unused KINETIS_PITn_IRQ definitions from timer-kinetis.c.

16. Replaced use of IRQ actions with request_irq() in timer-kinetis.c.

17. Removed all uses of KINETIS_MKCG() macro and whole include/mach/power.h
- now all clock gate details are specified directly in the DT.
For each clock gate #clock-cells = <2> where the first part of the gate
address is zero-based gate register number, the second part is the bit
index.

18. Shortened long timer names in timer-kinetis.c.

19. Ensured module friendliness of pinctrl driver (tristate
CONFIG_PINCTRL_KINETIS)

20. Removed txirq_names[] array from fsl-edma.c - sprinft()-generated
strings used instead.

21. fsl-lpuart and fsl-edma related patches are both split into two:
1) changes in the driver and 2) use in platform.

22. Removed all occurences of CONFIG_ARCH_KINETIS from fsl-edma.c - now it
looks more like fsl-lpuart driver (boolean 'kinetis' field in the main
driver structure).

Paul Osmialowski (9):
  arm: allow copying of vector table to internal SRAM memory
  arm: twr-k70f120m: basic support for Kinetis TWR-K70F120M
  arm: twr-k70f120m: clock driver for Kinetis SoC
  arm: twr-k70f120m: timer driver for Kinetis SoC
  arm: twr-k70f120m: IOMUX driver for Kinetis SoC
  arm: twr-k70f120m: extend Freescale eDMA driver with the ability to
support Kinetis SoC
  arm: twr-k70f120m: use Freescale eDMA driver with Kinetis SoC
  arm: twr-k70f120m: extend Freescale lpuart driver with ability to
support Kinetis SoC
  arm: twr-k70f120m: use Freescale lpuart driver with Kinetis SoC

 Documentation/devicetree/bindings/arm/fsl.txt  |   6 +
 .../devicetree/bindings/clock/kinetis-clock.txt|  63 +++
 Documentation/devicetree/bindings/dma/fsl-edma.txt |  38 +-
 .../bindings/pinctrl/fsl,kinetis-pinctrl.txt   |  31 ++
 .../devicetree/bindings/serial/fsl-lpuart.txt  |   6 +-
 .../bindings/timer/fsl,kinetis-pit-timer.txt   |  50 ++
 arch/arm/Kconfig   |  16 +-
 arch/arm/Kconfig-nommu |  12 +
 arch/arm/Makefile  |   1 +
 arch/arm/boot/dts/kinetis-twr-k70f120m.dts |  43 ++
 arch/arm/boot/dts/kinetis.dtsi | 241 +
 arch/arm/kernel/entry-v7m.S|   3 +
 arch/arm/mach-kinetis/Makefile |   5 +
 arch/arm/mach-kinetis/Makefile.boot|   3 +
 arch/arm/mach-kinetis/idle.c   |  27 +
 arch/arm/mach-kinetis/include/mach/memory.h|  61 +++
 arch/arm/mach-kinetis/kinetis.c|  34 ++
 arch/arm/mm/Kconfig|   1 +
 arch/arm/mm/proc-v7m.S |  11 +
 drivers/clk/Makefile   

[PATCH v2 5/9] arm: twr-k70f120m: IOMUX driver for Kinetis SoC

2015-06-30 Thread Paul Osmialowski
This is a very cheap and simple implementation of pinctrl driver
for Kinetis SoC - its primary role is to provide means for enabling UART
fuctionality on I/O PORT_E which will be utilized by the commits
yet to come.

Signed-off-by: Paul Osmialowski 
---
 .../bindings/pinctrl/fsl,kinetis-pinctrl.txt   |  31 ++
 arch/arm/Kconfig   |   2 +
 arch/arm/boot/dts/kinetis.dtsi |  48 ++
 drivers/pinctrl/freescale/Kconfig  |   8 +
 drivers/pinctrl/freescale/Makefile |   1 +
 drivers/pinctrl/freescale/pinctrl-kinetis.c| 541 +
 6 files changed, 631 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/fsl,kinetis-pinctrl.txt
 create mode 100644 drivers/pinctrl/freescale/pinctrl-kinetis.c

diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,kinetis-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/fsl,kinetis-pinctrl.txt
new file mode 100644
index 000..a351ce4
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,kinetis-pinctrl.txt
@@ -0,0 +1,31 @@
+Freescale Kinetis IOMUX Controller
+
+This controller is largely based on i.MX IOMUX Controller. Please refer to
+fsl,imx-pinctrl.txt in this directory for more detailed description.
+
+Required properties:
+- compatible: Should be "fsl,kinetis-iomuxc".
+- reg: Should contain the physical address and length of the gpio/pinmux
+  register range.
+- clocks: Clock that drives this I/O port.
+- fsl,pins: Two integers array, represents a group of pins mux and config
+  setting. The format is fsl,pins = , PIN_FUNC_ID is
+  a pin working on a specific function, CONFIG is the pad setting value
+  such as pull enable, pull select, drive strength enable. Please refer to
+  Kinetis datasheet for the valid pad config settings.
+
+Example:
+
+portE: pinmux@4004d000 {
+   compatible = "fsl,kinetis-padconf";
+   reg = <0x4004d000 0x1000>;
+   clocks = <&mcg_pclk_gate 4 13>;
+   uart2 {
+   uart2_pins: pinmux_uart2_pins {
+   fsl,pins = <
+   16  0x300 /* E.16 = UART2_TX */
+   17  0x300 /* E.17 = UART2_RX */
+   >;
+   };
+   };
+};
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 96ddaae..b21592b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -969,6 +969,8 @@ config ARCH_KINETIS
depends on ARM_SINGLE_ARMV7M
select ARMV7M_SYSTICK
select CLKSRC_KINETIS
+   select PINCTRL
+   select PINCTRL_KINETIS
help
  This enables support for the Freescale Kinetis MCUs
 
diff --git a/arch/arm/boot/dts/kinetis.dtsi b/arch/arm/boot/dts/kinetis.dtsi
index 0c572a5..5ff1d3b 100644
--- a/arch/arm/boot/dts/kinetis.dtsi
+++ b/arch/arm/boot/dts/kinetis.dtsi
@@ -10,9 +10,57 @@
pit1 = &pit1;
pit2 = &pit2;
pit3 = &pit3;
+   pmx0 = &portA;
+   pmx1 = &portB;
+   pmx2 = &portC;
+   pmx3 = &portD;
+   pmx4 = &portE;
+   pmx5 = &portF;
};
 
soc {
+   portA: pinmux@40049000 {
+   compatible = "fsl,kinetis-padconf";
+   reg = <0x40049000 0x1000>;
+   clocks = <&mcg_pclk_gate 4 9>;
+   status = "disabled";
+   };
+
+   portB: pinmux@4004a000 {
+   compatible = "fsl,kinetis-padconf";
+   reg = <0x4004a000 0x1000>;
+   clocks = <&mcg_pclk_gate 4 10>;
+   status = "disabled";
+   };
+
+   portC: pinmux@4004b000 {
+   compatible = "fsl,kinetis-padconf";
+   reg = <0x4004b000 0x1000>;
+   clocks = <&mcg_pclk_gate 4 11>;
+   status = "disabled";
+   };
+
+   portD: pinmux@4004c000 {
+   compatible = "fsl,kinetis-padconf";
+   reg = <0x4004c000 0x1000>;
+   clocks = <&mcg_pclk_gate 4 12>;
+   status = "disabled";
+   };
+
+   portE: pinmux@4004d000 {
+   compatible = "fsl,kinetis-padconf";
+   reg = <0x4004d000 0x1000>;
+   clocks = <&mcg_pclk_gate 4 13>;
+   status = "disabled";
+   };
+
+   portF: pinmux@4004e000 {
+   compatible = "fsl,kinetis-padconf";
+   reg = <0x4004e000 0x1000>;
+  

[PATCH v2 6/9] arm: twr-k70f120m: extend Freescale eDMA driver with the ability to support Kinetis SoC

2015-06-30 Thread Paul Osmialowski
Surprisingly small amount of work was required in order to extend already
existing eDMA driver with the support for Kinetis SoC architecture.

Signed-off-by: Paul Osmialowski 
---
 Documentation/devicetree/bindings/dma/fsl-edma.txt |  38 ++-
 drivers/dma/fsl-edma.c | 114 -
 2 files changed, 125 insertions(+), 27 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/fsl-edma.txt 
b/Documentation/devicetree/bindings/dma/fsl-edma.txt
index 191d7bd..88c3e20 100644
--- a/Documentation/devicetree/bindings/dma/fsl-edma.txt
+++ b/Documentation/devicetree/bindings/dma/fsl-edma.txt
@@ -9,6 +9,7 @@ group, DMAMUX0 or DMAMUX1, but not both.
 Required properties:
 - compatible :
- "fsl,vf610-edma" for eDMA used similar to that on Vybrid vf610 SoC
+   - "fsl,kinetis-edma" for eDMA used similar to that on Kinetis SoC
 - reg : Specifies base physical address(s) and size of the eDMA registers.
The 1st region is eDMA control register's address and size.
The 2nd and the 3rd regions are programmable channel multiplexing
@@ -16,7 +17,8 @@ Required properties:
 - interrupts : A list of interrupt-specifiers, one for each entry in
interrupt-names.
 - interrupt-names : Should contain:
-   "edma-tx" - the transmission interrupt
+   "edma-tx" - the transmission interrupt (Vybrid)
+   "edma-tx-n,m" - interrupt for channels n (0-15) and m (16-31) (Kinetis)
"edma-err" - the error interrupt
 - #dma-cells : Must be <2>.
The 1st cell specifies the DMAMUX(0 for DMAMUX0 and 1 for DMAMUX1).
@@ -28,6 +30,7 @@ Required properties:
 - clock-names : A list of channel group clock names. Should contain:
"dmamux0" - clock name of mux0 group
"dmamux1" - clock name of mux1 group
+   "edma"- clock gate for whole controller (Kinetis only)
 - clocks : A list of phandle and clock-specifier pairs, one for each entry in
clock-names.
 
@@ -54,6 +57,39 @@ edma0: dma-controller@40018000 {
<&clks VF610_CLK_DMAMUX1>;
 };
 
+edma: dma-controller@40008000 {
+   compatible = "fsl,kinetis-edma";
+   reg = <0x40008000 0x2000>, /* DMAC */
+   <0x40021000 0x1000>, /* DMAMUX0 */
+   <0x40022000 0x1000>; /* DMAMUX1 */
+   #dma-cells = <2>;
+   dma-channels = <32>;
+   interrupts = <0>,  <1>,  <2>,  <3>,
+<4>,  <5>,  <6>,  <7>,
+<8>,  <9>, <10>, <11>,
+   <12>, <13>, <14>, <15>,
+   <16>;
+   interrupt-names = "edma-tx-0,16",
+ "edma-tx-1,17",
+ "edma-tx-2,18",
+ "edma-tx-3,19",
+ "edma-tx-4,20",
+ "edma-tx-5,21",
+ "edma-tx-6,22",
+ "edma-tx-7,23",
+ "edma-tx-8,24",
+ "edma-tx-9,25",
+ "edma-tx-10,26",
+ "edma-tx-11,27",
+ "edma-tx-12,28",
+ "edma-tx-13,29",
+ "edma-tx-14,30",
+ "edma-tx-15,31",
+ "edma-err";
+   clocks = <&mcg_cclk_gate 6 1>,
+<&mcg_pclk_gate 5 1>, <&mcg_pclk_gate 5 2>;
+   clock-names = "edma", "dmamux0", "dmamux1";
+};
 
 * DMA clients
 DMA client drivers that uses the DMA function must use the format described
diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c
index 915eec3..e41a3b9 100644
--- a/drivers/dma/fsl-edma.c
+++ b/drivers/dma/fsl-edma.c
@@ -164,13 +164,13 @@ struct fsl_edma_desc {
 struct fsl_edma_engine {
struct dma_device   dma_dev;
void __iomem*membase;
+   struct clk  *clk;
void __iomem*muxbase[DMAMUX_NR];
struct clk  *muxclk[DMAMUX_NR];
struct mutexfsl_edma_mutex;
u32 n_chans;
-   int txirq;
-   int errirq;
boolbig_endian;
+   boolkinetis;
struct fsl_edma_chanchans[];
 };
 
@@ -788,42 +788,85 @@ static void fsl_edma_free_chan_resources(struct dma_chan 
*chan)
 }
 
 static int
-fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine 
*fsl_edma)
+fsl_edma_irq_init(struct platform_devi

[PATCH v2 4/9] arm: twr-k70f120m: timer driver for Kinetis SoC

2015-06-30 Thread Paul Osmialowski
Based on legacy pre-OF code by Alexander Potashev 

Signed-off-by: Paul Osmialowski 
---
 .../bindings/timer/fsl,kinetis-pit-timer.txt   |  50 
 arch/arm/Kconfig   |   1 +
 arch/arm/boot/dts/kinetis-twr-k70f120m.dts |   4 +
 arch/arm/boot/dts/kinetis.dtsi |  40 +++
 drivers/clocksource/Kconfig|   5 +
 drivers/clocksource/Makefile   |   1 +
 drivers/clocksource/timer-kinetis.c| 321 +
 7 files changed, 422 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/timer/fsl,kinetis-pit-timer.txt
 create mode 100644 drivers/clocksource/timer-kinetis.c

diff --git a/Documentation/devicetree/bindings/timer/fsl,kinetis-pit-timer.txt 
b/Documentation/devicetree/bindings/timer/fsl,kinetis-pit-timer.txt
new file mode 100644
index 000..4017230
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/fsl,kinetis-pit-timer.txt
@@ -0,0 +1,50 @@
+Freescale Kinetis SoC Periodic Interrupt Timer (PIT)
+
+Required properties:
+
+- compatible: Should be "fsl,kinetis-pit-timer".
+- reg: Specifies base physical address and size of the register set for the
+  Periodic Interrupt Timer.
+- clocks: The clock provided by the SoC to drive the timer.
+- Set of timer devices: following properties are required for each:
+   - reg: Specifies base physical address and size of the register set
+   for given timer device.
+   - interrupts: Should be the clock event device interrupt.
+
+Example:
+
+aliases {
+   pit0 = &pit0;
+   pit1 = &pit1;
+   pit2 = &pit2;
+   pit3 = &pit3;
+};
+
+pit@40037000 {
+   compatible = "fsl,kinetis-pit-timer";
+   reg = <0x40037000 0x100>;
+   clocks = <&mcg_pclk_gate 5 23>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   pit0: timer@40037100 {
+   reg = <0x40037100 0x10>;
+   interrupts = <68>;
+   };
+
+   pit1: timer@40037110 {
+   reg = <0x40037110 0x10>;
+   interrupts = <69>;
+   };
+
+   pit2: timer@40037120 {
+   reg = <0x40037120 0x10>;
+   interrupts = <70>;
+   };
+
+   pit3: timer@40037130 {
+   reg = <0x40037130 0x10>;
+   interrupts = <71>;
+   };
+};
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9c89bdc..96ddaae 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -968,6 +968,7 @@ config ARCH_KINETIS
bool "Freescale Kinetis MCU"
depends on ARM_SINGLE_ARMV7M
select ARMV7M_SYSTICK
+   select CLKSRC_KINETIS
help
  This enables support for the Freescale Kinetis MCUs
 
diff --git a/arch/arm/boot/dts/kinetis-twr-k70f120m.dts 
b/arch/arm/boot/dts/kinetis-twr-k70f120m.dts
index edccf37..a6efc29 100644
--- a/arch/arm/boot/dts/kinetis-twr-k70f120m.dts
+++ b/arch/arm/boot/dts/kinetis-twr-k70f120m.dts
@@ -14,3 +14,7 @@
reg = <0x800 0x800>;
};
 };
+
+&pit0 {
+   status = "ok";
+};
diff --git a/arch/arm/boot/dts/kinetis.dtsi b/arch/arm/boot/dts/kinetis.dtsi
index ae0cf00..0c572a5 100644
--- a/arch/arm/boot/dts/kinetis.dtsi
+++ b/arch/arm/boot/dts/kinetis.dtsi
@@ -5,7 +5,47 @@
 #include "armv7-m.dtsi"
 
 / {
+   aliases {
+   pit0 = &pit0;
+   pit1 = &pit1;
+   pit2 = &pit2;
+   pit3 = &pit3;
+   };
+
soc {
+   pit@40037000 {
+   compatible = "fsl,kinetis-pit-timer";
+   reg = <0x40037000 0x100>;
+   clocks = <&mcg_pclk_gate 5 23>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   pit0: timer@40037100 {
+   reg = <0x40037100 0x10>;
+   interrupts = <68>;
+   status = "disabled";
+   };
+
+   pit1: timer@40037110 {
+   reg = <0x40037110 0x10>;
+   interrupts = <69>;
+   status = "disabled";
+   };
+
+   pit2: timer@40037120 {
+   reg = <0x40037120 0x10>;
+   interrupts = <70>;
+   status = "disabled";
+   };
+
+   pit3: timer@40037130 {
+   reg = <0x40037130 0x10>;
+   interrupts = <71>;
+   stat

[PATCH v2 8/9] arm: twr-k70f120m: extend Freescale lpuart driver with ability to support Kinetis SoC

2015-06-30 Thread Paul Osmialowski
This adds Kinetis SoC UART support to Freescale lpuart driver.

Apart from some small changes (e.g. phony handler for error interrupt),
somewhat bigger change was required by rx DMA operation model: for Kinetis
the transfer residue should be consumed when handling interrupt caused by
IDLE state. As a reference I used DMA related code from pre-OF UART driver
published on Emcraft git repo:

https://github.com/EmcraftSystems/linux-emcraft.git

9dc9c6dd13fa3058c776ac71a5a9f71ec89712d3
 RT76540. serial: kinetis_uart: Support receiving from UART using DMA

by Alexander Potashev 

Signed-off-by: Paul Osmialowski 
---
 .../devicetree/bindings/serial/fsl-lpuart.txt  |  6 +-
 drivers/tty/serial/fsl_lpuart.c| 90 ++
 2 files changed, 80 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt 
b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
index c95005e..9a8d672 100644
--- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
@@ -6,6 +6,8 @@ Required properties:
 on Vybrid vf610 SoC with 8-bit register organization
   - "fsl,ls1021a-lpuart" for lpuart compatible with the one integrated
 on LS1021A SoC with 32-bit big-endian register organization
+  - "fsl,kinetis-lpuart" for lpuart compatible with the one integrated
+on Kinetis SoC with 8-bit register organization
 - reg : Address and length of the register set for the device
 - interrupts : Should contain uart interrupt
 - clocks : phandle + clock specifier pairs, one for each entry in clock-names
@@ -15,7 +17,9 @@ Optional properties:
 - dmas: A list of two dma specifiers, one for each entry in dma-names.
 - dma-names: should contain "tx" and "rx".
 
-Note: Optional properties for DMA support. Write them both or both not.
+Note: Optional properties for DMA support.
+For Kinetis SoC, write "rx" only.
+For others, write them both or both not.
 
 Example:
 
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 08ce76f..acf4094 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -236,6 +236,8 @@ struct lpuart_port {
unsigned inttxfifo_size;
unsigned intrxfifo_size;
boollpuart32;
+   boolkinetis;
+   int kinetis_err_irq;
 
boollpuart_dma_tx_use;
boollpuart_dma_rx_use;
@@ -264,6 +266,9 @@ static const struct of_device_id lpuart_dt_ids[] = {
{
.compatible = "fsl,ls1021a-lpuart",
},
+   {
+   .compatible = "fsl,kinetis-lpuart",
+   },
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
@@ -350,7 +355,9 @@ static void lpuart_pio_tx(struct lpuart_port *sport)
spin_lock_irqsave(&sport->port.lock, flags);
 
while (!uart_circ_empty(xmit) &&
-   readb(sport->port.membase + UARTTCFIFO) < sport->txfifo_size) {
+   (sport->kinetis ?
+ (readb(sport->port.membase + UARTSR1) & UARTSR1_TDRE) :
+ (readb(sport->port.membase + UARTTCFIFO) < sport->txfifo_size))) {
writeb(xmit->buf[xmit->tail], sport->port.membase + UARTDR);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
sport->port.icount.tx++;
@@ -471,7 +478,10 @@ static void lpuart_dma_rx_complete(void *arg)
unsigned long flags;
 
async_tx_ack(sport->dma_rx_desc);
-   mod_timer(&sport->lpuart_timer, jiffies + sport->dma_rx_timeout);
+   if (!(sport->kinetis)) {
+   mod_timer(&sport->lpuart_timer,
+   jiffies + sport->dma_rx_timeout);
+   }
 
spin_lock_irqsave(&sport->port.lock, flags);
 
@@ -483,16 +493,14 @@ static void lpuart_dma_rx_complete(void *arg)
spin_unlock_irqrestore(&sport->port.lock, flags);
 }
 
-static void lpuart_timer_func(unsigned long data)
+static inline void lpuart_dma_rx_extract_residue(struct lpuart_port *sport)
 {
-   struct lpuart_port *sport = (struct lpuart_port *)data;
struct tty_port *port = &sport->port.state->port;
struct dma_tx_state state;
unsigned long flags;
unsigned char temp;
int count;
 
-   del_timer(&sport->lpuart_timer);
dmaengine_pause(sport->dma_rx_chan);
dmaengine_tx_status(sport->dma_rx_chan, sport->dma_rx_cookie, &state);
dmaengine_terminate_all(sport->dma_rx_chan);
@@ -510,6 +518,14 @@ static void lpuart_timer_func(unsigned long data)
spin_unlock_irqrestore(&sport->port.lock, flags);
 }
 
+static void lpu

[PATCH v2 2/9] arm: twr-k70f120m: basic support for Kinetis TWR-K70F120M

2015-06-30 Thread Paul Osmialowski
This one was inspired by a serie of commits published on Emcraft git repo:

https://github.com/EmcraftSystems/linux-emcraft.git

Entry commit: f014da1df860ad702d923c95cb97e068bd302cb0
 RT75957. twr-k70f120m: basic support

by: Alexander Potashev 

Signed-off-by: Paul Osmialowski 
---
 Documentation/devicetree/bindings/arm/fsl.txt |  6 +
 arch/arm/Kconfig  |  9 ++-
 arch/arm/Kconfig-nommu|  1 +
 arch/arm/Makefile |  1 +
 arch/arm/boot/dts/kinetis-twr-k70f120m.dts| 16 +
 arch/arm/boot/dts/kinetis.dtsi|  5 
 arch/arm/mach-kinetis/Makefile|  5 
 arch/arm/mach-kinetis/Makefile.boot   |  3 +++
 arch/arm/mach-kinetis/idle.c  | 27 +
 arch/arm/mach-kinetis/kinetis.c   | 34 +++
 arch/arm/mm/Kconfig   |  1 +
 11 files changed, 107 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/kinetis-twr-k70f120m.dts
 create mode 100644 arch/arm/boot/dts/kinetis.dtsi
 create mode 100644 arch/arm/mach-kinetis/Makefile
 create mode 100644 arch/arm/mach-kinetis/Makefile.boot
 create mode 100644 arch/arm/mach-kinetis/idle.c
 create mode 100644 arch/arm/mach-kinetis/kinetis.c

diff --git a/Documentation/devicetree/bindings/arm/fsl.txt 
b/Documentation/devicetree/bindings/arm/fsl.txt
index 2a3ba73..36179fd 100644
--- a/Documentation/devicetree/bindings/arm/fsl.txt
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -135,3 +135,9 @@ LS2085A ARMv8 based Simulator model
 Required root node properties:
 - compatible = "fsl,ls2085a-simu", "fsl,ls2085a";
 
+Freescale Kinetis SoC Device Tree Bindings
+--
+
+TWR-K70F120M Kinetis K70 based development board.
+Required root node compatible properties:
+  - compatible = "fsl,kinetis-twr-k70f120m"
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a750c14..9c89bdc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -964,6 +964,13 @@ config ARCH_EFM32
  Support for Energy Micro's (now Silicon Labs) efm32 Giant Gecko
  processors.
 
+config ARCH_KINETIS
+   bool "Freescale Kinetis MCU"
+   depends on ARM_SINGLE_ARMV7M
+   select ARMV7M_SYSTICK
+   help
+ This enables support for the Freescale Kinetis MCUs
+
 config ARCH_LPC18XX
bool "NXP LPC18xx/LPC43xx"
depends on ARM_SINGLE_ARMV7M
@@ -1733,7 +1740,7 @@ source "mm/Kconfig"
 config FORCE_MAX_ZONEORDER
int "Maximum zone order" if ARCH_SHMOBILE_LEGACY
range 11 64 if ARCH_SHMOBILE_LEGACY
-   default "12" if SOC_AM33XX
+   default "12" if SOC_AM33XX || ARCH_KINETIS
default "9" if SA || ARCH_EFM32
default "11"
help
diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
index d081fcb..4b9aab3 100644
--- a/arch/arm/Kconfig-nommu
+++ b/arch/arm/Kconfig-nommu
@@ -65,6 +65,7 @@ config ARM_MPU
 
 config COPY_VECTOR_TABLE_TO_SRAM_ADDR
hex 'If non-zero, copy Vector Table to this SRAM Address' if CPU_V7M
+   default 0x2000 if ARCH_KINETIS
default 0x
depends on CPU_V7M
help
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 07ab3d2..e71fc01 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -170,6 +170,7 @@ machine-$(CONFIG_ARCH_IOP32X)   += iop32x
 machine-$(CONFIG_ARCH_IOP33X)  += iop33x
 machine-$(CONFIG_ARCH_IXP4XX)  += ixp4xx
 machine-$(CONFIG_ARCH_KEYSTONE)+= keystone
+machine-$(CONFIG_ARCH_KINETIS) += kinetis
 machine-$(CONFIG_ARCH_KS8695)  += ks8695
 machine-$(CONFIG_ARCH_LPC18XX) += lpc18xx
 machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx
diff --git a/arch/arm/boot/dts/kinetis-twr-k70f120m.dts 
b/arch/arm/boot/dts/kinetis-twr-k70f120m.dts
new file mode 100644
index 000..edccf37
--- /dev/null
+++ b/arch/arm/boot/dts/kinetis-twr-k70f120m.dts
@@ -0,0 +1,16 @@
+/*
+ * Device tree for TWR-K70F120M development board.
+ *
+ */
+
+/dts-v1/;
+#include "kinetis.dtsi"
+
+/ {
+   model = "Freescale TWR-K70F120M Development Kit";
+   compatible = "fsl,kinetis-twr-k70f120m";
+
+   memory {
+   reg = <0x800 0x800>;
+   };
+};
diff --git a/arch/arm/boot/dts/kinetis.dtsi b/arch/arm/boot/dts/kinetis.dtsi
new file mode 100644
index 000..93d2a8a
--- /dev/null
+++ b/arch/arm/boot/dts/kinetis.dtsi
@@ -0,0 +1,5 @@
+/*
+ * Device tree for Freescale Kinetis SoC.
+ *
+ */
+#include "armv7-m.dtsi"
diff --git a/arch/arm/mach-kinetis/Makefile b/arch/arm/mach-kinetis/Makefile
new file mode 100644
index 000..e759d9e
--- /dev/null
+++ b/arch/arm/mach-kinetis/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Freescal

[PATCH v2 9/9] arm: twr-k70f120m: use Freescale lpuart driver with Kinetis SoC

2015-06-30 Thread Paul Osmialowski
Note that enabling tx DMA resulted in messy output, so I didn't configure
it in the .dts file - however nothing in the code prevents one from doing
so. Also note that original reference UART driver from Emcraft did not
implement tx DMA at all.

Signed-off-by: Paul Osmialowski 
---
 arch/arm/boot/dts/kinetis-twr-k70f120m.dts | 23 +
 arch/arm/boot/dts/kinetis.dtsi | 78 ++
 2 files changed, 101 insertions(+)

diff --git a/arch/arm/boot/dts/kinetis-twr-k70f120m.dts 
b/arch/arm/boot/dts/kinetis-twr-k70f120m.dts
index a6efc29..5d8470a 100644
--- a/arch/arm/boot/dts/kinetis-twr-k70f120m.dts
+++ b/arch/arm/boot/dts/kinetis-twr-k70f120m.dts
@@ -10,11 +10,34 @@
model = "Freescale TWR-K70F120M Development Kit";
compatible = "fsl,kinetis-twr-k70f120m";
 
+   chosen {
+   bootargs = "console=ttyLP2,115200";
+   };
+
memory {
reg = <0x800 0x800>;
};
 };
 
+&uart2 {
+   pinctrl-names = "default";
+   pinctrl-0 = <&uart2_pins>;
+   status = "ok";
+};
+
+&portE {
+   status = "ok";
+
+   uart2 {
+   uart2_pins: pinmux_uart2_pins {
+   fsl,pins = <
+   16  0x300 /* E.16 = UART2_TX */
+   17  0x300 /* E.17 = UART2_RX */
+   >;
+   };
+   };
+};
+
 &pit0 {
status = "ok";
 };
diff --git a/arch/arm/boot/dts/kinetis.dtsi b/arch/arm/boot/dts/kinetis.dtsi
index c2861f5..fedafe3 100644
--- a/arch/arm/boot/dts/kinetis.dtsi
+++ b/arch/arm/boot/dts/kinetis.dtsi
@@ -16,9 +16,87 @@
pmx3 = &portD;
pmx4 = &portE;
pmx5 = &portF;
+   serial0 = &uart0;
+   serial1 = &uart1;
+   serial2 = &uart2;
+   serial3 = &uart3;
+   serial4 = &uart4;
+   serial5 = &uart5;
};
 
soc {
+   uart0: serial@4006a000 {
+   compatible = "fsl,kinetis-lpuart";
+   reg = <0x4006a000 0x1000>;
+   interrupts = <45>, <46>;
+   interrupt-names = "uart-stat", "uart-err";
+   clocks = <&mcg_cclk_gate 3 10>;
+   clock-names = "ipg";
+   dmas = <&edma 0 2>;
+   dma-names = "rx";
+   status = "disabled";
+   };
+
+   uart1: serial@4006b000 {
+   compatible = "fsl,kinetis-lpuart";
+   reg = <0x4006b000 0x1000>;
+   interrupts = <47>, <48>;
+   interrupt-names = "uart-stat", "uart-err";
+   clocks = <&mcg_cclk_gate 3 11>;
+   clock-names = "ipg";
+   dmas = <&edma 0 4>;
+   dma-names = "rx";
+   status = "disabled";
+   };
+
+   uart2: serial@4006c000 {
+   compatible = "fsl,kinetis-lpuart";
+   reg = <0x4006c000 0x1000>;
+   interrupts = <49>, <50>;
+   interrupt-names = "uart-stat", "uart-err";
+   clocks = <&mcg_pclk_gate 3 12>;
+   clock-names = "ipg";
+   dmas = <&edma 0 6>;
+   dma-names = "rx";
+   status = "disabled";
+   };
+
+   uart3: serial@4006d000 {
+   compatible = "fsl,kinetis-lpuart";
+   reg = <0x4006d000 0x1000>;
+   interrupts = <51>, <52>;
+   interrupt-names = "uart-stat", "uart-err";
+   clocks = <&mcg_pclk_gate 3 13>;
+   clock-names = "ipg";
+   dmas = <&edma 0 8>;
+   dma-names = "rx";
+   status = "disabled";
+   };
+
+   uart4: serial@400ea000 {
+   compatible = "fsl,kinetis-lpuart";
+   reg = <0x400ea000 0x1000>;
+   interrupts = <53>, <54>;
+   interrupt-names = "uart-stat", "uart-err";
+   clocks = <&mcg_pclk_gate 0 10>;
+

[PATCH v2 1/9] arm: allow copying of vector table to internal SRAM memory

2015-06-30 Thread Paul Osmialowski
Based on part of the commit published on Emcraft git repo:

https://github.com/EmcraftSystems/linux-emcraft.git

2ce1841b590d014d8738215fb1ffe05f53c8d9f0 "some commit"

by: Dmitry Cherkassov 

The ARM v7M allows setting the vector table either in
the boot memory or in the internal SRAM memory, controlled
by Bit 29 in the Vector Table Base register. This implies
that the OS vector table needs to be copied to the internal RAM.

New option CONFIG_COPY_VECTOR_TABLE_TO_SRAM_ADDR allows specification
of the desired destination for the OS vector table.

Signed-off-by: Paul Osmialowski 
---
 arch/arm/Kconfig-nommu  | 11 +++
 arch/arm/kernel/entry-v7m.S |  3 +++
 arch/arm/mm/proc-v7m.S  | 11 +++
 3 files changed, 25 insertions(+)

diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
index aed66d5..d081fcb 100644
--- a/arch/arm/Kconfig-nommu
+++ b/arch/arm/Kconfig-nommu
@@ -62,3 +62,14 @@ config ARM_MPU
 
  If your CPU has an MPU then you should choose 'y' here unless you
  know that you do not want to use the MPU.
+
+config COPY_VECTOR_TABLE_TO_SRAM_ADDR
+   hex 'If non-zero, copy Vector Table to this SRAM Address' if CPU_V7M
+   default 0x
+   depends on CPU_V7M
+   help
+ The ARM v7M allows setting the vector table either in
+ the boot memory or in the internal SRAM memory, controlled
+ by Bit 29 in the Vector Table Base register.
+ This implies that the OS vector table needs to be copied to
+ the internal RAM.
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index b6c8bb9..114096e 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -146,3 +146,6 @@ ENTRY(vector_table)
.rept   CONFIG_CPU_V7M_NUM_IRQ
.long   __irq_entry @ External Interrupts
.endr
+#if CONFIG_COPY_VECTOR_TABLE_TO_SRAM_ADDR > 0x
+ENTRY(vector_table_end)
+#endif
diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S
index 67d9209..ded9504 100644
--- a/arch/arm/mm/proc-v7m.S
+++ b/arch/arm/mm/proc-v7m.S
@@ -83,7 +83,18 @@ ENDPROC(cpu_v7m_do_resume)
 __v7m_setup:
@ Configure the vector table base address
ldr r0, =BASEADDR_V7M_SCB
+#if CONFIG_COPY_VECTOR_TABLE_TO_SRAM_ADDR > 0x
+   ldr r12, =CONFIG_COPY_VECTOR_TABLE_TO_SRAM_ADDR
+   mov r5, r12 @ Copy the kernel vector_table to
+   ldr r6, =vector_table   @ the in-SRAM vector table
+   ldr r4, =vector_table_end
+1: ldr r3, [r6], #4
+   str r3, [r5], #4
+   cmp r6, r4
+   bne 1b  @ End of the copy code
+#else
ldr r12, =vector_table
+#endif
str r12, [r0, V7M_SCB_VTOR]
 
@ enable UsageFault, BusFault and MemManage fault.
-- 
2.3.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/9] arm: add call to CPU idle quirks handler

2015-06-26 Thread Paul Osmialowski



On Fri, 26 Jun 2015, Arnd Bergmann wrote:


I doubt that the Kinetis has a custom version of the CPU core. Are you
sure that not all Cortex-M4 need this?


I'm not sure and I don't have any other Cortex-M SoC to verify that...
Without this hack, I'm experiencing following exception:

init started: BusyBox v1.17.0 (2015-03-27 08:16:34 CET)
~ # [1.91]
[1.91] Unhandled exception: IPSR = 0006 LR = fff1
[1.91] CPU: 0 PID: 0 Comm: swapper Not tainted 
4.1.0-next-20150623-7-gf22ea1d-dirty #1

[1.91] Hardware name: Freescale Kinetis
[1.91] task: 082666f8 ti: 08264000 task.ti: 08264000
[1.91] PC is at arch_cpu_idle+0x14/0x1c
[1.91] LR is at arch_cpu_idle+0x13/0x1c
[1.91] pc : [<0800a928>]lr : [<0800a927>]psr: 610b
[1.91] sp : 08265f98  ip : 08264020  fp : 0001
[1.91] r10: 0827433d  r9 :   r8 : 08266070
[1.91] r7 : 08272a88  r6 : 08266068  r5 :   r4 : 08266068
[1.91] r3 :   r2 : 08265fa0  r1 : 08264020  r0 : 08264000
[1.91] xPSR: 610b
[1.91] CPU: 0 PID: 0 Comm: swapper Not tainted 
4.1.0-next-20150623-7-gf22ea1d-dirty #1

[1.91] Hardware name: Freescale Kinetis
[1.91] [<0800c5cd>] (unwind_backtrace) from [<0800b8b3>] 
(show_stack+0xb/0xc)
[1.91] [<0800b8b3>] (show_stack) from [<0800bd8b>] 
(__invalid_entry+0x4b/0x4c)
[1.91] [<0800bd8b>] (__invalid_entry) from [] 
(0x)


Funny, it does not occur when JTAG is connected.



As long as the idle implementation depends only on the CPU core type,
it's easy to just define multiple .proc.info.init entries in the
same file, like we do in proc-v7.S.



I tried it and it works. This approach does not cause code duplication, 
but (comparing to arm_pm_idle-based approach) its long. Would something 
like this be accepted ever?


Note that contrary to proc-v7, there's no __v7m_proc macro, I had to 
define it in order to avoid another code duplication:


diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8ccffee..da35b0b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -967,6 +967,7 @@ config ARCH_EFM32
 config ARCH_KINETIS
bool "Freescale Kinetis MCU"
depends on ARM_SINGLE_ARMV7M
+   select CPU_KINETIS
select ARMV7M_SYSTICK
select CLKSRC_KINETIS
select PINCTRL
diff --git a/arch/arm/include/asm/cputype.h 
b/arch/arm/include/asm/cputype.h

index 85e374f..79792e9 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -234,6 +234,12 @@ static inline int cpu_is_xsc3(void)
 #definecpu_is_xscale() 1
 #endif

+#if !defined(CONFIG_CPU_KINETIS)
+#definecpu_is_kinetis()0
+#else
+#definecpu_is_kinetis()1
+#endif
+
 /*
  * Marvell's PJ4 and PJ4B cores are based on V7 version,
  * but require a specical sequence for enabling coprocessors.
diff --git a/arch/arm/include/asm/glue-proc.h 
b/arch/arm/include/asm/glue-proc.h

index 74be7c2..08583bb 100644
--- a/arch/arm/include/asm/glue-proc.h
+++ b/arch/arm/include/asm/glue-proc.h
@@ -230,6 +230,15 @@
 # endif
 #endif

+#ifdef CONFIG_CPU_KINETIS
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_kinetis
+# endif
+#endif
+
 #ifdef CONFIG_CPU_PJ4B
 # ifdef CPU_NAME
 #  undef  MULTI_CPU
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 121b580..ef59407 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -356,6 +356,11 @@ config CPU_PJ4B
bool
select CPU_V7

+# Freescale Kinetis
+config CPU_KINETIS
+   bool
+   select CPU_V7M
+
 # ARMv6
 config CPU_V6
 	bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || 
ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || 
MACH_REALVIEW_PBX)

diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S
index ded9504..671374f 100644
--- a/arch/arm/mm/proc-v7m.S
+++ b/arch/arm/mm/proc-v7m.S
@@ -73,6 +73,30 @@ ENTRY(cpu_v7m_do_resume)
 ENDPROC(cpu_v7m_do_resume)
 #endif

+#ifdef CONFIG_CPU_KINETIS
+   globl_equ   cpu_kinetis_switch_mm,  cpu_v7m_switch_mm
+   globl_equ   cpu_kinetis_proc_init,  cpu_v7m_proc_init
+   globl_equ   cpu_kinetis_proc_fin,   cpu_v7m_proc_fin
+   globl_equ   cpu_kinetis_reset,  cpu_v7m_reset
+ENTRY(cpu_kinetis_do_idle)
+   dsb
+   wfi
+   movwr3, #:lower16:0xe0082000
+   movtr3, #:upper16:0xe0082000
+   ldr r0, [r3, #0]
+   orr r2, r0, #0x8500
+   str r2, [r3, #0]
+   ret lr
+ENDPROC(cpu_kinetis_do_idle)
+	globl_equ	cpu_kinetis_dcache_clean_area, 
cpu_v7m_dcache_clean_area

+#ifdef CONFIG_ARM_CPU_SUSPEND
+   globl_equ   cpu_kinetis_do_suspend, cpu_v7m_do_suspend
+   globl_equ   cpu_kinedis_do_resume,  cpu_v7m_do_resume
+#endif
+.globl cpu_kinetis_suspend_size
+.equ   cpu_kinetis_suspend_size, cpu_v7m_suspend_size
+#endif
+
.section ".text.init", #alloc

Re: [PATCH 3/9] arm: add call to CPU idle quirks handler

2015-06-25 Thread Paul Osmialowski

Hi Nicolas,

Thanks for your proposal, however, I have some trouble with it.

That would look lovely:

#include 
#include 

/*
 *  cpu_kinetis_do_idle()
 *
 *  Idle the processor (wait for interrupt).
 *
 *  IRQs are already disabled.
 */
ENTRY(cpu_kinetis_do_idle)
wfi
movwr3, #:lower16:0xe0082000
movtr3, #:upper16:0xe0082000
ldr r0, [r3, #0]
orr r2, r0, #0x8500
str r2, [r3, #0]
ret lr
ENDPROC(cpu_kinetis_do_idle)

But... what about the rest of this hypothetical proc_kinetis.S file?

It would be a lot of code duplication with proc-v7m.S I think.

I could define CPU_KINETIS as such:

config CPU_KINETIS
bool
select CPU_V7M

But there's no such thing like customize_processor_functions that would be 
called after proc-v7m.S define_processor_functions specified things like 
idle routine.


Finally, while I was searching for suitable arm_pm_idle-based solution, I 
found idle.c in mach-gemini that encouraged me to write my own idle.c for 
Kinetis:


/*
 * arch/arm/mach-kinetis/idle.c
 */

#include 
#include 
#include 
#include 

static void kinetis_idle(void)
{
asm volatile ("wfi");

/*
 * This is a dirty hack that invalidates the I/D bus cache
 * on Kinetis K70. This must be done after idle.
 */
writel(readl(IOMEM(0xe0082000)) | 0x8500, IOMEM(0xe0082000));
}

static int __init kinetis_idle_init(void)
{
arm_pm_idle = kinetis_idle;
return 0;
}

arch_initcall(kinetis_idle_init);

Et voila:

(gdb) c
Continuing.
^C
Program received signal SIGTRAP, Trace/breakpoint trap.
kinetis_idle () at ../arch/arm/mach-kinetis/idle.c:18
18		writel(readl(IOMEM(0xe0082000)) | 0x8500, 
IOMEM(0xe0082000));

(gdb) bt
#0  kinetis_idle () at ../arch/arm/mach-kinetis/idle.c:18
#1  0x0800a91e in arch_cpu_idle () at ../arch/arm/kernel/process.c:70
#2  0x08025402 in cpuidle_idle_call (state=)
at ../kernel/sched/idle.c:157
#3  cpu_idle_loop (state=) at 
../kernel/sched/idle.c:253
#4  cpu_startup_entry (state=) at 
../kernel/sched/idle.c:301

#5  0x081bf816 in start_kernel () at ../init/main.c:683
#6  0x08008024 in stext () at ../arch/arm/kernel/head-nommu.S:85
(gdb)

On Thu, 25 Jun 2015, Nicolas Pitre wrote:


On Tue, 23 Jun 2015, Arnd Bergmann wrote:


On Tuesday 23 June 2015 23:19:41 Paul Osmialowski wrote:

Some SoCs need additional actions to be performed after arch idle,
e.g. Kinetis requires invalidation of the I/D bus cache.

Such handler could be held in provided  header file.

Signed-off-by: Paul Osmialowski 
---
 arch/arm/Kconfig  | 7 +++
 arch/arm/kernel/process.c | 7 +++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8e3a833..8ef8f8f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -98,6 +98,13 @@ config ARM_HAS_SG_CHAIN
 config NEED_SG_DMA_LENGTH
bool

+config NEED_MACH_IDLE_H
+   bool
+
+config ARM_CPU_IDLE_QUIRKS
+   bool
+   select NEED_MACH_IDLE_H
+


We're not adding header files like this, please come up
with another solution. How about a cpuidle driver, or
possibly just overriding arm_pm_idle()?


If the WFI instruction always requires I and D flushing, then it might
be a better idea to provide a replacement for the corresponding
cpu_*_do_idle function.  Plenty of examples exist for other cpu_*
functions.


Nicolas


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 7/9] arm: twr-k70f120m: IOMUX driver for Kinetis SoC

2015-06-24 Thread Paul Osmialowski

Hi Paul,

Thanks for your comments. I'll make it tristate.

On Wed, 24 Jun 2015, Paul Bolle wrote:


On Tue, 2015-06-23 at 23:19 +0200, Paul Osmialowski wrote:

--- a/drivers/pinctrl/freescale/Kconfig
+++ b/drivers/pinctrl/freescale/Kconfig



+config PINCTRL_KINETIS
+   bool "Kinetis pinctrl driver"
+   depends on OF
+   depends on SOC_K70
+   select PINMUX
+   help
+ Say Y here to enable the Kinetis pinctrl driver



--- a/drivers/pinctrl/freescale/Makefile
+++ b/drivers/pinctrl/freescale/Makefile



+obj-$(CONFIG_PINCTRL_KINETIS)  += pinctrl-kinetis.o



--- /dev/null
+++ b/drivers/pinctrl/freescale/pinctrl-kinetis.c



+#include 



+static struct pinctrl_desc kinetis_pinctrl_desc = {
+   [...]
+   .owner = THIS_MODULE,
+};



+static void __exit kinetis_pinctrl_exit(void)
+{
+   platform_driver_unregister(&kinetis_pinctrl_driver);
+}
+module_exit(kinetis_pinctrl_exit);
+
+MODULE_DESCRIPTION("Freescale Kinetis pinctrl driver");
+MODULE_LICENSE("GPL v2");


pinctrl-kinetis.o can only be built-in, right? But the code uses a few
module specific constructs. Did you mean to make PINCTRL_KINETIS
tristate instead?

Thanks,


Paul Bolle


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   >