Skip to content

Commit 56e2877

Browse files
committed
Merge tag 'misc-habanalabs-fixes-2020-06-24' of git://people.freedesktop.org/~gabbayo/linux into char-misc-linus
Oded writes: This tag contains the following fixes for kernel 5.8-rc2: - close security hole in GAUDI command buffer parsing by blocking an instruction that might allow user to run command buffer that wasn't parsed on a secured engine. - Fix bug in GAUDI MMU cache invalidation code. - Rename a function to resolve conflict with a static inline function in arch/m68k/include/asm/mcfmmu.h - Increase watchdog timeout of GAUDI QMAN arbitration H/W to prevent false reports on timeouts - Fix bug of dereferencing NULL pointer when an error occurs during command submission - Increase H/W timer for checking if PDMA engine is IDLE in GAUDI. * tag 'misc-habanalabs-fixes-2020-06-24' of git://people.freedesktop.org/~gabbayo/linux: habanalabs: increase h/w timer when checking idle habanalabs: Correct handling when failing to enqueue CB habanalabs: increase GAUDI QMAN ARB WDT timeout habanalabs: rename mmu_write() to mmu_asid_va_write() habanalabs: use PI in MMU cache invalidation habanalabs: block scalar load_and_exe on external queue
2 parents 8c289ea + ce04326 commit 56e2877

File tree

5 files changed

+56
-4
lines changed

5 files changed

+56
-4
lines changed

drivers/misc/habanalabs/command_submission.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ static void hl_fence_release(struct dma_fence *fence)
6262
container_of(fence, struct hl_cs_compl, base_fence);
6363
struct hl_device *hdev = hl_cs_cmpl->hdev;
6464

65+
/* EBUSY means the CS was never submitted and hence we don't have
66+
* an attached hw_sob object that we should handle here
67+
*/
68+
if (fence->error == -EBUSY)
69+
goto free;
70+
6571
if ((hl_cs_cmpl->type == CS_TYPE_SIGNAL) ||
6672
(hl_cs_cmpl->type == CS_TYPE_WAIT)) {
6773

@@ -92,6 +98,7 @@ static void hl_fence_release(struct dma_fence *fence)
9298
kref_put(&hl_cs_cmpl->hw_sob->kref, hl_sob_reset);
9399
}
94100

101+
free:
95102
kfree_rcu(hl_cs_cmpl, base_fence.rcu);
96103
}
97104

@@ -328,10 +335,16 @@ static void cs_do_release(struct kref *ref)
328335

329336
hl_ctx_put(cs->ctx);
330337

338+
/* We need to mark an error for not submitted because in that case
339+
* the dma fence release flow is different. Mainly, we don't need
340+
* to handle hw_sob for signal/wait
341+
*/
331342
if (cs->timedout)
332343
dma_fence_set_error(cs->fence, -ETIMEDOUT);
333344
else if (cs->aborted)
334345
dma_fence_set_error(cs->fence, -EIO);
346+
else if (!cs->submitted)
347+
dma_fence_set_error(cs->fence, -EBUSY);
335348

336349
dma_fence_signal(cs->fence);
337350
dma_fence_put(cs->fence);

drivers/misc/habanalabs/debugfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ static int mmu_show(struct seq_file *s, void *data)
480480
return 0;
481481
}
482482

483-
static ssize_t mmu_write(struct file *file, const char __user *buf,
483+
static ssize_t mmu_asid_va_write(struct file *file, const char __user *buf,
484484
size_t count, loff_t *f_pos)
485485
{
486486
struct seq_file *s = file->private_data;
@@ -1125,7 +1125,7 @@ static const struct hl_info_list hl_debugfs_list[] = {
11251125
{"command_submission_jobs", command_submission_jobs_show, NULL},
11261126
{"userptr", userptr_show, NULL},
11271127
{"vm", vm_show, NULL},
1128-
{"mmu", mmu_show, mmu_write},
1128+
{"mmu", mmu_show, mmu_asid_va_write},
11291129
{"engines", engines_show, NULL}
11301130
};
11311131

drivers/misc/habanalabs/gaudi/gaudi.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696

9797
#define GAUDI_NUM_OF_QM_ARB_ERR_CAUSE 3
9898

99-
#define GAUDI_ARB_WDT_TIMEOUT 0x400000
99+
#define GAUDI_ARB_WDT_TIMEOUT 0x1000000
100100

101101
static const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = {
102102
"gaudi cq 0_0", "gaudi cq 0_1", "gaudi cq 0_2", "gaudi cq 0_3",
@@ -1893,6 +1893,8 @@ static void gaudi_init_pci_dma_qman(struct hl_device *hdev, int dma_id,
18931893
WREG32(mmDMA0_QM_CP_MSG_BASE3_ADDR_LO_0 + q_off, so_base_ws_lo);
18941894
WREG32(mmDMA0_QM_CP_MSG_BASE3_ADDR_HI_0 + q_off, so_base_ws_hi);
18951895

1896+
WREG32(mmDMA0_QM_CP_BARRIER_CFG_0 + q_off, 0x100);
1897+
18961898
/* The following configuration is needed only once per QMAN */
18971899
if (qman_id == 0) {
18981900
/* Configure RAZWI IRQ */
@@ -2725,6 +2727,12 @@ static int gaudi_mmu_init(struct hl_device *hdev)
27252727
WREG32(mmSTLB_HOP_CONFIGURATION,
27262728
hdev->mmu_huge_page_opt ? 0x30440 : 0x40440);
27272729

2730+
/*
2731+
* The H/W expects the first PI after init to be 1. After wraparound
2732+
* we'll write 0.
2733+
*/
2734+
gaudi->mmu_cache_inv_pi = 1;
2735+
27282736
gaudi->hw_cap_initialized |= HW_CAP_MMU;
27292737

27302738
return 0;
@@ -3790,6 +3798,25 @@ static int gaudi_validate_dma_pkt_no_mmu(struct hl_device *hdev,
37903798
src_in_host);
37913799
}
37923800

3801+
static int gaudi_validate_load_and_exe_pkt(struct hl_device *hdev,
3802+
struct hl_cs_parser *parser,
3803+
struct packet_load_and_exe *user_pkt)
3804+
{
3805+
u32 cfg;
3806+
3807+
cfg = le32_to_cpu(user_pkt->cfg);
3808+
3809+
if (cfg & GAUDI_PKT_LOAD_AND_EXE_CFG_DST_MASK) {
3810+
dev_err(hdev->dev,
3811+
"User not allowed to use Load and Execute\n");
3812+
return -EPERM;
3813+
}
3814+
3815+
parser->patched_cb_size += sizeof(struct packet_load_and_exe);
3816+
3817+
return 0;
3818+
}
3819+
37933820
static int gaudi_validate_cb(struct hl_device *hdev,
37943821
struct hl_cs_parser *parser, bool is_mmu)
37953822
{
@@ -3838,6 +3865,11 @@ static int gaudi_validate_cb(struct hl_device *hdev,
38383865
rc = -EPERM;
38393866
break;
38403867

3868+
case PACKET_LOAD_AND_EXE:
3869+
rc = gaudi_validate_load_and_exe_pkt(hdev, parser,
3870+
(struct packet_load_and_exe *) user_pkt);
3871+
break;
3872+
38413873
case PACKET_LIN_DMA:
38423874
parser->contains_dma_pkt = true;
38433875
if (is_mmu)
@@ -3855,7 +3887,6 @@ static int gaudi_validate_cb(struct hl_device *hdev,
38553887
case PACKET_FENCE:
38563888
case PACKET_NOP:
38573889
case PACKET_ARB_POINT:
3858-
case PACKET_LOAD_AND_EXE:
38593890
parser->patched_cb_size += pkt_size;
38603891
break;
38613892

@@ -5994,6 +6025,8 @@ static int gaudi_mmu_invalidate_cache(struct hl_device *hdev, bool is_hard,
59946025
mutex_lock(&hdev->mmu_cache_lock);
59956026

59966027
/* L0 & L1 invalidation */
6028+
WREG32(mmSTLB_INV_PS, 3);
6029+
WREG32(mmSTLB_CACHE_INV, gaudi->mmu_cache_inv_pi++);
59976030
WREG32(mmSTLB_INV_PS, 2);
59986031

59996032
rc = hl_poll_timeout(

drivers/misc/habanalabs/gaudi/gaudiP.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ struct gaudi_internal_qman_info {
229229
* @multi_msi_mode: whether we are working in multi MSI single MSI mode.
230230
* Multi MSI is possible only with IOMMU enabled.
231231
* @ext_queue_idx: helper index for external queues initialization.
232+
* @mmu_cache_inv_pi: PI for MMU cache invalidation flow. The H/W expects an
233+
* 8-bit value so use u8.
232234
*/
233235
struct gaudi_device {
234236
int (*armcp_info_get)(struct hl_device *hdev);
@@ -248,6 +250,7 @@ struct gaudi_device {
248250
u32 hw_cap_initialized;
249251
u8 multi_msi_mode;
250252
u8 ext_queue_idx;
253+
u8 mmu_cache_inv_pi;
251254
};
252255

253256
void gaudi_init_security(struct hl_device *hdev);

drivers/misc/habanalabs/include/gaudi/gaudi_packets.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ struct packet_wait {
197197
__le32 ctl;
198198
};
199199

200+
#define GAUDI_PKT_LOAD_AND_EXE_CFG_DST_SHIFT 0
201+
#define GAUDI_PKT_LOAD_AND_EXE_CFG_DST_MASK 0x00000001
202+
200203
struct packet_load_and_exe {
201204
__le32 cfg;
202205
__le32 ctl;

0 commit comments

Comments
 (0)