add kmsg-fix-overlong-cont.patch
diff --git a/kmsg-fix-overlong-cont.patch b/kmsg-fix-overlong-cont.patch
new file mode 100644
index 0000000..a60f69e
--- /dev/null
+++ b/kmsg-fix-overlong-cont.patch
@@ -0,0 +1,129 @@
+---
+ kernel/printk.c |   33 +++++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 14 deletions(-)
+
+--- a/kernel/printk.c
++++ b/kernel/printk.c
+@@ -235,7 +235,8 @@ static u32 log_next_idx;
+ static u64 clear_seq;
+ static u32 clear_idx;
+ 
+-#define LOG_LINE_MAX 1024
++#define PREFIX_MAX		32
++#define LOG_LINE_MAX		1024 - PREFIX_MAX
+ 
+ /* record buffer */
+ #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+@@ -876,7 +877,7 @@ static size_t msg_print_text(const struc
+ 
+ 		if (buf) {
+ 			if (print_prefix(msg, syslog, NULL) +
+-			    text_len + 1>= size - len)
++			    text_len + 1 >= size - len)
+ 				break;
+ 
+ 			if (prefix)
+@@ -907,7 +908,7 @@ static int syslog_print(char __user *buf
+ 	struct log *msg;
+ 	int len = 0;
+ 
+-	text = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
++	text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
+ 	if (!text)
+ 		return -ENOMEM;
+ 
+@@ -930,7 +931,8 @@ static int syslog_print(char __user *buf
+ 
+ 		skip = syslog_partial;
+ 		msg = log_from_idx(syslog_idx);
+-		n = msg_print_text(msg, syslog_prev, true, text, LOG_LINE_MAX);
++		n = msg_print_text(msg, syslog_prev, true, text,
++				   LOG_LINE_MAX + PREFIX_MAX);
+ 		if (n - syslog_partial <= size) {
+ 			/* message fits into buffer, move forward */
+ 			syslog_idx = log_next(syslog_idx);
+@@ -969,7 +971,7 @@ static int syslog_print_all(char __user
+ 	char *text;
+ 	int len = 0;
+ 
+-	text = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
++	text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
+ 	if (!text)
+ 		return -ENOMEM;
+ 
+@@ -1022,7 +1024,8 @@ static int syslog_print_all(char __user
+ 			struct log *msg = log_from_idx(idx);
+ 			int textlen;
+ 
+-			textlen = msg_print_text(msg, prev, true, text, LOG_LINE_MAX);
++			textlen = msg_print_text(msg, prev, true, text,
++						 LOG_LINE_MAX + PREFIX_MAX);
+ 			if (textlen < 0) {
+ 				len = textlen;
+ 				break;
+@@ -1367,15 +1370,15 @@ static struct cont {
+ 	bool flushed:1;			/* buffer sealed and committed */
+ } cont;
+ 
+-static void cont_flush(void)
++static void cont_flush(enum log_flags flags)
+ {
+ 	if (cont.flushed)
+ 		return;
+ 	if (cont.len == 0)
+ 		return;
+ 
+-	log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec,
+-		  NULL, 0, cont.buf, cont.len);
++	log_store(cont.facility, cont.level, LOG_NOCONS | flags,
++		  cont.ts_nsec, NULL, 0, cont.buf, cont.len);
+ 
+ 	cont.flushed = true;
+ }
+@@ -1386,7 +1389,8 @@ static bool cont_add(int facility, int l
+ 		return false;
+ 
+ 	if (cont.len + len > sizeof(cont.buf)) {
+-		cont_flush();
++		/* the line gets too long, split it up in separate records */
++		cont_flush(LOG_CONT);
+ 		return false;
+ 	}
+ 
+@@ -1522,7 +1526,7 @@ asmlinkage int vprintk_emit(int facility
+ 		 * or another task also prints continuation lines.
+ 		 */
+ 		if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
+-			cont_flush();
++			cont_flush(0);
+ 
+ 		/* buffer line if possible, otherwise store it right away */
+ 		if (!cont_add(facility, level, text, text_len))
+@@ -1540,7 +1544,7 @@ asmlinkage int vprintk_emit(int facility
+ 		if (cont.len && cont.owner == current) {
+ 			if (!(lflags & LOG_PREFIX))
+ 				stored = cont_add(facility, level, text, text_len);
+-			cont_flush();
++			cont_flush(0);
+ 		}
+ 
+ 		if (!stored)
+@@ -1633,7 +1637,8 @@ EXPORT_SYMBOL(printk);
+ 
+ #else
+ 
+-#define LOG_LINE_MAX 0
++#define LOG_LINE_MAX		0
++#define PREFIX_MAX		0
+ static struct cont {
+ 	size_t len;
+ 	size_t cons;
+@@ -1938,7 +1943,7 @@ static enum log_flags console_prev;
+  */
+ void console_unlock(void)
+ {
+-	static char text[LOG_LINE_MAX];
++	static char text[LOG_LINE_MAX + PREFIX_MAX];
+ 	static u64 seen_seq;
+ 	unsigned long flags;
+ 	bool wake_klogd = false;
diff --git a/pr_cat.patch b/pr_cat.patch
new file mode 100644
index 0000000..aea0193
--- /dev/null
+++ b/pr_cat.patch
@@ -0,0 +1,117 @@
+diff --git a/kernel/printk.c b/kernel/printk.c
+index 177fa49..0f4df08 100644
+--- a/kernel/printk.c
++++ b/kernel/printk.c
+@@ -48,6 +48,40 @@
+ #define CREATE_TRACE_POINTS
+ #include <trace/events/printk.h>
+ 
++#define CATSTR_INIT(name)		\
++	name##_len = 0
++
++#define CATSTR_DEFINE(name, max)	\
++	char name[max];			\
++	size_t name##_len = 0;		\
++	size_t name##_max = max
++
++#define pr_cat(name, fmt, ...)		\
++	_pr_cat(name, &name##_len, name##_max, fmt, ##__VA_ARGS__)
++
++bool _pr_cat(char *s, size_t *len, size_t size, const char *fmt, ...)
++{
++	va_list args;
++	size_t r;
++
++	if (*len == size)
++		return false;
++
++	va_start(args, fmt);
++	r = vsnprintf(s + *len, size - *len, fmt, args);
++	va_end(args);
++
++	if (r + 1 >= size - *len) {
++		s[*len] = '\0';
++		*len = size;
++		return false;
++	}
++
++	*len += r;
++	s[*len] = '\0';
++	return true;
++}
++
+ /*
+  * Architectures can override it:
+  */
+@@ -587,6 +621,11 @@ static int devkmsg_open(struct inode *inode, struct file *file)
+ 	struct devkmsg_user *user;
+ 	int err;
+ 
++	console_lock();
++	print_modules();
++	print_modules();
++	console_unlock();
++
+ 	/* write-only does not need any file context */
+ 	if ((file->f_flags & O_ACCMODE) == O_WRONLY)
+ 		return 0;
+@@ -671,6 +710,59 @@ void __init setup_log_buf(int early)
+ 	unsigned long flags;
+ 	char *new_log_buf;
+ 	int free;
++	int i;
++
++	CATSTR_DEFINE(line, 64);
++	CATSTR_DEFINE(line2, 16);
++	CATSTR_DEFINE(line3, 12);
++
++	pr_cat(line, "1:");
++	pr_cat(line, "-%i ", 12);
++	pr_cat(line, "-%i ", 34);
++	pr_cat(line, "-%i ", 56);
++	pr_cat(line, "-%i ", 78);
++	pr_info("%s-%i\n", line, 90);
++
++	pr_cat(line2, "2:");
++	pr_cat(line2, "-%i ", 12);
++	pr_cat(line2, "-%i ", 34);
++	pr_cat(line2, "-%i ", 56);
++	pr_cat(line2, "-%i ", 78);
++	pr_info("%s-%i\n", line2, 90);
++
++	pr_cat(line3, "3:");
++	pr_cat(line3, "-%i ", 12);
++	pr_cat(line3, "-%i ", 34);
++	pr_cat(line3, "-%i ", 56);
++	pr_cat(line3, "-%i ", 78);
++	pr_info("%s-%i\n", line3, 90);
++
++	CATSTR_INIT(line3);
++	pr_cat(line3, "4:");
++	pr_cat(line3, "+%i ", 12);
++	pr_cat(line3, "+%i ", 34);
++	pr_cat(line3, "+%i ", 56);
++	pr_cat(line3, "+%i ", 78);
++	pr_info("%s-%i\n", line3, 90);
++
++	CATSTR_INIT(line3);
++	pr_cat(line3, "5:");
++	pr_cat(line3, "~%i ", 12);
++	pr_cat(line3, "~%i ", 34);
++	pr_cat(line3, "~%i ", 56);
++	pr_cat(line3, "~%i ", 78);
++	pr_info("%s-%i\n", line3, 90);
++
++	CATSTR_INIT(line);
++	pr_cat(line, "foo:");
++	for (i = 0; i < 50; i++) {
++		if (!pr_cat(line, " #%i", i)) {
++			pr_info("%s #%i\n", line, i);
++			CATSTR_INIT(line);
++			pr_cat(line, "foo+:");
++		}
++	}
++	pr_info("%s\n", line);
+ 
+ 	if (!new_log_buf_len)
+ 		return;
diff --git a/series b/series
index d6822ef..1683d3c 100644
--- a/series
+++ b/series
@@ -1,4 +1,6 @@
 #test-modules.patch
 #test-console-blocked.patch
+#pr_cat.patch
+kmsg-fix-overlong-cont.patch
 kmsg-config-no-printk.patch
 kmsg-export-flags.patch