AMD General Thanks for the fix, the patch is:
Reviewed-by: Tao Zhou <[email protected]> > -----Original Message----- > From: amd-gfx <[email protected]> On Behalf Of Xiang > Liu > Sent: Thursday, May 7, 2026 10:00 PM > To: [email protected] > Cc: Zhang, Hawking <[email protected]>; Zhou1, Tao > <[email protected]>; Liu, Xiang(Dean) <[email protected]> > Subject: [PATCH] drm/amd/ras: Fix CPER ring debugfs read overflow > > The legacy CPER debugfs reader can reach the payload path without a valid > pointer snapshot. The remaining user byte count is also treated as the ring > occupancy in dwords, so reads past the header can copy more than > requested. > > Take the CPER lock before sampling pointers. Resample rptr/wptr for payload > reads, bound the payload copy by available dwords and the remaining user > size, and advance the file position for each dword copied. > > Signed-off-by: Xiang Liu <[email protected]> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 29 +++++++++++++++++----- > -- > 1 file changed, 21 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c > index 5de786551aaa..e47a155f4bb1 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c > @@ -552,8 +552,9 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, > char __user *buf, > size_t size, loff_t *pos) > { > struct amdgpu_ring *ring = file_inode(f)->i_private; > - uint32_t value, result, early[3]; > + u32 value, result, early[3] = { 0 }; > uint64_t p; > + u32 avail_dw, start_dw, read_dw; > loff_t i; > int r; > > @@ -565,10 +566,10 @@ static ssize_t amdgpu_debugfs_ring_read(struct file > *f, char __user *buf, > > result = 0; > > - if (*pos < 12) { > - if (ring->funcs->type == AMDGPU_RING_TYPE_CPER) > - mutex_lock(&ring->adev->cper.ring_lock); > + if (ring->funcs->type == AMDGPU_RING_TYPE_CPER) > + mutex_lock(&ring->adev->cper.ring_lock); > > + if (*pos < 12) { > early[0] = amdgpu_ring_get_rptr(ring) & ring->buf_mask; > early[1] = amdgpu_ring_get_wptr(ring) & ring->buf_mask; > early[2] = ring->wptr & ring->buf_mask; @@ -600,13 +601,24 > @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf, > *pos += 4; > } > } else { > + early[0] = amdgpu_ring_get_rptr(ring) & ring->buf_mask; > + early[1] = amdgpu_ring_get_wptr(ring) & ring->buf_mask; > + > p = early[0]; > if (early[0] <= early[1]) > - size = (early[1] - early[0]); > + avail_dw = early[1] - early[0]; > else > - size = ring->ring_size - (early[0] - early[1]); > + avail_dw = ring->buf_mask + 1 - (early[0] - early[1]); > > - while (size) { > + start_dw = (*pos > 12) ? ((*pos - 12) >> 2) : 0; > + if (start_dw >= avail_dw) > + goto out; > + > + p = (p + start_dw) & ring->ptr_mask; > + avail_dw -= start_dw; > + read_dw = min_t(u32, avail_dw, size >> 2); > + > + while (read_dw) { > if (p == early[1]) > goto out; > > @@ -619,9 +631,10 @@ static ssize_t amdgpu_debugfs_ring_read(struct file > *f, char __user *buf, > > buf += 4; > result += 4; > - size--; > + read_dw--; > p++; > p &= ring->ptr_mask; > + *pos += 4; > } > } > > -- > 2.54.0
