mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: add detailed documentation for some common.nvgpu APIs
Add detailed documentation for common.nvgpu APIs as per the new guidance. Jira NVGPU-6973 Change-Id: I914dd4e4ead6a9d86ddd7c18a43d6c66d35da5d1 Signed-off-by: shashank singh <shashsingh@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2573169 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2672104 Reviewed-by: Rajesh Devaraj <rdevaraj@nvidia.com> Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
mobile promotions
parent
fb0ebef0a7
commit
6c46173be3
@@ -190,7 +190,8 @@ struct railgate_stats {
|
|||||||
/**
|
/**
|
||||||
* @defgroup NVGPU_COMMON_NVGPU_DEFINES
|
* @defgroup NVGPU_COMMON_NVGPU_DEFINES
|
||||||
*
|
*
|
||||||
* GPU litters defines.
|
* GPU litters defines which corresponds to various chip specific values related
|
||||||
|
* to h/w units.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,55 +211,55 @@ struct railgate_stats {
|
|||||||
#define GPU_LIT_NUM_SM_PER_TPC 4
|
#define GPU_LIT_NUM_SM_PER_TPC 4
|
||||||
/** Number of fbps. */
|
/** Number of fbps. */
|
||||||
#define GPU_LIT_NUM_FBPS 5
|
#define GPU_LIT_NUM_FBPS 5
|
||||||
/** Gpc base address. */
|
/** Gpc base address (in bytes). */
|
||||||
#define GPU_LIT_GPC_BASE 6
|
#define GPU_LIT_GPC_BASE 6
|
||||||
/** Gpc stride. */
|
/** Gpc stride (in bytes). */
|
||||||
#define GPU_LIT_GPC_STRIDE 7
|
#define GPU_LIT_GPC_STRIDE 7
|
||||||
/** Gpc shared base offset. */
|
/** Gpc shared base offset (in bytes). */
|
||||||
#define GPU_LIT_GPC_SHARED_BASE 8
|
#define GPU_LIT_GPC_SHARED_BASE 8
|
||||||
/** Tpc's base offset in gpc. */
|
/** Tpc's base offset in gpc (in bytes). */
|
||||||
#define GPU_LIT_TPC_IN_GPC_BASE 9
|
#define GPU_LIT_TPC_IN_GPC_BASE 9
|
||||||
/** Tpc's stride in gpc. */
|
/** Tpc's stride in gpc (in bytes). */
|
||||||
#define GPU_LIT_TPC_IN_GPC_STRIDE 10
|
#define GPU_LIT_TPC_IN_GPC_STRIDE 10
|
||||||
/** Tpc's shared base offset in gpc. */
|
/** Tpc's shared base offset in gpc (in bytes). */
|
||||||
#define GPU_LIT_TPC_IN_GPC_SHARED_BASE 11
|
#define GPU_LIT_TPC_IN_GPC_SHARED_BASE 11
|
||||||
/** Ppc's base offset in gpc. */
|
/** Ppc's base offset in gpc (in bytes). */
|
||||||
#define GPU_LIT_PPC_IN_GPC_BASE 12
|
#define GPU_LIT_PPC_IN_GPC_BASE 12
|
||||||
/** Ppc's stride in gpc. */
|
/** Ppc's stride in gpc (in bytes). */
|
||||||
#define GPU_LIT_PPC_IN_GPC_STRIDE 13
|
#define GPU_LIT_PPC_IN_GPC_STRIDE 13
|
||||||
/** Ppc's shared base offset in gpc. */
|
/** Ppc's shared base offset in gpc (in bytes). */
|
||||||
#define GPU_LIT_PPC_IN_GPC_SHARED_BASE 14
|
#define GPU_LIT_PPC_IN_GPC_SHARED_BASE 14
|
||||||
/** Rop base offset. */
|
/** Rop base offset (in bytes). */
|
||||||
#define GPU_LIT_ROP_BASE 15
|
#define GPU_LIT_ROP_BASE 15
|
||||||
/** Rop stride. */
|
/** Rop stride (in bytes). */
|
||||||
#define GPU_LIT_ROP_STRIDE 16
|
#define GPU_LIT_ROP_STRIDE 16
|
||||||
/** Rop shared base offset. */
|
/** Rop shared base offset (in bytes). */
|
||||||
#define GPU_LIT_ROP_SHARED_BASE 17
|
#define GPU_LIT_ROP_SHARED_BASE 17
|
||||||
/** Number of host engines. */
|
/** Number of host engines. */
|
||||||
#define GPU_LIT_HOST_NUM_ENGINES 18
|
#define GPU_LIT_HOST_NUM_ENGINES 18
|
||||||
/** Number of host pbdma. */
|
/** Number of host pbdma. */
|
||||||
#define GPU_LIT_HOST_NUM_PBDMA 19
|
#define GPU_LIT_HOST_NUM_PBDMA 19
|
||||||
/** LTC stride. */
|
/** LTC stride (in bytes). */
|
||||||
#define GPU_LIT_LTC_STRIDE 20
|
#define GPU_LIT_LTC_STRIDE 20
|
||||||
/** LTS stride. */
|
/** LTS stride (in bytes). */
|
||||||
#define GPU_LIT_LTS_STRIDE 21
|
#define GPU_LIT_LTS_STRIDE 21
|
||||||
/** Number of fbpas. */
|
/** Number of fbpas. */
|
||||||
#define GPU_LIT_NUM_FBPAS 22
|
#define GPU_LIT_NUM_FBPAS 22
|
||||||
/** Fbpa stride. */
|
/** Fbpa stride (in bytes). */
|
||||||
#define GPU_LIT_FBPA_STRIDE 23
|
#define GPU_LIT_FBPA_STRIDE 23
|
||||||
/** Fbpa base offset. */
|
/** Fbpa base offset (in bytes). */
|
||||||
#define GPU_LIT_FBPA_BASE 24
|
#define GPU_LIT_FBPA_BASE 24
|
||||||
/** Fbpa shared base offset. */
|
/** Fbpa shared base offset (in bytes). */
|
||||||
#define GPU_LIT_FBPA_SHARED_BASE 25
|
#define GPU_LIT_FBPA_SHARED_BASE 25
|
||||||
/** Sm pri stride. */
|
/** Sm pri stride (in bytes). */
|
||||||
#define GPU_LIT_SM_PRI_STRIDE 26
|
#define GPU_LIT_SM_PRI_STRIDE 26
|
||||||
/** Smpc pri base offset. */
|
/** Smpc pri base offset (in bytes). */
|
||||||
#define GPU_LIT_SMPC_PRI_BASE 27
|
#define GPU_LIT_SMPC_PRI_BASE 27
|
||||||
/** Smpc pri shared base offset. */
|
/** Smpc pri shared base offset (in bytes). */
|
||||||
#define GPU_LIT_SMPC_PRI_SHARED_BASE 28
|
#define GPU_LIT_SMPC_PRI_SHARED_BASE 28
|
||||||
/** Smpc pri unique base offset. */
|
/** Smpc pri unique base offset (in bytes). */
|
||||||
#define GPU_LIT_SMPC_PRI_UNIQUE_BASE 29
|
#define GPU_LIT_SMPC_PRI_UNIQUE_BASE 29
|
||||||
/** Smpc pri stride. */
|
/** Smpc pri stride (in bytes). */
|
||||||
#define GPU_LIT_SMPC_PRI_STRIDE 30
|
#define GPU_LIT_SMPC_PRI_STRIDE 30
|
||||||
/** Twod class. */
|
/** Twod class. */
|
||||||
#define GPU_LIT_TWOD_CLASS 31
|
#define GPU_LIT_TWOD_CLASS 31
|
||||||
@@ -272,7 +273,7 @@ struct railgate_stats {
|
|||||||
#define GPU_LIT_I2M_CLASS 35
|
#define GPU_LIT_I2M_CLASS 35
|
||||||
/** Dma copy class. */
|
/** Dma copy class. */
|
||||||
#define GPU_LIT_DMA_COPY_CLASS 36
|
#define GPU_LIT_DMA_COPY_CLASS 36
|
||||||
/** Gpc priv stride. */
|
/** Gpc priv stride (in bytes). */
|
||||||
#define GPU_LIT_GPC_PRIV_STRIDE 37
|
#define GPU_LIT_GPC_PRIV_STRIDE 37
|
||||||
#ifdef CONFIG_NVGPU_DEBUGGER
|
#ifdef CONFIG_NVGPU_DEBUGGER
|
||||||
#define GPU_LIT_PERFMON_PMMGPCTPCA_DOMAIN_START 38
|
#define GPU_LIT_PERFMON_PMMGPCTPCA_DOMAIN_START 38
|
||||||
@@ -426,7 +427,10 @@ struct gk20a {
|
|||||||
/** Name of the gpu. */
|
/** Name of the gpu. */
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
/** Is the GPU ready to be used? */
|
/**
|
||||||
|
* Is the GPU ready to be used? Access to this field is protected by
|
||||||
|
* lock \ref gk20a "gk20a.power_spinlock".
|
||||||
|
*/
|
||||||
u32 power_on_state;
|
u32 power_on_state;
|
||||||
|
|
||||||
/** Is the GPU probe complete? */
|
/** Is the GPU probe complete? */
|
||||||
@@ -452,7 +456,7 @@ struct gk20a {
|
|||||||
struct nvgpu_thread sw_quiesce_thread;
|
struct nvgpu_thread sw_quiesce_thread;
|
||||||
/**
|
/**
|
||||||
* Struct having callback and it's arguments. The callback gets called
|
* Struct having callback and it's arguments. The callback gets called
|
||||||
* when BUG() is hit by the code.
|
* when \ref BUG is hit by the code.
|
||||||
*/
|
*/
|
||||||
struct nvgpu_bug_cb sw_quiesce_bug_cb;
|
struct nvgpu_bug_cb sw_quiesce_bug_cb;
|
||||||
|
|
||||||
@@ -556,7 +560,7 @@ struct gk20a {
|
|||||||
struct nvgpu_mutex power_lock;
|
struct nvgpu_mutex power_lock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Lock to protect accessing \a power_on_state. */
|
/** Lock to protect accessing \ref gk20a "gk20a.power_on_state". */
|
||||||
struct nvgpu_spinlock power_spinlock;
|
struct nvgpu_spinlock power_spinlock;
|
||||||
|
|
||||||
#ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING
|
#ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING
|
||||||
@@ -905,7 +909,8 @@ struct gk20a {
|
|||||||
/**
|
/**
|
||||||
* @brief Check if watchdog and context switch timeouts are enabled.
|
* @brief Check if watchdog and context switch timeouts are enabled.
|
||||||
*
|
*
|
||||||
* @param g [in] The GPU superstucture.
|
* @param g [in] The GPU superstructure.
|
||||||
|
* - The function does not perform validation of g parameter.
|
||||||
*
|
*
|
||||||
* @return timeouts enablement status
|
* @return timeouts enablement status
|
||||||
* @retval True always for safety or if these timeouts are actually enabled on
|
* @retval True always for safety or if these timeouts are actually enabled on
|
||||||
@@ -923,18 +928,19 @@ static inline bool nvgpu_is_timeouts_enabled(struct gk20a *g)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Minimum poll delay value in us */
|
/** Minimum poll delay value for h/w interactions(in microseconds). */
|
||||||
#define POLL_DELAY_MIN_US 10U
|
#define POLL_DELAY_MIN_US 10U
|
||||||
/** Maximum poll delay value in us */
|
/** Maximum poll delay value for h/w interactions(in microseconds). */
|
||||||
#define POLL_DELAY_MAX_US 200U
|
#define POLL_DELAY_MAX_US 200U
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the global poll timeout value
|
* @brief Get the global poll timeout value
|
||||||
*
|
*
|
||||||
* @param g [in] The GPU superstucture.
|
* @param g [in] The GPU superstructure.
|
||||||
|
* - The function does not perform validation of g parameter.
|
||||||
*
|
*
|
||||||
* @return The value of the global poll timeout value in us.
|
* @return The value of the global poll timeout value in microseconds.
|
||||||
* @retval NVGPU_DEFAULT_POLL_TIMEOUT_MS for safety as timeout is always
|
* @retval \ref NVGPU_DEFAULT_POLL_TIMEOUT_MS for safety as timeout is always
|
||||||
* enabled.
|
* enabled.
|
||||||
*/
|
*/
|
||||||
static inline u32 nvgpu_get_poll_timeout(struct gk20a *g)
|
static inline u32 nvgpu_get_poll_timeout(struct gk20a *g)
|
||||||
|
|||||||
@@ -63,14 +63,34 @@ struct gops_clk {
|
|||||||
unsigned long rate);
|
unsigned long rate);
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
* @brief Get max rate of gpu clock.
|
* @brief Get max rate of gpu clock in Hertz.
|
||||||
*
|
*
|
||||||
* @param g [in] gpu device struct pointer
|
* @param g [in] gpu device struct pointer
|
||||||
|
* - The function does not perform validation of g parameter.
|
||||||
* @param api_domain [in] clock domains type
|
* @param api_domain [in] clock domains type
|
||||||
* - CTRL_CLK_DOMAIN_GPCCLK
|
* - Only CTRL_CLK_DOMAIN_GPCCLK value is valid.
|
||||||
*
|
*
|
||||||
* This routine helps to get max supported rate for given clock domain.
|
* This routine helps to get max supported rate (in Hz) for given clock
|
||||||
* Currently API only supports Graphics clock domain.
|
* domain. Currently API only supports Graphics clock domain. Steps
|
||||||
|
* involved are
|
||||||
|
* - Pointer to struct \ref nvgpu_os_rmos which embeds \a g is retrieved
|
||||||
|
* using function \ref nvgpu_os_rmos_from_gk20a
|
||||||
|
* "nvgpu_os_rmos_from_gk20a(g)".
|
||||||
|
* - Then pointer to struct \ref nvgpu_power_ctx is obtained using
|
||||||
|
* \ref nvgpu_os_rmos "nvgpu_os_rmos.context" in a local variable
|
||||||
|
* ctx.
|
||||||
|
* - If \a api_domain CTRL_CLK_DOMAIN_GPCCLK is used, handle of
|
||||||
|
* NvClockClock is obtained by calling \ref nvgpu_power_ctx_get_clk
|
||||||
|
* "nvgpu_power_ctx_get_clk(ctx, 0, &gpu_clk)" in a local variable
|
||||||
|
* gpu_clk. If the call fails return 0.
|
||||||
|
* - Finally, QNX-BSP external call
|
||||||
|
* NvClockGetMaxDeviceClockFreq(gpu_clk, &freq) is made and the
|
||||||
|
* frequency corresponding to \a api_domain CTRL_CLK_DOMAIN_GPCCLK is
|
||||||
|
* returned in a local variable freq. If the call fails then set freq
|
||||||
|
* to 0.
|
||||||
|
* - If the \a api_domain passed is not CTRL_CLK_DOMAIN_GPCCLK, then log
|
||||||
|
* error that "unknown clock domain".
|
||||||
|
* - Return freq variable after typecasting to u64.
|
||||||
*
|
*
|
||||||
* @return 0 in case of failure and > 0 in case of success
|
* @return 0 in case of failure and > 0 in case of success
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -171,9 +171,49 @@ struct gpu_ops {
|
|||||||
struct gops_profiler profiler;
|
struct gops_profiler profiler;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Ops to get litter value corresponding to litter define. */
|
/**
|
||||||
|
* @brief Ops to get litter value corresponding to litter define.
|
||||||
|
*
|
||||||
|
* @param g [in] The GPU driver struct.
|
||||||
|
* - The function does not perform validation of g parameter.
|
||||||
|
* @param value [in] Litter define.
|
||||||
|
* - Must be one of the litter defined in common.nvgpu unit.
|
||||||
|
*
|
||||||
|
* This function returns the value of the litter define.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
* - Use switch-case statement on param \a value and return chip
|
||||||
|
* specific litter value.
|
||||||
|
* - Call #BUG() if the default label of switch-case is hit.
|
||||||
|
*/
|
||||||
u32 (*get_litter_value)(struct gk20a *g, int value);
|
u32 (*get_litter_value)(struct gk20a *g, int value);
|
||||||
/** Ops to initialize gpu characteristics. */
|
|
||||||
|
/**
|
||||||
|
* @brief Ops to initialize gpu characteristics.
|
||||||
|
*
|
||||||
|
* @param g [in] The GPU driver struct.
|
||||||
|
* - The function does not perform validation of g parameter.
|
||||||
|
*
|
||||||
|
* This function initializes gpu characteristics for the specific chip.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
* - Calls \ref nvgpu_init_gpu_characteristics
|
||||||
|
* "nvgpu_init_gpu_characteristics(g)" to initialize the default
|
||||||
|
* characteristics and return error if it fails.
|
||||||
|
* - Calls \ref nvgpu_set_enabled
|
||||||
|
* "nvgpu_set_enabled(g, NVGPU_SUPPORT_TSG_SUBCONTEXTS, true)".
|
||||||
|
* - Calls \ref nvgpu_set_enabled
|
||||||
|
* "nvgpu_set_enabled(g, NVGPU_SUPPORT_SCG, true)".
|
||||||
|
* - Calls \ref nvgpu_set_enabled
|
||||||
|
* "nvgpu_set_enabled(g, NVGPU_SUPPORT_SYNCPOINT_ADDRESS, true)".
|
||||||
|
* - Calls \ref nvgpu_set_enabled
|
||||||
|
* "nvgpu_set_enabled(g, NVGPU_SUPPORT_USER_SYNCPOINT, true)".
|
||||||
|
* - Calls \ref nvgpu_set_enabled
|
||||||
|
* "nvgpu_set_enabled(g, NVGPU_SUPPORT_USER_SYNCPOINT, true)".
|
||||||
|
*
|
||||||
|
* @return 0 in case of success, < 0 otherwise.
|
||||||
|
* @retval 0 in case of success.
|
||||||
|
*/
|
||||||
int (*chip_init_gpu_characteristics)(struct gk20a *g);
|
int (*chip_init_gpu_characteristics)(struct gk20a *g);
|
||||||
|
|
||||||
/** Bus hal ops. */
|
/** Bus hal ops. */
|
||||||
|
|||||||
@@ -54,8 +54,10 @@ static inline s64 nvgpu_safe_cast_u64_to_s64(u64 ul_a);
|
|||||||
* @param ui_a [in] Addend value for adding.
|
* @param ui_a [in] Addend value for adding.
|
||||||
* @param ui_b [in] Addend value for adding.
|
* @param ui_b [in] Addend value for adding.
|
||||||
*
|
*
|
||||||
* Adds the two u32 values unless the result will overflow a u32. If the result
|
* Adds the two u32 (unsigned 32 bit) values unless the result will overflow a
|
||||||
* would overflow a u32, calls BUG().
|
* u32. Overflow will happen if the difference between UNIT_MAX (the max number
|
||||||
|
* representable with 32 bits) and one addend is less than the other addend.
|
||||||
|
* Call #BUG() in such a case else return the sum.
|
||||||
*
|
*
|
||||||
* @return If no overflow, sum of the two integers (\a ui_a + \a ui_b).
|
* @return If no overflow, sum of the two integers (\a ui_a + \a ui_b).
|
||||||
*/
|
*/
|
||||||
@@ -75,8 +77,14 @@ static inline u32 nvgpu_safe_add_u32(u32 ui_a, u32 ui_b)
|
|||||||
* @param si_a [in] Addend value for adding.
|
* @param si_a [in] Addend value for adding.
|
||||||
* @param si_b [in] Addend value for adding.
|
* @param si_b [in] Addend value for adding.
|
||||||
*
|
*
|
||||||
* Adds the two s32 values unless the result will overflow a s32. If the result
|
* Adds the two s32 (signed 32 bit) values unless the result will overflow or
|
||||||
* would overflow a s32, calls BUG().
|
* underflow a s32. If the result would overflow or underflow, call #BUG(). To
|
||||||
|
* determine whether the addition will cause an overflow/underflow, following
|
||||||
|
* steps are performed.
|
||||||
|
* - If \a si_b is greater than 0 and \a si_a is greater than difference between
|
||||||
|
* INT_MAX and \a si_b, addition will overflow so call #BUG().
|
||||||
|
* - If \a si_b is less than 0 and \a si_a is less than difference between
|
||||||
|
* INT_MIN and \a si_b, addition will underflow so call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, sum of the two integers (\a si_a + \a si_b).
|
* @return If no overflow, sum of the two integers (\a si_a + \a si_b).
|
||||||
*/
|
*/
|
||||||
@@ -97,8 +105,10 @@ static inline s32 nvgpu_safe_add_s32(s32 si_a, s32 si_b)
|
|||||||
* @param ul_a [in] Addend value for adding.
|
* @param ul_a [in] Addend value for adding.
|
||||||
* @param ul_b [in] Addend value for adding.
|
* @param ul_b [in] Addend value for adding.
|
||||||
*
|
*
|
||||||
* Adds the two u64 values unless the result will overflow a u64. If the result
|
* Adds the two u64 (unsigned 64 bit) values unless the result will overflow a
|
||||||
* would overflow a u64, calls BUG().
|
* u64. Overflow will happen if the difference between ULONG_MAX (the max number
|
||||||
|
* representable with 64 bits) and one addend is less than the other addend.
|
||||||
|
* Call #BUG() in such a case else return the sum.
|
||||||
*
|
*
|
||||||
* @return If no overflow, sum of the two integers (\a ul_a + \a ul_b).
|
* @return If no overflow, sum of the two integers (\a ul_a + \a ul_b).
|
||||||
*/
|
*/
|
||||||
@@ -119,8 +129,14 @@ NVGPU_COV_WHITELIST(false_positive, NVGPU_CERT(INT30_C), "Bug 2643092")
|
|||||||
* @param sl_a [in] Addend value for adding.
|
* @param sl_a [in] Addend value for adding.
|
||||||
* @param sl_b [in] Addend value for adding.
|
* @param sl_b [in] Addend value for adding.
|
||||||
*
|
*
|
||||||
* Adds the two s64 values unless the result will overflow a s64. If the result
|
* Adds the two s64 (signed 64 bit) values unless the result will overflow or
|
||||||
* would overflow a s64, calls BUG().
|
* underflow a s64. If the result would overflow or underflow, call #BUG(). To
|
||||||
|
* determine whether the addition will cause an overflow/underflow, following
|
||||||
|
* steps are performed.
|
||||||
|
* - If \a sl_b is greater than 0 and \a sl_a is greater than difference between
|
||||||
|
* LONG_MAX and \a sl_b, addition will overflow so call #BUG().
|
||||||
|
* - If \a sl_b is less than 0 and \a sl_a is less than difference between
|
||||||
|
* LONG_MIN and \a sl_b, addition will underflow so call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, sum of the two integers (\a sl_a + \a sl_b).
|
* @return If no overflow, sum of the two integers (\a sl_a + \a sl_b).
|
||||||
*/
|
*/
|
||||||
@@ -224,8 +240,9 @@ static inline u32 nvgpu_wrapping_sub_u32(u32 ui_a, u32 ui_b)
|
|||||||
* @param uc_a [in] Value of minuend.
|
* @param uc_a [in] Value of minuend.
|
||||||
* @param uc_b [in] Value of subtrahend.
|
* @param uc_b [in] Value of subtrahend.
|
||||||
*
|
*
|
||||||
* Subtracts \a uc_b from \a uc_a unless the result will underflow a u8. If the
|
* Subtracts \a uc_b from \a uc_a unless the result will underflow a u8
|
||||||
* result would underflow, calls BUG().
|
* (unsigned 8 bit). If \a uc_a is less than \a uc_b then result would underflow
|
||||||
|
* so call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, difference of the two integers (\a uc_a - \a uc_b).
|
* @return If no overflow, difference of the two integers (\a uc_a - \a uc_b).
|
||||||
*/
|
*/
|
||||||
@@ -245,8 +262,9 @@ static inline u8 nvgpu_safe_sub_u8(u8 uc_a, u8 uc_b)
|
|||||||
* @param ui_a [in] Value of minuend.
|
* @param ui_a [in] Value of minuend.
|
||||||
* @param ui_b [in] Value of subtrahend.
|
* @param ui_b [in] Value of subtrahend.
|
||||||
*
|
*
|
||||||
* Subtracts \a ui_b from \a ui_a unless the result will underflow a u32. If the
|
* Subtracts \a ui_b from \a ui_a unless the result will underflow a u32
|
||||||
* result would underflow, calls BUG().
|
* (unsigned 32 bit). If \a ui_a is less than \a ui_b then result would
|
||||||
|
* underflow so call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, difference of the two integers (\a ui_a - \a ui_b).
|
* @return If no overflow, difference of the two integers (\a ui_a - \a ui_b).
|
||||||
*/
|
*/
|
||||||
@@ -266,8 +284,14 @@ static inline u32 nvgpu_safe_sub_u32(u32 ui_a, u32 ui_b)
|
|||||||
* @param si_a [in] Value of minuend.
|
* @param si_a [in] Value of minuend.
|
||||||
* @param si_b [in] Value of subtrahend.
|
* @param si_b [in] Value of subtrahend.
|
||||||
*
|
*
|
||||||
* Subtracts \a si_b from \a si_a unless the result will underflow a s32. If the
|
* Subtracts \a si_b from \a si_a unless the result will underflow a s32
|
||||||
* result would underflow, calls BUG().
|
* (signed 32 bit). If the result would overflow or underflow, call #BUG(). To
|
||||||
|
* determine whether the subtraction will cause an overflow/underflow, following
|
||||||
|
* steps are performed.
|
||||||
|
* - If \a si_b is greater than 0 and \a si_a is less than sum of INT_MIN and
|
||||||
|
* \a si_b, subtraction will underflow so call #BUG().
|
||||||
|
* - If \a si_b is less than 0 and \a si_a is greater than sum of INT_MAX and
|
||||||
|
* \a si_b, addition will overflow so call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, difference of the two integers (\a si_a - \a si_b).
|
* @return If no overflow, difference of the two integers (\a si_a - \a si_b).
|
||||||
*/
|
*/
|
||||||
@@ -288,8 +312,9 @@ static inline s32 nvgpu_safe_sub_s32(s32 si_a, s32 si_b)
|
|||||||
* @param ul_a [in] Value of minuend.
|
* @param ul_a [in] Value of minuend.
|
||||||
* @param ul_b [in] Value of subtrahend.
|
* @param ul_b [in] Value of subtrahend.
|
||||||
*
|
*
|
||||||
* Subtracts \a ul_b from \a ul_a unless the result will underflow a u64. If the
|
* Subtracts \a ul_b from \a ul_a unless the result will underflow a u64
|
||||||
* result would underflow, calls BUG().
|
* (unsigned 64 bit). If \a ul_a is less than \a ul_b then result would
|
||||||
|
* underflow so call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, difference of the two integers (\a ul_a - \a ul_b).
|
* @return If no overflow, difference of the two integers (\a ul_a - \a ul_b).
|
||||||
*/
|
*/
|
||||||
@@ -321,7 +346,12 @@ static inline u64 nvgpu_safe_sub_u64(u64 ul_a, u64 ul_b)
|
|||||||
* @param si_b [in] Value of subtrahend.
|
* @param si_b [in] Value of subtrahend.
|
||||||
*
|
*
|
||||||
* Subtracts \a si_b from \a si_a unless the result will underflow a s64. If the
|
* Subtracts \a si_b from \a si_a unless the result will underflow a s64. If the
|
||||||
* result would underflow, calls BUG().
|
* result would overflow or underflow, call #BUG(). To determine whether the
|
||||||
|
* subtraction will cause an overflow/underflow, following steps are performed.
|
||||||
|
* - If \a si_b is greater than 0 and \si_a is less than sum of LONG_MIN and
|
||||||
|
* \a si_b, subtraction will underflow so call #BUG().
|
||||||
|
* - If \a si_b is less than 0 and \si_a is greater than sum of LONG_MAX and
|
||||||
|
* \a si_b, addition will overflow so call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, difference of the two integers (\a si_a - \a si_b).
|
* @return If no overflow, difference of the two integers (\a si_a - \a si_b).
|
||||||
*/
|
*/
|
||||||
@@ -343,7 +373,12 @@ static inline s64 nvgpu_safe_sub_s64(s64 si_a, s64 si_b)
|
|||||||
* @param ui_b [in] Value of multiplier.
|
* @param ui_b [in] Value of multiplier.
|
||||||
*
|
*
|
||||||
* Multiplies \a ui_a and \a ui_b unless the result will overflow a u32. If the
|
* Multiplies \a ui_a and \a ui_b unless the result will overflow a u32. If the
|
||||||
* result would underflow, calls BUG().
|
* result would overflow, call #BUG(). To determine whether the multiplication
|
||||||
|
* will cause an overflow, following steps are performed.
|
||||||
|
* - If \a ui_a or \a ui_b is 0 return 0 as multiplication result.
|
||||||
|
* - Else if \a ui_a is greater than UINT_MAX division by \a ui_b,
|
||||||
|
* multiplication will overflow so call #BUG().
|
||||||
|
* - Else return result of multiplication.
|
||||||
*
|
*
|
||||||
* @return If no overflow, product of the two integers (\a ui_a * \a ui_b).
|
* @return If no overflow, product of the two integers (\a ui_a * \a ui_b).
|
||||||
*/
|
*/
|
||||||
@@ -365,8 +400,13 @@ static inline u32 nvgpu_safe_mult_u32(u32 ui_a, u32 ui_b)
|
|||||||
* @param ul_a [in] Value of multiplicand.
|
* @param ul_a [in] Value of multiplicand.
|
||||||
* @param ul_b [in] Value of multiplier.
|
* @param ul_b [in] Value of multiplier.
|
||||||
*
|
*
|
||||||
* Multiplies \a ul_a and \a ul_b unless the result will overflow a u64. If the
|
* Multiplies \a ul_a and \a ul_b unless the result will overflow a u32. If the
|
||||||
* result would underflow, calls BUG().
|
* result would overflow, call #BUG(). To determine whether the multiplication
|
||||||
|
* will cause an overflow, following steps are performed.
|
||||||
|
* - If \a ul_a or \a ul_b is 0 return 0 as multiplication result.
|
||||||
|
* - Else if \a ul_a is greater than ULONG_MAX division by \a ul_b,
|
||||||
|
* multiplication will overflow so call #BUG().
|
||||||
|
* - Else return result of multiplication.
|
||||||
*
|
*
|
||||||
* @return If no overflow, product of the two integers (\a ul_a * \a ul_b).
|
* @return If no overflow, product of the two integers (\a ul_a * \a ul_b).
|
||||||
*/
|
*/
|
||||||
@@ -389,7 +429,20 @@ static inline u64 nvgpu_safe_mult_u64(u64 ul_a, u64 ul_b)
|
|||||||
* @param sl_b [in] Value of multiplier.
|
* @param sl_b [in] Value of multiplier.
|
||||||
*
|
*
|
||||||
* Multiplies \a sl_a and \a sl_b unless the result will overflow or underflow a
|
* Multiplies \a sl_a and \a sl_b unless the result will overflow or underflow a
|
||||||
* s64. If the result would overflow or underflow, calls BUG().
|
* s64. If the result would overflow or underflow, call #BUG(). To determine
|
||||||
|
* whether the multiplication will cause an overflow/underflow, following steps
|
||||||
|
* are performed.
|
||||||
|
* - If \a sl_a and \a sl_b are greater than 0 and LONG_MAX division by \a sl_b
|
||||||
|
* is less than \a sl_a, multiplication will overflow so call #BUG().
|
||||||
|
* - If \a sl_a is greater than 0, \a sl_b is less than or equal to 0 and
|
||||||
|
* LONG_MIN division by \a sl_a is greater than \a sl_b, multiplication will
|
||||||
|
* underflow so call #BUG().
|
||||||
|
* - If \a sl_b is greater than 0, \a sl_a is less than or equal to 0 and
|
||||||
|
* LONG_MIN division by \a sl_b is greater than \a sl_a, multiplication will
|
||||||
|
* underflow so call #BUG().
|
||||||
|
* - If \a sl_a is less than 0, \a sl_b is less than or equal to 0 and LONG_MAX
|
||||||
|
* division by \a sl_a is greater than \a sl_b, multiplication will overflow
|
||||||
|
* so call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow/underflow, product of the two integers (\a sl_a *
|
* @return If no overflow/underflow, product of the two integers (\a sl_a *
|
||||||
* \a sl_b).
|
* \a sl_b).
|
||||||
@@ -430,8 +483,8 @@ static inline s64 nvgpu_safe_mult_s64(s64 sl_a, s64 sl_b)
|
|||||||
*
|
*
|
||||||
* @param ul_a [in] Value to cast.
|
* @param ul_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a ul_a to a u16 unless the result will overflow a u16. If the result
|
* Casts \a ul_a to a u16 unless the result will overflow a u16. If \a ul_a is
|
||||||
* would overflow, calls BUG().
|
* greater than USHRT_MAX which indicates overflow, call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, u16 representation of the value in \a ul_a.
|
* @return If no overflow, u16 representation of the value in \a ul_a.
|
||||||
*/
|
*/
|
||||||
@@ -450,8 +503,8 @@ static inline u16 nvgpu_safe_cast_u64_to_u16(u64 ul_a)
|
|||||||
*
|
*
|
||||||
* @param ul_a [in] Value to cast.
|
* @param ul_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a ul_a to a u32 unless the result will overflow a u32. If the result
|
* Casts \a ul_a to a u32 unless the result will overflow a u32. If \a ul_a is
|
||||||
* would overflow, calls BUG().
|
* greater than UINT_MAX which indicates overflow, call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, u32 representation of the value in \a ul_a.
|
* @return If no overflow, u32 representation of the value in \a ul_a.
|
||||||
*/
|
*/
|
||||||
@@ -470,8 +523,9 @@ static inline u32 nvgpu_safe_cast_u64_to_u32(u64 ul_a)
|
|||||||
*
|
*
|
||||||
* @param ul_a [in] Value to cast.
|
* @param ul_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a ul_a to a u8 unless the result will overflow a u8. If the result
|
* Casts \a ul_a to a u8 unless the result will overflow a u8. If \a ul_a is
|
||||||
* would overflow, calls BUG().
|
* greater than UCHAR_MAX (typecasted to u64 as it is s32) which indicates
|
||||||
|
* overflow, call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, u8 representation of the value in \a ul_a.
|
* @return If no overflow, u8 representation of the value in \a ul_a.
|
||||||
*/
|
*/
|
||||||
@@ -491,7 +545,8 @@ static inline u8 nvgpu_safe_cast_u64_to_u8(u64 ul_a)
|
|||||||
* @param l_a [in] Value to cast.
|
* @param l_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a l_a to a u32 unless the result will overflow or underflow a u32.
|
* Casts \a l_a to a u32 unless the result will overflow or underflow a u32.
|
||||||
* If the result would overflow/underflow, calls BUG().
|
* If \a l_a is less than 0 which indicates underflow or if \a l_a is greater
|
||||||
|
* than UINT_MAX (typecasted to s64) which indicates overflow, call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow/underflow, u32 representation of the value in \a l_a.
|
* @return If no overflow/underflow, u32 representation of the value in \a l_a.
|
||||||
*/
|
*/
|
||||||
@@ -510,8 +565,8 @@ static inline u32 nvgpu_safe_cast_s64_to_u32(s64 l_a)
|
|||||||
*
|
*
|
||||||
* @param l_a [in] Value to cast.
|
* @param l_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a l_a to a u64 unless the result will underflow a u64. If the result
|
* Casts \a l_a to a u64 unless the result will underflow a u64. If \a l_a is
|
||||||
* would underflow, calls BUG().
|
* less than 0 which indicates underflow, call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no underflow, u64 representation of the value in \a l_a.
|
* @return If no underflow, u64 representation of the value in \a l_a.
|
||||||
*/
|
*/
|
||||||
@@ -542,8 +597,8 @@ static inline u32 nvgpu_safe_cast_bool_to_u32(bool bl_a)
|
|||||||
*
|
*
|
||||||
* @param sc_a [in] Value to cast.
|
* @param sc_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a sc_a to a u8 unless the result will underflow a u8. If the result
|
* Casts \a sc_a to a u8 unless the result will underflow a u8. If \a sc_a is
|
||||||
* would underflow, calls BUG().
|
* less than 0 which indicates underflow, call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no underflow, u8 representation of the value in \a sc_a.
|
* @return If no underflow, u8 representation of the value in \a sc_a.
|
||||||
*/
|
*/
|
||||||
@@ -563,8 +618,8 @@ NVGPU_COV_WHITELIST(false_positive, NVGPU_CERT(STR34_C), "Bug 2673832")
|
|||||||
*
|
*
|
||||||
* @param si_a [in] Value to cast.
|
* @param si_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a si_a to a u32 unless the result will underflow a u32. If the result
|
* Casts \a si_a to a u32 unless the result will underflow a u32. If \a si_a is
|
||||||
* would underflow, calls BUG().
|
* less than 0 which indicates underflow, call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no underflow, u32 representation of the value in \a si_a.
|
* @return If no underflow, u32 representation of the value in \a si_a.
|
||||||
*/
|
*/
|
||||||
@@ -583,8 +638,8 @@ static inline u32 nvgpu_safe_cast_s32_to_u32(s32 si_a)
|
|||||||
*
|
*
|
||||||
* @param si_a [in] Value to cast.
|
* @param si_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a si_a to a u64 unless the result will underflow a u64. If the result
|
* Casts \a si_a to a u64 unless the result will underflow a u64. If \a si_a is
|
||||||
* would underflow, calls BUG().
|
* less than 0 which indicates underflow, call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no underflow, u64 representation of the value in \a si_a.
|
* @return If no underflow, u64 representation of the value in \a si_a.
|
||||||
*/
|
*/
|
||||||
@@ -603,8 +658,8 @@ static inline u64 nvgpu_safe_cast_s32_to_u64(s32 si_a)
|
|||||||
*
|
*
|
||||||
* @param ui_a [in] Value to cast.
|
* @param ui_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a ui_a to a u16 unless the result will overflow a u16. If the result
|
* Casts \a ui_a to a u16 unless the result will overflow a u16. If \a ui_a is
|
||||||
* would overflow, calls BUG().
|
* greater than USHRT_MAX which indicates overflow, call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, u16 representation of the value in \a ui_a.
|
* @return If no overflow, u16 representation of the value in \a ui_a.
|
||||||
*/
|
*/
|
||||||
@@ -623,8 +678,9 @@ static inline u16 nvgpu_safe_cast_u32_to_u16(u32 ui_a)
|
|||||||
*
|
*
|
||||||
* @param ui_a [in] Value to cast.
|
* @param ui_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a ui_a to a u8 unless the result will overflow a u8. If the result
|
* Casts \a ui_a to a u8 unless the result will overflow a u8. If \a ui_a is
|
||||||
* would overflow, calls BUG().
|
* greater than UCHAR_MAX (typecasted to u32) which indicates overflow, call
|
||||||
|
* #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, u8 representation of the value in \a ui_a.
|
* @return If no overflow, u8 representation of the value in \a ui_a.
|
||||||
*/
|
*/
|
||||||
@@ -643,8 +699,9 @@ static inline u8 nvgpu_safe_cast_u32_to_u8(u32 ui_a)
|
|||||||
*
|
*
|
||||||
* @param ui_a [in] Value to cast.
|
* @param ui_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a ui_a to a s8 unless the result will overflow a s8. If the result
|
* Casts \a ui_a to a s8 unless the result will overflow a s8. If \a ui_a is
|
||||||
* would overflow, calls BUG().
|
* greater than SCHAR_MAX (typecasted to u32) which indicates overflow, call
|
||||||
|
* #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, s8 representation of the value in \a ui_a.
|
* @return If no overflow, s8 representation of the value in \a ui_a.
|
||||||
*/
|
*/
|
||||||
@@ -663,8 +720,9 @@ static inline s8 nvgpu_safe_cast_u32_to_s8(u32 ui_a)
|
|||||||
*
|
*
|
||||||
* @param ui_a [in] Value to cast.
|
* @param ui_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a ui_a to a s32 unless the result will overflow a s32. If the result
|
* Casts \a ui_a to a s32 unless the result will overflow a s32. If \a ui_a is
|
||||||
* would overflow, calls BUG().
|
* greater than SCHAR_MAX (typecasted to u32) which indicates overflow, call
|
||||||
|
* #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, s32 representation of the value in \a ui_a.
|
* @return If no overflow, s32 representation of the value in \a ui_a.
|
||||||
*/
|
*/
|
||||||
@@ -683,8 +741,9 @@ static inline s32 nvgpu_safe_cast_u32_to_s32(u32 ui_a)
|
|||||||
*
|
*
|
||||||
* @param ul_a [in] Value to cast.
|
* @param ul_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a ul_a to a s32 unless the result will overflow a s32. If the result
|
* Casts \a ul_a to a s32 unless the result will overflow a s32. If \a ul_a is
|
||||||
* would overflow, calls BUG().
|
* greater than INT_MAX (typecasted to u64) which indicates overflow, call
|
||||||
|
* #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, s32 representation of the value in \a ul_a.
|
* @return If no overflow, s32 representation of the value in \a ul_a.
|
||||||
*/
|
*/
|
||||||
@@ -703,8 +762,9 @@ static inline s32 nvgpu_safe_cast_u64_to_s32(u64 ul_a)
|
|||||||
*
|
*
|
||||||
* @param ul_a [in] Value to cast.
|
* @param ul_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a ul_a to a s64 unless the result will overflow a s64. If the result
|
* Casts \a ul_a to a s64 unless the result will overflow a s64. If \a ul_a
|
||||||
* would overflow, calls BUG().
|
* greater than LONG_MAX (typecasted to u64) which indicates overflow, call
|
||||||
|
* #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow, s64 representation of the value in \a ul_a.
|
* @return If no overflow, s64 representation of the value in \a ul_a.
|
||||||
*/
|
*/
|
||||||
@@ -725,7 +785,8 @@ NVGPU_COV_WHITELIST(false_positive, NVGPU_MISRA(Rule, 14_3), "Bug 2615925")
|
|||||||
* @param sl_a [in] Value to cast.
|
* @param sl_a [in] Value to cast.
|
||||||
*
|
*
|
||||||
* Casts \a sl_a to a s32 unless the result will overflow or underflow a s32. If
|
* Casts \a sl_a to a s32 unless the result will overflow or underflow a s32. If
|
||||||
* the result would overflow/underflow, calls BUG().
|
* \a sl_a is greater than INT_MAX which indicates overflow or \a sl_a is less
|
||||||
|
* than INT_MIN which indicates underflow, call #BUG().
|
||||||
*
|
*
|
||||||
* @return If no overflow/underflow, s32 representation of the value in \a sl_a.
|
* @return If no overflow/underflow, s32 representation of the value in \a sl_a.
|
||||||
*/
|
*/
|
||||||
@@ -787,7 +848,27 @@ static inline s32 nvgpu_safe_cast_s64_to_s32(s64 sl_a)
|
|||||||
*
|
*
|
||||||
* Validate precision of unsigned types. These validations are used to justify
|
* Validate precision of unsigned types. These validations are used to justify
|
||||||
* that no security issues exist in NvGPU driver due to CERT-C INT34-C and
|
* that no security issues exist in NvGPU driver due to CERT-C INT34-C and
|
||||||
* INT35-C violations.
|
* INT35-C violations. Steps of validation
|
||||||
|
* - If \ref #NVGPU_PRECISION "NVGPU_PRECISION(UINT_MAX)" typecasted to u64 does
|
||||||
|
* not matches size of unsigned init (in bytes) multiplied by 8 (number of
|
||||||
|
* bits in a byte), call #BUG().
|
||||||
|
* - If \ref #NVGPU_PRECISION "NVGPU_PRECISION(UCHAR_MAX)" is not equal to 8 or
|
||||||
|
* \ref #NVGPU_PRECISION "NVGPU_PRECISION(USHRT_MAX)" is not equal to 16 or
|
||||||
|
* \ref #NVGPU_PRECISION "NVGPU_PRECISION(UINT_MAX)" is not equal to 32 or
|
||||||
|
* \ref #NVGPU_PRECISION "NVGPU_PRECISION(ULONG_MAX)" is not equal to 64 or
|
||||||
|
* \ref #NVGPU_PRECISION "NVGPU_PRECISION(ULLONG_MAX)" is not equal to 64,
|
||||||
|
* call #BUG().
|
||||||
|
* - If size of s64 (in bytes) is not equal to size of long (in bytes) or
|
||||||
|
* size of s64 (in bytes) is not equal to size of int64_t (in bytes) or
|
||||||
|
* size of u64 (in bytes) is not equal to size of uint64_t (in bytes) or
|
||||||
|
* size of u64 (in bytes) is not equal to size of _Uint64_t (in bytes) or
|
||||||
|
* size of u64 (in bytes) is not equal to size of uintptr_t (in bytes) or
|
||||||
|
* size of u64 (in bytes) is not equal to size of unsigned long (in bytes) or
|
||||||
|
* size of size_t (in bytes) is not equal to size of u64 (in bytes) or
|
||||||
|
* size of size_t (in bytes) is not equal to size of unsigned long long (in
|
||||||
|
* bytes) or
|
||||||
|
* size of unsigned long long (in bytes) is not equal to size of unsigned long
|
||||||
|
* (in bytes), call #BUG().
|
||||||
*
|
*
|
||||||
* This function shall be called early in the driver probe to ensure that code
|
* This function shall be called early in the driver probe to ensure that code
|
||||||
* violating CERT-C INT34-C and INT35-C rules is not run before these checks.
|
* violating CERT-C INT34-C and INT35-C rules is not run before these checks.
|
||||||
|
|||||||
Reference in New Issue
Block a user