Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
54edeb03
Commit
54edeb03
authored
Oct 24, 2018
by
Petr Mladek
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-4.20-vsprintf-hash-fixes' into for-linus
parents
d2130e82
431bca24
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
110 additions
and
111 deletions
+110
-111
Documentation/core-api/printk-formats.rst
Documentation/core-api/printk-formats.rst
+2
-3
lib/vsprintf.c
lib/vsprintf.c
+108
-108
No files found.
Documentation/core-api/printk-formats.rst
View file @
54edeb03
...
...
@@ -420,9 +420,8 @@ struct clk
%pC pll1
%pCn pll1
For printing struct clk structures. %pC and %pCn print the name
(Common Clock Framework) or address (legacy clock framework) of the
structure.
For printing struct clk structures. %pC and %pCn print the name of the clock
(Common Clock Framework) or a unique 32-bit ID (legacy clock framework).
Passed by reference.
...
...
lib/vsprintf.c
View file @
54edeb03
...
...
@@ -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
(
&
not_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
(
&
not_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
(
&
not_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
(
&
not_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
(
&
not_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
(
&
not_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
...
...
@@ -1944,7 +1944,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'
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment