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:
Nitin Kumbhar
2019-05-31 15:35:42 +05:30
committed by mobile promotions
parent 7ee75980cc
commit c69c5a7a60
12 changed files with 77 additions and 58 deletions

View File

@@ -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)