summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c
diff options
context:
space:
mode:
authorThomas Fleury <tfleury@nvidia.com>2016-04-28 12:54:13 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-05-21 14:33:46 -0400
commitf71ac07972c5818cca9a652ca649b61d6572dc9b (patch)
tree869c107809a41c57d468f5ca5b03a6a5c924edc3 /drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c
parent989f7f70c3b7a77467cb216932490e48dc03c64c (diff)
gpu: nvgpu: fix out-of-bound idx for FECS trace
Fix a case where user space could potentially see an out of bounds write index for user facing context switch buffer. Check if write_idx is valid, and disable FECS tracing if corrupted. Bug 1757714 Change-Id: I5710c40121fa6935dba3918adf5290488e31e9f6 Signed-off-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-on: http://git-master/r/1139305 (cherry picked from commit 47b65e5b59037932777be4911fe040e6acbc5651) Reviewed-on: http://git-master/r/1150048 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Richard Zhao <rizhao@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c
index 19ba6dde..028763a2 100644
--- a/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c
@@ -43,6 +43,7 @@ struct gk20a_ctxsw_dev {
43 bool write_enabled; 43 bool write_enabled;
44 wait_queue_head_t readout_wq; 44 wait_queue_head_t readout_wq;
45 size_t size; 45 size_t size;
46 u32 num_ents;
46 47
47 atomic_t vma_ref; 48 atomic_t vma_ref;
48 49
@@ -165,6 +166,7 @@ static int gk20a_ctxsw_dev_alloc_buffer(struct gk20a_ctxsw_dev *dev,
165 dev->hdr = buf; 166 dev->hdr = buf;
166 dev->ents = (struct nvgpu_ctxsw_trace_entry *) (dev->hdr + 1); 167 dev->ents = (struct nvgpu_ctxsw_trace_entry *) (dev->hdr + 1);
167 dev->size = size; 168 dev->size = size;
169 dev->num_ents = dev->hdr->num_ents;
168 170
169 gk20a_dbg(gpu_dbg_ctxsw, "size=%zu hdr=%p ents=%p num_ents=%d", 171 gk20a_dbg(gpu_dbg_ctxsw, "size=%zu hdr=%p ents=%p num_ents=%d",
170 dev->size, dev->hdr, dev->ents, dev->hdr->num_ents); 172 dev->size, dev->hdr, dev->ents, dev->hdr->num_ents);
@@ -553,6 +555,7 @@ int gk20a_ctxsw_trace_write(struct gk20a *g,
553 struct gk20a_ctxsw_dev *dev; 555 struct gk20a_ctxsw_dev *dev;
554 int ret = 0; 556 int ret = 0;
555 const char *reason; 557 const char *reason;
558 u32 write_idx;
556 559
557 if (unlikely(entry->vmid >= GK20A_CTXSW_TRACE_NUM_DEVS)) 560 if (unlikely(entry->vmid >= GK20A_CTXSW_TRACE_NUM_DEVS))
558 return -ENODEV; 561 return -ENODEV;
@@ -571,6 +574,16 @@ int gk20a_ctxsw_trace_write(struct gk20a *g,
571 goto done; 574 goto done;
572 } 575 }
573 576
577 write_idx = hdr->write_idx;
578 if (write_idx >= dev->num_ents) {
579 gk20a_err(dev_from_gk20a(dev->g),
580 "write_idx=%u out of range [0..%u]",
581 write_idx, dev->num_ents);
582 ret = -ENOSPC;
583 reason = "write_idx out of range";
584 goto disable;
585 }
586
574 entry->seqno = hdr->write_seqno++; 587 entry->seqno = hdr->write_seqno++;
575 588
576 if (!dev->write_enabled) { 589 if (!dev->write_enabled) {
@@ -595,20 +608,24 @@ int gk20a_ctxsw_trace_write(struct gk20a *g,
595 entry->seqno, entry->context_id, entry->pid, 608 entry->seqno, entry->context_id, entry->pid,
596 entry->tag, entry->timestamp); 609 entry->tag, entry->timestamp);
597 610
598 dev->ents[hdr->write_idx] = *entry; 611 dev->ents[write_idx] = *entry;
599 612
600 /* ensure record is written before updating write index */ 613 /* ensure record is written before updating write index */
601 smp_wmb(); 614 smp_wmb();
602 615
603 hdr->write_idx++; 616 write_idx++;
604 if (unlikely(hdr->write_idx >= hdr->num_ents)) 617 if (unlikely(write_idx >= hdr->num_ents))
605 hdr->write_idx = 0; 618 write_idx = 0;
619 hdr->write_idx = write_idx;
606 gk20a_dbg(gpu_dbg_ctxsw, "added: read=%d write=%d len=%d", 620 gk20a_dbg(gpu_dbg_ctxsw, "added: read=%d write=%d len=%d",
607 hdr->read_idx, hdr->write_idx, ring_len(hdr)); 621 hdr->read_idx, hdr->write_idx, ring_len(hdr));
608 622
609 mutex_unlock(&dev->write_lock); 623 mutex_unlock(&dev->write_lock);
610 return ret; 624 return ret;
611 625
626disable:
627 g->ops.fecs_trace.disable(g);
628
612drop: 629drop:
613 hdr->drop_count++; 630 hdr->drop_count++;
614 631