VYPR
Unrated severityNVD Advisory· Published Jun 3, 2026

CVE-2025-71314

CVE-2025-71314

Description

Linux kernel's DRM/panthor driver can hang, preventing GPU command processing and requiring a system reset.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Linux kernel's DRM/panthor driver can hang, preventing GPU command processing and requiring a system reset.

Vulnerability

The Linux kernel's DRM/panthor driver has a vulnerability where memory subsystem flush operations can hang indefinitely. This issue affects the panthor driver and can occur when buggy GPU jobs are created by the UMD, leading to a blocked memory subsystem.

Exploitation

An attacker can trigger this vulnerability by providing buggy GPU jobs to the system, which can cause the panthor_gpu_flush_caches() operation to hang. This hang blocks the memory subsystem, preventing new commands from being processed.

Impact

When the panthor_gpu_flush_caches() operation hangs, the memory subsystem becomes blocked, and flush operations never complete. This leads to a situation where the GPU cannot process new commands, effectively halting GPU operations until a reset is performed. The system may return -EIO for subsequent operations.

Mitigation

This vulnerability has been resolved in the Linux kernel. The fix involves scheduling a reset when flush operations time out, resetting pending requests, and skipping subsequent queued flush operations to avoid further waits. The specific commit addressing this is available at [1], [2], [3], and [4]. No specific version information or release date for the patch is provided in the references.

AI Insight generated on Jun 3, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

8
57753f2c64c0

drm/panthor: Recover from panthor_gpu_flush_caches() failures

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitBoris BrezillonNov 28, 2025Fixed in 6.18.14via kernel-cna
1 file changed · +12 8
  • drivers/gpu/drm/panthor/panthor_gpu.c+12 8 modified
    diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c
    index db69449a5be09..b92c9e738dbfa 100644
    --- a/drivers/gpu/drm/panthor/panthor_gpu.c
    +++ b/drivers/gpu/drm/panthor/panthor_gpu.c
    @@ -259,38 +259,42 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev)
     int panthor_gpu_flush_caches(struct panthor_device *ptdev,
     			     u32 l2, u32 lsc, u32 other)
     {
    -	bool timedout = false;
     	unsigned long flags;
    +	int ret = 0;
     
     	/* Serialize cache flush operations. */
     	guard(mutex)(&ptdev->gpu->cache_flush_lock);
     
     	spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
    -	if (!drm_WARN_ON(&ptdev->base,
    -			 ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
    +	if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
     		ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		gpu_write(ptdev, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
    +	} else {
    +		ret = -EIO;
     	}
     	spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     
    +	if (ret)
    +		return ret;
    +
     	if (!wait_event_timeout(ptdev->gpu->reqs_acked,
     				!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED),
     				msecs_to_jiffies(100))) {
     		spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
     		if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
     		    !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
    -			timedout = true;
    +			ret = -ETIMEDOUT;
     		else
     			ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     	}
     
    -	if (timedout) {
    +	if (ret) {
    +		panthor_device_schedule_reset(ptdev);
     		drm_err(&ptdev->base, "Flush caches timeout");
    -		return -ETIMEDOUT;
     	}
     
    -	return 0;
    +	return ret;
     }
     
     /**
    @@ -330,6 +334,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)
     		return -ETIMEDOUT;
     	}
     
    +	ptdev->gpu->pending_reqs = 0;
     	return 0;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
2c899c6026fc

drm/panthor: Recover from panthor_gpu_flush_caches() failures

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitBoris BrezillonNov 28, 2025Fixed in 6.19.4via kernel-cna
1 file changed · +12 8
  • drivers/gpu/drm/panthor/panthor_gpu.c+12 8 modified
    diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c
    index 06b231b2460ab..9cb5dee932120 100644
    --- a/drivers/gpu/drm/panthor/panthor_gpu.c
    +++ b/drivers/gpu/drm/panthor/panthor_gpu.c
    @@ -289,38 +289,42 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev)
     int panthor_gpu_flush_caches(struct panthor_device *ptdev,
     			     u32 l2, u32 lsc, u32 other)
     {
    -	bool timedout = false;
     	unsigned long flags;
    +	int ret = 0;
     
     	/* Serialize cache flush operations. */
     	guard(mutex)(&ptdev->gpu->cache_flush_lock);
     
     	spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
    -	if (!drm_WARN_ON(&ptdev->base,
    -			 ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
    +	if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
     		ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		gpu_write(ptdev, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
    +	} else {
    +		ret = -EIO;
     	}
     	spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     
    +	if (ret)
    +		return ret;
    +
     	if (!wait_event_timeout(ptdev->gpu->reqs_acked,
     				!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED),
     				msecs_to_jiffies(100))) {
     		spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
     		if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
     		    !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
    -			timedout = true;
    +			ret = -ETIMEDOUT;
     		else
     			ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     	}
     
    -	if (timedout) {
    +	if (ret) {
    +		panthor_device_schedule_reset(ptdev);
     		drm_err(&ptdev->base, "Flush caches timeout");
    -		return -ETIMEDOUT;
     	}
     
    -	return 0;
    +	return ret;
     }
     
     /**
    @@ -360,6 +364,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)
     		return -ETIMEDOUT;
     	}
     
    +	ptdev->gpu->pending_reqs = 0;
     	return 0;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
3c0a60195b37

drm/panthor: Recover from panthor_gpu_flush_caches() failures

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitBoris BrezillonNov 28, 2025Fixed in 7.0via kernel-cna
1 file changed · +12 8
  • drivers/gpu/drm/panthor/panthor_gpu.c+12 8 modified
    diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c
    index 06b231b2460ab..9cb5dee932120 100644
    --- a/drivers/gpu/drm/panthor/panthor_gpu.c
    +++ b/drivers/gpu/drm/panthor/panthor_gpu.c
    @@ -289,38 +289,42 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev)
     int panthor_gpu_flush_caches(struct panthor_device *ptdev,
     			     u32 l2, u32 lsc, u32 other)
     {
    -	bool timedout = false;
     	unsigned long flags;
    +	int ret = 0;
     
     	/* Serialize cache flush operations. */
     	guard(mutex)(&ptdev->gpu->cache_flush_lock);
     
     	spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
    -	if (!drm_WARN_ON(&ptdev->base,
    -			 ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
    +	if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
     		ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		gpu_write(ptdev, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
    +	} else {
    +		ret = -EIO;
     	}
     	spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     
    +	if (ret)
    +		return ret;
    +
     	if (!wait_event_timeout(ptdev->gpu->reqs_acked,
     				!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED),
     				msecs_to_jiffies(100))) {
     		spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
     		if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
     		    !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
    -			timedout = true;
    +			ret = -ETIMEDOUT;
     		else
     			ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     	}
     
    -	if (timedout) {
    +	if (ret) {
    +		panthor_device_schedule_reset(ptdev);
     		drm_err(&ptdev->base, "Flush caches timeout");
    -		return -ETIMEDOUT;
     	}
     
    -	return 0;
    +	return ret;
     }
     
     /**
    @@ -360,6 +364,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)
     		return -ETIMEDOUT;
     	}
     
    +	ptdev->gpu->pending_reqs = 0;
     	return 0;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
8ec4f1b14a61

drm/panthor: Recover from panthor_gpu_flush_caches() failures

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitBoris BrezillonNov 28, 2025Fixed in 6.12.75via kernel-cna
1 file changed · +12 8
  • drivers/gpu/drm/panthor/panthor_gpu.c+12 8 modified
    diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c
    index 1ca2924e6d552..15e4371d98945 100644
    --- a/drivers/gpu/drm/panthor/panthor_gpu.c
    +++ b/drivers/gpu/drm/panthor/panthor_gpu.c
    @@ -384,38 +384,42 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev)
     int panthor_gpu_flush_caches(struct panthor_device *ptdev,
     			     u32 l2, u32 lsc, u32 other)
     {
    -	bool timedout = false;
     	unsigned long flags;
    +	int ret = 0;
     
     	/* Serialize cache flush operations. */
     	guard(mutex)(&ptdev->gpu->cache_flush_lock);
     
     	spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
    -	if (!drm_WARN_ON(&ptdev->base,
    -			 ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
    +	if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
     		ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		gpu_write(ptdev, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
    +	} else {
    +		ret = -EIO;
     	}
     	spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     
    +	if (ret)
    +		return ret;
    +
     	if (!wait_event_timeout(ptdev->gpu->reqs_acked,
     				!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED),
     				msecs_to_jiffies(100))) {
     		spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
     		if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
     		    !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
    -			timedout = true;
    +			ret = -ETIMEDOUT;
     		else
     			ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     	}
     
    -	if (timedout) {
    +	if (ret) {
    +		panthor_device_schedule_reset(ptdev);
     		drm_err(&ptdev->base, "Flush caches timeout");
    -		return -ETIMEDOUT;
     	}
     
    -	return 0;
    +	return ret;
     }
     
     /**
    @@ -455,6 +459,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)
     		return -ETIMEDOUT;
     	}
     
    +	ptdev->gpu->pending_reqs = 0;
     	return 0;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
3c0a60195b37

drm/panthor: Recover from panthor_gpu_flush_caches() failures

1 file changed · +12 8
  • drivers/gpu/drm/panthor/panthor_gpu.c+12 8 modified
    diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c
    index 06b231b2460ab..9cb5dee932120 100644
    --- a/drivers/gpu/drm/panthor/panthor_gpu.c
    +++ b/drivers/gpu/drm/panthor/panthor_gpu.c
    @@ -289,38 +289,42 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev)
     int panthor_gpu_flush_caches(struct panthor_device *ptdev,
     			     u32 l2, u32 lsc, u32 other)
     {
    -	bool timedout = false;
     	unsigned long flags;
    +	int ret = 0;
     
     	/* Serialize cache flush operations. */
     	guard(mutex)(&ptdev->gpu->cache_flush_lock);
     
     	spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
    -	if (!drm_WARN_ON(&ptdev->base,
    -			 ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
    +	if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
     		ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		gpu_write(ptdev, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
    +	} else {
    +		ret = -EIO;
     	}
     	spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     
    +	if (ret)
    +		return ret;
    +
     	if (!wait_event_timeout(ptdev->gpu->reqs_acked,
     				!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED),
     				msecs_to_jiffies(100))) {
     		spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
     		if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
     		    !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
    -			timedout = true;
    +			ret = -ETIMEDOUT;
     		else
     			ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     	}
     
    -	if (timedout) {
    +	if (ret) {
    +		panthor_device_schedule_reset(ptdev);
     		drm_err(&ptdev->base, "Flush caches timeout");
    -		return -ETIMEDOUT;
     	}
     
    -	return 0;
    +	return ret;
     }
     
     /**
    @@ -360,6 +364,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)
     		return -ETIMEDOUT;
     	}
     
    +	ptdev->gpu->pending_reqs = 0;
     	return 0;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
57753f2c64c0

drm/panthor: Recover from panthor_gpu_flush_caches() failures

1 file changed · +12 8
  • drivers/gpu/drm/panthor/panthor_gpu.c+12 8 modified
    diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c
    index db69449a5be09..b92c9e738dbfa 100644
    --- a/drivers/gpu/drm/panthor/panthor_gpu.c
    +++ b/drivers/gpu/drm/panthor/panthor_gpu.c
    @@ -259,38 +259,42 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev)
     int panthor_gpu_flush_caches(struct panthor_device *ptdev,
     			     u32 l2, u32 lsc, u32 other)
     {
    -	bool timedout = false;
     	unsigned long flags;
    +	int ret = 0;
     
     	/* Serialize cache flush operations. */
     	guard(mutex)(&ptdev->gpu->cache_flush_lock);
     
     	spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
    -	if (!drm_WARN_ON(&ptdev->base,
    -			 ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
    +	if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
     		ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		gpu_write(ptdev, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
    +	} else {
    +		ret = -EIO;
     	}
     	spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     
    +	if (ret)
    +		return ret;
    +
     	if (!wait_event_timeout(ptdev->gpu->reqs_acked,
     				!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED),
     				msecs_to_jiffies(100))) {
     		spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
     		if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
     		    !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
    -			timedout = true;
    +			ret = -ETIMEDOUT;
     		else
     			ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     	}
     
    -	if (timedout) {
    +	if (ret) {
    +		panthor_device_schedule_reset(ptdev);
     		drm_err(&ptdev->base, "Flush caches timeout");
    -		return -ETIMEDOUT;
     	}
     
    -	return 0;
    +	return ret;
     }
     
     /**
    @@ -330,6 +334,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)
     		return -ETIMEDOUT;
     	}
     
    +	ptdev->gpu->pending_reqs = 0;
     	return 0;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
8ec4f1b14a61

drm/panthor: Recover from panthor_gpu_flush_caches() failures

1 file changed · +12 8
  • drivers/gpu/drm/panthor/panthor_gpu.c+12 8 modified
    diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c
    index 1ca2924e6d552..15e4371d98945 100644
    --- a/drivers/gpu/drm/panthor/panthor_gpu.c
    +++ b/drivers/gpu/drm/panthor/panthor_gpu.c
    @@ -384,38 +384,42 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev)
     int panthor_gpu_flush_caches(struct panthor_device *ptdev,
     			     u32 l2, u32 lsc, u32 other)
     {
    -	bool timedout = false;
     	unsigned long flags;
    +	int ret = 0;
     
     	/* Serialize cache flush operations. */
     	guard(mutex)(&ptdev->gpu->cache_flush_lock);
     
     	spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
    -	if (!drm_WARN_ON(&ptdev->base,
    -			 ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
    +	if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
     		ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		gpu_write(ptdev, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
    +	} else {
    +		ret = -EIO;
     	}
     	spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     
    +	if (ret)
    +		return ret;
    +
     	if (!wait_event_timeout(ptdev->gpu->reqs_acked,
     				!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED),
     				msecs_to_jiffies(100))) {
     		spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
     		if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
     		    !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
    -			timedout = true;
    +			ret = -ETIMEDOUT;
     		else
     			ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     	}
     
    -	if (timedout) {
    +	if (ret) {
    +		panthor_device_schedule_reset(ptdev);
     		drm_err(&ptdev->base, "Flush caches timeout");
    -		return -ETIMEDOUT;
     	}
     
    -	return 0;
    +	return ret;
     }
     
     /**
    @@ -455,6 +459,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)
     		return -ETIMEDOUT;
     	}
     
    +	ptdev->gpu->pending_reqs = 0;
     	return 0;
     }
     
    -- 
    cgit 1.3-korg
    
    
    
2c899c6026fc

drm/panthor: Recover from panthor_gpu_flush_caches() failures

1 file changed · +12 8
  • drivers/gpu/drm/panthor/panthor_gpu.c+12 8 modified
    diff --git a/drivers/gpu/drm/panthor/panthor_gpu.c b/drivers/gpu/drm/panthor/panthor_gpu.c
    index 06b231b2460ab..9cb5dee932120 100644
    --- a/drivers/gpu/drm/panthor/panthor_gpu.c
    +++ b/drivers/gpu/drm/panthor/panthor_gpu.c
    @@ -289,38 +289,42 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev)
     int panthor_gpu_flush_caches(struct panthor_device *ptdev,
     			     u32 l2, u32 lsc, u32 other)
     {
    -	bool timedout = false;
     	unsigned long flags;
    +	int ret = 0;
     
     	/* Serialize cache flush operations. */
     	guard(mutex)(&ptdev->gpu->cache_flush_lock);
     
     	spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
    -	if (!drm_WARN_ON(&ptdev->base,
    -			 ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
    +	if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
     		ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		gpu_write(ptdev, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
    +	} else {
    +		ret = -EIO;
     	}
     	spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     
    +	if (ret)
    +		return ret;
    +
     	if (!wait_event_timeout(ptdev->gpu->reqs_acked,
     				!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED),
     				msecs_to_jiffies(100))) {
     		spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
     		if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
     		    !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
    -			timedout = true;
    +			ret = -ETIMEDOUT;
     		else
     			ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
     		spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
     	}
     
    -	if (timedout) {
    +	if (ret) {
    +		panthor_device_schedule_reset(ptdev);
     		drm_err(&ptdev->base, "Flush caches timeout");
    -		return -ETIMEDOUT;
     	}
     
    -	return 0;
    +	return ret;
     }
     
     /**
    @@ -360,6 +364,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev)
     		return -ETIMEDOUT;
     	}
     
    +	ptdev->gpu->pending_reqs = 0;
     	return 0;
     }
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

No source-code context for this CVE — mechanics is only generated when we can read the actual fix diff. Without that, the four sections (root cause, attack vector, affected code, fix) would be speculation rather than analysis.

References

4

News mentions

0

No linked articles in our index yet.