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-2024-04-19' of https://gitlab.freedesktop.org/drm/kernel

Pull drm fixes from Dave Airlie:
"Regular week of fixes, seems to be about right for this time in the
release cycle, amdgpu, and nouveau are the main one with some
scattered fixes otherwise.

ttm:
- Stop pooling cached NUMA pages

amdgpu:
- Fix invalid resource->start check
- USB-C DSC fix
- Fix a potential UAF in VA IOCTL
- Fix visible VRAM handling during faults

amdkfd:
- Fix memory leak in create_process failure

radeon:
- Silence UBSAN warnings from variable sized arrays

nouveau:
- dp: Don't probe DP ports twice
- nv04: Fix OOB access
- nv50: Disable AUX bus for disconnected DP ports
- nvkm: Fix instmem race condition

panel:
- Don't unregister DSI devices in several drivers

v3d:
- Fix enabled_ns increment

xe:
- Fix bo leak on error path during fb init
- Fix use-after-free due to order vm is put and destroyed"

* tag 'drm-fixes-2024-04-19' of https://gitlab.freedesktop.org/drm/kernel:
drm/radeon: silence UBSAN warning (v3)
drm/radeon: make -fstrict-flex-arrays=3 happy
drm/amdgpu: fix visible VRAM handling during faults
drm/amdgpu: validate the parameters of bo mapping operations more clearly
Revert "drm/amd/display: fix USB-C flag update after enc10 feature init"
drm/amdkfd: Fix memory leak in create_process failure
drm/amdgpu: remove invalid resource->start check v2
drm/xe/vm: prevent UAF with asid based lookup
drm/xe: Fix bo leak in intel_fb_bo_framebuffer_init
drm/panel: novatek-nt36682e: don't unregister DSI device
drm/panel: visionox-rm69299: don't unregister DSI device
drm/nouveau/dp: Don't probe eDP ports twice harder
drm/nouveau/kms/nv50-: Disable AUX bus for disconnected DP ports
drm/v3d: Don't increment `enabled_ns` twice
drm/vmwgfx: Sort primary plane formats by order of preference
drm/vmwgfx: Fix crtc's atomic check conditional
drm/vmwgfx: Fix prime import/export
drm/ttm: stop pooling cached NUMA pages v2
drm: nv04: Fix out of bounds access
nouveau: fix instmem race condition around ptr stores

+326 -178
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
··· 819 819 820 820 p->bytes_moved += ctx.bytes_moved; 821 821 if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && 822 - amdgpu_bo_in_cpu_visible_vram(bo)) 822 + amdgpu_res_cpu_visible(adev, bo->tbo.resource)) 823 823 p->bytes_moved_vis += ctx.bytes_moved; 824 824 825 825 if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
+11 -11
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
··· 617 617 return r; 618 618 619 619 if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && 620 - bo->tbo.resource->mem_type == TTM_PL_VRAM && 621 - amdgpu_bo_in_cpu_visible_vram(bo)) 620 + amdgpu_res_cpu_visible(adev, bo->tbo.resource)) 622 621 amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved, 623 622 ctx.bytes_moved); 624 623 else ··· 1271 1272 void amdgpu_bo_get_memory(struct amdgpu_bo *bo, 1272 1273 struct amdgpu_mem_stats *stats) 1273 1274 { 1275 + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 1276 + struct ttm_resource *res = bo->tbo.resource; 1274 1277 uint64_t size = amdgpu_bo_size(bo); 1275 1278 struct drm_gem_object *obj; 1276 1279 unsigned int domain; 1277 1280 bool shared; 1278 1281 1279 1282 /* Abort if the BO doesn't currently have a backing store */ 1280 - if (!bo->tbo.resource) 1283 + if (!res) 1281 1284 return; 1282 1285 1283 1286 obj = &bo->tbo.base; 1284 1287 shared = drm_gem_object_is_shared_for_memory_stats(obj); 1285 1288 1286 - domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type); 1289 + domain = amdgpu_mem_type_to_domain(res->mem_type); 1287 1290 switch (domain) { 1288 1291 case AMDGPU_GEM_DOMAIN_VRAM: 1289 1292 stats->vram += size; 1290 - if (amdgpu_bo_in_cpu_visible_vram(bo)) 1293 + if (amdgpu_res_cpu_visible(adev, bo->tbo.resource)) 1291 1294 stats->visible_vram += size; 1292 1295 if (shared) 1293 1296 stats->vram_shared += size; ··· 1390 1389 /* Remember that this BO was accessed by the CPU */ 1391 1390 abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; 1392 1391 1393 - if (bo->resource->mem_type != TTM_PL_VRAM) 1394 - return 0; 1395 - 1396 - if (amdgpu_bo_in_cpu_visible_vram(abo)) 1392 + if (amdgpu_res_cpu_visible(adev, bo->resource)) 1397 1393 return 0; 1398 1394 1399 1395 /* Can't move a pinned BO to visible VRAM */ ··· 1413 1415 1414 1416 /* this should never happen */ 1415 1417 if (bo->resource->mem_type == TTM_PL_VRAM && 1416 - !amdgpu_bo_in_cpu_visible_vram(abo)) 1418 + !amdgpu_res_cpu_visible(adev, bo->resource)) 1417 1419 return VM_FAULT_SIGBUS; 1418 1420 1419 1421 ttm_bo_move_to_lru_tail_unlocked(bo); ··· 1577 1579 */ 1578 1580 u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m) 1579 1581 { 1582 + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 1580 1583 struct dma_buf_attachment *attachment; 1581 1584 struct dma_buf *dma_buf; 1582 1585 const char *placement; ··· 1586 1587 1587 1588 if (dma_resv_trylock(bo->tbo.base.resv)) { 1588 1589 unsigned int domain; 1590 + 1589 1591 domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type); 1590 1592 switch (domain) { 1591 1593 case AMDGPU_GEM_DOMAIN_VRAM: 1592 - if (amdgpu_bo_in_cpu_visible_vram(bo)) 1594 + if (amdgpu_res_cpu_visible(adev, bo->tbo.resource)) 1593 1595 placement = "VRAM VISIBLE"; 1594 1596 else 1595 1597 placement = "VRAM";
-22
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
··· 251 251 } 252 252 253 253 /** 254 - * amdgpu_bo_in_cpu_visible_vram - check if BO is (partly) in visible VRAM 255 - */ 256 - static inline bool amdgpu_bo_in_cpu_visible_vram(struct amdgpu_bo *bo) 257 - { 258 - struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 259 - struct amdgpu_res_cursor cursor; 260 - 261 - if (!bo->tbo.resource || bo->tbo.resource->mem_type != TTM_PL_VRAM) 262 - return false; 263 - 264 - amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor); 265 - while (cursor.remaining) { 266 - if (cursor.start < adev->gmc.visible_vram_size) 267 - return true; 268 - 269 - amdgpu_res_next(&cursor, cursor.size); 270 - } 271 - 272 - return false; 273 - } 274 - 275 - /** 276 254 * amdgpu_bo_explicit_sync - return whether the bo is explicitly synced 277 255 */ 278 256 static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo)
+44 -33
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
··· 133 133 134 134 } else if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && 135 135 !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && 136 - amdgpu_bo_in_cpu_visible_vram(abo)) { 136 + amdgpu_res_cpu_visible(adev, bo->resource)) { 137 137 138 138 /* Try evicting to the CPU inaccessible part of VRAM 139 139 * first, but only set GTT as busy placement, so this ··· 403 403 return r; 404 404 } 405 405 406 + /** 407 + * amdgpu_res_cpu_visible - Check that resource can be accessed by CPU 408 + * @adev: amdgpu device 409 + * @res: the resource to check 410 + * 411 + * Returns: true if the full resource is CPU visible, false otherwise. 412 + */ 413 + bool amdgpu_res_cpu_visible(struct amdgpu_device *adev, 414 + struct ttm_resource *res) 415 + { 416 + struct amdgpu_res_cursor cursor; 417 + 418 + if (!res) 419 + return false; 420 + 421 + if (res->mem_type == TTM_PL_SYSTEM || res->mem_type == TTM_PL_TT || 422 + res->mem_type == AMDGPU_PL_PREEMPT) 423 + return true; 424 + 425 + if (res->mem_type != TTM_PL_VRAM) 426 + return false; 427 + 428 + amdgpu_res_first(res, 0, res->size, &cursor); 429 + while (cursor.remaining) { 430 + if ((cursor.start + cursor.size) >= adev->gmc.visible_vram_size) 431 + return false; 432 + amdgpu_res_next(&cursor, cursor.size); 433 + } 434 + 435 + return true; 436 + } 437 + 406 438 /* 407 - * amdgpu_mem_visible - Check that memory can be accessed by ttm_bo_move_memcpy 439 + * amdgpu_res_copyable - Check that memory can be accessed by ttm_bo_move_memcpy 408 440 * 409 441 * Called by amdgpu_bo_move() 410 442 */ 411 - static bool amdgpu_mem_visible(struct amdgpu_device *adev, 412 - struct ttm_resource *mem) 443 + static bool amdgpu_res_copyable(struct amdgpu_device *adev, 444 + struct ttm_resource *mem) 413 445 { 414 - u64 mem_size = (u64)mem->size; 415 - struct amdgpu_res_cursor cursor; 416 - u64 end; 417 - 418 - if (mem->mem_type == TTM_PL_SYSTEM || 419 - mem->mem_type == TTM_PL_TT) 420 - return true; 421 - if (mem->mem_type != TTM_PL_VRAM) 446 + if (!amdgpu_res_cpu_visible(adev, mem)) 422 447 return false; 423 448 424 - amdgpu_res_first(mem, 0, mem_size, &cursor); 425 - end = cursor.start + cursor.size; 426 - while (cursor.remaining) { 427 - amdgpu_res_next(&cursor, cursor.size); 449 + /* ttm_resource_ioremap only supports contiguous memory */ 450 + if (mem->mem_type == TTM_PL_VRAM && 451 + !(mem->placement & TTM_PL_FLAG_CONTIGUOUS)) 452 + return false; 428 453 429 - if (!cursor.remaining) 430 - break; 431 - 432 - /* ttm_resource_ioremap only supports contiguous memory */ 433 - if (end != cursor.start) 434 - return false; 435 - 436 - end = cursor.start + cursor.size; 437 - } 438 - 439 - return end <= adev->gmc.visible_vram_size; 454 + return true; 440 455 } 441 456 442 457 /* ··· 544 529 545 530 if (r) { 546 531 /* Check that all memory is CPU accessible */ 547 - if (!amdgpu_mem_visible(adev, old_mem) || 548 - !amdgpu_mem_visible(adev, new_mem)) { 532 + if (!amdgpu_res_copyable(adev, old_mem) || 533 + !amdgpu_res_copyable(adev, new_mem)) { 549 534 pr_err("Move buffer fallback to memcpy unavailable\n"); 550 535 return r; 551 536 } ··· 572 557 struct ttm_resource *mem) 573 558 { 574 559 struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); 575 - size_t bus_size = (size_t)mem->size; 576 560 577 561 switch (mem->mem_type) { 578 562 case TTM_PL_SYSTEM: ··· 582 568 break; 583 569 case TTM_PL_VRAM: 584 570 mem->bus.offset = mem->start << PAGE_SHIFT; 585 - /* check if it's visible */ 586 - if ((mem->bus.offset + bus_size) > adev->gmc.visible_vram_size) 587 - return -EINVAL; 588 571 589 572 if (adev->mman.aper_base_kaddr && 590 573 mem->placement & TTM_PL_FLAG_CONTIGUOUS)
+3
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
··· 139 139 int amdgpu_vram_mgr_query_page_status(struct amdgpu_vram_mgr *mgr, 140 140 uint64_t start); 141 141 142 + bool amdgpu_res_cpu_visible(struct amdgpu_device *adev, 143 + struct ttm_resource *res); 144 + 142 145 int amdgpu_ttm_init(struct amdgpu_device *adev); 143 146 void amdgpu_ttm_fini(struct amdgpu_device *adev); 144 147 void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,
+46 -26
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 1613 1613 trace_amdgpu_vm_bo_map(bo_va, mapping); 1614 1614 } 1615 1615 1616 + /* Validate operation parameters to prevent potential abuse */ 1617 + static int amdgpu_vm_verify_parameters(struct amdgpu_device *adev, 1618 + struct amdgpu_bo *bo, 1619 + uint64_t saddr, 1620 + uint64_t offset, 1621 + uint64_t size) 1622 + { 1623 + uint64_t tmp, lpfn; 1624 + 1625 + if (saddr & AMDGPU_GPU_PAGE_MASK 1626 + || offset & AMDGPU_GPU_PAGE_MASK 1627 + || size & AMDGPU_GPU_PAGE_MASK) 1628 + return -EINVAL; 1629 + 1630 + if (check_add_overflow(saddr, size, &tmp) 1631 + || check_add_overflow(offset, size, &tmp) 1632 + || size == 0 /* which also leads to end < begin */) 1633 + return -EINVAL; 1634 + 1635 + /* make sure object fit at this offset */ 1636 + if (bo && offset + size > amdgpu_bo_size(bo)) 1637 + return -EINVAL; 1638 + 1639 + /* Ensure last pfn not exceed max_pfn */ 1640 + lpfn = (saddr + size - 1) >> AMDGPU_GPU_PAGE_SHIFT; 1641 + if (lpfn >= adev->vm_manager.max_pfn) 1642 + return -EINVAL; 1643 + 1644 + return 0; 1645 + } 1646 + 1616 1647 /** 1617 1648 * amdgpu_vm_bo_map - map bo inside a vm 1618 1649 * ··· 1670 1639 struct amdgpu_bo *bo = bo_va->base.bo; 1671 1640 struct amdgpu_vm *vm = bo_va->base.vm; 1672 1641 uint64_t eaddr; 1642 + int r; 1673 1643 1674 - /* validate the parameters */ 1675 - if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK) 1676 - return -EINVAL; 1677 - if (saddr + size <= saddr || offset + size <= offset) 1678 - return -EINVAL; 1679 - 1680 - /* make sure object fit at this offset */ 1681 - eaddr = saddr + size - 1; 1682 - if ((bo && offset + size > amdgpu_bo_size(bo)) || 1683 - (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT)) 1684 - return -EINVAL; 1644 + r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size); 1645 + if (r) 1646 + return r; 1685 1647 1686 1648 saddr /= AMDGPU_GPU_PAGE_SIZE; 1687 - eaddr /= AMDGPU_GPU_PAGE_SIZE; 1649 + eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; 1688 1650 1689 1651 tmp = amdgpu_vm_it_iter_first(&vm->va, saddr, eaddr); 1690 1652 if (tmp) { ··· 1730 1706 uint64_t eaddr; 1731 1707 int r; 1732 1708 1733 - /* validate the parameters */ 1734 - if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK) 1735 - return -EINVAL; 1736 - if (saddr + size <= saddr || offset + size <= offset) 1737 - return -EINVAL; 1738 - 1739 - /* make sure object fit at this offset */ 1740 - eaddr = saddr + size - 1; 1741 - if ((bo && offset + size > amdgpu_bo_size(bo)) || 1742 - (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT)) 1743 - return -EINVAL; 1709 + r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size); 1710 + if (r) 1711 + return r; 1744 1712 1745 1713 /* Allocate all the needed memory */ 1746 1714 mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); ··· 1746 1730 } 1747 1731 1748 1732 saddr /= AMDGPU_GPU_PAGE_SIZE; 1749 - eaddr /= AMDGPU_GPU_PAGE_SIZE; 1733 + eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; 1750 1734 1751 1735 mapping->start = saddr; 1752 1736 mapping->last = eaddr; ··· 1833 1817 struct amdgpu_bo_va_mapping *before, *after, *tmp, *next; 1834 1818 LIST_HEAD(removed); 1835 1819 uint64_t eaddr; 1820 + int r; 1836 1821 1837 - eaddr = saddr + size - 1; 1822 + r = amdgpu_vm_verify_parameters(adev, NULL, saddr, 0, size); 1823 + if (r) 1824 + return r; 1825 + 1838 1826 saddr /= AMDGPU_GPU_PAGE_SIZE; 1839 - eaddr /= AMDGPU_GPU_PAGE_SIZE; 1827 + eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; 1840 1828 1841 1829 /* Allocate all the needed memory */ 1842 1830 before = kzalloc(sizeof(*before), GFP_KERNEL);
+2 -2
drivers/gpu/drm/amd/amdkfd/kfd_process.c
··· 819 819 mutex_lock(&kfd_processes_mutex); 820 820 821 821 if (kfd_is_locked()) { 822 - mutex_unlock(&kfd_processes_mutex); 823 822 pr_debug("KFD is locked! Cannot create process"); 824 - return ERR_PTR(-EINVAL); 823 + process = ERR_PTR(-EINVAL); 824 + goto out; 825 825 } 826 826 827 827 /* A prior open of /dev/kfd could have already created the process. */
+7 -6
drivers/gpu/drm/nouveau/nouveau_bios.c
··· 23 23 */ 24 24 25 25 #include "nouveau_drv.h" 26 + #include "nouveau_bios.h" 26 27 #include "nouveau_reg.h" 27 28 #include "dispnv04/hw.h" 28 29 #include "nouveau_encoder.h" ··· 1678 1677 */ 1679 1678 if (nv_match_device(dev, 0x0201, 0x1462, 0x8851)) { 1680 1679 if (*conn == 0xf2005014 && *conf == 0xffffffff) { 1681 - fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, 1); 1680 + fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, DCB_OUTPUT_B); 1682 1681 return false; 1683 1682 } 1684 1683 } ··· 1764 1763 #ifdef __powerpc__ 1765 1764 /* Apple iMac G4 NV17 */ 1766 1765 if (of_machine_is_compatible("PowerMac4,5")) { 1767 - fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, 1); 1768 - fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, 2); 1766 + fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, DCB_OUTPUT_B); 1767 + fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, DCB_OUTPUT_C); 1769 1768 return; 1770 1769 } 1771 1770 #endif 1772 1771 1773 1772 /* Make up some sane defaults */ 1774 1773 fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1775 - bios->legacy.i2c_indices.crt, 1, 1); 1774 + bios->legacy.i2c_indices.crt, 1, DCB_OUTPUT_B); 1776 1775 1777 1776 if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0) 1778 1777 fabricate_dcb_output(dcb, DCB_OUTPUT_TV, 1779 1778 bios->legacy.i2c_indices.tv, 1780 - all_heads, 0); 1779 + all_heads, DCB_OUTPUT_A); 1781 1780 1782 1781 else if (bios->tmds.output0_script_ptr || 1783 1782 bios->tmds.output1_script_ptr) 1784 1783 fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1785 1784 bios->legacy.i2c_indices.panel, 1786 - all_heads, 1); 1785 + all_heads, DCB_OUTPUT_B); 1787 1786 } 1788 1787 1789 1788 static int
+18 -5
drivers/gpu/drm/nouveau/nouveau_dp.c
··· 225 225 u8 *dpcd = nv_encoder->dp.dpcd; 226 226 int ret = NOUVEAU_DP_NONE, hpd; 227 227 228 - /* If we've already read the DPCD on an eDP device, we don't need to 229 - * reread it as it won't change 228 + /* eDP ports don't support hotplugging - so there's no point in probing eDP ports unless we 229 + * haven't probed them once before. 230 230 */ 231 - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP && 232 - dpcd[DP_DPCD_REV] != 0) 233 - return NOUVEAU_DP_SST; 231 + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 232 + if (connector->status == connector_status_connected) 233 + return NOUVEAU_DP_SST; 234 + else if (connector->status == connector_status_disconnected) 235 + return NOUVEAU_DP_NONE; 236 + } 237 + 238 + // Ensure that the aux bus is enabled for probing 239 + drm_dp_dpcd_set_powered(&nv_connector->aux, true); 234 240 235 241 mutex_lock(&nv_encoder->dp.hpd_irq_lock); 236 242 if (mstm) { ··· 298 292 out: 299 293 if (mstm && !mstm->suspended && ret != NOUVEAU_DP_MST) 300 294 nv50_mstm_remove(mstm); 295 + 296 + /* GSP doesn't like when we try to do aux transactions on a port it considers disconnected, 297 + * and since we don't really have a usecase for that anyway - just disable the aux bus here 298 + * if we've decided the connector is disconnected 299 + */ 300 + if (ret == NOUVEAU_DP_NONE) 301 + drm_dp_dpcd_set_powered(&nv_connector->aux, false); 301 302 302 303 mutex_unlock(&nv_encoder->dp.hpd_irq_lock); 303 304 return ret;
+6 -1
drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
··· 222 222 void __iomem *map = NULL; 223 223 224 224 /* Already mapped? */ 225 - if (refcount_inc_not_zero(&iobj->maps)) 225 + if (refcount_inc_not_zero(&iobj->maps)) { 226 + /* read barrier match the wmb on refcount set */ 227 + smp_rmb(); 226 228 return iobj->map; 229 + } 227 230 228 231 /* Take the lock, and re-check that another thread hasn't 229 232 * already mapped the object in the meantime. ··· 253 250 iobj->base.memory.ptrs = &nv50_instobj_fast; 254 251 else 255 252 iobj->base.memory.ptrs = &nv50_instobj_slow; 253 + /* barrier to ensure the ptrs are written before refcount is set */ 254 + smp_wmb(); 256 255 refcount_set(&iobj->maps, 1); 257 256 } 258 257
-2
drivers/gpu/drm/panel/panel-novatek-nt36672e.c
··· 614 614 struct nt36672e_panel *ctx = mipi_dsi_get_drvdata(dsi); 615 615 616 616 mipi_dsi_detach(ctx->dsi); 617 - mipi_dsi_device_unregister(ctx->dsi); 618 - 619 617 drm_panel_remove(&ctx->panel); 620 618 } 621 619
-2
drivers/gpu/drm/panel/panel-visionox-rm69299.c
··· 253 253 struct visionox_rm69299 *ctx = mipi_dsi_get_drvdata(dsi); 254 254 255 255 mipi_dsi_detach(ctx->dsi); 256 - mipi_dsi_device_unregister(ctx->dsi); 257 - 258 256 drm_panel_remove(&ctx->panel); 259 257 } 260 258
+5 -5
drivers/gpu/drm/radeon/pptable.h
··· 424 424 typedef struct _ATOM_PPLIB_STATE_V2 425 425 { 426 426 //number of valid dpm levels in this state; Driver uses it to calculate the whole 427 - //size of the state: sizeof(ATOM_PPLIB_STATE_V2) + (ucNumDPMLevels - 1) * sizeof(UCHAR) 427 + //size of the state: struct_size(ATOM_PPLIB_STATE_V2, clockInfoIndex, ucNumDPMLevels) 428 428 UCHAR ucNumDPMLevels; 429 429 430 430 //a index to the array of nonClockInfos ··· 432 432 /** 433 433 * Driver will read the first ucNumDPMLevels in this array 434 434 */ 435 - UCHAR clockInfoIndex[1]; 435 + UCHAR clockInfoIndex[] __counted_by(ucNumDPMLevels); 436 436 } ATOM_PPLIB_STATE_V2; 437 437 438 438 typedef struct _StateArray{ 439 439 //how many states we have 440 440 UCHAR ucNumEntries; 441 441 442 - ATOM_PPLIB_STATE_V2 states[1]; 442 + ATOM_PPLIB_STATE_V2 states[] __counted_by(ucNumEntries); 443 443 }StateArray; 444 444 445 445 ··· 450 450 //sizeof(ATOM_PPLIB_CLOCK_INFO) 451 451 UCHAR ucEntrySize; 452 452 453 - UCHAR clockInfo[1]; 453 + UCHAR clockInfo[] __counted_by(ucNumEntries); 454 454 }ClockInfoArray; 455 455 456 456 typedef struct _NonClockInfoArray{ ··· 460 460 //sizeof(ATOM_PPLIB_NONCLOCK_INFO) 461 461 UCHAR ucEntrySize; 462 462 463 - ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[1]; 463 + ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[] __counted_by(ucNumEntries); 464 464 }NonClockInfoArray; 465 465 466 466 typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record
+6 -2
drivers/gpu/drm/radeon/radeon_atombios.c
··· 923 923 max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO; 924 924 925 925 for (i = 0; i < max_device; i++) { 926 - ATOM_CONNECTOR_INFO_I2C ci = 927 - supported_devices->info.asConnInfo[i]; 926 + ATOM_CONNECTOR_INFO_I2C ci; 927 + 928 + if (frev > 1) 929 + ci = supported_devices->info_2d1.asConnInfo[i]; 930 + else 931 + ci = supported_devices->info.asConnInfo[i]; 928 932 929 933 bios_connectors[i].valid = false; 930 934
+28 -10
drivers/gpu/drm/ttm/ttm_pool.c
··· 288 288 enum ttm_caching caching, 289 289 unsigned int order) 290 290 { 291 - if (pool->use_dma_alloc || pool->nid != NUMA_NO_NODE) 291 + if (pool->use_dma_alloc) 292 292 return &pool->caching[caching].orders[order]; 293 293 294 294 #ifdef CONFIG_X86 295 295 switch (caching) { 296 296 case ttm_write_combined: 297 + if (pool->nid != NUMA_NO_NODE) 298 + return &pool->caching[caching].orders[order]; 299 + 297 300 if (pool->use_dma32) 298 301 return &global_dma32_write_combined[order]; 299 302 300 303 return &global_write_combined[order]; 301 304 case ttm_uncached: 305 + if (pool->nid != NUMA_NO_NODE) 306 + return &pool->caching[caching].orders[order]; 307 + 302 308 if (pool->use_dma32) 303 309 return &global_dma32_uncached[order]; 304 310 ··· 572 566 pool->use_dma_alloc = use_dma_alloc; 573 567 pool->use_dma32 = use_dma32; 574 568 575 - if (use_dma_alloc || nid != NUMA_NO_NODE) { 576 - for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) 577 - for (j = 0; j < NR_PAGE_ORDERS; ++j) 578 - ttm_pool_type_init(&pool->caching[i].orders[j], 579 - pool, i, j); 569 + for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) { 570 + for (j = 0; j < NR_PAGE_ORDERS; ++j) { 571 + struct ttm_pool_type *pt; 572 + 573 + /* Initialize only pool types which are actually used */ 574 + pt = ttm_pool_select_type(pool, i, j); 575 + if (pt != &pool->caching[i].orders[j]) 576 + continue; 577 + 578 + ttm_pool_type_init(pt, pool, i, j); 579 + } 580 580 } 581 581 } 582 582 EXPORT_SYMBOL(ttm_pool_init); ··· 611 599 { 612 600 unsigned int i, j; 613 601 614 - if (pool->use_dma_alloc || pool->nid != NUMA_NO_NODE) { 615 - for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) 616 - for (j = 0; j < NR_PAGE_ORDERS; ++j) 617 - ttm_pool_type_fini(&pool->caching[i].orders[j]); 602 + for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) { 603 + for (j = 0; j < NR_PAGE_ORDERS; ++j) { 604 + struct ttm_pool_type *pt; 605 + 606 + pt = ttm_pool_select_type(pool, i, j); 607 + if (pt != &pool->caching[i].orders[j]) 608 + continue; 609 + 610 + ttm_pool_type_fini(pt); 611 + } 618 612 } 619 613 620 614 /* We removed the pool types from the LRU, but we need to also make sure
-4
drivers/gpu/drm/v3d/v3d_irq.c
··· 105 105 struct v3d_file_priv *file = v3d->bin_job->base.file->driver_priv; 106 106 u64 runtime = local_clock() - file->start_ns[V3D_BIN]; 107 107 108 - file->enabled_ns[V3D_BIN] += local_clock() - file->start_ns[V3D_BIN]; 109 108 file->jobs_sent[V3D_BIN]++; 110 109 v3d->queue[V3D_BIN].jobs_sent++; 111 110 ··· 125 126 struct v3d_file_priv *file = v3d->render_job->base.file->driver_priv; 126 127 u64 runtime = local_clock() - file->start_ns[V3D_RENDER]; 127 128 128 - file->enabled_ns[V3D_RENDER] += local_clock() - file->start_ns[V3D_RENDER]; 129 129 file->jobs_sent[V3D_RENDER]++; 130 130 v3d->queue[V3D_RENDER].jobs_sent++; 131 131 ··· 145 147 struct v3d_file_priv *file = v3d->csd_job->base.file->driver_priv; 146 148 u64 runtime = local_clock() - file->start_ns[V3D_CSD]; 147 149 148 - file->enabled_ns[V3D_CSD] += local_clock() - file->start_ns[V3D_CSD]; 149 150 file->jobs_sent[V3D_CSD]++; 150 151 v3d->queue[V3D_CSD].jobs_sent++; 151 152 ··· 192 195 struct v3d_file_priv *file = v3d->tfu_job->base.file->driver_priv; 193 196 u64 runtime = local_clock() - file->start_ns[V3D_TFU]; 194 197 195 - file->enabled_ns[V3D_TFU] += local_clock() - file->start_ns[V3D_TFU]; 196 198 file->jobs_sent[V3D_TFU]++; 197 199 v3d->queue[V3D_TFU].jobs_sent++; 198 200
+32 -3
drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
··· 456 456 .no_wait_gpu = false 457 457 }; 458 458 u32 j, initial_line = dst_offset / dst_stride; 459 - struct vmw_bo_blit_line_data d; 459 + struct vmw_bo_blit_line_data d = {0}; 460 460 int ret = 0; 461 + struct page **dst_pages = NULL; 462 + struct page **src_pages = NULL; 461 463 462 464 /* Buffer objects need to be either pinned or reserved: */ 463 465 if (!(dst->pin_count)) ··· 479 477 return ret; 480 478 } 481 479 480 + if (!src->ttm->pages && src->ttm->sg) { 481 + src_pages = kvmalloc_array(src->ttm->num_pages, 482 + sizeof(struct page *), GFP_KERNEL); 483 + if (!src_pages) 484 + return -ENOMEM; 485 + ret = drm_prime_sg_to_page_array(src->ttm->sg, src_pages, 486 + src->ttm->num_pages); 487 + if (ret) 488 + goto out; 489 + } 490 + if (!dst->ttm->pages && dst->ttm->sg) { 491 + dst_pages = kvmalloc_array(dst->ttm->num_pages, 492 + sizeof(struct page *), GFP_KERNEL); 493 + if (!dst_pages) { 494 + ret = -ENOMEM; 495 + goto out; 496 + } 497 + ret = drm_prime_sg_to_page_array(dst->ttm->sg, dst_pages, 498 + dst->ttm->num_pages); 499 + if (ret) 500 + goto out; 501 + } 502 + 482 503 d.mapped_dst = 0; 483 504 d.mapped_src = 0; 484 505 d.dst_addr = NULL; 485 506 d.src_addr = NULL; 486 - d.dst_pages = dst->ttm->pages; 487 - d.src_pages = src->ttm->pages; 507 + d.dst_pages = dst->ttm->pages ? dst->ttm->pages : dst_pages; 508 + d.src_pages = src->ttm->pages ? src->ttm->pages : src_pages; 488 509 d.dst_num_pages = PFN_UP(dst->resource->size); 489 510 d.src_num_pages = PFN_UP(src->resource->size); 490 511 d.dst_prot = ttm_io_prot(dst, dst->resource, PAGE_KERNEL); ··· 529 504 kunmap_atomic(d.src_addr); 530 505 if (d.dst_addr) 531 506 kunmap_atomic(d.dst_addr); 507 + if (src_pages) 508 + kvfree(src_pages); 509 + if (dst_pages) 510 + kvfree(dst_pages); 532 511 533 512 return ret; 534 513 }
+4 -3
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
··· 377 377 { 378 378 struct ttm_operation_ctx ctx = { 379 379 .interruptible = params->bo_type != ttm_bo_type_kernel, 380 - .no_wait_gpu = false 380 + .no_wait_gpu = false, 381 + .resv = params->resv, 381 382 }; 382 383 struct ttm_device *bdev = &dev_priv->bdev; 383 384 struct drm_device *vdev = &dev_priv->drm; ··· 395 394 396 395 vmw_bo_placement_set(vmw_bo, params->domain, params->busy_domain); 397 396 ret = ttm_bo_init_reserved(bdev, &vmw_bo->tbo, params->bo_type, 398 - &vmw_bo->placement, 0, &ctx, NULL, 399 - NULL, destroy); 397 + &vmw_bo->placement, 0, &ctx, 398 + params->sg, params->resv, destroy); 400 399 if (unlikely(ret)) 401 400 return ret; 402 401
+2
drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
··· 55 55 enum ttm_bo_type bo_type; 56 56 size_t size; 57 57 bool pin; 58 + struct dma_resv *resv; 59 + struct sg_table *sg; 58 60 }; 59 61 60 62 /**
+1
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
··· 1628 1628 1629 1629 .prime_fd_to_handle = vmw_prime_fd_to_handle, 1630 1630 .prime_handle_to_fd = vmw_prime_handle_to_fd, 1631 + .gem_prime_import_sg_table = vmw_prime_import_sg_table, 1631 1632 1632 1633 .fops = &vmwgfx_driver_fops, 1633 1634 .name = VMWGFX_DRIVER_NAME,
+3
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
··· 1130 1130 struct drm_file *file_priv, 1131 1131 uint32_t handle, uint32_t flags, 1132 1132 int *prime_fd); 1133 + struct drm_gem_object *vmw_prime_import_sg_table(struct drm_device *dev, 1134 + struct dma_buf_attachment *attach, 1135 + struct sg_table *table); 1133 1136 1134 1137 /* 1135 1138 * MemoryOBject management - vmwgfx_mob.c
+32
drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
··· 149 149 return ret; 150 150 } 151 151 152 + struct drm_gem_object *vmw_prime_import_sg_table(struct drm_device *dev, 153 + struct dma_buf_attachment *attach, 154 + struct sg_table *table) 155 + { 156 + int ret; 157 + struct vmw_private *dev_priv = vmw_priv(dev); 158 + struct drm_gem_object *gem = NULL; 159 + struct vmw_bo *vbo; 160 + struct vmw_bo_params params = { 161 + .domain = (dev_priv->has_mob) ? VMW_BO_DOMAIN_SYS : VMW_BO_DOMAIN_VRAM, 162 + .busy_domain = VMW_BO_DOMAIN_SYS, 163 + .bo_type = ttm_bo_type_sg, 164 + .size = attach->dmabuf->size, 165 + .pin = false, 166 + .resv = attach->dmabuf->resv, 167 + .sg = table, 168 + 169 + }; 170 + 171 + dma_resv_lock(params.resv, NULL); 172 + 173 + ret = vmw_bo_create(dev_priv, &params, &vbo); 174 + if (ret != 0) 175 + goto out_no_bo; 176 + 177 + vbo->tbo.base.funcs = &vmw_gem_object_funcs; 178 + 179 + gem = &vbo->tbo.base; 180 + out_no_bo: 181 + dma_resv_unlock(params.resv); 182 + return gem; 183 + } 152 184 153 185 int vmw_gem_object_create_ioctl(struct drm_device *dev, void *data, 154 186 struct drm_file *filp)
+8 -3
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
··· 933 933 int vmw_du_crtc_atomic_check(struct drm_crtc *crtc, 934 934 struct drm_atomic_state *state) 935 935 { 936 + struct vmw_private *vmw = vmw_priv(crtc->dev); 936 937 struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state, 937 938 crtc); 938 939 struct vmw_display_unit *du = vmw_crtc_to_du(new_state->crtc); ··· 941 940 bool has_primary = new_state->plane_mask & 942 941 drm_plane_mask(crtc->primary); 943 942 944 - /* We always want to have an active plane with an active CRTC */ 945 - if (has_primary != new_state->enable) 946 - return -EINVAL; 943 + /* 944 + * This is fine in general, but broken userspace might expect 945 + * some actual rendering so give a clue as why it's blank. 946 + */ 947 + if (new_state->enable && !has_primary) 948 + drm_dbg_driver(&vmw->drm, 949 + "CRTC without a primary plane will be blank.\n"); 947 950 948 951 949 952 if (new_state->connector_mask != connector_mask &&
+2 -2
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
··· 243 243 244 244 245 245 static const uint32_t __maybe_unused vmw_primary_plane_formats[] = { 246 - DRM_FORMAT_XRGB1555, 247 - DRM_FORMAT_RGB565, 248 246 DRM_FORMAT_XRGB8888, 249 247 DRM_FORMAT_ARGB8888, 248 + DRM_FORMAT_RGB565, 249 + DRM_FORMAT_XRGB1555, 250 250 }; 251 251 252 252 static const uint32_t __maybe_unused vmw_cursor_plane_formats[] = {
+13 -2
drivers/gpu/drm/vmwgfx/vmwgfx_prime.c
··· 75 75 int fd, u32 *handle) 76 76 { 77 77 struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; 78 + int ret = ttm_prime_fd_to_handle(tfile, fd, handle); 78 79 79 - return ttm_prime_fd_to_handle(tfile, fd, handle); 80 + if (ret) 81 + ret = drm_gem_prime_fd_to_handle(dev, file_priv, fd, handle); 82 + 83 + return ret; 80 84 } 81 85 82 86 int vmw_prime_handle_to_fd(struct drm_device *dev, ··· 89 85 int *prime_fd) 90 86 { 91 87 struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; 92 - return ttm_prime_handle_to_fd(tfile, handle, flags, prime_fd); 88 + int ret; 89 + 90 + if (handle > VMWGFX_NUM_MOB) 91 + ret = ttm_prime_handle_to_fd(tfile, handle, flags, prime_fd); 92 + else 93 + ret = drm_gem_prime_handle_to_fd(dev, file_priv, handle, flags, prime_fd); 94 + 95 + return ret; 93 96 }
+30 -14
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
··· 188 188 switch (dev_priv->map_mode) { 189 189 case vmw_dma_map_bind: 190 190 case vmw_dma_map_populate: 191 - vsgt->sgt = &vmw_tt->sgt; 192 - ret = sg_alloc_table_from_pages_segment( 193 - &vmw_tt->sgt, vsgt->pages, vsgt->num_pages, 0, 194 - (unsigned long)vsgt->num_pages << PAGE_SHIFT, 195 - dma_get_max_seg_size(dev_priv->drm.dev), GFP_KERNEL); 196 - if (ret) 197 - goto out_sg_alloc_fail; 191 + if (vmw_tt->dma_ttm.page_flags & TTM_TT_FLAG_EXTERNAL) { 192 + vsgt->sgt = vmw_tt->dma_ttm.sg; 193 + } else { 194 + vsgt->sgt = &vmw_tt->sgt; 195 + ret = sg_alloc_table_from_pages_segment(&vmw_tt->sgt, 196 + vsgt->pages, vsgt->num_pages, 0, 197 + (unsigned long)vsgt->num_pages << PAGE_SHIFT, 198 + dma_get_max_seg_size(dev_priv->drm.dev), 199 + GFP_KERNEL); 200 + if (ret) 201 + goto out_sg_alloc_fail; 202 + } 198 203 199 204 ret = vmw_ttm_map_for_dma(vmw_tt); 200 205 if (unlikely(ret != 0)) ··· 214 209 return 0; 215 210 216 211 out_map_fail: 217 - sg_free_table(vmw_tt->vsgt.sgt); 218 - vmw_tt->vsgt.sgt = NULL; 212 + drm_warn(&dev_priv->drm, "VSG table map failed!"); 213 + sg_free_table(vsgt->sgt); 214 + vsgt->sgt = NULL; 219 215 out_sg_alloc_fail: 220 216 return ret; 221 217 } ··· 362 356 static int vmw_ttm_populate(struct ttm_device *bdev, 363 357 struct ttm_tt *ttm, struct ttm_operation_ctx *ctx) 364 358 { 365 - int ret; 359 + bool external = (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) != 0; 366 360 367 - /* TODO: maybe completely drop this ? */ 368 361 if (ttm_tt_is_populated(ttm)) 369 362 return 0; 370 363 371 - ret = ttm_pool_alloc(&bdev->pool, ttm, ctx); 364 + if (external && ttm->sg) 365 + return drm_prime_sg_to_dma_addr_array(ttm->sg, 366 + ttm->dma_address, 367 + ttm->num_pages); 372 368 373 - return ret; 369 + return ttm_pool_alloc(&bdev->pool, ttm, ctx); 374 370 } 375 371 376 372 static void vmw_ttm_unpopulate(struct ttm_device *bdev, ··· 380 372 { 381 373 struct vmw_ttm_tt *vmw_tt = container_of(ttm, struct vmw_ttm_tt, 382 374 dma_ttm); 375 + bool external = (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) != 0; 376 + 377 + if (external) 378 + return; 383 379 384 380 vmw_ttm_unbind(bdev, ttm); 385 381 ··· 402 390 { 403 391 struct vmw_ttm_tt *vmw_be; 404 392 int ret; 393 + bool external = bo->type == ttm_bo_type_sg; 405 394 406 395 vmw_be = kzalloc(sizeof(*vmw_be), GFP_KERNEL); 407 396 if (!vmw_be) ··· 411 398 vmw_be->dev_priv = vmw_priv_from_ttm(bo->bdev); 412 399 vmw_be->mob = NULL; 413 400 414 - if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent) 401 + if (external) 402 + page_flags |= TTM_TT_FLAG_EXTERNAL | TTM_TT_FLAG_EXTERNAL_MAPPABLE; 403 + 404 + if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent || external) 415 405 ret = ttm_sg_tt_init(&vmw_be->dma_ttm, bo, page_flags, 416 406 ttm_cached); 417 407 else
+6 -2
drivers/gpu/drm/xe/display/intel_fb_bo.c
··· 31 31 32 32 ret = ttm_bo_reserve(&bo->ttm, true, false, NULL); 33 33 if (ret) 34 - return ret; 34 + goto err; 35 35 36 36 if (!(bo->flags & XE_BO_SCANOUT_BIT)) { 37 37 /* ··· 42 42 */ 43 43 if (XE_IOCTL_DBG(i915, !list_empty(&bo->ttm.base.gpuva.list))) { 44 44 ttm_bo_unreserve(&bo->ttm); 45 - return -EINVAL; 45 + ret = -EINVAL; 46 + goto err; 46 47 } 47 48 bo->flags |= XE_BO_SCANOUT_BIT; 48 49 } 49 50 ttm_bo_unreserve(&bo->ttm); 51 + return 0; 50 52 53 + err: 54 + xe_bo_put(bo); 51 55 return ret; 52 56 } 53 57
+11 -10
drivers/gpu/drm/xe/xe_vm.c
··· 1577 1577 xe->usm.num_vm_in_fault_mode--; 1578 1578 else if (!(vm->flags & XE_VM_FLAG_MIGRATION)) 1579 1579 xe->usm.num_vm_in_non_fault_mode--; 1580 + 1581 + if (vm->usm.asid) { 1582 + void *lookup; 1583 + 1584 + xe_assert(xe, xe->info.has_asid); 1585 + xe_assert(xe, !(vm->flags & XE_VM_FLAG_MIGRATION)); 1586 + 1587 + lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid); 1588 + xe_assert(xe, lookup == vm); 1589 + } 1580 1590 mutex_unlock(&xe->usm.lock); 1581 1591 1582 1592 for_each_tile(tile, xe, id) ··· 1602 1592 struct xe_device *xe = vm->xe; 1603 1593 struct xe_tile *tile; 1604 1594 u8 id; 1605 - void *lookup; 1606 1595 1607 1596 /* xe_vm_close_and_put was not called? */ 1608 1597 xe_assert(xe, !vm->size); 1609 1598 1610 1599 mutex_destroy(&vm->snap_mutex); 1611 1600 1612 - if (!(vm->flags & XE_VM_FLAG_MIGRATION)) { 1601 + if (!(vm->flags & XE_VM_FLAG_MIGRATION)) 1613 1602 xe_device_mem_access_put(xe); 1614 - 1615 - if (xe->info.has_asid && vm->usm.asid) { 1616 - mutex_lock(&xe->usm.lock); 1617 - lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid); 1618 - xe_assert(xe, lookup == vm); 1619 - mutex_unlock(&xe->usm.lock); 1620 - } 1621 - } 1622 1603 1623 1604 for_each_tile(tile, xe, id) 1624 1605 XE_WARN_ON(vm->pt_root[id]);