2019-02-02 12:41:15 +03:00
// SPDX-License-Identifier: GPL-2.0
2013-12-20 14:02:18 +04:00
/*
* linux / drivers / efi / runtime - map . c
* Copyright ( C ) 2013 Red Hat , Inc . , Dave Young < dyoung @ redhat . com >
*/
# include <linux/string.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/types.h>
# include <linux/efi.h>
# include <linux/slab.h>
# include <asm/setup.h>
struct efi_runtime_map_entry {
efi_memory_desc_t md ;
struct kobject kobj ; /* kobject for each entry */
} ;
static struct efi_runtime_map_entry * * map_entries ;
struct map_attribute {
struct attribute attr ;
ssize_t ( * show ) ( struct efi_runtime_map_entry * entry , char * buf ) ;
} ;
static inline struct map_attribute * to_map_attr ( struct attribute * attr )
{
return container_of ( attr , struct map_attribute , attr ) ;
}
static ssize_t type_show ( struct efi_runtime_map_entry * entry , char * buf )
{
return snprintf ( buf , PAGE_SIZE , " 0x%x \n " , entry - > md . type ) ;
}
# define EFI_RUNTIME_FIELD(var) entry->md.var
# define EFI_RUNTIME_U64_ATTR_SHOW(name) \
static ssize_t name # # _show ( struct efi_runtime_map_entry * entry , char * buf ) \
{ \
return snprintf ( buf , PAGE_SIZE , " 0x%llx \n " , EFI_RUNTIME_FIELD ( name ) ) ; \
}
EFI_RUNTIME_U64_ATTR_SHOW ( phys_addr ) ;
EFI_RUNTIME_U64_ATTR_SHOW ( virt_addr ) ;
EFI_RUNTIME_U64_ATTR_SHOW ( num_pages ) ;
EFI_RUNTIME_U64_ATTR_SHOW ( attribute ) ;
static inline struct efi_runtime_map_entry * to_map_entry ( struct kobject * kobj )
{
return container_of ( kobj , struct efi_runtime_map_entry , kobj ) ;
}
static ssize_t map_attr_show ( struct kobject * kobj , struct attribute * attr ,
char * buf )
{
struct efi_runtime_map_entry * entry = to_map_entry ( kobj ) ;
struct map_attribute * map_attr = to_map_attr ( attr ) ;
return map_attr - > show ( entry , buf ) ;
}
2017-12-06 12:50:08 +03:00
static struct map_attribute map_type_attr = __ATTR_RO_MODE ( type , 0400 ) ;
static struct map_attribute map_phys_addr_attr = __ATTR_RO_MODE ( phys_addr , 0400 ) ;
static struct map_attribute map_virt_addr_attr = __ATTR_RO_MODE ( virt_addr , 0400 ) ;
static struct map_attribute map_num_pages_attr = __ATTR_RO_MODE ( num_pages , 0400 ) ;
static struct map_attribute map_attribute_attr = __ATTR_RO_MODE ( attribute , 0400 ) ;
2013-12-20 14:02:18 +04:00
/*
* These are default attributes that are added for every memmap entry .
*/
static struct attribute * def_attrs [ ] = {
& map_type_attr . attr ,
& map_phys_addr_attr . attr ,
& map_virt_addr_attr . attr ,
& map_num_pages_attr . attr ,
& map_attribute_attr . attr ,
NULL
} ;
static const struct sysfs_ops map_attr_ops = {
. show = map_attr_show ,
} ;
static void map_release ( struct kobject * kobj )
{
struct efi_runtime_map_entry * entry ;
entry = to_map_entry ( kobj ) ;
kfree ( entry ) ;
}
static struct kobj_type __refdata map_ktype = {
. sysfs_ops = & map_attr_ops ,
. default_attrs = def_attrs ,
. release = map_release ,
} ;
static struct kset * map_kset ;
static struct efi_runtime_map_entry *
2016-03-02 02:02:56 +03:00
add_sysfs_runtime_map_entry ( struct kobject * kobj , int nr ,
efi_memory_desc_t * md )
2013-12-20 14:02:18 +04:00
{
int ret ;
struct efi_runtime_map_entry * entry ;
if ( ! map_kset ) {
map_kset = kset_create_and_add ( " runtime-map " , NULL , kobj ) ;
if ( ! map_kset )
return ERR_PTR ( - ENOMEM ) ;
}
entry = kzalloc ( sizeof ( * entry ) , GFP_KERNEL ) ;
if ( ! entry ) {
kset_unregister ( map_kset ) ;
2015-04-21 16:46:28 +03:00
map_kset = NULL ;
return ERR_PTR ( - ENOMEM ) ;
2013-12-20 14:02:18 +04:00
}
2016-03-02 02:02:56 +03:00
memcpy ( & entry - > md , md , sizeof ( efi_memory_desc_t ) ) ;
2013-12-20 14:02:18 +04:00
kobject_init ( & entry - > kobj , & map_ktype ) ;
entry - > kobj . kset = map_kset ;
ret = kobject_add ( & entry - > kobj , NULL , " %d " , nr ) ;
if ( ret ) {
kobject_put ( & entry - > kobj ) ;
kset_unregister ( map_kset ) ;
2015-04-21 16:46:28 +03:00
map_kset = NULL ;
2013-12-20 14:02:18 +04:00
return ERR_PTR ( ret ) ;
}
return entry ;
}
2014-08-09 01:26:11 +04:00
int efi_get_runtime_map_size ( void )
{
2016-03-02 02:02:56 +03:00
return efi . memmap . nr_map * efi . memmap . desc_size ;
2014-08-09 01:26:11 +04:00
}
int efi_get_runtime_map_desc_size ( void )
{
2016-03-02 02:02:56 +03:00
return efi . memmap . desc_size ;
2014-08-09 01:26:11 +04:00
}
int efi_runtime_map_copy ( void * buf , size_t bufsz )
{
size_t sz = efi_get_runtime_map_size ( ) ;
if ( sz > bufsz )
sz = bufsz ;
2016-03-02 02:02:56 +03:00
memcpy ( buf , efi . memmap . map , sz ) ;
2014-08-09 01:26:11 +04:00
return 0 ;
}
2013-12-20 14:02:18 +04:00
int __init efi_runtime_map_init ( struct kobject * efi_kobj )
{
int i , j , ret = 0 ;
struct efi_runtime_map_entry * entry ;
2016-03-02 02:02:56 +03:00
efi_memory_desc_t * md ;
2013-12-20 14:02:18 +04:00
2016-03-02 02:02:56 +03:00
if ( ! efi_enabled ( EFI_MEMMAP ) )
2013-12-20 14:02:18 +04:00
return 0 ;
treewide: kzalloc() -> kcalloc()
The kzalloc() function has a 2-factor argument form, kcalloc(). This
patch replaces cases of:
kzalloc(a * b, gfp)
with:
kcalloc(a * b, gfp)
as well as handling cases of:
kzalloc(a * b * c, gfp)
with:
kzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kzalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kzalloc(4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kzalloc
+ kcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kzalloc(sizeof(THING) * C2, ...)
|
kzalloc(sizeof(TYPE) * C2, ...)
|
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(C1 * C2, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:03:40 +03:00
map_entries = kcalloc ( efi . memmap . nr_map , sizeof ( entry ) , GFP_KERNEL ) ;
2013-12-20 14:02:18 +04:00
if ( ! map_entries ) {
ret = - ENOMEM ;
goto out ;
}
2016-03-02 02:02:56 +03:00
i = 0 ;
for_each_efi_memory_desc ( md ) {
entry = add_sysfs_runtime_map_entry ( efi_kobj , i , md ) ;
2013-12-20 14:02:18 +04:00
if ( IS_ERR ( entry ) ) {
ret = PTR_ERR ( entry ) ;
goto out_add_entry ;
}
2016-03-02 02:02:56 +03:00
* ( map_entries + i + + ) = entry ;
2013-12-20 14:02:18 +04:00
}
return 0 ;
out_add_entry :
2015-01-15 12:21:21 +03:00
for ( j = i - 1 ; j > = 0 ; j - - ) {
2013-12-20 14:02:18 +04:00
entry = * ( map_entries + j ) ;
kobject_put ( & entry - > kobj ) ;
}
out :
return ret ;
}