mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
habanalabs: improve security in Debug IOCTL
This patch improves the security in the Debug IOCTL. It adds checks that: - The register index value is in the allowed range for all opcodes. - The event types number is in the allowed range in SPMU enable. - The events number is in the allowed range in SPMU disable. Signed-off-by: Omer Shpigelman <oshpigelman@habana.ai> Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
This commit is contained in:
parent
8d1759329d
commit
9b50f539ff
1 changed files with 62 additions and 10 deletions
|
@ -15,6 +15,10 @@
|
|||
|
||||
#define GOYA_PLDM_CORESIGHT_TIMEOUT_USEC (CORESIGHT_TIMEOUT_USEC * 100)
|
||||
|
||||
#define SPMU_SECTION_SIZE DMA_CH_0_CS_SPMU_MAX_OFFSET
|
||||
#define SPMU_EVENT_TYPES_OFFSET 0x400
|
||||
#define SPMU_MAX_COUNTERS 6
|
||||
|
||||
static u64 debug_stm_regs[GOYA_STM_LAST + 1] = {
|
||||
[GOYA_STM_CPU] = mmCPU_STM_BASE,
|
||||
[GOYA_STM_DMA_CH_0_CS] = mmDMA_CH_0_CS_STM_BASE,
|
||||
|
@ -226,9 +230,16 @@ static int goya_config_stm(struct hl_device *hdev,
|
|||
struct hl_debug_params *params)
|
||||
{
|
||||
struct hl_debug_params_stm *input;
|
||||
u64 base_reg = debug_stm_regs[params->reg_idx] - CFG_BASE;
|
||||
u64 base_reg;
|
||||
int rc;
|
||||
|
||||
if (params->reg_idx >= ARRAY_SIZE(debug_stm_regs)) {
|
||||
dev_err(hdev->dev, "Invalid register index in STM\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base_reg = debug_stm_regs[params->reg_idx] - CFG_BASE;
|
||||
|
||||
WREG32(base_reg + 0xFB0, CORESIGHT_UNLOCK);
|
||||
|
||||
if (params->enable) {
|
||||
|
@ -288,10 +299,17 @@ static int goya_config_etf(struct hl_device *hdev,
|
|||
struct hl_debug_params *params)
|
||||
{
|
||||
struct hl_debug_params_etf *input;
|
||||
u64 base_reg = debug_etf_regs[params->reg_idx] - CFG_BASE;
|
||||
u64 base_reg;
|
||||
u32 val;
|
||||
int rc;
|
||||
|
||||
if (params->reg_idx >= ARRAY_SIZE(debug_etf_regs)) {
|
||||
dev_err(hdev->dev, "Invalid register index in ETF\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base_reg = debug_etf_regs[params->reg_idx] - CFG_BASE;
|
||||
|
||||
WREG32(base_reg + 0xFB0, CORESIGHT_UNLOCK);
|
||||
|
||||
val = RREG32(base_reg + 0x304);
|
||||
|
@ -445,11 +463,18 @@ static int goya_config_etr(struct hl_device *hdev,
|
|||
static int goya_config_funnel(struct hl_device *hdev,
|
||||
struct hl_debug_params *params)
|
||||
{
|
||||
WREG32(debug_funnel_regs[params->reg_idx] - CFG_BASE + 0xFB0,
|
||||
CORESIGHT_UNLOCK);
|
||||
u64 base_reg;
|
||||
|
||||
WREG32(debug_funnel_regs[params->reg_idx] - CFG_BASE,
|
||||
params->enable ? 0x33F : 0);
|
||||
if (params->reg_idx >= ARRAY_SIZE(debug_funnel_regs)) {
|
||||
dev_err(hdev->dev, "Invalid register index in FUNNEL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base_reg = debug_funnel_regs[params->reg_idx] - CFG_BASE;
|
||||
|
||||
WREG32(base_reg + 0xFB0, CORESIGHT_UNLOCK);
|
||||
|
||||
WREG32(base_reg, params->enable ? 0x33F : 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -458,9 +483,16 @@ static int goya_config_bmon(struct hl_device *hdev,
|
|||
struct hl_debug_params *params)
|
||||
{
|
||||
struct hl_debug_params_bmon *input;
|
||||
u64 base_reg = debug_bmon_regs[params->reg_idx] - CFG_BASE;
|
||||
u64 base_reg;
|
||||
u32 pcie_base = 0;
|
||||
|
||||
if (params->reg_idx >= ARRAY_SIZE(debug_bmon_regs)) {
|
||||
dev_err(hdev->dev, "Invalid register index in BMON\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base_reg = debug_bmon_regs[params->reg_idx] - CFG_BASE;
|
||||
|
||||
WREG32(base_reg + 0x104, 1);
|
||||
|
||||
if (params->enable) {
|
||||
|
@ -522,7 +554,7 @@ static int goya_config_bmon(struct hl_device *hdev,
|
|||
static int goya_config_spmu(struct hl_device *hdev,
|
||||
struct hl_debug_params *params)
|
||||
{
|
||||
u64 base_reg = debug_spmu_regs[params->reg_idx] - CFG_BASE;
|
||||
u64 base_reg;
|
||||
struct hl_debug_params_spmu *input = params->input;
|
||||
u64 *output;
|
||||
u32 output_arr_len;
|
||||
|
@ -531,6 +563,13 @@ static int goya_config_spmu(struct hl_device *hdev,
|
|||
u32 cycle_cnt_idx;
|
||||
int i;
|
||||
|
||||
if (params->reg_idx >= ARRAY_SIZE(debug_spmu_regs)) {
|
||||
dev_err(hdev->dev, "Invalid register index in SPMU\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base_reg = debug_spmu_regs[params->reg_idx] - CFG_BASE;
|
||||
|
||||
if (params->enable) {
|
||||
input = params->input;
|
||||
|
||||
|
@ -539,7 +578,13 @@ static int goya_config_spmu(struct hl_device *hdev,
|
|||
|
||||
if (input->event_types_num < 3) {
|
||||
dev_err(hdev->dev,
|
||||
"not enough values for SPMU enable\n");
|
||||
"not enough event types values for SPMU enable\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (input->event_types_num > SPMU_MAX_COUNTERS) {
|
||||
dev_err(hdev->dev,
|
||||
"too many event types values for SPMU enable\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -547,7 +592,8 @@ static int goya_config_spmu(struct hl_device *hdev,
|
|||
WREG32(base_reg + 0xE04, 0x41013040);
|
||||
|
||||
for (i = 0 ; i < input->event_types_num ; i++)
|
||||
WREG32(base_reg + 0x400 + i * 4, input->event_types[i]);
|
||||
WREG32(base_reg + SPMU_EVENT_TYPES_OFFSET + i * 4,
|
||||
input->event_types[i]);
|
||||
|
||||
WREG32(base_reg + 0xE04, 0x41013041);
|
||||
WREG32(base_reg + 0xC00, 0x8000003F);
|
||||
|
@ -567,6 +613,12 @@ static int goya_config_spmu(struct hl_device *hdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (events_num > SPMU_MAX_COUNTERS) {
|
||||
dev_err(hdev->dev,
|
||||
"too many events values for SPMU disable\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
WREG32(base_reg + 0xE04, 0x41013040);
|
||||
|
||||
for (i = 0 ; i < events_num ; i++)
|
||||
|
|
Loading…
Reference in a new issue