Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu/gfx11: Implement cleaner shader support for GFX11 hardware

The patch modifies the gfx_v11_0_kiq_set_resources function to write
the cleaner shader's memory controller address to the ring buffer. It
also adds a new function, gfx_v11_0_ring_emit_cleaner_shader, which
emits the PACKET3_RUN_CLEANER_SHADER packet to the ring buffer.

This patch adds support for the PACKET3_RUN_CLEANER_SHADER packet in the
gfx_v11_0 module. This packet is used to emit the cleaner shader, which
is used to clear GPU memory before it's reused, helping to prevent data
leakage between different processes.

Finally, the patch updates the ring function structures to include the
new gfx_v11_0_ring_emit_cleaner_shader function. This allows the
cleaner shader to be emitted as part of the ring's operations.

Cc: Christian König <christian.koenig@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Srinivasan Shanmugam and committed by
Alex Deucher
8fc279e5 6e796cb4

+37 -4
+37 -4
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
··· 293 293 294 294 static void gfx11_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask) 295 295 { 296 + struct amdgpu_device *adev = kiq_ring->adev; 297 + u64 shader_mc_addr; 298 + 299 + /* Cleaner shader MC address */ 300 + shader_mc_addr = adev->gfx.cleaner_shader_gpu_addr >> 8; 301 + 296 302 amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_RESOURCES, 6)); 297 303 amdgpu_ring_write(kiq_ring, PACKET3_SET_RESOURCES_VMID_MASK(0) | 298 304 PACKET3_SET_RESOURCES_UNMAP_LATENTY(0xa) | /* unmap_latency: 0xa (~ 1s) */ 299 305 PACKET3_SET_RESOURCES_QUEUE_TYPE(0)); /* vmid_mask:0 queue_type:0 (KIQ) */ 300 306 amdgpu_ring_write(kiq_ring, lower_32_bits(queue_mask)); /* queue mask lo */ 301 307 amdgpu_ring_write(kiq_ring, upper_32_bits(queue_mask)); /* queue mask hi */ 302 - amdgpu_ring_write(kiq_ring, 0); /* gws mask lo */ 303 - amdgpu_ring_write(kiq_ring, 0); /* gws mask hi */ 308 + amdgpu_ring_write(kiq_ring, lower_32_bits(shader_mc_addr)); /* cleaner shader addr lo */ 309 + amdgpu_ring_write(kiq_ring, upper_32_bits(shader_mc_addr)); /* cleaner shader addr hi */ 304 310 amdgpu_ring_write(kiq_ring, 0); /* oac mask */ 305 311 amdgpu_ring_write(kiq_ring, 0); /* gds heap base:0, gds heap size:0 */ 306 312 } ··· 1581 1575 break; 1582 1576 } 1583 1577 1578 + switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { 1579 + default: 1580 + adev->gfx.enable_cleaner_shader = false; 1581 + } 1582 + 1584 1583 /* Enable CG flag in one VF mode for enabling RLC safe mode enter/exit */ 1585 1584 if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 0, 3) && 1586 1585 amdgpu_sriov_is_pp_one_vf(adev)) ··· 1711 1700 1712 1701 gfx_v11_0_alloc_ip_dump(adev); 1713 1702 1703 + r = amdgpu_gfx_sysfs_isolation_shader_init(adev); 1704 + if (r) 1705 + return r; 1706 + 1714 1707 return 0; 1715 1708 } 1716 1709 ··· 1764 1749 amdgpu_gfx_kiq_fini(adev, 0); 1765 1750 } 1766 1751 1752 + amdgpu_gfx_cleaner_shader_sw_fini(adev); 1753 + 1767 1754 gfx_v11_0_pfp_fini(adev); 1768 1755 gfx_v11_0_me_fini(adev); 1769 1756 gfx_v11_0_rlc_fini(adev); ··· 1775 1758 gfx_v11_0_rlc_autoload_buffer_fini(adev); 1776 1759 1777 1760 gfx_v11_0_free_microcode(adev); 1761 + 1762 + amdgpu_gfx_sysfs_isolation_shader_fini(adev); 1778 1763 1779 1764 kfree(adev->gfx.ip_dump_core); 1780 1765 kfree(adev->gfx.ip_dump_compute_queues); ··· 4594 4575 int r; 4595 4576 struct amdgpu_device *adev = ip_block->adev; 4596 4577 4578 + amdgpu_gfx_cleaner_shader_init(adev, adev->gfx.cleaner_shader_size, 4579 + adev->gfx.cleaner_shader_ptr); 4580 + 4597 4581 if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) { 4598 4582 if (adev->gfx.imu.funcs) { 4599 4583 /* RLC autoload sequence 1: Program rlc ram */ ··· 6794 6772 amdgpu_gfx_off_ctrl(adev, true); 6795 6773 } 6796 6774 6775 + static void gfx_v11_0_ring_emit_cleaner_shader(struct amdgpu_ring *ring) 6776 + { 6777 + /* Emit the cleaner shader */ 6778 + amdgpu_ring_write(ring, PACKET3(PACKET3_RUN_CLEANER_SHADER, 0)); 6779 + amdgpu_ring_write(ring, 0); /* RESERVED field, programmed to zero */ 6780 + } 6781 + 6797 6782 static const struct amd_ip_funcs gfx_v11_0_ip_funcs = { 6798 6783 .name = "gfx_v11_0", 6799 6784 .early_init = gfx_v11_0_early_init, ··· 6850 6821 5 + /* HDP_INVL */ 6851 6822 22 + /* SET_Q_PREEMPTION_MODE */ 6852 6823 8 + 8 + /* FENCE x2 */ 6853 - 8, /* gfx_v11_0_emit_mem_sync */ 6824 + 8 + /* gfx_v11_0_emit_mem_sync */ 6825 + 2, /* gfx_v11_0_ring_emit_cleaner_shader */ 6854 6826 .emit_ib_size = 4, /* gfx_v11_0_ring_emit_ib_gfx */ 6855 6827 .emit_ib = gfx_v11_0_ring_emit_ib_gfx, 6856 6828 .emit_fence = gfx_v11_0_ring_emit_fence, ··· 6874 6844 .soft_recovery = gfx_v11_0_ring_soft_recovery, 6875 6845 .emit_mem_sync = gfx_v11_0_emit_mem_sync, 6876 6846 .reset = gfx_v11_0_reset_kgq, 6847 + .emit_cleaner_shader = gfx_v11_0_ring_emit_cleaner_shader, 6877 6848 }; 6878 6849 6879 6850 static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_compute = { ··· 6895 6864 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + 6896 6865 2 + /* gfx_v11_0_ring_emit_vm_flush */ 6897 6866 8 + 8 + 8 + /* gfx_v11_0_ring_emit_fence x3 for user fence, vm fence */ 6898 - 8, /* gfx_v11_0_emit_mem_sync */ 6867 + 8 + /* gfx_v11_0_emit_mem_sync */ 6868 + 2, /* gfx_v11_0_ring_emit_cleaner_shader */ 6899 6869 .emit_ib_size = 7, /* gfx_v11_0_ring_emit_ib_compute */ 6900 6870 .emit_ib = gfx_v11_0_ring_emit_ib_compute, 6901 6871 .emit_fence = gfx_v11_0_ring_emit_fence, ··· 6914 6882 .soft_recovery = gfx_v11_0_ring_soft_recovery, 6915 6883 .emit_mem_sync = gfx_v11_0_emit_mem_sync, 6916 6884 .reset = gfx_v11_0_reset_kcq, 6885 + .emit_cleaner_shader = gfx_v11_0_ring_emit_cleaner_shader, 6917 6886 }; 6918 6887 6919 6888 static const struct amdgpu_ring_funcs gfx_v11_0_ring_funcs_kiq = {