From ede6b6bc43c68ef030f88235e91e85939b8bdb49 Mon Sep 17 00:00:00 2001 From: Chen Li Date: Fri, 25 Dec 2020 11:54:57 +0800 Subject: drm/radeon: use writel to avoid gcc optimization v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using e8860(gcn1) on arm64, the kernel crashed on drm/radeon: [ 11.240414] pc : __memset+0x4c/0x188 [ 11.244101] lr : radeon_uvd_get_create_msg+0x114/0x1d0 [radeon] [ 11.249995] sp : ffff00000d7eb700 [ 11.253295] x29: ffff00000d7eb700 x28: ffff8001f632a868 [ 11.258585] x27: 0000000000040000 x26: ffff00000de00000 [ 11.263875] x25: 0000000000000125 x24: 0000000000000001 [ 11.269168] x23: 0000000000000000 x22: 0000000000000005 [ 11.274459] x21: ffff00000df24000 x20: ffff8001f74b4000 [ 11.279753] x19: 0000000000124000 x18: 0000000000000020 [ 11.285043] x17: 0000000000000000 x16: 0000000000000000 [ 11.290336] x15: ffff000009309000 x14: ffffffffffffffff [ 11.290340] x13: ffff0000094b6f88 x12: ffff0000094b6bd2 [ 11.290343] x11: ffff00000d7eb700 x10: ffff00000d7eb700 [ 11.306246] x9 : ffff00000d7eb700 x8 : ffff00000df2402c [ 11.306254] x7 : 0000000000000000 x6 : ffff0000094b626a [ 11.306257] x5 : 0000000000000000 x4 : 0000000000000004 [ 11.306262] x3 : ffffffffffffffff x2 : 0000000000000fd4 [ 11.306265] x1 : 0000000000000000 x0 : ffff00000df2402c [ 11.306272] Call trace: [ 11.306316] __memset+0x4c/0x188 [ 11.306638] uvd_v1_0_ib_test+0x70/0x1c0 [radeon] [ 11.306758] radeon_ib_ring_tests+0x54/0xe0 [radeon] ... Obviously, the __memset call is generated by gcc(8.3.1). It optimizes this for loop into memset. But this may break on some platforms which cannot map device memory correctly. So, just invoke `writel` to handle this. v3 (chk): minor cleanups in code and commit message Signed-off-by: Chen Li Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_uvd.c | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers/gpu/drm/radeon/radeon_uvd.c') diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 39c1c339be7b..dfa9fdbe98da 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -781,7 +781,7 @@ int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring, uint64_t offs = radeon_bo_size(rdev->uvd.vcpu_bo) - RADEON_GPU_PAGE_SIZE; - uint32_t *msg = rdev->uvd.cpu_addr + offs; + uint32_t __iomem *msg = (void __iomem *)(rdev->uvd.cpu_addr + offs); uint64_t addr = rdev->uvd.gpu_addr + offs; int r, i; @@ -791,19 +791,19 @@ int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring, return r; /* stitch together an UVD create msg */ - msg[0] = cpu_to_le32(0x00000de4); - msg[1] = cpu_to_le32(0x00000000); - msg[2] = cpu_to_le32(handle); - msg[3] = cpu_to_le32(0x00000000); - msg[4] = cpu_to_le32(0x00000000); - msg[5] = cpu_to_le32(0x00000000); - msg[6] = cpu_to_le32(0x00000000); - msg[7] = cpu_to_le32(0x00000780); - msg[8] = cpu_to_le32(0x00000440); - msg[9] = cpu_to_le32(0x00000000); - msg[10] = cpu_to_le32(0x01b37000); + writel(cpu_to_le32(0x00000de4), &msg[0]); + writel(0x0, (void __iomem *)&msg[1]); + writel(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(0x0, &msg[9]); + writel(cpu_to_le32(0x01b37000), &msg[10]); for (i = 11; i < 1024; ++i) - msg[i] = cpu_to_le32(0x0); + writel(0x0, &msg[i]); r = radeon_uvd_send_msg(rdev, ring, addr, fence); radeon_bo_unreserve(rdev->uvd.vcpu_bo); @@ -817,7 +817,7 @@ int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring, uint64_t offs = radeon_bo_size(rdev->uvd.vcpu_bo) - RADEON_GPU_PAGE_SIZE; - uint32_t *msg = rdev->uvd.cpu_addr + offs; + uint32_t __iomem *msg = (void __iomem *)(rdev->uvd.cpu_addr + offs); uint64_t addr = rdev->uvd.gpu_addr + offs; int r, i; @@ -827,12 +827,12 @@ int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring, return r; /* stitch together an UVD destroy msg */ - msg[0] = cpu_to_le32(0x00000de4); - msg[1] = cpu_to_le32(0x00000002); - msg[2] = cpu_to_le32(handle); - msg[3] = cpu_to_le32(0x00000000); + writel(cpu_to_le32(0x00000de4), &msg[0]); + writel(cpu_to_le32(0x00000002), &msg[1]); + writel(cpu_to_le32(handle), &msg[2]); + writel(0x0, &msg[3]); for (i = 4; i < 1024; ++i) - msg[i] = cpu_to_le32(0x0); + writel(0x0, &msg[i]); r = radeon_uvd_send_msg(rdev, ring, addr, fence); radeon_bo_unreserve(rdev->uvd.vcpu_bo); -- cgit v1.2.3-59-g8ed1b