mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 18:16:01 +03:00
gpu: nvgpu: use safe ops in ALIGN and ALIGN_MASK
Shortcomings of ALIGN macros: - ALIGN_MASK down aligns when there is an wrapping/overflow instead of throwing an error. This can affect the size assumptions. - Alignment a's check will be bypassed when ALIGN_MASK is directly used. Fix these issues by 1) adding compile time error for non-unsigned type arguments 2) using unsigned type safe ops for addition and subtraction. Also, change users of ALIGN to pass unsigned types only. JIRA NVGPU-3515 Jira NVGPU-3411 Change-Id: I5b94a262e09aad473c420af750ead6b0f9d36a9b Signed-off-by: Nitin Kumbhar <nkumbhar@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2128382 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
7ee75980cc
commit
c69c5a7a60
@@ -98,23 +98,37 @@
|
||||
#define roundup(x, y) round_up(x, y)
|
||||
#define round_down(x, y) ((x) & ~round_mask(x, y))
|
||||
|
||||
#define ALIGN_MASK(x, mask) \
|
||||
({ \
|
||||
typeof(x) ret; \
|
||||
typeof(x) sum = (x) + (mask); \
|
||||
\
|
||||
if ((sum >= (x)) && (sum >= (mask))) { \
|
||||
ret = sum & ~(mask); \
|
||||
} else { \
|
||||
ret = (typeof(x))~(typeof(x))0 & ~(mask); \
|
||||
} \
|
||||
ret; \
|
||||
})
|
||||
#define IS_UNSIGNED_TYPE(x) \
|
||||
(__builtin_types_compatible_p(typeof(x), unsigned int) || \
|
||||
__builtin_types_compatible_p(typeof(x), unsigned long) || \
|
||||
__builtin_types_compatible_p(typeof(x), unsigned long long))
|
||||
|
||||
#define IS_UNSIGNED_LONG_TYPE(x) \
|
||||
(__builtin_types_compatible_p(typeof(x), unsigned long) || \
|
||||
__builtin_types_compatible_p(typeof(x), unsigned long long))
|
||||
|
||||
#define ALIGN_MASK(x, mask) \
|
||||
__builtin_choose_expr( \
|
||||
(IS_UNSIGNED_TYPE(x) && IS_UNSIGNED_TYPE(mask)), \
|
||||
__builtin_choose_expr( \
|
||||
IS_UNSIGNED_LONG_TYPE(x), \
|
||||
(nvgpu_safe_add_u64((x), (mask)) & ~(mask)), \
|
||||
(nvgpu_safe_add_u32((x), (mask)) & ~(mask))), \
|
||||
/* Results in build error. Make x/mask type unsigned */ \
|
||||
(void)0)
|
||||
|
||||
#define ALIGN(x, a) \
|
||||
__builtin_choose_expr( \
|
||||
(IS_UNSIGNED_TYPE(x) && IS_UNSIGNED_TYPE(a)), \
|
||||
__builtin_choose_expr( \
|
||||
IS_UNSIGNED_LONG_TYPE(x), \
|
||||
ALIGN_MASK((x), \
|
||||
(nvgpu_safe_sub_u64((typeof(x))(a), 1))), \
|
||||
ALIGN_MASK((x), \
|
||||
(nvgpu_safe_sub_u32((typeof(x))(a), 1)))), \
|
||||
/* Results in build error. Make x/a type unsigned */ \
|
||||
(void)0)
|
||||
|
||||
#define ALIGN(x, a) ALIGN_MASK(x, \
|
||||
(a) > (typeof(a))0 ? \
|
||||
(typeof(x))(a) - 1U : \
|
||||
(typeof(x))0)
|
||||
#define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE)
|
||||
|
||||
#define HZ_TO_KHZ(x) ((x) / KHZ)
|
||||
|
||||
Reference in New Issue
Block a user