On Thu, Jun 3, 2021 at 3:35 AM Chen Li chenli@uniontech.com wrote:
I met a gpu addr bug recently and the kernel log tells me the pc is memcpy/memset and link register is radeon_uvd_resume.
As we know, in some architectures, optimized memcpy/memset may not work well on device memory. Trival memcpy_toio/memset_io can fix this problem.
BTW, amdgpu has already done it in: commit ba0b2275a678 ("drm/amdgpu: use memcpy_to/fromio for UVD fw upload"), that's why it has no this issue on the same gpu and platform.
Also fix some coding issues reported from sparse.
Can you split the sparse fixes and the mmio fixes into two patches?
Thanks,
Alex
Signed-off-by: Chen Li chenli@uniontech.com
drivers/gpu/drm/radeon/radeon_uvd.c | 30 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index dfa9fdbe98da..0d6a5cfa2abf 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -152,9 +152,11 @@ int radeon_uvd_init(struct radeon_device *rdev)
rdev->uvd.fw_header_present = true;
family_id = le32_to_cpu(hdr->ucode_version) & 0xff;
version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff;
version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
family_id = (__force u32)(hdr->ucode_version) & 0xff;
version_major = (le32_to_cpu((__force __le32)(hdr->ucode_version))
>> 24) & 0xff;
version_minor = (le32_to_cpu((__force __le32)(hdr->ucode_version))
>> 8) & 0xff; DRM_INFO("Found UVD firmware Version: %u.%u Family ID: %u\n", version_major, version_minor, family_id);
@@ -286,7 +288,9 @@ int radeon_uvd_resume(struct radeon_device *rdev) if (rdev->uvd.vcpu_bo == NULL) return -EINVAL;
memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size);
memcpy_toio((void __iomem *)rdev->uvd.cpu_addr,
rdev->uvd_fw->data,
le32_to_cpu((__force __le32)rdev->uvd_fw->size)); size = radeon_bo_size(rdev->uvd.vcpu_bo); size -= rdev->uvd_fw->size;
@@ -294,7 +298,7 @@ int radeon_uvd_resume(struct radeon_device *rdev) ptr = rdev->uvd.cpu_addr; ptr += rdev->uvd_fw->size;
memset(ptr, 0, size);
memset_io((void __iomem *)ptr, 0, size); return 0;
} @@ -791,17 +795,17 @@ int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring, return r;
/* stitch together an UVD create msg */
writel(cpu_to_le32(0x00000de4), &msg[0]);
writel((__force u32)cpu_to_le32(0x00000de4), &msg[0]); writel(0x0, (void __iomem *)&msg[1]);
writel(cpu_to_le32(handle), &msg[2]);
writel((__force u32)cpu_to_le32(handle), &msg[2]); writel(0x0, &msg[3]); writel(0x0, &msg[4]); writel(0x0, &msg[5]); writel(0x0, &msg[6]);
writel(cpu_to_le32(0x00000780), &msg[7]);
writel(cpu_to_le32(0x00000440), &msg[8]);
writel((__force u32)cpu_to_le32(0x00000780), &msg[7]);
writel((__force u32)cpu_to_le32(0x00000440), &msg[8]); writel(0x0, &msg[9]);
writel(cpu_to_le32(0x01b37000), &msg[10]);
writel((__force u32)cpu_to_le32(0x01b37000), &msg[10]); for (i = 11; i < 1024; ++i) writel(0x0, &msg[i]);
@@ -827,9 +831,9 @@ int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring, return r;
/* stitch together an UVD destroy msg */
writel(cpu_to_le32(0x00000de4), &msg[0]);
writel(cpu_to_le32(0x00000002), &msg[1]);
writel(cpu_to_le32(handle), &msg[2]);
writel((__force u32)cpu_to_le32(0x00000de4), &msg[0]);
writel((__force u32)cpu_to_le32(0x00000002), &msg[1]);
writel((__force u32)cpu_to_le32(handle), &msg[2]); writel(0x0, &msg[3]); for (i = 4; i < 1024; ++i) writel(0x0, &msg[i]);
-- 2.31.1