From 8e4ee5e87ce60be439eca8d3a65bd870f6821902 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 1 Dec 2022 00:58:02 +0100 Subject: drm/i915: Wrap all access to i915_vma.node.start|size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already wrap i915_vma.node.start for use with the GGTT, as there we can perform additional sanity checks that the node belongs to the GGTT and fits within the 32b registers. In the next couple of patches, we will introduce guard pages around the objects _inside_ the drm_mm_node allocation. That is we will offset the vma->pages so that the first page is at drm_mm_node.start + vma->guard (not 0 as is currently the case). All users must then not use i915_vma.node.start directly, but compute the guard offset, thus all users are converted to use a i915_vma_offset() wrapper. The notable exceptions are the selftests that are testing exact behaviour of i915_vma_pin/i915_vma_insert. Signed-off-by: Chris Wilson Signed-off-by: Tejas Upadhyay Co-developed-by: Thomas Hellström Signed-off-by: Thomas Hellström Signed-off-by: Tvrtko Ursulin Signed-off-by: Andi Shyti Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20221130235805.221010-3-andi.shyti@linux.intel.com --- drivers/gpu/drm/i915/display/intel_fbdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_fbdev.c') diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index ab385d18ddcc..05c3d4739c85 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -284,7 +284,7 @@ static int intelfb_create(struct drm_fb_helper *helper, /* Our framebuffer is the entirety of fbdev's system memory */ info->fix.smem_start = - (unsigned long)(ggtt->gmadr.start + vma->node.start); + (unsigned long)(ggtt->gmadr.start + i915_ggtt_offset(vma)); info->fix.smem_len = vma->size; } -- cgit v1.2.3 From 672279e4bab23cb03c27eece303149568bf21330 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 19 Dec 2022 17:05:02 +0100 Subject: drm/i915: Do not set struct fb_info.apertures Generic fbdev drivers use the apertures field in struct fb_info to control ownership of the framebuffer memory and graphics device. Do not set the values in i915. Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20221219160516.23436-5-tzimmermann@suse.de --- drivers/gpu/drm/i915/display/intel_fbdev.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_fbdev.c') diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 5575d7abdc09..0d19c61b786a 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -267,23 +267,16 @@ static int intelfb_create(struct drm_fb_helper *helper, info->fbops = &intelfb_ops; - /* setup aperture base/size for vesafb takeover */ obj = intel_fb_obj(&intel_fb->base); if (i915_gem_object_is_lmem(obj)) { struct intel_memory_region *mem = obj->mm.region; - info->apertures->ranges[0].base = mem->io_start; - info->apertures->ranges[0].size = mem->io_size; - /* Use fbdev's framebuffer from lmem for discrete */ info->fix.smem_start = (unsigned long)(mem->io_start + i915_gem_object_get_dma_address(obj, 0)); info->fix.smem_len = obj->base.size; } else { - info->apertures->ranges[0].base = ggtt->gmadr.start; - info->apertures->ranges[0].size = ggtt->mappable_end; - /* Our framebuffer is the entirety of fbdev's system memory */ info->fix.smem_start = (unsigned long)(ggtt->gmadr.start + vma->node.start); -- cgit v1.2.3 From 1eca0778f4b35d63cb224a460bcebd5eb13f5da9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 16 Jan 2023 19:34:21 +0200 Subject: drm/i915: add struct i915_dsm to wrap dsm members together Wrap the stolen memory related struct drm_i915_private members (dsm, dsm_reserved, and stolen_usable_size) together in a a new struct i915_dsm. Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20230116173422.1858527-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_fbdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_fbdev.c') diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 5575d7abdc09..f88ccc1bb3ac 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -170,7 +170,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper, * important and we should probably use that space with FBC or other * features. */ - if (size * 2 < dev_priv->stolen_usable_size) + if (size * 2 < dev_priv->dsm.usable_size) obj = i915_gem_object_create_stolen(dev_priv, size); if (IS_ERR(obj)) obj = i915_gem_object_create_shmem(dev_priv, size); -- cgit v1.2.3 From 6c80a93be62d398e1854d95069340b2e60f96166 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 25 Jan 2023 21:04:11 +0100 Subject: drm/fb-helper: Initialize fb-helper's preferred BPP in prepare function Initialize the fb-helper's preferred_bpp field early from within drm_fb_helper_prepare(); instead of the later client hot-plugging callback. This simplifies the generic fbdev setup function. No real changes, but all drivers' fbdev code has to be adapted. v3: * build with CONFIG_DRM_FBDEV_EMULATION unset (kernel test bot) Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230125200415.14123-7-tzimmermann@suse.de --- drivers/gpu/drm/i915/display/intel_fbdev.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_fbdev.c') diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index bbdb98d7c96e..b6f5c554b50f 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -520,10 +520,12 @@ int intel_fbdev_init(struct drm_device *dev) return -ENOMEM; mutex_init(&ifbdev->hpd_lock); - drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs); + drm_fb_helper_prepare(dev, &ifbdev->helper, 32, &intel_fb_helper_funcs); - if (!intel_fbdev_init_bios(dev, ifbdev)) - ifbdev->preferred_bpp = 32; + if (intel_fbdev_init_bios(dev, ifbdev)) + ifbdev->helper.preferred_bpp = ifbdev->preferred_bpp; + else + ifbdev->preferred_bpp = ifbdev->helper.preferred_bpp; ret = drm_fb_helper_init(dev, &ifbdev->helper); if (ret) { @@ -542,8 +544,7 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie) struct intel_fbdev *ifbdev = data; /* Due to peculiar init order wrt to hpd handling this is separate. */ - if (drm_fb_helper_initial_config(&ifbdev->helper, - ifbdev->preferred_bpp)) + if (drm_fb_helper_initial_config(&ifbdev->helper)) intel_fbdev_unregister(to_i915(ifbdev->helper.dev)); } -- cgit v1.2.3 From 8038510b1fe443ffbc0e356db5f47cbb8678a594 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 8 Feb 2023 13:42:57 +0200 Subject: drm/i915: Fix system suspend without fbdev being initialized If fbdev is not initialized for some reason - in practice on platforms without display - suspending fbdev should be skipped during system suspend, fix this up. While at it add an assert that suspending fbdev only happens with the display present. This fixes the following: [ 91.227923] PM: suspend entry (s2idle) [ 91.254598] Filesystems sync: 0.025 seconds [ 91.270518] Freezing user space processes [ 91.272266] Freezing user space processes completed (elapsed 0.001 seconds) [ 91.272686] OOM killer disabled. [ 91.272872] Freezing remaining freezable tasks [ 91.274295] Freezing remaining freezable tasks completed (elapsed 0.001 seconds) [ 91.659622] BUG: kernel NULL pointer dereference, address: 00000000000001c8 [ 91.659981] #PF: supervisor write access in kernel mode [ 91.660252] #PF: error_code(0x0002) - not-present page [ 91.660511] PGD 0 P4D 0 [ 91.660647] Oops: 0002 [#1] PREEMPT SMP NOPTI [ 91.660875] CPU: 4 PID: 917 Comm: bash Not tainted 6.2.0-rc7+ #54 [ 91.661185] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20221117gitfff6d81270b5-9.fc37 unknown [ 91.661680] RIP: 0010:mutex_lock+0x19/0x30 [ 91.661914] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 53 48 89 fb e8 62 d3 ff ff 31 c0 65 48 8b 14 25 00 15 03 00 48 0f b1 13 75 06 5b c3 cc cc cc cc 48 89 df 5b eb b4 0f 1f 40 [ 91.662840] RSP: 0018:ffffa1e8011ffc08 EFLAGS: 00010246 [ 91.663087] RAX: 0000000000000000 RBX: 00000000000001c8 RCX: 0000000000000000 [ 91.663440] RDX: ffff8be455eb0000 RSI: 0000000000000001 RDI: 00000000000001c8 [ 91.663802] RBP: ffff8be459440000 R08: ffff8be459441f08 R09: ffffffff8e1432c0 [ 91.664167] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000001 [ 91.664532] R13: 00000000000001c8 R14: 0000000000000000 R15: ffff8be442f4fb20 [ 91.664905] FS: 00007f28ffc16740(0000) GS:ffff8be4bb900000(0000) knlGS:0000000000000000 [ 91.665334] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 91.665626] CR2: 00000000000001c8 CR3: 0000000114926006 CR4: 0000000000770ee0 [ 91.665988] PKRU: 55555554 [ 91.666131] Call Trace: [ 91.666265] [ 91.666381] intel_fbdev_set_suspend+0x97/0x1b0 [i915] [ 91.666738] i915_drm_suspend+0xb9/0x100 [i915] [ 91.667029] pci_pm_suspend+0x78/0x170 [ 91.667234] ? __pfx_pci_pm_suspend+0x10/0x10 [ 91.667461] dpm_run_callback+0x47/0x150 [ 91.667673] __device_suspend+0x10a/0x4e0 [ 91.667880] dpm_suspend+0x134/0x270 [ 91.668069] dpm_suspend_start+0x79/0x80 [ 91.668272] suspend_devices_and_enter+0x11b/0x890 [ 91.668526] pm_suspend.cold+0x270/0x2fc [ 91.668737] state_store+0x46/0x90 [ 91.668916] kernfs_fop_write_iter+0x11b/0x200 [ 91.669153] vfs_write+0x1e1/0x3a0 [ 91.669336] ksys_write+0x53/0xd0 [ 91.669510] do_syscall_64+0x58/0xc0 [ 91.669699] ? syscall_exit_to_user_mode_prepare+0x18e/0x1c0 [ 91.669980] ? syscall_exit_to_user_mode_prepare+0x18e/0x1c0 [ 91.670278] ? syscall_exit_to_user_mode+0x17/0x40 [ 91.670524] ? do_syscall_64+0x67/0xc0 [ 91.670717] ? __irq_exit_rcu+0x3d/0x140 [ 91.670931] entry_SYSCALL_64_after_hwframe+0x72/0xdc [ 91.671202] RIP: 0033:0x7f28ffd14284 v2: CC stable. (Jani) Fixes: f8cc091e0530 ("drm/i915/fbdev: suspend HPD before fbdev unregistration") References: https://gitlab.freedesktop.org/drm/intel/-/issues/8015 Reported-and-tested-by: iczero Cc: Andrzej Hajda Cc: iczero Cc: # v6.1+ Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230208114300.3123934-2-imre.deak@intel.com (cherry picked from commit 9542d708409a41449e99c9a464deb5e062c4bee2) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_fbdev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_fbdev.c') diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index ed197db5861d..4d761c8d42ab 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -620,7 +620,13 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev; struct fb_info *info; - if (!ifbdev || !ifbdev->vma) + if (!ifbdev) + return; + + if (drm_WARN_ON(&dev_priv->drm, !HAS_DISPLAY(dev_priv))) + return; + + if (!ifbdev->vma) goto set_suspend; info = ifbdev->helper.info; -- cgit v1.2.3 From 3fb1f62f80a1d249260db5ea9e22c51e52fab9ae Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 16 Feb 2023 15:06:20 +0100 Subject: drm/fb-helper: Remove drm_fb_helper_unprepare() from drm_fb_helper_fini() Move drm_fb_helper_unprepare() from drm_fb_helper_fini() into the calling fbdev implementation. Avoids a possible stale mutex with generic fbdev code. As indicated by its name, drm_fb_helper_prepare() prepares struct drm_fb_helper before setting up the fbdev support with a call to drm_fb_helper_init(). In legacy fbdev emulation, this happens next to each other. If successful, drm_fb_helper_fini() later tear down the fbdev device and also unprepare via drm_fb_helper_unprepare(). Generic fbdev emulation prepares struct drm_fb_helper immediately after allocating the instance. It only calls drm_fb_helper_init() as part of processing a hotplug event. If the hotplug-handling fails, it runs drm_fb_helper_fini(). This unprepares the fb-helper instance and the next hotplug event runs on stale data. Solve this by moving drm_fb_helper_unprepare() from drm_fb_helper_fini() into the fbdev implementations. Call it right before freeing the fb-helper instance. Fixes: 643231b28380 ("drm/fbdev-generic: Minimize hotplug error handling") Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230216140620.17699-1-tzimmermann@suse.de --- drivers/gpu/drm/i915/display/intel_fbdev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915/display/intel_fbdev.c') diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index ed197db5861d..3a11e23c45af 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -340,6 +340,7 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev) if (ifbdev->fb) drm_framebuffer_remove(&ifbdev->fb->base); + drm_fb_helper_unprepare(&ifbdev->helper); kfree(ifbdev); } -- cgit v1.2.3