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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-fixes-2026-05-02' of https://gitlab.freedesktop.org/drm/kernel

Pull drm fixes from Dave Airlie:
"Fixes for rc2, the usual amdgpu/xe double header, I think xe had a
couple of weeks combined due to some maintainer access issues,
otherwise there's just a few misc fixes and documentation fixups.

core and helpers:
- calculate framebuffer geometry with format helpers
- fix docs

amdgpu:
- GFX12 fix for CONFIG_DRM_DEBUG_MM configs
- Fix DC analog support
- Userq fixes
- GART placement fix
- Aldebaran SMU fixes
- AMDGPU_INFO_READ_MMR_REG fix
- UVD 3.1 fix
- GC 6 TCC fix
- Fix root reservation in amdgpu_vm_handle_fault()
- RAS fix
- Module reload fix for APUs
- Fix build for CONFIG_DRM_FBDEV_EMULATION=n
- IGT DWB regression fix
- GC 11.5.4 fix
- VCN user fence fixes
- JPEG user fence fixes
- SMU 13.0.6 fix
- VCN 3/4 IB parser fixes
- NV3x+ dGPU vblank fix
- DCE6/8 fixes for LVDS/eDP panels without an EDID

amdkfd:
- Fix for when CONFIG_HSA_AMD is not set
- SVM fixes

xe:
- uapi: Add missing pad and extensions check
- uapi: Reject unsafe PAT indices for CPU cached memory
- Drop registration of guc_submit_wedged_fini from xe_guc_submit_wedge
- Xe3p tuning and workaround fixes
- USE drm mm instead of drm SA for CCS read/write
- Fix leaks and null derefs
- Fix Wa_18022495364

appletbdrm:
- allocate protocol buffers with kvzalloc()

dma-buf:
- fix docs

imagination:
- avoid segfault in debugfs

ofdrm:
- put PCI device reference on errors

udl:
- increase USB timeout"

* tag 'drm-fixes-2026-05-02' of https://gitlab.freedesktop.org/drm/kernel: (77 commits)
drm/xe/uapi: Reject coh_none PAT index for CPU_ADDR_MIRROR
drm/xe/uapi: Reject coh_none PAT index for CPU cached memory in madvise
drm/xe/xelp: Fix Wa_18022495364
drm/xe/gsc: Fix BO leak on error in query_compatibility_version()
drm/xe/eustall: Fix drm_dev_put called before stream disable in close
drm/xe: Fix error cleanup in xe_exec_queue_create_ioctl()
drm/xe: Fix dma-buf attachment leak in xe_gem_prime_import()
drm/xe: Fix bo leak in xe_dma_buf_init_obj() on allocation failure
drm/xe/bo: Fix bo leak on GGTT flag validation in xe_bo_init_locked()
drm/xe/bo: Fix bo leak on unaligned size validation in xe_bo_init_locked()
drm/xe: Fix potential NULL deref in xe_exec_queue_tlb_inval_last_fence_put_unlocked
drm/xe/vf: Use drm mm instead of drm sa for CCS read/write
drm/xe: Add memory pool with shadow support
drm/xe/debugfs: Correct printing of register whitelist ranges
drm/xe: Mark ROW_CHICKEN5 as a masked register
drm/xe/tuning: Use proper register offset for GAMSTLB_CTRL
drm/xe/xe3p_lpg: Add missing indirect ring state feature flag
drm/xe: Drop redundant rtp entries for Wa_14019988906 & Wa_14019877138
drm/xe/vm: Add missing pad and extensions check
drm/xe: Drop registration of guc_submit_wedged_fini from xe_guc_submit_wedge()
...

+1085 -269
+1
.mailmap
··· 19 19 Ahmad Masri <quic_amasri@quicinc.com> <amasri@codeaurora.org> 20 20 Adam Oldham <oldhamca@gmail.com> 21 21 Adam Radford <aradford@gmail.com> 22 + Aditya Garg <gargaditya08@proton.me> <gargaditya08@live.com> 22 23 Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com> 23 24 Adrian Bunk <bunk@stusta.de> 24 25 Ajay Kaher <ajay.kaher@broadcom.com> <akaher@vmware.com>
+1 -1
MAINTAINERS
··· 7873 7873 7874 7874 DRM DRIVER FOR APPLE TOUCH BARS 7875 7875 M: Aun-Ali Zaidi <admin@kodeit.net> 7876 - M: Aditya Garg <gargaditya08@live.com> 7876 + M: Aditya Garg <gargaditya08@proton.me> 7877 7877 L: dri-devel@lists.freedesktop.org 7878 7878 S: Maintained 7879 7879 T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
+5 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 2839 2839 * that checks whether the PSP is running. A solution for those issues 2840 2840 * in the APU is to trigger a GPU reset, but this should be done during 2841 2841 * the unload phase to avoid adding boot latency and screen flicker. 2842 + * GFX V11 has GC block as default off IP. Every time AMDGPU driver sends 2843 + * a request to PMFW to unload MP1, PMFW will put GC in reset and power down 2844 + * the voltage. Hence, skipping reset for APUs with GFX V11 or later. 2842 2845 */ 2843 - if ((adev->flags & AMD_IS_APU) && !adev->gmc.is_app_apu) { 2846 + if ((adev->flags & AMD_IS_APU) && !adev->gmc.is_app_apu && 2847 + amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(11, 0, 0)) { 2844 2848 r = amdgpu_asic_reset(adev); 2845 2849 if (r) 2846 2850 dev_err(adev->dev, "asic reset on %s failed\n", __func__);
+1 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
··· 3090 3090 case IP_VERSION(11, 5, 1): 3091 3091 case IP_VERSION(11, 5, 2): 3092 3092 case IP_VERSION(11, 5, 3): 3093 - adev->family = AMDGPU_FAMILY_GC_11_5_0; 3094 - break; 3095 3093 case IP_VERSION(11, 5, 4): 3096 - adev->family = AMDGPU_FAMILY_GC_11_5_4; 3094 + adev->family = AMDGPU_FAMILY_GC_11_5_0; 3097 3095 break; 3098 3096 case IP_VERSION(12, 0, 0): 3099 3097 case IP_VERSION(12, 0, 1):
+4 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 3158 3158 amdgpu_register_atpx_handler(); 3159 3159 amdgpu_acpi_detect(); 3160 3160 3161 - /* Ignore KFD init failures. Normal when CONFIG_HSA_AMD is not set. */ 3162 - amdgpu_amdkfd_init(); 3161 + /* Ignore KFD init failures when CONFIG_HSA_AMD is not set. */ 3162 + r = amdgpu_amdkfd_init(); 3163 + if (r && r != -ENOENT) 3164 + goto error_fence; 3163 3165 3164 3166 if (amdgpu_pp_feature_mask & PP_OVERDRIVE_MASK) { 3165 3167 add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
+4 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
··· 314 314 mc->gart_start = max_mc_address - mc->gart_size + 1; 315 315 break; 316 316 case AMDGPU_GART_PLACEMENT_LOW: 317 - mc->gart_start = 0; 317 + if (size_bf >= mc->gart_size) 318 + mc->gart_start = 0; 319 + else 320 + mc->gart_start = ALIGN(mc->fb_end, four_gb); 318 321 break; 319 322 case AMDGPU_GART_PLACEMENT_BEST_FIT: 320 323 default:
+24 -33
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
··· 873 873 ? -EFAULT : 0; 874 874 } 875 875 case AMDGPU_INFO_READ_MMR_REG: { 876 - int ret = 0; 877 - unsigned int n, alloc_size; 878 - uint32_t *regs; 879 876 unsigned int se_num = (info->read_mmr_reg.instance >> 880 877 AMDGPU_INFO_MMR_SE_INDEX_SHIFT) & 881 878 AMDGPU_INFO_MMR_SE_INDEX_MASK; 882 879 unsigned int sh_num = (info->read_mmr_reg.instance >> 883 880 AMDGPU_INFO_MMR_SH_INDEX_SHIFT) & 884 881 AMDGPU_INFO_MMR_SH_INDEX_MASK; 885 - 886 - if (!down_read_trylock(&adev->reset_domain->sem)) 887 - return -ENOENT; 882 + unsigned int alloc_size; 883 + uint32_t *regs; 884 + int ret; 888 885 889 886 /* set full masks if the userspace set all bits 890 887 * in the bitfields 891 888 */ 892 - if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) { 889 + if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) 893 890 se_num = 0xffffffff; 894 - } else if (se_num >= AMDGPU_GFX_MAX_SE) { 895 - ret = -EINVAL; 896 - goto out; 897 - } 891 + else if (se_num >= AMDGPU_GFX_MAX_SE) 892 + return -EINVAL; 898 893 899 - if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK) { 894 + if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK) 900 895 sh_num = 0xffffffff; 901 - } else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE) { 902 - ret = -EINVAL; 903 - goto out; 904 - } 896 + else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE) 897 + return -EINVAL; 905 898 906 - if (info->read_mmr_reg.count > 128) { 907 - ret = -EINVAL; 908 - goto out; 909 - } 899 + if (info->read_mmr_reg.count > 128) 900 + return -EINVAL; 910 901 911 - regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs), GFP_KERNEL); 912 - if (!regs) { 913 - ret = -ENOMEM; 914 - goto out; 915 - } 902 + regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs), 903 + GFP_KERNEL); 904 + if (!regs) 905 + return -ENOMEM; 916 906 907 + down_read(&adev->reset_domain->sem); 917 908 alloc_size = info->read_mmr_reg.count * sizeof(*regs); 918 - 919 909 amdgpu_gfx_off_ctrl(adev, false); 910 + ret = 0; 920 911 for (i = 0; i < info->read_mmr_reg.count; i++) { 921 912 if (amdgpu_asic_read_register(adev, se_num, sh_num, 922 913 info->read_mmr_reg.dword_offset + i, 923 914 &regs[i])) { 924 915 DRM_DEBUG_KMS("unallowed offset %#x\n", 925 916 info->read_mmr_reg.dword_offset + i); 926 - kfree(regs); 927 - amdgpu_gfx_off_ctrl(adev, true); 928 917 ret = -EFAULT; 929 - goto out; 918 + break; 930 919 } 931 920 } 932 921 amdgpu_gfx_off_ctrl(adev, true); 933 - n = copy_to_user(out, regs, min(size, alloc_size)); 934 - kfree(regs); 935 - ret = (n ? -EFAULT : 0); 936 - out: 937 922 up_read(&adev->reset_domain->sem); 923 + 924 + if (!ret) { 925 + ret = copy_to_user(out, regs, min(size, alloc_size)) 926 + ? -EFAULT : 0; 927 + } 928 + kfree(regs); 938 929 return ret; 939 930 } 940 931 case AMDGPU_INFO_DEV_INFO: {
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
··· 1950 1950 if (!control || amdgpu_bad_page_threshold == 0) 1951 1951 return; 1952 1952 1953 - if (control->ras_num_bad_pages >= ras->bad_page_cnt_threshold) { 1953 + if (control->ras_num_bad_pages > ras->bad_page_cnt_threshold) { 1954 1954 if (amdgpu_dpm_send_rma_reason(adev)) 1955 1955 dev_warn(adev->dev, "Unable to send out-of-band RMA CPER"); 1956 1956 else
+3
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 75 75 unsigned int type, 76 76 uint64_t size_in_page) 77 77 { 78 + if (!size_in_page) 79 + return 0; 80 + 78 81 return ttm_range_man_init(&adev->mman.bdev, type, 79 82 false, size_in_page); 80 83 }
+15 -7
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
··· 205 205 msecs_to_jiffies(timeout_ms)); 206 206 } 207 207 208 + void amdgpu_userq_process_fence_irq(struct amdgpu_device *adev, u32 doorbell) 209 + { 210 + struct xarray *xa = &adev->userq_doorbell_xa; 211 + struct amdgpu_usermode_queue *queue; 212 + unsigned long flags; 213 + 214 + xa_lock_irqsave(xa, flags); 215 + queue = xa_load(xa, doorbell); 216 + if (queue) 217 + amdgpu_userq_fence_driver_process(queue->fence_drv); 218 + xa_unlock_irqrestore(xa, flags); 219 + } 220 + 208 221 static void amdgpu_userq_init_hang_detect_work(struct amdgpu_usermode_queue *queue) 209 222 { 210 223 INIT_DELAYED_WORK(&queue->hang_detect_work, amdgpu_userq_hang_detect_work); ··· 656 643 #endif 657 644 amdgpu_userq_detect_and_reset_queues(uq_mgr); 658 645 r = amdgpu_userq_unmap_helper(queue); 659 - /*TODO: It requires a reset for userq hw unmap error*/ 660 - if (r) { 661 - drm_warn(adev_to_drm(uq_mgr->adev), "trying to destroy a HW mapping userq\n"); 662 - queue->state = AMDGPU_USERQ_STATE_HUNG; 663 - } 664 - 665 646 atomic_dec(&uq_mgr->userq_count[queue->queue_type]); 666 647 amdgpu_userq_cleanup(queue); 667 648 mutex_unlock(&uq_mgr->userq_mutex); ··· 1194 1187 bo = range->bo; 1195 1188 ret = amdgpu_ttm_tt_get_user_pages(bo, range); 1196 1189 if (ret) 1197 - goto unlock_all; 1190 + goto free_ranges; 1198 1191 } 1199 1192 1200 1193 invalidated = true; ··· 1221 1214 1222 1215 unlock_all: 1223 1216 drm_exec_fini(&exec); 1217 + free_ranges: 1224 1218 xa_for_each(&xa, tmp_key, range) { 1225 1219 if (!range) 1226 1220 continue;
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
··· 156 156 void amdgpu_userq_pre_reset(struct amdgpu_device *adev); 157 157 int amdgpu_userq_post_reset(struct amdgpu_device *adev, bool vram_lost); 158 158 void amdgpu_userq_start_hang_detect_work(struct amdgpu_usermode_queue *queue); 159 + void amdgpu_userq_process_fence_irq(struct amdgpu_device *adev, u32 doorbell); 159 160 160 161 int amdgpu_userq_input_va_validate(struct amdgpu_device *adev, 161 162 struct amdgpu_usermode_queue *queue,
+14 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 3023 3023 3024 3024 is_compute_context = vm->is_compute_context; 3025 3025 3026 - if (is_compute_context && !svm_range_restore_pages(adev, pasid, vmid, 3027 - node_id, addr >> PAGE_SHIFT, ts, write_fault)) { 3026 + if (is_compute_context) { 3027 + /* Unreserve root since svm_range_restore_pages might try to reserve it. */ 3028 + /* TODO: rework svm_range_restore_pages so that this isn't necessary. */ 3028 3029 amdgpu_bo_unreserve(root); 3030 + 3031 + if (!svm_range_restore_pages(adev, pasid, vmid, 3032 + node_id, addr >> PAGE_SHIFT, ts, write_fault)) { 3033 + amdgpu_bo_unref(&root); 3034 + return true; 3035 + } 3029 3036 amdgpu_bo_unref(&root); 3030 - return true; 3037 + 3038 + /* Re-acquire the VM lock, could be that the VM was freed in between. */ 3039 + vm = amdgpu_vm_lock_by_pasid(adev, &root, pasid); 3040 + if (!vm) 3041 + return false; 3031 3042 } 3032 3043 3033 3044 addr /= AMDGPU_GPU_PAGE_SIZE;
+1 -9
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
··· 6523 6523 DRM_DEBUG("IH: CP EOP\n"); 6524 6524 6525 6525 if (adev->enable_mes && doorbell_offset) { 6526 - struct amdgpu_usermode_queue *queue; 6527 - struct xarray *xa = &adev->userq_doorbell_xa; 6528 - unsigned long flags; 6529 - 6530 - xa_lock_irqsave(xa, flags); 6531 - queue = xa_load(xa, doorbell_offset); 6532 - if (queue) 6533 - amdgpu_userq_fence_driver_process(queue->fence_drv); 6534 - xa_unlock_irqrestore(xa, flags); 6526 + amdgpu_userq_process_fence_irq(adev, doorbell_offset); 6535 6527 } else { 6536 6528 me_id = (entry->ring_id & 0x0c) >> 2; 6537 6529 pipe_id = (entry->ring_id & 0x03) >> 0;
+1 -9
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
··· 4854 4854 DRM_DEBUG("IH: CP EOP\n"); 4855 4855 4856 4856 if (adev->enable_mes && doorbell_offset) { 4857 - struct xarray *xa = &adev->userq_doorbell_xa; 4858 - struct amdgpu_usermode_queue *queue; 4859 - unsigned long flags; 4860 - 4861 - xa_lock_irqsave(xa, flags); 4862 - queue = xa_load(xa, doorbell_offset); 4863 - if (queue) 4864 - amdgpu_userq_fence_driver_process(queue->fence_drv); 4865 - xa_unlock_irqrestore(xa, flags); 4857 + amdgpu_userq_process_fence_irq(adev, doorbell_offset); 4866 4858 } else { 4867 4859 me_id = (entry->ring_id & 0x0c) >> 2; 4868 4860 pipe_id = (entry->ring_id & 0x03) >> 0;
+1 -10
drivers/gpu/drm/amd/amdgpu/gfx_v12_1.c
··· 3643 3643 DRM_DEBUG("IH: CP EOP\n"); 3644 3644 3645 3645 if (adev->enable_mes && doorbell_offset) { 3646 - struct xarray *xa = &adev->userq_doorbell_xa; 3647 - struct amdgpu_usermode_queue *queue; 3648 - unsigned long flags; 3649 - 3650 - xa_lock_irqsave(xa, flags); 3651 - queue = xa_load(xa, doorbell_offset); 3652 - if (queue) 3653 - amdgpu_userq_fence_driver_process(queue->fence_drv); 3654 - 3655 - xa_unlock_irqrestore(xa, flags); 3646 + amdgpu_userq_process_fence_irq(adev, doorbell_offset); 3656 3647 } else { 3657 3648 me_id = (entry->ring_id & 0x0c) >> 2; 3658 3649 pipe_id = (entry->ring_id & 0x03) >> 0;
+66
drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
··· 1571 1571 mutex_unlock(&adev->grbm_idx_mutex); 1572 1572 } 1573 1573 1574 + /** 1575 + * gfx_v6_0_setup_tcc() - setup which TCCs are used 1576 + * 1577 + * @adev: amdgpu_device pointer 1578 + * 1579 + * Verify whether the current GPU has any TCCs disabled, 1580 + * which can happen when the GPU is harvested and some 1581 + * memory channels are disabled, reducing the memory bus width. 1582 + * For example, on the Radeon HD 7870 XT (Tahiti LE). 1583 + * 1584 + * If some TCCs are disabled, we need to make sure that 1585 + * the disabled TCCs are not used, and the remaining TCCs 1586 + * are used optimally. 1587 + * 1588 + * TCP_CHAN_STEER_LO/HI control which TCC is used by TCP channels. 1589 + * TCP_ADDR_CONFIG.NUM_TCC_BANKS controls how many channels are used. 1590 + * 1591 + * For optimal performance: 1592 + * - Rely on the CHAN_STEER from the golden registers table, 1593 + * only skip disabled TCCs but keep the mapping order. 1594 + * - Limit NUM_TCC_BANKS to number of active TCCs to avoid thrashing, 1595 + * which performs better than using the same TCC twice. 1596 + */ 1597 + static void gfx_v6_0_setup_tcc(struct amdgpu_device *adev) 1598 + { 1599 + u32 i, tcc, tcp_addr_config, num_active_tcc = 0; 1600 + u64 chan_steer, patched_chan_steer = 0; 1601 + const u32 num_max_tcc = adev->gfx.config.max_texture_channel_caches; 1602 + const u32 dis_tcc_mask = 1603 + amdgpu_gfx_create_bitmask(num_max_tcc) & 1604 + (REG_GET_FIELD(RREG32(mmCGTS_TCC_DISABLE), 1605 + CGTS_TCC_DISABLE, TCC_DISABLE) | 1606 + REG_GET_FIELD(RREG32(mmCGTS_USER_TCC_DISABLE), 1607 + CGTS_USER_TCC_DISABLE, TCC_DISABLE)); 1608 + 1609 + /* When no TCC is disabled, the golden registers table already has optimal TCC setup */ 1610 + if (!dis_tcc_mask) 1611 + return; 1612 + 1613 + /* Each 4-bit nibble contains the index of a TCC used by all TCPs */ 1614 + chan_steer = RREG32(mmTCP_CHAN_STEER_LO) | ((u64)RREG32(mmTCP_CHAN_STEER_HI) << 32ull); 1615 + 1616 + /* Patch the TCP to TCC mapping to skip disabled TCCs */ 1617 + for (i = 0; i < num_max_tcc; ++i) { 1618 + tcc = (chan_steer >> (u64)(4 * i)) & 0xf; 1619 + 1620 + if (!((1 << tcc) & dis_tcc_mask)) { 1621 + /* Copy enabled TCC indices to the patched register value. */ 1622 + patched_chan_steer |= (u64)tcc << (u64)(4 * num_active_tcc); 1623 + ++num_active_tcc; 1624 + } 1625 + } 1626 + 1627 + WARN_ON(num_active_tcc != num_max_tcc - hweight32(dis_tcc_mask)); 1628 + 1629 + /* Patch number of TCCs used by TCPs */ 1630 + tcp_addr_config = REG_SET_FIELD(RREG32(mmTCP_ADDR_CONFIG), 1631 + TCP_ADDR_CONFIG, NUM_TCC_BANKS, 1632 + num_active_tcc - 1); 1633 + 1634 + WREG32(mmTCP_ADDR_CONFIG, tcp_addr_config); 1635 + WREG32(mmTCP_CHAN_STEER_HI, upper_32_bits(patched_chan_steer)); 1636 + WREG32(mmTCP_CHAN_STEER_LO, lower_32_bits(patched_chan_steer)); 1637 + } 1638 + 1574 1639 static void gfx_v6_0_config_init(struct amdgpu_device *adev) 1575 1640 { 1576 1641 adev->gfx.config.double_offchip_lds_buf = 0; ··· 1794 1729 gfx_v6_0_tiling_mode_table_init(adev); 1795 1730 1796 1731 gfx_v6_0_setup_rb(adev); 1732 + gfx_v6_0_setup_tcc(adev); 1797 1733 1798 1734 gfx_v6_0_setup_spi(adev); 1799 1735
+1
drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
··· 802 802 static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = { 803 803 .type = AMDGPU_RING_TYPE_VCN_JPEG, 804 804 .align_mask = 0xf, 805 + .no_user_fence = true, 805 806 .get_rptr = jpeg_v2_0_dec_ring_get_rptr, 806 807 .get_wptr = jpeg_v2_0_dec_ring_get_wptr, 807 808 .set_wptr = jpeg_v2_0_dec_ring_set_wptr,
+2
drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
··· 693 693 static const struct amdgpu_ring_funcs jpeg_v2_5_dec_ring_vm_funcs = { 694 694 .type = AMDGPU_RING_TYPE_VCN_JPEG, 695 695 .align_mask = 0xf, 696 + .no_user_fence = true, 696 697 .get_rptr = jpeg_v2_5_dec_ring_get_rptr, 697 698 .get_wptr = jpeg_v2_5_dec_ring_get_wptr, 698 699 .set_wptr = jpeg_v2_5_dec_ring_set_wptr, ··· 725 724 static const struct amdgpu_ring_funcs jpeg_v2_6_dec_ring_vm_funcs = { 726 725 .type = AMDGPU_RING_TYPE_VCN_JPEG, 727 726 .align_mask = 0xf, 727 + .no_user_fence = true, 728 728 .get_rptr = jpeg_v2_5_dec_ring_get_rptr, 729 729 .get_wptr = jpeg_v2_5_dec_ring_get_wptr, 730 730 .set_wptr = jpeg_v2_5_dec_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
··· 594 594 static const struct amdgpu_ring_funcs jpeg_v3_0_dec_ring_vm_funcs = { 595 595 .type = AMDGPU_RING_TYPE_VCN_JPEG, 596 596 .align_mask = 0xf, 597 + .no_user_fence = true, 597 598 .get_rptr = jpeg_v3_0_dec_ring_get_rptr, 598 599 .get_wptr = jpeg_v3_0_dec_ring_get_wptr, 599 600 .set_wptr = jpeg_v3_0_dec_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
··· 759 759 static const struct amdgpu_ring_funcs jpeg_v4_0_dec_ring_vm_funcs = { 760 760 .type = AMDGPU_RING_TYPE_VCN_JPEG, 761 761 .align_mask = 0xf, 762 + .no_user_fence = true, 762 763 .get_rptr = jpeg_v4_0_dec_ring_get_rptr, 763 764 .get_wptr = jpeg_v4_0_dec_ring_get_wptr, 764 765 .set_wptr = jpeg_v4_0_dec_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
··· 1219 1219 static const struct amdgpu_ring_funcs jpeg_v4_0_3_dec_ring_vm_funcs = { 1220 1220 .type = AMDGPU_RING_TYPE_VCN_JPEG, 1221 1221 .align_mask = 0xf, 1222 + .no_user_fence = true, 1222 1223 .get_rptr = jpeg_v4_0_3_dec_ring_get_rptr, 1223 1224 .get_wptr = jpeg_v4_0_3_dec_ring_get_wptr, 1224 1225 .set_wptr = jpeg_v4_0_3_dec_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
··· 804 804 static const struct amdgpu_ring_funcs jpeg_v4_0_5_dec_ring_vm_funcs = { 805 805 .type = AMDGPU_RING_TYPE_VCN_JPEG, 806 806 .align_mask = 0xf, 807 + .no_user_fence = true, 807 808 .get_rptr = jpeg_v4_0_5_dec_ring_get_rptr, 808 809 .get_wptr = jpeg_v4_0_5_dec_ring_get_wptr, 809 810 .set_wptr = jpeg_v4_0_5_dec_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c
··· 680 680 static const struct amdgpu_ring_funcs jpeg_v5_0_0_dec_ring_vm_funcs = { 681 681 .type = AMDGPU_RING_TYPE_VCN_JPEG, 682 682 .align_mask = 0xf, 683 + .no_user_fence = true, 683 684 .get_rptr = jpeg_v5_0_0_dec_ring_get_rptr, 684 685 .get_wptr = jpeg_v5_0_0_dec_ring_get_wptr, 685 686 .set_wptr = jpeg_v5_0_0_dec_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c
··· 884 884 static const struct amdgpu_ring_funcs jpeg_v5_0_1_dec_ring_vm_funcs = { 885 885 .type = AMDGPU_RING_TYPE_VCN_JPEG, 886 886 .align_mask = 0xf, 887 + .no_user_fence = true, 887 888 .get_rptr = jpeg_v5_0_1_dec_ring_get_rptr, 888 889 .get_wptr = jpeg_v5_0_1_dec_ring_get_wptr, 889 890 .set_wptr = jpeg_v5_0_1_dec_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_2.c
··· 703 703 static const struct amdgpu_ring_funcs jpeg_v5_0_2_dec_ring_vm_funcs = { 704 704 .type = AMDGPU_RING_TYPE_VCN_JPEG, 705 705 .align_mask = 0xf, 706 + .no_user_fence = true, 706 707 .get_rptr = jpeg_v5_0_2_dec_ring_get_rptr, 707 708 .get_wptr = jpeg_v5_0_2_dec_ring_get_wptr, 708 709 .set_wptr = jpeg_v5_0_2_dec_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c
··· 661 661 static const struct amdgpu_ring_funcs jpeg_v5_3_0_dec_ring_vm_funcs = { 662 662 .type = AMDGPU_RING_TYPE_VCN_JPEG, 663 663 .align_mask = 0xf, 664 + .no_user_fence = true, 664 665 .get_rptr = jpeg_v5_3_0_dec_ring_get_rptr, 665 666 .get_wptr = jpeg_v5_3_0_dec_ring_get_wptr, 666 667 .set_wptr = jpeg_v5_3_0_dec_ring_set_wptr,
+1 -10
drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
··· 1662 1662 u32 doorbell_offset = entry->src_data[0]; 1663 1663 1664 1664 if (adev->enable_mes && doorbell_offset) { 1665 - struct amdgpu_usermode_queue *queue; 1666 - struct xarray *xa = &adev->userq_doorbell_xa; 1667 - unsigned long flags; 1668 - 1669 1665 doorbell_offset >>= SDMA0_QUEUE0_DOORBELL_OFFSET__OFFSET__SHIFT; 1670 - 1671 - xa_lock_irqsave(xa, flags); 1672 - queue = xa_load(xa, doorbell_offset); 1673 - if (queue) 1674 - amdgpu_userq_fence_driver_process(queue->fence_drv); 1675 - xa_unlock_irqrestore(xa, flags); 1666 + amdgpu_userq_process_fence_irq(adev, doorbell_offset); 1676 1667 } 1677 1668 1678 1669 return 0;
+1 -10
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
··· 1594 1594 u32 doorbell_offset = entry->src_data[0]; 1595 1595 1596 1596 if (adev->enable_mes && doorbell_offset) { 1597 - struct xarray *xa = &adev->userq_doorbell_xa; 1598 - struct amdgpu_usermode_queue *queue; 1599 - unsigned long flags; 1600 - 1601 1597 doorbell_offset >>= SDMA0_QUEUE0_DOORBELL_OFFSET__OFFSET__SHIFT; 1602 - 1603 - xa_lock_irqsave(xa, flags); 1604 - queue = xa_load(xa, doorbell_offset); 1605 - if (queue) 1606 - amdgpu_userq_fence_driver_process(queue->fence_drv); 1607 - xa_unlock_irqrestore(xa, flags); 1598 + amdgpu_userq_process_fence_irq(adev, doorbell_offset); 1608 1599 } 1609 1600 1610 1601 return 0;
+10
drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c
··· 242 242 uint64_t addr; 243 243 uint32_t size; 244 244 245 + /* When the keyselect is already set, don't perturb it. */ 246 + if (RREG32(mmUVD_FW_START)) 247 + return; 248 + 245 249 /* program the VCPU memory controller bits 0-27 */ 246 250 addr = (adev->uvd.inst->gpu_addr + AMDGPU_UVD_FIRMWARE_OFFSET) >> 3; 247 251 size = AMDGPU_UVD_FIRMWARE_SIZE(adev) >> 3; ··· 287 283 { 288 284 int i; 289 285 uint32_t keysel = adev->uvd.keyselect; 286 + 287 + if (RREG32(mmUVD_FW_START) & UVD_FW_STATUS__PASS_MASK) { 288 + dev_dbg(adev->dev, "UVD keyselect already set: 0x%x (on CPU: 0x%x)\n", 289 + RREG32(mmUVD_FW_START), adev->uvd.keyselect); 290 + return 0; 291 + } 290 292 291 293 WREG32(mmUVD_FW_START, keysel); 292 294
+2
drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
··· 2113 2113 static const struct amdgpu_ring_funcs vcn_v2_0_dec_ring_vm_funcs = { 2114 2114 .type = AMDGPU_RING_TYPE_VCN_DEC, 2115 2115 .align_mask = 0xf, 2116 + .no_user_fence = true, 2116 2117 .secure_submission_supported = true, 2117 2118 .get_rptr = vcn_v2_0_dec_ring_get_rptr, 2118 2119 .get_wptr = vcn_v2_0_dec_ring_get_wptr, ··· 2146 2145 .type = AMDGPU_RING_TYPE_VCN_ENC, 2147 2146 .align_mask = 0x3f, 2148 2147 .nop = VCN_ENC_CMD_NO_OP, 2148 + .no_user_fence = true, 2149 2149 .get_rptr = vcn_v2_0_enc_ring_get_rptr, 2150 2150 .get_wptr = vcn_v2_0_enc_ring_get_wptr, 2151 2151 .set_wptr = vcn_v2_0_enc_ring_set_wptr,
+2
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
··· 1778 1778 static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = { 1779 1779 .type = AMDGPU_RING_TYPE_VCN_DEC, 1780 1780 .align_mask = 0xf, 1781 + .no_user_fence = true, 1781 1782 .secure_submission_supported = true, 1782 1783 .get_rptr = vcn_v2_5_dec_ring_get_rptr, 1783 1784 .get_wptr = vcn_v2_5_dec_ring_get_wptr, ··· 1880 1879 .type = AMDGPU_RING_TYPE_VCN_ENC, 1881 1880 .align_mask = 0x3f, 1882 1881 .nop = VCN_ENC_CMD_NO_OP, 1882 + .no_user_fence = true, 1883 1883 .get_rptr = vcn_v2_5_enc_ring_get_rptr, 1884 1884 .get_wptr = vcn_v2_5_enc_ring_get_wptr, 1885 1885 .set_wptr = vcn_v2_5_enc_ring_set_wptr,
+6 -1
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c
··· 1856 1856 .type = AMDGPU_RING_TYPE_VCN_DEC, 1857 1857 .align_mask = 0x3f, 1858 1858 .nop = VCN_DEC_SW_CMD_NO_OP, 1859 + .no_user_fence = true, 1859 1860 .secure_submission_supported = true, 1860 1861 .get_rptr = vcn_v3_0_dec_ring_get_rptr, 1861 1862 .get_wptr = vcn_v3_0_dec_ring_get_wptr, ··· 1973 1972 1974 1973 for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) { 1975 1974 uint32_t offset, size, *create; 1975 + uint64_t buf_end; 1976 1976 1977 1977 if (msg[0] != RDECODE_MESSAGE_CREATE) 1978 1978 continue; ··· 1981 1979 offset = msg[1]; 1982 1980 size = msg[2]; 1983 1981 1984 - if (size < 4 || offset + size > end - addr) { 1982 + if (size < 4 || check_add_overflow(offset, size, &buf_end) || 1983 + buf_end > end - addr) { 1985 1984 DRM_ERROR("VCN message buffer exceeds BO bounds!\n"); 1986 1985 r = -EINVAL; 1987 1986 goto out; ··· 2039 2036 static const struct amdgpu_ring_funcs vcn_v3_0_dec_ring_vm_funcs = { 2040 2037 .type = AMDGPU_RING_TYPE_VCN_DEC, 2041 2038 .align_mask = 0xf, 2039 + .no_user_fence = true, 2042 2040 .secure_submission_supported = true, 2043 2041 .get_rptr = vcn_v3_0_dec_ring_get_rptr, 2044 2042 .get_wptr = vcn_v3_0_dec_ring_get_wptr, ··· 2142 2138 .type = AMDGPU_RING_TYPE_VCN_ENC, 2143 2139 .align_mask = 0x3f, 2144 2140 .nop = VCN_ENC_CMD_NO_OP, 2141 + .no_user_fence = true, 2145 2142 .get_rptr = vcn_v3_0_enc_ring_get_rptr, 2146 2143 .get_wptr = vcn_v3_0_enc_ring_get_wptr, 2147 2144 .set_wptr = vcn_v3_0_enc_ring_set_wptr,
+4 -1
drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
··· 1889 1889 1890 1890 for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) { 1891 1891 uint32_t offset, size, *create; 1892 + uint64_t buf_end; 1892 1893 1893 1894 if (msg[0] != RDECODE_MESSAGE_CREATE) 1894 1895 continue; ··· 1897 1896 offset = msg[1]; 1898 1897 size = msg[2]; 1899 1898 1900 - if (size < 4 || offset + size > end - addr) { 1899 + if (size < 4 || check_add_overflow(offset, size, &buf_end) || 1900 + buf_end > end - addr) { 1901 1901 DRM_ERROR("VCN message buffer exceeds BO bounds!\n"); 1902 1902 r = -EINVAL; 1903 1903 goto out; ··· 1996 1994 .type = AMDGPU_RING_TYPE_VCN_ENC, 1997 1995 .align_mask = 0x3f, 1998 1996 .nop = VCN_ENC_CMD_NO_OP, 1997 + .no_user_fence = true, 1999 1998 .extra_bytes = sizeof(struct amdgpu_vcn_rb_metadata), 2000 1999 .get_rptr = vcn_v4_0_unified_ring_get_rptr, 2001 2000 .get_wptr = vcn_v4_0_unified_ring_get_wptr,
+1
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
··· 1775 1775 .type = AMDGPU_RING_TYPE_VCN_ENC, 1776 1776 .align_mask = 0x3f, 1777 1777 .nop = VCN_ENC_CMD_NO_OP, 1778 + .no_user_fence = true, 1778 1779 .get_rptr = vcn_v4_0_3_unified_ring_get_rptr, 1779 1780 .get_wptr = vcn_v4_0_3_unified_ring_get_wptr, 1780 1781 .set_wptr = vcn_v4_0_3_unified_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
··· 1483 1483 .type = AMDGPU_RING_TYPE_VCN_ENC, 1484 1484 .align_mask = 0x3f, 1485 1485 .nop = VCN_ENC_CMD_NO_OP, 1486 + .no_user_fence = true, 1486 1487 .get_rptr = vcn_v4_0_5_unified_ring_get_rptr, 1487 1488 .get_wptr = vcn_v4_0_5_unified_ring_get_wptr, 1488 1489 .set_wptr = vcn_v4_0_5_unified_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c
··· 1207 1207 .type = AMDGPU_RING_TYPE_VCN_ENC, 1208 1208 .align_mask = 0x3f, 1209 1209 .nop = VCN_ENC_CMD_NO_OP, 1210 + .no_user_fence = true, 1210 1211 .get_rptr = vcn_v5_0_0_unified_ring_get_rptr, 1211 1212 .get_wptr = vcn_v5_0_0_unified_ring_get_wptr, 1212 1213 .set_wptr = vcn_v5_0_0_unified_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
··· 1419 1419 .type = AMDGPU_RING_TYPE_VCN_ENC, 1420 1420 .align_mask = 0x3f, 1421 1421 .nop = VCN_ENC_CMD_NO_OP, 1422 + .no_user_fence = true, 1422 1423 .get_rptr = vcn_v5_0_1_unified_ring_get_rptr, 1423 1424 .get_wptr = vcn_v5_0_1_unified_ring_get_wptr, 1424 1425 .set_wptr = vcn_v5_0_1_unified_ring_set_wptr,
+1
drivers/gpu/drm/amd/amdgpu/vcn_v5_0_2.c
··· 994 994 .type = AMDGPU_RING_TYPE_VCN_ENC, 995 995 .align_mask = 0x3f, 996 996 .nop = VCN_ENC_CMD_NO_OP, 997 + .no_user_fence = true, 997 998 .get_rptr = vcn_v5_0_2_unified_ring_get_rptr, 998 999 .get_wptr = vcn_v5_0_2_unified_ring_get_wptr, 999 1000 .set_wptr = vcn_v5_0_2_unified_ring_set_wptr,
+24 -2
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
··· 25 25 #include <linux/err.h> 26 26 #include <linux/fs.h> 27 27 #include <linux/file.h> 28 + #include <linux/overflow.h> 28 29 #include <linux/sched.h> 29 30 #include <linux/slab.h> 30 31 #include <linux/uaccess.h> ··· 1696 1695 return kfd_smi_event_open(pdd->dev, &args->anon_fd); 1697 1696 } 1698 1697 1698 + static int kfd_ioctl_svm_validate(void *kdata, unsigned int usize) 1699 + { 1700 + struct kfd_ioctl_svm_args *args = kdata; 1701 + size_t expected = struct_size(args, attrs, args->nattr); 1702 + 1703 + if (expected == SIZE_MAX || usize < expected) 1704 + return -EINVAL; 1705 + return 0; 1706 + } 1707 + 1699 1708 #if IS_ENABLED(CONFIG_HSA_AMD_SVM) 1700 1709 1701 1710 static int kfd_ioctl_set_xnack_mode(struct file *filep, ··· 3220 3209 3221 3210 #define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \ 3222 3211 [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \ 3223 - .cmd_drv = 0, .name = #ioctl} 3212 + .validate = NULL, .cmd_drv = 0, .name = #ioctl} 3213 + 3214 + #define AMDKFD_IOCTL_DEF_V(ioctl, _func, _validate, _flags) \ 3215 + [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \ 3216 + .validate = _validate, .cmd_drv = 0, .name = #ioctl} 3224 3217 3225 3218 /** Ioctl table */ 3226 3219 static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { ··· 3321 3306 AMDKFD_IOCTL_DEF(AMDKFD_IOC_SMI_EVENTS, 3322 3307 kfd_ioctl_smi_events, 0), 3323 3308 3324 - AMDKFD_IOCTL_DEF(AMDKFD_IOC_SVM, kfd_ioctl_svm, 0), 3309 + AMDKFD_IOCTL_DEF_V(AMDKFD_IOC_SVM, kfd_ioctl_svm, 3310 + kfd_ioctl_svm_validate, 0), 3325 3311 3326 3312 AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_XNACK_MODE, 3327 3313 kfd_ioctl_set_xnack_mode, 0), ··· 3445 3429 } 3446 3430 } else if (cmd & IOC_OUT) { 3447 3431 memset(kdata, 0, usize); 3432 + } 3433 + 3434 + if (ioctl->validate) { 3435 + retcode = ioctl->validate(kdata, usize); 3436 + if (retcode) 3437 + goto err_i1; 3448 3438 } 3449 3439 3450 3440 retcode = func(filep, process, kdata);
+3
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
··· 1047 1047 typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p, 1048 1048 void *data); 1049 1049 1050 + typedef int amdkfd_ioctl_validate_t(void *kdata, unsigned int usize); 1051 + 1050 1052 struct amdkfd_ioctl_desc { 1051 1053 unsigned int cmd; 1052 1054 int flags; 1053 1055 amdkfd_ioctl_t *func; 1056 + amdkfd_ioctl_validate_t *validate; 1054 1057 unsigned int cmd_drv; 1055 1058 const char *name; 1056 1059 };
+11
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
··· 1366 1366 1367 1367 pr_debug("CPU[0x%llx 0x%llx] -> GPU[0x%llx 0x%llx]\n", start, last, 1368 1368 gpu_start, gpu_end); 1369 + 1370 + if (!amdgpu_vm_ready(vm)) { 1371 + pr_debug("VM not ready, canceling unmap\n"); 1372 + return -EINVAL; 1373 + } 1374 + 1369 1375 return amdgpu_vm_update_range(adev, vm, false, true, true, false, NULL, gpu_start, 1370 1376 gpu_end, init_pte_value, 0, 0, NULL, NULL, 1371 1377 fence); ··· 1448 1442 1449 1443 pr_debug("svms 0x%p [0x%lx 0x%lx] readonly %d\n", prange->svms, 1450 1444 last_start, last_start + npages - 1, readonly); 1445 + 1446 + if (!amdgpu_vm_ready(vm)) { 1447 + pr_debug("VM not ready, canceling map\n"); 1448 + return -EINVAL; 1449 + } 1451 1450 1452 1451 for (i = offset; i < offset + npages; i++) { 1453 1452 uint64_t gpu_start;
+20 -4
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 1903 1903 goto error; 1904 1904 } 1905 1905 1906 - init_data.asic_id.chip_family = adev->family; 1906 + /* special handling for early revisions of GC 11.5.4 */ 1907 + if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 5, 4)) 1908 + init_data.asic_id.chip_family = AMDGPU_FAMILY_GC_11_5_4; 1909 + else 1910 + init_data.asic_id.chip_family = adev->family; 1907 1911 1908 1912 init_data.asic_id.pci_revision_id = adev->pdev->revision; 1909 1913 init_data.asic_id.hw_internal_rev = adev->external_rev_id; ··· 9408 9404 if (acrtc_state) { 9409 9405 timing = &acrtc_state->stream->timing; 9410 9406 9411 - if (amdgpu_ip_version(adev, DCE_HWIP, 0) < 9412 - IP_VERSION(3, 5, 0) || 9413 - !(adev->flags & AMD_IS_APU)) { 9407 + if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= 9408 + IP_VERSION(3, 2, 0) && 9409 + !(adev->flags & AMD_IS_APU)) { 9410 + /* 9411 + * DGPUs NV3x and newer that support idle optimizations 9412 + * experience intermittent flip-done timeouts on cursor 9413 + * updates. Restore 5s offdelay behavior for now. 9414 + * 9415 + * Discussion on the issue: 9416 + * https://lore.kernel.org/amd-gfx/20260217191632.1243826-1-sysdadmin@m1k.cloud/ 9417 + */ 9418 + config.offdelay_ms = 5000; 9419 + config.disable_immediate = false; 9420 + } else if (amdgpu_ip_version(adev, DCE_HWIP, 0) < 9421 + IP_VERSION(3, 5, 0)) { 9414 9422 /* 9415 9423 * Older HW and DGPU have issues with instant off; 9416 9424 * use a 2 frame offdelay.
+44
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
··· 1032 1032 return drm_edid_read_custom(connector, dm_helpers_probe_acpi_edid, connector); 1033 1033 } 1034 1034 1035 + static const struct drm_edid * 1036 + dm_helpers_read_vbios_hardcoded_edid(struct dc_link *link, struct amdgpu_dm_connector *aconnector) 1037 + { 1038 + struct dc_bios *bios = link->ctx->dc_bios; 1039 + struct embedded_panel_info info; 1040 + const struct drm_edid *edid; 1041 + enum bp_result r; 1042 + 1043 + if (!dc_is_embedded_signal(link->connector_signal) || 1044 + !bios->funcs->get_embedded_panel_info) 1045 + return NULL; 1046 + 1047 + memset(&info, 0, sizeof(info)); 1048 + r = bios->funcs->get_embedded_panel_info(bios, &info); 1049 + 1050 + if (r != BP_RESULT_OK) { 1051 + dm_error("Error when reading embedded panel info: %u\n", r); 1052 + return NULL; 1053 + } 1054 + 1055 + if (!info.fake_edid || !info.fake_edid_size) { 1056 + dm_error("Embedded panel info doesn't contain an EDID\n"); 1057 + return NULL; 1058 + } 1059 + 1060 + edid = drm_edid_alloc(info.fake_edid, info.fake_edid_size); 1061 + 1062 + if (!drm_edid_valid(edid)) { 1063 + dm_error("EDID from embedded panel info is invalid\n"); 1064 + drm_edid_free(edid); 1065 + return NULL; 1066 + } 1067 + 1068 + aconnector->base.display_info.width_mm = info.panel_width_mm; 1069 + aconnector->base.display_info.height_mm = info.panel_height_mm; 1070 + 1071 + return edid; 1072 + } 1073 + 1035 1074 void populate_hdmi_info_from_connector(struct drm_hdmi_info *hdmi, struct dc_edid_caps *edid_caps) 1036 1075 { 1037 1076 edid_caps->scdc_present = hdmi->scdc.supported; ··· 1091 1052 1092 1053 if (link->aux_mode) 1093 1054 ddc = &aconnector->dm_dp_aux.aux.ddc; 1055 + else if (link->ddc_hw_inst == GPIO_DDC_LINE_UNKNOWN && 1056 + dc_is_embedded_signal(link->connector_signal)) 1057 + ddc = NULL; 1094 1058 else 1095 1059 ddc = &aconnector->i2c->base; 1096 1060 ··· 1107 1065 drm_edid = dm_helpers_read_acpi_edid(aconnector); 1108 1066 if (drm_edid) 1109 1067 drm_info(connector->dev, "Using ACPI provided EDID for %s\n", connector->name); 1068 + else if (!ddc) 1069 + drm_edid = dm_helpers_read_vbios_hardcoded_edid(link, aconnector); 1110 1070 else 1111 1071 drm_edid = drm_edid_read_ddc(connector, ddc); 1112 1072 drm_edid_connector_update(connector, drm_edid);
+72 -1
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
··· 794 794 795 795 static enum bp_result bios_parser_dac_load_detection( 796 796 struct dc_bios *dcb, 797 - enum engine_id engine_id) 797 + enum engine_id engine_id, 798 + struct graphics_object_id ext_enc_id) 798 799 { 799 800 struct bios_parser *bp = BP_FROM_DCB(dcb); 800 801 struct dc_context *ctx = dcb->ctx; 801 802 struct bp_load_detection_parameters bp_params = {0}; 803 + struct bp_external_encoder_control ext_cntl = {0}; 802 804 enum bp_result bp_result = BP_RESULT_UNSUPPORTED; 803 805 uint32_t bios_0_scratch; 804 806 uint32_t device_id_mask = 0; ··· 826 824 827 825 bp_params.engine_id = engine_id; 828 826 bp_result = bp->cmd_tbl.dac_load_detection(bp, &bp_params); 827 + } else if (ext_enc_id.id) { 828 + if (!bp->cmd_tbl.external_encoder_control) 829 + return BP_RESULT_UNSUPPORTED; 830 + 831 + ext_cntl.action = EXTERNAL_ENCODER_CONTROL_DAC_LOAD_DETECT; 832 + ext_cntl.encoder_id = ext_enc_id; 833 + bp_result = bp->cmd_tbl.external_encoder_control(bp, &ext_cntl); 829 834 } 830 835 831 836 if (bp_result != BP_RESULT_OK) ··· 1313 1304 return BP_RESULT_FAILURE; 1314 1305 } 1315 1306 1307 + static enum bp_result get_embedded_panel_extra_info( 1308 + struct bios_parser *bp, 1309 + struct embedded_panel_info *info, 1310 + const uint32_t table_offset) 1311 + { 1312 + uint8_t *record = bios_get_image(&bp->base, table_offset, 1); 1313 + ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; 1314 + ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; 1315 + 1316 + while (*record != ATOM_RECORD_END_TYPE) { 1317 + switch (*record) { 1318 + case LCD_MODE_PATCH_RECORD_MODE_TYPE: 1319 + record += sizeof(ATOM_PATCH_RECORD_MODE); 1320 + break; 1321 + case LCD_RTS_RECORD_TYPE: 1322 + record += sizeof(ATOM_LCD_RTS_RECORD); 1323 + break; 1324 + case LCD_CAP_RECORD_TYPE: 1325 + record += sizeof(ATOM_LCD_MODE_CONTROL_CAP); 1326 + break; 1327 + case LCD_FAKE_EDID_PATCH_RECORD_TYPE: 1328 + fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; 1329 + if (fake_edid_record->ucFakeEDIDLength) { 1330 + if (fake_edid_record->ucFakeEDIDLength == 128) 1331 + info->fake_edid_size = 1332 + fake_edid_record->ucFakeEDIDLength; 1333 + else 1334 + info->fake_edid_size = 1335 + fake_edid_record->ucFakeEDIDLength * 128; 1336 + 1337 + info->fake_edid = fake_edid_record->ucFakeEDIDString; 1338 + 1339 + record += struct_size(fake_edid_record, 1340 + ucFakeEDIDString, 1341 + info->fake_edid_size); 1342 + } else { 1343 + /* empty fake edid record must be 3 bytes long */ 1344 + record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1; 1345 + } 1346 + break; 1347 + case LCD_PANEL_RESOLUTION_RECORD_TYPE: 1348 + panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; 1349 + info->panel_width_mm = panel_res_record->usHSize; 1350 + info->panel_height_mm = panel_res_record->usVSize; 1351 + record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD); 1352 + break; 1353 + default: 1354 + return BP_RESULT_BADBIOSTABLE; 1355 + } 1356 + } 1357 + 1358 + return BP_RESULT_OK; 1359 + } 1360 + 1316 1361 static enum bp_result get_embedded_panel_info_v1_2( 1317 1362 struct bios_parser *bp, 1318 1363 struct embedded_panel_info *info) ··· 1482 1419 1483 1420 if (ATOM_PANEL_MISC_API_ENABLED & lvds->ucLVDS_Misc) 1484 1421 info->lcd_timing.misc_info.API_ENABLED = true; 1422 + 1423 + if (lvds->usExtInfoTableOffset) 1424 + return get_embedded_panel_extra_info(bp, info, 1425 + le16_to_cpu(lvds->usExtInfoTableOffset) + DATA_TABLES(LCD_Info)); 1485 1426 1486 1427 return BP_RESULT_OK; 1487 1428 } ··· 1611 1544 info->lcd_timing.misc_info.GREY_LEVEL = 1612 1545 (uint32_t) (ATOM_PANEL_MISC_V13_GREY_LEVEL & 1613 1546 lvds->ucLCD_Misc) >> ATOM_PANEL_MISC_V13_GREY_LEVEL_SHIFT; 1547 + 1548 + if (lvds->usExtInfoTableOffset) 1549 + return get_embedded_panel_extra_info(bp, info, 1550 + le16_to_cpu(lvds->usExtInfoTableOffset) + DATA_TABLES(LCD_Info)); 1614 1551 1615 1552 return BP_RESULT_OK; 1616 1553 }
+1 -1
drivers/gpu/drm/amd/display/dc/dc.h
··· 1682 1682 struct dc_link_training_overrides preferred_training_settings; 1683 1683 struct dp_audio_test_data audio_test_data; 1684 1684 1685 - uint8_t ddc_hw_inst; 1685 + enum gpio_ddc_line ddc_hw_inst; 1686 1686 1687 1687 uint8_t hpd_src; 1688 1688
+2 -1
drivers/gpu/drm/amd/display/dc/dc_bios_types.h
··· 102 102 struct bp_external_encoder_control *cntl); 103 103 enum bp_result (*dac_load_detection)( 104 104 struct dc_bios *bios, 105 - enum engine_id engine_id); 105 + enum engine_id engine_id, 106 + struct graphics_object_id ext_enc_id); 106 107 enum bp_result (*transmitter_control)( 107 108 struct dc_bios *bios, 108 109 struct bp_transmitter_control *cntl);
+2 -2
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mmhubbub.c
··· 40 40 #define FN(reg_name, field_name) \ 41 41 mcif_wb30->mcif_wb_shift->field_name, mcif_wb30->mcif_wb_mask->field_name 42 42 43 - #define MCIF_ADDR(addr) (((unsigned long long)addr & 0xffffffffff) + 0xFE) >> 8 44 - #define MCIF_ADDR_HIGH(addr) (unsigned long long)addr >> 40 43 + #define MCIF_ADDR(addr) ((uint32_t)((((unsigned long long)(addr) & 0xffffffffffULL) + 0xFEULL) >> 8)) 44 + #define MCIF_ADDR_HIGH(addr) ((uint32_t)(((unsigned long long)(addr)) >> 40)) 45 45 46 46 /* wbif programming guide: 47 47 * 1. set up wbif parameter:
+3
drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
··· 646 646 enum gpio_ddc_line dal_ddc_get_line( 647 647 const struct ddc *ddc) 648 648 { 649 + if (!ddc) 650 + return GPIO_DDC_LINE_UNKNOWN; 651 + 649 652 return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data); 650 653 } 651 654
+59 -35
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
··· 665 665 } 666 666 667 667 static void 668 - dce110_dac_encoder_control(struct pipe_ctx *pipe_ctx, bool enable) 668 + dce110_external_encoder_control(enum bp_external_encoder_control_action action, 669 + struct dc_link *link, 670 + struct dc_crtc_timing *timing) 669 671 { 670 - struct dc_link *link = pipe_ctx->stream->link; 672 + struct dc *dc = link->ctx->dc; 671 673 struct dc_bios *bios = link->ctx->dc_bios; 672 - struct bp_encoder_control encoder_control = {0}; 674 + const struct dc_link_settings *link_settings = &link->cur_link_settings; 675 + enum bp_result bp_result = BP_RESULT_OK; 676 + struct bp_external_encoder_control ext_cntl = { 677 + .action = action, 678 + .connector_obj_id = link->link_enc->connector, 679 + .encoder_id = link->ext_enc_id, 680 + .lanes_number = link_settings->lane_count, 681 + .link_rate = link_settings->link_rate, 673 682 674 - encoder_control.action = enable ? ENCODER_CONTROL_ENABLE : ENCODER_CONTROL_DISABLE; 675 - encoder_control.engine_id = link->link_enc->analog_engine; 676 - encoder_control.pixel_clock = pipe_ctx->stream->timing.pix_clk_100hz / 10; 677 - bios->funcs->encoder_control(bios, &encoder_control); 683 + /* Use signal type of the real link encoder, ie. DP */ 684 + .signal = link->connector_signal, 685 + 686 + /* We don't know the timing yet when executing the SETUP action, 687 + * so use a reasonably high default value. It seems that ENABLE 688 + * can change the actual pixel clock but doesn't work with higher 689 + * pixel clocks than what SETUP was called with. 690 + */ 691 + .pixel_clock = timing ? timing->pix_clk_100hz / 10 : 300000, 692 + .color_depth = timing ? timing->display_color_depth : COLOR_DEPTH_888, 693 + }; 694 + DC_LOGGER_INIT(dc->ctx); 695 + 696 + bp_result = bios->funcs->external_encoder_control(bios, &ext_cntl); 697 + 698 + if (bp_result != BP_RESULT_OK) 699 + DC_LOG_ERROR("Failed to execute external encoder action: 0x%x\n", action); 700 + } 701 + 702 + static void 703 + dce110_prepare_ddc(struct dc_link *link) 704 + { 705 + if (link->ext_enc_id.id) 706 + dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_DDC_SETUP, link, NULL); 678 707 } 679 708 680 709 static bool ··· 713 684 struct link_encoder *link_enc = link->link_enc; 714 685 enum bp_result bp_result; 715 686 716 - bp_result = bios->funcs->dac_load_detection(bios, link_enc->analog_engine); 687 + bp_result = bios->funcs->dac_load_detection( 688 + bios, link_enc->analog_engine, link->ext_enc_id); 717 689 return bp_result == BP_RESULT_OK; 718 690 } 719 691 ··· 730 700 uint32_t early_control = 0; 731 701 struct timing_generator *tg = pipe_ctx->stream_res.tg; 732 702 733 - link_hwss->setup_stream_attribute(pipe_ctx); 734 703 link_hwss->setup_stream_encoder(pipe_ctx); 735 704 736 705 dc->hwss.update_info_frame(pipe_ctx); ··· 748 719 749 720 tg->funcs->set_early_control(tg, early_control); 750 721 751 - if (dc_is_rgb_signal(pipe_ctx->stream->signal)) 752 - dce110_dac_encoder_control(pipe_ctx, true); 722 + if (link->ext_enc_id.id) 723 + dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_ENABLE, link, timing); 753 724 } 754 725 755 726 static enum bp_result link_transmitter_control( ··· 1248 1219 link_enc->transmitter - TRANSMITTER_UNIPHY_A); 1249 1220 } 1250 1221 1251 - if (dc_is_rgb_signal(pipe_ctx->stream->signal)) 1252 - dce110_dac_encoder_control(pipe_ctx, false); 1222 + if (link->ext_enc_id.id) 1223 + dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_DISABLE, link, NULL); 1253 1224 } 1254 1225 1255 1226 void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, ··· 1632 1603 1633 1604 return DC_OK; 1634 1605 } 1635 - static void 1636 - dce110_select_crtc_source(struct pipe_ctx *pipe_ctx) 1637 - { 1638 - struct dc_link *link = pipe_ctx->stream->link; 1639 - struct dc_bios *bios = link->ctx->dc_bios; 1640 - struct bp_crtc_source_select crtc_source_select = {0}; 1641 - enum engine_id engine_id = link->link_enc->preferred_engine; 1642 - 1643 - if (dc_is_rgb_signal(pipe_ctx->stream->signal)) 1644 - engine_id = link->link_enc->analog_engine; 1645 - crtc_source_select.controller_id = CONTROLLER_ID_D0 + pipe_ctx->stream_res.tg->inst; 1646 - crtc_source_select.color_depth = pipe_ctx->stream->timing.display_color_depth; 1647 - crtc_source_select.engine_id = engine_id; 1648 - crtc_source_select.sink_signal = pipe_ctx->stream->signal; 1649 - bios->funcs->select_crtc_source(bios, &crtc_source_select); 1650 - } 1651 1606 1652 1607 enum dc_status dce110_apply_single_controller_ctx_to_hw( 1653 1608 struct pipe_ctx *pipe_ctx, ··· 1650 1637 1651 1638 if (hws->funcs.disable_stream_gating) { 1652 1639 hws->funcs.disable_stream_gating(dc, pipe_ctx); 1653 - } 1654 - 1655 - if (pipe_ctx->stream->signal == SIGNAL_TYPE_RGB) { 1656 - dce110_select_crtc_source(pipe_ctx); 1657 1640 } 1658 1641 1659 1642 if (pipe_ctx->stream_res.audio != NULL) { ··· 1731 1722 pipe_ctx->stream_res.tg->funcs->set_static_screen_control( 1732 1723 pipe_ctx->stream_res.tg, event_triggers, 2); 1733 1724 1734 - if (!dc_is_virtual_signal(pipe_ctx->stream->signal) && 1735 - !dc_is_rgb_signal(pipe_ctx->stream->signal)) 1725 + if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) 1736 1726 pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg( 1737 1727 pipe_ctx->stream_res.stream_enc, 1738 1728 pipe_ctx->stream_res.tg->inst); ··· 3384 3376 link->phy_state.symclk_state = SYMCLK_ON_TX_ON; 3385 3377 } 3386 3378 3379 + static void dce110_enable_analog_link_output( 3380 + struct dc_link *link, 3381 + uint32_t pix_clk_100hz) 3382 + { 3383 + link->link_enc->funcs->enable_analog_output( 3384 + link->link_enc, 3385 + pix_clk_100hz); 3386 + } 3387 + 3387 3388 void dce110_enable_dp_link_output( 3388 3389 struct dc_link *link, 3389 3390 const struct link_resource *link_res, ··· 3438 3421 &pipes[i].pll_settings); 3439 3422 } 3440 3423 } 3424 + } 3425 + 3426 + if (link->ext_enc_id.id) { 3427 + dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_INIT, link, NULL); 3428 + dce110_external_encoder_control(EXTERNAL_ENCODER_CONTROL_SETUP, link, NULL); 3441 3429 } 3442 3430 3443 3431 if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) { ··· 3535 3513 .enable_lvds_link_output = dce110_enable_lvds_link_output, 3536 3514 .enable_tmds_link_output = dce110_enable_tmds_link_output, 3537 3515 .enable_dp_link_output = dce110_enable_dp_link_output, 3516 + .enable_analog_link_output = dce110_enable_analog_link_output, 3538 3517 .disable_link_output = dce110_disable_link_output, 3539 3518 .dac_load_detect = dce110_dac_load_detect, 3519 + .prepare_ddc = dce110_prepare_ddc, 3540 3520 }; 3541 3521 3542 3522 static const struct hwseq_private_funcs dce110_private_funcs = {
+2 -1
drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
··· 753 753 enc_init_data, 754 754 &link_enc_feature, 755 755 &link_enc_regs[link_regs_id], 756 - &link_enc_aux_regs[enc_init_data->channel - 1], 756 + enc_init_data->channel == CHANNEL_ID_UNKNOWN ? 757 + NULL : &link_enc_aux_regs[enc_init_data->channel - 1], 757 758 enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? 758 759 NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); 759 760 return &enc110->base;
+2 -1
drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
··· 760 760 enc_init_data, 761 761 &link_enc_feature, 762 762 &link_enc_regs[link_regs_id], 763 - &link_enc_aux_regs[enc_init_data->channel - 1], 763 + enc_init_data->channel == CHANNEL_ID_UNKNOWN ? 764 + NULL : &link_enc_aux_regs[enc_init_data->channel - 1], 764 765 enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? 765 766 NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); 766 767 return &enc110->base;
+4
drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
··· 153 153 uint32_t drr_enabled; 154 154 uint32_t min_drr_refresh_rate; 155 155 bool realtek_eDPToLVDS; 156 + uint16_t panel_width_mm; 157 + uint16_t panel_height_mm; 158 + uint16_t fake_edid_size; 159 + const uint8_t *fake_edid; 156 160 }; 157 161 158 162 struct dc_firmware_info {
+1
drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
··· 425 425 dpm_table->dpm_levels[0].enabled = true; 426 426 dpm_table->dpm_levels[1].value = pptable->GfxclkFmax; 427 427 dpm_table->dpm_levels[1].enabled = true; 428 + dpm_table->flags |= SMU_DPM_TABLE_FINE_GRAINED; 428 429 } else { 429 430 dpm_table->count = 1; 430 431 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
+1
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
··· 1129 1129 /* gfxclk dpm table setup */ 1130 1130 dpm_table = &dpm_context->dpm_tables.gfx_table; 1131 1131 dpm_table->clk_type = SMU_GFXCLK; 1132 + dpm_table->flags = SMU_DPM_TABLE_FINE_GRAINED; 1132 1133 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) { 1133 1134 /* In the case of gfxclk, only fine-grained dpm is honored. 1134 1135 * Get min/max values from FW.
+1 -1
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
··· 1370 1370 level_index = 1; 1371 1371 } 1372 1372 1373 - if (!is_fine_grained) { 1373 + if (!is_fine_grained || count == 1) { 1374 1374 for (i = 0; i < count; i++) { 1375 1375 freq_match = !is_deep_sleep && 1376 1376 smu_cmn_freqs_match(
+1 -1
drivers/gpu/drm/drm_color_mgmt.c
··· 831 831 } 832 832 833 833 /** 834 - * drm_crtc_fill_palette_332 - Programs a default palette for R332-like formats 834 + * drm_crtc_fill_palette_332 - Programs a default palette for RGB332-like formats 835 835 * @crtc: The displaying CRTC 836 836 * @set_palette: Callback for programming the hardware gamma LUT 837 837 *
+2 -2
drivers/gpu/drm/drm_gem_framebuffer_helper.c
··· 172 172 } 173 173 174 174 for (i = 0; i < info->num_planes; i++) { 175 - unsigned int width = mode_cmd->width / (i ? info->hsub : 1); 176 - unsigned int height = mode_cmd->height / (i ? info->vsub : 1); 175 + unsigned int width = drm_format_info_plane_width(info, mode_cmd->width, i); 176 + unsigned int height = drm_format_info_plane_height(info, mode_cmd->height, i); 177 177 unsigned int min_size; 178 178 179 179 objs[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
+1 -1
drivers/gpu/drm/imagination/pvr_fw_trace.c
··· 558 558 &pvr_fw_trace_fops); 559 559 } 560 560 561 - debugfs_create_file("trace_mask", 0600, dir, fw_trace, 561 + debugfs_create_file("trace_mask", 0600, dir, pvr_dev, 562 562 &pvr_fw_trace_mask_fops); 563 563 }
+2
drivers/gpu/drm/sysfb/ofdrm.c
··· 350 350 struct pci_dev *pcidev = data; 351 351 352 352 pci_disable_device(pcidev); 353 + pci_dev_put(pcidev); 353 354 } 354 355 355 356 static int ofdrm_device_init_pci(struct ofdrm_device *odev) ··· 376 375 if (ret) { 377 376 drm_err(dev, "pci_enable_device(%s) failed: %d\n", 378 377 dev_name(&pcidev->dev), ret); 378 + pci_dev_put(pcidev); 379 379 return ret; 380 380 } 381 381 ret = devm_add_action_or_reset(&pdev->dev, ofdrm_pci_release, pcidev);
+2 -2
drivers/gpu/drm/tiny/appletbdrm.c
··· 353 353 frames_size + 354 354 sizeof(struct appletbdrm_fb_request_footer), 16); 355 355 356 - appletbdrm_state->request = kzalloc(request_size, GFP_KERNEL); 356 + appletbdrm_state->request = kvzalloc(request_size, GFP_KERNEL); 357 357 358 358 if (!appletbdrm_state->request) 359 359 return -ENOMEM; ··· 543 543 { 544 544 struct appletbdrm_plane_state *appletbdrm_state = to_appletbdrm_plane_state(state); 545 545 546 - kfree(appletbdrm_state->request); 546 + kvfree(appletbdrm_state->request); 547 547 kfree(appletbdrm_state->response); 548 548 549 549 __drm_gem_destroy_shadow_plane_state(&appletbdrm_state->base);
+1 -2
drivers/gpu/drm/udl/udl_main.c
··· 285 285 return unode->urb; 286 286 } 287 287 288 - #define GET_URB_TIMEOUT HZ 289 288 struct urb *udl_get_urb(struct udl_device *udl) 290 289 { 291 290 struct urb *urb; 292 291 293 292 spin_lock_irq(&udl->urbs.lock); 294 - urb = udl_get_urb_locked(udl, GET_URB_TIMEOUT); 293 + urb = udl_get_urb_locked(udl, HZ * 2); 295 294 spin_unlock_irq(&udl->urbs.lock); 296 295 return urb; 297 296 }
+4 -1
drivers/gpu/drm/udl/udl_modeset.c
··· 21 21 #include <drm/drm_gem_framebuffer_helper.h> 22 22 #include <drm/drm_gem_shmem_helper.h> 23 23 #include <drm/drm_modeset_helper_vtables.h> 24 + #include <drm/drm_print.h> 24 25 #include <drm/drm_probe_helper.h> 25 26 #include <drm/drm_vblank.h> 26 27 ··· 343 342 return; 344 343 345 344 urb = udl_get_urb(udl); 346 - if (!urb) 345 + if (!urb) { 346 + drm_err_ratelimited(dev, "get urb failed when enabling crtc\n"); 347 347 goto out; 348 + } 348 349 349 350 buf = (char *)urb->transfer_buffer; 350 351 buf = udl_vidreg_lock(buf);
+1
drivers/gpu/drm/xe/Makefile
··· 88 88 xe_irq.o \ 89 89 xe_late_bind_fw.o \ 90 90 xe_lrc.o \ 91 + xe_mem_pool.o \ 91 92 xe_migrate.o \ 92 93 xe_mmio.o \ 93 94 xe_mmio_gem.o \
+1 -1
drivers/gpu/drm/xe/regs/xe_gt_regs.h
··· 583 583 #define DISABLE_128B_EVICTION_COMMAND_UDW REG_BIT(36 - 32) 584 584 #define LSCFE_SAME_ADDRESS_ATOMICS_COALESCING_DISABLE REG_BIT(35 - 32) 585 585 586 - #define ROW_CHICKEN5 XE_REG_MCR(0xe7f0) 586 + #define ROW_CHICKEN5 XE_REG_MCR(0xe7f0, XE_REG_OPTION_MASKED) 587 587 #define CPSS_AWARE_DIS REG_BIT(3) 588 588 589 589 #define SARB_CHICKEN1 XE_REG_MCR(0xe90c)
+6 -2
drivers/gpu/drm/xe/xe_bo.c
··· 2322 2322 } 2323 2323 2324 2324 /* XE_BO_FLAG_GGTTx requires XE_BO_FLAG_GGTT also be set */ 2325 - if ((flags & XE_BO_FLAG_GGTT_ALL) && !(flags & XE_BO_FLAG_GGTT)) 2325 + if ((flags & XE_BO_FLAG_GGTT_ALL) && !(flags & XE_BO_FLAG_GGTT)) { 2326 + xe_bo_free(bo); 2326 2327 return ERR_PTR(-EINVAL); 2328 + } 2327 2329 2328 2330 if (flags & (XE_BO_FLAG_VRAM_MASK | XE_BO_FLAG_STOLEN) && 2329 2331 !(flags & XE_BO_FLAG_IGNORE_MIN_PAGE_SIZE) && ··· 2344 2342 alignment = SZ_4K >> PAGE_SHIFT; 2345 2343 } 2346 2344 2347 - if (type == ttm_bo_type_device && aligned_size != size) 2345 + if (type == ttm_bo_type_device && aligned_size != size) { 2346 + xe_bo_free(bo); 2348 2347 return ERR_PTR(-EINVAL); 2348 + } 2349 2349 2350 2350 if (!bo) { 2351 2351 bo = xe_bo_alloc();
+2 -1
drivers/gpu/drm/xe/xe_bo_types.h
··· 18 18 #include "xe_ggtt_types.h" 19 19 20 20 struct xe_device; 21 + struct xe_mem_pool_node; 21 22 struct xe_vm; 22 23 23 24 #define XE_BO_MAX_PLACEMENTS 3 ··· 89 88 bool ccs_cleared; 90 89 91 90 /** @bb_ccs: BB instructions of CCS read/write. Valid only for VF */ 92 - struct xe_bb *bb_ccs[XE_SRIOV_VF_CCS_CTX_COUNT]; 91 + struct xe_mem_pool_node *bb_ccs[XE_SRIOV_VF_CCS_CTX_COUNT]; 93 92 94 93 /** 95 94 * @cpu_caching: CPU caching mode. Currently only used for userspace
+18 -5
drivers/gpu/drm/xe/xe_dma_buf.c
··· 258 258 return ERR_PTR(ret); 259 259 } 260 260 261 + /* 262 + * Takes ownership of @storage: on success it is transferred to the returned 263 + * drm_gem_object; on failure it is freed before returning the error. 264 + * This matches the contract of xe_bo_init_locked() which frees @storage on 265 + * its error paths, so callers need not (and must not) free @storage after 266 + * this call. 267 + */ 261 268 static struct drm_gem_object * 262 269 xe_dma_buf_init_obj(struct drm_device *dev, struct xe_bo *storage, 263 270 struct dma_buf *dma_buf) ··· 278 271 int ret = 0; 279 272 280 273 dummy_obj = drm_gpuvm_resv_object_alloc(&xe->drm); 281 - if (!dummy_obj) 274 + if (!dummy_obj) { 275 + xe_bo_free(storage); 282 276 return ERR_PTR(-ENOMEM); 277 + } 283 278 284 279 dummy_obj->resv = resv; 285 280 xe_validation_guard(&ctx, &xe->val, &exec, (struct xe_val_flags) {}, ret) { ··· 290 281 if (ret) 291 282 break; 292 283 284 + /* xe_bo_init_locked() frees storage on error */ 293 285 bo = xe_bo_init_locked(xe, storage, NULL, resv, NULL, dma_buf->size, 294 286 0, /* Will require 1way or 2way for vm_bind */ 295 287 ttm_bo_type_sg, XE_BO_FLAG_SYSTEM, &exec); ··· 378 368 goto out_err; 379 369 } 380 370 381 - /* Errors here will take care of freeing the bo. */ 371 + /* 372 + * xe_dma_buf_init_obj() takes ownership of bo on both success 373 + * and failure, so we must not touch bo after this call. 374 + */ 382 375 obj = xe_dma_buf_init_obj(dev, bo, dma_buf); 383 - if (IS_ERR(obj)) 376 + if (IS_ERR(obj)) { 377 + dma_buf_detach(dma_buf, attach); 384 378 return obj; 385 - 386 - 379 + } 387 380 get_dma_buf(dma_buf); 388 381 obj->import_attach = attach; 389 382 return obj;
+2 -2
drivers/gpu/drm/xe/xe_eu_stall.c
··· 869 869 struct xe_eu_stall_data_stream *stream = file->private_data; 870 870 struct xe_gt *gt = stream->gt; 871 871 872 - drm_dev_put(&gt->tile->xe->drm); 873 - 874 872 mutex_lock(&gt->eu_stall->stream_lock); 875 873 xe_eu_stall_disable_locked(stream); 876 874 xe_eu_stall_data_buf_destroy(stream); 877 875 xe_eu_stall_stream_free(stream); 878 876 mutex_unlock(&gt->eu_stall->stream_lock); 877 + 878 + drm_dev_put(&gt->tile->xe->drm); 879 879 880 880 return 0; 881 881 }
+6 -3
drivers/gpu/drm/xe/xe_exec_queue.c
··· 1405 1405 if (q->vm && q->hwe->hw_engine_group) { 1406 1406 err = xe_hw_engine_group_add_exec_queue(q->hwe->hw_engine_group, q); 1407 1407 if (err) 1408 - goto put_exec_queue; 1408 + goto kill_exec_queue; 1409 1409 } 1410 1410 } 1411 1411 ··· 1416 1416 /* user id alloc must always be last in ioctl to prevent UAF */ 1417 1417 err = xa_alloc(&xef->exec_queue.xa, &id, q, xa_limit_32b, GFP_KERNEL); 1418 1418 if (err) 1419 - goto kill_exec_queue; 1419 + goto del_hw_engine_group; 1420 1420 1421 1421 args->exec_queue_id = id; 1422 1422 1423 1423 return 0; 1424 1424 1425 + del_hw_engine_group: 1426 + if (q->vm && q->hwe && q->hwe->hw_engine_group) 1427 + xe_hw_engine_group_del_exec_queue(q->hwe->hw_engine_group, q); 1425 1428 kill_exec_queue: 1426 1429 xe_exec_queue_kill(q); 1427 1430 delete_queue_group: ··· 1763 1760 void xe_exec_queue_tlb_inval_last_fence_put_unlocked(struct xe_exec_queue *q, 1764 1761 unsigned int type) 1765 1762 { 1766 - xe_assert(q->vm->xe, type == XE_EXEC_QUEUE_TLB_INVAL_MEDIA_GT || 1763 + xe_assert(gt_to_xe(q->gt), type == XE_EXEC_QUEUE_TLB_INVAL_MEDIA_GT || 1767 1764 type == XE_EXEC_QUEUE_TLB_INVAL_PRIMARY_GT); 1768 1765 1769 1766 dma_fence_put(q->tlb_inval[type].last_fence);
+1 -1
drivers/gpu/drm/xe/xe_gsc.c
··· 166 166 &rd_offset); 167 167 if (err) { 168 168 xe_gt_err(gt, "HuC: invalid GSC reply for version query (err=%d)\n", err); 169 - return err; 169 + goto out_bo; 170 170 } 171 171 172 172 compat->major = version_query_rd(xe, &bo->vmap, rd_offset, proj_major);
+9 -24
drivers/gpu/drm/xe/xe_guc_submit.c
··· 261 261 static void guc_submit_fini(void *arg) 262 262 { 263 263 struct xe_guc *guc = arg; 264 - 265 - /* Forcefully kill any remaining exec queues */ 266 - xe_guc_ct_stop(&guc->ct); 267 - guc_submit_reset_prepare(guc); 268 - xe_guc_softreset(guc); 269 - xe_guc_submit_stop(guc); 270 - xe_uc_fw_sanitize(&guc->fw); 271 - xe_guc_submit_pause_abort(guc); 272 - } 273 - 274 - static void guc_submit_wedged_fini(void *arg) 275 - { 276 - struct xe_guc *guc = arg; 277 264 struct xe_exec_queue *q; 278 265 unsigned long index; 279 266 267 + /* Drop any wedged queue refs */ 280 268 mutex_lock(&guc->submission_state.lock); 281 269 xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) { 282 270 if (exec_queue_wedged(q)) { ··· 274 286 } 275 287 } 276 288 mutex_unlock(&guc->submission_state.lock); 289 + 290 + /* Forcefully kill any remaining exec queues */ 291 + xe_guc_ct_stop(&guc->ct); 292 + guc_submit_reset_prepare(guc); 293 + xe_guc_softreset(guc); 294 + xe_guc_submit_stop(guc); 295 + xe_uc_fw_sanitize(&guc->fw); 296 + xe_guc_submit_pause_abort(guc); 277 297 } 278 298 279 299 static const struct xe_exec_queue_ops guc_exec_queue_ops; ··· 1316 1320 void xe_guc_submit_wedge(struct xe_guc *guc) 1317 1321 { 1318 1322 struct xe_device *xe = guc_to_xe(guc); 1319 - struct xe_gt *gt = guc_to_gt(guc); 1320 1323 struct xe_exec_queue *q; 1321 1324 unsigned long index; 1322 - int err; 1323 1325 1324 1326 xe_gt_assert(guc_to_gt(guc), guc_to_xe(guc)->wedged.mode); 1325 1327 ··· 1329 1335 return; 1330 1336 1331 1337 if (xe->wedged.mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET) { 1332 - err = devm_add_action_or_reset(guc_to_xe(guc)->drm.dev, 1333 - guc_submit_wedged_fini, guc); 1334 - if (err) { 1335 - xe_gt_err(gt, "Failed to register clean-up on wedged.mode=%s; " 1336 - "Although device is wedged.\n", 1337 - xe_wedged_mode_to_string(XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET)); 1338 - return; 1339 - } 1340 - 1341 1338 mutex_lock(&guc->submission_state.lock); 1342 1339 xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) 1343 1340 if (xe_exec_queue_get_unless_zero(q))
+1 -1
drivers/gpu/drm/xe/xe_lrc.c
··· 1214 1214 if (xe_gt_WARN_ON(lrc->gt, max_len < 3)) 1215 1215 return -ENOSPC; 1216 1216 1217 - *cmd++ = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(1); 1217 + *cmd++ = MI_LOAD_REGISTER_IMM | MI_LRI_LRM_CS_MMIO | MI_LRI_NUM_REGS(1); 1218 1218 *cmd++ = CS_DEBUG_MODE2(0).addr; 1219 1219 *cmd++ = REG_MASKED_FIELD_ENABLE(INSTRUCTION_STATE_CACHE_INVALIDATE); 1220 1220
+403
drivers/gpu/drm/xe/xe_mem_pool.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2026 Intel Corporation 4 + */ 5 + 6 + #include <linux/kernel.h> 7 + 8 + #include <drm/drm_managed.h> 9 + 10 + #include "instructions/xe_mi_commands.h" 11 + #include "xe_bo.h" 12 + #include "xe_device_types.h" 13 + #include "xe_map.h" 14 + #include "xe_mem_pool.h" 15 + #include "xe_mem_pool_types.h" 16 + #include "xe_tile_printk.h" 17 + 18 + /** 19 + * struct xe_mem_pool - DRM MM pool for sub-allocating memory from a BO on an 20 + * XE tile. 21 + * 22 + * The XE memory pool is a DRM MM manager that provides sub-allocation of memory 23 + * from a backing buffer object (BO) on a specific XE tile. It is designed to 24 + * manage memory for GPU workloads, allowing for efficient allocation and 25 + * deallocation of memory regions within the BO. 26 + * 27 + * The memory pool maintains a primary BO that is pinned in the GGTT and mapped 28 + * into the CPU address space for direct access. Optionally, it can also maintain 29 + * a shadow BO that can be used for atomic updates to the primary BO's contents. 30 + * 31 + * The API provided by the memory pool allows clients to allocate and free memory 32 + * regions, retrieve GPU and CPU addresses, and synchronize data between the 33 + * primary and shadow BOs as needed. 34 + */ 35 + struct xe_mem_pool { 36 + /** @base: Range allocator over [0, @size) in bytes */ 37 + struct drm_mm base; 38 + /** @bo: Active pool BO (GGTT-pinned, CPU-mapped). */ 39 + struct xe_bo *bo; 40 + /** @shadow: Shadow BO for atomic command updates. */ 41 + struct xe_bo *shadow; 42 + /** @swap_guard: Timeline guard updating @bo and @shadow */ 43 + struct mutex swap_guard; 44 + /** @cpu_addr: CPU virtual address of the active BO. */ 45 + void *cpu_addr; 46 + /** @is_iomem: Indicates if the BO mapping is I/O memory. */ 47 + bool is_iomem; 48 + }; 49 + 50 + static struct xe_mem_pool *node_to_pool(struct xe_mem_pool_node *node) 51 + { 52 + return container_of(node->sa_node.mm, struct xe_mem_pool, base); 53 + } 54 + 55 + static struct xe_tile *pool_to_tile(struct xe_mem_pool *pool) 56 + { 57 + return pool->bo->tile; 58 + } 59 + 60 + static void fini_pool_action(struct drm_device *drm, void *arg) 61 + { 62 + struct xe_mem_pool *pool = arg; 63 + 64 + if (pool->is_iomem) 65 + kvfree(pool->cpu_addr); 66 + 67 + drm_mm_takedown(&pool->base); 68 + } 69 + 70 + static int pool_shadow_init(struct xe_mem_pool *pool) 71 + { 72 + struct xe_tile *tile = pool->bo->tile; 73 + struct xe_device *xe = tile_to_xe(tile); 74 + struct xe_bo *shadow; 75 + int ret; 76 + 77 + xe_assert(xe, !pool->shadow); 78 + 79 + ret = drmm_mutex_init(&xe->drm, &pool->swap_guard); 80 + if (ret) 81 + return ret; 82 + 83 + if (IS_ENABLED(CONFIG_PROVE_LOCKING)) { 84 + fs_reclaim_acquire(GFP_KERNEL); 85 + might_lock(&pool->swap_guard); 86 + fs_reclaim_release(GFP_KERNEL); 87 + } 88 + shadow = xe_managed_bo_create_pin_map(xe, tile, 89 + xe_bo_size(pool->bo), 90 + XE_BO_FLAG_VRAM_IF_DGFX(tile) | 91 + XE_BO_FLAG_GGTT | 92 + XE_BO_FLAG_GGTT_INVALIDATE | 93 + XE_BO_FLAG_PINNED_NORESTORE); 94 + if (IS_ERR(shadow)) 95 + return PTR_ERR(shadow); 96 + 97 + pool->shadow = shadow; 98 + 99 + return 0; 100 + } 101 + 102 + /** 103 + * xe_mem_pool_init() - Initialize memory pool. 104 + * @tile: the &xe_tile where allocate. 105 + * @size: number of bytes to allocate. 106 + * @guard: the size of the guard region at the end of the BO that is not 107 + * sub-allocated, in bytes. 108 + * @flags: flags to use to create shadow pool. 109 + * 110 + * Initializes a memory pool for sub-allocating memory from a backing BO on the 111 + * specified XE tile. The backing BO is pinned in the GGTT and mapped into 112 + * the CPU address space for direct access. Optionally, a shadow BO can also be 113 + * initialized for atomic updates to the primary BO's contents. 114 + * 115 + * Returns: a pointer to the &xe_mem_pool, or an error pointer on failure. 116 + */ 117 + struct xe_mem_pool *xe_mem_pool_init(struct xe_tile *tile, u32 size, 118 + u32 guard, int flags) 119 + { 120 + struct xe_device *xe = tile_to_xe(tile); 121 + struct xe_mem_pool *pool; 122 + struct xe_bo *bo; 123 + u32 managed_size; 124 + int ret; 125 + 126 + xe_tile_assert(tile, size > guard); 127 + managed_size = size - guard; 128 + 129 + pool = drmm_kzalloc(&xe->drm, sizeof(*pool), GFP_KERNEL); 130 + if (!pool) 131 + return ERR_PTR(-ENOMEM); 132 + 133 + bo = xe_managed_bo_create_pin_map(xe, tile, size, 134 + XE_BO_FLAG_VRAM_IF_DGFX(tile) | 135 + XE_BO_FLAG_GGTT | 136 + XE_BO_FLAG_GGTT_INVALIDATE | 137 + XE_BO_FLAG_PINNED_NORESTORE); 138 + if (IS_ERR(bo)) { 139 + xe_tile_err(tile, "Failed to prepare %uKiB BO for mem pool (%pe)\n", 140 + size / SZ_1K, bo); 141 + return ERR_CAST(bo); 142 + } 143 + pool->bo = bo; 144 + pool->is_iomem = bo->vmap.is_iomem; 145 + 146 + if (pool->is_iomem) { 147 + pool->cpu_addr = kvzalloc(size, GFP_KERNEL); 148 + if (!pool->cpu_addr) 149 + return ERR_PTR(-ENOMEM); 150 + } else { 151 + pool->cpu_addr = bo->vmap.vaddr; 152 + } 153 + 154 + if (flags & XE_MEM_POOL_BO_FLAG_INIT_SHADOW_COPY) { 155 + ret = pool_shadow_init(pool); 156 + 157 + if (ret) 158 + goto out_err; 159 + } 160 + 161 + drm_mm_init(&pool->base, 0, managed_size); 162 + ret = drmm_add_action_or_reset(&xe->drm, fini_pool_action, pool); 163 + if (ret) 164 + return ERR_PTR(ret); 165 + 166 + return pool; 167 + 168 + out_err: 169 + if (flags & XE_MEM_POOL_BO_FLAG_INIT_SHADOW_COPY) 170 + xe_tile_err(tile, 171 + "Failed to initialize shadow BO for mem pool (%d)\n", ret); 172 + if (bo->vmap.is_iomem) 173 + kvfree(pool->cpu_addr); 174 + return ERR_PTR(ret); 175 + } 176 + 177 + /** 178 + * xe_mem_pool_sync() - Copy the entire contents of the main pool to shadow pool. 179 + * @pool: the memory pool containing the primary and shadow BOs. 180 + * 181 + * Copies the entire contents of the primary pool to the shadow pool. This must 182 + * be done after xe_mem_pool_init() with the XE_MEM_POOL_BO_FLAG_INIT_SHADOW_COPY 183 + * flag to ensure that the shadow pool has the same initial contents as the primary 184 + * pool. After this initial synchronization, clients can choose to synchronize the 185 + * shadow pool with the primary pool on a node basis using 186 + * xe_mem_pool_sync_shadow_locked() as needed. 187 + * 188 + * Return: None. 189 + */ 190 + void xe_mem_pool_sync(struct xe_mem_pool *pool) 191 + { 192 + struct xe_tile *tile = pool_to_tile(pool); 193 + struct xe_device *xe = tile_to_xe(tile); 194 + 195 + xe_tile_assert(tile, pool->shadow); 196 + 197 + xe_map_memcpy_to(xe, &pool->shadow->vmap, 0, 198 + pool->cpu_addr, xe_bo_size(pool->bo)); 199 + } 200 + 201 + /** 202 + * xe_mem_pool_swap_shadow_locked() - Swap the primary BO with the shadow BO. 203 + * @pool: the memory pool containing the primary and shadow BOs. 204 + * 205 + * Swaps the primary buffer object with the shadow buffer object in the mem 206 + * pool. This allows for atomic updates to the contents of the primary BO 207 + * by first writing to the shadow BO and then swapping it with the primary BO. 208 + * Swap_guard must be held to ensure synchronization with any concurrent swap 209 + * operations. 210 + * 211 + * Return: None. 212 + */ 213 + void xe_mem_pool_swap_shadow_locked(struct xe_mem_pool *pool) 214 + { 215 + struct xe_tile *tile = pool_to_tile(pool); 216 + 217 + xe_tile_assert(tile, pool->shadow); 218 + lockdep_assert_held(&pool->swap_guard); 219 + 220 + swap(pool->bo, pool->shadow); 221 + if (!pool->bo->vmap.is_iomem) 222 + pool->cpu_addr = pool->bo->vmap.vaddr; 223 + } 224 + 225 + /** 226 + * xe_mem_pool_sync_shadow_locked() - Copy node from primary pool to shadow pool. 227 + * @node: the node allocated in the memory pool. 228 + * 229 + * Copies the specified batch buffer from the primary pool to the shadow pool. 230 + * Swap_guard must be held to ensure synchronization with any concurrent swap 231 + * operations. 232 + * 233 + * Return: None. 234 + */ 235 + void xe_mem_pool_sync_shadow_locked(struct xe_mem_pool_node *node) 236 + { 237 + struct xe_mem_pool *pool = node_to_pool(node); 238 + struct xe_tile *tile = pool_to_tile(pool); 239 + struct xe_device *xe = tile_to_xe(tile); 240 + struct drm_mm_node *sa_node = &node->sa_node; 241 + 242 + xe_tile_assert(tile, pool->shadow); 243 + lockdep_assert_held(&pool->swap_guard); 244 + 245 + xe_map_memcpy_to(xe, &pool->shadow->vmap, 246 + sa_node->start, 247 + pool->cpu_addr + sa_node->start, 248 + sa_node->size); 249 + } 250 + 251 + /** 252 + * xe_mem_pool_gpu_addr() - Retrieve GPU address of memory pool. 253 + * @pool: the memory pool 254 + * 255 + * Returns: GGTT address of the memory pool. 256 + */ 257 + u64 xe_mem_pool_gpu_addr(struct xe_mem_pool *pool) 258 + { 259 + return xe_bo_ggtt_addr(pool->bo); 260 + } 261 + 262 + /** 263 + * xe_mem_pool_cpu_addr() - Retrieve CPU address of manager pool. 264 + * @pool: the memory pool 265 + * 266 + * Returns: CPU virtual address of memory pool. 267 + */ 268 + void *xe_mem_pool_cpu_addr(struct xe_mem_pool *pool) 269 + { 270 + return pool->cpu_addr; 271 + } 272 + 273 + /** 274 + * xe_mem_pool_bo_swap_guard() - Retrieve the mutex used to guard swap 275 + * operations on a memory pool. 276 + * @pool: the memory pool 277 + * 278 + * Returns: Swap guard mutex or NULL if shadow pool is not created. 279 + */ 280 + struct mutex *xe_mem_pool_bo_swap_guard(struct xe_mem_pool *pool) 281 + { 282 + if (!pool->shadow) 283 + return NULL; 284 + 285 + return &pool->swap_guard; 286 + } 287 + 288 + /** 289 + * xe_mem_pool_bo_flush_write() - Copy the data from the sub-allocation 290 + * to the GPU memory. 291 + * @node: the node allocated in the memory pool to flush. 292 + */ 293 + void xe_mem_pool_bo_flush_write(struct xe_mem_pool_node *node) 294 + { 295 + struct xe_mem_pool *pool = node_to_pool(node); 296 + struct xe_tile *tile = pool_to_tile(pool); 297 + struct xe_device *xe = tile_to_xe(tile); 298 + struct drm_mm_node *sa_node = &node->sa_node; 299 + 300 + if (!pool->bo->vmap.is_iomem) 301 + return; 302 + 303 + xe_map_memcpy_to(xe, &pool->bo->vmap, sa_node->start, 304 + pool->cpu_addr + sa_node->start, 305 + sa_node->size); 306 + } 307 + 308 + /** 309 + * xe_mem_pool_bo_sync_read() - Copy the data from GPU memory to the 310 + * sub-allocation. 311 + * @node: the node allocated in the memory pool to read back. 312 + */ 313 + void xe_mem_pool_bo_sync_read(struct xe_mem_pool_node *node) 314 + { 315 + struct xe_mem_pool *pool = node_to_pool(node); 316 + struct xe_tile *tile = pool_to_tile(pool); 317 + struct xe_device *xe = tile_to_xe(tile); 318 + struct drm_mm_node *sa_node = &node->sa_node; 319 + 320 + if (!pool->bo->vmap.is_iomem) 321 + return; 322 + 323 + xe_map_memcpy_from(xe, pool->cpu_addr + sa_node->start, 324 + &pool->bo->vmap, sa_node->start, sa_node->size); 325 + } 326 + 327 + /** 328 + * xe_mem_pool_alloc_node() - Allocate a new node for use with xe_mem_pool. 329 + * 330 + * Returns: node structure or an ERR_PTR(-ENOMEM). 331 + */ 332 + struct xe_mem_pool_node *xe_mem_pool_alloc_node(void) 333 + { 334 + struct xe_mem_pool_node *node = kzalloc_obj(*node); 335 + 336 + if (!node) 337 + return ERR_PTR(-ENOMEM); 338 + 339 + return node; 340 + } 341 + 342 + /** 343 + * xe_mem_pool_insert_node() - Insert a node into the memory pool. 344 + * @pool: the memory pool to insert into 345 + * @node: the node to insert 346 + * @size: the size of the node to be allocated in bytes. 347 + * 348 + * Inserts a node into the specified memory pool using drm_mm for 349 + * allocation. 350 + * 351 + * Returns: 0 on success or a negative error code on failure. 352 + */ 353 + int xe_mem_pool_insert_node(struct xe_mem_pool *pool, 354 + struct xe_mem_pool_node *node, u32 size) 355 + { 356 + if (!pool) 357 + return -EINVAL; 358 + 359 + return drm_mm_insert_node(&pool->base, &node->sa_node, size); 360 + } 361 + 362 + /** 363 + * xe_mem_pool_free_node() - Free a node allocated from the memory pool. 364 + * @node: the node to free 365 + * 366 + * Returns: None. 367 + */ 368 + void xe_mem_pool_free_node(struct xe_mem_pool_node *node) 369 + { 370 + if (!node) 371 + return; 372 + 373 + drm_mm_remove_node(&node->sa_node); 374 + kfree(node); 375 + } 376 + 377 + /** 378 + * xe_mem_pool_node_cpu_addr() - Retrieve CPU address of the node. 379 + * @node: the node allocated in the memory pool 380 + * 381 + * Returns: CPU virtual address of the node. 382 + */ 383 + void *xe_mem_pool_node_cpu_addr(struct xe_mem_pool_node *node) 384 + { 385 + struct xe_mem_pool *pool = node_to_pool(node); 386 + 387 + return xe_mem_pool_cpu_addr(pool) + node->sa_node.start; 388 + } 389 + 390 + /** 391 + * xe_mem_pool_dump() - Dump the state of the DRM MM manager for debugging. 392 + * @pool: the memory pool info be dumped. 393 + * @p: The DRM printer to use for output. 394 + * 395 + * Only the drm managed region is dumped, not the state of the BOs or any other 396 + * pool information. 397 + * 398 + * Returns: None. 399 + */ 400 + void xe_mem_pool_dump(struct xe_mem_pool *pool, struct drm_printer *p) 401 + { 402 + drm_mm_print(&pool->base, p); 403 + }
+35
drivers/gpu/drm/xe/xe_mem_pool.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright © 2026 Intel Corporation 4 + */ 5 + #ifndef _XE_MEM_POOL_H_ 6 + #define _XE_MEM_POOL_H_ 7 + 8 + #include <linux/sizes.h> 9 + #include <linux/types.h> 10 + 11 + #include <drm/drm_mm.h> 12 + #include "xe_mem_pool_types.h" 13 + 14 + struct drm_printer; 15 + struct xe_mem_pool; 16 + struct xe_tile; 17 + 18 + struct xe_mem_pool *xe_mem_pool_init(struct xe_tile *tile, u32 size, 19 + u32 guard, int flags); 20 + void xe_mem_pool_sync(struct xe_mem_pool *pool); 21 + void xe_mem_pool_swap_shadow_locked(struct xe_mem_pool *pool); 22 + void xe_mem_pool_sync_shadow_locked(struct xe_mem_pool_node *node); 23 + u64 xe_mem_pool_gpu_addr(struct xe_mem_pool *pool); 24 + void *xe_mem_pool_cpu_addr(struct xe_mem_pool *pool); 25 + struct mutex *xe_mem_pool_bo_swap_guard(struct xe_mem_pool *pool); 26 + void xe_mem_pool_bo_flush_write(struct xe_mem_pool_node *node); 27 + void xe_mem_pool_bo_sync_read(struct xe_mem_pool_node *node); 28 + struct xe_mem_pool_node *xe_mem_pool_alloc_node(void); 29 + int xe_mem_pool_insert_node(struct xe_mem_pool *pool, 30 + struct xe_mem_pool_node *node, u32 size); 31 + void xe_mem_pool_free_node(struct xe_mem_pool_node *node); 32 + void *xe_mem_pool_node_cpu_addr(struct xe_mem_pool_node *node); 33 + void xe_mem_pool_dump(struct xe_mem_pool *pool, struct drm_printer *p); 34 + 35 + #endif
+21
drivers/gpu/drm/xe/xe_mem_pool_types.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright © 2026 Intel Corporation 4 + */ 5 + 6 + #ifndef _XE_MEM_POOL_TYPES_H_ 7 + #define _XE_MEM_POOL_TYPES_H_ 8 + 9 + #include <drm/drm_mm.h> 10 + 11 + #define XE_MEM_POOL_BO_FLAG_INIT_SHADOW_COPY BIT(0) 12 + 13 + /** 14 + * struct xe_mem_pool_node - Sub-range allocations from mem pool. 15 + */ 16 + struct xe_mem_pool_node { 17 + /** @sa_node: drm_mm_node for this allocation. */ 18 + struct drm_mm_node sa_node; 19 + }; 20 + 21 + #endif
+31 -25
drivers/gpu/drm/xe/xe_migrate.c
··· 29 29 #include "xe_hw_engine.h" 30 30 #include "xe_lrc.h" 31 31 #include "xe_map.h" 32 + #include "xe_mem_pool.h" 32 33 #include "xe_mocs.h" 33 34 #include "xe_printk.h" 34 35 #include "xe_pt.h" ··· 1167 1166 u32 batch_size, batch_size_allocated; 1168 1167 struct xe_device *xe = gt_to_xe(gt); 1169 1168 struct xe_res_cursor src_it, ccs_it; 1169 + struct xe_mem_pool *bb_pool; 1170 1170 struct xe_sriov_vf_ccs_ctx *ctx; 1171 - struct xe_sa_manager *bb_pool; 1172 1171 u64 size = xe_bo_size(src_bo); 1173 - struct xe_bb *bb = NULL; 1172 + struct xe_mem_pool_node *bb; 1174 1173 u64 src_L0, src_L0_ofs; 1174 + struct xe_bb xe_bb_tmp; 1175 1175 u32 src_L0_pt; 1176 1176 int err; 1177 1177 ··· 1210 1208 size -= src_L0; 1211 1209 } 1212 1210 1213 - bb = xe_bb_alloc(gt); 1211 + bb = xe_mem_pool_alloc_node(); 1214 1212 if (IS_ERR(bb)) 1215 1213 return PTR_ERR(bb); 1216 1214 1217 1215 bb_pool = ctx->mem.ccs_bb_pool; 1218 - scoped_guard(mutex, xe_sa_bo_swap_guard(bb_pool)) { 1219 - xe_sa_bo_swap_shadow(bb_pool); 1216 + scoped_guard(mutex, xe_mem_pool_bo_swap_guard(bb_pool)) { 1217 + xe_mem_pool_swap_shadow_locked(bb_pool); 1220 1218 1221 - err = xe_bb_init(bb, bb_pool, batch_size); 1219 + err = xe_mem_pool_insert_node(bb_pool, bb, batch_size * sizeof(u32)); 1222 1220 if (err) { 1223 1221 xe_gt_err(gt, "BB allocation failed.\n"); 1224 - xe_bb_free(bb, NULL); 1222 + kfree(bb); 1225 1223 return err; 1226 1224 } 1227 1225 ··· 1229 1227 size = xe_bo_size(src_bo); 1230 1228 batch_size = 0; 1231 1229 1230 + xe_bb_tmp = (struct xe_bb){ .cs = xe_mem_pool_node_cpu_addr(bb), .len = 0 }; 1232 1231 /* 1233 1232 * Emit PTE and copy commands here. 1234 1233 * The CCS copy command can only support limited size. If the size to be ··· 1258 1255 xe_assert(xe, IS_ALIGNED(ccs_it.start, PAGE_SIZE)); 1259 1256 batch_size += EMIT_COPY_CCS_DW; 1260 1257 1261 - emit_pte(m, bb, src_L0_pt, false, true, &src_it, src_L0, src); 1258 + emit_pte(m, &xe_bb_tmp, src_L0_pt, false, true, &src_it, src_L0, src); 1262 1259 1263 - emit_pte(m, bb, ccs_pt, false, false, &ccs_it, ccs_size, src); 1260 + emit_pte(m, &xe_bb_tmp, ccs_pt, false, false, &ccs_it, ccs_size, src); 1264 1261 1265 - bb->len = emit_flush_invalidate(bb->cs, bb->len, flush_flags); 1266 - flush_flags = xe_migrate_ccs_copy(m, bb, src_L0_ofs, src_is_pltt, 1262 + xe_bb_tmp.len = emit_flush_invalidate(xe_bb_tmp.cs, xe_bb_tmp.len, 1263 + flush_flags); 1264 + flush_flags = xe_migrate_ccs_copy(m, &xe_bb_tmp, src_L0_ofs, src_is_pltt, 1267 1265 src_L0_ofs, dst_is_pltt, 1268 1266 src_L0, ccs_ofs, true); 1269 - bb->len = emit_flush_invalidate(bb->cs, bb->len, flush_flags); 1267 + xe_bb_tmp.len = emit_flush_invalidate(xe_bb_tmp.cs, xe_bb_tmp.len, 1268 + flush_flags); 1270 1269 1271 1270 size -= src_L0; 1272 1271 } 1273 1272 1274 - xe_assert(xe, (batch_size_allocated == bb->len)); 1273 + xe_assert(xe, (batch_size_allocated == xe_bb_tmp.len)); 1274 + xe_assert(xe, bb->sa_node.size == xe_bb_tmp.len * sizeof(u32)); 1275 1275 src_bo->bb_ccs[read_write] = bb; 1276 1276 1277 1277 xe_sriov_vf_ccs_rw_update_bb_addr(ctx); 1278 - xe_sa_bo_sync_shadow(bb->bo); 1278 + xe_mem_pool_sync_shadow_locked(bb); 1279 1279 } 1280 1280 1281 1281 return 0; ··· 1303 1297 void xe_migrate_ccs_rw_copy_clear(struct xe_bo *src_bo, 1304 1298 enum xe_sriov_vf_ccs_rw_ctxs read_write) 1305 1299 { 1306 - struct xe_bb *bb = src_bo->bb_ccs[read_write]; 1300 + struct xe_mem_pool_node *bb = src_bo->bb_ccs[read_write]; 1307 1301 struct xe_device *xe = xe_bo_device(src_bo); 1302 + struct xe_mem_pool *bb_pool; 1308 1303 struct xe_sriov_vf_ccs_ctx *ctx; 1309 - struct xe_sa_manager *bb_pool; 1310 1304 u32 *cs; 1311 1305 1312 1306 xe_assert(xe, IS_SRIOV_VF(xe)); ··· 1314 1308 ctx = &xe->sriov.vf.ccs.contexts[read_write]; 1315 1309 bb_pool = ctx->mem.ccs_bb_pool; 1316 1310 1317 - guard(mutex) (xe_sa_bo_swap_guard(bb_pool)); 1318 - xe_sa_bo_swap_shadow(bb_pool); 1311 + scoped_guard(mutex, xe_mem_pool_bo_swap_guard(bb_pool)) { 1312 + xe_mem_pool_swap_shadow_locked(bb_pool); 1319 1313 1320 - cs = xe_sa_bo_cpu_addr(bb->bo); 1321 - memset(cs, MI_NOOP, bb->len * sizeof(u32)); 1322 - xe_sriov_vf_ccs_rw_update_bb_addr(ctx); 1314 + cs = xe_mem_pool_node_cpu_addr(bb); 1315 + memset(cs, MI_NOOP, bb->sa_node.size); 1316 + xe_sriov_vf_ccs_rw_update_bb_addr(ctx); 1323 1317 1324 - xe_sa_bo_sync_shadow(bb->bo); 1325 - 1326 - xe_bb_free(bb, NULL); 1327 - src_bo->bb_ccs[read_write] = NULL; 1318 + xe_mem_pool_sync_shadow_locked(bb); 1319 + xe_mem_pool_free_node(bb); 1320 + src_bo->bb_ccs[read_write] = NULL; 1321 + } 1328 1322 } 1329 1323 1330 1324 /**
+1
drivers/gpu/drm/xe/xe_pci.c
··· 118 118 119 119 static const struct xe_graphics_desc graphics_xe3p_lpg = { 120 120 XE2_GFX_FEATURES, 121 + .has_indirect_ring_state = 1, 121 122 .multi_queue_engine_class_mask = BIT(XE_ENGINE_CLASS_COPY) | BIT(XE_ENGINE_CLASS_COMPUTE), 122 123 .num_geometry_xecore_fuse_regs = 3, 123 124 .num_compute_xecore_fuse_regs = 3,
+1 -1
drivers/gpu/drm/xe/xe_reg_whitelist.c
··· 226 226 } 227 227 228 228 range_start = reg & REG_GENMASK(25, range_bit); 229 - range_end = range_start | REG_GENMASK(range_bit, 0); 229 + range_end = range_start | REG_GENMASK(range_bit - 1, 0); 230 230 231 231 switch (val & RING_FORCE_TO_NONPRIV_ACCESS_MASK) { 232 232 case RING_FORCE_TO_NONPRIV_ACCESS_RW:
+29 -25
drivers/gpu/drm/xe/xe_sriov_vf_ccs.c
··· 14 14 #include "xe_guc.h" 15 15 #include "xe_guc_submit.h" 16 16 #include "xe_lrc.h" 17 + #include "xe_mem_pool.h" 17 18 #include "xe_migrate.h" 18 19 #include "xe_pm.h" 19 - #include "xe_sa.h" 20 20 #include "xe_sriov_printk.h" 21 21 #include "xe_sriov_vf.h" 22 22 #include "xe_sriov_vf_ccs.h" ··· 141 141 142 142 static int alloc_bb_pool(struct xe_tile *tile, struct xe_sriov_vf_ccs_ctx *ctx) 143 143 { 144 + struct xe_mem_pool *pool; 144 145 struct xe_device *xe = tile_to_xe(tile); 145 - struct xe_sa_manager *sa_manager; 146 + u32 *pool_cpu_addr, *last_dw_addr; 146 147 u64 bb_pool_size; 147 - int offset, err; 148 + int err; 148 149 149 150 bb_pool_size = get_ccs_bb_pool_size(xe); 150 151 xe_sriov_info(xe, "Allocating %s CCS BB pool size = %lldMB\n", 151 152 ctx->ctx_id ? "Restore" : "Save", bb_pool_size / SZ_1M); 152 153 153 - sa_manager = __xe_sa_bo_manager_init(tile, bb_pool_size, SZ_4K, SZ_16, 154 - XE_SA_BO_MANAGER_FLAG_SHADOW); 155 - 156 - if (IS_ERR(sa_manager)) { 157 - xe_sriov_err(xe, "Suballocator init failed with error: %pe\n", 158 - sa_manager); 159 - err = PTR_ERR(sa_manager); 154 + pool = xe_mem_pool_init(tile, bb_pool_size, sizeof(u32), 155 + XE_MEM_POOL_BO_FLAG_INIT_SHADOW_COPY); 156 + if (IS_ERR(pool)) { 157 + xe_sriov_err(xe, "xe_mem_pool_init failed with error: %pe\n", 158 + pool); 159 + err = PTR_ERR(pool); 160 160 return err; 161 161 } 162 162 163 - offset = 0; 164 - xe_map_memset(xe, &sa_manager->bo->vmap, offset, MI_NOOP, 165 - bb_pool_size); 166 - xe_map_memset(xe, &sa_manager->shadow->vmap, offset, MI_NOOP, 167 - bb_pool_size); 163 + pool_cpu_addr = xe_mem_pool_cpu_addr(pool); 164 + memset(pool_cpu_addr, 0, bb_pool_size); 168 165 169 - offset = bb_pool_size - sizeof(u32); 170 - xe_map_wr(xe, &sa_manager->bo->vmap, offset, u32, MI_BATCH_BUFFER_END); 171 - xe_map_wr(xe, &sa_manager->shadow->vmap, offset, u32, MI_BATCH_BUFFER_END); 166 + last_dw_addr = pool_cpu_addr + (bb_pool_size / sizeof(u32)) - 1; 167 + *last_dw_addr = MI_BATCH_BUFFER_END; 172 168 173 - ctx->mem.ccs_bb_pool = sa_manager; 169 + /** 170 + * Sync the main copy and shadow copy so that the shadow copy is 171 + * replica of main copy. We sync only BBs after init part. So, we 172 + * need to make sure the main pool and shadow copy are in sync after 173 + * this point. This is needed as GuC may read the BB commands from 174 + * shadow copy. 175 + */ 176 + xe_mem_pool_sync(pool); 174 177 178 + ctx->mem.ccs_bb_pool = pool; 175 179 return 0; 176 180 } 177 181 178 182 static void ccs_rw_update_ring(struct xe_sriov_vf_ccs_ctx *ctx) 179 183 { 180 - u64 addr = xe_sa_manager_gpu_addr(ctx->mem.ccs_bb_pool); 184 + u64 addr = xe_mem_pool_gpu_addr(ctx->mem.ccs_bb_pool); 181 185 struct xe_lrc *lrc = xe_exec_queue_lrc(ctx->mig_q); 182 186 u32 dw[10], i = 0; 183 187 ··· 392 388 #define XE_SRIOV_VF_CCS_RW_BB_ADDR_OFFSET (2 * sizeof(u32)) 393 389 void xe_sriov_vf_ccs_rw_update_bb_addr(struct xe_sriov_vf_ccs_ctx *ctx) 394 390 { 395 - u64 addr = xe_sa_manager_gpu_addr(ctx->mem.ccs_bb_pool); 391 + u64 addr = xe_mem_pool_gpu_addr(ctx->mem.ccs_bb_pool); 396 392 struct xe_lrc *lrc = xe_exec_queue_lrc(ctx->mig_q); 397 393 struct xe_device *xe = gt_to_xe(ctx->mig_q->gt); 398 394 ··· 416 412 struct xe_device *xe = xe_bo_device(bo); 417 413 enum xe_sriov_vf_ccs_rw_ctxs ctx_id; 418 414 struct xe_sriov_vf_ccs_ctx *ctx; 415 + struct xe_mem_pool_node *bb; 419 416 struct xe_tile *tile; 420 - struct xe_bb *bb; 421 417 int err = 0; 422 418 423 419 xe_assert(xe, IS_VF_CCS_READY(xe)); ··· 449 445 { 450 446 struct xe_device *xe = xe_bo_device(bo); 451 447 enum xe_sriov_vf_ccs_rw_ctxs ctx_id; 452 - struct xe_bb *bb; 448 + struct xe_mem_pool_node *bb; 453 449 454 450 xe_assert(xe, IS_VF_CCS_READY(xe)); 455 451 ··· 475 471 */ 476 472 void xe_sriov_vf_ccs_print(struct xe_device *xe, struct drm_printer *p) 477 473 { 478 - struct xe_sa_manager *bb_pool; 479 474 enum xe_sriov_vf_ccs_rw_ctxs ctx_id; 475 + struct xe_mem_pool *bb_pool; 480 476 481 477 if (!IS_VF_CCS_READY(xe)) 482 478 return; ··· 489 485 490 486 drm_printf(p, "ccs %s bb suballoc info\n", ctx_id ? "write" : "read"); 491 487 drm_printf(p, "-------------------------\n"); 492 - drm_suballoc_dump_debug_info(&bb_pool->base, p, xe_sa_manager_gpu_addr(bb_pool)); 488 + xe_mem_pool_dump(bb_pool, p); 493 489 drm_puts(p, "\n"); 494 490 } 495 491 }
+1 -4
drivers/gpu/drm/xe/xe_sriov_vf_ccs_types.h
··· 17 17 XE_SRIOV_VF_CCS_CTX_COUNT 18 18 }; 19 19 20 - struct xe_migrate; 21 - struct xe_sa_manager; 22 - 23 20 /** 24 21 * struct xe_sriov_vf_ccs_ctx - VF CCS migration context data. 25 22 */ ··· 30 33 /** @mem: memory data */ 31 34 struct { 32 35 /** @mem.ccs_bb_pool: Pool from which batch buffers are allocated. */ 33 - struct xe_sa_manager *ccs_bb_pool; 36 + struct xe_mem_pool *ccs_bb_pool; 34 37 } mem; 35 38 }; 36 39
+1 -1
drivers/gpu/drm/xe/xe_tuning.c
··· 97 97 { XE_RTP_NAME("Tuning: Set STLB Bank Hash Mode to 4KB"), 98 98 XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3510, XE_RTP_END_VERSION_UNDEFINED), 99 99 IS_INTEGRATED), 100 - XE_RTP_ACTIONS(FIELD_SET(XEHP_GAMSTLB_CTRL, BANK_HASH_MODE, 100 + XE_RTP_ACTIONS(FIELD_SET(GAMSTLB_CTRL, BANK_HASH_MODE, 101 101 BANK_HASH_4KB_MODE)) 102 102 }, 103 103 };
+4 -1
drivers/gpu/drm/xe/xe_vm.c
··· 3658 3658 op == DRM_XE_VM_BIND_OP_MAP_USERPTR) || 3659 3659 XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE && 3660 3660 op == DRM_XE_VM_BIND_OP_MAP_USERPTR) || 3661 + XE_IOCTL_DBG(xe, !IS_DGFX(xe) && coh_mode == XE_COH_NONE && 3662 + is_cpu_addr_mirror) || 3661 3663 XE_IOCTL_DBG(xe, xe_device_is_l2_flush_optimized(xe) && 3662 3664 (op == DRM_XE_VM_BIND_OP_MAP_USERPTR || 3663 3665 is_cpu_addr_mirror) && ··· 4158 4156 int ret = 0; 4159 4157 4160 4158 if (XE_IOCTL_DBG(xe, (args->reserved[0] || args->reserved[1] || 4161 - args->reserved[2]))) 4159 + args->reserved[2] || args->extensions || 4160 + args->pad))) 4162 4161 return -EINVAL; 4163 4162 4164 4163 vm = xe_vm_lookup(xef, args->vm_id);
+47
drivers/gpu/drm/xe/xe_vm_madvise.c
··· 621 621 return 0; 622 622 } 623 623 624 + static bool check_pat_args_are_sane(struct xe_device *xe, 625 + struct xe_vmas_in_madvise_range *madvise_range, 626 + u16 pat_index) 627 + { 628 + u16 coh_mode = xe_pat_index_get_coh_mode(xe, pat_index); 629 + int i; 630 + 631 + /* 632 + * Using coh_none with CPU cached buffers is not allowed on iGPU. 633 + * On iGPU the GPU shares the LLC with the CPU, so with coh_none 634 + * the GPU bypasses CPU caches and reads directly from DRAM, 635 + * potentially seeing stale sensitive data from previously freed 636 + * pages. On dGPU this restriction does not apply, because the 637 + * platform does not provide a non-coherent system memory access 638 + * path that would violate the DMA coherency contract. 639 + */ 640 + if (coh_mode != XE_COH_NONE || IS_DGFX(xe)) 641 + return true; 642 + 643 + for (i = 0; i < madvise_range->num_vmas; i++) { 644 + struct xe_vma *vma = madvise_range->vmas[i]; 645 + struct xe_bo *bo = xe_vma_bo(vma); 646 + 647 + if (bo) { 648 + /* BO with WB caching + COH_NONE is not allowed */ 649 + if (XE_IOCTL_DBG(xe, bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB)) 650 + return false; 651 + /* Imported dma-buf without caching info, assume cached */ 652 + if (XE_IOCTL_DBG(xe, !bo->cpu_caching)) 653 + return false; 654 + } else if (XE_IOCTL_DBG(xe, xe_vma_is_cpu_addr_mirror(vma) || 655 + xe_vma_is_userptr(vma))) 656 + /* System memory (userptr/SVM) is always CPU cached */ 657 + return false; 658 + } 659 + 660 + return true; 661 + } 662 + 624 663 static bool check_bo_args_are_sane(struct xe_vm *vm, struct xe_vma **vmas, 625 664 int num_vmas, u32 atomic_val) 626 665 { ··· 786 747 (pat_index != 19 && coh_mode != XE_COH_2WAY))) { 787 748 err = -EINVAL; 788 749 goto madv_fini; 750 + } 751 + } 752 + 753 + if (args->type == DRM_XE_MEM_RANGE_ATTR_PAT) { 754 + if (!check_pat_args_are_sane(xe, &madvise_range, 755 + args->pat_index.val)) { 756 + err = -EINVAL; 757 + goto free_vmas; 789 758 } 790 759 } 791 760
-8
drivers/gpu/drm/xe/xe_wa.c
··· 743 743 XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), 744 744 XE_RTP_ACTIONS(SET(WM_CHICKEN3, HIZ_PLANE_COMPRESSION_DIS)) 745 745 }, 746 - { XE_RTP_NAME("14019988906"), 747 - XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), 748 - XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD)) 749 - }, 750 - { XE_RTP_NAME("14019877138"), 751 - XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), 752 - XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT)) 753 - }, 754 746 { XE_RTP_NAME("14021490052"), 755 747 XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), 756 748 XE_RTP_ACTIONS(SET(FF_MODE,
+6
include/drm/drm_fb_helper.h
··· 273 273 int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper); 274 274 bool drm_fb_helper_gem_is_fb(const struct drm_fb_helper *fb_helper, 275 275 const struct drm_gem_object *obj); 276 + #else 277 + static inline bool drm_fb_helper_gem_is_fb(const struct drm_fb_helper *fb_helper, 278 + const struct drm_gem_object *obj) 279 + { 280 + return false; 281 + } 276 282 #endif 277 283 278 284 #endif
+2 -2
include/linux/dma-buf.h
··· 322 322 * @vmapping_counter: 323 323 * 324 324 * Used internally to refcnt the vmaps returned by dma_buf_vmap(). 325 - * Protected by @lock. 325 + * Protected by @resv. 326 326 */ 327 327 unsigned vmapping_counter; 328 328 329 329 /** 330 330 * @vmap_ptr: 331 - * The current vmap ptr if @vmapping_counter > 0. Protected by @lock. 331 + * The current vmap ptr if @vmapping_counter > 0. Protected by @resv. 332 332 */ 333 333 struct iosys_map vmap_ptr; 334 334