mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
UPSTREAM: lib/vsprintf: Prepare for more general use of ptr_to_id()
Move the function and its dependencies up so it can be called from special pointer type formatting routines. Bug: 78533979 Link: http://lkml.kernel.org/r/20181011084249.4520-2-geert+renesas@glider.be To: "Tobin C . Harding" <me@tobin.cc> To: Andrew Morton <akpm@linux-foundation.org> To: Jonathan Corbet <corbet@lwn.net> Cc: linux-doc@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> [pmladek@suse.com: Split into separate patch] Signed-off-by: Petr Mladek <pmladek@suse.com> (cherry picked from commit 9073dac14e397f26603b14d5c0929186a0404a53) Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I8331506dc5b873ae333312e0614f5ad2c37c4f7e
This commit is contained in:
parent
8fd5652b23
commit
eb8143f946
172
lib/vsprintf.c
172
lib/vsprintf.c
@ -629,6 +629,92 @@ 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);
|
||||
}
|
||||
|
||||
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 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)
|
||||
{
|
||||
unsigned long hashval;
|
||||
const int default_width = 2 * sizeof(ptr);
|
||||
|
||||
if (static_branch_unlikely(¬_filled_random_ptr_key)) {
|
||||
spec.field_width = default_width;
|
||||
/* string length must be less than default_width */
|
||||
return string(buf, end, "(ptrval)", 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
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static noinline_for_stack
|
||||
char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_spec spec,
|
||||
const char *fmt)
|
||||
@ -1669,92 +1755,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
|
||||
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 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 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)
|
||||
{
|
||||
unsigned long hashval;
|
||||
const int default_width = 2 * sizeof(ptr);
|
||||
|
||||
if (static_branch_unlikely(¬_filled_random_ptr_key)) {
|
||||
spec.field_width = default_width;
|
||||
/* string length must be less than default_width */
|
||||
return string(buf, end, "(ptrval)", 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
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Show a '%p' thing. A kernel extension is that the '%p' is followed
|
||||
* by an extra set of alphanumeric characters that are extended format
|
||||
|
Loading…
x
Reference in New Issue
Block a user