From: Matt Coster Date: Fri, 27 Feb 2026 14:12:47 +0000 (+0000) Subject: drm/imagination: Check for NULL struct dev_pm_domain_list X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=713ec926d8256d5989043ec95620b88a79924aa3;p=thirdparty%2Fkernel%2Flinux.git drm/imagination: Check for NULL struct dev_pm_domain_list While dev_pm_domain_detach_list() itself contains the necessary NULL check, the access to struct dev_pm_domain_list->num_pds does not and thus faults on devices with <=1 power domains (where the struct dev_pm_domain_list machinery is skipped for simplicity). This can be reproduced on AM625, which produces the following log[1]: [ 10.820056] powervr fd00000.gpu: Direct firmware load for powervr/rogue_33.15.11.3_v1.fw failed with error -2 [ 10.831903] powervr fd00000.gpu: [drm] *ERROR* failed to load firmware powervr/rogue_33.15.11.3_v1.fw (err=-2) ... [ 10.844023] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018 ... [ 11.090162] Call trace: [ 11.092600] pvr_power_domains_fini+0x18/0xa0 [powervr] (P) [ 11.098218] pvr_probe+0x100/0x14c [powervr] [ 11.102505] platform_probe+0x5c/0xa4 Fixes: e19cc5ab347e3 ("drm/imagination: Use dev_pm_domain_attach_list()") Reported-by: Mark Brown Closes: https://lore.kernel.org/r/c353fdef-9ccd-4a11-a527-ab4a792d8e70@sirena.org.uk/ [1] Tested-by: Mark Brown Reviewed-by: Alessio Belle Link: https://patch.msgid.link/20260227-single-domain-power-fixes-v1-1-d37ba0825f7c@imgtec.com Signed-off-by: Matt Coster --- diff --git a/drivers/gpu/drm/imagination/pvr_power.c b/drivers/gpu/drm/imagination/pvr_power.c index 006a72ed5064f..be8018085b2df 100644 --- a/drivers/gpu/drm/imagination/pvr_power.c +++ b/drivers/gpu/drm/imagination/pvr_power.c @@ -668,14 +668,16 @@ void pvr_power_domains_fini(struct pvr_device *pvr_dev) { struct pvr_device_power *pvr_power = &pvr_dev->power; - int i = (int)pvr_power->domains->num_pds - 1; + if (!pvr_power->domains) + goto out; - while (--i >= 0) + for (int i = (int)pvr_power->domains->num_pds - 2; i >= 0; --i) device_link_del(pvr_power->domain_links[i]); dev_pm_domain_detach_list(pvr_power->domains); kfree(pvr_power->domain_links); +out: *pvr_power = (struct pvr_device_power){ 0 }; }