mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 05:31:15 +00:00
Printk changes for 4.20
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJb0GRmAAoJEFKgDEdIgJTy/IEQAKOC4fHonA5LUa8GEO7s+byX LNQzH/NAR+86CCKdWzaiCpyNEbwzXC/5kFuGB+NIKGrutQ+HO1haKG6URRvZiw0c YgxaRpJ1h5OfZNuCjql5dX/bFAuBPwEPUAPusA4YJYSiXota2O76OW+RwEpr71i5 /Z2ygi3nlPECOhS1jTwY+cxGci67cfBIzKKdTXEft53xO38xAp0+Ea5Ljf2kIbgl rNz6XqJcy7rcAwEvh1kHw0AVEauLWs4NRlLX5eX7FHnqoh4TVFxWhLfNKirRo7gb vHemuucVUdvgG8yoFyg9CkFNLIMV9fWyDXkxab7dvrgD61oceLbNZ7dL86eijz7j qBoQy/igiH1nqIiczhTtp+JltIMzjPmC3unaie7f+oTHnKinzAaaND3wUjqObdZm MZQWsjIpBXC1nIcIs35NZiVMs8xcOG/sekkRcjU6/kbrBkoRqR5xhbm/tIcaCj0Z wKTlgET9b4dnmX8ZiEpvrfeMGxEu4yqfh1O3rvKnk8hKgxTvnzsSriHKh86KSv1L Gby4BA1zYwQxsJJ6LZMJjtHptxKBTcLANx8C/E9wPETP4EM5A1m5egJYRlDW3hb9 MhM4vzUQfq63b9gPduP10jlLrXsWBQRAcAvtvm2lou3TNqipm6ZqVn9vqkv0retR Auk7mO33MVpHbDOQw1GK =N+Ts -----END PGP SIGNATURE----- Merge tag 'printk-for-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk Pull printk updates from Petr Mladek: - Fix two more locations where printf formatting leaked pointers - Better log_buf_len parameter handling - Add prefix to messages from printk code - Do not miss messages on other consoles when the log is replayed on a new one - Reduce race between console registration and panic() when the log might get replayed on all consoles - Some cont buffer code clean up - Call console only when there is something to do (log vs cont buffer) * tag 'printk-for-4.20' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk: lib/vsprintf: Hash printed address for netdev bits fallback lib/vsprintf: Hash legacy clock addresses lib/vsprintf: Prepare for more general use of ptr_to_id() lib/vsprintf: Make ptr argument conts in ptr_to_id() printk: fix integer overflow in setup_log_buf() printk: do not preliminary split up cont buffer printk: lock/unlock console only for new logbuf entries printk: keep kernel cont support always enabled printk: Give error on attempt to set log buffer length to over 2G printk: Add KBUILD_MODNAME and remove a redundant print prefix printk: Correct wrong casting printk: Fix panic caused by passing log_buf_len to command line printk: CON_PRINTBUFFER console registration is a bit racy printk: Do not miss new messages when replaying the log
This commit is contained in:
commit
a67eefad99
3 changed files with 158 additions and 149 deletions
216
lib/vsprintf.c
216
lib/vsprintf.c
|
@ -612,6 +612,109 @@ char *string(char *buf, char *end, const char *s, struct printf_spec spec)
|
|||
return widen_string(buf, len, 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);
|
||||
}
|
||||
|
||||
/* Make pointers available for printing early in the boot sequence. */
|
||||
static int debug_boot_weak_hash __ro_after_init;
|
||||
|
||||
static int __init debug_boot_weak_hash_enable(char *str)
|
||||
{
|
||||
debug_boot_weak_hash = 1;
|
||||
pr_info("debug_boot_weak_hash enabled\n");
|
||||
return 0;
|
||||
}
|
||||
early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable);
|
||||
|
||||
static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key);
|
||||
static siphash_key_t ptr_key __read_mostly;
|
||||
|
||||
static void enable_ptr_key_workfn(struct work_struct *work)
|
||||
{
|
||||
get_random_bytes(&ptr_key, sizeof(ptr_key));
|
||||
/* Needs to run from preemptible context */
|
||||
static_branch_disable(¬_filled_random_ptr_key);
|
||||
}
|
||||
|
||||
static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn);
|
||||
|
||||
static void fill_random_ptr_key(struct random_ready_callback *unused)
|
||||
{
|
||||
/* This may be in an interrupt handler. */
|
||||
queue_work(system_unbound_wq, &enable_ptr_key_work);
|
||||
}
|
||||
|
||||
static struct random_ready_callback random_ready = {
|
||||
.func = fill_random_ptr_key
|
||||
};
|
||||
|
||||
static int __init initialize_ptr_random(void)
|
||||
{
|
||||
int key_size = sizeof(ptr_key);
|
||||
int ret;
|
||||
|
||||
/* Use hw RNG if available. */
|
||||
if (get_random_bytes_arch(&ptr_key, key_size) == key_size) {
|
||||
static_branch_disable(¬_filled_random_ptr_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = add_random_ready_callback(&random_ready);
|
||||
if (!ret) {
|
||||
return 0;
|
||||
} else if (ret == -EALREADY) {
|
||||
/* This is in preemptible context */
|
||||
enable_ptr_key_workfn(&enable_ptr_key_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
early_initcall(initialize_ptr_random);
|
||||
|
||||
/* Maps a pointer to a 32 bit unique identifier. */
|
||||
static char *ptr_to_id(char *buf, char *end, const void *ptr,
|
||||
struct printf_spec spec)
|
||||
{
|
||||
const char *str = sizeof(ptr) == 8 ? "(____ptrval____)" : "(ptrval)";
|
||||
unsigned long hashval;
|
||||
|
||||
/* When debugging early boot use non-cryptographically secure hash. */
|
||||
if (unlikely(debug_boot_weak_hash)) {
|
||||
hashval = hash_long((unsigned long)ptr, 32);
|
||||
return pointer_string(buf, end, (const void *)hashval, spec);
|
||||
}
|
||||
|
||||
if (static_branch_unlikely(¬_filled_random_ptr_key)) {
|
||||
spec.field_width = 2 * sizeof(ptr);
|
||||
/* string length must be less than default_width */
|
||||
return string(buf, end, str, spec);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key);
|
||||
/*
|
||||
* Mask off the first 32 bits, this makes explicit that we have
|
||||
* modified the address (and 32 bits is plenty for a unique ID).
|
||||
*/
|
||||
hashval = hashval & 0xffffffff;
|
||||
#else
|
||||
hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key);
|
||||
#endif
|
||||
return pointer_string(buf, end, (const void *)hashval, spec);
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_spec spec,
|
||||
const char *fmt)
|
||||
|
@ -1357,20 +1460,6 @@ char *uuid_string(char *buf, char *end, const u8 *addr,
|
|||
return string(buf, end, uuid, 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);
|
||||
}
|
||||
|
||||
int kptr_restrict __read_mostly;
|
||||
|
||||
static noinline_for_stack
|
||||
|
@ -1421,7 +1510,8 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
|
|||
}
|
||||
|
||||
static noinline_for_stack
|
||||
char *netdev_bits(char *buf, char *end, const void *addr, const char *fmt)
|
||||
char *netdev_bits(char *buf, char *end, const void *addr,
|
||||
struct printf_spec spec, const char *fmt)
|
||||
{
|
||||
unsigned long long num;
|
||||
int size;
|
||||
|
@ -1432,9 +1522,7 @@ char *netdev_bits(char *buf, char *end, const void *addr, const char *fmt)
|
|||
size = sizeof(netdev_features_t);
|
||||
break;
|
||||
default:
|
||||
num = (unsigned long)addr;
|
||||
size = sizeof(unsigned long);
|
||||
break;
|
||||
return ptr_to_id(buf, end, addr, spec);
|
||||
}
|
||||
|
||||
return special_hex_number(buf, end, num, size);
|
||||
|
@ -1474,7 +1562,7 @@ char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec,
|
|||
#ifdef CONFIG_COMMON_CLK
|
||||
return string(buf, end, __clk_get_name(clk), spec);
|
||||
#else
|
||||
return special_hex_number(buf, end, (unsigned long)clk, sizeof(unsigned long));
|
||||
return ptr_to_id(buf, end, clk, spec);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1651,94 +1739,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
|
|||
return widen_string(buf, buf - buf_start, end, spec);
|
||||
}
|
||||
|
||||
/* Make pointers available for printing early in the boot sequence. */
|
||||
static int debug_boot_weak_hash __ro_after_init;
|
||||
|
||||
static int __init debug_boot_weak_hash_enable(char *str)
|
||||
{
|
||||
debug_boot_weak_hash = 1;
|
||||
pr_info("debug_boot_weak_hash enabled\n");
|
||||
return 0;
|
||||
}
|
||||
early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable);
|
||||
|
||||
static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key);
|
||||
static siphash_key_t ptr_key __read_mostly;
|
||||
|
||||
static void enable_ptr_key_workfn(struct work_struct *work)
|
||||
{
|
||||
get_random_bytes(&ptr_key, sizeof(ptr_key));
|
||||
/* Needs to run from preemptible context */
|
||||
static_branch_disable(¬_filled_random_ptr_key);
|
||||
}
|
||||
|
||||
static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn);
|
||||
|
||||
static void fill_random_ptr_key(struct random_ready_callback *unused)
|
||||
{
|
||||
/* This may be in an interrupt handler. */
|
||||
queue_work(system_unbound_wq, &enable_ptr_key_work);
|
||||
}
|
||||
|
||||
static struct random_ready_callback random_ready = {
|
||||
.func = fill_random_ptr_key
|
||||
};
|
||||
|
||||
static int __init initialize_ptr_random(void)
|
||||
{
|
||||
int key_size = sizeof(ptr_key);
|
||||
int ret;
|
||||
|
||||
/* Use hw RNG if available. */
|
||||
if (get_random_bytes_arch(&ptr_key, key_size) == key_size) {
|
||||
static_branch_disable(¬_filled_random_ptr_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = add_random_ready_callback(&random_ready);
|
||||
if (!ret) {
|
||||
return 0;
|
||||
} else if (ret == -EALREADY) {
|
||||
/* This is in preemptible context */
|
||||
enable_ptr_key_workfn(&enable_ptr_key_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
early_initcall(initialize_ptr_random);
|
||||
|
||||
/* Maps a pointer to a 32 bit unique identifier. */
|
||||
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;
|
||||
|
||||
/* When debugging early boot use non-cryptographically secure hash. */
|
||||
if (unlikely(debug_boot_weak_hash)) {
|
||||
hashval = hash_long((unsigned long)ptr, 32);
|
||||
return pointer_string(buf, end, (const void *)hashval, spec);
|
||||
}
|
||||
|
||||
if (static_branch_unlikely(¬_filled_random_ptr_key)) {
|
||||
spec.field_width = 2 * sizeof(ptr);
|
||||
/* string length must be less than default_width */
|
||||
return string(buf, end, str, spec);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key);
|
||||
/*
|
||||
* Mask off the first 32 bits, this makes explicit that we have
|
||||
* modified the address (and 32 bits is plenty for a unique ID).
|
||||
*/
|
||||
hashval = hashval & 0xffffffff;
|
||||
#else
|
||||
hashval = (unsigned long)siphash_1u32((u32)ptr, &ptr_key);
|
||||
#endif
|
||||
return pointer_string(buf, end, (const void *)hashval, spec);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show a '%p' thing. A kernel extension is that the '%p' is followed
|
||||
* by an extra set of alphanumeric characters that are extended format
|
||||
|
@ -1942,7 +1942,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
|
|||
break;
|
||||
return restricted_pointer(buf, end, ptr, spec);
|
||||
case 'N':
|
||||
return netdev_bits(buf, end, ptr, fmt);
|
||||
return netdev_bits(buf, end, ptr, spec, fmt);
|
||||
case 'a':
|
||||
return address_val(buf, end, ptr, fmt);
|
||||
case 'd':
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue