Merge branch 'akpm' (patches from Andrew)

Merge second patch-bomb from Andrew Morton:

 - most of the rest of MM

 - procfs

 - lib/ updates

 - printk updates

 - bitops infrastructure tweaks

 - checkpatch updates

 - nilfs2 update

 - signals

 - various other misc bits: coredump, seqfile, kexec, pidns, zlib, ipc,
   dma-debug, dma-mapping, ...

* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (102 commits)
  ipc,msg: drop dst nil validation in copy_msg
  include/linux/zutil.h: fix usage example of zlib_adler32()
  panic: release stale console lock to always get the logbuf printed out
  dma-debug: check nents in dma_sync_sg*
  dma-mapping: tidy up dma_parms default handling
  pidns: fix set/getpriority and ioprio_set/get in PRIO_USER mode
  kexec: use file name as the output message prefix
  fs, seqfile: always allow oom killer
  seq_file: reuse string_escape_str()
  fs/seq_file: use seq_* helpers in seq_hex_dump()
  coredump: change zap_threads() and zap_process() to use for_each_thread()
  coredump: ensure all coredumping tasks have SIGNAL_GROUP_COREDUMP
  signal: remove jffs2_garbage_collect_thread()->allow_signal(SIGCONT)
  signal: introduce kernel_signal_stop() to fix jffs2_garbage_collect_thread()
  signal: turn dequeue_signal_lock() into kernel_dequeue_signal()
  signals: kill block_all_signals() and unblock_all_signals()
  nilfs2: fix gcc uninitialized-variable warnings in powerpc build
  nilfs2: fix gcc unused-but-set-variable warnings
  MAINTAINERS: nilfs2: add header file for tracing
  nilfs2: add tracepoints for analyzing reading and writing metadata files
  ...
This commit is contained in:
Linus Torvalds
2015-11-07 14:32:45 -08:00
211 changed files with 2308 additions and 1642 deletions
+3
View File
@@ -1686,6 +1686,9 @@ config TEST_STRING_HELPERS
config TEST_KSTRTOX
tristate "Test kstrto*() family of functions at runtime"
config TEST_PRINTF
tristate "Test printf() family of functions at runtime"
config TEST_RHASHTABLE
tristate "Perform selftest on resizable hash table"
default n
+1
View File
@@ -42,6 +42,7 @@ obj-$(CONFIG_TEST_RHASHTABLE) += test_rhashtable.o
obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o
obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
obj-$(CONFIG_TEST_PRINTF) += test_printf.o
ifeq ($(CONFIG_DEBUG_KOBJECT),y)
CFLAGS_kobject.o += -DDEBUG
+8
View File
@@ -1249,6 +1249,14 @@ static void check_sync(struct device *dev,
dir2name[entry->direction],
dir2name[ref->direction]);
if (ref->sg_call_ents && ref->type == dma_debug_sg &&
ref->sg_call_ents != entry->sg_call_ents) {
err_printk(ref->dev, entry, "DMA-API: device driver syncs "
"DMA sg list with different entry count "
"[map count=%d] [sync count=%d]\n",
entry->sg_call_ents, ref->sg_call_ents);
}
out:
put_hash_bucket(bucket, &flags);
}
+4 -4
View File
@@ -42,7 +42,7 @@ extern struct _ddebug __stop___verbose[];
struct ddebug_table {
struct list_head link;
char *mod_name;
const char *mod_name;
unsigned int num_ddebugs;
struct _ddebug *ddebugs;
};
@@ -841,12 +841,12 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
const char *name)
{
struct ddebug_table *dt;
char *new_name;
const char *new_name;
dt = kzalloc(sizeof(*dt), GFP_KERNEL);
if (dt == NULL)
return -ENOMEM;
new_name = kstrdup(name, GFP_KERNEL);
new_name = kstrdup_const(name, GFP_KERNEL);
if (new_name == NULL) {
kfree(dt);
return -ENOMEM;
@@ -907,7 +907,7 @@ int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
static void ddebug_table_free(struct ddebug_table *dt)
{
list_del_init(&dt->link);
kfree(dt->mod_name);
kfree_const(dt->mod_name);
kfree(dt);
}
+2 -1
View File
@@ -1,6 +1,7 @@
#include <linux/compiler.h>
#include <linux/export.h>
#include <linux/cryptohash.h>
#include <linux/bitops.h>
/* F, G and H are basic MD4 functions: selection, majority, parity */
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
@@ -14,7 +15,7 @@
* Rotation is separate from addition to prevent recomputation
*/
#define ROUND(f, a, b, c, d, x, s) \
(a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s)))
(a += f(b, c, d) + x, a = rol32(a, s))
#define K1 0
#define K2 013240474631UL
#define K3 015666365641UL
+5 -1
View File
@@ -169,11 +169,15 @@ int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize,
}
} else {
for (j = 0; j < len; j++) {
if (linebuflen < lx + 3)
if (linebuflen < lx + 2)
goto overflow2;
ch = ptr[j];
linebuf[lx++] = hex_asc_hi(ch);
if (linebuflen < lx + 2)
goto overflow2;
linebuf[lx++] = hex_asc_lo(ch);
if (linebuflen < lx + 2)
goto overflow2;
linebuf[lx++] = ' ';
}
if (j)
+2 -2
View File
@@ -399,7 +399,7 @@ void idr_preload(gfp_t gfp_mask)
* allocation guarantee. Disallow usage from those contexts.
*/
WARN_ON_ONCE(in_interrupt());
might_sleep_if(gfp_mask & __GFP_WAIT);
might_sleep_if(gfpflags_allow_blocking(gfp_mask));
preempt_disable();
@@ -453,7 +453,7 @@ int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask)
struct idr_layer *pa[MAX_IDR_LEVEL + 1];
int id;
might_sleep_if(gfp_mask & __GFP_WAIT);
might_sleep_if(gfpflags_allow_blocking(gfp_mask));
/* sanity checks */
if (WARN_ON_ONCE(start < 0))
+2 -3
View File
@@ -36,8 +36,7 @@ bool current_is_single_threaded(void)
if (unlikely(p == task->group_leader))
continue;
t = p;
do {
for_each_thread(p, t) {
if (unlikely(t->mm == mm))
goto found;
if (likely(t->mm))
@@ -48,7 +47,7 @@ bool current_is_single_threaded(void)
* forked before exiting.
*/
smp_rmb();
} while_each_thread(p, t);
}
}
ret = true;
found:
+16
View File
@@ -31,6 +31,22 @@ char *kvasprintf(gfp_t gfp, const char *fmt, va_list ap)
}
EXPORT_SYMBOL(kvasprintf);
/*
* If fmt contains no % (or is exactly %s), use kstrdup_const. If fmt
* (or the sole vararg) points to rodata, we will then save a memory
* allocation and string copy. In any case, the return value should be
* freed using kfree_const().
*/
const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list ap)
{
if (!strchr(fmt, '%'))
return kstrdup_const(fmt, gfp);
if (!strcmp(fmt, "%s"))
return kstrdup_const(va_arg(ap, const char*), gfp);
return kvasprintf(gfp, fmt, ap);
}
EXPORT_SYMBOL(kvasprintf_const);
char *kasprintf(gfp_t gfp, const char *fmt, ...)
{
va_list ap;
+22 -8
View File
@@ -257,18 +257,32 @@ static int kobject_add_internal(struct kobject *kobj)
int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
va_list vargs)
{
char *s;
const char *s;
if (kobj->name && !fmt)
return 0;
s = kvasprintf(GFP_KERNEL, fmt, vargs);
s = kvasprintf_const(GFP_KERNEL, fmt, vargs);
if (!s)
return -ENOMEM;
/* ewww... some of these buggers have '/' in the name ... */
strreplace(s, '/', '!');
kfree(kobj->name);
/*
* ewww... some of these buggers have '/' in the name ... If
* that's the case, we need to make sure we have an actual
* allocated copy to modify, since kvasprintf_const may have
* returned something from .rodata.
*/
if (strchr(s, '/')) {
char *t;
t = kstrdup(s, GFP_KERNEL);
kfree_const(s);
if (!t)
return -ENOMEM;
strreplace(t, '/', '!');
s = t;
}
kfree_const(kobj->name);
kobj->name = s;
return 0;
@@ -466,7 +480,7 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
envp[0] = devpath_string;
envp[1] = NULL;
name = dup_name = kstrdup(new_name, GFP_KERNEL);
name = dup_name = kstrdup_const(new_name, GFP_KERNEL);
if (!name) {
error = -ENOMEM;
goto out;
@@ -486,7 +500,7 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
kobject_uevent_env(kobj, KOBJ_MOVE, envp);
out:
kfree(dup_name);
kfree_const(dup_name);
kfree(devpath_string);
kfree(devpath);
kobject_put(kobj);
@@ -634,7 +648,7 @@ static void kobject_cleanup(struct kobject *kobj)
/* free name if we allocated it */
if (name) {
pr_debug("kobject: '%s': free name\n", name);
kfree(name);
kfree_const(name);
}
}
+2 -2
View File
@@ -66,12 +66,12 @@ struct llist_node *llist_del_first(struct llist_head *head)
{
struct llist_node *entry, *old_entry, *next;
entry = head->first;
entry = smp_load_acquire(&head->first);
for (;;) {
if (entry == NULL)
return NULL;
old_entry = entry;
next = entry->next;
next = READ_ONCE(entry->next);
entry = cmpxchg(&head->first, old_entry, next);
if (entry == old_entry)
break;
+1 -1
View File
@@ -135,7 +135,7 @@ static inline unsigned alloc_local_tag(struct percpu_ida_cpu *tags)
* TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, of course).
*
* @gfp indicates whether or not to wait until a free id is available (it's not
* used for internal memory allocations); thus if passed __GFP_WAIT we may sleep
* used for internal memory allocations); thus if passed __GFP_RECLAIM we may sleep
* however long it takes until another thread frees an id (same semantics as a
* mempool).
*
+5 -5
View File
@@ -188,7 +188,7 @@ radix_tree_node_alloc(struct radix_tree_root *root)
* preloading in the interrupt anyway as all the allocations have to
* be atomic. So just do normal allocation when in interrupt.
*/
if (!(gfp_mask & __GFP_WAIT) && !in_interrupt()) {
if (!gfpflags_allow_blocking(gfp_mask) && !in_interrupt()) {
struct radix_tree_preload *rtp;
/*
@@ -249,7 +249,7 @@ radix_tree_node_free(struct radix_tree_node *node)
* with preemption not disabled.
*
* To make use of this facility, the radix tree must be initialised without
* __GFP_WAIT being passed to INIT_RADIX_TREE().
* __GFP_DIRECT_RECLAIM being passed to INIT_RADIX_TREE().
*/
static int __radix_tree_preload(gfp_t gfp_mask)
{
@@ -286,12 +286,12 @@ out:
* with preemption not disabled.
*
* To make use of this facility, the radix tree must be initialised without
* __GFP_WAIT being passed to INIT_RADIX_TREE().
* __GFP_DIRECT_RECLAIM being passed to INIT_RADIX_TREE().
*/
int radix_tree_preload(gfp_t gfp_mask)
{
/* Warn on non-sensical use... */
WARN_ON_ONCE(!(gfp_mask & __GFP_WAIT));
WARN_ON_ONCE(!gfpflags_allow_blocking(gfp_mask));
return __radix_tree_preload(gfp_mask);
}
EXPORT_SYMBOL(radix_tree_preload);
@@ -303,7 +303,7 @@ EXPORT_SYMBOL(radix_tree_preload);
*/
int radix_tree_maybe_preload(gfp_t gfp_mask)
{
if (gfp_mask & __GFP_WAIT)
if (gfpflags_allow_blocking(gfp_mask))
return __radix_tree_preload(gfp_mask);
/* Preloading doesn't help anything with this gfp mask, skip it */
preempt_disable();
+36
View File
@@ -326,6 +326,39 @@ out:
kfree(out_test);
}
#define string_get_size_maxbuf 16
#define test_string_get_size_one(size, blk_size, units, exp_result) \
do { \
BUILD_BUG_ON(sizeof(exp_result) >= string_get_size_maxbuf); \
__test_string_get_size((size), (blk_size), (units), \
(exp_result)); \
} while (0)
static __init void __test_string_get_size(const u64 size, const u64 blk_size,
const enum string_size_units units,
const char *exp_result)
{
char buf[string_get_size_maxbuf];
string_get_size(size, blk_size, units, buf, sizeof(buf));
if (!memcmp(buf, exp_result, strlen(exp_result) + 1))
return;
buf[sizeof(buf) - 1] = '\0';
pr_warn("Test 'test_string_get_size_one' failed!\n");
pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %d\n",
size, blk_size, units);
pr_warn("expected: '%s', got '%s'\n", exp_result, buf);
}
static __init void test_string_get_size(void)
{
test_string_get_size_one(16384, 512, STRING_UNITS_2, "8.00 MiB");
test_string_get_size_one(8192, 4096, STRING_UNITS_10, "32.7 MB");
test_string_get_size_one(1, 512, STRING_UNITS_10, "512 B");
}
static int __init test_string_helpers_init(void)
{
unsigned int i;
@@ -344,6 +377,9 @@ static int __init test_string_helpers_init(void)
for (i = 0; i < (ESCAPE_ANY_NP | ESCAPE_HEX) + 1; i++)
test_string_escape("escape 1", escape1, i, TEST_STRING_2_DICT_1);
/* Test string_get_size() */
test_string_get_size();
return -EINVAL;
}
module_init(test_string_helpers_init);
+362
View File
@@ -0,0 +1,362 @@
/*
* Test cases for printf facility.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/in.h>
#define BUF_SIZE 256
#define FILL_CHAR '$'
#define PTR1 ((void*)0x01234567)
#define PTR2 ((void*)(long)(int)0xfedcba98)
#if BITS_PER_LONG == 64
#define PTR1_ZEROES "000000000"
#define PTR1_SPACES " "
#define PTR1_STR "1234567"
#define PTR2_STR "fffffffffedcba98"
#define PTR_WIDTH 16
#else
#define PTR1_ZEROES "0"
#define PTR1_SPACES " "
#define PTR1_STR "1234567"
#define PTR2_STR "fedcba98"
#define PTR_WIDTH 8
#endif
#define PTR_WIDTH_STR stringify(PTR_WIDTH)
static unsigned total_tests __initdata;
static unsigned failed_tests __initdata;
static char *test_buffer __initdata;
static int __printf(4, 0) __init
do_test(int bufsize, const char *expect, int elen,
const char *fmt, va_list ap)
{
va_list aq;
int ret, written;
total_tests++;
memset(test_buffer, FILL_CHAR, BUF_SIZE);
va_copy(aq, ap);
ret = vsnprintf(test_buffer, bufsize, fmt, aq);
va_end(aq);
if (ret != elen) {
pr_warn("vsnprintf(buf, %d, \"%s\", ...) returned %d, expected %d\n",
bufsize, fmt, ret, elen);
return 1;
}
if (!bufsize) {
if (memchr_inv(test_buffer, FILL_CHAR, BUF_SIZE)) {
pr_warn("vsnprintf(buf, 0, \"%s\", ...) wrote to buffer\n",
fmt);
return 1;
}
return 0;
}
written = min(bufsize-1, elen);
if (test_buffer[written]) {
pr_warn("vsnprintf(buf, %d, \"%s\", ...) did not nul-terminate buffer\n",
bufsize, fmt);
return 1;
}
if (memcmp(test_buffer, expect, written)) {
pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n",
bufsize, fmt, test_buffer, written, expect);
return 1;
}
return 0;
}
static void __printf(3, 4) __init
__test(const char *expect, int elen, const char *fmt, ...)
{
va_list ap;
int rand;
char *p;
BUG_ON(elen >= BUF_SIZE);
va_start(ap, fmt);
/*
* Every fmt+args is subjected to four tests: Three where we
* tell vsnprintf varying buffer sizes (plenty, not quite
* enough and 0), and then we also test that kvasprintf would
* be able to print it as expected.
*/
failed_tests += do_test(BUF_SIZE, expect, elen, fmt, ap);
rand = 1 + prandom_u32_max(elen+1);
/* Since elen < BUF_SIZE, we have 1 <= rand <= BUF_SIZE. */
failed_tests += do_test(rand, expect, elen, fmt, ap);
failed_tests += do_test(0, expect, elen, fmt, ap);
p = kvasprintf(GFP_KERNEL, fmt, ap);
if (p) {
if (memcmp(p, expect, elen+1)) {
pr_warn("kvasprintf(..., \"%s\", ...) returned '%s', expected '%s'\n",
fmt, p, expect);
failed_tests++;
}
kfree(p);
}
va_end(ap);
}
#define test(expect, fmt, ...) \
__test(expect, strlen(expect), fmt, ##__VA_ARGS__)
static void __init
test_basic(void)
{
/* Work around annoying "warning: zero-length gnu_printf format string". */
char nul = '\0';
test("", &nul);
test("100%", "100%%");
test("xxx%yyy", "xxx%cyyy", '%');
__test("xxx\0yyy", 7, "xxx%cyyy", '\0');
}
static void __init
test_number(void)
{
test("0x1234abcd ", "%#-12x", 0x1234abcd);
test(" 0x1234abcd", "%#12x", 0x1234abcd);
test("0|001| 12|+123| 1234|-123|-1234", "%d|%03d|%3d|%+d|% d|%+d|% d", 0, 1, 12, 123, 1234, -123, -1234);
}
static void __init
test_string(void)
{
test("", "%s%.0s", "", "123");
test("ABCD|abc|123", "%s|%.3s|%.*s", "ABCD", "abcdef", 3, "123456");
test("1 | 2|3 | 4|5 ", "%-3s|%3s|%-*s|%*s|%*s", "1", "2", 3, "3", 3, "4", -3, "5");
/*
* POSIX and C99 say that a missing precision should be
* treated as a precision of 0. However, the kernel's printf
* implementation treats this case as if the . wasn't
* present. Let's add a test case documenting the current
* behaviour; should anyone ever feel the need to follow the
* standards more closely, this can be revisited.
*/
test("a||", "%.s|%.0s|%.*s", "a", "b", 0, "c");
test("a | | ", "%-3.s|%-3.0s|%-3.*s", "a", "b", 0, "c");
}
static void __init
plain(void)
{
test(PTR1_ZEROES PTR1_STR " " PTR2_STR, "%p %p", PTR1, PTR2);
/*
* The field width is overloaded for some %p extensions to
* pass another piece of information. For plain pointers, the
* behaviour is slightly odd: One cannot pass either the 0
* flag nor a precision to %p without gcc complaining, and if
* one explicitly gives a field width, the number is no longer
* zero-padded.
*/
test("|" PTR1_STR PTR1_SPACES " | " PTR1_SPACES PTR1_STR "|",
"|%-*p|%*p|", PTR_WIDTH+2, PTR1, PTR_WIDTH+2, PTR1);
test("|" PTR2_STR " | " PTR2_STR "|",
"|%-*p|%*p|", PTR_WIDTH+2, PTR2, PTR_WIDTH+2, PTR2);
/*
* Unrecognized %p extensions are treated as plain %p, but the
* alphanumeric suffix is ignored (that is, does not occur in
* the output.)
*/
test("|"PTR1_ZEROES PTR1_STR"|", "|%p0y|", PTR1);
test("|"PTR2_STR"|", "|%p0y|", PTR2);
}
static void __init
symbol_ptr(void)
{
}
static void __init
kernel_ptr(void)
{
}
static void __init
struct_resource(void)
{
}
static void __init
addr(void)
{
}
static void __init
escaped_str(void)
{
}
static void __init
hex_string(void)
{
const char buf[3] = {0xc0, 0xff, 0xee};
test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee",
"%3ph|%3phC|%3phD|%3phN", buf, buf, buf, buf);
test("c0 ff ee|c0:ff:ee|c0-ff-ee|c0ffee",
"%*ph|%*phC|%*phD|%*phN", 3, buf, 3, buf, 3, buf, 3, buf);
}
static void __init
mac(void)
{
const u8 addr[6] = {0x2d, 0x48, 0xd6, 0xfc, 0x7a, 0x05};
test("2d:48:d6:fc:7a:05", "%pM", addr);
test("05:7a:fc:d6:48:2d", "%pMR", addr);
test("2d-48-d6-fc-7a-05", "%pMF", addr);
test("2d48d6fc7a05", "%pm", addr);
test("057afcd6482d", "%pmR", addr);
}
static void __init
ip4(void)
{
struct sockaddr_in sa;
sa.sin_family = AF_INET;
sa.sin_port = cpu_to_be16(12345);
sa.sin_addr.s_addr = cpu_to_be32(0x7f000001);
test("127.000.000.001|127.0.0.1", "%pi4|%pI4", &sa.sin_addr, &sa.sin_addr);
test("127.000.000.001|127.0.0.1", "%piS|%pIS", &sa, &sa);
sa.sin_addr.s_addr = cpu_to_be32(0x01020304);
test("001.002.003.004:12345|1.2.3.4:12345", "%piSp|%pISp", &sa, &sa);
}
static void __init
ip6(void)
{
}
static void __init
ip(void)
{
ip4();
ip6();
}
static void __init
uuid(void)
{
const char uuid[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
test("00010203-0405-0607-0809-0a0b0c0d0e0f", "%pUb", uuid);
test("00010203-0405-0607-0809-0A0B0C0D0E0F", "%pUB", uuid);
test("03020100-0504-0706-0809-0a0b0c0d0e0f", "%pUl", uuid);
test("03020100-0504-0706-0809-0A0B0C0D0E0F", "%pUL", uuid);
}
static void __init
dentry(void)
{
}
static void __init
struct_va_format(void)
{
}
static void __init
struct_clk(void)
{
}
static void __init
bitmap(void)
{
DECLARE_BITMAP(bits, 20);
const int primes[] = {2,3,5,7,11,13,17,19};
int i;
bitmap_zero(bits, 20);
test("00000|00000", "%20pb|%*pb", bits, 20, bits);
test("|", "%20pbl|%*pbl", bits, 20, bits);
for (i = 0; i < ARRAY_SIZE(primes); ++i)
set_bit(primes[i], bits);
test("a28ac|a28ac", "%20pb|%*pb", bits, 20, bits);
test("2-3,5,7,11,13,17,19|2-3,5,7,11,13,17,19", "%20pbl|%*pbl", bits, 20, bits);
bitmap_fill(bits, 20);
test("fffff|fffff", "%20pb|%*pb", bits, 20, bits);
test("0-19|0-19", "%20pbl|%*pbl", bits, 20, bits);
}
static void __init
netdev_features(void)
{
}
static void __init
test_pointer(void)
{
plain();
symbol_ptr();
kernel_ptr();
struct_resource();
addr();
escaped_str();
hex_string();
mac();
ip();
uuid();
dentry();
struct_va_format();
struct_clk();
bitmap();
netdev_features();
}
static int __init
test_printf_init(void)
{
test_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
if (!test_buffer)
return -ENOMEM;
test_basic();
test_number();
test_string();
test_pointer();
kfree(test_buffer);
if (failed_tests == 0)
pr_info("all %u tests passed\n", total_tests);
else
pr_warn("failed %u out of %u tests\n", failed_tests, total_tests);
return failed_tests ? -EINVAL : 0;
}
module_init(test_printf_init);
MODULE_AUTHOR("Rasmus Villemoes <linux@rasmusvillemoes.dk>");
MODULE_LICENSE("GPL");
+34 -46
View File
@@ -1449,6 +1449,8 @@ int kptr_restrict __read_mostly;
* (legacy clock framework) of the clock
* - 'Cr' For a clock, it prints the current rate of the clock
*
* ** Please update also Documentation/printk-formats.txt when making changes **
*
* Note: The difference between 'S' and 'F' is that on ia64 and ppc64
* function pointers are really function descriptors, which contain a
* pointer to the real address.
@@ -1457,7 +1459,7 @@ static noinline_for_stack
char *pointer(const char *fmt, char *buf, char *end, void *ptr,
struct printf_spec spec)
{
int default_width = 2 * sizeof(void *) + (spec.flags & SPECIAL ? 2 : 0);
const int default_width = 2 * sizeof(void *);
if (!ptr && *fmt != 'K') {
/*
@@ -1769,14 +1771,14 @@ qualifier:
case 'n':
/*
* Since %n poses a greater security risk than utility, treat
* it as an invalid format specifier. Warn about its use so
* that new instances don't get added.
* Since %n poses a greater security risk than
* utility, treat it as any other invalid or
* unsupported format specifier.
*/
WARN_ONCE(1, "Please remove ignored %%n in '%s'\n", fmt);
/* Fall-through */
default:
WARN_ONCE(1, "Please remove unsupported %%%c in format string\n", *fmt);
spec->type = FORMAT_TYPE_INVALID;
return fmt - start;
}
@@ -1811,41 +1813,16 @@ qualifier:
* @fmt: The format string to use
* @args: Arguments for the format string
*
* This function follows C99 vsnprintf, but has some extensions:
* %pS output the name of a text symbol with offset
* %ps output the name of a text symbol without offset
* %pF output the name of a function pointer with its offset
* %pf output the name of a function pointer without its offset
* %pB output the name of a backtrace symbol with its offset
* %pR output the address range in a struct resource with decoded flags
* %pr output the address range in a struct resource with raw flags
* %pb output the bitmap with field width as the number of bits
* %pbl output the bitmap as range list with field width as the number of bits
* %pM output a 6-byte MAC address with colons
* %pMR output a 6-byte MAC address with colons in reversed order
* %pMF output a 6-byte MAC address with dashes
* %pm output a 6-byte MAC address without colons
* %pmR output a 6-byte MAC address without colons in reversed order
* %pI4 print an IPv4 address without leading zeros
* %pi4 print an IPv4 address with leading zeros
* %pI6 print an IPv6 address with colons
* %pi6 print an IPv6 address without colons
* %pI6c print an IPv6 address as specified by RFC 5952
* %pIS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address
* %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address
* %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper
* case.
* %*pE[achnops] print an escaped buffer
* %*ph[CDN] a variable-length hex string with a separator (supports up to 64
* bytes of the input)
* %pC output the name (Common Clock Framework) or address (legacy clock
* framework) of a clock
* %pCn output the name (Common Clock Framework) or address (legacy clock
* framework) of a clock
* %pCr output the current rate of a clock
* %n is ignored
* This function generally follows C99 vsnprintf, but has some
* extensions and a few limitations:
*
* ** Please update Documentation/printk-formats.txt when making changes **
* %n is unsupported
* %p* is handled by pointer()
*
* See pointer() or Documentation/printk-formats.txt for more
* extensive description.
*
* ** Please update the documentation in both places when making changes **
*
* The return value is the number of characters which would
* be generated for the given input, excluding the trailing
@@ -1944,10 +1921,15 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
break;
case FORMAT_TYPE_INVALID:
if (str < end)
*str = '%';
++str;
break;
/*
* Presumably the arguments passed gcc's type
* checking, but there is no safe or sane way
* for us to continue parsing the format and
* fetching from the va_list; the remaining
* specifiers and arguments would be out of
* sync.
*/
goto out;
default:
switch (spec.type) {
@@ -1992,6 +1974,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
}
}
out:
if (size > 0) {
if (str < end)
*str = '\0';
@@ -2189,9 +2172,10 @@ do { \
switch (spec.type) {
case FORMAT_TYPE_NONE:
case FORMAT_TYPE_INVALID:
case FORMAT_TYPE_PERCENT_CHAR:
break;
case FORMAT_TYPE_INVALID:
goto out;
case FORMAT_TYPE_WIDTH:
case FORMAT_TYPE_PRECISION:
@@ -2253,6 +2237,7 @@ do { \
}
}
out:
return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf;
#undef save_arg
}
@@ -2286,7 +2271,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
char *str, *end;
const char *args = (const char *)bin_buf;
if (WARN_ON_ONCE((int) size < 0))
if (WARN_ON_ONCE(size > INT_MAX))
return 0;
str = buf;
@@ -2375,12 +2360,14 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
break;
case FORMAT_TYPE_PERCENT_CHAR:
case FORMAT_TYPE_INVALID:
if (str < end)
*str = '%';
++str;
break;
case FORMAT_TYPE_INVALID:
goto out;
default: {
unsigned long long num;
@@ -2423,6 +2410,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
} /* switch(spec.type) */
} /* while(*fmt) */
out:
if (size > 0) {
if (str < end)
*str = '\0';