* [PATCH v5 5/5] vhost/vsock: add VHOST_RESET_OWNER ioctl
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
In-Reply-To: <20260720102241.371610-1-andrey.drobyshev@virtuozzo.com>
From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This ioctl is needed for QEMU's CPR (checkpoint-restore) migration of
the guest with vhost-vsock device. For this to work, we need to reset
the device ownership on the source side by calling RESET_OWNER, and then
claim it on the dest side by calling SET_OWNER. We expect not to lose any
AF_VSOCK connection while this happens.
To that end, unlike the release path, RESET_OWNER keeps the guest CID
hashed: established connections survive, and host sends issued while
the device is between owners simply stay on send_pkt_queue until the
next device start drains them.
Since the device stays reachable through the CID hash, the lockless
send/cancel paths can race with the worker teardown in
vhost_workers_free(). The previous commit ("vhost: synchronize with
RCU readers when freeing workers") makes that safe.
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
---
drivers/vhost/vsock.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index d5022d21120b..86f25ff80722 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -903,6 +903,29 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
return -EFAULT;
}
+static long vhost_vsock_reset_owner(struct vhost_vsock *vsock)
+{
+ struct vhost_iotlb *umem;
+ long err;
+
+ mutex_lock(&vsock->dev.mutex);
+ err = vhost_dev_check_owner(&vsock->dev);
+ if (err)
+ goto done;
+ umem = vhost_dev_reset_owner_prepare();
+ if (!umem) {
+ err = -ENOMEM;
+ goto done;
+ }
+ vhost_vsock_drop_backends(vsock);
+ vhost_vsock_flush(vsock);
+ vhost_dev_stop(&vsock->dev);
+ vhost_dev_reset_owner(&vsock->dev, umem);
+done:
+ mutex_unlock(&vsock->dev.mutex);
+ return err;
+}
+
static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
unsigned long arg)
{
@@ -946,6 +969,8 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl,
return -EOPNOTSUPP;
vhost_set_backend_features(&vsock->dev, features);
return 0;
+ case VHOST_RESET_OWNER:
+ return vhost_vsock_reset_owner(vsock);
default:
mutex_lock(&vsock->dev.mutex);
r = vhost_dev_ioctl(&vsock->dev, ioctl, argp);
--
2.47.1
^ permalink raw reply related
* [PATCH v5 3/5] vhost/vsock: re-scan TX virtqueue on device start
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
In-Reply-To: <20260720102241.371610-1-andrey.drobyshev@virtuozzo.com>
During QEMU CPR live-update (and VHOST_RESET_OWNER in general) the guest
keeps running while the host drops and later re-attaches vhost backends.
If the guest adds a buffer to the TX virtqueue (guest->host) and kicks
while the backend is temporarily NULL (between vhost_vsock_drop_backends()
and the next vhost_vsock_start()), then the kick is delivered to the
vhost worker, handle_tx_kick() sees a NULL backend and returns, and the
kick signal is consumed. The buffer is then left in the ring.
Then upon device start vhost_vsock_start() only re-kicks the RX send
worker, never the TX VQ, so the buffer is processed only if the guest
happens to kick again. But if the guest itself is now waiting for data
from the host, it will never kick TX VQ again, and we end up in a
deadlock.
The issue itself is pre-existing, but it only manifests during a device
pause caused by VHOST_RESET_OWNER. Namely, the deadlock is reproduced
during active host->guest socat data transfer under multiple consecutive
CPR live-update's.
To fix this, in vhost_vsock_start(), after kicking the RX send worker, also
queue the TX vq poll so any buffers the guest enqueued while we were paused
get scanned.
The VHOST_RESET_OWNER ioctl itself is implemented in the following
patch, thus this patch is a preparation to support VHOST_RESET_OWNER.
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
drivers/vhost/vsock.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 27169a09e87e..d5022d21120b 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -646,6 +646,13 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
*/
vhost_vq_work_queue(&vsock->vqs[VSOCK_VQ_RX], &vsock->send_pkt_work);
+ /* The guest may have added TX buffers while the device was stopped
+ * (e.g. across VHOST_RESET_OWNER) and their kicks got consumed by
+ * the NULL-backend window. Re-scan the TX VQ, mirroring the RX
+ * send-worker kick above.
+ */
+ vhost_poll_queue(&vsock->vqs[VSOCK_VQ_TX].poll);
+
mutex_unlock(&vsock->dev.mutex);
return 0;
--
2.47.1
^ permalink raw reply related
* [PATCH v5 2/5] vhost/vsock: suppress EHOSTUNREACH fast-fail during CPR pause
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
In-Reply-To: <20260720102241.371610-1-andrey.drobyshev@virtuozzo.com>
Earlier commit bb26ed5f3a8b ("vhost/vsock: Refuse the connection
immediately when guest isn't ready") added a fast-fail in
vhost_transport_send_pkt(). It rejects every host send with -EHOSTUNREACH
until the destination calls SET_RUNNING(1). The fast-fail condition checks
whether device's backends are dropped, and if they're, the guest is
considered to be not ready.
However, there might be other reasons for backends to be nulled. In
particular, when QEMU is performing CPR (checkpoint-restore) migration,
device ownership is being RESET and SET again, which leads to backends
drop and reattach. If we end up connecting during this window, an
AF_VSOCK client gets -EHOSTUNREACH, which is wrong.
Add an 'ever_started' flag which is set once in vhost_vsock_start() and is
never cleared. The behaviour changes to:
* When device was never started -> flag is unset -> no listener can
exist yet -> fast-fail;
* Once the device starts -> flag is set -> we don't fast-fail ->
we queue and preserve during any later stop / CPR pause.
The VHOST_RESET_OWNER ioctl is implemented in a following patch, and
without RESET_OWNER the problem we fix here isn't manifesting - thus
this patch is a preparation to support RESET_OWNER.
Important caveat: after the first start, a connect during any stopped
window is queued instead of fast-failed. That was the behaviour before
the patch bb26ed5f3a8b, and we're restoring it now. However we still
keep the behaviour originally intended by that commit (i.e. fast-fail if
there's no real listener yet) while fixing the CPR path.
Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
drivers/vhost/vsock.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index b12221ce6faf..27169a09e87e 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -61,6 +61,7 @@ struct vhost_vsock {
u32 guest_cid;
bool seqpacket_allow;
+ bool ever_started; /* set on first SET_RUNNING(1); never cleared */
};
static u32 vhost_transport_get_local_cid(void)
@@ -302,17 +303,12 @@ vhost_transport_send_pkt(struct sk_buff *skb, struct net *net)
return -ENODEV;
}
- /* Fast-fail if the guest hasn't enabled the RX vq yet. Queuing the packet
- * and making the caller wait is pointless: even if the guest manages to init
- * within the timeout, it'll immediately reply with RST, because there's no
- * listener on the port yet.
- *
- * vhost_vq_get_backend() without vq->mutex is acceptable here: locking
- * the mutex would be too expensive in this hot path, and we already have
- * all the outcomes covered: if the backend becomes NULL right after the check,
- * vhost_transport_do_send_pkt() will check it under the mutex anyway.
+ /* Fast-fail until the guest first enables the device (SET_RUNNING(1)).
+ * Before that there is no listener, so queuing is pointless.
+ * 'ever_started' is never cleared, so once we're up we keep queuing
+ * across later stop / CPR-pause windows.
*/
- if (unlikely(!data_race(vhost_vq_get_backend(&vsock->vqs[VSOCK_VQ_RX])))) {
+ if (unlikely(!READ_ONCE(vsock->ever_started))) {
rcu_read_unlock();
kfree_skb(skb);
return -EHOSTUNREACH;
@@ -640,6 +636,11 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
mutex_unlock(&vq->mutex);
}
+ /* Set 'ever_started' flag on the first start; never cleared, so send_pkt
+ * keeps queuing (instead of fast-failing) on later stop / CPR pauses.
+ */
+ WRITE_ONCE(vsock->ever_started, true);
+
/* Some packets may have been queued before the device was started,
* let's kick the send worker to send them.
*/
@@ -728,6 +729,7 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file)
vsock->guest_cid = 0; /* no CID assigned yet */
vsock->seqpacket_allow = false;
+ vsock->ever_started = false;
atomic_set(&vsock->queued_replies, 0);
--
2.47.1
^ permalink raw reply related
* [PATCH v5 1/5] vhost/vsock: split out vhost_vsock_drop_backends helper
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
In-Reply-To: <20260720102241.371610-1-andrey.drobyshev@virtuozzo.com>
From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Split the actual backend dropping part from vhost_vsock_stop. We're
going to need it for the VHOST_RESET_OWNER implementation in the
following patch, when vsock->dev.mutex is already taken and owner is
checked.
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vsock.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 9aaab6bb8061..b12221ce6faf 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -664,9 +664,24 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
return ret;
}
-static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner)
+static void vhost_vsock_drop_backends(struct vhost_vsock *vsock)
{
+ struct vhost_virtqueue *vq;
size_t i;
+
+ lockdep_assert_held(&vsock->dev.mutex);
+
+ for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
+ vq = &vsock->vqs[i];
+
+ mutex_lock(&vq->mutex);
+ vhost_vq_set_backend(vq, NULL);
+ mutex_unlock(&vq->mutex);
+ }
+}
+
+static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner)
+{
int ret = 0;
mutex_lock(&vsock->dev.mutex);
@@ -677,14 +692,7 @@ static int vhost_vsock_stop(struct vhost_vsock *vsock, bool check_owner)
goto err;
}
- for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
- struct vhost_virtqueue *vq = &vsock->vqs[i];
-
- mutex_lock(&vq->mutex);
- vhost_vq_set_backend(vq, NULL);
- mutex_unlock(&vq->mutex);
- }
-
+ vhost_vsock_drop_backends(vsock);
err:
mutex_unlock(&vsock->dev.mutex);
return ret;
--
2.47.1
^ permalink raw reply related
* [PATCH v5 0/5] vhost/vsock: add support for VHOST_RESET_OWNER and CPR migration
From: Andrey Drobyshev @ 2026-07-20 10:22 UTC (permalink / raw)
To: linux-kernel
Cc: kvm, virtualization, netdev, sgarzare, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den, andrey.drobyshev
v4 -> v5:
* Patch 4:
- call synchronize_rcu() unconditionally;
- call vhost_dev_flush(dev) instead of vhost_run_work_list(worker)
to drain remaining work;
- reword comment and commit message.
v4: https://lore.kernel.org/virtualization/20260714151638.143019-1-andrey.drobyshev@virtuozzo.com
Andrey Drobyshev (3):
vhost/vsock: suppress EHOSTUNREACH fast-fail during CPR pause
vhost/vsock: re-scan TX virtqueue on device start
vhost: synchronize with RCU readers when freeing workers
Pavel Tikhomirov (2):
vhost/vsock: split out vhost_vsock_drop_backends helper
vhost/vsock: add VHOST_RESET_OWNER ioctl
drivers/vhost/vhost.c | 11 ++++++
drivers/vhost/vsock.c | 80 +++++++++++++++++++++++++++++++++----------
2 files changed, 72 insertions(+), 19 deletions(-)
--
2.47.1
^ permalink raw reply
* [PATCH 2/3] sched: Convert paravirt_steal to new static key APIs
From: Hongyan Xia @ 2026-07-20 9:38 UTC (permalink / raw)
To: mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
vschneid@redhat.com, kprateek.nayak@amd.com, Juergen Gross,
Ajay Kaher, Alexey Makhalov, Broadcom internal kernel review list,
Catalin Marinas, Will Deacon, Huacai Chen, WANG Xuerui,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy (CS GROUP), Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Thomas Gleixner, Borislav Petkov,
Dave Hansen, x86@kernel.org, H. Peter Anvin, Paolo Bonzini,
Vitaly Kuznetsov, Stefano Stabellini, Oleksandr Tyshchenko
Cc: Jiazi Li, linux-kernel@vger.kernel.org,
virtualization@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, loongarch@lists.linux.dev,
linuxppc-dev@lists.ozlabs.org, linux-riscv@lists.infradead.org,
kvm@vger.kernel.org, xen-devel@lists.xenproject.org
In-Reply-To: <cover.1784538478.git.hongyan.xia@transsion.com>
From: Hongyan Xia <hongyan.xia@transsion.com>
paravirt_steal_rq_enabled and paravirt_steal_enabled use raw static_key
APIs which are now deprecated. Use the new API instead.
No functional change.
Signed-off-by: Hongyan Xia <hongyan.xia@transsion.com>
---
arch/arm64/kernel/paravirt.c | 4 ++--
arch/loongarch/kernel/paravirt.c | 4 ++--
arch/powerpc/platforms/pseries/setup.c | 4 ++--
arch/riscv/kernel/paravirt.c | 4 ++--
arch/x86/kernel/cpu/vmware.c | 4 ++--
arch/x86/kernel/kvm.c | 4 ++--
drivers/xen/time.c | 4 ++--
include/linux/sched/cputime.h | 6 +++---
kernel/sched/core.c | 4 ++--
kernel/sched/cputime.c | 4 ++--
10 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c
index 572efb96b23f..30bf61d031eb 100644
--- a/arch/arm64/kernel/paravirt.c
+++ b/arch/arm64/kernel/paravirt.c
@@ -157,9 +157,9 @@ int __init pv_time_init(void)
static_call_update(pv_steal_clock, para_steal_clock);
- static_key_slow_inc(¶virt_steal_enabled);
+ static_branch_inc(¶virt_steal_enabled);
if (steal_acc)
- static_key_slow_inc(¶virt_steal_rq_enabled);
+ static_branch_inc(¶virt_steal_rq_enabled);
pr_info("using stolen time PV\n");
diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
index 10821cce554c..e8965a3f8082 100644
--- a/arch/loongarch/kernel/paravirt.c
+++ b/arch/loongarch/kernel/paravirt.c
@@ -308,10 +308,10 @@ int __init pv_time_init(void)
static_call_update(pv_steal_clock, paravt_steal_clock);
- static_key_slow_inc(¶virt_steal_enabled);
+ static_branch_inc(¶virt_steal_enabled);
#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
if (steal_acc)
- static_key_slow_inc(¶virt_steal_rq_enabled);
+ static_branch_inc(¶virt_steal_rq_enabled);
#endif
if (static_key_enabled(&virt_preempt_key))
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 1223dc961242..8dcbc4bb7025 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -852,9 +852,9 @@ static void __init pSeries_setup_arch(void)
static_branch_enable(&shared_processor);
pv_spinlocks_init();
#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
- static_key_slow_inc(¶virt_steal_enabled);
+ static_branch_inc(¶virt_steal_enabled);
if (steal_acc)
- static_key_slow_inc(¶virt_steal_rq_enabled);
+ static_branch_inc(¶virt_steal_rq_enabled);
#endif
}
diff --git a/arch/riscv/kernel/paravirt.c b/arch/riscv/kernel/paravirt.c
index 5f56be79cd06..9c13a6f1ea2a 100644
--- a/arch/riscv/kernel/paravirt.c
+++ b/arch/riscv/kernel/paravirt.c
@@ -116,9 +116,9 @@ int __init pv_time_init(void)
static_call_update(pv_steal_clock, pv_time_steal_clock);
- static_key_slow_inc(¶virt_steal_enabled);
+ static_branch_inc(¶virt_steal_enabled);
if (steal_acc)
- static_key_slow_inc(¶virt_steal_rq_enabled);
+ static_branch_inc(¶virt_steal_rq_enabled);
pr_info("Computing paravirt steal-time\n");
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 34b73573b108..f7ab9e7902cf 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -328,9 +328,9 @@ static int vmware_cpu_down_prepare(unsigned int cpu)
static __init int activate_jump_labels(void)
{
if (has_steal_clock) {
- static_key_slow_inc(¶virt_steal_enabled);
+ static_branch_inc(¶virt_steal_enabled);
if (steal_acc)
- static_key_slow_inc(¶virt_steal_rq_enabled);
+ static_branch_inc(¶virt_steal_rq_enabled);
}
return 0;
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index dcef84da304b..d3dcd64f22c2 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -1052,9 +1052,9 @@ const __initconst struct hypervisor_x86 x86_hyper_kvm = {
static __init int activate_jump_labels(void)
{
if (has_steal_clock) {
- static_key_slow_inc(¶virt_steal_enabled);
+ static_branch_inc(¶virt_steal_enabled);
if (steal_acc)
- static_key_slow_inc(¶virt_steal_rq_enabled);
+ static_branch_inc(¶virt_steal_rq_enabled);
}
return 0;
diff --git a/drivers/xen/time.c b/drivers/xen/time.c
index a2be0a4d45b0..a02d48a2aa68 100644
--- a/drivers/xen/time.c
+++ b/drivers/xen/time.c
@@ -169,7 +169,7 @@ void __init xen_time_setup_guest(void)
static_call_update(pv_steal_clock, xen_steal_clock);
- static_key_slow_inc(¶virt_steal_enabled);
+ static_branch_inc(¶virt_steal_enabled);
if (xen_runstate_remote)
- static_key_slow_inc(¶virt_steal_rq_enabled);
+ static_branch_inc(¶virt_steal_rq_enabled);
}
diff --git a/include/linux/sched/cputime.h b/include/linux/sched/cputime.h
index e90efaf6d26e..694126411dfe 100644
--- a/include/linux/sched/cputime.h
+++ b/include/linux/sched/cputime.h
@@ -182,9 +182,9 @@ extern unsigned long long
task_sched_runtime(struct task_struct *task);
#ifdef CONFIG_PARAVIRT
-struct static_key;
-extern struct static_key paravirt_steal_enabled;
-extern struct static_key paravirt_steal_rq_enabled;
+#include <linux/jump_label.h>
+DECLARE_STATIC_KEY_FALSE(paravirt_steal_enabled);
+DECLARE_STATIC_KEY_FALSE(paravirt_steal_rq_enabled);
#ifdef CONFIG_HAVE_PV_STEAL_CLOCK_GEN
u64 dummy_steal_clock(int cpu);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 96226707c2f6..786975d4ca1e 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -795,7 +795,7 @@ struct rq *_task_rq_lock(struct task_struct *p, struct rq_flags *rf)
/* Use CONFIG_PARAVIRT as this will avoid more #ifdef in arch code. */
#ifdef CONFIG_PARAVIRT
-struct static_key paravirt_steal_rq_enabled;
+DEFINE_STATIC_KEY_FALSE(paravirt_steal_rq_enabled);
#endif
static void update_rq_clock_task(struct rq *rq, s64 delta)
@@ -834,7 +834,7 @@ static void update_rq_clock_task(struct rq *rq, s64 delta)
}
#endif
#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
- if (static_key_false((¶virt_steal_rq_enabled))) {
+ if (static_branch_unlikely(¶virt_steal_rq_enabled)) {
u64 prev_steal;
steal = prev_steal = paravirt_steal_clock(cpu_of(rq));
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 06bddaa738e5..f16970ca81d0 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -255,7 +255,7 @@ void __account_forceidle_time(struct task_struct *p, u64 delta)
* occasion account more time than the calling functions think elapsed.
*/
#ifdef CONFIG_PARAVIRT
-struct static_key paravirt_steal_enabled;
+DEFINE_STATIC_KEY_FALSE(paravirt_steal_enabled);
#ifdef CONFIG_HAVE_PV_STEAL_CLOCK_GEN
static u64 native_steal_clock(int cpu)
@@ -270,7 +270,7 @@ DEFINE_STATIC_CALL(pv_steal_clock, native_steal_clock);
static __always_inline u64 steal_account_process_time(u64 maxtime)
{
#ifdef CONFIG_PARAVIRT
- if (static_key_false(¶virt_steal_enabled)) {
+ if (static_branch_unlikely(¶virt_steal_enabled)) {
u64 steal;
steal = paravirt_steal_clock(smp_processor_id());
--
2.47.3
^ permalink raw reply related
* Re: [PATCH v2 1/4] virtio-mem: validate device-reported block size
From: David Hildenbrand (Arm) @ 2026-07-20 9:19 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Carlos Bilbao, Michael S. Tsirkin, Hari Mishal, Jason Wang,
Xuan Zhuo, Eugenio Pérez, virtualization, linux-kernel,
elena.reshetova, huster, mhollick, jiska.classen
In-Reply-To: <2026072036-outburst-rebel-c71b@gregkh>
>>> We've the virto-mem config struct layout and the kernel source, so for
>>> obvious fixes like a NULL check, static analysis is better than fuzzing.
>>> Claude took a few mins to find me two examples:
>>>
>>> Patch 1: virtio-mem: reject non-power-of-two device_block_size
>>> This one is for virtio_mem_init() to check if
>>> !is_power_of_2(vm->device_block_size)
>>>
>>> Patch 2: virto-mem: validate region_size and usable_region_size
>>> THis one checks region_size != 0 and vm->usable_reion_size >
>>> vm->region_size.
>>>
>>> An endless factory of "silly" checks like these are low hanging fruit.
>>
>> "silly" is the right word.
>
> "silly" in what way?
>
As in producing "silly" low-hanging fruit patches that don't move the needle
when it comes to security.
> Seriously, I'm trying to figure out what you all care about here and
> what exactly the threat model you want this driver to work in, and I'm
> getting conflicting answers.
>
> Either you all do worry about the "device" sending bad data and want to
> protect from that, or you don't and you trust it. Pick one please so
> that we know how to deal with these bug reports we are getting.
>
> For example, for USB we have said our threat model is:
>
> - we do NOT trust the device before a driver is bound to the device,
> so if a malicious device can do something to the kernel, the kernel
> needs to be fixed.
> - During the probe() call for a USB driver, the driver does NOT trust
> the device, and again, anything a malicious device can do to the
> kernel, the kernel should fix.
> - After probe() for a USB driver succeeds, it's up to the driver if it
> wants to validate all data coming from the device or not. Right
> now, in general, the kernel trusts the device at that point in time
> so additional checks are discretionary and at the whim of the
> maintainer.
>
> For that last point, I will note that some BIG users of Linux (i.e.
> billions of Android devices) still explicitly do NOT want to trust the
> USB device at this point in time, and are relying on the kernel to
> protect the system from bad devices. In that case, various patches have
> been taken to different drivers and subsystems to play whack-a-mole on
> while Android gets their act together to finally come up with a solid
> defensive plan (like ChromeOS has had for a decade.) It will be seen
> which happens first, all drivers are properly fuzzed and fixed up, or
> Android gets their act together and finally fixes their b0rked system
> trust model. I think Android management is relying on the kernel
> community to do the kernel work as they keep refusing to staff the
> userspace work that they need to do here...
Right, and for virtio devices trusting the device after probe is just extremely
questionable.
What changes during probe that the device suddenly sends us good data?
Why would a hypervisor that tried to break us before probe not try to break us
after probe?
>
> And yes, I really need to write this up in a more solid document for USB
> and get it into the tree, but at least this email thread has forced me
> to write down the above :)
>
>
> So, again, for virtio drivers, what exactly do you all want to say is
> your threat model that the drivers need to handle? Can you all agree on
> something please? Otherwise, for new developers like Hari, this is
> totaly confusion as to what they should be doing.
Well, I am also totally confused why we end up checking against some MUST
clauses in the spec, but not against others.
I am very much in favor of making virtio-mem completely safe to use even in
coco, where it is currently not used at all.
If it's really about "don't let a device trigger any unexpected kernel code
execution by sanitizing all input data", fine with me. We should do exactly
that. Try checking all MUST clauses etc.
But I don't think doing the "low hanging fruit" adds any security. It should be
done properly or not at all.
--
Cheers,
David
^ permalink raw reply
* [RFC PATCH] vhost-scsi: Serialize completion notification with callfd updates
From: Jia Jia @ 2026-07-20 8:53 UTC (permalink / raw)
To: mst, jasowangio, michael.christie
Cc: pbonzini, stefanha, eperezma, virtualization, kvm
During userspace stress testing on a KASAN-enabled host, a host-side
callfd replacement concurrent with ordinary SCSI completions exposed an
eventfd_ctx lifetime race. The test requires access to /dev/vhost-scsi and
a host process that can issue VHOST_SET_VRING_CALL; on the default device
permissions this normally means root or an explicitly delegated service.
The test used TUR completions while closing the old callfd and binding a
new one. The unbind form tends to produce a NULL pointer, while replacing
the callfd after closing the old file makes the old eventfd_ctx eligible
for release.
vhost_scsi_complete_cmd_work() drops vq->mutex before calling
vhost_signal(). VHOST_SET_VRING_CALL updates call_ctx under the same mutex
and puts the old eventfd_ctx before returning. vhost_signal() does not take
the mutex or hold a reference to call_ctx.ctx:
if (vq->call_ctx.ctx && vhost_notify(dev, vq))
eventfd_signal(vq->call_ctx.ctx);
CPU 0 (ioctl / callfd replace) CPU 1 (vhost worker)
vhost_scsi_complete_cmd_work()
mutex_unlock(&vq->mutex)
vhost_signal()
/* load old ctx */
vhost_notify() ...
VHOST_SET_VRING_CALL
mutex_lock(&vq->mutex)
swap(vq->call_ctx.ctx, new)
eventfd_ctx_put(old) /* free */
mutex_unlock(&vq->mutex)
eventfd_signal(old)
/* use-after-free */
On the reproducing run, the worker ran on CPU 1 and the callfd ioctl path
ran on CPU 0. KASAN reported:
BUG: KASAN: slab-use-after-free in eventfd_signal_mask+0x6c/0x110
The use stack was:
eventfd_signal_mask
vhost_signal
vhost_scsi_complete_cmd_work
vhost_run_work_list
vhost_task_fn
The freeing stack was:
eventfd_ctx_put
vhost_vring_ioctl
vhost_scsi_ioctl
__x64_sys_ioctl
Hold vq->mutex across vhost_signal() so SET_VRING_CALL cannot swap and
release the context while the completion worker is notifying the guest.
This gives the completion and callfd update a clear ordering without
changing the vhost API or adding a new lock. Other vhost-scsi response
paths already signal while holding the virtqueue mutex.
A private eventfd reference taken under the mutex would allow signalling
after unlock, but it needs additional reference-count plumbing. An RCU
design would require broader vhost-core changes for all call_ctx readers
and additional eventfd lifetime rules. Since callfd changes are a
control-plane operation, extending the existing per-virtqueue critical
section is the smaller complete fix.
This is an RFC because keeping vhost_notify() and eventfd_signal() inside
the virtqueue critical section extends the lock hold time slightly. I'd
appreciate feedback on whether this is acceptable or whether a
reference-pinning approach, taking the reference under the mutex and
releasing it after unlock, would be preferable.
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
---
drivers/vhost/scsi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 9a1253b9d8c5..7f46bc0de3c2 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -735,10 +735,9 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
vhost_scsi_release_cmd_res(se_cmd);
}
- mutex_unlock(&svq->vq.mutex);
-
if (signal)
vhost_signal(&svq->vs->dev, &svq->vq);
+ mutex_unlock(&svq->vq.mutex);
}
static struct vhost_scsi_cmd *
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v4 4/5] vhost: synchronize with RCU readers when freeing workers
From: Stefano Garzarella @ 2026-07-20 8:39 UTC (permalink / raw)
To: Andrey Drobyshev
Cc: linux-kernel, kvm, virtualization, netdev, mst, stefanha,
dongli.zhang, maciej.szmigiero, bchaney, mark.kanda, ptikhomirov,
den
In-Reply-To: <55d7c896-b871-4c50-a324-35f5c4a9d11a@virtuozzo.com>
On Thu, Jul 16, 2026 at 09:01:22PM +0300, Andrey Drobyshev wrote:
>On 7/16/26 7:13 PM, Stefano Garzarella wrote:
>> On Thu, Jul 16, 2026 at 06:39:48PM +0300, Andrey Drobyshev wrote:
>>> On 7/16/26 11:57 AM, Stefano Garzarella wrote:
>>>> On Tue, Jul 14, 2026 at 06:16:37PM +0300, Andrey Drobyshev wrote:
>>>>> vhost_vq_work_queue() only holds the RCU read lock while it dereferences
>>>>> vq->worker and queues work on it. vhost_workers_free() however clears
>>>>> the vq->worker pointers and immediately frees the workers, without
>>>>> waiting for a grace period. A caller that fetched the worker right
>>>>> before the pointer was cleared can therefore still be queueing work on
>>>>> it while it is freed. And even when the queueing itself wins the race,
>>>>> the work is never run, so its VHOST_WORK_QUEUED bit stays set and all
>>>>> future attempts to queue it are silently skipped.
>>>>>
>>>>> None of the current callers can actually hit this: net and scsi stop
>>>>> their virtqueues before the workers are freed, and vsock unhashes the
>>>>> device and does synchronize_rcu() of its own in vhost_vsock_dev_release()
>>>>> before the workers go away. But the upcoming VHOST_RESET_OWNER support
>>>>> in vhost-vsock keeps the device hashed while its workers are freed, so
>>>>> the lockless send/cancel paths become able to race with the teardown.
>>>>>
>>>>> Close this the way vhost_worker_killed() already does: clear the
>>>>> vq->worker pointers, wait for a grace period, run whatever the last
>>>>> readers may have queued, and only then free the workers. The
>>>>> synchronize_rcu() is skipped if the device has no workers, so cleanup of
>>>>> devices which never got an owner stays cheap.
>>>>>
>>>>
>>>> Do we need a Fixes tag for this?
>>>>
>>>
>>> I'm guessing it should be:
>>>
>>> Fixes: 228a27cf78af ("vhost: Allow worker switching while work is queueing")
>>>
>>>> Thanks for pointing out that the issue wasn't occurring, but I think we
>>>> should add it because it's a sneaky problem we discovered by chance.
>>>> IMO the code should already have `synchronize_rcu()` after
>>>> `rcu_assign_pointer()` loop.
>>>>
>>>> @Michael, what do you think?
>>>>
>>>>> Suggested-by: Stefano Garzarella <sgarzare@redhat.com>
>>>>> Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
>>>>> ---
>>>>> drivers/vhost/vhost.c | 15 +++++++++++++++
>>>>> 1 file changed, 15 insertions(+)
>>>>>
>>>>> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
>>>>> index 4c525b3e16ea..0d1414d40f4e 100644
>>>>> --- a/drivers/vhost/vhost.c
>>>>> +++ b/drivers/vhost/vhost.c
>>>>> @@ -729,6 +729,21 @@ static void vhost_workers_free(struct vhost_dev *dev)
>>>>>
>>>>> for (i = 0; i < dev->nvqs; i++)
>>>>> rcu_assign_pointer(dev->vqs[i]->worker, NULL);
>>>>> +
>>>>> + /*
>>>>> + * vhost_vq_work_queue() reads vq->worker under rcu_read_lock(), so a
>>>>> + * caller that fetched a worker before we cleared the pointers above
>>>>> + * may still be about to queue work on it. Wait for those RCU readers
>>>>> + * to finish before freeing the worker, then run whatever they queued
>>>>> + * so nothing is left with VHOST_WORK_QUEUED set. Mirrors
>>>>> + * vhost_worker_killed().
>>>>> + */
>>>>> + if (!xa_empty(&dev->worker_xa)) {
>>>>> + synchronize_rcu();
>>>>> + xa_for_each(&dev->worker_xa, i, worker)
>>>>> + vhost_run_work_list(worker);
>>>>> + }
>>>>> +
>>>>
>>>> Following sashiko review [1], I tried to undersand why we need this, but
>>>> TBH I'm really confused. That said, this seems wrong also because it
>>>> will work only with vhost_tasks, and not with kthreads.
>>>>
>>>> IIUC vhost_worker_killed() will be called anyway when calling
>>>> vhost_worker_destroy(). For vhost_tasks, it will call
>>>> vhost_task_do_stop() that calls vhost_task_stop(). This sets
>>>> VHOST_TASK_FLAGS_STOP and wait the worker on vtsk->exited before freeing
>>>> stuff. The worker breaks the loop and calls vtsk->handle_sigkill() that
>>>> is exactly vhost_worker_killed() you mentioned we are mirroring here.
>>>>
>>>
>>> Hmm, are we sure it's the case for our codepath? Looking at the
>>> vhost_task loop function:
>>>
>>>> static int vhost_task_fn(void *data)
>>>> {
>>>> for (;;) {
>>>> if (signal_pending(current)) {
>>>> if (get_signal(&ksig))
>>>> break;
>>>> }
>>>> ...
>>>> if (test_bit(VHOST_TASK_FLAGS_STOP, &vtsk->flags)) {
>>>> __set_current_state(TASK_RUNNING);
>>>> break;
>>>> }
>>>> did_work = vtsk->fn(vtsk->data);
>>>> ...
>>>> }
>>>>
>>>> ...
>>>>
>>>> if (!test_bit(VHOST_TASK_FLAGS_STOP, &vtsk->flags)) {
>>>> set_bit(VHOST_TASK_FLAGS_KILLED, &vtsk->flags);
>>>> vtsk->handle_sigkill(vtsk->data);
>>>> }
>>>> ...
>>>> }
>>>
>>> AFAICT, we exit the loop in 2 cases: signal delivery or STOP bit
>>> setting. Like you said, STOP is set by vhost_task_stop. E.g. for our
>>> RESET_OWNER case:
>>>
>>> vhost_vsock_reset_owner()
>>> vhost_dev_reset_owner()
>>> vhost_dev_cleanup()
>>> vhost_workers_free()
>>> vhost_worker_destroy()
>>> vhost_task_stop() // for vhost_task_ops backend
>>> set_bit(VHOST_TASK_FLAGS_STOP)
>>>
>>> So, first of all, actual work by .fn() callback is done after the exit
>>> checks, therefore we skip it - no chance to drain there.
>>>
>>> Secondly, the handle_sigkill() callback is deliberately NOT called in
>>> the STOP case and only called on fatal signal delivery. And for
>>> vhost_task backend the .handle_sigkill() callback is exactly
>>> vhost_worker_killed().
>>>
>>> So my understanding is: if we only call synchronize_rcu() here and leave
>>> this path undrained, then whatever work which was put by send_pkt() for
>>> the worker currently being freed - will be lost. Please correct me if
>>> I'm wrong.
>>
>> Yep, your right. But what will be the issue of loosing them?
>>
>> IIUC we are not loosing any data, just avoiding some works that will be
>> handled later when/if will set a new owner.
>>
>
>But will it actually be handled?
>
>vhost_transport_send_pkt() // called on every packet send
> virtio_vsock_skb_queue_tail(&send_pkt_queue, skb) // add skb to list
> vhost_vq_work_queue(&send_pkt_work) // try to arm the work
> vhost_worker_queue()
> if (!test_and_set_bit(VHOST_WORK_QUEUED, &work->flags)) {
> llist_add(&worker->work_list)
> }
>
>So send_pkt_queue is a list of skbs, it lives on the vhost_vsock device
>state, and survives RESET_OWNER. In that sense you're probably right
>that we aren't loosing any data.
>
>There's also send_pkt_work object, also living on the vhost_vsock device
>state. So we're accumulating skbs, and then send_pkg_work gets put in
>the worker task list - but only if it's NOT already armed in there, i.e.
>QUEUED bit is unset. And the bit gets cleared by the workload callback
>- for vhost_task backend it's vhost_run_work_list().
>
>The most important thing is WHERE this piece of work is being put. That
>is worker->work_list - this list does not survive RESET_OWNER, as we
>free the worker in vhost_workers_free().
>
>Now imagine we have RESET_OWNER racing with send_pkt. In
>vhost_workers_free() we acquire ptr to a worker but not NULL'ify it yet.
> Then on the send_pkt path we arm the send_pkt_work, set the QUEUED bit,
>and place it on the work_list of a DYING worker. Then the worker gets
>freed. Now we have send_pkt_work (a singleton struct) with QUEUED set
>in its flags, and with no worker to walk through this piece of work and
>clear this flag. As a result - send_pkt_work can't be placed in the
>list of any other worker, because it doesn't pass the "if
>(!test_and_set_bit(QUEUED)" check. Thus no new packets can be
>processed, and the connection is stalled.
>
>Does this make sense?
Honestly, I don't see the problem. The device is about to be stopped
because the VMM is resetting the owner, so the connection is going to
stall anyway, since I don't think the guest will never answer, isn't it?
>>>
>>> That said, I agree that vhost_run_work_list() will only work with
>>> vhost_task backend, not with kthreads backend. If we do
>>> vhost_worker_flush() instead - I guess it'll keep the drain here, yet
>>> become backend-agnostic. I.e.:
>>>
>>>> + if (!xa_empty(&dev->worker_xa)) {
>>>> + synchronize_rcu();
>>>> + xa_for_each(&dev->worker_xa, i, worker)
>>>> + vhost_worker_flush(worker);
>>>> + }
>>>
>>> With the last 2 lines being equivalent to just calling
>>> vhost_dev_flush(dev). And once we become backend-agnostic here, I'm
>>> guessing the warning reported by Sashiko should be dealt with as well.
>>
>> I'd avoid `if !xa_empty(&dev->worker_xa)` at all, and call
>> synchronize_rcu() in any case.
>>
>
>Agreed.
>
>> About vhost_dev_flush(), we are calling it in several places, and maybe
>> we should re-check them. E.g. we call in vhost_vsock_flush(), but it's
>> also called by vhost_dev_stop(), maybe we can avoid to call
>> vhost_vsock_flush() if we call vhost_dev_stop().
>>
>> I'm not sure we really need another one here, but if you think some
>> other works can be queued between the vhost_dev_stop() and the
>> synchronize_rcu() we are adding here, then okay, it may have sense.
>>
>
>Note that in our particular case we're gonna do:
>
>vhost_workers_free()
> vhost_dev_flush() // the flush we're planning to add
> xa_for_each(&dev->worker_xa, i, worker)
> vhost_worker_destroy(dev, worker)
> xa_destroy(&dev->worker_xa)
>
>So we walk through the XArray, destroy workers in it one by one, then
>destroy the XArray itself. Then the next time we call
>vhost_dev_flush(), e.g. from vhost_dev_stop() or wherever else, it tries
>iterating over the XArray which no longer exists - which is gonna be a
>no-op.
>
>Now, we can reach vhost_workers_free() via (at least) 2 paths:
>RESET_OWNER and device release path. On the former the flush is needed
>as I illustrated above. On the latter it's indeed redundant but is
>cheap as it's a no-op.
Again, I don't see the need for it TBH, but at the same time, I don't
think it's a problem to include it, so if you think it's necessary, go
ahead and add it.
Thanks,
Stefano
^ permalink raw reply
* Re: [PATCH v2 1/4] virtio-mem: validate device-reported block size
From: Greg Kroah-Hartman @ 2026-07-20 8:28 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Carlos Bilbao, Michael S. Tsirkin, Hari Mishal, Jason Wang,
Xuan Zhuo, Eugenio Pérez, virtualization, linux-kernel,
elena.reshetova, huster, mhollick, jiska.classen
In-Reply-To: <9569e577-aa82-4642-b9d9-fd496fc12849@kernel.org>
On Mon, Jul 20, 2026 at 08:57:13AM +0100, David Hildenbrand (Arm) wrote:
> On 7/18/26 18:07, Carlos Bilbao wrote:
> > On 7/17/26 22:29, Greg Kroah-Hartman wrote:
> >
> >> On Fri, Jul 17, 2026 at 08:31:09PM -0700, Carlos Bilbao wrote:
> >>> Historically, one of the biggest criticisms of coco, especially around
> >>> device hardening, was that there were too many values that a
> >>> malicious/buggy device could misreport, making it a losing battle. That is
> >>> no longer the case with LLMs, and we have the advantage (and challenge) of
> >>> open-source dev, which allows us to receive many of these fixes "for free".
> >>> If others want to burn their tokens, let them :)
> >> I have lots of tokens to burn :)
> >>
> >> So along those lines, any suggestions on how best to fuzz these code
> >> paths? Any workloads you all use for testing that I can take advantage
> >> of?
> >
> >
> > We've the virtio-mem config struct layout and the kernel source, so for
> > obvious fixes like a NULL check, static analysis is better than fuzzing.
> > Claude took a few mins to find me two examples:
> >
> > Patch 1: virtio-mem: reject non-power-of-two device_block_size
> > This one is for virtio_mem_init() to check if
> > !is_power_of_2(vm->device_block_size)
> >
> > Patch 2: virto-mem: validate region_size and usable_region_size
> > THis one checks region_size != 0 and vm->usable_reion_size >
> > vm->region_size.
> >
> > An endless factory of "silly" checks like these are low hanging fruit.
> >
> > Now, for harder bugs, looking around for fuzz options, VirtFuzz [1] looks
> > like a great candidate for those interested in pursuing this direction.
> >
> >
> > Their PoC fuzzes wireless/Bluetooth stack, but nothing our AI overlords
> > can't quickly adapt for virtio-mem and other virtio drivers; the JSON
> > definition to describe device behavior is easily extensible. Their threat
> > model [2] describes an external attacker, but in the context of coco, the
> > virtio device itself is the attacker. Here's a vibe coded PR of what I mean:
> >
> > https://github.com/seemoo-lab/VirtFuzz/pull/7
> >
> > CCed the creators/authors, thanks for open sourcing this!
> >
> > Thanks,
> > Carlos
> >
> > [1] https://github.com/seemoo-lab/VirtFuzz
> >
> > On 7/17/26 22:29, Greg Kroah-Hartman wrote:
> >
> >> On Fri, Jul 17, 2026 at 08:31:09PM -0700, Carlos Bilbao wrote:
> >>> Historically, one of the biggest criticisms of coco, especially around
> >>> device hardening, was that there were too many values that a
> >>> malicious/buggy device could misreport, making it a losing battle. That is
> >>> no longer the case with LLMs, and we have the advantage (and challenge) of
> >>> open-source dev, which allows us to receive many of these fixes "for free".
> >>> If others want to burn their tokens, let them :)
> >> I have lots of tokens to burn :)
> >>
> >> So along those lines, any suggestions on how best to fuzz these code
> >> paths? Any workloads you all use for testing that I can take advantage
> >> of?
> >
> >
> > We've the virto-mem config struct layout and the kernel source, so for
> > obvious fixes like a NULL check, static analysis is better than fuzzing.
> > Claude took a few mins to find me two examples:
> >
> > Patch 1: virtio-mem: reject non-power-of-two device_block_size
> > This one is for virtio_mem_init() to check if
> > !is_power_of_2(vm->device_block_size)
> >
> > Patch 2: virto-mem: validate region_size and usable_region_size
> > THis one checks region_size != 0 and vm->usable_reion_size >
> > vm->region_size.
> >
> > An endless factory of "silly" checks like these are low hanging fruit.
>
> "silly" is the right word.
"silly" in what way?
Seriously, I'm trying to figure out what you all care about here and
what exactly the threat model you want this driver to work in, and I'm
getting conflicting answers.
Either you all do worry about the "device" sending bad data and want to
protect from that, or you don't and you trust it. Pick one please so
that we know how to deal with these bug reports we are getting.
For example, for USB we have said our threat model is:
- we do NOT trust the device before a driver is bound to the device,
so if a malicious device can do something to the kernel, the kernel
needs to be fixed.
- During the probe() call for a USB driver, the driver does NOT trust
the device, and again, anything a malicious device can do to the
kernel, the kernel should fix.
- After probe() for a USB driver succeeds, it's up to the driver if it
wants to validate all data coming from the device or not. Right
now, in general, the kernel trusts the device at that point in time
so additional checks are discretionary and at the whim of the
maintainer.
For that last point, I will note that some BIG users of Linux (i.e.
billions of Android devices) still explicitly do NOT want to trust the
USB device at this point in time, and are relying on the kernel to
protect the system from bad devices. In that case, various patches have
been taken to different drivers and subsystems to play whack-a-mole on
while Android gets their act together to finally come up with a solid
defensive plan (like ChromeOS has had for a decade.) It will be seen
which happens first, all drivers are properly fuzzed and fixed up, or
Android gets their act together and finally fixes their b0rked system
trust model. I think Android management is relying on the kernel
community to do the kernel work as they keep refusing to staff the
userspace work that they need to do here...
And yes, I really need to write this up in a more solid document for USB
and get it into the tree, but at least this email thread has forced me
to write down the above :)
So, again, for virtio drivers, what exactly do you all want to say is
your threat model that the drivers need to handle? Can you all agree on
something please? Otherwise, for new developers like Hari, this is
totaly confusion as to what they should be doing.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH] vsock: use sock_error() to consume sk_err after connect timeout
From: Stefano Garzarella @ 2026-07-20 8:17 UTC (permalink / raw)
To: Nguyen Dinh Phi
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, syzbot+1b2c9c4a0f8708082678, virtualization, netdev,
linux-kernel
In-Reply-To: <20260719220103.684489-1-phind.uet@gmail.com>
On Mon, Jul 20, 2026 at 05:57:47AM +0800, Nguyen Dinh Phi wrote:
>After vsock_connect() exits the wait loop due to sk->sk_err being
>set, the error was read but not cleared. This left sk->sk_err set
>for subsequent operations.
So, is this a fix? If yes, we should put a Fixes tag.
Also, can you describe how to trigger the issue?
Because I see this in vsock_connect(), so I thought it was in some way
already handled:
/* sk_err might have been set as a result of an earlier
* (failed) connect attempt.
*/
sk->sk_err = 0;
>Switch to sock_error() which atomically reads and clears sk->sk_err,
>so the error is consumed when returned.
>
>Signed-off-by: Nguyen Dinh Phi <phind.uet@gmail.com>
>Reported-by: syzbot+1b2c9c4a0f8708082678@syzkaller.appspotmail.com
Can you explain how this patch fixes that issue?
(this should be the first information to be put in the commit message
IMHO)
I'd like to understand better if this is a fix of real bug or just an
improvement to the code (which is fine by me).
Thanks,
Stefano
>---
> net/vmw_vsock/af_vsock.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
>diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
>index 622dbd046799..43eddc33ed12 100644
>--- a/net/vmw_vsock/af_vsock.c
>+++ b/net/vmw_vsock/af_vsock.c
>@@ -1847,14 +1847,11 @@ static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
> prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
> }
>
>- if (sk->sk_err) {
>- err = -sk->sk_err;
>+ err = sock_error(sk);
>+ if (err) {
> sk->sk_state = TCP_CLOSE;
> sock->state = SS_UNCONNECTED;
>- } else {
>- err = 0;
> }
>-
> out_wait:
> finish_wait(sk_sleep(sk), &wait);
> out:
>--
>2.53.0
>
^ permalink raw reply
* Re: [PATCH v2 1/4] virtio-mem: validate device-reported block size
From: David Hildenbrand (Arm) @ 2026-07-20 7:57 UTC (permalink / raw)
To: Carlos Bilbao, Greg Kroah-Hartman
Cc: Michael S. Tsirkin, Hari Mishal, Jason Wang, Xuan Zhuo,
Eugenio Pérez, virtualization, linux-kernel, elena.reshetova,
huster, mhollick, jiska.classen
In-Reply-To: <ae5bc86b-cb8d-4530-9e58-d285007deac0@gmail.com>
On 7/18/26 18:07, Carlos Bilbao wrote:
> On 7/17/26 22:29, Greg Kroah-Hartman wrote:
>
>> On Fri, Jul 17, 2026 at 08:31:09PM -0700, Carlos Bilbao wrote:
>>> Historically, one of the biggest criticisms of coco, especially around
>>> device hardening, was that there were too many values that a
>>> malicious/buggy device could misreport, making it a losing battle. That is
>>> no longer the case with LLMs, and we have the advantage (and challenge) of
>>> open-source dev, which allows us to receive many of these fixes "for free".
>>> If others want to burn their tokens, let them :)
>> I have lots of tokens to burn :)
>>
>> So along those lines, any suggestions on how best to fuzz these code
>> paths? Any workloads you all use for testing that I can take advantage
>> of?
>
>
> We've the virtio-mem config struct layout and the kernel source, so for
> obvious fixes like a NULL check, static analysis is better than fuzzing.
> Claude took a few mins to find me two examples:
>
> Patch 1: virtio-mem: reject non-power-of-two device_block_size
> This one is for virtio_mem_init() to check if
> !is_power_of_2(vm->device_block_size)
>
> Patch 2: virto-mem: validate region_size and usable_region_size
> THis one checks region_size != 0 and vm->usable_reion_size >
> vm->region_size.
>
> An endless factory of "silly" checks like these are low hanging fruit.
>
> Now, for harder bugs, looking around for fuzz options, VirtFuzz [1] looks
> like a great candidate for those interested in pursuing this direction.
>
>
> Their PoC fuzzes wireless/Bluetooth stack, but nothing our AI overlords
> can't quickly adapt for virtio-mem and other virtio drivers; the JSON
> definition to describe device behavior is easily extensible. Their threat
> model [2] describes an external attacker, but in the context of coco, the
> virtio device itself is the attacker. Here's a vibe coded PR of what I mean:
>
> https://github.com/seemoo-lab/VirtFuzz/pull/7
>
> CCed the creators/authors, thanks for open sourcing this!
>
> Thanks,
> Carlos
>
> [1] https://github.com/seemoo-lab/VirtFuzz
>
> On 7/17/26 22:29, Greg Kroah-Hartman wrote:
>
>> On Fri, Jul 17, 2026 at 08:31:09PM -0700, Carlos Bilbao wrote:
>>> Historically, one of the biggest criticisms of coco, especially around
>>> device hardening, was that there were too many values that a
>>> malicious/buggy device could misreport, making it a losing battle. That is
>>> no longer the case with LLMs, and we have the advantage (and challenge) of
>>> open-source dev, which allows us to receive many of these fixes "for free".
>>> If others want to burn their tokens, let them :)
>> I have lots of tokens to burn :)
>>
>> So along those lines, any suggestions on how best to fuzz these code
>> paths? Any workloads you all use for testing that I can take advantage
>> of?
>
>
> We've the virto-mem config struct layout and the kernel source, so for
> obvious fixes like a NULL check, static analysis is better than fuzzing.
> Claude took a few mins to find me two examples:
>
> Patch 1: virtio-mem: reject non-power-of-two device_block_size
> This one is for virtio_mem_init() to check if
> !is_power_of_2(vm->device_block_size)
>
> Patch 2: virto-mem: validate region_size and usable_region_size
> THis one checks region_size != 0 and vm->usable_reion_size >
> vm->region_size.
>
> An endless factory of "silly" checks like these are low hanging fruit.
"silly" is the right word.
--
Cheers,
David
^ permalink raw reply
* [PATCH] tools/virtio: Fix control typo in trace agent comment
From: GuoHan Zhao @ 2026-07-20 1:45 UTC (permalink / raw)
To: Michael S. Tsirkin, Jason Wang, virtualization
Cc: Xuan Zhuo, Eugenio Pérez, linux-kernel
Fix a misspelling of "control" in the trace agent controller description.
Signed-off-by: GuoHan Zhao <zhaoguohan@kylinos.cn>
---
tools/virtio/virtio-trace/trace-agent-ctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/virtio/virtio-trace/trace-agent-ctl.c b/tools/virtio/virtio-trace/trace-agent-ctl.c
index 39860be6e2d8..9577579e86da 100644
--- a/tools/virtio/virtio-trace/trace-agent-ctl.c
+++ b/tools/virtio/virtio-trace/trace-agent-ctl.c
@@ -84,7 +84,7 @@ static int wait_order(int ctl_fd)
}
/*
- * contol read/write threads by handling global_run_operation
+ * control read/write threads by handling global_run_operation
*/
void *rw_ctl_loop(int ctl_fd)
{
--
2.43.0
^ permalink raw reply related
* [PATCH] tools/virtio: Fix userspace typo in vringh test comment
From: GuoHan Zhao @ 2026-07-20 1:44 UTC (permalink / raw)
To: Michael S. Tsirkin, Jason Wang, virtualization
Cc: Xuan Zhuo, Eugenio Pérez, linux-kernel
Fix a misspelling of "userspace" in the vringh test description.
Signed-off-by: GuoHan Zhao <zhaoguohan@kylinos.cn>
---
tools/virtio/vringh_test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/virtio/vringh_test.c b/tools/virtio/vringh_test.c
index 5ea6d29bc992..84961b9ab5ff 100644
--- a/tools/virtio/vringh_test.c
+++ b/tools/virtio/vringh_test.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
-/* Simple test of virtio code, entirely in userpsace. */
+/* Simple test of virtio code, entirely in userspace. */
#define _GNU_SOURCE
#include <sched.h>
#include <err.h>
--
2.43.0
^ permalink raw reply related
* [PATCH] vsock: use sock_error() to consume sk_err after connect timeout
From: Nguyen Dinh Phi @ 2026-07-19 21:57 UTC (permalink / raw)
To: Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: Nguyen Dinh Phi, syzbot+1b2c9c4a0f8708082678, virtualization,
netdev, linux-kernel
After vsock_connect() exits the wait loop due to sk->sk_err being
set, the error was read but not cleared. This left sk->sk_err set
for subsequent operations.
Switch to sock_error() which atomically reads and clears sk->sk_err,
so the error is consumed when returned.
Signed-off-by: Nguyen Dinh Phi <phind.uet@gmail.com>
Reported-by: syzbot+1b2c9c4a0f8708082678@syzkaller.appspotmail.com
---
net/vmw_vsock/af_vsock.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 622dbd046799..43eddc33ed12 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1847,14 +1847,11 @@ static int vsock_connect(struct socket *sock, struct sockaddr_unsized *addr,
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
}
- if (sk->sk_err) {
- err = -sk->sk_err;
+ err = sock_error(sk);
+ if (err) {
sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED;
- } else {
- err = 0;
}
-
out_wait:
finish_wait(sk_sleep(sk), &wait);
out:
--
2.53.0
^ permalink raw reply related
* Re: [PATCH 6.12] vsock/virtio: fix zerocopy completion for multi-skb sends
From: Sasha Levin @ 2026-07-19 15:00 UTC (permalink / raw)
To: stable, Greg Kroah-Hartman
Cc: Sasha Levin, Alexander Martyniuk, lvc-project, Michael S. Tsirkin,
Jason Wang, Xuan Zhuo, Eugenio Pérez, Stefan Hajnoczi,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Arseniy Krasnov, virtualization, kvm,
netdev, linux-kernel, Maher Azzouzi
In-Reply-To: <20260716163600.115458-1-alexevgmart@gmail.com>
> When a large message is fragmented into multiple skbs, the zerocopy
> uarg is only allocated and attached to the last skb in the loop.
> Non-final skbs carry pinned user pages with no completion tracking,
> so the kernel has no way to notify userspace when those pages are safe
> to reuse.
Queued for 6.12, thanks.
--
Thanks,
Sasha
^ permalink raw reply
* [PATCH 15/15] Documentation/gpu: remove completed drm_simple_encoder_init() todo
From: Diogo Silva @ 2026-07-18 23:35 UTC (permalink / raw)
To: Jingoo Han, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie,
Simona Vetter, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
Laurent Pinchart, Tomi Valkeinen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Michal Simek, Thierry Reding,
Mikko Perttunen, Jonathan Hunter, Stefan Agner, Alison Wang,
Anitha Chrisanthus, David Airlie, Gerd Hoffmann, Dmitry Osipenko,
Gurchetan Singh, Chia-I Wu, Jyri Sarha, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Geert Uytterhoeven, Xinliang Liu,
Sumit Semwal, Yongqin Liu, John Stultz, Liviu Dudau,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Jonathan Corbet, Shuah Khan
Cc: dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel,
linux-tegra, virtualization, imx, linux-mediatek,
linux-renesas-soc, linux-amlogic, linux-doc, Diogo Silva
In-Reply-To: <20260719-drm_simple_encoder_init-v1-0-a78c509e3062@gmail.com>
All drm_simple_encoder_init() users have been removed, so drop the
completed todo item.
Signed-off-by: Diogo Silva <diogompaissilva@gmail.com>
---
Documentation/gpu/todo.rst | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 14cf37590fc7..b7351467dc74 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -29,21 +29,6 @@ refactorings already and are an expert in the specific area
Subsystem-wide refactorings
===========================
-Open-code drm_simple_encoder_init()
------------------------------------
-
-The helper drm_simple_encoder_init() was supposed to simplify encoder
-initialization. Instead it only added an intermediate layer between atomic
-modesetting and the DRM driver.
-
-The task here is to remove drm_simple_encoder_init(). Search for a driver
-that calls drm_simple_encoder_init() and inline the helper. The driver will
-also need its own instance of drm_encoder_funcs.
-
-Contact: Thomas Zimmermann, respective driver maintainer
-
-Level: Easy
-
Replace struct drm_simple_display_pipe with regular atomic helpers
------------------------------------------------------------------
--
2.54.0
^ permalink raw reply related
* [PATCH 14/15] drm/drm_simple: remove deprecated drm_simple_encoder_init function
From: Diogo Silva @ 2026-07-18 23:35 UTC (permalink / raw)
To: Jingoo Han, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie,
Simona Vetter, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
Laurent Pinchart, Tomi Valkeinen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Michal Simek, Thierry Reding,
Mikko Perttunen, Jonathan Hunter, Stefan Agner, Alison Wang,
Anitha Chrisanthus, David Airlie, Gerd Hoffmann, Dmitry Osipenko,
Gurchetan Singh, Chia-I Wu, Jyri Sarha, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Geert Uytterhoeven, Xinliang Liu,
Sumit Semwal, Yongqin Liu, John Stultz, Liviu Dudau,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Jonathan Corbet, Shuah Khan
Cc: dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel,
linux-tegra, virtualization, imx, linux-mediatek,
linux-renesas-soc, linux-amlogic, linux-doc, Diogo Silva
In-Reply-To: <20260719-drm_simple_encoder_init-v1-0-a78c509e3062@gmail.com>
The simple KMS helpers are deprecated because they only add an
intermediate layer between drivers and atomic modesetting.
All driver users of drm_simple_encoder_init() have been converted to
drm_encoder_init(). Drop the helper and open-code its remaining internal
use in drm_simple_display_pipe_init() to prevent new users.
Signed-off-by: Diogo Silva <diogompaissilva@gmail.com>
---
drivers/gpu/drm/drm_simple_kms_helper.c | 13 ++-----------
include/drm/drm_simple_kms_helper.h | 4 ----
2 files changed, 2 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
index 8e1d07b9f1e3..7878b9d7d524 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -20,16 +20,6 @@ static const struct drm_encoder_funcs drm_simple_encoder_funcs_cleanup = {
.destroy = drm_encoder_cleanup,
};
-int drm_simple_encoder_init(struct drm_device *dev,
- struct drm_encoder *encoder,
- int encoder_type)
-{
- return drm_encoder_init(dev, encoder,
- &drm_simple_encoder_funcs_cleanup,
- encoder_type, NULL);
-}
-EXPORT_SYMBOL(drm_simple_encoder_init);
-
void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size,
size_t offset, int encoder_type)
{
@@ -363,7 +353,8 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
return ret;
encoder->possible_crtcs = drm_crtc_mask(crtc);
- ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_NONE);
+ ret = drm_encoder_init(dev, encoder, &drm_simple_encoder_funcs_cleanup,
+ DRM_MODE_ENCODER_NONE, NULL);
if (ret || !connector)
return ret;
diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h
index cb672ce0e856..c95f86ff355f 100644
--- a/include/drm/drm_simple_kms_helper.h
+++ b/include/drm/drm_simple_kms_helper.h
@@ -68,10 +68,6 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
const uint64_t *format_modifiers,
struct drm_connector *connector);
-int drm_simple_encoder_init(struct drm_device *dev,
- struct drm_encoder *encoder,
- int encoder_type);
-
void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size,
size_t offset, int encoder_type);
--
2.54.0
^ permalink raw reply related
* [PATCH 13/15] drm/meson: remove dependency on DRM simple helpers
From: Diogo Silva @ 2026-07-18 23:35 UTC (permalink / raw)
To: Jingoo Han, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie,
Simona Vetter, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
Laurent Pinchart, Tomi Valkeinen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Michal Simek, Thierry Reding,
Mikko Perttunen, Jonathan Hunter, Stefan Agner, Alison Wang,
Anitha Chrisanthus, David Airlie, Gerd Hoffmann, Dmitry Osipenko,
Gurchetan Singh, Chia-I Wu, Jyri Sarha, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Geert Uytterhoeven, Xinliang Liu,
Sumit Semwal, Yongqin Liu, John Stultz, Liviu Dudau,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Jonathan Corbet, Shuah Khan
Cc: dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel,
linux-tegra, virtualization, imx, linux-mediatek,
linux-renesas-soc, linux-amlogic, linux-doc, Diogo Silva
In-Reply-To: <20260719-drm_simple_encoder_init-v1-0-a78c509e3062@gmail.com>
The simple KMS helpers are deprecated because they only add an
intermediate layer between drivers and atomic modesetting.
Open-code drm_simple_encoder_init() by calling drm_encoder_init()
directly and providing driver-local drm_encoder_funcs.
Signed-off-by: Diogo Silva <diogompaissilva@gmail.com>
---
drivers/gpu/drm/meson/meson_encoder_cvbs.c | 11 ++++++++---
drivers/gpu/drm/meson/meson_encoder_dsi.c | 11 ++++++++---
drivers/gpu/drm/meson/meson_encoder_hdmi.c | 11 ++++++++---
3 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
index 22cacb1660c4..cdb84d2283f8 100644
--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
@@ -17,8 +17,8 @@
#include <drm/drm_bridge_connector.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
+#include <drm/drm_encoder.h>
#include <drm/drm_probe_helper.h>
-#include <drm/drm_simple_kms_helper.h>
#include "meson_registers.h"
#include "meson_vclk.h"
@@ -218,6 +218,10 @@ static const struct drm_bridge_funcs meson_encoder_cvbs_bridge_funcs = {
.atomic_create_state = drm_atomic_helper_bridge_create_state,
};
+static const struct drm_encoder_funcs meson_encoder_cvbs_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
int meson_encoder_cvbs_probe(struct meson_drm *priv)
{
struct drm_device *drm = priv->drm;
@@ -257,8 +261,9 @@ int meson_encoder_cvbs_probe(struct meson_drm *priv)
meson_encoder_cvbs->priv = priv;
/* Encoder */
- ret = drm_simple_encoder_init(priv->drm, &meson_encoder_cvbs->encoder,
- DRM_MODE_ENCODER_TVDAC);
+ ret = drm_encoder_init(priv->drm, &meson_encoder_cvbs->encoder,
+ &meson_encoder_cvbs_funcs,
+ DRM_MODE_ENCODER_TVDAC, NULL);
if (ret)
return dev_err_probe(priv->dev, ret,
"Failed to init CVBS encoder\n");
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
index 3e422b612f74..faa309cb97a6 100644
--- a/drivers/gpu/drm/meson/meson_encoder_dsi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
@@ -10,10 +10,10 @@
#include <linux/of_graph.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
#include <drm/drm_device.h>
+#include <drm/drm_encoder.h>
#include <drm/drm_probe_helper.h>
#include "meson_drv.h"
@@ -99,6 +99,10 @@ static const struct drm_bridge_funcs meson_encoder_dsi_bridge_funcs = {
.atomic_create_state = drm_atomic_helper_bridge_create_state,
};
+static const struct drm_encoder_funcs meson_encoder_dsi_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
int meson_encoder_dsi_probe(struct meson_drm *priv)
{
struct meson_encoder_dsi *meson_encoder_dsi;
@@ -133,8 +137,9 @@ int meson_encoder_dsi_probe(struct meson_drm *priv)
meson_encoder_dsi->priv = priv;
/* Encoder */
- ret = drm_simple_encoder_init(priv->drm, &meson_encoder_dsi->encoder,
- DRM_MODE_ENCODER_DSI);
+ ret = drm_encoder_init(priv->drm, &meson_encoder_dsi->encoder,
+ &meson_encoder_dsi_funcs, DRM_MODE_ENCODER_DSI,
+ NULL);
if (ret)
return dev_err_probe(priv->dev, ret,
"Failed to init DSI encoder\n");
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
index 0c7a72cb514a..c4355c5cc340 100644
--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -23,8 +23,8 @@
#include <drm/drm_bridge_connector.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
+#include <drm/drm_encoder.h>
#include <drm/drm_probe_helper.h>
-#include <drm/drm_simple_kms_helper.h>
#include <linux/media-bus-format.h>
#include <linux/videodev2.h>
@@ -369,6 +369,10 @@ static const struct drm_bridge_funcs meson_encoder_hdmi_bridge_funcs = {
.atomic_create_state = drm_atomic_helper_bridge_create_state,
};
+static const struct drm_encoder_funcs meson_encoder_hdmi_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
int meson_encoder_hdmi_probe(struct meson_drm *priv)
{
struct meson_encoder_hdmi *meson_encoder_hdmi;
@@ -407,8 +411,9 @@ int meson_encoder_hdmi_probe(struct meson_drm *priv)
meson_encoder_hdmi->priv = priv;
/* Encoder */
- ret = drm_simple_encoder_init(priv->drm, &meson_encoder_hdmi->encoder,
- DRM_MODE_ENCODER_TMDS);
+ ret = drm_encoder_init(priv->drm, &meson_encoder_hdmi->encoder,
+ &meson_encoder_hdmi_funcs,
+ DRM_MODE_ENCODER_TMDS, NULL);
if (ret) {
dev_err_probe(priv->dev, ret, "Failed to init HDMI encoder\n");
goto err_put_node;
--
2.54.0
^ permalink raw reply related
* [PATCH 12/15] drm/arm/komeda: remove dependency on DRM simple helpers
From: Diogo Silva @ 2026-07-18 23:35 UTC (permalink / raw)
To: Jingoo Han, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie,
Simona Vetter, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
Laurent Pinchart, Tomi Valkeinen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Michal Simek, Thierry Reding,
Mikko Perttunen, Jonathan Hunter, Stefan Agner, Alison Wang,
Anitha Chrisanthus, David Airlie, Gerd Hoffmann, Dmitry Osipenko,
Gurchetan Singh, Chia-I Wu, Jyri Sarha, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Geert Uytterhoeven, Xinliang Liu,
Sumit Semwal, Yongqin Liu, John Stultz, Liviu Dudau,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Jonathan Corbet, Shuah Khan
Cc: dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel,
linux-tegra, virtualization, imx, linux-mediatek,
linux-renesas-soc, linux-amlogic, linux-doc, Diogo Silva
In-Reply-To: <20260719-drm_simple_encoder_init-v1-0-a78c509e3062@gmail.com>
The simple KMS helpers are deprecated because they only add an
intermediate layer between drivers and atomic modesetting.
Open-code drm_simple_encoder_init() by calling drm_encoder_init()
directly and providing driver-local drm_encoder_funcs.
Signed-off-by: Diogo Silva <diogompaissilva@gmail.com>
---
drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index e8cb782a6f8e..719568d9f7c2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -11,9 +11,9 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_encoder.h>
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>
-#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_bridge.h>
#include "komeda_dev.h"
@@ -635,6 +635,10 @@ static int komeda_attach_bridge(struct device *dev,
return err;
}
+static const struct drm_encoder_funcs komeda_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
static int komeda_crtc_add(struct komeda_kms_dev *kms,
struct komeda_crtc *kcrtc)
{
@@ -658,7 +662,8 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms,
* bridge
*/
kcrtc->encoder.possible_crtcs = drm_crtc_mask(crtc);
- err = drm_simple_encoder_init(base, encoder, DRM_MODE_ENCODER_TMDS);
+ err = drm_encoder_init(base, encoder, &komeda_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS, NULL);
if (err)
return err;
--
2.54.0
^ permalink raw reply related
* [PATCH 11/15] drm/hisilicon/kirin: remove dependency on DRM simple helpers
From: Diogo Silva @ 2026-07-18 23:35 UTC (permalink / raw)
To: Jingoo Han, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie,
Simona Vetter, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
Laurent Pinchart, Tomi Valkeinen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Michal Simek, Thierry Reding,
Mikko Perttunen, Jonathan Hunter, Stefan Agner, Alison Wang,
Anitha Chrisanthus, David Airlie, Gerd Hoffmann, Dmitry Osipenko,
Gurchetan Singh, Chia-I Wu, Jyri Sarha, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Geert Uytterhoeven, Xinliang Liu,
Sumit Semwal, Yongqin Liu, John Stultz, Liviu Dudau,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Jonathan Corbet, Shuah Khan
Cc: dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel,
linux-tegra, virtualization, imx, linux-mediatek,
linux-renesas-soc, linux-amlogic, linux-doc, Diogo Silva
In-Reply-To: <20260719-drm_simple_encoder_init-v1-0-a78c509e3062@gmail.com>
The simple KMS helpers are deprecated because they only add an
intermediate layer between drivers and atomic modesetting.
Open-code drm_simple_encoder_init() by calling drm_encoder_init()
directly and providing driver-local drm_encoder_funcs.
Signed-off-by: Diogo Silva <diogompaissilva@gmail.com>
---
drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
index 15042365dec0..62c5bd3277da 100644
--- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
+++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c
@@ -20,11 +20,11 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_device.h>
+#include <drm/drm_encoder.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_of.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
-#include <drm/drm_simple_kms_helper.h>
#include "dw_dsi_reg.h"
@@ -687,6 +687,10 @@ static int dsi_encoder_atomic_check(struct drm_encoder *encoder,
return 0;
}
+static const struct drm_encoder_funcs dw_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
static const struct drm_encoder_helper_funcs dw_encoder_helper_funcs = {
.atomic_check = dsi_encoder_atomic_check,
.mode_valid = dsi_encoder_mode_valid,
@@ -708,7 +712,8 @@ static int dw_drm_encoder_init(struct device *dev,
}
encoder->possible_crtcs = crtc_mask;
- ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_DSI);
+ ret = drm_encoder_init(drm_dev, encoder, &dw_encoder_funcs,
+ DRM_MODE_ENCODER_DSI, NULL);
if (ret) {
DRM_ERROR("failed to init dsi encoder\n");
return ret;
--
2.54.0
^ permalink raw reply related
* [PATCH 10/15] drm/renesas/shmobile: remove dependency on DRM simple helpers
From: Diogo Silva @ 2026-07-18 23:35 UTC (permalink / raw)
To: Jingoo Han, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie,
Simona Vetter, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
Laurent Pinchart, Tomi Valkeinen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Michal Simek, Thierry Reding,
Mikko Perttunen, Jonathan Hunter, Stefan Agner, Alison Wang,
Anitha Chrisanthus, David Airlie, Gerd Hoffmann, Dmitry Osipenko,
Gurchetan Singh, Chia-I Wu, Jyri Sarha, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Geert Uytterhoeven, Xinliang Liu,
Sumit Semwal, Yongqin Liu, John Stultz, Liviu Dudau,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Jonathan Corbet, Shuah Khan
Cc: dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel,
linux-tegra, virtualization, imx, linux-mediatek,
linux-renesas-soc, linux-amlogic, linux-doc, Diogo Silva
In-Reply-To: <20260719-drm_simple_encoder_init-v1-0-a78c509e3062@gmail.com>
The simple KMS helpers are deprecated because they only add an
intermediate layer between drivers and atomic modesetting.
Open-code drm_simple_encoder_init() by calling drm_encoder_init()
directly and providing driver-local drm_encoder_funcs.
Signed-off-by: Diogo Silva <diogompaissilva@gmail.com>
---
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
index 1a2b9b68af6f..2dc477c7eda6 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c
@@ -21,6 +21,7 @@
#include <drm/drm_bridge_connector.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
+#include <drm/drm_encoder.h>
#include <drm/drm_fb_dma_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
@@ -29,7 +30,6 @@
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>
-#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_vblank.h>
#include <video/videomode.h>
@@ -436,6 +436,10 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
.mode_fixup = shmob_drm_encoder_mode_fixup,
};
+static const struct drm_encoder_funcs shmob_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
/* -----------------------------------------------------------------------------
* Encoder
*/
@@ -448,8 +452,8 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
encoder->possible_crtcs = 1;
- ret = drm_simple_encoder_init(&sdev->ddev, encoder,
- DRM_MODE_ENCODER_DPI);
+ ret = drm_encoder_init(&sdev->ddev, encoder, &shmob_encoder_funcs,
+ DRM_MODE_ENCODER_DPI, NULL);
if (ret < 0)
return ret;
--
2.54.0
^ permalink raw reply related
* [PATCH 09/15] drm/mediatek: remove dependency on DRM simple helpers
From: Diogo Silva @ 2026-07-18 23:35 UTC (permalink / raw)
To: Jingoo Han, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie,
Simona Vetter, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
Laurent Pinchart, Tomi Valkeinen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Michal Simek, Thierry Reding,
Mikko Perttunen, Jonathan Hunter, Stefan Agner, Alison Wang,
Anitha Chrisanthus, David Airlie, Gerd Hoffmann, Dmitry Osipenko,
Gurchetan Singh, Chia-I Wu, Jyri Sarha, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Geert Uytterhoeven, Xinliang Liu,
Sumit Semwal, Yongqin Liu, John Stultz, Liviu Dudau,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Jonathan Corbet, Shuah Khan
Cc: dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel,
linux-tegra, virtualization, imx, linux-mediatek,
linux-renesas-soc, linux-amlogic, linux-doc, Diogo Silva
In-Reply-To: <20260719-drm_simple_encoder_init-v1-0-a78c509e3062@gmail.com>
The simple KMS helpers are deprecated because they only add an
intermediate layer between drivers and atomic modesetting.
Open-code drm_simple_encoder_init() by calling drm_encoder_init()
directly and providing driver-local drm_encoder_funcs.
Signed-off-by: Diogo Silva <diogompaissilva@gmail.com>
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 3f3f56eed3f9..7cd136bd9605 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -21,12 +21,12 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
+#include <drm/drm_encoder.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
-#include <drm/drm_simple_kms_helper.h>
#include "mtk_ddp_comp.h"
#include "mtk_disp_drv.h"
@@ -913,12 +913,16 @@ void mtk_dsi_ddp_stop(struct device *dev)
mtk_dsi_poweroff(dsi);
}
+static const struct drm_encoder_funcs mtk_dsi_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
{
int ret;
- ret = drm_simple_encoder_init(drm, &dsi->encoder,
- DRM_MODE_ENCODER_DSI);
+ ret = drm_encoder_init(drm, &dsi->encoder, &mtk_dsi_encoder_funcs,
+ DRM_MODE_ENCODER_DSI, NULL);
if (ret) {
drm_err(drm, "Failed to encoder init to drm\n");
return ret;
--
2.54.0
^ permalink raw reply related
* [PATCH 08/15] drm/imx: remove dependency on DRM simple helpers
From: Diogo Silva @ 2026-07-18 23:35 UTC (permalink / raw)
To: Jingoo Han, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie,
Simona Vetter, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
Laurent Pinchart, Tomi Valkeinen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Michal Simek, Thierry Reding,
Mikko Perttunen, Jonathan Hunter, Stefan Agner, Alison Wang,
Anitha Chrisanthus, David Airlie, Gerd Hoffmann, Dmitry Osipenko,
Gurchetan Singh, Chia-I Wu, Jyri Sarha, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Geert Uytterhoeven, Xinliang Liu,
Sumit Semwal, Yongqin Liu, John Stultz, Liviu Dudau,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Jonathan Corbet, Shuah Khan
Cc: dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel,
linux-tegra, virtualization, imx, linux-mediatek,
linux-renesas-soc, linux-amlogic, linux-doc, Diogo Silva
In-Reply-To: <20260719-drm_simple_encoder_init-v1-0-a78c509e3062@gmail.com>
The simple KMS helpers are deprecated because they only add an
intermediate layer between drivers and atomic modesetting.
Open-code drm_simple_encoder_init() by calling drm_encoder_init()
directly and providing driver-local drm_encoder_funcs.
Signed-off-by: Diogo Silva <diogompaissilva@gmail.com>
---
drivers/gpu/drm/imx/dc/dc-kms.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/imx/dc/dc-kms.c b/drivers/gpu/drm/imx/dc/dc-kms.c
index 0f8cfaf4c4d1..a9adcfc68b84 100644
--- a/drivers/gpu/drm/imx/dc/dc-kms.c
+++ b/drivers/gpu/drm/imx/dc/dc-kms.c
@@ -17,7 +17,6 @@
#include <drm/drm_mode_config.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
-#include <drm/drm_simple_kms_helper.h>
#include <drm/drm_vblank.h>
#include "dc-de.h"
@@ -30,6 +29,10 @@ static const struct drm_mode_config_funcs dc_drm_mode_config_funcs = {
.atomic_commit = drm_atomic_helper_commit,
};
+static const struct drm_encoder_funcs dc_kms_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
int crtc_index)
{
@@ -55,7 +58,8 @@ static int dc_kms_init_encoder_per_crtc(struct dc_drm_device *dc_drm,
}
encoder = &dc_drm->encoder[crtc_index];
- ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
+ ret = drm_encoder_init(drm, encoder, &dc_kms_encoder_funcs,
+ DRM_MODE_ENCODER_NONE, NULL);
if (ret) {
dev_err(dev, "failed to initialize encoder for CRTC%u: %d\n",
crtc->index, ret);
--
2.54.0
^ permalink raw reply related
* [PATCH 07/15] drm/tidss: remove dependency on DRM simple helpers
From: Diogo Silva @ 2026-07-18 23:35 UTC (permalink / raw)
To: Jingoo Han, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie,
Simona Vetter, Krzysztof Kozlowski, Peter Griffin, Alim Akhtar,
Laurent Pinchart, Tomi Valkeinen, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Michal Simek, Thierry Reding,
Mikko Perttunen, Jonathan Hunter, Stefan Agner, Alison Wang,
Anitha Chrisanthus, David Airlie, Gerd Hoffmann, Dmitry Osipenko,
Gurchetan Singh, Chia-I Wu, Jyri Sarha, Liu Ying, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Chun-Kuang Hu, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Geert Uytterhoeven, Xinliang Liu,
Sumit Semwal, Yongqin Liu, John Stultz, Liviu Dudau,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Jonathan Corbet, Shuah Khan
Cc: dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel,
linux-tegra, virtualization, imx, linux-mediatek,
linux-renesas-soc, linux-amlogic, linux-doc, Diogo Silva
In-Reply-To: <20260719-drm_simple_encoder_init-v1-0-a78c509e3062@gmail.com>
The simple KMS helpers are deprecated because they only add an
intermediate layer between drivers and atomic modesetting.
Open-code drm_simple_encoder_init() by calling drm_encoder_init()
directly and providing driver-local drm_encoder_funcs.
Signed-off-by: Diogo Silva <diogompaissilva@gmail.com>
---
drivers/gpu/drm/tidss/tidss_encoder.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/tidss/tidss_encoder.c b/drivers/gpu/drm/tidss/tidss_encoder.c
index 698f8d964ca0..10dbcc6cdf6a 100644
--- a/drivers/gpu/drm/tidss/tidss_encoder.c
+++ b/drivers/gpu/drm/tidss/tidss_encoder.c
@@ -9,11 +9,11 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
+#include <drm/drm_encoder.h>
#include <drm/drm_crtc.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_panel.h>
#include <drm/drm_of.h>
-#include <drm/drm_simple_kms_helper.h>
#include "tidss_crtc.h"
#include "tidss_drv.h"
@@ -81,6 +81,10 @@ static const struct drm_bridge_funcs tidss_bridge_funcs = {
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
};
+static const struct drm_encoder_funcs tidss_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
int tidss_encoder_create(struct tidss_device *tidss,
struct drm_bridge *next_bridge,
u32 encoder_type, u32 possible_crtcs)
@@ -95,8 +99,8 @@ int tidss_encoder_create(struct tidss_device *tidss,
if (IS_ERR(t_enc))
return PTR_ERR(t_enc);
- ret = drm_simple_encoder_init(&tidss->ddev, &t_enc->encoder,
- encoder_type);
+ ret = drm_encoder_init(&tidss->ddev, &t_enc->encoder,
+ &tidss_encoder_funcs, encoder_type, NULL);
if (ret)
return ret;
--
2.54.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox