From nobody Thu Jun 25 05:23:46 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D747D3812E1 for ; Fri, 12 Jun 2026 18:15:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781288115; cv=none; b=M8OiOJ/AquH5x3qU+SIgwYTzo5MoAOpDe/4AH2gBsHH8Z+Hr+h9CbQ4Rd1nVj1sfrbjz3wj33akOE4JqpHsJeHc+ik17Otc59WTgp1NX/wj0wOqGYkLcx8TCVxFQYsVnTwcjJStl4qJYTqc34BuHLcMb16cPfby6A2kedJqsXeg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781288115; c=relaxed/simple; bh=dG3DzxnaurEJh8xpxUNSsCxz0YUeYiFBZPBHly71tiU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=SN66rKkpgLJfK6H3oOYHboJFr7grnvQUgWXbrhsotVajLYjqgT9CRoWwQsvivrukWzhqg+S3zbTRZcWH8hb61uGnuMdTUZEn9gFdC6w4+BXLnRZFEkpzM3b10uQGgVaIBb4koRt3EeN390RSWfhFkKUpN+/8QF8SmBSm1Gb1UDE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=gWrlFmWD; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="gWrlFmWD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1781288112; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Qu9A9kd8JCmjRb9VSzcWI4Z7Ay28AWwMmLW/VYYJhfk=; b=gWrlFmWDauH6Vt8P+DfaPpbKVD9mR6gBqw5RNiMK8NcwnB59YdCKsy2DkM7cxDshZeeq70 EZQ0jMelod5U/EsjP6HaV0SVYC1/grctZLIxHMnN0WuICm/0MDQHZAHL+ZLlSFhiERxIfT fIUTMVIsdEMow7/+pMtQqb2Qs6xs+28= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-634-2drVd6BdNgib-FZU7VIJ7Q-1; Fri, 12 Jun 2026 14:15:08 -0400 X-MC-Unique: 2drVd6BdNgib-FZU7VIJ7Q-1 X-Mimecast-MFC-AGG-ID: 2drVd6BdNgib-FZU7VIJ7Q_1781288107 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 21ED218501C1; Fri, 12 Jun 2026 18:15:07 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.32.24]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2438130001A1; Fri, 12 Jun 2026 18:15:02 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin" Cc: Maxime Coquelin , linux-kernel@vger.kernel.org, Yongji Xie , Jason Wang , virtualization@lists.linux.dev, Cindy Lu , Stefano Garzarella , Xuan Zhuo , =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier Subject: [PATCH v4 1/2] vduse: do not take rwsem at reset work flush Date: Fri, 12 Jun 2026 20:14:56 +0200 Message-ID: <20260612181457.622955-2-eperezma@redhat.com> In-Reply-To: <20260612181457.622955-1-eperezma@redhat.com> References: <20260612181457.622955-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Next patches need to check suspend flag at this work item, and the rwlock is used to protect the suspend flag update. If the work takes the rwlock too it will produce a deadlock. Signed-off-by: Eugenio P=C3=A9rez --- drivers/vdpa/vdpa_user/vduse_dev.c | 63 ++++++++++++++++-------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vd= use_dev.c index eff104f90cee..0f15575df394 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -501,44 +501,47 @@ static void vduse_dev_reset(struct vduse_dev *dev) vduse_domain_reset_bounce_map(domain); } =20 - down_write(&dev->rwsem); + scoped_guard(rwsem_write, &dev->rwsem) { + dev->status =3D 0; + dev->driver_features =3D 0; + dev->generation++; + spin_lock(&dev->irq_lock); + dev->config_cb.callback =3D NULL; + dev->config_cb.private =3D NULL; + spin_unlock(&dev->irq_lock); + + for (i =3D 0; i < dev->vq_num; i++) { + struct vduse_virtqueue *vq =3D dev->vqs[i]; + + vq->ready =3D false; + vq->desc_addr =3D 0; + vq->driver_addr =3D 0; + vq->device_addr =3D 0; + vq->num =3D 0; + memset(&vq->state, 0, sizeof(vq->state)); + + spin_lock(&vq->kick_lock); + vq->kicked =3D false; + if (vq->kickfd) + eventfd_ctx_put(vq->kickfd); + vq->kickfd =3D NULL; + spin_unlock(&vq->kick_lock); + + spin_lock(&vq->irq_lock); + vq->cb.callback =3D NULL; + vq->cb.private =3D NULL; + vq->cb.trigger =3D NULL; + spin_unlock(&vq->irq_lock); + } + } =20 - dev->status =3D 0; - dev->driver_features =3D 0; - dev->generation++; - spin_lock(&dev->irq_lock); - dev->config_cb.callback =3D NULL; - dev->config_cb.private =3D NULL; - spin_unlock(&dev->irq_lock); flush_work(&dev->inject); - for (i =3D 0; i < dev->vq_num; i++) { struct vduse_virtqueue *vq =3D dev->vqs[i]; =20 - vq->ready =3D false; - vq->desc_addr =3D 0; - vq->driver_addr =3D 0; - vq->device_addr =3D 0; - vq->num =3D 0; - memset(&vq->state, 0, sizeof(vq->state)); - - spin_lock(&vq->kick_lock); - vq->kicked =3D false; - if (vq->kickfd) - eventfd_ctx_put(vq->kickfd); - vq->kickfd =3D NULL; - spin_unlock(&vq->kick_lock); - - spin_lock(&vq->irq_lock); - vq->cb.callback =3D NULL; - vq->cb.private =3D NULL; - vq->cb.trigger =3D NULL; - spin_unlock(&vq->irq_lock); flush_work(&vq->inject); flush_work(&vq->kick); } - - up_write(&dev->rwsem); } =20 static int vduse_vdpa_set_vq_address(struct vdpa_device *vdpa, u16 idx, --=20 2.54.0 From nobody Thu Jun 25 05:23:46 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D6D238656D for ; Fri, 12 Jun 2026 18:15:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781288119; cv=none; b=DRodA6uhcX+zoZkmZrUDMkl9m6E17JTX8qiG2bzcM6A1t3srhuX7zepkyZcpaD5Ug5Yc1OymvkZ1bZpRxIfUb1lFvn1tsK/uqoBIukNQzi+/hfKfY5757BhRUuwO/WEzSNBm1hZOimLTgajAuuxX1igV/EdRMZen92wGgmdqETc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781288119; c=relaxed/simple; bh=ygF0xZ+bBE+nje9RMBG3Vmj/td5eIqzMNrD9v6psoI4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Ew7TU2xVr9WLXFpk7zD1832l9XfqQ3EexTtvZh/KV1KgHUS6OSJCUjKpJgMYWxU/+oH6wV6LAi7UM4sdr84A0S0np2T5lLAnFZ3X4BHjq+wMlGEFHG2koHCu6fr13AgD14wsN9YC0hzBxtaIYE1H2Mq9GF0SAQ6p2fk9Zzz8+Xo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=MNMNGuWm; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="MNMNGuWm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1781288116; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VaJrkoqFzLWWB9tDl/zS2yeIIDG+OTFOtI2yTjsgXsU=; b=MNMNGuWmkvUT3ftjXFQAMMNE/DH/vkGyVV895b11V+E9iYk1SnIR1CdzwsKgQOlQAz5wkX gE+Rr2O6WYPcwNefntqfFCWasGt3nF4zHbZBLcWjtkOqx4IdAThOG8W3wLos9r7C0udtsH jhyGCLGQ6f+bw+0zU5kGKvqjbAfwpRk= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-84-rZQ3-ln_PDe1mJjM0slJYA-1; Fri, 12 Jun 2026 14:15:13 -0400 X-MC-Unique: rZQ3-ln_PDe1mJjM0slJYA-1 X-Mimecast-MFC-AGG-ID: rZQ3-ln_PDe1mJjM0slJYA_1781288112 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 63AD41955E72; Fri, 12 Jun 2026 18:15:11 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.32.24]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9AE463008B37; Fri, 12 Jun 2026 18:15:07 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin" Cc: Maxime Coquelin , linux-kernel@vger.kernel.org, Yongji Xie , Jason Wang , virtualization@lists.linux.dev, Cindy Lu , Stefano Garzarella , Xuan Zhuo , =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier Subject: [PATCH v4 2/2] vduse: Add suspend Date: Fri, 12 Jun 2026 20:14:57 +0200 Message-ID: <20260612181457.622955-3-eperezma@redhat.com> In-Reply-To: <20260612181457.622955-1-eperezma@redhat.com> References: <20260612181457.622955-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Implement suspend operation for vduse devices, so vhost-vdpa will offer that backend feature and userspace can effectively suspend the device. This is a must before get virtqueue indexes (base) for live migration, since the device could modify them after userland gets them. This patch does not implement resume, so VMM resets the whole device to recover from a live migration failure. Resume optimization can be implemented on top of these patches, as other vDPA devices have done in the past. Signed-off-by: Eugenio P=C3=A9rez --- v4: * Add preparatory patch to not flush the kick and irq works under rwsem (MST). * Fix jump over a semaphore guard (Nathan Chancellor). * Fix take the device semaphore in the vq spinlock context (MST). * Add suspend guard at vq_signal_irqfd so the device will not send an IRQ after suspend. v3: * Expand the patch message with information about resume operation. v2: * Take the rwsem only before the actual kick, not in vduse_vdpa_kick_vq. This assures that we're not in a critical section. --- drivers/vdpa/vdpa_user/vduse_dev.c | 101 +++++++++++++++++++++++++---- include/uapi/linux/vduse.h | 4 ++ 2 files changed, 94 insertions(+), 11 deletions(-) diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vd= use_dev.c index 0f15575df394..80dc37ed7e13 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -54,7 +54,8 @@ #define IRQ_UNBOUND -1 =20 /* Supported VDUSE features */ -static const uint64_t vduse_features =3D BIT_U64(VDUSE_F_QUEUE_READY); +static const uint64_t vduse_features =3D BIT_U64(VDUSE_F_QUEUE_READY) | + BIT_U64(VDUSE_F_SUSPEND); =20 /* * VDUSE instance have not asked the vduse API version, so assume 0. @@ -85,6 +86,7 @@ struct vduse_virtqueue { int irq_effective_cpu; struct cpumask irq_affinity; struct kobject kobj; + struct vduse_dev *dev; }; =20 struct vduse_dev; @@ -134,6 +136,7 @@ struct vduse_dev { int minor; bool broken; bool connected; + bool suspended; u64 api_version; u64 device_features; u64 driver_features; @@ -502,6 +505,7 @@ static void vduse_dev_reset(struct vduse_dev *dev) } =20 scoped_guard(rwsem_write, &dev->rwsem) { + dev->suspended =3D false; dev->status =3D 0; dev->driver_features =3D 0; dev->generation++; @@ -560,16 +564,18 @@ static int vduse_vdpa_set_vq_address(struct vdpa_devi= ce *vdpa, u16 idx, =20 static void vduse_vq_kick(struct vduse_virtqueue *vq) { - spin_lock(&vq->kick_lock); + guard(rwsem_read)(&vq->dev->rwsem); + if (vq->dev->suspended) + return; + + guard(spinlock)(&vq->kick_lock); if (!vq->ready) - goto unlock; + return; =20 if (vq->kickfd) eventfd_signal(vq->kickfd); else vq->kicked =3D true; -unlock: - spin_unlock(&vq->kick_lock); } =20 static void vduse_vq_kick_work(struct work_struct *work) @@ -922,6 +928,27 @@ static int vduse_vdpa_set_map(struct vdpa_device *vdpa, return 0; } =20 +static int vduse_vdpa_suspend(struct vdpa_device *vdpa) +{ + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); + struct vduse_dev_msg msg =3D { 0 }; + int ret; + + msg.req.type =3D VDUSE_SUSPEND; + + ret =3D vduse_dev_msg_sync(dev, &msg); + if (ret =3D=3D 0) { + scoped_guard(rwsem_write, &dev->rwsem) + dev->suspended =3D true; + + cancel_work_sync(&dev->inject); + for (u32 i =3D 0; i < dev->vq_num; i++) + cancel_work_sync(&dev->vqs[i]->inject); + } + + return ret; +} + static void vduse_vdpa_free(struct vdpa_device *vdpa) { struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); @@ -963,6 +990,41 @@ static const struct vdpa_config_ops vduse_vdpa_config_= ops =3D { .free =3D vduse_vdpa_free, }; =20 +static const struct vdpa_config_ops vduse_vdpa_config_ops_with_suspend =3D= { + .set_vq_address =3D vduse_vdpa_set_vq_address, + .kick_vq =3D vduse_vdpa_kick_vq, + .set_vq_cb =3D vduse_vdpa_set_vq_cb, + .set_vq_num =3D vduse_vdpa_set_vq_num, + .get_vq_size =3D vduse_vdpa_get_vq_size, + .get_vq_group =3D vduse_get_vq_group, + .set_vq_ready =3D vduse_vdpa_set_vq_ready, + .get_vq_ready =3D vduse_vdpa_get_vq_ready, + .set_vq_state =3D vduse_vdpa_set_vq_state, + .get_vq_state =3D vduse_vdpa_get_vq_state, + .get_vq_align =3D vduse_vdpa_get_vq_align, + .get_device_features =3D vduse_vdpa_get_device_features, + .set_driver_features =3D vduse_vdpa_set_driver_features, + .get_driver_features =3D vduse_vdpa_get_driver_features, + .set_config_cb =3D vduse_vdpa_set_config_cb, + .get_vq_num_max =3D vduse_vdpa_get_vq_num_max, + .get_device_id =3D vduse_vdpa_get_device_id, + .get_vendor_id =3D vduse_vdpa_get_vendor_id, + .get_status =3D vduse_vdpa_get_status, + .set_status =3D vduse_vdpa_set_status, + .get_config_size =3D vduse_vdpa_get_config_size, + .get_config =3D vduse_vdpa_get_config, + .set_config =3D vduse_vdpa_set_config, + .get_generation =3D vduse_vdpa_get_generation, + .set_vq_affinity =3D vduse_vdpa_set_vq_affinity, + .get_vq_affinity =3D vduse_vdpa_get_vq_affinity, + .reset =3D vduse_vdpa_reset, + .set_map =3D vduse_vdpa_set_map, + .set_group_asid =3D vduse_set_group_asid, + .get_vq_map =3D vduse_get_vq_map, + .suspend =3D vduse_vdpa_suspend, + .free =3D vduse_vdpa_free, +}; + static void vduse_dev_sync_single_for_device(union virtio_map token, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) @@ -1174,6 +1236,10 @@ static void vduse_dev_irq_inject(struct work_struct = *work) { struct vduse_dev *dev =3D container_of(work, struct vduse_dev, inject); =20 + guard(rwsem_read)(&dev->rwsem); + if (dev->suspended) + return; + spin_lock_bh(&dev->irq_lock); if (dev->config_cb.callback) dev->config_cb.callback(dev->config_cb.private); @@ -1185,6 +1251,10 @@ static void vduse_vq_irq_inject(struct work_struct *= work) struct vduse_virtqueue *vq =3D container_of(work, struct vduse_virtqueue, inject); =20 + guard(rwsem_read)(&vq->dev->rwsem); + if (vq->dev->suspended) + return; + spin_lock_bh(&vq->irq_lock); if (vq->ready && vq->cb.callback) vq->cb.callback(vq->cb.private); @@ -1195,6 +1265,10 @@ static bool vduse_vq_signal_irqfd(struct vduse_virtq= ueue *vq) { bool signal =3D false; =20 + guard(rwsem_read)(&vq->dev->rwsem); + if (vq->dev->suspended) + return false; + if (!vq->cb.trigger) return false; =20 @@ -1214,9 +1288,9 @@ static int vduse_dev_queue_irq_work(struct vduse_dev = *dev, { int ret =3D -EINVAL; =20 - down_read(&dev->rwsem); - if (!(dev->status & VIRTIO_CONFIG_S_DRIVER_OK)) - goto unlock; + guard(rwsem_read)(&dev->rwsem); + if (dev->suspended || !(dev->status & VIRTIO_CONFIG_S_DRIVER_OK)) + return ret; =20 ret =3D 0; if (irq_effective_cpu =3D=3D IRQ_UNBOUND) @@ -1224,8 +1298,6 @@ static int vduse_dev_queue_irq_work(struct vduse_dev = *dev, else queue_work_on(irq_effective_cpu, vduse_irq_bound_wq, irq_work); -unlock: - up_read(&dev->rwsem); =20 return ret; } @@ -1979,6 +2051,7 @@ static int vduse_dev_init_vqs(struct vduse_dev *dev, = u32 vq_align, u32 vq_num) } =20 dev->vqs[i]->index =3D i; + dev->vqs[i]->dev =3D dev; dev->vqs[i]->irq_effective_cpu =3D IRQ_UNBOUND; INIT_WORK(&dev->vqs[i]->inject, vduse_vq_irq_inject); INIT_WORK(&dev->vqs[i]->kick, vduse_vq_kick_work); @@ -2429,12 +2502,18 @@ static struct vduse_mgmt_dev *vduse_mgmt; static int vduse_dev_init_vdpa(struct vduse_dev *dev, const char *name) { struct vduse_vdpa *vdev; + const struct vdpa_config_ops *ops; =20 if (dev->vdev) return -EEXIST; =20 + if (dev->vduse_features & BIT_U64(VDUSE_F_SUSPEND)) + ops =3D &vduse_vdpa_config_ops_with_suspend; + else + ops =3D &vduse_vdpa_config_ops; + vdev =3D vdpa_alloc_device(struct vduse_vdpa, vdpa, dev->dev, - &vduse_vdpa_config_ops, &vduse_map_ops, + ops, &vduse_map_ops, dev->ngroups, dev->nas, name, true); if (IS_ERR(vdev)) return PTR_ERR(vdev); diff --git a/include/uapi/linux/vduse.h b/include/uapi/linux/vduse.h index 7324faea5df4..8c616895c511 100644 --- a/include/uapi/linux/vduse.h +++ b/include/uapi/linux/vduse.h @@ -17,6 +17,9 @@ /* The VDUSE instance expects a request for vq ready */ #define VDUSE_F_QUEUE_READY 0 =20 +/* The VDUSE instance expects a request for suspend */ +#define VDUSE_F_SUSPEND 1 + /* * Get the version of VDUSE API that kernel supported (VDUSE_API_VERSION). * This is used for future extension. @@ -334,6 +337,7 @@ enum vduse_req_type { VDUSE_UPDATE_IOTLB, VDUSE_SET_VQ_GROUP_ASID, VDUSE_SET_VQ_READY, + VDUSE_SUSPEND, }; =20 /** --=20 2.54.0