Commit d75ae5bd authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'printk-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk

Pull printk updates from Petr Mladek:

 - Help userspace log daemons to catch up with a flood of messages. They
   will get woken after each message even if the console is far behind
   and handled by another process.

 - Flush printk safe buffers safely even when panic() happens in the
   normal context.

 - Fix possible va_list reuse when race happened in printk_safe().

 - Remove %pCr printf format to prevent sleeping in the atomic context.

 - Misc vsprintf code cleanup.

* tag 'printk-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk:
  printk: drop in_nmi check from printk_safe_flush_on_panic()
  lib/vsprintf: Remove atomic-unsafe support for %pCr
  serial: sh-sci: Stop using printk format %pCr
  thermal: bcm2835: Stop using printk format %pCr
  clk: renesas: cpg-mssr: Stop using printk format %pCr
  printk: fix possible reuse of va_list variable
  printk: wake up klogd in vprintk_emit
  vsprintf: Tweak pF/pf comment
  lib/vsprintf: Mark expected switch fall-through
  lib/vsprintf: Replace space with '_' before crng is ready
  lib/vsprintf: Deduplicate pointer_string()
  lib/vsprintf: Move pointer_string() upper
  lib/vsprintf: Make flag_spec global
  lib/vsprintf: Make strspec global
  lib/vsprintf: Make dec_spec global
  lib/test_printf: Mark big constant with UL
parents 0eb00613 8bafa2a4
...@@ -419,11 +419,10 @@ struct clk ...@@ -419,11 +419,10 @@ struct clk
%pC pll1 %pC pll1
%pCn pll1 %pCn pll1
%pCr 1560000000
For printing struct clk structures. %pC and %pCn print the name For printing struct clk structures. %pC and %pCn print the name
(Common Clock Framework) or address (legacy clock framework) of the (Common Clock Framework) or address (legacy clock framework) of the
structure; %pCr prints the current clock rate. structure.
Passed by reference. Passed by reference.
......
...@@ -258,8 +258,9 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, ...@@ -258,8 +258,9 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec,
dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
PTR_ERR(clk)); PTR_ERR(clk));
else else
dev_dbg(dev, "clock (%u, %u) is %pC at %pCr Hz\n", dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
clkspec->args[0], clkspec->args[1], clk, clk); clkspec->args[0], clkspec->args[1], clk,
clk_get_rate(clk));
return clk; return clk;
} }
...@@ -326,7 +327,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, ...@@ -326,7 +327,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
if (IS_ERR_OR_NULL(clk)) if (IS_ERR_OR_NULL(clk))
goto fail; goto fail;
dev_dbg(dev, "Core clock %pC at %pCr Hz\n", clk, clk); dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
priv->clks[id] = clk; priv->clks[id] = clk;
return; return;
...@@ -392,7 +393,7 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, ...@@ -392,7 +393,7 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
if (IS_ERR(clk)) if (IS_ERR(clk))
goto fail; goto fail;
dev_dbg(dev, "Module clock %pC at %pCr Hz\n", clk, clk); dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
priv->clks[id] = clk; priv->clks[id] = clk;
priv->smstpcr_saved[clock->index / 32].mask |= BIT(clock->index % 32); priv->smstpcr_saved[clock->index / 32].mask |= BIT(clock->index % 32);
return; return;
......
...@@ -213,8 +213,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) ...@@ -213,8 +213,8 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
rate = clk_get_rate(data->clk); rate = clk_get_rate(data->clk);
if ((rate < 1920000) || (rate > 5000000)) if ((rate < 1920000) || (rate > 5000000))
dev_warn(&pdev->dev, dev_warn(&pdev->dev,
"Clock %pCn running at %pCr Hz is outside of the recommended range: 1.92 to 5MHz\n", "Clock %pCn running at %lu Hz is outside of the recommended range: 1.92 to 5MHz\n",
data->clk, data->clk); data->clk, rate);
/* register of thermal sensor and get info from DT */ /* register of thermal sensor and get info from DT */
tz = thermal_zone_of_sensor_register(&pdev->dev, 0, data, tz = thermal_zone_of_sensor_register(&pdev->dev, 0, data,
......
...@@ -2724,8 +2724,8 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) ...@@ -2724,8 +2724,8 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev)
dev_dbg(dev, "failed to get %s (%ld)\n", clk_names[i], dev_dbg(dev, "failed to get %s (%ld)\n", clk_names[i],
PTR_ERR(clk)); PTR_ERR(clk));
else else
dev_dbg(dev, "clk %s is %pC rate %pCr\n", clk_names[i], dev_dbg(dev, "clk %s is %pC rate %lu\n", clk_names[i],
clk, clk); clk, clk_get_rate(clk));
sci_port->clks[i] = IS_ERR(clk) ? NULL : clk; sci_port->clks[i] = IS_ERR(clk) ? NULL : clk;
} }
return 0; return 0;
......
...@@ -1908,6 +1908,7 @@ asmlinkage int vprintk_emit(int facility, int level, ...@@ -1908,6 +1908,7 @@ asmlinkage int vprintk_emit(int facility, int level,
preempt_enable(); preempt_enable();
} }
wake_up_klogd();
return printed_len; return printed_len;
} }
EXPORT_SYMBOL(vprintk_emit); EXPORT_SYMBOL(vprintk_emit);
...@@ -2289,9 +2290,7 @@ void console_unlock(void) ...@@ -2289,9 +2290,7 @@ void console_unlock(void)
{ {
static char ext_text[CONSOLE_EXT_LOG_MAX]; static char ext_text[CONSOLE_EXT_LOG_MAX];
static char text[LOG_LINE_MAX + PREFIX_MAX]; static char text[LOG_LINE_MAX + PREFIX_MAX];
static u64 seen_seq;
unsigned long flags; unsigned long flags;
bool wake_klogd = false;
bool do_cond_resched, retry; bool do_cond_resched, retry;
if (console_suspended) { if (console_suspended) {
...@@ -2335,11 +2334,6 @@ void console_unlock(void) ...@@ -2335,11 +2334,6 @@ void console_unlock(void)
printk_safe_enter_irqsave(flags); printk_safe_enter_irqsave(flags);
raw_spin_lock(&logbuf_lock); raw_spin_lock(&logbuf_lock);
if (seen_seq != log_next_seq) {
wake_klogd = true;
seen_seq = log_next_seq;
}
if (console_seq < log_first_seq) { if (console_seq < log_first_seq) {
len = sprintf(text, "** %u printk messages dropped **\n", len = sprintf(text, "** %u printk messages dropped **\n",
(unsigned)(log_first_seq - console_seq)); (unsigned)(log_first_seq - console_seq));
...@@ -2397,7 +2391,7 @@ void console_unlock(void) ...@@ -2397,7 +2391,7 @@ void console_unlock(void)
if (console_lock_spinning_disable_and_check()) { if (console_lock_spinning_disable_and_check()) {
printk_safe_exit_irqrestore(flags); printk_safe_exit_irqrestore(flags);
goto out; return;
} }
printk_safe_exit_irqrestore(flags); printk_safe_exit_irqrestore(flags);
...@@ -2429,10 +2423,6 @@ void console_unlock(void) ...@@ -2429,10 +2423,6 @@ void console_unlock(void)
if (retry && console_trylock()) if (retry && console_trylock())
goto again; goto again;
out:
if (wake_klogd)
wake_up_klogd();
} }
EXPORT_SYMBOL(console_unlock); EXPORT_SYMBOL(console_unlock);
......
...@@ -82,6 +82,7 @@ static __printf(2, 0) int printk_safe_log_store(struct printk_safe_seq_buf *s, ...@@ -82,6 +82,7 @@ static __printf(2, 0) int printk_safe_log_store(struct printk_safe_seq_buf *s,
{ {
int add; int add;
size_t len; size_t len;
va_list ap;
again: again:
len = atomic_read(&s->len); len = atomic_read(&s->len);
...@@ -100,7 +101,9 @@ static __printf(2, 0) int printk_safe_log_store(struct printk_safe_seq_buf *s, ...@@ -100,7 +101,9 @@ static __printf(2, 0) int printk_safe_log_store(struct printk_safe_seq_buf *s,
if (!len) if (!len)
smp_rmb(); smp_rmb();
add = vscnprintf(s->buffer + len, sizeof(s->buffer) - len, fmt, args); va_copy(ap, args);
add = vscnprintf(s->buffer + len, sizeof(s->buffer) - len, fmt, ap);
va_end(ap);
if (!add) if (!add)
return 0; return 0;
...@@ -278,7 +281,7 @@ void printk_safe_flush_on_panic(void) ...@@ -278,7 +281,7 @@ void printk_safe_flush_on_panic(void)
* Make sure that we could access the main ring buffer. * Make sure that we could access the main ring buffer.
* Do not risk a double release when more CPUs are up. * Do not risk a double release when more CPUs are up.
*/ */
if (in_nmi() && raw_spin_is_locked(&logbuf_lock)) { if (raw_spin_is_locked(&logbuf_lock)) {
if (num_online_cpus() > 1) if (num_online_cpus() > 1)
return; return;
......
...@@ -204,7 +204,7 @@ test_string(void) ...@@ -204,7 +204,7 @@ test_string(void)
#if BITS_PER_LONG == 64 #if BITS_PER_LONG == 64
#define PTR_WIDTH 16 #define PTR_WIDTH 16
#define PTR ((void *)0xffff0123456789ab) #define PTR ((void *)0xffff0123456789abUL)
#define PTR_STR "ffff0123456789ab" #define PTR_STR "ffff0123456789ab"
#define ZEROS "00000000" /* hex 32 zero bits */ #define ZEROS "00000000" /* hex 32 zero bits */
......
...@@ -703,6 +703,22 @@ char *symbol_string(char *buf, char *end, void *ptr, ...@@ -703,6 +703,22 @@ char *symbol_string(char *buf, char *end, void *ptr,
#endif #endif
} }
static const struct printf_spec default_str_spec = {
.field_width = -1,
.precision = -1,
};
static const struct printf_spec default_flag_spec = {
.base = 16,
.precision = -1,
.flags = SPECIAL | SMALL,
};
static const struct printf_spec default_dec_spec = {
.base = 10,
.precision = -1,
};
static noinline_for_stack static noinline_for_stack
char *resource_string(char *buf, char *end, struct resource *res, char *resource_string(char *buf, char *end, struct resource *res,
struct printf_spec spec, const char *fmt) struct printf_spec spec, const char *fmt)
...@@ -732,21 +748,11 @@ char *resource_string(char *buf, char *end, struct resource *res, ...@@ -732,21 +748,11 @@ char *resource_string(char *buf, char *end, struct resource *res,
.precision = -1, .precision = -1,
.flags = SMALL | ZEROPAD, .flags = SMALL | ZEROPAD,
}; };
static const struct printf_spec dec_spec = {
.base = 10,
.precision = -1,
.flags = 0,
};
static const struct printf_spec str_spec = { static const struct printf_spec str_spec = {
.field_width = -1, .field_width = -1,
.precision = 10, .precision = 10,
.flags = LEFT, .flags = LEFT,
}; };
static const struct printf_spec flag_spec = {
.base = 16,
.precision = -1,
.flags = SPECIAL | SMALL,
};
/* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8) /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8)
* 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */ * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */
...@@ -770,10 +776,10 @@ char *resource_string(char *buf, char *end, struct resource *res, ...@@ -770,10 +776,10 @@ char *resource_string(char *buf, char *end, struct resource *res,
specp = &mem_spec; specp = &mem_spec;
} else if (res->flags & IORESOURCE_IRQ) { } else if (res->flags & IORESOURCE_IRQ) {
p = string(p, pend, "irq ", str_spec); p = string(p, pend, "irq ", str_spec);
specp = &dec_spec; specp = &default_dec_spec;
} else if (res->flags & IORESOURCE_DMA) { } else if (res->flags & IORESOURCE_DMA) {
p = string(p, pend, "dma ", str_spec); p = string(p, pend, "dma ", str_spec);
specp = &dec_spec; specp = &default_dec_spec;
} else if (res->flags & IORESOURCE_BUS) { } else if (res->flags & IORESOURCE_BUS) {
p = string(p, pend, "bus ", str_spec); p = string(p, pend, "bus ", str_spec);
specp = &bus_spec; specp = &bus_spec;
...@@ -803,7 +809,7 @@ char *resource_string(char *buf, char *end, struct resource *res, ...@@ -803,7 +809,7 @@ char *resource_string(char *buf, char *end, struct resource *res,
p = string(p, pend, " disabled", str_spec); p = string(p, pend, " disabled", str_spec);
} else { } else {
p = string(p, pend, " flags ", str_spec); p = string(p, pend, " flags ", str_spec);
p = number(p, pend, res->flags, flag_spec); p = number(p, pend, res->flags, default_flag_spec);
} }
*p++ = ']'; *p++ = ']';
*p = '\0'; *p = '\0';
...@@ -913,9 +919,6 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap, ...@@ -913,9 +919,6 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap,
int cur, rbot, rtop; int cur, rbot, rtop;
bool first = true; bool first = true;
/* reused to print numbers */
spec = (struct printf_spec){ .base = 10 };
rbot = cur = find_first_bit(bitmap, nr_bits); rbot = cur = find_first_bit(bitmap, nr_bits);
while (cur < nr_bits) { while (cur < nr_bits) {
rtop = cur; rtop = cur;
...@@ -930,13 +933,13 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap, ...@@ -930,13 +933,13 @@ char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap,
} }
first = false; first = false;
buf = number(buf, end, rbot, spec); buf = number(buf, end, rbot, default_dec_spec);
if (rbot < rtop) { if (rbot < rtop) {
if (buf < end) if (buf < end)
*buf = '-'; *buf = '-';
buf++; buf++;
buf = number(buf, end, rtop, spec); buf = number(buf, end, rtop, default_dec_spec);
} }
rbot = cur; rbot = cur;
...@@ -1354,11 +1357,9 @@ char *uuid_string(char *buf, char *end, const u8 *addr, ...@@ -1354,11 +1357,9 @@ char *uuid_string(char *buf, char *end, const u8 *addr,
return string(buf, end, uuid, spec); return string(buf, end, uuid, spec);
} }
int kptr_restrict __read_mostly;
static noinline_for_stack static noinline_for_stack
char *restricted_pointer(char *buf, char *end, const void *ptr, char *pointer_string(char *buf, char *end, const void *ptr,
struct printf_spec spec) struct printf_spec spec)
{ {
spec.base = 16; spec.base = 16;
spec.flags |= SMALL; spec.flags |= SMALL;
...@@ -1367,6 +1368,15 @@ char *restricted_pointer(char *buf, char *end, const void *ptr, ...@@ -1367,6 +1368,15 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
spec.flags |= ZEROPAD; spec.flags |= ZEROPAD;
} }
return number(buf, end, (unsigned long int)ptr, spec);
}
int kptr_restrict __read_mostly;
static noinline_for_stack
char *restricted_pointer(char *buf, char *end, const void *ptr,
struct printf_spec spec)
{
switch (kptr_restrict) { switch (kptr_restrict) {
case 0: case 0:
/* Always print %pK values */ /* Always print %pK values */
...@@ -1378,8 +1388,11 @@ char *restricted_pointer(char *buf, char *end, const void *ptr, ...@@ -1378,8 +1388,11 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
* kptr_restrict==1 cannot be used in IRQ context * kptr_restrict==1 cannot be used in IRQ context
* because its test for CAP_SYSLOG would be meaningless. * because its test for CAP_SYSLOG would be meaningless.
*/ */
if (in_irq() || in_serving_softirq() || in_nmi()) if (in_irq() || in_serving_softirq() || in_nmi()) {
if (spec.field_width == -1)
spec.field_width = 2 * sizeof(ptr);
return string(buf, end, "pK-error", spec); return string(buf, end, "pK-error", spec);
}
/* /*
* Only print the real pointer value if the current * Only print the real pointer value if the current
...@@ -1404,7 +1417,7 @@ char *restricted_pointer(char *buf, char *end, const void *ptr, ...@@ -1404,7 +1417,7 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
break; break;
} }
return number(buf, end, (unsigned long)ptr, spec); return pointer_string(buf, end, ptr, spec);
} }
static noinline_for_stack static noinline_for_stack
...@@ -1456,9 +1469,6 @@ char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec, ...@@ -1456,9 +1469,6 @@ char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec,
return string(buf, end, NULL, spec); return string(buf, end, NULL, spec);
switch (fmt[1]) { switch (fmt[1]) {
case 'r':
return number(buf, end, clk_get_rate(clk), spec);
case 'n': case 'n':
default: default:
#ifdef CONFIG_COMMON_CLK #ifdef CONFIG_COMMON_CLK
...@@ -1474,23 +1484,13 @@ char *format_flags(char *buf, char *end, unsigned long flags, ...@@ -1474,23 +1484,13 @@ char *format_flags(char *buf, char *end, unsigned long flags,
const struct trace_print_flags *names) const struct trace_print_flags *names)
{ {
unsigned long mask; unsigned long mask;
const struct printf_spec strspec = {
.field_width = -1,
.precision = -1,
};
const struct printf_spec numspec = {
.flags = SPECIAL|SMALL,
.field_width = -1,
.precision = -1,
.base = 16,
};
for ( ; flags && names->name; names++) { for ( ; flags && names->name; names++) {
mask = names->mask; mask = names->mask;
if ((flags & mask) != mask) if ((flags & mask) != mask)
continue; continue;
buf = string(buf, end, names->name, strspec); buf = string(buf, end, names->name, default_str_spec);
flags &= ~mask; flags &= ~mask;
if (flags) { if (flags) {
...@@ -1501,7 +1501,7 @@ char *format_flags(char *buf, char *end, unsigned long flags, ...@@ -1501,7 +1501,7 @@ char *format_flags(char *buf, char *end, unsigned long flags,
} }
if (flags) if (flags)
buf = number(buf, end, flags, numspec); buf = number(buf, end, flags, default_flag_spec);
return buf; return buf;
} }
...@@ -1548,22 +1548,18 @@ char *device_node_gen_full_name(const struct device_node *np, char *buf, char *e ...@@ -1548,22 +1548,18 @@ char *device_node_gen_full_name(const struct device_node *np, char *buf, char *e
{ {
int depth; int depth;
const struct device_node *parent = np->parent; const struct device_node *parent = np->parent;
static const struct printf_spec strspec = {
.field_width = -1,
.precision = -1,
};
/* special case for root node */ /* special case for root node */
if (!parent) if (!parent)
return string(buf, end, "/", strspec); return string(buf, end, "/", default_str_spec);
for (depth = 0; parent->parent; depth++) for (depth = 0; parent->parent; depth++)
parent = parent->parent; parent = parent->parent;
for ( ; depth >= 0; depth--) { for ( ; depth >= 0; depth--) {
buf = string(buf, end, "/", strspec); buf = string(buf, end, "/", default_str_spec);
buf = string(buf, end, device_node_name_for_depth(np, depth), buf = string(buf, end, device_node_name_for_depth(np, depth),
strspec); default_str_spec);
} }
return buf; return buf;
} }
...@@ -1655,20 +1651,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, ...@@ -1655,20 +1651,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
return widen_string(buf, buf - buf_start, end, spec); return widen_string(buf, buf - buf_start, end, spec);
} }
static noinline_for_stack
char *pointer_string(char *buf, char *end, const void *ptr,
struct printf_spec spec)
{
spec.base = 16;
spec.flags |= SMALL;
if (spec.field_width == -1) {
spec.field_width = 2 * sizeof(ptr);
spec.flags |= ZEROPAD;
}
return number(buf, end, (unsigned long int)ptr, spec);
}
static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key); static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key);
static siphash_key_t ptr_key __read_mostly; static siphash_key_t ptr_key __read_mostly;
...@@ -1710,13 +1692,13 @@ early_initcall(initialize_ptr_random); ...@@ -1710,13 +1692,13 @@ early_initcall(initialize_ptr_random);
/* Maps a pointer to a 32 bit unique identifier. */ /* Maps a pointer to a 32 bit unique identifier. */
static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
{ {
const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)";
unsigned long hashval; unsigned long hashval;
const int default_width = 2 * sizeof(ptr);
if (static_branch_unlikely(&not_filled_random_ptr_key)) { if (static_branch_unlikely(&not_filled_random_ptr_key)) {
spec.field_width = default_width; spec.field_width = 2 * sizeof(ptr);
/* string length must be less than default_width */ /* string length must be less than default_width */
return string(buf, end, "(ptrval)", spec); return string(buf, end, str, spec);
} }
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
...@@ -1729,15 +1711,7 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) ...@@ -1729,15 +1711,7 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
#else #else
hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key); hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key);
#endif #endif
return pointer_string(buf, end, (const void *)hashval, spec);
spec.flags |= SMALL;
if (spec.field_width == -1) {
spec.field_width = default_width;
spec.flags |= ZEROPAD;
}
spec.base = 16;
return number(buf, end, hashval, spec);
} }
/* /*
...@@ -1750,10 +1724,10 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) ...@@ -1750,10 +1724,10 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
* *
* Right now we handle: * Right now we handle:
* *
* - 'F' For symbolic function descriptor pointers with offset * - 'S' For symbolic direct pointers (or function descriptors) with offset
* - 'f' For simple symbolic function names without offset * - 's' For symbolic direct pointers (or function descriptors) without offset
* - 'S' For symbolic direct pointers with offset * - 'F' Same as 'S'
* - 's' For symbolic direct pointers without offset * - 'f' Same as 's'
* - '[FfSs]R' as above with __builtin_extract_return_addr() translation * - '[FfSs]R' as above with __builtin_extract_return_addr() translation
* - 'B' For backtraced symbolic direct pointers with offset * - 'B' For backtraced symbolic direct pointers with offset
* - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
...@@ -1850,10 +1824,6 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) ...@@ -1850,10 +1824,6 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
* ** When making changes please also update: * ** When making changes please also update:
* Documentation/core-api/printk-formats.rst * Documentation/core-api/printk-formats.rst
* *
* 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.
*
* Note: The default behaviour (unadorned %p) is to hash the address, * Note: The default behaviour (unadorned %p) is to hash the address,
* rendering it useful as a unique identifier. * rendering it useful as a unique identifier.
*/ */
...@@ -2129,6 +2099,7 @@ int format_decode(const char *fmt, struct printf_spec *spec) ...@@ -2129,6 +2099,7 @@ int format_decode(const char *fmt, struct printf_spec *spec)
case 'x': case 'x':
spec->flags |= SMALL; spec->flags |= SMALL;
/* fall through */
case 'X': case 'X':
spec->base = 16; spec->base = 16;
...@@ -3087,8 +3058,10 @@ int vsscanf(const char *buf, const char *fmt, va_list args) ...@@ -3087,8 +3058,10 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
break; break;
case 'i': case 'i':
base = 0; base = 0;
/* fall through */
case 'd': case 'd':
is_sign = true; is_sign = true;
/* fall through */
case 'u': case 'u':
break; break;
case '%': case '%':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment