History

Merge tag 'drm-fixes-2023-01-13' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie: "There is a bit of a post-holiday build up here I expect, small fixes across the board, amdgpu and msm being the main leaders, with others having a few. One code removal patch for nouveau: buddy: - benchmark regression fix for top-down buddy allocation panel: - add Lenovo panel orientation quirk ttm: - fix kernel oops regression amdgpu: - fix missing fence references - fix missing pipeline sync fencing - SMU13 fan speed fix - SMU13 fix power cap handling - SMU13 BACO fix - Fix a possible segfault in bo validation error case - Delay removal of firmware framebuffer - Fix error when unloading amdkfd: - SVM fix when clearing vram - GC11 fix for multi-GPU i915: - Reserve enough fence slot for i915_vma_unbind_vsync - Fix potential use after free - Reset engines twice in case of reset failure - Use multi-cast registers for SVG Unit registers msm: - display: - doc warning fixes - dt attribs cleanups - memory leak fix - error handing in hdmi probe fix - dp_aux_isr incorrect signalling fix - shutdown path fix - accel: - a5xx: fix quirks to be a bitmask - a6xx: fix gx halt to avoid 1s hang - kexec shutdown fix - fix potential double free vmwgfx: - drop rcu usage to make code more robust virtio: - fix use-after-free in gem handle code nouveau: - drop unused nouveau_fbcon.c" * tag 'drm-fixes-2023-01-13' of git://anongit.freedesktop.org/drm/drm: (35 commits) drm: Optimize drm buddy top-down allocation method drm/ttm: Fix a regression causing kernel oops'es drm/i915/gt: Cover rest of SVG unit MCR registers drm/nouveau: Remove file nouveau_fbcon.c drm/amdkfd: Fix NULL pointer error for GC 11.0.1 on mGPU drm/amd/pm/smu13: BACO is supported when it's in BACO state drm/amdkfd: Add sync after creating vram bo drm/i915/gt: Reset twice drm/amdgpu: fix pipeline sync v2 drm/vmwgfx: Remove rcu locks from user resources drm/virtio: Fix GEM handle creation UAF drm/amdgpu: Fixed bug on error when unloading amdgpu drm/amd: Delay removal of the firmware framebuffer drm/amdgpu: Fix potential NULL dereference drm/i915: Fix potential context UAFs drm/i915: Reserve enough fence slot for i915_vma_unbind_async drm: Add orientation quirk for Lenovo ideapad D330-10IGL drm/msm/a6xx: Avoid gx gbit halt during rpm suspend drm/msm/adreno: Make adreno quirks not overwrite each other drm/msm: another fix for the headless Adreno GPU ...

Linus Torvalds committed 3 years ago

Commit ff5ebaf2 parents d45b832 e695bc743 files · +332 −950Browse files

Unified · Split

43 files
  1. Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml +1 −3
  2. Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml +0 −1
  3. Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml +0 −1
  4. Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml +4 −0
  5. Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml +1 −1
  6. Documentation/devicetree/bindings/display/msm/qcom,sm6115-mdss.yaml +1 −1
  7. drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +1 −1
  8. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +34 −17
  9. drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +8 −0
  10. drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +0 −6
  11. drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +3 −2
  12. drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +3 −1
  13. drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +1 −1
  14. drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +1 −1
  15. drivers/gpu/drm/amd/amdkfd/kfd_svm.c +9 −0
  16. drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +6 −2
  17. drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +1 −0
  18. drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +1 −0
  19. drivers/gpu/drm/drm_buddy.c +54 −27
  20. drivers/gpu/drm/drm_panel_orientation_quirks.c +6 −0
  21. drivers/gpu/drm/i915/gem/i915_gem_context.c +18 −6
  22. drivers/gpu/drm/i915/gt/intel_gt_regs.h +2 −2
  23. drivers/gpu/drm/i915/gt/intel_reset.c +28 −6
  24. drivers/gpu/drm/i915/gt/intel_workarounds.c +2 −2
  25. drivers/gpu/drm/i915/i915_vma.c +1 −1
  26. drivers/gpu/drm/msm/adreno/a6xx_gmu.c +9 −6
  27. drivers/gpu/drm/msm/adreno/a6xx_gpu.c +7 −0
  28. drivers/gpu/drm/msm/adreno/a6xx_gpu.h +1 −0
  29. drivers/gpu/drm/msm/adreno/adreno_gpu.h +4 −6
  30. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +1 −2
  31. drivers/gpu/drm/msm/dp/dp_aux.c +4 −0
  32. drivers/gpu/drm/msm/hdmi/hdmi.c +10 −2
  33. drivers/gpu/drm/msm/msm_drv.c +1 −1
  34. drivers/gpu/drm/msm/msm_mdss.c +4 −2
  35. drivers/gpu/drm/nouveau/nouveau_fbcon.c +0 −613
  36. drivers/gpu/drm/ttm/ttm_bo_util.c +1 −1
  37. drivers/gpu/drm/virtio/virtgpu_ioctl.c +17 −2
  38. drivers/gpu/drm/vmwgfx/ttm_object.c +4 −37
  39. drivers/gpu/drm/vmwgfx/ttm_object.h +0 −14
  40. drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +0 −38
  41. drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +1 −17
  42. drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +82 −94
  43. drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +0 −33
Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml+1−3
@@ -32,7 +32,7 @@ properties: · 31 unmodified lines
3232 - description: Display byte clock
3333 - description: Display byte interface clock
3434 - description: Display pixel clock
35− - description: Display escape clock
35+ - description: Display core clock
3636 - description: Display AHB clock
3737 - description: Display AXI clock
3838
@@ -137,8 +137,6 @@ required: · 98 unmodified lines
137137 - phys
138138 - assigned-clocks
139139 - assigned-clock-parents
140− - power-domains
141− - operating-points-v2
142140 - ports
143141
144142 additionalProperties: false
Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml+0−1
@@ -69,7 +69,6 @@ required: · 68 unmodified lines
6969 - compatible
7070 - reg
7171 - reg-names
72− - vdds-supply
7372
7473 unevaluatedProperties: false
7574
Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml+0−1
@@ -39,7 +39,6 @@ required: · 38 unmodified lines
3939 - compatible
4040 - reg
4141 - reg-names
42− - vcca-supply
4342
4443 unevaluatedProperties: false
4544
Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml+4−0
@@ -34,6 +34,10 @@ properties: · 33 unmodified lines
3434 vddio-supply:
3535 description: Phandle to vdd-io regulator device node.
3636
37+ qcom,dsi-phy-regulator-ldo-mode:
38+ type: boolean
39+ description: Indicates if the LDO mode PHY regulator is wanted.
40+
3741 required:
3842 - compatible
3943 - reg
Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml+1−1
@@ -72,7 +72,7 @@ examples: · 71 unmodified lines
7272 #include <dt-bindings/interconnect/qcom,qcm2290.h>
7373 #include <dt-bindings/power/qcom-rpmpd.h>
7474
75− mdss@5e00000 {
75+ display-subsystem@5e00000 {
7676 #address-cells = <1>;
7777 #size-cells = <1>;
7878 compatible = "qcom,qcm2290-mdss";
Documentation/devicetree/bindings/display/msm/qcom,sm6115-mdss.yaml+1−1
@@ -62,7 +62,7 @@ examples: · 61 unmodified lines
6262 #include <dt-bindings/interrupt-controller/arm-gic.h>
6363 #include <dt-bindings/power/qcom-rpmpd.h>
6464
65− mdss@5e00000 {
65+ display-subsystem@5e00000 {
6666 #address-cells = <1>;
6767 #size-cells = <1>;
6868 compatible = "qcom,sm6115-mdss";
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c+1−1
@@ -2099,7 +2099,7 @@ int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_device *adev, struct amdgpu_b · 2098 unmodified lines
20992099 }
21002100
21012101 amdgpu_amdkfd_remove_eviction_fence(
2102− bo, bo->kfd_bo->process_info->eviction_fence);
2102+ bo, bo->vm_bo->vm->process_info->eviction_fence);
21032103
21042104 amdgpu_bo_unreserve(bo);
21052105
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+34−17
@@ -61,6 +61,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, · 60 unmodified lines
6161 amdgpu_ctx_put(p->ctx);
6262 return -ECANCELED;
6363 }
64+
65+ amdgpu_sync_create(&p->sync);
6466 return 0;
6567 }
6668
@@ -452,18 +454,6 @@ static int amdgpu_syncobj_lookup_and_add(struct amdgpu_cs_parser *p, · 385 unmodified lines
452454 }
453455
454456 r = amdgpu_sync_fence(&p->sync, fence);
455− if (r)
456− goto error;
457−
458− /*
459− * When we have an explicit dependency it might be necessary to insert a
460− * pipeline sync to make sure that all caches etc are flushed and the
461− * next job actually sees the results from the previous one.
462− */
463− if (fence->context == p->gang_leader->base.entity->fence_context)
464− r = amdgpu_sync_fence(&p->gang_leader->explicit_sync, fence);
465−
466−error:
467457 dma_fence_put(fence);
468458 return r;
469459 }
@@ -1188,10 +1178,19 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p) · 718 unmodified lines
11881178 static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
11891179 {
11901180 struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
1181+ struct drm_gpu_scheduler *sched;
11911182 struct amdgpu_bo_list_entry *e;
1183+ struct dma_fence *fence;
11921184 unsigned int i;
11931185 int r;
11941186
1187+ r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entities[p->gang_leader_idx]);
1188+ if (r) {
1189+ if (r != -ERESTARTSYS)
1190+ DRM_ERROR("amdgpu_ctx_wait_prev_fence failed.\n");
1191+ return r;
1192+ }
1193+
11951194 list_for_each_entry(e, &p->validated, tv.head) {
11961195 struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
11971196 struct dma_resv *resv = bo->tbo.base.resv;
@@ -1211,10 +1210,24 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p) · 13 unmodified lines
12111210 return r;
12121211 }
12131212
1214− r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entities[p->gang_leader_idx]);
1215− if (r && r != -ERESTARTSYS)
1216− DRM_ERROR("amdgpu_ctx_wait_prev_fence failed.\n");
1217− return r;
1213+ sched = p->gang_leader->base.entity->rq->sched;
1214+ while ((fence = amdgpu_sync_get_fence(&p->sync))) {
1215+ struct drm_sched_fence *s_fence = to_drm_sched_fence(fence);
1216+
1217+ /*
1218+ * When we have an dependency it might be necessary to insert a
1219+ * pipeline sync to make sure that all caches etc are flushed and the
1220+ * next job actually sees the results from the previous one
1221+ * before we start executing on the same scheduler ring.
1222+ */
1223+ if (!s_fence || s_fence->sched != sched)
1224+ continue;
1225+
1226+ r = amdgpu_sync_fence(&p->gang_leader->explicit_sync, fence);
1227+ if (r)
1228+ return r;
1229+ }
1230+ return 0;
12181231 }
12191232
12201233 static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
@@ -1254,9 +1267,12 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 33 unmodified lines
12541267 continue;
12551268
12561269 fence = &p->jobs[i]->base.s_fence->scheduled;
1270+ dma_fence_get(fence);
12571271 r = drm_sched_job_add_dependency(&leader->base, fence);
1258− if (r)
1272+ if (r) {
1273+ dma_fence_put(fence);
12591274 goto error_cleanup;
1275+ }
12601276 }
12611277
12621278 if (p->gang_size > 1) {
@@ -1344,6 +1360,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser) · 81 unmodified lines
13441360 {
13451361 unsigned i;
13461362
1363+ amdgpu_sync_free(&parser->sync);
13471364 for (i = 0; i < parser->num_post_deps; i++) {
13481365 drm_syncobj_put(parser->post_deps[i].syncobj);
13491366 kfree(parser->post_deps[i].chain);
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c+8−0
@@ -36,6 +36,7 @@ · 35 unmodified lines
3636 #include <generated/utsrelease.h>
3737 #include <linux/pci-p2pdma.h>
3838
39+#include <drm/drm_aperture.h>
3940 #include <drm/drm_atomic_helper.h>
4041 #include <drm/drm_fb_helper.h>
4142 #include <drm/drm_probe_helper.h>
@@ -90,6 +91,8 @@ MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin"); · 48 unmodified lines
9091 #define AMDGPU_MAX_RETRY_LIMIT 2
9192 #define AMDGPU_RETRY_SRIOV_RESET(r) ((r) == -EBUSY || (r) == -ETIMEDOUT || (r) == -EINVAL)
9293
94+static const struct drm_driver amdgpu_kms_driver;
95+
9396 const char *amdgpu_asic_name[] = {
9497 "TAHITI",
9598 "PITCAIRN",
@@ -3687,6 +3690,11 @@ int amdgpu_device_init(struct amdgpu_device *adev, · 3591 unmodified lines
36873690 if (r)
36883691 return r;
36893692
3693+ /* Get rid of things like offb */
3694+ r = drm_aperture_remove_conflicting_pci_framebuffers(adev->pdev, &amdgpu_kms_driver);
3695+ if (r)
3696+ return r;
3697+
36903698 /* Enable TMZ based on IP_VERSION */
36913699 amdgpu_gmc_tmz_set(adev);
36923700
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c+0−6
@@ -23,7 +23,6 @@ · 22 unmodified lines
2323 */
2424
2525 #include <drm/amdgpu_drm.h>
26−#include <drm/drm_aperture.h>
2726 #include <drm/drm_drv.h>
2827 #include <drm/drm_fbdev_generic.h>
2928 #include <drm/drm_gem.h>
@@ -2122,11 +2121,6 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, · 2092 unmodified lines
21222121 }
21232122 #endif
21242123
2125− /* Get rid of things like offb */
2126− ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &amdgpu_kms_driver);
2127− if (ret)
2128− return ret;
2129−
21302124 adev = devm_drm_dev_alloc(&pdev->dev, &amdgpu_kms_driver, typeof(*adev), ddev);
21312125 if (IS_ERR(adev))
21322126 return PTR_ERR(adev);
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c+3−2
@@ -470,8 +470,9 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev, · 469 unmodified lines
470470 return true;
471471
472472 fail:
473− DRM_DEBUG("BO size %lu > total memory in domain: %llu\n", size,
474− man->size);
473+ if (man)
474+ DRM_DEBUG("BO size %lu > total memory in domain: %llu\n", size,
475+ man->size);
475476 return false;
476477 }
477478
drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c+3−1
@@ -391,8 +391,10 @@ int amdgpu_sync_push_to_job(struct amdgpu_sync *sync, struct amdgpu_job *job) · 390 unmodified lines
391391
392392 dma_fence_get(f);
393393 r = drm_sched_job_add_dependency(&job->base, f);
394− if (r)
394+ if (r) {
395+ dma_fence_put(f);
395396 return r;
397+ }
396398 }
397399 return 0;
398400 }
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c+1−1
@@ -882,7 +882,7 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev) · 881 unmodified lines
882882 kfree(rsv);
883883
884884 list_for_each_entry_safe(rsv, temp, &mgr->reserved_pages, blocks) {
885− drm_buddy_free_list(&mgr->mm, &rsv->blocks);
885+ drm_buddy_free_list(&mgr->mm, &rsv->allocated);
886886 kfree(rsv);
887887 }
888888 drm_buddy_fini(&mgr->mm);
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c+1−1
@@ -200,7 +200,7 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q, · 199 unmodified lines
200200 queue_input.wptr_addr = (uint64_t)q->properties.write_ptr;
201201
202202 if (q->wptr_bo) {
203− wptr_addr_off = (uint64_t)q->properties.write_ptr - (uint64_t)q->wptr_bo->kfd_bo->va;
203+ wptr_addr_off = (uint64_t)q->properties.write_ptr & (PAGE_SIZE - 1);
204204 queue_input.wptr_mc_addr = ((uint64_t)q->wptr_bo->tbo.resource->start << PAGE_SHIFT) + wptr_addr_off;
205205 }
206206
drivers/gpu/drm/amd/amdkfd/kfd_svm.c+9−0
@@ -570,6 +570,15 @@ svm_range_vram_node_new(struct amdgpu_device *adev, struct svm_range *prange, · 569 unmodified lines
570570 goto reserve_bo_failed;
571571 }
572572
573+ if (clear) {
574+ r = amdgpu_bo_sync_wait(bo, AMDGPU_FENCE_OWNER_KFD, false);
575+ if (r) {
576+ pr_debug("failed %d to sync bo\n", r);
577+ amdgpu_bo_unreserve(bo);
578+ goto reserve_bo_failed;
579+ }
580+ }
581+
573582 r = dma_resv_reserve_fences(bo->tbo.base.resv, 1);
574583 if (r) {
575584 pr_debug("failed %d to reserve bo\n", r);
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c+6−2
@@ -1261,7 +1261,8 @@ int smu_v13_0_set_fan_speed_rpm(struct smu_context *smu, · 1260 unmodified lines
12611261 uint32_t speed)
12621262 {
12631263 struct amdgpu_device *adev = smu->adev;
1264− uint32_t tach_period, crystal_clock_freq;
1264+ uint32_t crystal_clock_freq = 2500;
1265+ uint32_t tach_period;
12651266 int ret;
12661267
12671268 if (!speed)
@@ -1271,7 +1272,6 @@ int smu_v13_0_set_fan_speed_rpm(struct smu_context *smu, · 3 unmodified lines
12711272 if (ret)
12721273 return ret;
12731274
1274− crystal_clock_freq = amdgpu_asic_get_xclk(adev);
12751275 tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed);
12761276 WREG32_SOC15(THM, 0, regCG_TACH_CTRL,
12771277 REG_SET_FIELD(RREG32_SOC15(THM, 0, regCG_TACH_CTRL),
@@ -2298,6 +2298,10 @@ bool smu_v13_0_baco_is_support(struct smu_context *smu) · 1020 unmodified lines
22982298 !smu_baco->platform_support)
22992299 return false;
23002300
2301+ /* return true if ASIC is in BACO state already */
2302+ if (smu_v13_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER)
2303+ return true;
2304+
23012305 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) &&
23022306 !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT))
23032307 return false;
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c+1−0
@@ -213,6 +213,7 @@ static struct cmn2asic_mapping smu_v13_0_0_feature_mask_map[SMU_FEATURE_COUNT] = · 212 unmodified lines
213213 FEA_MAP(SOC_PCC),
214214 [SMU_FEATURE_DPM_VCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
215215 [SMU_FEATURE_DPM_DCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
216+ [SMU_FEATURE_PPT_BIT] = {1, FEATURE_THROTTLERS_BIT},
216217 };
217218
218219 static struct cmn2asic_mapping smu_v13_0_0_table_map[SMU_TABLE_COUNT] = {
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c+1−0
@@ -192,6 +192,7 @@ static struct cmn2asic_mapping smu_v13_0_7_feature_mask_map[SMU_FEATURE_COUNT] = · 191 unmodified lines
192192 FEA_MAP(SOC_PCC),
193193 [SMU_FEATURE_DPM_VCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
194194 [SMU_FEATURE_DPM_DCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
195+ [SMU_FEATURE_PPT_BIT] = {1, FEATURE_THROTTLERS_BIT},
195196 };
196197
197198 static struct cmn2asic_mapping smu_v13_0_7_table_map[SMU_TABLE_COUNT] = {
drivers/gpu/drm/drm_buddy.c+54−27
@@ -38,6 +38,25 @@ static void drm_block_free(struct drm_buddy *mm, · 37 unmodified lines
3838 kmem_cache_free(slab_blocks, block);
3939 }
4040
41+static void list_insert_sorted(struct drm_buddy *mm,
42+ struct drm_buddy_block *block)
43+{
44+ struct drm_buddy_block *node;
45+ struct list_head *head;
46+
47+ head = &mm->free_list[drm_buddy_block_order(block)];
48+ if (list_empty(head)) {
49+ list_add(&block->link, head);
50+ return;
51+ }
52+
53+ list_for_each_entry(node, head, link)
54+ if (drm_buddy_block_offset(block) < drm_buddy_block_offset(node))
55+ break;
56+
57+ __list_add(&block->link, node->link.prev, &node->link);
58+}
59+
4160 static void mark_allocated(struct drm_buddy_block *block)
4261 {
4362 block->header &= ~DRM_BUDDY_HEADER_STATE;
@@ -52,8 +71,7 @@ static void mark_free(struct drm_buddy *mm, · 8 unmodified lines
5271 block->header &= ~DRM_BUDDY_HEADER_STATE;
5372 block->header |= DRM_BUDDY_FREE;
5473
55− list_add(&block->link,
56− &mm->free_list[drm_buddy_block_order(block)]);
74+ list_insert_sorted(mm, block);
5775 }
5876
5977 static void mark_split(struct drm_buddy_block *block)
@@ -387,20 +405,26 @@ err_undo: · 327 unmodified lines
387405 }
388406
389407 static struct drm_buddy_block *
390−get_maxblock(struct list_head *head)
408+get_maxblock(struct drm_buddy *mm, unsigned int order)
391409 {
392410 struct drm_buddy_block *max_block = NULL, *node;
411+ unsigned int i;
393412
394− max_block = list_first_entry_or_null(head,
395− struct drm_buddy_block,
396− link);
397− if (!max_block)
398− return NULL;
413+ for (i = order; i <= mm->max_order; ++i) {
414+ if (!list_empty(&mm->free_list[i])) {
415+ node = list_last_entry(&mm->free_list[i],
416+ struct drm_buddy_block,
417+ link);
418+ if (!max_block) {
419+ max_block = node;
420+ continue;
421+ }
399422
400− list_for_each_entry(node, head, link) {
401− if (drm_buddy_block_offset(node) >
402− drm_buddy_block_offset(max_block))
403− max_block = node;
423+ if (drm_buddy_block_offset(node) >
424+ drm_buddy_block_offset(max_block)) {
425+ max_block = node;
426+ }
427+ }
404428 }
405429
406430 return max_block;
@@ -412,20 +436,23 @@ alloc_from_freelist(struct drm_buddy *mm, · 5 unmodified lines
412436 unsigned long flags)
413437 {
414438 struct drm_buddy_block *block = NULL;
415− unsigned int i;
439+ unsigned int tmp;
416440 int err;
417441
418− for (i = order; i <= mm->max_order; ++i) {
419− if (flags & DRM_BUDDY_TOPDOWN_ALLOCATION) {
420− block = get_maxblock(&mm->free_list[i]);
421− if (block)
422− break;
423− } else {
424− block = list_first_entry_or_null(&mm->free_list[i],
425− struct drm_buddy_block,
426− link);
427− if (block)
428− break;
442+ if (flags & DRM_BUDDY_TOPDOWN_ALLOCATION) {
443+ block = get_maxblock(mm, order);
444+ if (block)
445+ /* Store the obtained block order */
446+ tmp = drm_buddy_block_order(block);
447+ } else {
448+ for (tmp = order; tmp <= mm->max_order; ++tmp) {
449+ if (!list_empty(&mm->free_list[tmp])) {
450+ block = list_last_entry(&mm->free_list[tmp],
451+ struct drm_buddy_block,
452+ link);
453+ if (block)
454+ break;
455+ }
429456 }
430457 }
431458
@@ -434,18 +461,18 @@ alloc_from_freelist(struct drm_buddy *mm, · 2 unmodified lines
434461
435462 BUG_ON(!drm_buddy_block_is_free(block));
436463
437− while (i != order) {
464+ while (tmp != order) {
438465 err = split_block(mm, block);
439466 if (unlikely(err))
440467 goto err_undo;
441468
442469 block = block->right;
443− i--;
470+ tmp--;
444471 }
445472 return block;
446473
447474 err_undo:
448− if (i != order)
475+ if (tmp != order)
449476 __drm_buddy_free(mm, block);
450477 return ERR_PTR(err);
451478 }
drivers/gpu/drm/drm_panel_orientation_quirks.c+6−0
@@ -304,6 +304,12 @@ static const struct dmi_system_id orientation_data[] = { · 303 unmodified lines
304304 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"),
305305 },
306306 .driver_data = (void *)&lcd1200x1920_rightside_up,
307+ }, { /* Lenovo Ideapad D330-10IGL (HD) */
308+ .matches = {
309+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
310+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGL"),
311+ },
312+ .driver_data = (void *)&lcd800x1280_rightside_up,
307313 }, { /* Lenovo Yoga Book X90F / X91F / X91L */
308314 .matches = {
309315 /* Non exact match to match all versions */
drivers/gpu/drm/i915/gem/i915_gem_context.c+18−6
@@ -1688,6 +1688,10 @@ void i915_gem_init__contexts(struct drm_i915_private *i915) · 1687 unmodified lines
16881688 init_contexts(&i915->gem.contexts);
16891689 }
16901690
1691+/*
1692+ * Note that this implicitly consumes the ctx reference, by placing
1693+ * the ctx in the context_xa.
1694+ */
16911695 static void gem_context_register(struct i915_gem_context *ctx,
16921696 struct drm_i915_file_private *fpriv,
16931697 u32 id)
@@ -1703,10 +1707,6 @@ static void gem_context_register(struct i915_gem_context *ctx, · 9 unmodified lines
17031707 snprintf(ctx->name, sizeof(ctx->name), "%s[%d]",
17041708 current->comm, pid_nr(ctx->pid));
17051709
1706− /* And finally expose ourselves to userspace via the idr */
1707− old = xa_store(&fpriv->context_xa, id, ctx, GFP_KERNEL);
1708− WARN_ON(old);
1709−
17101710 spin_lock(&ctx->client->ctx_lock);
17111711 list_add_tail_rcu(&ctx->client_link, &ctx->client->ctx_list);
17121712 spin_unlock(&ctx->client->ctx_lock);
@@ -1714,6 +1714,10 @@ static void gem_context_register(struct i915_gem_context *ctx, · 1 unmodified line
17141714 spin_lock(&i915->gem.contexts.lock);
17151715 list_add_tail(&ctx->link, &i915->gem.contexts.list);
17161716 spin_unlock(&i915->gem.contexts.lock);
1717+
1718+ /* And finally expose ourselves to userspace via the idr */
1719+ old = xa_store(&fpriv->context_xa, id, ctx, GFP_KERNEL);
1720+ WARN_ON(old);
17171721 }
17181722
17191723 int i915_gem_context_open(struct drm_i915_private *i915,
@@ -2199,14 +2203,22 @@ finalize_create_context_locked(struct drm_i915_file_private *file_priv, · 479 unmodified lines
21992203 if (IS_ERR(ctx))
22002204 return ctx;
22012205
2206+ /*
2207+ * One for the xarray and one for the caller. We need to grab
2208+ * the reference *prior* to making the ctx visble to userspace
2209+ * in gem_context_register(), as at any point after that
2210+ * userspace can try to race us with another thread destroying
2211+ * the context under our feet.
2212+ */
2213+ i915_gem_context_get(ctx);
2214+
22022215 gem_context_register(ctx, file_priv, id);
22032216
22042217 old = xa_erase(&file_priv->proto_context_xa, id);
22052218 GEM_BUG_ON(old != pc);
22062219 proto_context_close(file_priv->dev_priv, pc);
22072220
2208− /* One for the xarray and one for the caller */
2209− return i915_gem_context_get(ctx);
2221+ return ctx;
22102222 }
22112223
22122224 struct i915_gem_context *
drivers/gpu/drm/i915/gt/intel_gt_regs.h+2−2
@@ -406,10 +406,10 @@ · 405 unmodified lines
406406 #define GEN9_WM_CHICKEN3 _MMIO(0x5588)
407407 #define GEN9_FACTOR_IN_CLR_VAL_HIZ (1 << 9)
408408
409−#define CHICKEN_RASTER_1 _MMIO(0x6204)
409+#define CHICKEN_RASTER_1 MCR_REG(0x6204)
410410 #define DIS_SF_ROUND_NEAREST_EVEN REG_BIT(8)
411411
412−#define CHICKEN_RASTER_2 _MMIO(0x6208)
412+#define CHICKEN_RASTER_2 MCR_REG(0x6208)
413413 #define TBIMR_FAST_CLIP REG_BIT(5)
414414
415415 #define VFLSKPD MCR_REG(0x62a8)
drivers/gpu/drm/i915/gt/intel_reset.c+28−6
@@ -278,6 +278,7 @@ out: · 277 unmodified lines
278278 static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask)
279279 {
280280 struct intel_uncore *uncore = gt->uncore;
281+ int loops = 2;
281282 int err;
282283
283284 /*
@@ -285,18 +286,39 @@ static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask) · 1 unmodified line
285286 * for fifo space for the write or forcewake the chip for
286287 * the read
287288 */
288− intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask);
289+ do {
290+ intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask);
289291
290− /* Wait for the device to ack the reset requests */
291− err = __intel_wait_for_register_fw(uncore,
292− GEN6_GDRST, hw_domain_mask, 0,
293− 500, 0,
294− NULL);
292+ /*
293+ * Wait for the device to ack the reset requests.
294+ *
295+ * On some platforms, e.g. Jasperlake, we see that the
296+ * engine register state is not cleared until shortly after
297+ * GDRST reports completion, causing a failure as we try
298+ * to immediately resume while the internal state is still
299+ * in flux. If we immediately repeat the reset, the second
300+ * reset appears to serialise with the first, and since
301+ * it is a no-op, the registers should retain their reset
302+ * value. However, there is still a concern that upon
303+ * leaving the second reset, the internal engine state
304+ * is still in flux and not ready for resuming.
305+ */
306+ err = __intel_wait_for_register_fw(uncore, GEN6_GDRST,
307+ hw_domain_mask, 0,
308+ 2000, 0,
309+ NULL);
310+ } while (err == 0 && --loops);
295311 if (err)
296312 GT_TRACE(gt,
297313 "Wait for 0x%08x engines reset failed\n",
298314 hw_domain_mask);
299315
316+ /*
317+ * As we have observed that the engine state is still volatile
318+ * after GDRST is acked, impose a small delay to let everything settle.
319+ */
320+ udelay(50);
321+
300322 return err;
301323 }
302324
drivers/gpu/drm/i915/gt/intel_workarounds.c+2−2
@@ -645,7 +645,7 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, · 644 unmodified lines
645645 static void dg2_ctx_gt_tuning_init(struct intel_engine_cs *engine,
646646 struct i915_wa_list *wal)
647647 {
648− wa_masked_en(wal, CHICKEN_RASTER_2, TBIMR_FAST_CLIP);
648+ wa_mcr_masked_en(wal, CHICKEN_RASTER_2, TBIMR_FAST_CLIP);
649649 wa_mcr_write_clr_set(wal, XEHP_L3SQCREG5, L3_PWM_TIMER_INIT_VAL_MASK,
650650 REG_FIELD_PREP(L3_PWM_TIMER_INIT_VAL_MASK, 0x7f));
651651 wa_mcr_add(wal,
@@ -775,7 +775,7 @@ static void dg2_ctx_workarounds_init(struct intel_engine_cs *engine, · 123 unmodified lines
775775 wa_masked_field_set(wal, VF_PREEMPTION, PREEMPTION_VERTEX_COUNT, 0x4000);
776776
777777 /* Wa_15010599737:dg2 */
778− wa_masked_en(wal, CHICKEN_RASTER_1, DIS_SF_ROUND_NEAREST_EVEN);
778+ wa_mcr_masked_en(wal, CHICKEN_RASTER_1, DIS_SF_ROUND_NEAREST_EVEN);
779779 }
780780
781781 static void fakewa_disable_nestedbb_mode(struct intel_engine_cs *engine,
drivers/gpu/drm/i915/i915_vma.c+1−1
@@ -2116,7 +2116,7 @@ int i915_vma_unbind_async(struct i915_vma *vma, bool trylock_vm) · 2115 unmodified lines
21162116 if (!obj->mm.rsgt)
21172117 return -EBUSY;
21182118
2119− err = dma_resv_reserve_fences(obj->base.resv, 1);
2119+ err = dma_resv_reserve_fences(obj->base.resv, 2);
21202120 if (err)
21212121 return -EBUSY;
21222122
drivers/gpu/drm/msm/adreno/a6xx_gmu.c+9−6
@@ -876,7 +876,8 @@ static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu) · 875 unmodified lines
876876 #define GBIF_CLIENT_HALT_MASK BIT(0)
877877 #define GBIF_ARB_HALT_MASK BIT(1)
878878
879−static void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu)
879+static void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu,
880+ bool gx_off)
880881 {
881882 struct msm_gpu *gpu = &adreno_gpu->base;
882883
@@ -889,9 +890,11 @@ static void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu) · 6 unmodified lines
889890 return;
890891 }
891892
892− /* Halt the gx side of GBIF */
893− gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 1);
894− spin_until(gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT_ACK) & 1);
893+ if (gx_off) {
894+ /* Halt the gx side of GBIF */
895+ gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 1);
896+ spin_until(gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT_ACK) & 1);
897+ }
895898
896899 /* Halt new client requests on GBIF */
897900 gpu_write(gpu, REG_A6XX_GBIF_HALT, GBIF_CLIENT_HALT_MASK);
@@ -929,7 +932,7 @@ static void a6xx_gmu_force_off(struct a6xx_gmu *gmu) · 31 unmodified lines
929932 /* Halt the gmu cm3 core */
930933 gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
931934
932− a6xx_bus_clear_pending_transactions(adreno_gpu);
935+ a6xx_bus_clear_pending_transactions(adreno_gpu, true);
933936
934937 /* Reset GPU core blocks */
935938 gpu_write(gpu, REG_A6XX_RBBM_SW_RESET_CMD, 1);
@@ -1083,7 +1086,7 @@ static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu) · 147 unmodified lines
10831086 return;
10841087 }
10851088
1086− a6xx_bus_clear_pending_transactions(adreno_gpu);
1089+ a6xx_bus_clear_pending_transactions(adreno_gpu, a6xx_gpu->hung);
10871090
10881091 /* tell the GMU we want to slumber */
10891092 ret = a6xx_gmu_notify_slumber(gmu);
drivers/gpu/drm/msm/adreno/a6xx_gpu.c+7−0
@@ -1270,6 +1270,12 @@ static void a6xx_recover(struct msm_gpu *gpu) · 1269 unmodified lines
12701270 if (hang_debug)
12711271 a6xx_dump(gpu);
12721272
1273+ /*
1274+ * To handle recovery specific sequences during the rpm suspend we are
1275+ * about to trigger
1276+ */
1277+ a6xx_gpu->hung = true;
1278+
12731279 /* Halt SQE first */
12741280 gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 3);
12751281
@@ -1312,6 +1318,7 @@ static void a6xx_recover(struct msm_gpu *gpu) · 36 unmodified lines
13121318 mutex_unlock(&gpu->active_lock);
13131319
13141320 msm_gpu_hw_init(gpu);
1321+ a6xx_gpu->hung = false;
13151322 }
13161323
13171324 static const char *a6xx_uche_fault_block(struct msm_gpu *gpu, u32 mid)
drivers/gpu/drm/msm/adreno/a6xx_gpu.h+1−0
@@ -32,6 +32,7 @@ struct a6xx_gpu { · 31 unmodified lines
3232 void *llc_slice;
3333 void *htw_llc_slice;
3434 bool have_mmu500;
35+ bool hung;
3536 };
3637
3738 #define to_a6xx_gpu(x) container_of(x, struct a6xx_gpu, base)
drivers/gpu/drm/msm/adreno/adreno_gpu.h+4−6
@@ -29,11 +29,9 @@ enum { · 28 unmodified lines
2929 ADRENO_FW_MAX,
3030 };
3131
32−enum adreno_quirks {
33− ADRENO_QUIRK_TWO_PASS_USE_WFI = 1,
34− ADRENO_QUIRK_FAULT_DETECT_MASK = 2,
35− ADRENO_QUIRK_LMLOADKILL_DISABLE = 3,
36−};
32+#define ADRENO_QUIRK_TWO_PASS_USE_WFI BIT(0)
33+#define ADRENO_QUIRK_FAULT_DETECT_MASK BIT(1)
34+#define ADRENO_QUIRK_LMLOADKILL_DISABLE BIT(2)
3735
3836 struct adreno_rev {
3937 uint8_t core;
@@ -65,7 +63,7 @@ struct adreno_info { · 25 unmodified lines
6563 const char *name;
6664 const char *fw[ADRENO_FW_MAX];
6765 uint32_t gmem;
68− enum adreno_quirks quirks;
66+ u64 quirks;
6967 struct msm_gpu *(*init)(struct drm_device *dev);
7068 const char *zapfw;
7169 u32 inactive_period;
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c+1−2
@@ -132,7 +132,6 @@ static void dpu_encoder_phys_wb_set_qos(struct dpu_encoder_phys *phys_enc) · 131 unmodified lines
132132 * dpu_encoder_phys_wb_setup_fb - setup output framebuffer
133133 * @phys_enc: Pointer to physical encoder
134134 * @fb: Pointer to output framebuffer
135− * @wb_roi: Pointer to output region of interest
136135 */
137136 static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc,
138137 struct drm_framebuffer *fb)
@@ -692,7 +691,7 @@ static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops) · 553 unmodified lines
692691
693692 /**
694693 * dpu_encoder_phys_wb_init - initialize writeback encoder
695− * @init: Pointer to init info structure with initialization params
694+ * @p: Pointer to init info structure with initialization params
696695 */
697696 struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
698697 struct dpu_enc_phys_init_params *p)
drivers/gpu/drm/msm/dp/dp_aux.c+4−0
@@ -423,6 +423,10 @@ void dp_aux_isr(struct drm_dp_aux *dp_aux) · 422 unmodified lines
423423
424424 isr = dp_catalog_aux_get_irq(aux->catalog);
425425
426+ /* no interrupts pending, return immediately */
427+ if (!isr)
428+ return;
429+
426430 if (!aux->cmd_busy)
427431 return;
428432
drivers/gpu/drm/msm/hdmi/hdmi.c+10−2
@@ -532,11 +532,19 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev) · 531 unmodified lines
532532
533533 ret = devm_pm_runtime_enable(&pdev->dev);
534534 if (ret)
535− return ret;
535+ goto err_put_phy;
536536
537537 platform_set_drvdata(pdev, hdmi);
538538
539− return component_add(&pdev->dev, &msm_hdmi_ops);
539+ ret = component_add(&pdev->dev, &msm_hdmi_ops);
540+ if (ret)
541+ goto err_put_phy;
542+
543+ return 0;
544+
545+err_put_phy:
546+ msm_hdmi_put_phy(hdmi);
547+ return ret;
540548 }
541549
542550 static int msm_hdmi_dev_remove(struct platform_device *pdev)
drivers/gpu/drm/msm/msm_drv.c+1−1
@@ -1278,7 +1278,7 @@ void msm_drv_shutdown(struct platform_device *pdev) · 1277 unmodified lines
12781278 * msm_drm_init, drm_dev->registered is used as an indicator that the
12791279 * shutdown will be successful.
12801280 */
1281− if (drm && drm->registered)
1281+ if (drm && drm->registered && priv->kms)
12821282 drm_atomic_helper_shutdown(drm);
12831283 }
12841284
drivers/gpu/drm/msm/msm_mdss.c+4−2
@@ -47,15 +47,17 @@ struct msm_mdss { · 46 unmodified lines
4747 static int msm_mdss_parse_data_bus_icc_path(struct device *dev,
4848 struct msm_mdss *msm_mdss)
4949 {
50− struct icc_path *path0 = of_icc_get(dev, "mdp0-mem");
51− struct icc_path *path1 = of_icc_get(dev, "mdp1-mem");
50+ struct icc_path *path0;
51+ struct icc_path *path1;
5252
53+ path0 = of_icc_get(dev, "mdp0-mem");
5354 if (IS_ERR_OR_NULL(path0))
5455 return PTR_ERR_OR_ZERO(path0);
5556
5657 msm_mdss->path[0] = path0;
5758 msm_mdss->num_paths = 1;
5859
60+ path1 = of_icc_get(dev, "mdp1-mem");
5961 if (!IS_ERR_OR_NULL(path1)) {
6062 msm_mdss->path[1] = path1;
6163 msm_mdss->num_paths++;
drivers/gpu/drm/nouveau/nouveau_fbcon.c+0−613
@@ -1,613 +0,0 @@
1−/*
2− * Copyright © 2007 David Airlie
3− *
4− * Permission is hereby granted, free of charge, to any person obtaining a
5− * copy of this software and associated documentation files (the "Software"),
6− * to deal in the Software without restriction, including without limitation
7− * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8− * and/or sell copies of the Software, and to permit persons to whom the
9− * Software is furnished to do so, subject to the following conditions:
10− *
11− * The above copyright notice and this permission notice (including the next
12− * paragraph) shall be included in all copies or substantial portions of the
13− * Software.
14− *
15− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16− * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17− * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18− * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19− * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20− * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21− * DEALINGS IN THE SOFTWARE.
22− *
23− * Authors:
24− * David Airlie
25− */
26−
27−#include <linux/module.h>
28−#include <linux/kernel.h>
29−#include <linux/errno.h>
30−#include <linux/string.h>
31−#include <linux/mm.h>
32−#include <linux/tty.h>
33−#include <linux/sysrq.h>
34−#include <linux/delay.h>
35−#include <linux/init.h>
36−#include <linux/screen_info.h>
37−#include <linux/vga_switcheroo.h>
38−#include <linux/console.h>
39−
40−#include <drm/drm_crtc.h>
41−#include <drm/drm_crtc_helper.h>
42−#include <drm/drm_probe_helper.h>
43−#include <drm/drm_fb_helper.h>
44−#include <drm/drm_fourcc.h>
45−#include <drm/drm_atomic.h>
46−
47−#include "nouveau_drv.h"
48−#include "nouveau_gem.h"
49−#include "nouveau_bo.h"
50−#include "nouveau_fbcon.h"
51−#include "nouveau_chan.h"
52−#include "nouveau_vmm.h"
53−
54−#include "nouveau_crtc.h"
55−
56−MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
57−int nouveau_nofbaccel = 0;
58−module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
59−
60−MODULE_PARM_DESC(fbcon_bpp, "fbcon bits-per-pixel (default: auto)");
61−static int nouveau_fbcon_bpp;
62−module_param_named(fbcon_bpp, nouveau_fbcon_bpp, int, 0400);
63−
64−static void
65−nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
66−{
67− struct nouveau_fbdev *fbcon = info->par;
68− struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
69− struct nvif_device *device = &drm->client.device;
70− int ret;
71−
72− if (info->state != FBINFO_STATE_RUNNING)
73− return;
74−
75− ret = -ENODEV;
76− if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) &&
77− mutex_trylock(&drm->client.mutex)) {
78− if (device->info.family < NV_DEVICE_INFO_V0_TESLA)
79− ret = nv04_fbcon_fillrect(info, rect);
80− else
81− if (device->info.family < NV_DEVICE_INFO_V0_FERMI)
82− ret = nv50_fbcon_fillrect(info, rect);
83− else
84− ret = nvc0_fbcon_fillrect(info, rect);
85− mutex_unlock(&drm->client.mutex);
86− }
87−
88− if (ret == 0)
89− return;
90−
91− if (ret != -ENODEV)
92− nouveau_fbcon_gpu_lockup(info);
93− drm_fb_helper_cfb_fillrect(info, rect);
94−}
95−
96−static void
97−nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
98−{
99− struct nouveau_fbdev *fbcon = info->par;
100− struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
101− struct nvif_device *device = &drm->client.device;
102− int ret;
103−
104− if (info->state != FBINFO_STATE_RUNNING)
105− return;
106−
107− ret = -ENODEV;
108− if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) &&
109− mutex_trylock(&drm->client.mutex)) {
110− if (device->info.family < NV_DEVICE_INFO_V0_TESLA)
111− ret = nv04_fbcon_copyarea(info, image);
112− else
113− if (device->info.family < NV_DEVICE_INFO_V0_FERMI)
114− ret = nv50_fbcon_copyarea(info, image);
115− else
116− ret = nvc0_fbcon_copyarea(info, image);
117− mutex_unlock(&drm->client.mutex);
118− }
119−
120− if (ret == 0)
121− return;
122−
123− if (ret != -ENODEV)
124− nouveau_fbcon_gpu_lockup(info);
125− drm_fb_helper_cfb_copyarea(info, image);
126−}
127−
128−static void
129−nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
130−{
131− struct nouveau_fbdev *fbcon = info->par;
132− struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
133− struct nvif_device *device = &drm->client.device;
134− int ret;
135−
136− if (info->state != FBINFO_STATE_RUNNING)
137− return;
138−
139− ret = -ENODEV;
140− if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) &&
141− mutex_trylock(&drm->client.mutex)) {
142− if (device->info.family < NV_DEVICE_INFO_V0_TESLA)
143− ret = nv04_fbcon_imageblit(info, image);
144− else
145− if (device->info.family < NV_DEVICE_INFO_V0_FERMI)
146− ret = nv50_fbcon_imageblit(info, image);
147− else
148− ret = nvc0_fbcon_imageblit(info, image);
149− mutex_unlock(&drm->client.mutex);
150− }
151−
152− if (ret == 0)
153− return;
154−
155− if (ret != -ENODEV)
156− nouveau_fbcon_gpu_lockup(info);
157− drm_fb_helper_cfb_imageblit(info, image);
158−}
159−
160−static int
161−nouveau_fbcon_sync(struct fb_info *info)
162−{
163− struct nouveau_fbdev *fbcon = info->par;
164− struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
165− struct nouveau_channel *chan = drm->channel;
166− int ret;
167−
168− if (!chan || !chan->accel_done || in_interrupt() ||
169− info->state != FBINFO_STATE_RUNNING ||
170− info->flags & FBINFO_HWACCEL_DISABLED)
171− return 0;
172−
173− if (!mutex_trylock(&drm->client.mutex))
174− return 0;
175−
176− ret = nouveau_channel_idle(chan);
177− mutex_unlock(&drm->client.mutex);
178− if (ret) {
179− nouveau_fbcon_gpu_lockup(info);
180− return 0;
181− }
182−
183− chan->accel_done = false;
184− return 0;
185−}
186−
187−static int
188−nouveau_fbcon_open(struct fb_info *info, int user)
189−{
190− struct nouveau_fbdev *fbcon = info->par;
191− struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
192− int ret = pm_runtime_get_sync(drm->dev->dev);
193− if (ret < 0 && ret != -EACCES) {
194− pm_runtime_put(drm->dev->dev);
195− return ret;
196− }
197− return 0;
198−}
199−
200−static int
201−nouveau_fbcon_release(struct fb_info *info, int user)
202−{
203− struct nouveau_fbdev *fbcon = info->par;
204− struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
205− pm_runtime_put(drm->dev->dev);
206− return 0;
207−}
208−
209−static const struct fb_ops nouveau_fbcon_ops = {
210− .owner = THIS_MODULE,
211− DRM_FB_HELPER_DEFAULT_OPS,
212− .fb_open = nouveau_fbcon_open,
213− .fb_release = nouveau_fbcon_release,
214− .fb_fillrect = nouveau_fbcon_fillrect,
215− .fb_copyarea = nouveau_fbcon_copyarea,
216− .fb_imageblit = nouveau_fbcon_imageblit,
217− .fb_sync = nouveau_fbcon_sync,
218−};
219−
220−static const struct fb_ops nouveau_fbcon_sw_ops = {
221− .owner = THIS_MODULE,
222− DRM_FB_HELPER_DEFAULT_OPS,
223− .fb_open = nouveau_fbcon_open,
224− .fb_release = nouveau_fbcon_release,
225− .fb_fillrect = drm_fb_helper_cfb_fillrect,
226− .fb_copyarea = drm_fb_helper_cfb_copyarea,
227− .fb_imageblit = drm_fb_helper_cfb_imageblit,
228−};
229−
230−void
231−nouveau_fbcon_accel_save_disable(struct drm_device *dev)
232−{
233− struct nouveau_drm *drm = nouveau_drm(dev);
234− if (drm->fbcon && drm->fbcon->helper.info) {
235− drm->fbcon->saved_flags = drm->fbcon->helper.info->flags;
236− drm->fbcon->helper.info->flags |= FBINFO_HWACCEL_DISABLED;
237− }
238−}
239−
240−void
241−nouveau_fbcon_accel_restore(struct drm_device *dev)
242−{
243− struct nouveau_drm *drm = nouveau_drm(dev);
244− if (drm->fbcon && drm->fbcon->helper.info)
245− drm->fbcon->helper.info->flags = drm->fbcon->saved_flags;
246−}
247−
248−static void
249−nouveau_fbcon_accel_fini(struct drm_device *dev)
250−{
251− struct nouveau_drm *drm = nouveau_drm(dev);
252− struct nouveau_fbdev *fbcon = drm->fbcon;
253− if (fbcon && drm->channel) {
254− console_lock();
255− if (fbcon->helper.info)
256− fbcon->helper.info->flags |= FBINFO_HWACCEL_DISABLED;
257− console_unlock();
258− nouveau_channel_idle(drm->channel);
259− nvif_object_dtor(&fbcon->twod);
260− nvif_object_dtor(&fbcon->blit);
261− nvif_object_dtor(&fbcon->gdi);
262− nvif_object_dtor(&fbcon->patt);
263− nvif_object_dtor(&fbcon->rop);
264− nvif_object_dtor(&fbcon->clip);
265− nvif_object_dtor(&fbcon->surf2d);
266− }
267−}
268−
269−static void
270−nouveau_fbcon_accel_init(struct drm_device *dev)
271−{
272− struct nouveau_drm *drm = nouveau_drm(dev);
273− struct nouveau_fbdev *fbcon = drm->fbcon;
274− struct fb_info *info = fbcon->helper.info;
275− int ret;
276−
277− if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA)
278− ret = nv04_fbcon_accel_init(info);
279− else
280− if (drm->client.device.info.family < NV_DEVICE_INFO_V0_FERMI)
281− ret = nv50_fbcon_accel_init(info);
282− else
283− ret = nvc0_fbcon_accel_init(info);
284−
285− if (ret == 0)
286− info->fbops = &nouveau_fbcon_ops;
287−}
288−
289−static void
290−nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *fbcon)
291−{
292− struct fb_info *info = fbcon->helper.info;
293− struct fb_fillrect rect;
294−
295− /* Clear the entire fbcon. The drm will program every connector
296− * with it's preferred mode. If the sizes differ, one display will
297− * quite likely have garbage around the console.
298− */
299− rect.dx = rect.dy = 0;
300− rect.width = info->var.xres_virtual;
301− rect.height = info->var.yres_virtual;
302− rect.color = 0;
303− rect.rop = ROP_COPY;
304− info->fbops->fb_fillrect(info, &rect);
305−}
306−
307−static int
308−nouveau_fbcon_create(struct drm_fb_helper *helper,
309− struct drm_fb_helper_surface_size *sizes)
310−{
311− struct nouveau_fbdev *fbcon =
312− container_of(helper, struct nouveau_fbdev, helper);
313− struct drm_device *dev = fbcon->helper.dev;
314− struct nouveau_drm *drm = nouveau_drm(dev);
315− struct nvif_device *device = &drm->client.device;
316− struct fb_info *info;
317− struct drm_framebuffer *fb;
318− struct nouveau_channel *chan;
319− struct nouveau_bo *nvbo;
320− struct drm_mode_fb_cmd2 mode_cmd = {};
321− int ret;
322−
323− mode_cmd.width = sizes->surface_width;
324− mode_cmd.height = sizes->surface_height;
325−
326− mode_cmd.pitches[0] = mode_cmd.width * (sizes->surface_bpp >> 3);
327− mode_cmd.pitches[0] = roundup(mode_cmd.pitches[0], 256);
328−
329− mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
330− sizes->surface_depth);
331−
332− ret = nouveau_gem_new(&drm->client, mode_cmd.pitches[0] *
333− mode_cmd.height, 0, NOUVEAU_GEM_DOMAIN_VRAM,
334− 0, 0x0000, &nvbo);
335− if (ret) {
336− NV_ERROR(drm, "failed to allocate framebuffer\n");
337− goto out;
338− }
339−
340− ret = nouveau_framebuffer_new(dev, &mode_cmd, &nvbo->bo.base, &fb);
341− if (ret)
342− goto out_unref;
343−
344− ret = nouveau_bo_pin(nvbo, NOUVEAU_GEM_DOMAIN_VRAM, false);
345− if (ret) {
346− NV_ERROR(drm, "failed to pin fb: %d\n", ret);
347− goto out_unref;
348− }
349−
350− ret = nouveau_bo_map(nvbo);
351− if (ret) {
352− NV_ERROR(drm, "failed to map fb: %d\n", ret);
353− goto out_unpin;
354− }
355−
356− chan = nouveau_nofbaccel ? NULL : drm->channel;
357− if (chan && device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
358− ret = nouveau_vma_new(nvbo, chan->vmm, &fbcon->vma);
359− if (ret) {
360− NV_ERROR(drm, "failed to map fb into chan: %d\n", ret);
361− chan = NULL;
362− }
363− }
364−
365− info = drm_fb_helper_alloc_info(helper);
366− if (IS_ERR(info)) {
367− ret = PTR_ERR(info);
368− goto out_unlock;
369− }
370−
371− /* setup helper */
372− fbcon->helper.fb = fb;
373−
374− if (!chan)
375− info->flags = FBINFO_HWACCEL_DISABLED;
376− else
377− info->flags = FBINFO_HWACCEL_COPYAREA |
378− FBINFO_HWACCEL_FILLRECT |
379− FBINFO_HWACCEL_IMAGEBLIT;
380− info->fbops = &nouveau_fbcon_sw_ops;
381− info->fix.smem_start = nvbo->bo.resource->bus.offset;
382− info->fix.smem_len = nvbo->bo.base.size;
383−
384− info->screen_base = nvbo_kmap_obj_iovirtual(nvbo);
385− info->screen_size = nvbo->bo.base.size;
386−
387− drm_fb_helper_fill_info(info, &fbcon->helper, sizes);
388−
389− /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
390−
391− if (chan)
392− nouveau_fbcon_accel_init(dev);
393− nouveau_fbcon_zfill(dev, fbcon);
394−
395− /* To allow resizeing without swapping buffers */
396− NV_INFO(drm, "allocated %dx%d fb: 0x%llx, bo %p\n",
397− fb->width, fb->height, nvbo->offset, nvbo);
398−
399− if (dev_is_pci(dev->dev))
400− vga_switcheroo_client_fb_set(to_pci_dev(dev->dev), info);
401−
402− return 0;
403−
404−out_unlock:
405− if (chan)
406− nouveau_vma_del(&fbcon->vma);
407− nouveau_bo_unmap(nvbo);
408−out_unpin:
409− nouveau_bo_unpin(nvbo);
410−out_unref:
411− nouveau_bo_ref(NULL, &nvbo);
412−out:
413− return ret;
414−}
415−
416−static int
417−nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon)
418−{
419− struct drm_framebuffer *fb = fbcon->helper.fb;
420− struct nouveau_bo *nvbo;
421−
422− drm_fb_helper_unregister_info(&fbcon->helper);
423− drm_fb_helper_fini(&fbcon->helper);
424−
425− if (fb && fb->obj[0]) {
426− nvbo = nouveau_gem_object(fb->obj[0]);
427− nouveau_vma_del(&fbcon->vma);
428− nouveau_bo_unmap(nvbo);
429− nouveau_bo_unpin(nvbo);
430− drm_framebuffer_put(fb);
431− }
432−
433− return 0;
434−}
435−
436−void nouveau_fbcon_gpu_lockup(struct fb_info *info)
437−{
438− struct nouveau_fbdev *fbcon = info->par;
439− struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
440−
441− NV_ERROR(drm, "GPU lockup - switching to software fbcon\n");
442− info->flags |= FBINFO_HWACCEL_DISABLED;
443−}
444−
445−static const struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
446− .fb_probe = nouveau_fbcon_create,
447−};
448−
449−static void
450−nouveau_fbcon_set_suspend_work(struct work_struct *work)
451−{
452− struct nouveau_drm *drm = container_of(work, typeof(*drm), fbcon_work);
453− int state = READ_ONCE(drm->fbcon_new_state);
454−
455− if (state == FBINFO_STATE_RUNNING)
456− pm_runtime_get_sync(drm->dev->dev);
457−
458− console_lock();
459− if (state == FBINFO_STATE_RUNNING)
460− nouveau_fbcon_accel_restore(drm->dev);
461− drm_fb_helper_set_suspend(&drm->fbcon->helper, state);
462− if (state != FBINFO_STATE_RUNNING)
463− nouveau_fbcon_accel_save_disable(drm->dev);
464− console_unlock();
465−
466− if (state == FBINFO_STATE_RUNNING) {
467− nouveau_fbcon_hotplug_resume(drm->fbcon);
468− pm_runtime_mark_last_busy(drm->dev->dev);
469− pm_runtime_put_autosuspend(drm->dev->dev);
470− }
471−}
472−
473−void
474−nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
475−{
476− struct nouveau_drm *drm = nouveau_drm(dev);
477−
478− if (!drm->fbcon)
479− return;
480−
481− drm->fbcon_new_state = state;
482− /* Since runtime resume can happen as a result of a sysfs operation,
483− * it's possible we already have the console locked. So handle fbcon
484− * init/deinit from a seperate work thread
485− */
486− schedule_work(&drm->fbcon_work);
487−}
488−
489−void
490−nouveau_fbcon_output_poll_changed(struct drm_device *dev)
491−{
492− struct nouveau_drm *drm = nouveau_drm(dev);
493− struct nouveau_fbdev *fbcon = drm->fbcon;
494− int ret;
495−
496− if (!fbcon)
497− return;
498−
499− mutex_lock(&fbcon->hotplug_lock);
500−
501− ret = pm_runtime_get(dev->dev);
502− if (ret == 1 || ret == -EACCES) {
503− drm_fb_helper_hotplug_event(&fbcon->helper);
504−
505− pm_runtime_mark_last_busy(dev->dev);
506− pm_runtime_put_autosuspend(dev->dev);
507− } else if (ret == 0) {
508− /* If the GPU was already in the process of suspending before
509− * this event happened, then we can't block here as we'll
510− * deadlock the runtime pmops since they wait for us to
511− * finish. So, just defer this event for when we runtime
512− * resume again. It will be handled by fbcon_work.
513− */
514− NV_DEBUG(drm, "fbcon HPD event deferred until runtime resume\n");
515− fbcon->hotplug_waiting = true;
516− pm_runtime_put_noidle(drm->dev->dev);
517− } else {
518− DRM_WARN("fbcon HPD event lost due to RPM failure: %d\n",
519− ret);
520− }
521−
522− mutex_unlock(&fbcon->hotplug_lock);
523−}
524−
525−void
526−nouveau_fbcon_hotplug_resume(struct nouveau_fbdev *fbcon)
527−{
528− struct nouveau_drm *drm;
529−
530− if (!fbcon)
531− return;
532− drm = nouveau_drm(fbcon->helper.dev);
533−
534− mutex_lock(&fbcon->hotplug_lock);
535− if (fbcon->hotplug_waiting) {
536− fbcon->hotplug_waiting = false;
537−
538− NV_DEBUG(drm, "Handling deferred fbcon HPD events\n");
539− drm_fb_helper_hotplug_event(&fbcon->helper);
540− }
541− mutex_unlock(&fbcon->hotplug_lock);
542−}
543−
544−int
545−nouveau_fbcon_init(struct drm_device *dev)
546−{
547− struct nouveau_drm *drm = nouveau_drm(dev);
548− struct nouveau_fbdev *fbcon;
549− int preferred_bpp = nouveau_fbcon_bpp;
550− int ret;
551−
552− if (!dev->mode_config.num_crtc ||
553− (to_pci_dev(dev->dev)->class >> 8) != PCI_CLASS_DISPLAY_VGA)
554− return 0;
555−
556− fbcon = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);
557− if (!fbcon)
558− return -ENOMEM;
559−
560− drm->fbcon = fbcon;
561− INIT_WORK(&drm->fbcon_work, nouveau_fbcon_set_suspend_work);
562− mutex_init(&fbcon->hotplug_lock);
563−
564− drm_fb_helper_prepare(dev, &fbcon->helper, &nouveau_fbcon_helper_funcs);
565−
566− ret = drm_fb_helper_init(dev, &fbcon->helper);
567− if (ret)
568− goto free;
569−
570− if (preferred_bpp != 8 && preferred_bpp != 16 && preferred_bpp != 32) {
571− if (drm->client.device.info.ram_size <= 32 * 1024 * 1024)
572− preferred_bpp = 8;
573− else
574− if (drm->client.device.info.ram_size <= 64 * 1024 * 1024)
575− preferred_bpp = 16;
576− else
577− preferred_bpp = 32;
578− }
579−
580− /* disable all the possible outputs/crtcs before entering KMS mode */
581− if (!drm_drv_uses_atomic_modeset(dev))
582− drm_helper_disable_unused_functions(dev);
583−
584− ret = drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp);
585− if (ret)
586− goto fini;
587−
588− if (fbcon->helper.info)
589− fbcon->helper.info->pixmap.buf_align = 4;
590− return 0;
591−
592−fini:
593− drm_fb_helper_fini(&fbcon->helper);
594−free:
595− kfree(fbcon);
596− drm->fbcon = NULL;
597− return ret;
598−}
599−
600−void
601−nouveau_fbcon_fini(struct drm_device *dev)
602−{
603− struct nouveau_drm *drm = nouveau_drm(dev);
604−
605− if (!drm->fbcon)
606− return;
607−
608− drm_kms_helper_poll_fini(dev);
609− nouveau_fbcon_accel_fini(dev);
610− nouveau_fbcon_destroy(dev, drm->fbcon);
611− kfree(drm->fbcon);
612− drm->fbcon = NULL;
613−}
drivers/gpu/drm/ttm/ttm_bo_util.c+1−1
@@ -173,7 +173,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, · 172 unmodified lines
173173
174174 clear = src_iter->ops->maps_tt && (!ttm || !ttm_tt_is_populated(ttm));
175175 if (!(clear && ttm && !(ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC)))
176− ttm_move_memcpy(clear, ttm->num_pages, dst_iter, src_iter);
176+ ttm_move_memcpy(clear, PFN_UP(dst_mem->size), dst_iter, src_iter);
177177
178178 if (!src_iter->ops->maps_tt)
179179 ttm_kmap_iter_linear_io_fini(&_src_iter.io, bdev, src_mem);
drivers/gpu/drm/virtio/virtgpu_ioctl.c+17−2
@@ -358,10 +358,18 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, · 357 unmodified lines
358358 drm_gem_object_release(obj);
359359 return ret;
360360 }
361− drm_gem_object_put(obj);
362361
363362 rc->res_handle = qobj->hw_res_handle; /* similiar to a VM address */
364363 rc->bo_handle = handle;
364+
365+ /*
366+ * The handle owns the reference now. But we must drop our
367+ * remaining reference *after* we no longer need to dereference
368+ * the obj. Otherwise userspace could guess the handle and
369+ * race closing it from another thread.
370+ */
371+ drm_gem_object_put(obj);
372+
365373 return 0;
366374 }
367375
@@ -723,11 +731,18 @@ static int virtio_gpu_resource_create_blob_ioctl(struct drm_device *dev, · 355 unmodified lines
723731 drm_gem_object_release(obj);
724732 return ret;
725733 }
726− drm_gem_object_put(obj);
727734
728735 rc_blob->res_handle = bo->hw_res_handle;
729736 rc_blob->bo_handle = handle;
730737
738+ /*
739+ * The handle owns the reference now. But we must drop our
740+ * remaining reference *after* we no longer need to dereference
741+ * the obj. Otherwise userspace could guess the handle and
742+ * race closing it from another thread.
743+ */
744+ drm_gem_object_put(obj);
745+
731746 return 0;
732747 }
733748
drivers/gpu/drm/vmwgfx/ttm_object.c+4−37
@@ -254,40 +254,6 @@ void ttm_base_object_unref(struct ttm_base_object **p_base) · 253 unmodified lines
254254 kref_put(&base->refcount, ttm_release_base);
255255 }
256256
257−/**
258− * ttm_base_object_noref_lookup - look up a base object without reference
259− * @tfile: The struct ttm_object_file the object is registered with.
260− * @key: The object handle.
261− *
262− * This function looks up a ttm base object and returns a pointer to it
263− * without refcounting the pointer. The returned pointer is only valid
264− * until ttm_base_object_noref_release() is called, and the object
265− * pointed to by the returned pointer may be doomed. Any persistent usage
266− * of the object requires a refcount to be taken using kref_get_unless_zero().
267− * Iff this function returns successfully it needs to be paired with
268− * ttm_base_object_noref_release() and no sleeping- or scheduling functions
269− * may be called inbetween these function callse.
270− *
271− * Return: A pointer to the object if successful or NULL otherwise.
272− */
273−struct ttm_base_object *
274−ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint64_t key)
275−{
276− struct vmwgfx_hash_item *hash;
277− int ret;
278−
279− rcu_read_lock();
280− ret = ttm_tfile_find_ref_rcu(tfile, key, &hash);
281− if (ret) {
282− rcu_read_unlock();
283− return NULL;
284− }
285−
286− __release(RCU);
287− return hlist_entry(hash, struct ttm_ref_object, hash)->obj;
288−}
289−EXPORT_SYMBOL(ttm_base_object_noref_lookup);
290−
291257 struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile,
292258 uint64_t key)
293259 {
@@ -295,15 +261,16 @@ struct ttm_base_object *ttm_base_object_lookup(struct ttm_object_file *tfile, · 1 unmodified line
295261 struct vmwgfx_hash_item *hash;
296262 int ret;
297263
298− rcu_read_lock();
299− ret = ttm_tfile_find_ref_rcu(tfile, key, &hash);
264+ spin_lock(&tfile->lock);
265+ ret = ttm_tfile_find_ref(tfile, key, &hash);
300266
301267 if (likely(ret == 0)) {
302268 base = hlist_entry(hash, struct ttm_ref_object, hash)->obj;
303269 if (!kref_get_unless_zero(&base->refcount))
304270 base = NULL;
305271 }
306− rcu_read_unlock();
272+ spin_unlock(&tfile->lock);
273+
307274
308275 return base;
309276 }
drivers/gpu/drm/vmwgfx/ttm_object.h+0−14
@@ -307,18 +307,4 @@ extern int ttm_prime_handle_to_fd(struct ttm_object_file *tfile, · 306 unmodified lines
307307 #define ttm_prime_object_kfree(__obj, __prime) \
308308 kfree_rcu(__obj, __prime.base.rhead)
309309
310−struct ttm_base_object *
311−ttm_base_object_noref_lookup(struct ttm_object_file *tfile, uint64_t key);
312−
313−/**
314− * ttm_base_object_noref_release - release a base object pointer looked up
315− * without reference
316− *
317− * Releases a base object pointer looked up with ttm_base_object_noref_lookup().
318− */
319−static inline void ttm_base_object_noref_release(void)
320−{
321− __acquire(RCU);
322− rcu_read_unlock();
323−}
324310 #endif
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c+0−38
@@ -715,44 +715,6 @@ int vmw_user_bo_lookup(struct drm_file *filp, · 714 unmodified lines
715715 return 0;
716716 }
717717
718−/**
719− * vmw_user_bo_noref_lookup - Look up a vmw user buffer object without reference
720− * @filp: The TTM object file the handle is registered with.
721− * @handle: The user buffer object handle.
722− *
723− * This function looks up a struct vmw_bo and returns a pointer to the
724− * struct vmw_buffer_object it derives from without refcounting the pointer.
725− * The returned pointer is only valid until vmw_user_bo_noref_release() is
726− * called, and the object pointed to by the returned pointer may be doomed.
727− * Any persistent usage of the object requires a refcount to be taken using
728− * ttm_bo_reference_unless_doomed(). Iff this function returns successfully it
729− * needs to be paired with vmw_user_bo_noref_release() and no sleeping-
730− * or scheduling functions may be called in between these function calls.
731− *
732− * Return: A struct vmw_buffer_object pointer if successful or negative
733− * error pointer on failure.
734− */
735−struct vmw_buffer_object *
736−vmw_user_bo_noref_lookup(struct drm_file *filp, u32 handle)
737−{
738− struct vmw_buffer_object *vmw_bo;
739− struct ttm_buffer_object *bo;
740− struct drm_gem_object *gobj = drm_gem_object_lookup(filp, handle);
741−
742− if (!gobj) {
743− DRM_ERROR("Invalid buffer object handle 0x%08lx.\n",
744− (unsigned long)handle);
745− return ERR_PTR(-ESRCH);
746− }
747− vmw_bo = gem_to_vmw_bo(gobj);
748− bo = ttm_bo_get_unless_zero(&vmw_bo->base);
749− vmw_bo = vmw_buffer_object(bo);
750− drm_gem_object_put(gobj);
751−
752− return vmw_bo;
753−}
754−
755−
756718 /**
757719 * vmw_bo_fence_single - Utility function to fence a single TTM buffer
758720 * object without unreserving it.
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h+1−17
@@ -830,12 +830,7 @@ extern int vmw_user_resource_lookup_handle( · 829 unmodified lines
830830 uint32_t handle,
831831 const struct vmw_user_resource_conv *converter,
832832 struct vmw_resource **p_res);
833−extern struct vmw_resource *
834−vmw_user_resource_noref_lookup_handle(struct vmw_private *dev_priv,
835− struct ttm_object_file *tfile,
836− uint32_t handle,
837− const struct vmw_user_resource_conv *
838− converter);
833+
839834 extern int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
840835 struct drm_file *file_priv);
841836 extern int vmw_stream_unref_ioctl(struct drm_device *dev, void *data,
@@ -874,15 +869,6 @@ static inline bool vmw_resource_mob_attached(const struct vmw_resource *res) · 32 unmodified lines
874869 return !RB_EMPTY_NODE(&res->mob_node);
875870 }
876871
877−/**
878− * vmw_user_resource_noref_release - release a user resource pointer looked up
879− * without reference
880− */
881−static inline void vmw_user_resource_noref_release(void)
882−{
883− ttm_base_object_noref_release();
884−}
885−
886872 /**
887873 * Buffer object helper functions - vmwgfx_bo.c
888874 */
@@ -934,8 +920,6 @@ extern void vmw_bo_unmap(struct vmw_buffer_object *vbo); · 45 unmodified lines
934920 extern void vmw_bo_move_notify(struct ttm_buffer_object *bo,
935921 struct ttm_resource *mem);
936922 extern void vmw_bo_swap_notify(struct ttm_buffer_object *bo);
937−extern struct vmw_buffer_object *
938−vmw_user_bo_noref_lookup(struct drm_file *filp, u32 handle);
939923
940924 /**
941925 * vmw_bo_adjust_prio - Adjust the buffer object eviction priority
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c+82−94
@@ -290,20 +290,26 @@ static void vmw_execbuf_rcache_update(struct vmw_res_cache_entry *rcache, · 289 unmodified lines
290290 rcache->valid_handle = 0;
291291 }
292292
293+enum vmw_val_add_flags {
294+ vmw_val_add_flag_none = 0,
295+ vmw_val_add_flag_noctx = 1 << 0,
296+};
297+
293298 /**
294− * vmw_execbuf_res_noref_val_add - Add a resource described by an unreferenced
295− * rcu-protected pointer to the validation list.
299+ * vmw_execbuf_res_val_add - Add a resource to the validation list.
296300 *
297301 * @sw_context: Pointer to the software context.
298302 * @res: Unreferenced rcu-protected pointer to the resource.
299303 * @dirty: Whether to change dirty status.
304+ * @flags: specifies whether to use the context or not
300305 *
301306 * Returns: 0 on success. Negative error code on failure. Typical error codes
302307 * are %-EINVAL on inconsistency and %-ESRCH if the resource was doomed.
303308 */
304−static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context,
305− struct vmw_resource *res,
306− u32 dirty)
309+static int vmw_execbuf_res_val_add(struct vmw_sw_context *sw_context,
310+ struct vmw_resource *res,
311+ u32 dirty,
312+ u32 flags)
307313 {
308314 struct vmw_private *dev_priv = res->dev_priv;
309315 int ret;
@@ -318,24 +324,30 @@ static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, · 8 unmodified lines
318324 if (dirty)
319325 vmw_validation_res_set_dirty(sw_context->ctx,
320326 rcache->private, dirty);
321− vmw_user_resource_noref_release();
322327 return 0;
323328 }
324329
325− priv_size = vmw_execbuf_res_size(dev_priv, res_type);
326− ret = vmw_validation_add_resource(sw_context->ctx, res, priv_size,
327− dirty, (void **)&ctx_info,
328− &first_usage);
329− vmw_user_resource_noref_release();
330− if (ret)
331− return ret;
330+ if ((flags & vmw_val_add_flag_noctx) != 0) {
331+ ret = vmw_validation_add_resource(sw_context->ctx, res, 0, dirty,
332+ (void **)&ctx_info, NULL);
333+ if (ret)
334+ return ret;
332335
333− if (priv_size && first_usage) {
334− ret = vmw_cmd_ctx_first_setup(dev_priv, sw_context, res,
335− ctx_info);
336− if (ret) {
337− VMW_DEBUG_USER("Failed first usage context setup.\n");
336+ } else {
337+ priv_size = vmw_execbuf_res_size(dev_priv, res_type);
338+ ret = vmw_validation_add_resource(sw_context->ctx, res, priv_size,
339+ dirty, (void **)&ctx_info,
340+ &first_usage);
341+ if (ret)
338342 return ret;
343+
344+ if (priv_size && first_usage) {
345+ ret = vmw_cmd_ctx_first_setup(dev_priv, sw_context, res,
346+ ctx_info);
347+ if (ret) {
348+ VMW_DEBUG_USER("Failed first usage context setup.\n");
349+ return ret;
350+ }
339351 }
340352 }
341353
@@ -343,43 +355,6 @@ static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, · 1 unmodified line
343355 return 0;
344356 }
345357
346−/**
347− * vmw_execbuf_res_noctx_val_add - Add a non-context resource to the resource
348− * validation list if it's not already on it
349− *
350− * @sw_context: Pointer to the software context.
351− * @res: Pointer to the resource.
352− * @dirty: Whether to change dirty status.
353− *
354− * Returns: Zero on success. Negative error code on failure.
355− */
356−static int vmw_execbuf_res_noctx_val_add(struct vmw_sw_context *sw_context,
357− struct vmw_resource *res,
358− u32 dirty)
359−{
360− struct vmw_res_cache_entry *rcache;
361− enum vmw_res_type res_type = vmw_res_type(res);
362− void *ptr;
363− int ret;
364−
365− rcache = &sw_context->res_cache[res_type];
366− if (likely(rcache->valid && rcache->res == res)) {
367− if (dirty)
368− vmw_validation_res_set_dirty(sw_context->ctx,
369− rcache->private, dirty);
370− return 0;
371− }
372−
373− ret = vmw_validation_add_resource(sw_context->ctx, res, 0, dirty,
374− &ptr, NULL);
375− if (ret)
376− return ret;
377−
378− vmw_execbuf_rcache_update(rcache, res, ptr);
379−
380− return 0;
381−}
382−
383358 /**
384359 * vmw_view_res_val_add - Add a view and the surface it's pointing to to the
385360 * validation list
@@ -398,13 +373,13 @@ static int vmw_view_res_val_add(struct vmw_sw_context *sw_context, · 12 unmodified lines
398373 * First add the resource the view is pointing to, otherwise it may be
399374 * swapped out when the view is validated.
400375 */
401− ret = vmw_execbuf_res_noctx_val_add(sw_context, vmw_view_srf(view),
402− vmw_view_dirtying(view));
376+ ret = vmw_execbuf_res_val_add(sw_context, vmw_view_srf(view),
377+ vmw_view_dirtying(view), vmw_val_add_flag_noctx);
403378 if (ret)
404379 return ret;
405380
406− return vmw_execbuf_res_noctx_val_add(sw_context, view,
407− VMW_RES_DIRTY_NONE);
381+ return vmw_execbuf_res_val_add(sw_context, view, VMW_RES_DIRTY_NONE,
382+ vmw_val_add_flag_noctx);
408383 }
409384
410385 /**
@@ -475,8 +450,9 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, · 64 unmodified lines
475450 if (IS_ERR(res))
476451 continue;
477452
478− ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
479− VMW_RES_DIRTY_SET);
453+ ret = vmw_execbuf_res_val_add(sw_context, res,
454+ VMW_RES_DIRTY_SET,
455+ vmw_val_add_flag_noctx);
480456 if (unlikely(ret != 0))
481457 return ret;
482458 }
@@ -490,9 +466,9 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, · 7 unmodified lines
490466 if (vmw_res_type(entry->res) == vmw_res_view)
491467 ret = vmw_view_res_val_add(sw_context, entry->res);
492468 else
493− ret = vmw_execbuf_res_noctx_val_add
494− (sw_context, entry->res,
495− vmw_binding_dirtying(entry->bt));
469+ ret = vmw_execbuf_res_val_add(sw_context, entry->res,
470+ vmw_binding_dirtying(entry->bt),
471+ vmw_val_add_flag_noctx);
496472 if (unlikely(ret != 0))
497473 break;
498474 }
@@ -658,7 +634,8 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, · 159 unmodified lines
658634 {
659635 struct vmw_res_cache_entry *rcache = &sw_context->res_cache[res_type];
660636 struct vmw_resource *res;
661− int ret;
637+ int ret = 0;
638+ bool needs_unref = false;
662639
663640 if (p_res)
664641 *p_res = NULL;
@@ -683,17 +660,18 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, · 18 unmodified lines
683660 if (ret)
684661 return ret;
685662
686− res = vmw_user_resource_noref_lookup_handle
687− (dev_priv, sw_context->fp->tfile, *id_loc, converter);
688− if (IS_ERR(res)) {
663+ ret = vmw_user_resource_lookup_handle
664+ (dev_priv, sw_context->fp->tfile, *id_loc, converter, &res);
665+ if (ret != 0) {
689666 VMW_DEBUG_USER("Could not find/use resource 0x%08x.\n",
690667 (unsigned int) *id_loc);
691− return PTR_ERR(res);
668+ return ret;
692669 }
670+ needs_unref = true;
693671
694− ret = vmw_execbuf_res_noref_val_add(sw_context, res, dirty);
672+ ret = vmw_execbuf_res_val_add(sw_context, res, dirty, vmw_val_add_flag_none);
695673 if (unlikely(ret != 0))
696− return ret;
674+ goto res_check_done;
697675
698676 if (rcache->valid && rcache->res == res) {
699677 rcache->valid_handle = true;
@@ -708,7 +686,11 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, · 8 unmodified lines
708686 if (p_res)
709687 *p_res = res;
710688
711− return 0;
689+res_check_done:
690+ if (needs_unref)
691+ vmw_resource_unreference(&res);
692+
693+ return ret;
712694 }
713695
714696 /**
@@ -1171,9 +1153,9 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, · 456 unmodified lines
11711153 int ret;
11721154
11731155 vmw_validation_preload_bo(sw_context->ctx);
1174− vmw_bo = vmw_user_bo_noref_lookup(sw_context->filp, handle);
1175− if (IS_ERR(vmw_bo)) {
1176− VMW_DEBUG_USER("Could not find or use MOB buffer.\n");
1156+ ret = vmw_user_bo_lookup(sw_context->filp, handle, &vmw_bo);
1157+ if (ret != 0) {
1158+ drm_dbg(&dev_priv->drm, "Could not find or use MOB buffer.\n");
11771159 return PTR_ERR(vmw_bo);
11781160 }
11791161 ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, true, false);
@@ -1225,9 +1207,9 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, · 45 unmodified lines
12251207 int ret;
12261208
12271209 vmw_validation_preload_bo(sw_context->ctx);
1228− vmw_bo = vmw_user_bo_noref_lookup(sw_context->filp, handle);
1229− if (IS_ERR(vmw_bo)) {
1230− VMW_DEBUG_USER("Could not find or use GMR region.\n");
1210+ ret = vmw_user_bo_lookup(sw_context->filp, handle, &vmw_bo);
1211+ if (ret != 0) {
1212+ drm_dbg(&dev_priv->drm, "Could not find or use GMR region.\n");
12311213 return PTR_ERR(vmw_bo);
12321214 }
12331215 ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, false, false);
@@ -2025,8 +2007,9 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, · 791 unmodified lines
20252007 res = vmw_shader_lookup(vmw_context_res_man(ctx),
20262008 cmd->body.shid, cmd->body.type);
20272009 if (!IS_ERR(res)) {
2028− ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
2029− VMW_RES_DIRTY_NONE);
2010+ ret = vmw_execbuf_res_val_add(sw_context, res,
2011+ VMW_RES_DIRTY_NONE,
2012+ vmw_val_add_flag_noctx);
20302013 if (unlikely(ret != 0))
20312014 return ret;
20322015
@@ -2273,8 +2256,9 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, · 240 unmodified lines
22732256 return PTR_ERR(res);
22742257 }
22752258
2276− ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
2277− VMW_RES_DIRTY_NONE);
2259+ ret = vmw_execbuf_res_val_add(sw_context, res,
2260+ VMW_RES_DIRTY_NONE,
2261+ vmw_val_add_flag_noctx);
22782262 if (ret)
22792263 return ret;
22802264 }
@@ -2777,8 +2761,8 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, · 496 unmodified lines
27772761 return PTR_ERR(res);
27782762 }
27792763
2780− ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
2781− VMW_RES_DIRTY_NONE);
2764+ ret = vmw_execbuf_res_val_add(sw_context, res, VMW_RES_DIRTY_NONE,
2765+ vmw_val_add_flag_noctx);
27822766 if (ret) {
27832767 VMW_DEBUG_USER("Error creating resource validation node.\n");
27842768 return ret;
@@ -3098,8 +3082,8 @@ static int vmw_cmd_dx_bind_streamoutput(struct vmw_private *dev_priv, · 313 unmodified lines
30983082
30993083 vmw_dx_streamoutput_set_size(res, cmd->body.sizeInBytes);
31003084
3101− ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
3102− VMW_RES_DIRTY_NONE);
3085+ ret = vmw_execbuf_res_val_add(sw_context, res, VMW_RES_DIRTY_NONE,
3086+ vmw_val_add_flag_noctx);
31033087 if (ret) {
31043088 DRM_ERROR("Error creating resource validation node.\n");
31053089 return ret;
@@ -3148,8 +3132,8 @@ static int vmw_cmd_dx_set_streamoutput(struct vmw_private *dev_priv, · 42 unmodified lines
31483132 return 0;
31493133 }
31503134
3151− ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
3152− VMW_RES_DIRTY_NONE);
3135+ ret = vmw_execbuf_res_val_add(sw_context, res, VMW_RES_DIRTY_NONE,
3136+ vmw_val_add_flag_noctx);
31533137 if (ret) {
31543138 DRM_ERROR("Error creating resource validation node.\n");
31553139 return ret;
@@ -4066,22 +4050,26 @@ static int vmw_execbuf_tie_context(struct vmw_private *dev_priv, · 910 unmodified lines
40664050 if (ret)
40674051 return ret;
40684052
4069− res = vmw_user_resource_noref_lookup_handle
4053+ ret = vmw_user_resource_lookup_handle
40704054 (dev_priv, sw_context->fp->tfile, handle,
4071− user_context_converter);
4072− if (IS_ERR(res)) {
4055+ user_context_converter, &res);
4056+ if (ret != 0) {
40734057 VMW_DEBUG_USER("Could not find or user DX context 0x%08x.\n",
40744058 (unsigned int) handle);
4075− return PTR_ERR(res);
4059+ return ret;
40764060 }
40774061
4078− ret = vmw_execbuf_res_noref_val_add(sw_context, res, VMW_RES_DIRTY_SET);
4079− if (unlikely(ret != 0))
4062+ ret = vmw_execbuf_res_val_add(sw_context, res, VMW_RES_DIRTY_SET,
4063+ vmw_val_add_flag_none);
4064+ if (unlikely(ret != 0)) {
4065+ vmw_resource_unreference(&res);
40804066 return ret;
4067+ }
40814068
40824069 sw_context->dx_ctx_node = vmw_execbuf_info_from_res(sw_context, res);
40834070 sw_context->man = vmw_context_res_man(res);
40844071
4072+ vmw_resource_unreference(&res);
40854073 return 0;
40864074 }
40874075
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c+0−33
@@ -281,39 +281,6 @@ out_bad_resource: · 280 unmodified lines
281281 return ret;
282282 }
283283
284−/**
285− * vmw_user_resource_noref_lookup_handle - lookup a struct resource from a
286− * TTM user-space handle and perform basic type checks
287− *
288− * @dev_priv: Pointer to a device private struct
289− * @tfile: Pointer to a struct ttm_object_file identifying the caller
290− * @handle: The TTM user-space handle
291− * @converter: Pointer to an object describing the resource type
292− *
293− * If the handle can't be found or is associated with an incorrect resource
294− * type, -EINVAL will be returned.
295− */
296−struct vmw_resource *
297−vmw_user_resource_noref_lookup_handle(struct vmw_private *dev_priv,
298− struct ttm_object_file *tfile,
299− uint32_t handle,
300− const struct vmw_user_resource_conv
301− *converter)
302−{
303− struct ttm_base_object *base;
304−
305− base = ttm_base_object_noref_lookup(tfile, handle);
306− if (!base)
307− return ERR_PTR(-ESRCH);
308−
309− if (unlikely(ttm_base_object_type(base) != converter->object_type)) {
310− ttm_base_object_noref_release();
311− return ERR_PTR(-EINVAL);
312− }
313−
314− return converter->base_obj_to_res(base);
315−}
316−
317284 /*
318285 * Helper function that looks either a surface or bo.
319286 *