Add kabi macros helpers.
Li Lingfeng (1): kabi: deduplication friendly structs
Wei Li (2): kabi: fix build error when CONFIG_KABI_RESERVE=n kabi: cleanup config entries of kabi
Xie XiuQi (3): kabi: add kabi helper macros kabi: add KABI_SIZE_ALIGN_CHECKS for more stringent kabi checks kabi: enables more stringent kabi checks
Zheng Zengkai (3): KABI: Add CONFIG_KABI_RESERVE to control KABI padding reserve openeuler_defconfig: Enable CONFIG_KABI_RESERVE for x86 and arm64 kabi: Generalize naming of kabi helper macros
arch/arm64/configs/openeuler_defconfig | 2 + arch/x86/configs/openeuler_defconfig | 2 + include/linux/kabi.h | 509 +++++++++++++++++++++++++ init/Kconfig | 16 + 4 files changed, 529 insertions(+) create mode 100644 include/linux/kabi.h
From: Xie XiuQi xiexiuqi@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4K3S5
---------------------------------------------
We intruduce kabi helper macros which derived from RHEL "include/linux/rh_kabi.h", tried to standardize the kabi work on openEuler.
Signed-off-by: Xie XiuQi xiexiuqi@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Yu Liao liaoyu15@huawei.com --- include/linux/kabi.h | 499 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 499 insertions(+) create mode 100644 include/linux/kabi.h
diff --git a/include/linux/kabi.h b/include/linux/kabi.h new file mode 100644 index 000000000000..da5e6d71e66b --- /dev/null +++ b/include/linux/kabi.h @@ -0,0 +1,499 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * kabi.h - openEuler kABI abstraction header + * + * Copyright (c) 2014 Don Zickus + * Copyright (c) 2015-2018 Jiri Benc + * Copyright (c) 2015 Sabrina Dubroca, Hannes Frederic Sowa + * Copyright (c) 2016-2018 Prarit Bhargava + * Copyright (c) 2017 Paolo Abeni, Larry Woodman + * Copyright (c) 2021 Xie XiuQi xiexiuqi@huawei.com + * + * This file is released under the GPLv2. + * See the file COPYING for more details. + * + * These kabi macros hide the changes from the kabi checker and from the + * process that computes the exported symbols' checksums. + * They have 2 variants: one (defined under __GENKSYMS__) used when + * generating the checksums, and the other used when building the kernel's + * binaries. + * + * The use of these macros does not guarantee that the usage and modification + * of code is correct. As with all openEuler only changes, an engineer must + * explain why the use of the macro is valid in the patch containing the + * changes. + * + * The macro helpers are derived from RHEL "include/linux/rh_kabi.h" + * Mostly debrand from RHEL. + */ + +#ifndef _LINUX_KABI_H +#define _LINUX_KABI_H + +#include <linux/compiler.h> +#include <linux/stringify.h> + +/* + * NOTE + * Unless indicated otherwise, don't use ';' after these macros as it + * messes up the kABI checker by changing what the resulting token string + * looks like. Instead let the macros add the ';' so it can be properly + * hidden from the kABI checker (mainly for KABI_EXTEND, but applied to + * most macros for uniformity). + * + * KABI_CONST + * Adds a new const modifier to a function parameter preserving the old + * checksum. + * + * KABI_ADD_MODIFIER + * Adds a new modifier to a function parameter or a typedef, preserving + * the old checksum. Useful e.g. for adding rcu annotations or changing + * int to unsigned. Beware that this may change the semantics; if you're + * sure this is safe, always explain why binary compatibility with 3rd + * party modules is retained. + * + * KABI_DEPRECATE + * Marks the element as deprecated and make it unusable by modules while + * keeping a hole in its place to preserve binary compatibility. + * + * # define KABI_BROKEN_INSERT_ENUM(_new) _new, + * # define KABI_BROKEN_REMOVE_ENUM(_orig) + * KABI_DEPRECATE_FN + * Marks the function pointer as deprecated and make it unusable by modules + * while keeping a hole in its place to preserve binary compatibility. + * + * KABI_EXTEND + * Adds a new field to a struct. This must always be added to the end of + * the struct. Before using this macro, make sure this is actually safe + * to do - there is a number of conditions under which it is *not* safe. + * In particular (but not limited to), this macro cannot be used: + * - if the struct in question is embedded in another struct, or + * - if the struct is allocated by drivers either statically or + * dynamically, or + * - if the struct is allocated together with driver data (an example of + * such behavior is struct net_device or struct request). + * + * KABI_EXTEND_WITH_SIZE + * Adds a new element (usually a struct) to a struct and reserves extra + * space for the new element. The provided 'size' is the total space to + * be added in longs (i.e. it's 8 * 'size' bytes), including the size of + * the added element. It is automatically checked that the new element + * does not overflow the reserved space, now nor in the future. However, + * no attempt is done to check the content of the added element (struct) + * for kABI conformance - kABI checking inside the added element is + * effectively switched off. + * For any struct being added by KABI_EXTEND_WITH_SIZE, it is + * recommended its content to be documented as not covered by kABI + * guarantee. + * + * KABI_FILL_HOLE + * Fills a hole in a struct. + * + * Warning: only use if a hole exists for _all_ arches. Use pahole to verify. + * + * KABI_RENAME + * Renames an element without changing its type. This macro can be used in + * bitfields, for example. + * + * NOTE: does not include the final ';' + * + * KABI_REPLACE + * Replaces the _orig field by the _new field. The size of the occupied + * space is preserved, it's fine if the _new field is smaller than the + * _orig field. If a _new field is larger or has a different alignment, + * compilation will abort. + * + * + * KABI_HIDE_INCLUDE + * Hides the given include file from kABI checksum computations. This is + * used when a newly added #include makes a previously opaque struct + * visible. + * + * Example usage: + * #include KABI_HIDE_INCLUDE(<linux/poll.h>) + * + * KABI_FAKE_INCLUDE + * Pretends inclusion of the given file for kABI checksum computations. + * This is used when upstream removed a particular #include but that made + * some structures opaque that were previously visible and is causing kABI + * checker failures. + * + * Example usage: + * #include KABI_FAKE_INCLUDE(<linux/rhashtable.h>) + * + * KABI_RESERVE + * Adds a reserved field to a struct. This is done prior to kABI freeze + * for structs that cannot be expanded later using KABI_EXTEND (for + * example because they are embedded in another struct or because they are + * allocated by drivers or because they use unusual memory layout). The + * size of the reserved field is 'unsigned long' and is assumed to be + * 8 bytes. + * + * The argument is a number unique for the given struct; usually, multiple + * KABI_RESERVE macros are added to a struct with numbers starting from + * one. + * + * Example usage: + * struct foo { + * int a; + * KABI_RESERVE(1) + * KABI_RESERVE(2) + * }; + * + * KABI_USE + * Simple wrappers to replace standard openEuler reserved elements. + * + * KABI_AUX_EMBED + * KABI_AUX_PTR + * Adds an extenstion of a struct in the form of "auxiliary structure". + * This is done prior to kABI freeze for structs that cannot be expanded + * later using KABI_EXTEND. See also KABI_RESERVED, these two + * approaches can (and often are) combined. + * + * To use this for 'struct foo' (the "base structure"), define a new + * structure called 'struct foo_rh'; this new struct is called "auxiliary + * structure". Then add KABI_AUX_EMBED or KABI_AUX_PTR to the end + * of the base structure. The argument is the name of the base structure, + * without the 'struct' keyword. + * + * KABI_AUX_PTR stores a pointer to the aux structure in the base + * struct. The lifecycle of the aux struct needs to be properly taken + * care of. + * + * KABI_AUX_EMBED embeds the aux struct into the base struct. This + * cannot be used when the base struct is itself embedded into another + * struct, allocated in an array, etc. + * + * Both approaches (ptr and embed) work correctly even when the aux struct + * is allocated by modules. To ensure this, the code responsible for + * allocation/assignment of the aux struct has to properly set the size of + * the aux struct; see the KABI_AUX_SET_SIZE and KABI_AUX_INIT_SIZE + * macros. + * + * New fields can be later added to the auxiliary structure, always to its + * end. Note the auxiliary structure cannot be shrunk in size later (i.e., + * fields cannot be removed, only deprecated). Any code accessing fields + * from the aux struct must guard the access using the KABI_AUX macro. + * The access itself is then done via a '_rh' field in the base struct. + * + * The auxiliary structure is not guaranteed for access by modules unless + * explicitly commented as such in the declaration of the aux struct + * itself or some of its elements. + * + * Example: + * + * struct foo_rh { + * int newly_added; + * }; + * + * struct foo { + * bool big_hammer; + * KABI_AUX_PTR(foo) + * }; + * + * void use(struct foo *f) + * { + * if (KABI_AUX(f, foo, newly_added)) + * f->_rh->newly_added = 123; + * else + * // the field 'newly_added' is not present in the passed + * // struct, fall back to old behavior + * f->big_hammer = true; + * } + * + * static struct foo_rh my_foo_rh { + * .newly_added = 0; + * } + * + * static struct foo my_foo = { + * .big_hammer = false, + * ._rh = &my_foo_rh, + * KABI_AUX_INIT_SIZE(foo) + * }; + * + * KABI_USE_AUX_PTR + * Creates an auxiliary structure post kABI freeze. This works by using + * two reserved fields (thus there has to be two reserved fields still + * available) and converting them to KABI_AUX_PTR. + * + * Example: + * + * struct foo_rh { + * }; + * + * struct foo { + * int a; + * KABI_RESERVE(1) + * KABI_USE_AUX_PTR(2, 3, foo) + * }; + * + * KABI_AUX_SET_SIZE + * KABI_AUX_INIT_SIZE + * Calculates and stores the size of the auxiliary structure. + * + * KABI_AUX_SET_SIZE is for dynamically allocated base structs, + * KABI_AUX_INIT_SIZE is for statically allocated case structs. + * + * These macros must be called from the allocation (KABI_AUX_SET_SIZE) + * or declaration (KABI_AUX_INIT_SIZE) site, regardless of whether + * that happens in the kernel or in a module. Without calling one of + * these macros, the aux struct will appear to have no fields to the + * kernel. + * + * Note: since KABI_AUX_SET_SIZE is intended to be invoked outside of + * a struct definition, it does not add the semicolon and must be + * terminated by semicolon by the caller. + * + * KABI_AUX + * Verifies that the given field exists in the given auxiliary structure. + * This MUST be called prior to accessing that field; failing to do that + * may lead to invalid memory access. + * + * The first argument is a pointer to the base struct, the second argument + * is the name of the base struct (without the 'struct' keyword), the + * third argument is the field name. + * + * This macro works for structs extended by either of KABI_AUX_EMBED, + * KABI_AUX_PTR and KABI_USE_AUX_PTR. + * + * KABI_FORCE_CHANGE + * Force change of the symbol checksum. The argument of the macro is a + * version for cases we need to do this more than once. + * + * This macro does the opposite: it changes the symbol checksum without + * actually changing anything about the exported symbol. It is useful for + * symbols that are not whitelisted, we're changing them in an + * incompatible way and want to prevent 3rd party modules to silently + * corrupt memory. Instead, by changing the symbol checksum, such modules + * won't be loaded by the kernel. This macro should only be used as a + * last resort when all other KABI workarounds have failed. + * + * KABI_EXCLUDE + * !!! WARNING: DANGEROUS, DO NOT USE unless you are aware of all the !!! + * !!! implications. This should be used ONLY EXCEPTIONALLY and only !!! + * !!! under specific circumstances. Very likely, this macro does not !!! + * !!! do what you expect it to do. Note that any usage of this macro !!! + * !!! MUST be paired with a KABI_FORCE_CHANGE annotation of !!! + * !!! a suitable symbol (or an equivalent safeguard) and the commit !!! + * !!! log MUST explain why the chosen solution is appropriate. !!! + * + * Exclude the element from checksum generation. Any such element is + * considered not to be part of the kABI whitelist and may be changed at + * will. Note however that it's the responsibility of the developer + * changing the element to ensure 3rd party drivers using this element + * won't panic, for example by not allowing them to be loaded. That can + * be achieved by changing another, non-whitelisted symbol they use, + * either by nature of the change or by using KABI_FORCE_CHANGE. + * + * Also note that any change to the element must preserve its size. Change + * of the size is not allowed and would constitute a silent kABI breakage. + * Beware that the KABI_EXCLUDE macro does not do any size checks. + * + * KABI_BROKEN_INSERT + * KABI_BROKEN_REMOVE + * Insert a field to the middle of a struct / delete a field from a struct. + * Note that this breaks kABI! It can be done only when it's certain that + * no 3rd party driver can validly reach into the struct. A typical + * example is a struct that is: both (a) referenced only through a long + * chain of pointers from another struct that is part of a whitelisted + * symbol and (b) kernel internal only, it should have never been visible + * to genksyms in the first place. + * + * Another example are structs that are explicitly exempt from kABI + * guarantee but we did not have enough foresight to use KABI_EXCLUDE. + * In this case, the warning for KABI_EXCLUDE applies. + * + * A detailed explanation of correctness of every KABI_BROKEN_* macro + * use is especially important. + * + * KABI_BROKEN_INSERT_BLOCK + * KABI_BROKEN_REMOVE_BLOCK + * A version of KABI_BROKEN_INSERT / REMOVE that allows multiple fields + * to be inserted or removed together. All fields need to be terminated + * by ';' inside(!) the macro parameter. The macro itself must not be + * terminated by ';'. + * + * KABI_BROKEN_REPLACE + * Replace a field by a different one without doing any checking. This + * allows replacing a field by another with a different size. Similarly + * to other KABI_BROKEN macros, use of this indicates a kABI breakage. + * + * KABI_BROKEN_INSERT_ENUM + * KABI_BROKEN_REMOVE_ENUM + * Insert a field to the middle of an enumaration type / delete a field from + * an enumaration type. Note that this can break kABI especially if the + * number of enum fields is used in an array within a structure. It can be + * done only when it is certain that no 3rd party driver will use the + * enumeration type or a structure that embeds an array with size determined + * by an enumeration type. + * + * KABI_EXTEND_ENUM + * Adds a new field to an enumeration type. This must always be added to + * the end of the enum. Before using this macro, make sure this is actually + * safe to do. + */ +#ifdef __GENKSYMS__ + +# define KABI_CONST +# define KABI_ADD_MODIFIER(_new) +# define KABI_EXTEND(_new) +# define KABI_FILL_HOLE(_new) +# define KABI_FORCE_CHANGE(ver) __attribute__((kabi_change ## ver)) +# define KABI_RENAME(_orig, _new) _orig +# define KABI_HIDE_INCLUDE(_file) <linux/kabi.h> +# define KABI_FAKE_INCLUDE(_file) _file +# define KABI_BROKEN_INSERT(_new) +# define KABI_BROKEN_REMOVE(_orig) _orig; +# define KABI_BROKEN_INSERT_BLOCK(_new) +# define KABI_BROKEN_REMOVE_BLOCK(_orig) _orig +# define KABI_BROKEN_REPLACE(_orig, _new) _orig; +# define KABI_BROKEN_INSERT_ENUM(_new) +# define KABI_BROKEN_REMOVE_ENUM(_orig) _orig, +# define KABI_EXTEND_ENUM(_new) + +# define _KABI_DEPRECATE(_type, _orig) _type _orig +# define _KABI_DEPRECATE_FN(_type, _orig, _args...) _type (*_orig)(_args) +# define _KABI_REPLACE(_orig, _new) _orig +# define _KABI_EXCLUDE(_elem) + +#else + +# define KABI_ALIGN_WARNING ". Disable CONFIG_KABI_SIZE_ALIGN_CHECKS if debugging." + +# define KABI_CONST const +# define KABI_ADD_MODIFIER(_new) _new +# define KABI_EXTEND(_new) _new; +# define KABI_FILL_HOLE(_new) _new; +# define KABI_FORCE_CHANGE(ver) +# define KABI_RENAME(_orig, _new) _new +# define KABI_HIDE_INCLUDE(_file) _file +# define KABI_FAKE_INCLUDE(_file) <linux/kabi.h> +# define KABI_BROKEN_INSERT(_new) _new; +# define KABI_BROKEN_REMOVE(_orig) +# define KABI_BROKEN_INSERT_BLOCK(_new) _new +# define KABI_BROKEN_REMOVE_BLOCK(_orig) +# define KABI_BROKEN_REPLACE(_orig, _new) _new; +# define KABI_BROKEN_INSERT_ENUM(_new) _new, +# define KABI_BROKEN_REMOVE_ENUM(_orig) +# define KABI_EXTEND_ENUM(_new) _new, + +#if IS_BUILTIN(CONFIG_KABI_SIZE_ALIGN_CHECKS) +# define __KABI_CHECK_SIZE_ALIGN(_orig, _new) \ + union { \ + _Static_assert(sizeof(struct{_new;}) <= sizeof(struct{_orig;}), \ + __FILE__ ":" __stringify(__LINE__) ": " __stringify(_new) " is larger than " __stringify(_orig) KABI_ALIGN_WARNING); \ + _Static_assert(__alignof__(struct{_new;}) <= __alignof__(struct{_orig;}), \ + __FILE__ ":" __stringify(__LINE__) ": " __stringify(_orig) " is not aligned the same as " __stringify(_new) KABI_ALIGN_WARNING); \ + } +# define __ABI_CHECK_SIZE(_item, _size) \ + _Static_assert(sizeof(struct{_item;}) <= _size, \ + __FILE__ ":" __stringify(__LINE__) ": " __stringify(_item) " is larger than the reserved size (" __stringify(_size) " bytes)" KABI_ALIGN_WARNING) +#else +# define __KABI_CHECK_SIZE_ALIGN(_orig, _new) +# define __KABI_CHECK_SIZE(_item, _size) +#endif + +# define _KABI_DEPRECATE(_type, _orig) _type kabi_reserved_##_orig +# define _KABI_DEPRECATE_FN(_type, _orig, _args...) \ + _type (* kabi_reserved_##_orig)(_args) +# define _KABI_REPLACE(_orig, _new) \ + union { \ + _new; \ + struct { \ + _orig; \ + } __UNIQUE_ID(kabi_hide); \ + __KABI_CHECK_SIZE_ALIGN(_orig, _new); \ + } + +# define _KABI_EXCLUDE(_elem) _elem + +#endif /* __GENKSYMS__ */ + +/* semicolon added wrappers for the KABI_REPLACE macros */ +# define KABI_DEPRECATE(_type, _orig) _KABI_DEPRECATE(_type, _orig); +# define KABI_DEPRECATE_FN(_type, _orig, _args...) \ + _KABI_DEPRECATE_FN(_type, _orig, _args); +# define KABI_REPLACE(_orig, _new) _KABI_REPLACE(_orig, _new); +/* + * Macro for breaking up a random element into two smaller chunks using an + * anonymous struct inside an anonymous union. + */ +# define KABI_REPLACE2(orig, _new1, _new2) KABI_REPLACE(orig, struct{ _new1; _new2;}) + +/* + * We tried to standardize on openEuler reserved names. These wrappers + * leverage those common names making it easier to read and find in the + * code. + */ +# define _KABI_RESERVE(n) unsigned long kabi_reserved##n +# define KABI_RESERVE(n) _KABI_RESERVE(n); +/* + * Simple wrappers to replace standard openEuler reserved elements. + */ +# define KABI_USE(n, _new) KABI_REPLACE(_KABI_RESERVE(n), _new) +/* + * Macros for breaking up a reserved element into two smaller chunks using + * an anonymous struct inside an anonymous union. + */ +# define KABI_USE2(n, _new1, _new2) KABI_REPLACE(_KABI_RESERVE(n), struct{ _new1; _new2; }) + +#define KABI_EXCLUDE(_elem) _KABI_EXCLUDE(_elem); + +#define KABI_EXTEND_WITH_SIZE(_new, _size) \ + KABI_EXTEND(union { \ + _new; \ + unsigned long KABI_UNIQUE_ID[_size]; \ + __KABI_CHECK_SIZE(_new, 8 * (_size)); \ + }) + +#define _KABI_AUX_PTR(_struct) \ + size_t _struct##_size_rh; \ + _KABI_EXCLUDE(struct _struct##_rh *_rh) +#define KABI_AUX_PTR(_struct) \ + _KABI_AUX_PTR(_struct); + +#define _KABI_AUX_EMBED(_struct) \ + size_t _struct##_size_rh; \ + _KABI_EXCLUDE(struct _struct##_rh _rh) +#define KABI_AUX_EMBED(_struct) \ + _KABI_AUX_EMBED(_struct); + +#define KABI_USE_AUX_PTR(n1, n2, _struct) \ + KABI_USE(n1, n2, \ + struct { KABI_AUX_PTR(_struct) }) + +/* + * KABI_AUX_SET_SIZE calculates and sets the size of the extended struct and + * stores it in the size_rh field for structs that are dynamically allocated. + * This macro MUST be called when expanding a base struct with + * KABI_SIZE_AND_EXTEND, and it MUST be called from the allocation site + * regardless of being allocated in the kernel or a module. + * Note: since this macro is intended to be invoked outside of a struct, + * a semicolon is necessary at the end of the line where it is invoked. + */ +#define KABI_AUX_SET_SIZE(_name, _struct) ({ \ + (_name)->_struct##_size_rh = sizeof(struct _struct##_rh); \ +}) + +/* + * KABI_AUX_INIT_SIZE calculates and sets the size of the extended struct and + * stores it in the size_rh field for structs that are statically allocated. + * This macro MUST be called when expanding a base struct with + * KABI_SIZE_AND_EXTEND, and it MUST be called from the declaration site + * regardless of being allocated in the kernel or a module. + */ +#define KABI_AUX_INIT_SIZE(_struct) \ + ._struct##_size_rh = sizeof(struct _struct##_rh), + +/* + * KABI_AUX verifies allocated memory exists. This MUST be called to + * verify that memory in the _rh struct is valid, and can be called + * regardless if KABI_SIZE_AND_EXTEND or KABI_SIZE_AND_EXTEND_PTR is + * used. + */ +#define KABI_AUX(_ptr, _struct, _field) ({ \ + size_t __off = offsetof(struct _struct##_rh, _field); \ + (_ptr)->_struct##_size_rh > __off ? true : false; \ +}) + +#endif /* _LINUX_KABI_H */
From: Xie XiuQi xiexiuqi@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4K3S5
---------------------------------------------
This option enables more stringent kabi checks. Those must be disable in case of a debug-build because they allow to change struct sizes.
Signed-off-by: Xie XiuQi xiexiuqi@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Yu Liao liaoyu15@huawei.com --- Kconfig | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/Kconfig b/Kconfig index 745bc773f567..bb409bb587b0 100644 --- a/Kconfig +++ b/Kconfig @@ -30,3 +30,10 @@ source "lib/Kconfig" source "lib/Kconfig.debug"
source "Documentation/Kconfig" + +config KABI_SIZE_ALIGN_CHECKS + bool "Enables more stringent kabi checks in the macros" + default y + help + This option enables more stringent kabi checks. Those must be disable + in case of a debug-build because they allow to change struct sizes.
From: Xie XiuQi xiexiuqi@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4K3S5
---------------------------------------------
This option enables more stringent kabi checks. Those must be disable in case of a debug-build because they allow to change struct sizes.
We enable this option by default.
Signed-off-by: Xie XiuQi xiexiuqi@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Yu Liao liaoyu15@huawei.com --- arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + 2 files changed, 2 insertions(+)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 9d071bb380f6..2f32eaea550b 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -254,6 +254,7 @@ CONFIG_DEBUG_PERF_USE_VMALLOC=y CONFIG_SYSTEM_DATA_VERIFICATION=y CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y +CONFIG_KABI_SIZE_ALIGN_CHECKS=y # end of General setup
CONFIG_ARM64=y diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index 0713d2669844..302528aff0ac 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -277,6 +277,7 @@ CONFIG_PERF_EVENTS=y CONFIG_SYSTEM_DATA_VERIFICATION=y CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y +CONFIG_KABI_SIZE_ALIGN_CHECKS=y # end of General setup
CONFIG_64BIT=y
From: Zheng Zengkai zhengzengkai@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4K3S5
---------------------------------------------
Add CONFIG_KABI_RESERVE to control KABI padding reserve or not, for some embedded system, KABI padding reserve may be not necessary.
By the way, adjust unsigned long to u64 to unify basic reserve length for both 32bit and 64bit architectures.
Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Yu Liao liaoyu15@huawei.com --- Kconfig | 8 ++++++++ include/linux/kabi.h | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/Kconfig b/Kconfig index bb409bb587b0..9c9b5fedd43c 100644 --- a/Kconfig +++ b/Kconfig @@ -37,3 +37,11 @@ config KABI_SIZE_ALIGN_CHECKS help This option enables more stringent kabi checks. Those must be disable in case of a debug-build because they allow to change struct sizes. + +config KABI_RESERVE + bool "Enable KABI PADDING RESERVE" + default y + help + This option enables KABI padding reserve. + For some embedded system, KABI padding reserve may be not necessary. + Disable it on demand. diff --git a/include/linux/kabi.h b/include/linux/kabi.h index da5e6d71e66b..713f63cf56cb 100644 --- a/include/linux/kabi.h +++ b/include/linux/kabi.h @@ -425,7 +425,11 @@ * leverage those common names making it easier to read and find in the * code. */ -# define _KABI_RESERVE(n) unsigned long kabi_reserved##n +#ifdef CONFIG_KABI_RESERVE + # define _KABI_RESERVE(n) u64 kabi_reserved##n +#else + # define _KABI_RESERVE(n) +#endif # define KABI_RESERVE(n) _KABI_RESERVE(n); /* * Simple wrappers to replace standard openEuler reserved elements.
From: Zheng Zengkai zhengzengkai@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4K3S5
---------------------------
Enable CONFIG_KABI_RESERVE for x86 and arm64 architectures in openeuler_defconfig by default.
Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Yu Liao liaoyu15@huawei.com --- arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + 2 files changed, 2 insertions(+)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 2f32eaea550b..24afec47352a 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -255,6 +255,7 @@ CONFIG_SYSTEM_DATA_VERIFICATION=y CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y CONFIG_KABI_SIZE_ALIGN_CHECKS=y +CONFIG_KABI_RESERVE=y # end of General setup
CONFIG_ARM64=y diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index 302528aff0ac..3259c78af686 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -278,6 +278,7 @@ CONFIG_SYSTEM_DATA_VERIFICATION=y CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y CONFIG_KABI_SIZE_ALIGN_CHECKS=y +CONFIG_KABI_RESERVE=y # end of General setup
CONFIG_64BIT=y
From: Zheng Zengkai zhengzengkai@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4K3S5
--------------------------
Generalize naming of some kabi helper macros.
Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Yu Liao liaoyu15@huawei.com --- include/linux/kabi.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/include/linux/kabi.h b/include/linux/kabi.h index 713f63cf56cb..0bc7ca2483f4 100644 --- a/include/linux/kabi.h +++ b/include/linux/kabi.h @@ -151,7 +151,7 @@ * approaches can (and often are) combined. * * To use this for 'struct foo' (the "base structure"), define a new - * structure called 'struct foo_rh'; this new struct is called "auxiliary + * structure called 'struct foo_resvd'; this new struct is called "auxiliary * structure". Then add KABI_AUX_EMBED or KABI_AUX_PTR to the end * of the base structure. The argument is the name of the base structure, * without the 'struct' keyword. @@ -174,7 +174,7 @@ * end. Note the auxiliary structure cannot be shrunk in size later (i.e., * fields cannot be removed, only deprecated). Any code accessing fields * from the aux struct must guard the access using the KABI_AUX macro. - * The access itself is then done via a '_rh' field in the base struct. + * The access itself is then done via a '_resvd' field in the base struct. * * The auxiliary structure is not guaranteed for access by modules unless * explicitly commented as such in the declaration of the aux struct @@ -182,7 +182,7 @@ * * Example: * - * struct foo_rh { + * struct foo_resvd { * int newly_added; * }; * @@ -194,20 +194,20 @@ * void use(struct foo *f) * { * if (KABI_AUX(f, foo, newly_added)) - * f->_rh->newly_added = 123; + * f->_resvd->newly_added = 123; * else * // the field 'newly_added' is not present in the passed * // struct, fall back to old behavior * f->big_hammer = true; * } * - * static struct foo_rh my_foo_rh { + * static struct foo_resvd my_foo_resvd { * .newly_added = 0; * } * * static struct foo my_foo = { * .big_hammer = false, - * ._rh = &my_foo_rh, + * ._resvd = &my_foo_resvd, * KABI_AUX_INIT_SIZE(foo) * }; * @@ -218,7 +218,7 @@ * * Example: * - * struct foo_rh { + * struct foo_resvd { * }; * * struct foo { @@ -385,7 +385,7 @@ _Static_assert(__alignof__(struct{_new;}) <= __alignof__(struct{_orig;}), \ __FILE__ ":" __stringify(__LINE__) ": " __stringify(_orig) " is not aligned the same as " __stringify(_new) KABI_ALIGN_WARNING); \ } -# define __ABI_CHECK_SIZE(_item, _size) \ +# define __KABI_CHECK_SIZE(_item, _size) \ _Static_assert(sizeof(struct{_item;}) <= _size, \ __FILE__ ":" __stringify(__LINE__) ": " __stringify(_item) " is larger than the reserved size (" __stringify(_size) " bytes)" KABI_ALIGN_WARNING) #else @@ -451,14 +451,14 @@ })
#define _KABI_AUX_PTR(_struct) \ - size_t _struct##_size_rh; \ - _KABI_EXCLUDE(struct _struct##_rh *_rh) + size_t _struct##_size_resvd; \ + _KABI_EXCLUDE(struct _struct##_resvd *_resvd) #define KABI_AUX_PTR(_struct) \ _KABI_AUX_PTR(_struct);
#define _KABI_AUX_EMBED(_struct) \ - size_t _struct##_size_rh; \ - _KABI_EXCLUDE(struct _struct##_rh _rh) + size_t _struct##_size_resvd; \ + _KABI_EXCLUDE(struct _struct##_resvd _resvd) #define KABI_AUX_EMBED(_struct) \ _KABI_AUX_EMBED(_struct);
@@ -468,7 +468,7 @@
/* * KABI_AUX_SET_SIZE calculates and sets the size of the extended struct and - * stores it in the size_rh field for structs that are dynamically allocated. + * stores it in the size_resvd field for structs that are dynamically allocated. * This macro MUST be called when expanding a base struct with * KABI_SIZE_AND_EXTEND, and it MUST be called from the allocation site * regardless of being allocated in the kernel or a module. @@ -476,28 +476,28 @@ * a semicolon is necessary at the end of the line where it is invoked. */ #define KABI_AUX_SET_SIZE(_name, _struct) ({ \ - (_name)->_struct##_size_rh = sizeof(struct _struct##_rh); \ + (_name)->_struct##_size_resvd = sizeof(struct _struct##_resvd); \ })
/* * KABI_AUX_INIT_SIZE calculates and sets the size of the extended struct and - * stores it in the size_rh field for structs that are statically allocated. + * stores it in the size_resvd field for structs that are statically allocated. * This macro MUST be called when expanding a base struct with * KABI_SIZE_AND_EXTEND, and it MUST be called from the declaration site * regardless of being allocated in the kernel or a module. */ #define KABI_AUX_INIT_SIZE(_struct) \ - ._struct##_size_rh = sizeof(struct _struct##_rh), + ._struct##_size_resvd = sizeof(struct _struct##_resvd),
/* * KABI_AUX verifies allocated memory exists. This MUST be called to - * verify that memory in the _rh struct is valid, and can be called + * verify that memory in the _resvd struct is valid, and can be called * regardless if KABI_SIZE_AND_EXTEND or KABI_SIZE_AND_EXTEND_PTR is * used. */ #define KABI_AUX(_ptr, _struct, _field) ({ \ - size_t __off = offsetof(struct _struct##_rh, _field); \ - (_ptr)->_struct##_size_rh > __off ? true : false; \ + size_t __off = offsetof(struct _struct##_resvd, _field); \ + (_ptr)->_struct##_size_resvd > __off ? true : false; \ })
#endif /* _LINUX_KABI_H */
From: Wei Li liwei391@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4T1NF CVE: NA
-------------------------------------------------
When CONFIG_KABI_RESERVE=n && CONFIG_KABI_SIZE_ALIGN_CHECKS=y, with kabi reserved padding replaced by KABI_USE(), we will get the build error:
include/linux/kabi.h:383:3: error: static assertion failed: \ "include/linux/fs.h:2306: long aaa is larger than . \ Disable CONFIG_KABI_SIZE_ALIGN_CHECKS if debugging." _Static_assert(sizeof(struct{_new;}) <= sizeof(struct{_orig;}), \ ^~~~~~~~~~~~~~
In fact, the result of KABI_USE() when CONFIG_KABI_RESERVE=n is weird, update _KABI_REPLACE() to fix this.
Signed-off-by: Wei Li liwei391@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Yu Liao liaoyu15@huawei.com --- include/linux/kabi.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/include/linux/kabi.h b/include/linux/kabi.h index 0bc7ca2483f4..a52d9fa72cfa 100644 --- a/include/linux/kabi.h +++ b/include/linux/kabi.h @@ -396,6 +396,7 @@ # define _KABI_DEPRECATE(_type, _orig) _type kabi_reserved_##_orig # define _KABI_DEPRECATE_FN(_type, _orig, _args...) \ _type (* kabi_reserved_##_orig)(_args) +#ifdef CONFIG_KABI_RESERVE # define _KABI_REPLACE(_orig, _new) \ union { \ _new; \ @@ -404,6 +405,9 @@ } __UNIQUE_ID(kabi_hide); \ __KABI_CHECK_SIZE_ALIGN(_orig, _new); \ } +#else +# define _KABI_REPLACE(_orig, _new) KABI_BROKEN_REPLACE(_orig, _new) +#endif
# define _KABI_EXCLUDE(_elem) _elem
@@ -426,9 +430,9 @@ * code. */ #ifdef CONFIG_KABI_RESERVE - # define _KABI_RESERVE(n) u64 kabi_reserved##n +# define _KABI_RESERVE(n) u64 kabi_reserved##n #else - # define _KABI_RESERVE(n) +# define _KABI_RESERVE(n) #endif # define KABI_RESERVE(n) _KABI_RESERVE(n); /*
From: Wei Li liwei391@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4T1NF CVE: NA
-------------------------------------------------
Move config entries of kabi to "General setup", and make CONFIG_KABI_SIZE_ALIGN_CHECKS depending on CONFIG_KABI_RESERVE.
Signed-off-by: Wei Li liwei391@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Yu Liao liaoyu15@huawei.com --- Kconfig | 15 --------------- init/Kconfig | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/Kconfig b/Kconfig index 9c9b5fedd43c..745bc773f567 100644 --- a/Kconfig +++ b/Kconfig @@ -30,18 +30,3 @@ source "lib/Kconfig" source "lib/Kconfig.debug"
source "Documentation/Kconfig" - -config KABI_SIZE_ALIGN_CHECKS - bool "Enables more stringent kabi checks in the macros" - default y - help - This option enables more stringent kabi checks. Those must be disable - in case of a debug-build because they allow to change struct sizes. - -config KABI_RESERVE - bool "Enable KABI PADDING RESERVE" - default y - help - This option enables KABI padding reserve. - For some embedded system, KABI padding reserve may be not necessary. - Disable it on demand. diff --git a/init/Kconfig b/init/Kconfig index 7a3299a632e0..53a7eaf69409 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1927,6 +1927,22 @@ config BINDGEN_VERSION_TEXT config TRACEPOINTS bool
+config KABI_RESERVE + bool "Enable KABI PADDING RESERVE" + default y + help + This option enables KABI padding reserve. + For some embedded system, KABI padding reserve may be not necessary. + Disable it on demand. + +config KABI_SIZE_ALIGN_CHECKS + bool "Enables more stringent kabi checks in the macros" + default y + depends on KABI_RESERVE + help + This option enables more stringent kabi checks. Those must be disable + in case of a debug-build because they allow to change struct sizes. + endmenu # General setup
source "arch/Kconfig"
From: Li Lingfeng lilingfeng3@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I53Q6M CVE: NA Reference:https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/commit/...
---------------------------
We don't really need the field names to be globally unique, it is enough when they are unique in the given struct. Since structs do not generally span mutliple files, using the line number is enough to ensure an unique identifier. It means that we can't use two KABI_RENAME macros on the same line but that's not happening anyway.
This allows pahole to deduplicate the type info of structs using KABI macros, lowering the size of vmlinuz from 26M to 8.5
Signed-off-by: Li Lingfeng lilingfeng3@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Reviewed-by: zhihao Cheng chengzhihao1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Yu Liao liaoyu15@huawei.com --- include/linux/kabi.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/kabi.h b/include/linux/kabi.h index a52d9fa72cfa..fe3213c0f576 100644 --- a/include/linux/kabi.h +++ b/include/linux/kabi.h @@ -393,6 +393,8 @@ # define __KABI_CHECK_SIZE(_item, _size) #endif
+#define KABI_UNIQUE_ID __PASTE(kabi_hidden_, __LINE__) + # define _KABI_DEPRECATE(_type, _orig) _type kabi_reserved_##_orig # define _KABI_DEPRECATE_FN(_type, _orig, _args...) \ _type (* kabi_reserved_##_orig)(_args) @@ -402,7 +404,7 @@ _new; \ struct { \ _orig; \ - } __UNIQUE_ID(kabi_hide); \ + } KABI_UNIQUE_ID; \ __KABI_CHECK_SIZE_ALIGN(_orig, _new); \ } #else
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/1990 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/A...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/1990 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/A...