VYPR
Unrated severityNVD Advisory· Published Jun 8, 2026

CVE-2025-71315

CVE-2025-71315

Description

Linux kernel's virtual KMS driver had a custom vblank timer replaced with the DRM implementation, resolving a vulnerability.

AI Insight

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

Linux kernel's virtual KMS driver had a custom vblank timer replaced with the DRM implementation, resolving a vulnerability.

Vulnerability

The Linux kernel's virtual KMS (vkms) driver contained a custom vblank timer implementation within struct vkms_output. This vulnerability was resolved by replacing this custom timer with the existing DRM vblank timer implementation, which is conceptually similar but differs in its specific code.

Exploitation

Details on how this vulnerability could be exploited are not yet disclosed in the available references. The vulnerability lies within the kernel's graphics subsystem, specifically the virtual KMS component.

Impact

Details on the impact of this vulnerability are not yet disclosed in the available references. Exploitation could potentially lead to unintended behavior or compromise within the graphics subsystem.

Mitigation

This vulnerability has been resolved by converting the drm/vkms driver to use the DRM's vblank timer. The specific fixed version and release date are not detailed in the provided references, but the change is present in the kernel git repository. No workarounds are mentioned, and the vulnerability is not listed as known exploited.

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

Affected products

2

Patches

4
a0582cc92398

drm/vkms: Convert to DRM's vblank timer

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitThomas ZimmermannMay 26, 2026Fixed in 6.18.34via kernel-cna
2 files changed · +7 79
  • drivers/gpu/drm/vkms/vkms_crtc.c+7 76 modified
    diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
    index e60573e0f3e95..bd79f24686dce 100644
    --- a/drivers/gpu/drm/vkms/vkms_crtc.c
    +++ b/drivers/gpu/drm/vkms/vkms_crtc.c
    @@ -7,25 +7,18 @@
     #include <drm/drm_managed.h>
     #include <drm/drm_probe_helper.h>
     #include <drm/drm_vblank.h>
    +#include <drm/drm_vblank_helper.h>
     
     #include "vkms_drv.h"
     
    -static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
    +static bool vkms_crtc_handle_vblank_timeout(struct drm_crtc *crtc)
     {
    -	struct vkms_output *output = container_of(timer, struct vkms_output,
    -						  vblank_hrtimer);
    -	struct drm_crtc *crtc = &output->crtc;
    +	struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
     	struct vkms_crtc_state *state;
    -	u64 ret_overrun;
     	bool ret, fence_cookie;
     
     	fence_cookie = dma_fence_begin_signalling();
     
    -	ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
    -					  output->period_ns);
    -	if (ret_overrun != 1)
    -		pr_warn("%s: vblank timer overrun\n", __func__);
    -
     	spin_lock(&output->lock);
     	ret = drm_crtc_handle_vblank(crtc);
     	if (!ret)
    @@ -57,55 +50,6 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
     
     	dma_fence_end_signalling(fence_cookie);
     
    -	return HRTIMER_RESTART;
    -}
    -
    -static int vkms_enable_vblank(struct drm_crtc *crtc)
    -{
    -	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
    -	struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
    -
    -	hrtimer_setup(&out->vblank_hrtimer, &vkms_vblank_simulate, CLOCK_MONOTONIC,
    -		      HRTIMER_MODE_REL);
    -	out->period_ns = ktime_set(0, vblank->framedur_ns);
    -	hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL);
    -
    -	return 0;
    -}
    -
    -static void vkms_disable_vblank(struct drm_crtc *crtc)
    -{
    -	struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
    -
    -	hrtimer_cancel(&out->vblank_hrtimer);
    -}
    -
    -static bool vkms_get_vblank_timestamp(struct drm_crtc *crtc,
    -				      int *max_error, ktime_t *vblank_time,
    -				      bool in_vblank_irq)
    -{
    -	struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
    -	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
    -
    -	if (!READ_ONCE(vblank->enabled)) {
    -		*vblank_time = ktime_get();
    -		return true;
    -	}
    -
    -	*vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
    -
    -	if (WARN_ON(*vblank_time == vblank->time))
    -		return true;
    -
    -	/*
    -	 * To prevent races we roll the hrtimer forward before we do any
    -	 * interrupt processing - this is how real hw works (the interrupt is
    -	 * only generated after all the vblank registers are updated) and what
    -	 * the vblank core expects. Therefore we need to always correct the
    -	 * timestampe by one frame.
    -	 */
    -	*vblank_time -= output->period_ns;
    -
     	return true;
     }
     
    @@ -159,9 +103,7 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = {
     	.reset                  = vkms_atomic_crtc_reset,
     	.atomic_duplicate_state = vkms_atomic_crtc_duplicate_state,
     	.atomic_destroy_state   = vkms_atomic_crtc_destroy_state,
    -	.enable_vblank		= vkms_enable_vblank,
    -	.disable_vblank		= vkms_disable_vblank,
    -	.get_vblank_timestamp	= vkms_get_vblank_timestamp,
    +	DRM_CRTC_VBLANK_TIMER_FUNCS,
     	.get_crc_sources	= vkms_get_crc_sources,
     	.set_crc_source		= vkms_set_crc_source,
     	.verify_crc_source	= vkms_verify_crc_source,
    @@ -213,18 +155,6 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
     	return 0;
     }
     
    -static void vkms_crtc_atomic_enable(struct drm_crtc *crtc,
    -				    struct drm_atomic_state *state)
    -{
    -	drm_crtc_vblank_on(crtc);
    -}
    -
    -static void vkms_crtc_atomic_disable(struct drm_crtc *crtc,
    -				     struct drm_atomic_state *state)
    -{
    -	drm_crtc_vblank_off(crtc);
    -}
    -
     static void vkms_crtc_atomic_begin(struct drm_crtc *crtc,
     				   struct drm_atomic_state *state)
     	__acquires(&vkms_output->lock)
    @@ -265,8 +195,9 @@ static const struct drm_crtc_helper_funcs vkms_crtc_helper_funcs = {
     	.atomic_check	= vkms_crtc_atomic_check,
     	.atomic_begin	= vkms_crtc_atomic_begin,
     	.atomic_flush	= vkms_crtc_atomic_flush,
    -	.atomic_enable	= vkms_crtc_atomic_enable,
    -	.atomic_disable	= vkms_crtc_atomic_disable,
    +	.atomic_enable	= drm_crtc_vblank_atomic_enable,
    +	.atomic_disable	= drm_crtc_vblank_atomic_disable,
    +	.handle_vblank_timeout = vkms_crtc_handle_vblank_timeout,
     };
     
     struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plane *primary,
    
  • drivers/gpu/drm/vkms/vkms_drv.h+0 3 modified
    diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
    index 8013c31efe3b1..fb9711e1c6fbd 100644
    --- a/drivers/gpu/drm/vkms/vkms_drv.h
    +++ b/drivers/gpu/drm/vkms/vkms_drv.h
    @@ -215,8 +215,6 @@ struct vkms_output {
     	struct drm_crtc crtc;
     	struct drm_writeback_connector wb_connector;
     	struct drm_encoder wb_encoder;
    -	struct hrtimer vblank_hrtimer;
    -	ktime_t period_ns;
     	struct workqueue_struct *composer_workq;
     	spinlock_t lock;
     
    -- 
    cgit 1.3-korg
    
    
    
02e2681ffe1a

drm/vkms: Convert to DRM's vblank timer

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitThomas ZimmermannSep 16, 2025Fixed in 6.19via kernel-cna
2 files changed · +7 79
  • drivers/gpu/drm/vkms/vkms_crtc.c+7 76 modified
    diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
    index e60573e0f3e95..bd79f24686dce 100644
    --- a/drivers/gpu/drm/vkms/vkms_crtc.c
    +++ b/drivers/gpu/drm/vkms/vkms_crtc.c
    @@ -7,25 +7,18 @@
     #include <drm/drm_managed.h>
     #include <drm/drm_probe_helper.h>
     #include <drm/drm_vblank.h>
    +#include <drm/drm_vblank_helper.h>
     
     #include "vkms_drv.h"
     
    -static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
    +static bool vkms_crtc_handle_vblank_timeout(struct drm_crtc *crtc)
     {
    -	struct vkms_output *output = container_of(timer, struct vkms_output,
    -						  vblank_hrtimer);
    -	struct drm_crtc *crtc = &output->crtc;
    +	struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
     	struct vkms_crtc_state *state;
    -	u64 ret_overrun;
     	bool ret, fence_cookie;
     
     	fence_cookie = dma_fence_begin_signalling();
     
    -	ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
    -					  output->period_ns);
    -	if (ret_overrun != 1)
    -		pr_warn("%s: vblank timer overrun\n", __func__);
    -
     	spin_lock(&output->lock);
     	ret = drm_crtc_handle_vblank(crtc);
     	if (!ret)
    @@ -57,55 +50,6 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
     
     	dma_fence_end_signalling(fence_cookie);
     
    -	return HRTIMER_RESTART;
    -}
    -
    -static int vkms_enable_vblank(struct drm_crtc *crtc)
    -{
    -	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
    -	struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
    -
    -	hrtimer_setup(&out->vblank_hrtimer, &vkms_vblank_simulate, CLOCK_MONOTONIC,
    -		      HRTIMER_MODE_REL);
    -	out->period_ns = ktime_set(0, vblank->framedur_ns);
    -	hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL);
    -
    -	return 0;
    -}
    -
    -static void vkms_disable_vblank(struct drm_crtc *crtc)
    -{
    -	struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
    -
    -	hrtimer_cancel(&out->vblank_hrtimer);
    -}
    -
    -static bool vkms_get_vblank_timestamp(struct drm_crtc *crtc,
    -				      int *max_error, ktime_t *vblank_time,
    -				      bool in_vblank_irq)
    -{
    -	struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
    -	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
    -
    -	if (!READ_ONCE(vblank->enabled)) {
    -		*vblank_time = ktime_get();
    -		return true;
    -	}
    -
    -	*vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
    -
    -	if (WARN_ON(*vblank_time == vblank->time))
    -		return true;
    -
    -	/*
    -	 * To prevent races we roll the hrtimer forward before we do any
    -	 * interrupt processing - this is how real hw works (the interrupt is
    -	 * only generated after all the vblank registers are updated) and what
    -	 * the vblank core expects. Therefore we need to always correct the
    -	 * timestampe by one frame.
    -	 */
    -	*vblank_time -= output->period_ns;
    -
     	return true;
     }
     
    @@ -159,9 +103,7 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = {
     	.reset                  = vkms_atomic_crtc_reset,
     	.atomic_duplicate_state = vkms_atomic_crtc_duplicate_state,
     	.atomic_destroy_state   = vkms_atomic_crtc_destroy_state,
    -	.enable_vblank		= vkms_enable_vblank,
    -	.disable_vblank		= vkms_disable_vblank,
    -	.get_vblank_timestamp	= vkms_get_vblank_timestamp,
    +	DRM_CRTC_VBLANK_TIMER_FUNCS,
     	.get_crc_sources	= vkms_get_crc_sources,
     	.set_crc_source		= vkms_set_crc_source,
     	.verify_crc_source	= vkms_verify_crc_source,
    @@ -213,18 +155,6 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
     	return 0;
     }
     
    -static void vkms_crtc_atomic_enable(struct drm_crtc *crtc,
    -				    struct drm_atomic_state *state)
    -{
    -	drm_crtc_vblank_on(crtc);
    -}
    -
    -static void vkms_crtc_atomic_disable(struct drm_crtc *crtc,
    -				     struct drm_atomic_state *state)
    -{
    -	drm_crtc_vblank_off(crtc);
    -}
    -
     static void vkms_crtc_atomic_begin(struct drm_crtc *crtc,
     				   struct drm_atomic_state *state)
     	__acquires(&vkms_output->lock)
    @@ -265,8 +195,9 @@ static const struct drm_crtc_helper_funcs vkms_crtc_helper_funcs = {
     	.atomic_check	= vkms_crtc_atomic_check,
     	.atomic_begin	= vkms_crtc_atomic_begin,
     	.atomic_flush	= vkms_crtc_atomic_flush,
    -	.atomic_enable	= vkms_crtc_atomic_enable,
    -	.atomic_disable	= vkms_crtc_atomic_disable,
    +	.atomic_enable	= drm_crtc_vblank_atomic_enable,
    +	.atomic_disable	= drm_crtc_vblank_atomic_disable,
    +	.handle_vblank_timeout = vkms_crtc_handle_vblank_timeout,
     };
     
     struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plane *primary,
    
  • drivers/gpu/drm/vkms/vkms_drv.h+0 3 modified
    diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
    index 8013c31efe3b1..fb9711e1c6fbd 100644
    --- a/drivers/gpu/drm/vkms/vkms_drv.h
    +++ b/drivers/gpu/drm/vkms/vkms_drv.h
    @@ -215,8 +215,6 @@ struct vkms_output {
     	struct drm_crtc crtc;
     	struct drm_writeback_connector wb_connector;
     	struct drm_encoder wb_encoder;
    -	struct hrtimer vblank_hrtimer;
    -	ktime_t period_ns;
     	struct workqueue_struct *composer_workq;
     	spinlock_t lock;
     
    -- 
    cgit 1.3-korg
    
    
    
a0582cc92398

drm/vkms: Convert to DRM's vblank timer

2 files changed · +7 79
  • drivers/gpu/drm/vkms/vkms_crtc.c+7 76 modified
    diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
    index e60573e0f3e95..bd79f24686dce 100644
    --- a/drivers/gpu/drm/vkms/vkms_crtc.c
    +++ b/drivers/gpu/drm/vkms/vkms_crtc.c
    @@ -7,25 +7,18 @@
     #include <drm/drm_managed.h>
     #include <drm/drm_probe_helper.h>
     #include <drm/drm_vblank.h>
    +#include <drm/drm_vblank_helper.h>
     
     #include "vkms_drv.h"
     
    -static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
    +static bool vkms_crtc_handle_vblank_timeout(struct drm_crtc *crtc)
     {
    -	struct vkms_output *output = container_of(timer, struct vkms_output,
    -						  vblank_hrtimer);
    -	struct drm_crtc *crtc = &output->crtc;
    +	struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
     	struct vkms_crtc_state *state;
    -	u64 ret_overrun;
     	bool ret, fence_cookie;
     
     	fence_cookie = dma_fence_begin_signalling();
     
    -	ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
    -					  output->period_ns);
    -	if (ret_overrun != 1)
    -		pr_warn("%s: vblank timer overrun\n", __func__);
    -
     	spin_lock(&output->lock);
     	ret = drm_crtc_handle_vblank(crtc);
     	if (!ret)
    @@ -57,55 +50,6 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
     
     	dma_fence_end_signalling(fence_cookie);
     
    -	return HRTIMER_RESTART;
    -}
    -
    -static int vkms_enable_vblank(struct drm_crtc *crtc)
    -{
    -	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
    -	struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
    -
    -	hrtimer_setup(&out->vblank_hrtimer, &vkms_vblank_simulate, CLOCK_MONOTONIC,
    -		      HRTIMER_MODE_REL);
    -	out->period_ns = ktime_set(0, vblank->framedur_ns);
    -	hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL);
    -
    -	return 0;
    -}
    -
    -static void vkms_disable_vblank(struct drm_crtc *crtc)
    -{
    -	struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
    -
    -	hrtimer_cancel(&out->vblank_hrtimer);
    -}
    -
    -static bool vkms_get_vblank_timestamp(struct drm_crtc *crtc,
    -				      int *max_error, ktime_t *vblank_time,
    -				      bool in_vblank_irq)
    -{
    -	struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
    -	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
    -
    -	if (!READ_ONCE(vblank->enabled)) {
    -		*vblank_time = ktime_get();
    -		return true;
    -	}
    -
    -	*vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
    -
    -	if (WARN_ON(*vblank_time == vblank->time))
    -		return true;
    -
    -	/*
    -	 * To prevent races we roll the hrtimer forward before we do any
    -	 * interrupt processing - this is how real hw works (the interrupt is
    -	 * only generated after all the vblank registers are updated) and what
    -	 * the vblank core expects. Therefore we need to always correct the
    -	 * timestampe by one frame.
    -	 */
    -	*vblank_time -= output->period_ns;
    -
     	return true;
     }
     
    @@ -159,9 +103,7 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = {
     	.reset                  = vkms_atomic_crtc_reset,
     	.atomic_duplicate_state = vkms_atomic_crtc_duplicate_state,
     	.atomic_destroy_state   = vkms_atomic_crtc_destroy_state,
    -	.enable_vblank		= vkms_enable_vblank,
    -	.disable_vblank		= vkms_disable_vblank,
    -	.get_vblank_timestamp	= vkms_get_vblank_timestamp,
    +	DRM_CRTC_VBLANK_TIMER_FUNCS,
     	.get_crc_sources	= vkms_get_crc_sources,
     	.set_crc_source		= vkms_set_crc_source,
     	.verify_crc_source	= vkms_verify_crc_source,
    @@ -213,18 +155,6 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
     	return 0;
     }
     
    -static void vkms_crtc_atomic_enable(struct drm_crtc *crtc,
    -				    struct drm_atomic_state *state)
    -{
    -	drm_crtc_vblank_on(crtc);
    -}
    -
    -static void vkms_crtc_atomic_disable(struct drm_crtc *crtc,
    -				     struct drm_atomic_state *state)
    -{
    -	drm_crtc_vblank_off(crtc);
    -}
    -
     static void vkms_crtc_atomic_begin(struct drm_crtc *crtc,
     				   struct drm_atomic_state *state)
     	__acquires(&vkms_output->lock)
    @@ -265,8 +195,9 @@ static const struct drm_crtc_helper_funcs vkms_crtc_helper_funcs = {
     	.atomic_check	= vkms_crtc_atomic_check,
     	.atomic_begin	= vkms_crtc_atomic_begin,
     	.atomic_flush	= vkms_crtc_atomic_flush,
    -	.atomic_enable	= vkms_crtc_atomic_enable,
    -	.atomic_disable	= vkms_crtc_atomic_disable,
    +	.atomic_enable	= drm_crtc_vblank_atomic_enable,
    +	.atomic_disable	= drm_crtc_vblank_atomic_disable,
    +	.handle_vblank_timeout = vkms_crtc_handle_vblank_timeout,
     };
     
     struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plane *primary,
    
  • drivers/gpu/drm/vkms/vkms_drv.h+0 3 modified
    diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
    index 8013c31efe3b1..fb9711e1c6fbd 100644
    --- a/drivers/gpu/drm/vkms/vkms_drv.h
    +++ b/drivers/gpu/drm/vkms/vkms_drv.h
    @@ -215,8 +215,6 @@ struct vkms_output {
     	struct drm_crtc crtc;
     	struct drm_writeback_connector wb_connector;
     	struct drm_encoder wb_encoder;
    -	struct hrtimer vblank_hrtimer;
    -	ktime_t period_ns;
     	struct workqueue_struct *composer_workq;
     	spinlock_t lock;
     
    -- 
    cgit 1.3-korg
    
    
    
02e2681ffe1a

drm/vkms: Convert to DRM's vblank timer

2 files changed · +7 79
  • drivers/gpu/drm/vkms/vkms_crtc.c+7 76 modified
    diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
    index e60573e0f3e95..bd79f24686dce 100644
    --- a/drivers/gpu/drm/vkms/vkms_crtc.c
    +++ b/drivers/gpu/drm/vkms/vkms_crtc.c
    @@ -7,25 +7,18 @@
     #include <drm/drm_managed.h>
     #include <drm/drm_probe_helper.h>
     #include <drm/drm_vblank.h>
    +#include <drm/drm_vblank_helper.h>
     
     #include "vkms_drv.h"
     
    -static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
    +static bool vkms_crtc_handle_vblank_timeout(struct drm_crtc *crtc)
     {
    -	struct vkms_output *output = container_of(timer, struct vkms_output,
    -						  vblank_hrtimer);
    -	struct drm_crtc *crtc = &output->crtc;
    +	struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
     	struct vkms_crtc_state *state;
    -	u64 ret_overrun;
     	bool ret, fence_cookie;
     
     	fence_cookie = dma_fence_begin_signalling();
     
    -	ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
    -					  output->period_ns);
    -	if (ret_overrun != 1)
    -		pr_warn("%s: vblank timer overrun\n", __func__);
    -
     	spin_lock(&output->lock);
     	ret = drm_crtc_handle_vblank(crtc);
     	if (!ret)
    @@ -57,55 +50,6 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
     
     	dma_fence_end_signalling(fence_cookie);
     
    -	return HRTIMER_RESTART;
    -}
    -
    -static int vkms_enable_vblank(struct drm_crtc *crtc)
    -{
    -	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
    -	struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
    -
    -	hrtimer_setup(&out->vblank_hrtimer, &vkms_vblank_simulate, CLOCK_MONOTONIC,
    -		      HRTIMER_MODE_REL);
    -	out->period_ns = ktime_set(0, vblank->framedur_ns);
    -	hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL);
    -
    -	return 0;
    -}
    -
    -static void vkms_disable_vblank(struct drm_crtc *crtc)
    -{
    -	struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
    -
    -	hrtimer_cancel(&out->vblank_hrtimer);
    -}
    -
    -static bool vkms_get_vblank_timestamp(struct drm_crtc *crtc,
    -				      int *max_error, ktime_t *vblank_time,
    -				      bool in_vblank_irq)
    -{
    -	struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
    -	struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
    -
    -	if (!READ_ONCE(vblank->enabled)) {
    -		*vblank_time = ktime_get();
    -		return true;
    -	}
    -
    -	*vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
    -
    -	if (WARN_ON(*vblank_time == vblank->time))
    -		return true;
    -
    -	/*
    -	 * To prevent races we roll the hrtimer forward before we do any
    -	 * interrupt processing - this is how real hw works (the interrupt is
    -	 * only generated after all the vblank registers are updated) and what
    -	 * the vblank core expects. Therefore we need to always correct the
    -	 * timestampe by one frame.
    -	 */
    -	*vblank_time -= output->period_ns;
    -
     	return true;
     }
     
    @@ -159,9 +103,7 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = {
     	.reset                  = vkms_atomic_crtc_reset,
     	.atomic_duplicate_state = vkms_atomic_crtc_duplicate_state,
     	.atomic_destroy_state   = vkms_atomic_crtc_destroy_state,
    -	.enable_vblank		= vkms_enable_vblank,
    -	.disable_vblank		= vkms_disable_vblank,
    -	.get_vblank_timestamp	= vkms_get_vblank_timestamp,
    +	DRM_CRTC_VBLANK_TIMER_FUNCS,
     	.get_crc_sources	= vkms_get_crc_sources,
     	.set_crc_source		= vkms_set_crc_source,
     	.verify_crc_source	= vkms_verify_crc_source,
    @@ -213,18 +155,6 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
     	return 0;
     }
     
    -static void vkms_crtc_atomic_enable(struct drm_crtc *crtc,
    -				    struct drm_atomic_state *state)
    -{
    -	drm_crtc_vblank_on(crtc);
    -}
    -
    -static void vkms_crtc_atomic_disable(struct drm_crtc *crtc,
    -				     struct drm_atomic_state *state)
    -{
    -	drm_crtc_vblank_off(crtc);
    -}
    -
     static void vkms_crtc_atomic_begin(struct drm_crtc *crtc,
     				   struct drm_atomic_state *state)
     	__acquires(&vkms_output->lock)
    @@ -265,8 +195,9 @@ static const struct drm_crtc_helper_funcs vkms_crtc_helper_funcs = {
     	.atomic_check	= vkms_crtc_atomic_check,
     	.atomic_begin	= vkms_crtc_atomic_begin,
     	.atomic_flush	= vkms_crtc_atomic_flush,
    -	.atomic_enable	= vkms_crtc_atomic_enable,
    -	.atomic_disable	= vkms_crtc_atomic_disable,
    +	.atomic_enable	= drm_crtc_vblank_atomic_enable,
    +	.atomic_disable	= drm_crtc_vblank_atomic_disable,
    +	.handle_vblank_timeout = vkms_crtc_handle_vblank_timeout,
     };
     
     struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plane *primary,
    
  • drivers/gpu/drm/vkms/vkms_drv.h+0 3 modified
    diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
    index 8013c31efe3b1..fb9711e1c6fbd 100644
    --- a/drivers/gpu/drm/vkms/vkms_drv.h
    +++ b/drivers/gpu/drm/vkms/vkms_drv.h
    @@ -215,8 +215,6 @@ struct vkms_output {
     	struct drm_crtc crtc;
     	struct drm_writeback_connector wb_connector;
     	struct drm_encoder wb_encoder;
    -	struct hrtimer vblank_hrtimer;
    -	ktime_t period_ns;
     	struct workqueue_struct *composer_workq;
     	spinlock_t lock;
     
    -- 
    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

2

News mentions

0

No linked articles in our index yet.