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-intel-gt-next-2025-09-12' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next

Driver Changes:

- Include the GuC registers in the error state (Daniele)
- Use memdup_user() (Thorsten)
- Selftest improvements (Jonathan)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://lore.kernel.org/r/aMPCfRObHMg6DZAs@jlahtine-mobl

+116 -12
+3 -9
drivers/gpu/drm/i915/gem/i915_gem_context.c
··· 2158 2158 goto out_ce; 2159 2159 } 2160 2160 2161 - state = kmalloc(ce->engine->context_size, GFP_KERNEL); 2162 - if (!state) { 2163 - ret = -ENOMEM; 2161 + state = memdup_user(u64_to_user_ptr(user.image), ce->engine->context_size); 2162 + if (IS_ERR(state)) { 2163 + ret = PTR_ERR(state); 2164 2164 goto out_ce; 2165 - } 2166 - 2167 - if (copy_from_user(state, u64_to_user_ptr(user.image), 2168 - ce->engine->context_size)) { 2169 - ret = -EFAULT; 2170 - goto out_state; 2171 2165 } 2172 2166 2173 2167 shmem_state = shmem_create_from_data(ce->engine->name,
+1 -3
drivers/gpu/drm/i915/gt/selftest_hangcheck.c
··· 904 904 arg->result = PTR_ERR(ce[count]); 905 905 pr_err("[%s] Create context #%ld failed: %d!\n", 906 906 engine->name, count, arg->result); 907 - if (!count) 908 - return; 909 - while (--count) 907 + while (count--) 910 908 intel_context_put(ce[count]); 911 909 return; 912 910 }
+8
drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
··· 46 46 /* allows for 5us (in 10ns units) before GT can go to RC6 */ 47 47 intel_uncore_write(uncore, GUC_ARAT_C6DIS, 0x1FF); 48 48 } 49 + 50 + /* 51 + * Starting from IP 12.50 we need to enable the mirroring of GuC 52 + * internal state to debug registers. This is always enabled on previous 53 + * IPs. 54 + */ 55 + if (GRAPHICS_VER_FULL(uncore->i915) >= IP_VER(12, 50)) 56 + intel_uncore_rmw(uncore, GUC_SHIM_CONTROL2, 0, GUC_ENABLE_DEBUG_REG); 49 57 } 50 58 51 59 static int guc_xfer_rsa_mmio(struct intel_uc_fw *guc_fw,
+1
drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
··· 96 96 #define GUC_GEN10_SHIM_WC_ENABLE (1<<21) 97 97 98 98 #define GUC_SHIM_CONTROL2 _MMIO(0xc068) 99 + #define GUC_ENABLE_DEBUG_REG (1<<11) 99 100 #define GUC_IS_PRIVILEGED (1<<29) 100 101 #define GSC_LOADS_HUC (1<<30) 101 102
+102
drivers/gpu/drm/i915/i915_gpu_error.c
··· 685 685 ctb->head, ctb->tail, ctb->desc_offset, ctb->cmds_offset, ctb->size); 686 686 } 687 687 688 + /* This list includes registers that are useful in debugging GuC hangs. */ 689 + const struct { 690 + u32 start; 691 + u32 count; 692 + } guc_hw_reg_state[] = { 693 + { 0xc0b0, 2 }, 694 + { 0xc000, 65 }, 695 + { 0xc140, 1 }, 696 + { 0xc180, 16 }, 697 + { 0xc1dc, 10 }, 698 + { 0xc300, 79 }, 699 + { 0xc4b4, 47 }, 700 + { 0xc574, 1 }, 701 + { 0xc57c, 1 }, 702 + { 0xc584, 11 }, 703 + { 0xc5c0, 8 }, 704 + { 0xc5e4, 1 }, 705 + { 0xc5ec, 103 }, 706 + { 0xc7c0, 1 }, 707 + { 0xc0b0, 2 } 708 + }; 709 + 710 + static u32 print_range_line(struct drm_i915_error_state_buf *m, u32 start, u32 *dump, u32 count) 711 + { 712 + if (count >= 8) { 713 + err_printf(m, "[0x%04x] 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", 714 + start, dump[0], dump[1], dump[2], dump[3], 715 + dump[4], dump[5], dump[6], dump[7]); 716 + return 8; 717 + } else if (count >= 4) { 718 + err_printf(m, "[0x%04x] 0x%08x 0x%08x 0x%08x 0x%08x\n", 719 + start, dump[0], dump[1], dump[2], dump[3]); 720 + return 4; 721 + } else if (count >= 2) { 722 + err_printf(m, "[0x%04x] 0x%08x 0x%08x\n", start, dump[0], dump[1]); 723 + return 2; 724 + } 725 + 726 + err_printf(m, "[0x%04x] 0x%08x\n", start, dump[0]); 727 + return 1; 728 + } 729 + 730 + static void err_print_guc_hw_state(struct drm_i915_error_state_buf *m, u32 *hw_state) 731 + { 732 + u32 total = 0; 733 + int i; 734 + 735 + if (!hw_state) 736 + return; 737 + 738 + err_printf(m, "GuC Register State:\n"); 739 + 740 + for (i = 0; i < ARRAY_SIZE(guc_hw_reg_state); i++) { 741 + u32 entry = 0; 742 + 743 + while (entry < guc_hw_reg_state[i].count) { 744 + u32 start = guc_hw_reg_state[i].start + entry * sizeof(u32); 745 + u32 count = guc_hw_reg_state[i].count - entry; 746 + u32 *values = hw_state + total + entry; 747 + 748 + entry += print_range_line(m, start, values, count); 749 + } 750 + 751 + GEM_BUG_ON(entry != guc_hw_reg_state[i].count); 752 + total += entry; 753 + } 754 + } 755 + 688 756 static void err_print_uc(struct drm_i915_error_state_buf *m, 689 757 const struct intel_uc_coredump *error_uc) 690 758 { ··· 761 693 intel_uc_fw_dump(&error_uc->guc_fw, &p); 762 694 intel_uc_fw_dump(&error_uc->huc_fw, &p); 763 695 err_printf(m, "GuC timestamp: 0x%08x\n", error_uc->guc.timestamp); 696 + err_print_guc_hw_state(m, error_uc->guc.hw_state); 764 697 intel_gpu_error_print_vma(m, NULL, error_uc->guc.vma_log); 765 698 err_printf(m, "GuC CTB fence: %d\n", error_uc->guc.last_fence); 766 699 err_print_guc_ctb(m, "Send", error_uc->guc.ctb + 0); ··· 1094 1025 kfree(uc->huc_fw.file_wanted.path); 1095 1026 i915_vma_coredump_free(uc->guc.vma_log); 1096 1027 i915_vma_coredump_free(uc->guc.vma_ctb); 1028 + kfree(uc->guc.hw_state); 1097 1029 1098 1030 kfree(uc); 1099 1031 } ··· 1791 1721 saved->cmds_offset = ((void *)ctb->cmds) - blob_ptr; 1792 1722 } 1793 1723 1724 + static u32 read_guc_state_reg(struct intel_uncore *uncore, int range, int count) 1725 + { 1726 + GEM_BUG_ON(range >= ARRAY_SIZE(guc_hw_reg_state)); 1727 + GEM_BUG_ON(count >= guc_hw_reg_state[range].count); 1728 + 1729 + return intel_uncore_read(uncore, 1730 + _MMIO(guc_hw_reg_state[range].start + count * sizeof(u32))); 1731 + } 1732 + 1733 + static void gt_record_guc_hw_state(struct intel_uncore *uncore, 1734 + struct intel_uc_coredump *error_uc) 1735 + { 1736 + u32 *hw_state; 1737 + u32 count = 0; 1738 + int i, j; 1739 + 1740 + for (i = 0; i < ARRAY_SIZE(guc_hw_reg_state); i++) 1741 + count += guc_hw_reg_state[i].count; 1742 + 1743 + hw_state = kcalloc(count, sizeof(u32), ALLOW_FAIL); 1744 + if (!hw_state) 1745 + return; 1746 + 1747 + count = 0; 1748 + for (i = 0; i < ARRAY_SIZE(guc_hw_reg_state); i++) 1749 + for (j = 0; j < guc_hw_reg_state[i].count; j++) 1750 + hw_state[count++] = read_guc_state_reg(uncore, i, j); 1751 + 1752 + error_uc->guc.hw_state = hw_state; 1753 + } 1754 + 1794 1755 static struct intel_uc_coredump * 1795 1756 gt_record_uc(struct intel_gt_coredump *gt, 1796 1757 struct i915_vma_compress *compress) ··· 1856 1755 uc->guc.ct.ctbs.send.desc, (struct intel_guc *)&uc->guc); 1857 1756 gt_record_guc_ctb(error_uc->guc.ctb + 1, &uc->guc.ct.ctbs.recv, 1858 1757 uc->guc.ct.ctbs.send.desc, (struct intel_guc *)&uc->guc); 1758 + gt_record_guc_hw_state(gt->_gt->uncore, error_uc); 1859 1759 1860 1760 return error_uc; 1861 1761 }
+1
drivers/gpu/drm/i915/i915_gpu_error.h
··· 177 177 struct intel_ctb_coredump ctb[2]; 178 178 struct i915_vma_coredump *vma_ctb; 179 179 struct i915_vma_coredump *vma_log; 180 + u32 *hw_state; 180 181 u32 timestamp; 181 182 u16 last_fence; 182 183 bool is_guc_capture;