* [RFC PATCH v6 4/4] virtio-mmio: wire up noirq system sleep PM callbacks
From: Sungho Bae @ 2026-04-27 17:30 UTC (permalink / raw)
To: mst, jasowang
Cc: xuanzhuo, eperezma, virtualization, linux-kernel, Sungho Bae
In-Reply-To: <20260427173045.28652-1-baver.bae@gmail.com>
From: Sungho Bae <baver.bae@lge.com>
Add noirq system-sleep PM support to the virtio-mmio transport.
This change wires noirq freeze/restore callbacks into virtio-mmio and
hooks queue reset/reactivation into the transport config ops so virtqueues
can be reinitialized and reused across suspend/resume.
For legacy (v1) devices, keep GUEST_PAGE_SIZE programming aligned with the
noirq restore path while avoiding duplicate programming in normal restore.
This enables virtio-mmio based devices to participate safely in the noirq
PM phase, which is required for early-restore users.
Signed-off-by: Sungho Bae <baver.bae@lge.com>
---
drivers/virtio/virtio_mmio.c | 136 ++++++++++++++++++++++++-----------
1 file changed, 96 insertions(+), 40 deletions(-)
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 595c2274fbb5..71d13cb57c43 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -336,6 +336,77 @@ static void vm_del_vqs(struct virtio_device *vdev)
free_irq(platform_get_irq(vm_dev->pdev, 0), vm_dev);
}
+static int vm_active_vq(struct virtio_device *vdev, struct virtqueue *vq)
+{
+ struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+ int q_num = virtqueue_get_vring_size(vq);
+
+ writel(q_num, vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
+ if (vm_dev->version == 1) {
+ u64 q_pfn = virtqueue_get_desc_addr(vq) >> PAGE_SHIFT;
+
+ /*
+ * virtio-mmio v1 uses a 32bit QUEUE PFN. If we have something
+ * that doesn't fit in 32bit, fail the setup rather than
+ * pretending to be successful.
+ */
+ if (q_pfn >> 32) {
+ dev_err(&vdev->dev,
+ "platform bug: legacy virtio-mmio must not be used with RAM above 0x%llxGB\n",
+ 0x1ULL << (32 + PAGE_SHIFT - 30));
+ return -E2BIG;
+ }
+
+ writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN);
+ writel(q_pfn, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
+ } else {
+ u64 addr;
+
+ addr = virtqueue_get_desc_addr(vq);
+ writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_LOW);
+ writel((u32)(addr >> 32),
+ vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_HIGH);
+
+ addr = virtqueue_get_avail_addr(vq);
+ writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_LOW);
+ writel((u32)(addr >> 32),
+ vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_HIGH);
+
+ addr = virtqueue_get_used_addr(vq);
+ writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_USED_LOW);
+ writel((u32)(addr >> 32),
+ vm_dev->base + VIRTIO_MMIO_QUEUE_USED_HIGH);
+
+ writel(1, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
+ }
+
+ return 0;
+}
+
+static int vm_reset_vqs(struct virtio_device *vdev)
+{
+ struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
+ struct virtqueue *vq;
+ int err;
+
+ virtio_device_for_each_vq(vdev, vq) {
+ /* Re-initialize vring state */
+ err = virtqueue_reinit_vring(vq);
+ if (err < 0)
+ return err;
+
+ /* Select the queue we're interested in */
+ writel(vq->index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
+
+ /* Activate the queue */
+ err = vm_active_vq(vdev, vq);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
static void vm_synchronize_cbs(struct virtio_device *vdev)
{
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
@@ -388,45 +459,9 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
vq->num_max = num;
/* Activate the queue */
- writel(virtqueue_get_vring_size(vq), vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
- if (vm_dev->version == 1) {
- u64 q_pfn = virtqueue_get_desc_addr(vq) >> PAGE_SHIFT;
-
- /*
- * virtio-mmio v1 uses a 32bit QUEUE PFN. If we have something
- * that doesn't fit in 32bit, fail the setup rather than
- * pretending to be successful.
- */
- if (q_pfn >> 32) {
- dev_err(&vdev->dev,
- "platform bug: legacy virtio-mmio must not be used with RAM above 0x%llxGB\n",
- 0x1ULL << (32 + PAGE_SHIFT - 30));
- err = -E2BIG;
- goto error_bad_pfn;
- }
-
- writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN);
- writel(q_pfn, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
- } else {
- u64 addr;
-
- addr = virtqueue_get_desc_addr(vq);
- writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_LOW);
- writel((u32)(addr >> 32),
- vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_HIGH);
-
- addr = virtqueue_get_avail_addr(vq);
- writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_LOW);
- writel((u32)(addr >> 32),
- vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_HIGH);
-
- addr = virtqueue_get_used_addr(vq);
- writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_USED_LOW);
- writel((u32)(addr >> 32),
- vm_dev->base + VIRTIO_MMIO_QUEUE_USED_HIGH);
-
- writel(1, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
- }
+ err = vm_active_vq(vdev, vq);
+ if (err < 0)
+ goto error_bad_pfn;
return vq;
@@ -528,11 +563,13 @@ static const struct virtio_config_ops virtio_mmio_config_ops = {
.reset = vm_reset,
.find_vqs = vm_find_vqs,
.del_vqs = vm_del_vqs,
+ .reset_vqs = vm_reset_vqs,
.get_features = vm_get_features,
.finalize_features = vm_finalize_features,
.bus_name = vm_bus_name,
.get_shm_region = vm_get_shm_region,
.synchronize_cbs = vm_synchronize_cbs,
+ .noirq_safe = true,
};
#ifdef CONFIG_PM_SLEEP
@@ -547,14 +584,33 @@ static int virtio_mmio_restore(struct device *dev)
{
struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
- if (vm_dev->version == 1)
+ if (vm_dev->version == 1 && !vm_dev->vdev.noirq_restore_done)
writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
return virtio_device_restore(&vm_dev->vdev);
}
+static int virtio_mmio_freeze_noirq(struct device *dev)
+{
+ struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
+
+ return virtio_device_freeze_noirq(&vm_dev->vdev);
+}
+
+static int virtio_mmio_restore_noirq(struct device *dev)
+{
+ struct virtio_mmio_device *vm_dev = dev_get_drvdata(dev);
+
+ if (vm_dev->version == 1)
+ writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
+
+ return virtio_device_restore_noirq(&vm_dev->vdev);
+}
+
static const struct dev_pm_ops virtio_mmio_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(virtio_mmio_freeze, virtio_mmio_restore)
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(virtio_mmio_freeze_noirq,
+ virtio_mmio_restore_noirq)
};
#endif
--
2.43.0
^ permalink raw reply related
* [RFC PATCH v6 3/4] virtio: add noirq system sleep PM infrastructure
From: Sungho Bae @ 2026-04-27 17:30 UTC (permalink / raw)
To: mst, jasowang
Cc: xuanzhuo, eperezma, virtualization, linux-kernel, Sungho Bae
In-Reply-To: <20260427173045.28652-1-baver.bae@gmail.com>
From: Sungho Bae <baver.bae@lge.com>
Some virtio-mmio devices, such as virtio-clock or virtio-regulator,
must become operational before the regular PM restore callback runs
because other devices may depend on them.
Add the core infrastructure needed to support noirq system-sleep PM
callbacks for virtio transports:
- virtio_add_status_noirq(): status helper without might_sleep().
- virtio_features_ok_noirq(): feature negotiation without might_sleep().
- virtio_reset_device_noirq(): device reset that skips
virtio_synchronize_cbs() (IRQ handlers are already quiesced in the
noirq phase).
- virtio_device_reinit_noirq(): full noirq bring-up sequence using the
above helpers.
- virtio_config_core_enable_noirq(): config enable with irqsave
locking.
- virtio_device_ready_noirq(): marks DRIVER_OK without
virtio_synchronize_cbs().
Not all transports can safely call reset, get_status, set_status, or
finalize_features during the noirq phase: transports like virtio-ccw
issue channel commands and wait for a completion interrupt, which will
never be delivered because device interrupts are masked at the interrupt
controller during noirq suspend/resume. To address this, introduce a
boolean field noirq_safe in struct virtio_config_ops. Transports that
implement the above operations via simple MMIO reads/writes (e.g.
virtio-mmio) set this flag; all others leave it at the default false.
The noirq helpers assert noirq_safe via WARN_ON at runtime.
virtio_device_freeze_noirq() enforces the contract at freeze time,
returning -EOPNOTSUPP early if the driver provides restore_noirq but
the transport does not meet the requirements, to prevent a deadlock on
resume. virtio_device_restore_noirq() performs a second check as a
safety net in case freeze_noirq was not called.
Add freeze_noirq/restore_noirq callbacks to struct virtio_driver and
provide matching helper wrappers in the virtio core:
- virtio_device_freeze_noirq(): validates noirq_safe and reset_vqs
requirements, then forwards to drv->freeze_noirq().
- virtio_device_restore_noirq(): guards against unsafe transports,
runs the noirq bring-up sequence, resets existing vrings via the
new config_ops->reset_vqs() hook, then calls drv->restore_noirq().
Modify virtio_device_restore() so that when a driver provides
restore_noirq, the normal-phase restore skips the re-initialization
that was already done in the noirq phase.
Signed-off-by: Sungho Bae <baver.bae@lge.com>
---
drivers/virtio/virtio.c | 255 +++++++++++++++++++++++++++++++++-
include/linux/virtio.h | 24 ++++
include/linux/virtio_config.h | 39 ++++++
3 files changed, 314 insertions(+), 4 deletions(-)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 98f1875f8df1..9a2a9439f1f4 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -193,6 +193,17 @@ static void virtio_config_core_enable(struct virtio_device *dev)
spin_unlock_irq(&dev->config_lock);
}
+static void virtio_config_core_enable_noirq(struct virtio_device *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->config_lock, flags);
+ dev->config_core_enabled = true;
+ if (dev->config_change_pending)
+ __virtio_config_changed(dev);
+ spin_unlock_irqrestore(&dev->config_lock, flags);
+}
+
void virtio_add_status(struct virtio_device *dev, unsigned int status)
{
might_sleep();
@@ -200,6 +211,21 @@ void virtio_add_status(struct virtio_device *dev, unsigned int status)
}
EXPORT_SYMBOL_GPL(virtio_add_status);
+/*
+ * Same as virtio_add_status() but without the might_sleep() assertion,
+ * so it is safe to call from noirq context.
+ *
+ * Requires the transport to have set config_ops->noirq_safe, which declares
+ * that reset, get_status, and set_status do not wait for a completion
+ * interrupt and are therefore safe during the noirq PM phase.
+ */
+void virtio_add_status_noirq(struct virtio_device *dev, unsigned int status)
+{
+ WARN_ON(!dev->config->noirq_safe);
+ dev->config->set_status(dev, dev->config->get_status(dev) | status);
+}
+EXPORT_SYMBOL_GPL(virtio_add_status_noirq);
+
/* Do some validation, then set FEATURES_OK */
static int virtio_features_ok(struct virtio_device *dev)
{
@@ -234,6 +260,38 @@ static int virtio_features_ok(struct virtio_device *dev)
return 0;
}
+/* noirq-safe variant: no might_sleep(), uses virtio_add_status_noirq() */
+static int virtio_features_ok_noirq(struct virtio_device *dev)
+{
+ unsigned int status;
+
+ if (virtio_check_mem_acc_cb(dev)) {
+ if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1)) {
+ dev_warn(&dev->dev,
+ "device must provide VIRTIO_F_VERSION_1\n");
+ return -ENODEV;
+ }
+
+ if (!virtio_has_feature(dev, VIRTIO_F_ACCESS_PLATFORM)) {
+ dev_warn(&dev->dev,
+ "device must provide VIRTIO_F_ACCESS_PLATFORM\n");
+ return -ENODEV;
+ }
+ }
+
+ if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1))
+ return 0;
+
+ virtio_add_status_noirq(dev, VIRTIO_CONFIG_S_FEATURES_OK);
+ status = dev->config->get_status(dev);
+ if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
+ dev_err(&dev->dev, "virtio: device refuses features: %x\n",
+ status);
+ return -ENODEV;
+ }
+ return 0;
+}
+
/**
* virtio_reset_device - quiesce device for removal
* @dev: the device to reset
@@ -267,6 +325,28 @@ void virtio_reset_device(struct virtio_device *dev)
}
EXPORT_SYMBOL_GPL(virtio_reset_device);
+/**
+ * virtio_reset_device_noirq - noirq-safe variant of virtio_reset_device()
+ * @dev: the device to reset
+ *
+ * Requires the transport to have set config_ops->noirq_safe.
+ */
+void virtio_reset_device_noirq(struct virtio_device *dev)
+{
+ WARN_ON(!dev->config->noirq_safe);
+
+#ifdef CONFIG_VIRTIO_HARDEN_NOTIFICATION
+ /*
+ * The noirq stage runs with device IRQ handlers disabled, so
+ * virtio_synchronize_cbs() must not be called here.
+ */
+ virtio_break_device(dev);
+#endif
+
+ dev->config->reset(dev);
+}
+EXPORT_SYMBOL_GPL(virtio_reset_device_noirq);
+
static int virtio_dev_probe(struct device *_d)
{
int err, i;
@@ -539,6 +619,7 @@ int register_virtio_device(struct virtio_device *dev)
dev->config_driver_disabled = false;
dev->config_core_enabled = false;
dev->config_change_pending = false;
+ dev->noirq_restore_done = false;
INIT_LIST_HEAD(&dev->vqs);
spin_lock_init(&dev->vqs_list_lock);
@@ -618,6 +699,47 @@ static int virtio_device_reinit(struct virtio_device *dev)
return virtio_features_ok(dev);
}
+/*
+ * noirq-safe variant of virtio_device_reinit().
+ *
+ * Requires the transport to declare config_ops->noirq_safe, which means
+ * reset, get_status, set_status, and finalize_features are safe to call
+ * during the noirq PM phase.
+ */
+static int virtio_device_reinit_noirq(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+ int ret;
+
+ /*
+ * We always start by resetting the device, in case a previous
+ * driver messed it up.
+ */
+ virtio_reset_device_noirq(dev);
+
+ /* Acknowledge that we've seen the device. */
+ virtio_add_status_noirq(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
+
+ /*
+ * Maybe driver failed before freeze.
+ * Restore the failed status, for debugging.
+ */
+ if (dev->failed)
+ virtio_add_status_noirq(dev, VIRTIO_CONFIG_S_FAILED);
+
+ if (!drv)
+ return 0;
+
+ /* We have a driver! */
+ virtio_add_status_noirq(dev, VIRTIO_CONFIG_S_DRIVER);
+
+ ret = dev->config->finalize_features(dev);
+ if (ret)
+ return ret;
+
+ return virtio_features_ok_noirq(dev);
+}
+
#ifdef CONFIG_PM_SLEEP
int virtio_device_freeze(struct virtio_device *dev)
{
@@ -627,6 +749,20 @@ int virtio_device_freeze(struct virtio_device *dev)
virtio_config_core_disable(dev);
dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED;
+ dev->noirq_restore_done = false;
+
+ /*
+ * If the driver provides restore_noirq, verify that the transport
+ * supports noirq PM. It will fail early so the PM core can abort
+ * the transition gracefully, rather than silently skipping noirq
+ * restore and then failing in the normal restore path.
+ */
+ if (drv && drv->restore_noirq && !dev->config->noirq_safe) {
+ dev_warn(&dev->dev,
+ "transport does not support noirq PM\n");
+ virtio_config_core_enable(dev);
+ return -EOPNOTSUPP;
+ }
if (drv && drv->freeze) {
ret = drv->freeze(dev);
@@ -645,12 +781,31 @@ int virtio_device_restore(struct virtio_device *dev)
struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
int ret;
- ret = virtio_device_reinit(dev);
- if (ret)
+ /*
+ * If the driver implements restore_noirq but it did not complete
+ * successfully, the noirq phase must have failed. PM core may
+ * continue later resume phases for global recovery, but virtio
+ * does not use the normal restore path as an implicit same-device
+ * fallback.
+ */
+ if (drv && drv->restore_noirq && !dev->noirq_restore_done) {
+ ret = -EIO;
goto err;
+ }
- if (!drv)
- return 0;
+ /*
+ * Re-initialization is only needed when noirq restore was not
+ * attempted. If noirq restore succeeded, the transport was already
+ * reset, features renegotiated, and virtqueues restored, so only
+ * the driver-level restore() callback (if any) still needs to run.
+ */
+ if (!drv || !dev->noirq_restore_done) {
+ ret = virtio_device_reinit(dev);
+ if (ret)
+ goto err;
+ if (!drv)
+ return 0;
+ }
if (drv->restore) {
ret = drv->restore(dev);
@@ -671,6 +826,98 @@ int virtio_device_restore(struct virtio_device *dev)
return ret;
}
EXPORT_SYMBOL_GPL(virtio_device_restore);
+
+int virtio_device_freeze_noirq(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+
+ if (!drv)
+ return 0;
+
+ /*
+ * restore_noirq requires that the transport's config ops
+ * (reset, get_status, set_status) are safe to call during the noirq
+ * PM phase. Catch the mismatch early at freeze time so the PM core
+ * can abort cleanly rather than deadlocking on resume.
+ */
+ if (drv->restore_noirq && !dev->config->noirq_safe) {
+ dev_warn(&dev->dev,
+ "transport does not support noirq PM\n");
+ return -EOPNOTSUPP;
+ }
+
+ /*
+ * If the driver provides restore_noirq and has active vqs,
+ * the transport must support reset_vqs to restore them.
+ * Fail here so the PM core can abort the transition gracefully,
+ * rather than hitting -EOPNOTSUPP on resume.
+ */
+ if (drv->restore_noirq && !list_empty(&dev->vqs) &&
+ !dev->config->reset_vqs) {
+ dev_warn(&dev->dev,
+ "transport does not support noirq PM restore with active vqs (missing reset_vqs)\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (drv->freeze_noirq)
+ return drv->freeze_noirq(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(virtio_device_freeze_noirq);
+
+int virtio_device_restore_noirq(struct virtio_device *dev)
+{
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+ int ret;
+
+ if (!drv || !drv->restore_noirq)
+ return 0;
+
+ /*
+ * All transport ops called below (reset, get_status, set_status) must
+ * be noirq-safe. Return early if not - this should normally have
+ * been caught at freeze_noirq time.
+ */
+ if (!dev->config->noirq_safe) {
+ dev_warn(&dev->dev,
+ "transport does not support noirq PM; skipping restore\n");
+ return -EOPNOTSUPP;
+ }
+
+ ret = virtio_device_reinit_noirq(dev);
+ if (ret)
+ goto err;
+
+ if (!list_empty(&dev->vqs)) {
+ if (!dev->config->reset_vqs) {
+ ret = -EOPNOTSUPP;
+ goto err;
+ }
+
+ ret = dev->config->reset_vqs(dev);
+ if (ret)
+ goto err;
+ }
+
+ ret = drv->restore_noirq(dev);
+ if (ret)
+ goto err;
+
+ /* Mark that noirq restore has completed successfully. */
+ dev->noirq_restore_done = true;
+
+ /* If restore_noirq set DRIVER_OK, enable config now. */
+ if (dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK)
+ virtio_config_core_enable_noirq(dev);
+
+ return 0;
+
+err:
+ virtio_add_status_noirq(dev, VIRTIO_CONFIG_S_FAILED);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(virtio_device_restore_noirq);
#endif
int virtio_device_reset_prepare(struct virtio_device *dev)
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index 3bbc4cb6a672..9a33a1d26c51 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -151,6 +151,7 @@ struct virtio_admin_cmd {
* @config_driver_disabled: configuration change reporting disabled by
* a driver
* @config_change_pending: configuration change reported while disabled
+ * @noirq_restore_done: set when noirq restore completed successfully
* @config_lock: protects configuration change reporting
* @vqs_list_lock: protects @vqs.
* @dev: underlying device.
@@ -171,6 +172,7 @@ struct virtio_device {
bool config_core_enabled;
bool config_driver_disabled;
bool config_change_pending;
+ bool noirq_restore_done;
spinlock_t config_lock;
spinlock_t vqs_list_lock;
struct device dev;
@@ -209,8 +211,12 @@ void virtio_config_driver_enable(struct virtio_device *dev);
#ifdef CONFIG_PM_SLEEP
int virtio_device_freeze(struct virtio_device *dev);
int virtio_device_restore(struct virtio_device *dev);
+int virtio_device_freeze_noirq(struct virtio_device *dev);
+int virtio_device_restore_noirq(struct virtio_device *dev);
#endif
void virtio_reset_device(struct virtio_device *dev);
+void virtio_reset_device_noirq(struct virtio_device *dev);
+void virtio_add_status_noirq(struct virtio_device *dev, unsigned int status);
int virtio_device_reset_prepare(struct virtio_device *dev);
int virtio_device_reset_done(struct virtio_device *dev);
@@ -237,6 +243,22 @@ size_t virtio_max_dma_size(const struct virtio_device *vdev);
* changes; may be called in interrupt context.
* @freeze: optional function to call during suspend/hibernation.
* @restore: optional function to call on resume.
+ * When @restore_noirq is not implemented, core resets and reinitializes
+ * the device before calling this. When @restore_noirq succeeded, core
+ * skips reinitialization; drivers should avoid calling virtio_device_ready()
+ * if DRIVER_OK was already set in the noirq phase.
+ * When @restore_noirq failed, this callback is not invoked for same-device
+ * recovery; the saved noirq error is propagated instead.
+ * @freeze_noirq: optional function to call during noirq suspend/hibernation.
+ * @restore_noirq: optional function to call on noirq resume.
+ * If this callback fails, PM core may still continue later resume phases
+ * for global system recovery. Virtio does not treat @restore as an
+ * implicit same-device fallback for @restore_noirq failure; drivers should
+ * only implement @restore_noirq when noirq resume is their required
+ * recovery point.
+ * A noirq restore failure is detected by the normal restore path
+ * (restore_noirq implemented but noirq_restore_done is false) and
+ * returns -EIO instead of attempting same-device recovery.
* @reset_prepare: optional function to call when a transport specific reset
* occurs.
* @reset_done: optional function to call after transport specific reset
@@ -258,6 +280,8 @@ struct virtio_driver {
void (*config_changed)(struct virtio_device *dev);
int (*freeze)(struct virtio_device *dev);
int (*restore)(struct virtio_device *dev);
+ int (*freeze_noirq)(struct virtio_device *dev);
+ int (*restore_noirq)(struct virtio_device *dev);
int (*reset_prepare)(struct virtio_device *dev);
int (*reset_done)(struct virtio_device *dev);
void (*shutdown)(struct virtio_device *dev);
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 69f84ea85d71..0110b091f634 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -70,6 +70,9 @@ struct virtqueue_info {
* vqs_info: array of virtqueue info structures
* Returns 0 on success or error status
* @del_vqs: free virtqueues found by find_vqs().
+ * @reset_vqs: reinitialize existing virtqueues without allocating or
+ * freeing them (optional). Used during noirq restore.
+ * Returns 0 on success or error status.
* @synchronize_cbs: synchronize with the virtqueue callbacks (optional)
* The function guarantees that all memory operations on the
* queue before it are visible to the vring_interrupt() that is
@@ -108,6 +111,14 @@ struct virtqueue_info {
* Returns 0 on success or error status
* If disable_vq_and_reset is set, then enable_vq_after_reset must also be
* set.
+ * @noirq_safe: set to true if @reset, @get_status, @set_status, and
+ * @finalize_features are safe to call during the noirq phase of system
+ * suspend/resume. Transports that implement these operations via simple
+ * MMIO reads/writes (e.g. virtio-mmio) can set this flag. Transports
+ * that issue channel commands and wait for a completion interrupt (e.g.
+ * virtio-ccw) must NOT set it, because device interrupts are masked at
+ * the interrupt controller during the noirq phase, which would cause the
+ * wait to hang.
*/
struct virtio_config_ops {
void (*get)(struct virtio_device *vdev, unsigned offset,
@@ -123,6 +134,7 @@ struct virtio_config_ops {
struct virtqueue_info vqs_info[],
struct irq_affinity *desc);
void (*del_vqs)(struct virtio_device *);
+ int (*reset_vqs)(struct virtio_device *vdev);
void (*synchronize_cbs)(struct virtio_device *);
u64 (*get_features)(struct virtio_device *vdev);
void (*get_extended_features)(struct virtio_device *vdev,
@@ -137,6 +149,7 @@ struct virtio_config_ops {
struct virtio_shm_region *region, u8 id);
int (*disable_vq_and_reset)(struct virtqueue *vq);
int (*enable_vq_after_reset)(struct virtqueue *vq);
+ bool noirq_safe;
};
/**
@@ -371,6 +384,32 @@ void virtio_device_ready(struct virtio_device *dev)
dev->config->set_status(dev, status | VIRTIO_CONFIG_S_DRIVER_OK);
}
+/**
+ * virtio_device_ready_noirq - noirq-safe variant of virtio_device_ready()
+ * @dev: the virtio device
+ *
+ * Requires the transport to have set config_ops->noirq_safe, which declares
+ * that get_status and set_status do not wait for a completion interrupt.
+ */
+static inline
+void virtio_device_ready_noirq(struct virtio_device *dev)
+{
+ unsigned int status = dev->config->get_status(dev);
+
+ WARN_ON(!dev->config->noirq_safe);
+ WARN_ON(status & VIRTIO_CONFIG_S_DRIVER_OK);
+
+#ifdef CONFIG_VIRTIO_HARDEN_NOTIFICATION
+ /*
+ * The noirq stage runs with device IRQ handlers disabled, so
+ * virtio_synchronize_cbs() must not be called here.
+ */
+ __virtio_unbreak_device(dev);
+#endif
+
+ dev->config->set_status(dev, status | VIRTIO_CONFIG_S_DRIVER_OK);
+}
+
static inline
const char *virtio_bus_name(struct virtio_device *vdev)
{
--
2.43.0
^ permalink raw reply related
* [RFC PATCH v6 2/4] virtio_ring: export virtqueue_reinit_vring() for noirq restore
From: Sungho Bae @ 2026-04-27 17:30 UTC (permalink / raw)
To: mst, jasowang
Cc: xuanzhuo, eperezma, virtualization, linux-kernel, Sungho Bae
In-Reply-To: <20260427173045.28652-1-baver.bae@gmail.com>
From: Sungho Bae <baver.bae@lge.com>
After a device reset in noirq context the existing vrings must be
re-initialized without any memory allocation, because GFP_KERNEL is
not available.
The internal helpers virtqueue_reset_split() and
virtqueue_reset_packed() already reset vring indices and descriptor
state in place. Add a thin exported wrapper, virtqueue_reinit_vring(),
that dispatches to the appropriate helper based on the ring layout.
This will be used by a subsequent patch that adds noirq system-sleep
PM callbacks for virtio-mmio.
Signed-off-by: Sungho Bae <baver.bae@lge.com>
---
drivers/virtio/virtio_ring.c | 58 ++++++++++++++++++++++++++++++++++++
include/linux/virtio_ring.h | 3 ++
2 files changed, 61 insertions(+)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index fbca7ce1c6bf..d3339b820f6b 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -506,6 +506,15 @@ static void virtqueue_init(struct vring_virtqueue *vq, u32 num)
vq->event_triggered = false;
vq->num_added = 0;
+ /*
+ * Keep IN_ORDER state aligned with a freshly initialized/reset queue.
+ * For packed IN_ORDER, free_head is unused but harmlessly reset.
+ */
+ if (virtqueue_is_in_order(vq)) {
+ vq->free_head = 0;
+ vq->batch_last.id = UINT_MAX;
+ }
+
#ifdef DEBUG
vq->in_use = false;
vq->last_add_time_valid = false;
@@ -3936,5 +3945,54 @@ void virtqueue_map_sync_single_range_for_device(const struct virtqueue *_vq,
}
EXPORT_SYMBOL_GPL(virtqueue_map_sync_single_range_for_device);
+/**
+ * virtqueue_reinit_vring - reinitialize vring state without reallocation
+ * @_vq: the virtqueue
+ *
+ * Reset the avail/used indices and descriptor state of an existing
+ * virtqueue so it can be reused after a device reset. No memory is
+ * allocated or freed, making this safe for use in noirq context.
+ *
+ * Preconditions for callers:
+ * 1) The vq must be fully quiesced (no concurrent add/get/kick/IRQ callback).
+ * 2) Transport/device side must already have stopped/reset this queue.
+ * 3) All in-flight buffers must already be completed or detached.
+ *
+ * If called with outstanding descriptors, free-list state can be corrupted:
+ * num_free is restored to full capacity while desc_extra next-chain/free_head
+ * may still represent a partially consumed list.
+ *
+ * Return:
+ * 0 on success, or -EBUSY if preconditions are not met.
+ */
+int virtqueue_reinit_vring(struct virtqueue *_vq)
+{
+ struct vring_virtqueue *vq = to_vvq(_vq);
+ unsigned int num = virtqueue_is_packed(vq) ?
+ vq->packed.vring.num : vq->split.vring.num;
+
+ /* All in-flight descriptors must be completed or detached */
+ if (WARN_ON(vq->vq.num_free != num))
+ return -EBUSY;
+
+ if (virtqueue_is_packed(vq)) {
+ virtqueue_reset_packed(vq);
+ } else {
+ /*
+ * Split queue shadow index should match the visible avail
+ * index when the queue is fully quiesced.
+ */
+ if (WARN_ON(vq->split.avail_idx_shadow !=
+ virtio16_to_cpu(vq->vq.vdev,
+ vq->split.vring.avail->idx)))
+ return -EBUSY;
+
+ virtqueue_reset_split(vq);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(virtqueue_reinit_vring);
+
MODULE_DESCRIPTION("Virtio ring implementation");
MODULE_LICENSE("GPL");
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
index c97a12c1cda3..8b421fef4fef 100644
--- a/include/linux/virtio_ring.h
+++ b/include/linux/virtio_ring.h
@@ -118,6 +118,9 @@ void vring_del_virtqueue(struct virtqueue *vq);
/* Filter out transport-specific feature bits. */
void vring_transport_features(struct virtio_device *vdev);
+/* Reinitialize a virtqueue without reallocation (safe in noirq context) */
+int virtqueue_reinit_vring(struct virtqueue *_vq);
+
irqreturn_t vring_interrupt(int irq, void *_vq);
u32 vring_notification_data(struct virtqueue *_vq);
--
2.43.0
^ permalink raw reply related
* [RFC PATCH v6 1/4] virtio: separate PM restore and reset_done paths
From: Sungho Bae @ 2026-04-27 17:30 UTC (permalink / raw)
To: mst, jasowang
Cc: xuanzhuo, eperezma, virtualization, linux-kernel, Sungho Bae
In-Reply-To: <20260427173045.28652-1-baver.bae@gmail.com>
From: Sungho Bae <baver.bae@lge.com>
Refactor virtio_device_restore_priv() by extracting the common device
re-initialization sequence into virtio_device_reinit(). This helper
performs the full bring-up sequence: reset, status acknowledgment,
feature finalization, and feature negotiation.
virtio_device_restore() and virtio_device_reset_done() now each call
virtio_device_reinit() directly instead of going through a boolean-
dispatched wrapper. This makes each path independently readable and
extensible without further complicating the dispatch logic.
A follow-up series will add noirq PM callbacks that only affect the
restore path; having the two paths separated avoids adding more
conditionals to a shared function.
No functional change.
Signed-off-by: Sungho Bae <baver.bae@lge.com>
---
drivers/virtio/virtio.c | 81 +++++++++++++++++++++++++----------------
1 file changed, 50 insertions(+), 31 deletions(-)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 5bdc6b82b30b..98f1875f8df1 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -588,7 +588,7 @@ void unregister_virtio_device(struct virtio_device *dev)
}
EXPORT_SYMBOL_GPL(unregister_virtio_device);
-static int virtio_device_restore_priv(struct virtio_device *dev, bool restore)
+static int virtio_device_reinit(struct virtio_device *dev)
{
struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
int ret;
@@ -613,35 +613,9 @@ static int virtio_device_restore_priv(struct virtio_device *dev, bool restore)
ret = dev->config->finalize_features(dev);
if (ret)
- goto err;
-
- ret = virtio_features_ok(dev);
- if (ret)
- goto err;
-
- if (restore) {
- if (drv->restore) {
- ret = drv->restore(dev);
- if (ret)
- goto err;
- }
- } else {
- ret = drv->reset_done(dev);
- if (ret)
- goto err;
- }
-
- /* If restore didn't do it, mark device DRIVER_OK ourselves. */
- if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
- virtio_device_ready(dev);
-
- virtio_config_core_enable(dev);
-
- return 0;
+ return ret;
-err:
- virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
- return ret;
+ return virtio_features_ok(dev);
}
#ifdef CONFIG_PM_SLEEP
@@ -668,7 +642,33 @@ EXPORT_SYMBOL_GPL(virtio_device_freeze);
int virtio_device_restore(struct virtio_device *dev)
{
- return virtio_device_restore_priv(dev, true);
+ struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+ int ret;
+
+ ret = virtio_device_reinit(dev);
+ if (ret)
+ goto err;
+
+ if (!drv)
+ return 0;
+
+ if (drv->restore) {
+ ret = drv->restore(dev);
+ if (ret)
+ goto err;
+ }
+
+ /* If restore didn't do it, mark device DRIVER_OK ourselves. */
+ if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
+ virtio_device_ready(dev);
+
+ virtio_config_core_enable(dev);
+
+ return 0;
+
+err:
+ virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
+ return ret;
}
EXPORT_SYMBOL_GPL(virtio_device_restore);
#endif
@@ -698,11 +698,30 @@ EXPORT_SYMBOL_GPL(virtio_device_reset_prepare);
int virtio_device_reset_done(struct virtio_device *dev)
{
struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
+ int ret;
if (!drv || !drv->reset_done)
return -EOPNOTSUPP;
- return virtio_device_restore_priv(dev, false);
+ ret = virtio_device_reinit(dev);
+ if (ret)
+ goto err;
+
+ ret = drv->reset_done(dev);
+ if (ret)
+ goto err;
+
+ /* If reset_done didn't do it, mark device DRIVER_OK ourselves. */
+ if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
+ virtio_device_ready(dev);
+
+ virtio_config_core_enable(dev);
+
+ return 0;
+
+err:
+ virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
+ return ret;
}
EXPORT_SYMBOL_GPL(virtio_device_reset_done);
--
2.43.0
^ permalink raw reply related
* [RFC PATCH v6 0/4] virtio: add noirq system sleep PM callbacks for virtio-mmio
From: Sungho Bae @ 2026-04-27 17:30 UTC (permalink / raw)
To: mst, jasowang
Cc: xuanzhuo, eperezma, virtualization, linux-kernel, Sungho Bae
From: Sungho Bae <baver.bae@lge.com>
Hi all,
Some virtio-mmio based devices, such as virtio-clock or virtio-regulator,
must become operational before other devices have their regular PM restore
callbacks invoked, because those other devices depend on them.
Generally, PM framework provides the three phases (freeze, freeze_late,
freeze_noirq) for the system sleep sequence, and the corresponding resume
phases. But, virtio core only supports the normal freeze/restore phase,
so virtio drivers have no way to participate in the noirq phase, which runs
with IRQs disabled and is guaranteed to run before any normal-phase restore
callbacks.
This series adds the infrastructure and the virtio-mmio transport
wiring so that virtio drivers can implement freeze_noirq/restore_noirq
callbacks.
Design overview
===============
The noirq phase runs with device IRQ handlers disabled and must avoid
sleepable operations. The main constraints addressed are:
- might_sleep() in virtio_add_status() and virtio_features_ok().
- virtio_synchronize_cbs() in virtio_reset_device() (IRQs are already
quiesced).
- spin_lock_irq() in virtio_config_core_enable() (not safe to call
with interrupts already disabled).
- Memory allocation during vq setup (virtqueue_reinit_vring() reuses
existing buffers instead).
The series provides noirq-safe variants for each of these, plus a new
config_ops->reset_vqs() callback that lets the transport reprogram
queue registers without freeing/reallocating vring memory.
Not all transports can safely perform these operations in the noirq phase.
Transports like virtio-ccw issue channel commands and wait for a completion
interrupt, which will never arrive while device interrupts are masked at
the interrupt controller. A new boolean field config_ops->noirq_safe marks
transports that implement reset/status operations via simple MMIO
reads/writes and are therefore safe to use in noirq context. The noirq
helpers assert this flag at runtime, and virtio_device_freeze_noirq()
enforces it at freeze time, returning -EOPNOTSUPP early to prevent
a deadlock on resume.
When a driver implements restore_noirq, the device bring-up (reset ->
ACKNOWLEDGE -> DRIVER -> finalize_features -> FEATURES_OK) happens in
the noirq phase. The subsequent normal-phase virtio_device_restore()
detects this and skips the redundant re-initialization.
Patch breakdown
===============
Patch 1 is a preparatory refactoring with no functional change.
Patches 2-3 add the core infrastructure. Patch 4 wires it up for
virtio-mmio.
1. virtio: separate PM restore and reset_done paths
Splits virtio_device_restore_priv() into independent
virtio_device_restore() and virtio_device_reset_done() paths,
using a shared virtio_device_reinit() helper. This is a pure
refactoring to make the restore path independently extensible
without complicating the boolean dispatch.
2. virtio_ring: export virtqueue_reinit_vring() for noirq restore
Adds virtqueue_reinit_vring(), an exported wrapper that resets
vring indices and descriptor state in place without any memory
allocation, making it safe to call from noirq context. Also
resets IN_ORDER-specific state (free_head, batch_last.id) in
virtqueue_init() to keep the ring consistent after reinit, and
adds runtime WARN_ON checks for unexpected in-flight descriptor
state and split-ring index consistency.
3. virtio: add noirq system sleep PM infrastructure
Adds noirq-safe helpers (virtio_add_status_noirq,
virtio_features_ok_noirq, virtio_reset_device_noirq,
virtio_config_core_enable_noirq, virtio_device_ready_noirq) and
the freeze_noirq/restore_noirq driver callbacks plus the
config_ops->reset_vqs() transport hook. Introduces
config_ops->noirq_safe to mark transports whose reset/status
operations are safe in noirq context (e.g. simple MMIO), and
enforces early -EOPNOTSUPP in virtio_device_freeze_noirq() when
the transport does not meet noirq requirements. Modifies
virtio_device_restore() to skip bring-up when restore_noirq
already ran.
4. virtio-mmio: wire up noirq system sleep PM callbacks
Implements vm_reset_vqs() which iterates existing virtqueues,
reinitializes the vring state via virtqueue_reinit_vring(), and
reprograms the MMIO queue registers. Adds
virtio_mmio_freeze_noirq/virtio_mmio_restore_noirq and registers
them via SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(). Sets .noirq_safe = true
in virtio_mmio_config_ops to declare that MMIO-based status and
reset operations are safe during the noirq PM phase.
Testing
=======
Build-tested with arm64 cross-compilation.
(make ARCH=arm64 M=drivers/virtio)
Runtime-tested on an internal virtio-mmio platform with virtio-clock,
confirming that the clock device works well before other devices' normal
restore() callbacks run.
Changes
=======
v6:
virtio_ring: export virtqueue_reinit_vring() for noirq restore
- Made virtqueue_reinit_vring() fail with -EBUSY on precondition
violations and propagate that error.
virtio: add noirq system sleep PM infrastructure
- Make noirq restore failure terminal for the same device:
.restore is not a same-device fallback for .restore_noirq failure.
- Decouple noirq failure from pre-freeze dev->failed snapshot.
- Add noirq_safe validation in virtio_device_freeze() to catch transport
mismatch early.
virtio-mmio: wire up noirq system sleep PM callbacks
- Make vm_reset_vqs() handle virtqueue_reinit_vring() failures
to prevent continuing noirq restore with a potentially corrupted
split free-list state.
v5:
virtio: add noirq system sleep PM infrastructure
- Preserve FAILED across restore_noirq() failure by recording the
failure in dev->failed before falling back to the normal restore path.
- Document the restore/restore_noirq fallback contract more clearly,
especially for drivers that preserve virtqueues across suspend.
v4:
virtio_ring: export virtqueue_reinit_vring() for noirq restore
- Reinit safety was tightened by resetting IN_ORDER-specific state.
- Added extra split-ring consistency WARN_ON checks.
- Clarified caller preconditions for noirq-safe vring reinit.
virtio: add noirq system sleep PM infrastructure
- Added config_ops->noirq_safe to explicitly mark transports that are
safe in noirq PM phase.
- Enforced early -EOPNOTSUPP checks in freeze_noirq for unsupported
transport combinations (noirq_safe/reset_vqs requirements).
- Added defensive runtime guards/warnings in noirq helper and restore
paths.
- Discussed the freeze-before-freeze_noirq abort scenario raised in
review and concluded that the fallback restore path is intentionally
handled by regular restore after core reinit/reset, so reset_vqs is
kept limited to the noirq restore flow.
virtio-mmio: wire up noirq system sleep PM callbacks
- Marked virtio-mmio transport as noirq-capable by setting .noirq_safe
in virtio_mmio_config_ops.
v3:
virtio: separate PM restore and reset_done paths
- Refined restore flow to explicitly handle the no-driver case after
reinit, improving clarity and avoiding unnecessary driver-path
assumptions.
virtio_ring: export virtqueue_reinit_vring() for noirq restore
- Hardened virtqueue_reinit_vring() with stronger safety notes and
a runtime WARN_ON check to catch reinit with unexpected free-list
state.
virtio: add noirq system sleep PM infrastructure
- Added explicit noirq restore completion tracking noirq_restore_done
and updated PM sequencing to use it, plus early freeze_noirq
validation for missing reset_vqs support.
virtio-mmio: wire up noirq system sleep PM callbacks
- Updated virtio-mmio restore path to skip legacy GUEST_PAGE_SIZE
rewrite when noirq restore already completed.
v2:
virtio-mmio: wire up noirq system sleep PM callbacks
- The code that was duplicated in vm_setup_vq() and vm_reset_vqs() has
been moved to vm_active_vq() function.
Sungho Bae (4):
virtio: separate PM restore and reset_done paths
virtio_ring: export virtqueue_reinit_vring() for noirq restore
virtio: add noirq system sleep PM infrastructure
virtio-mmio: wire up noirq system sleep PM callbacks
drivers/virtio/virtio.c | 318 +++++++++++++++++++++++++++++++---
drivers/virtio/virtio_mmio.c | 136 ++++++++++-----
drivers/virtio/virtio_ring.c | 58 +++++++
include/linux/virtio.h | 24 +++
include/linux/virtio_config.h | 39 +++++
include/linux/virtio_ring.h | 3 +
6 files changed, 512 insertions(+), 66 deletions(-)
--
2.43.0
^ permalink raw reply
* Re: [syzbot] [virt?] [net?] memory leak in __vsock_create (2)
From: syzbot @ 2026-04-27 17:03 UTC (permalink / raw)
To: davem, edumazet, horms, kuba, linux-kernel, netdev, pabeni,
sgarzare, syzkaller-bugs, virtualization
In-Reply-To: <ae-MTiL0vf-y7Ygz@sgarzare-redhat>
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
memory leak in prepare_creds
2026/04/27 17:01:37 executed programs: 5
BUG: memory leak
unreferenced object 0xffff888103b7b900 (size 184):
comm "syz-executor", pid 6458, jiffies 4294946243
hex dump (first 32 bytes):
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc 5efbd4bc):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4574 [inline]
slab_alloc_node mm/slub.c:4898 [inline]
kmem_cache_alloc_noprof+0x36c/0x480 mm/slub.c:4905
prepare_creds+0x22/0x600 kernel/cred.c:185
copy_creds+0x44/0x290 kernel/cred.c:286
copy_process+0x920/0x2cf0 kernel/fork.c:2123
kernel_clone+0xde/0x700 kernel/fork.c:2723
__do_sys_clone+0x7f/0xb0 kernel/fork.c:2864
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xee/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
BUG: memory leak
unreferenced object 0xffff88810ad103a0 (size 32):
comm "syz-executor", pid 6458, jiffies 4294946243
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
f8 56 0a 00 81 88 ff ff 00 00 00 00 00 00 00 00 .V..............
backtrace (crc 109407f3):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4574 [inline]
slab_alloc_node mm/slub.c:4898 [inline]
__do_kmalloc_node mm/slub.c:5294 [inline]
__kmalloc_noprof+0x3b7/0x550 mm/slub.c:5307
kmalloc_noprof include/linux/slab.h:954 [inline]
kzalloc_noprof include/linux/slab.h:1188 [inline]
lsm_blob_alloc+0x4d/0x80 security/security.c:218
lsm_cred_alloc security/security.c:235 [inline]
security_prepare_creds+0x2d/0x290 security/security.c:2866
prepare_creds+0x395/0x600 kernel/cred.c:215
copy_creds+0x44/0x290 kernel/cred.c:286
copy_process+0x920/0x2cf0 kernel/fork.c:2123
kernel_clone+0xde/0x700 kernel/fork.c:2723
__do_sys_clone+0x7f/0xb0 kernel/fork.c:2864
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xee/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
BUG: memory leak
unreferenced object 0xffff888111516800 (size 1272):
comm "kworker/1:3", pid 5684, jiffies 4294946243
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
28 00 0b 40 00 00 00 00 00 00 00 00 00 00 00 00 (..@............
backtrace (crc 5e448183):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4574 [inline]
slab_alloc_node mm/slub.c:4898 [inline]
kmem_cache_alloc_noprof+0x36c/0x480 mm/slub.c:4905
sk_prot_alloc+0x3e/0x1b0 net/core/sock.c:2241
sk_alloc+0x36/0x460 net/core/sock.c:2303
__vsock_create.constprop.0+0x38/0x2f0 net/vmw_vsock/af_vsock.c:907
virtio_transport_recv_listen net/vmw_vsock/virtio_transport_common.c:1566 [inline]
virtio_transport_recv_pkt+0x88d/0xfb0 net/vmw_vsock/virtio_transport_common.c:1693
vsock_loopback_work+0x104/0x140 net/vmw_vsock/vsock_loopback.c:142
process_one_work+0x277/0x5b0 kernel/workqueue.c:3302
process_scheduled_works kernel/workqueue.c:3385 [inline]
worker_thread+0x255/0x4a0 kernel/workqueue.c:3466
kthread+0x14e/0x1a0 kernel/kthread.c:436
ret_from_fork+0x219/0x490 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
BUG: memory leak
unreferenced object 0xffff88812daab5e0 (size 32):
comm "kworker/1:3", pid 5684, jiffies 4294946243
hex dump (first 32 bytes):
f8 56 0a 00 81 88 ff ff 00 00 00 00 00 00 00 00 .V..............
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc 79381f4a):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4574 [inline]
slab_alloc_node mm/slub.c:4898 [inline]
__do_kmalloc_node mm/slub.c:5294 [inline]
__kmalloc_noprof+0x3b7/0x550 mm/slub.c:5307
kmalloc_noprof include/linux/slab.h:954 [inline]
kzalloc_noprof include/linux/slab.h:1188 [inline]
lsm_blob_alloc+0x4d/0x80 security/security.c:218
lsm_sock_alloc security/security.c:4478 [inline]
security_sk_alloc+0x2d/0x290 security/security.c:4494
sk_prot_alloc+0x8f/0x1b0 net/core/sock.c:2250
sk_alloc+0x36/0x460 net/core/sock.c:2303
__vsock_create.constprop.0+0x38/0x2f0 net/vmw_vsock/af_vsock.c:907
virtio_transport_recv_listen net/vmw_vsock/virtio_transport_common.c:1566 [inline]
virtio_transport_recv_pkt+0x88d/0xfb0 net/vmw_vsock/virtio_transport_common.c:1693
vsock_loopback_work+0x104/0x140 net/vmw_vsock/vsock_loopback.c:142
process_one_work+0x277/0x5b0 kernel/workqueue.c:3302
process_scheduled_works kernel/workqueue.c:3385 [inline]
worker_thread+0x255/0x4a0 kernel/workqueue.c:3466
kthread+0x14e/0x1a0 kernel/kthread.c:436
ret_from_fork+0x219/0x490 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
BUG: memory leak
unreferenced object 0xffff88810b1a75a0 (size 96):
comm "kworker/1:3", pid 5684, jiffies 4294946243
hex dump (first 32 bytes):
00 68 51 11 81 88 ff ff 00 00 00 00 00 00 00 00 .hQ.............
00 00 00 00 00 00 00 00 00 00 04 00 00 00 00 00 ................
backtrace (crc 428f2031):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4574 [inline]
slab_alloc_node mm/slub.c:4898 [inline]
__kmalloc_cache_noprof+0x371/0x480 mm/slub.c:5410
kmalloc_noprof include/linux/slab.h:950 [inline]
kzalloc_noprof include/linux/slab.h:1188 [inline]
virtio_transport_do_socket_init+0x2b/0xf0 net/vmw_vsock/virtio_transport_common.c:925
vsock_assign_transport+0x3a3/0x460 net/vmw_vsock/af_vsock.c:656
virtio_transport_recv_listen net/vmw_vsock/virtio_transport_common.c:1582 [inline]
virtio_transport_recv_pkt+0x8e5/0xfb0 net/vmw_vsock/virtio_transport_common.c:1693
vsock_loopback_work+0x104/0x140 net/vmw_vsock/vsock_loopback.c:142
process_one_work+0x277/0x5b0 kernel/workqueue.c:3302
process_scheduled_works kernel/workqueue.c:3385 [inline]
worker_thread+0x255/0x4a0 kernel/workqueue.c:3466
kthread+0x14e/0x1a0 kernel/kthread.c:436
ret_from_fork+0x219/0x490 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
BUG: memory leak
unreferenced object 0xffff888111516300 (size 1272):
comm "kworker/1:3", pid 5684, jiffies 4294946244
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
28 00 0b 40 00 00 00 00 00 00 00 00 00 00 00 00 (..@............
backtrace (crc e1cd45d1):
kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
slab_post_alloc_hook mm/slub.c:4574 [inline]
slab_alloc_node mm/slub.c:4898 [inline]
kmem_cache_alloc_noprof+0x36c/0x480 mm/slub.c:4905
sk_prot_alloc+0x3e/0x1b0 net/core/sock.c:2241
sk_alloc+0x36/0x460 net/core/sock.c:2303
__vsock_create.constprop.0+0x38/0x2f0 net/vmw_vsock/af_vsock.c:907
virtio_transport_recv_listen net/vmw_vsock/virtio_transport_common.c:1566 [inline]
virtio_transport_recv_pkt+0x88d/0xfb0 net/vmw_vsock/virtio_transport_common.c:1693
vsock_loopback_work+0x104/0x140 net/vmw_vsock/vsock_loopback.c:142
process_one_work+0x277/0x5b0 kernel/workqueue.c:3302
process_scheduled_works kernel/workqueue.c:3385 [inline]
worker_thread+0x255/0x4a0 kernel/workqueue.c:3466
kthread+0x14e/0x1a0 kernel/kthread.c:436
ret_from_fork+0x219/0x490 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
connection error: failed to recv *flatrpc.ExecutorMessageRawT: EOF
Tested on:
commit: 39ff9a4a vsock/virtio: fix socket leak on close_timeou..
git tree: https://github.com/stefano-garzarella/linux.git fix-syzbot-memleak-vsock-create
console output: https://syzkaller.appspot.com/x/log.txt?x=1742b896580000
kernel config: https://syzkaller.appspot.com/x/.config?x=dfcc8f993a958a78
dashboard link: https://syzkaller.appspot.com/bug?extid=1b2c9c4a0f8708082678
compiler: gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
Note: no patches were applied.
^ permalink raw reply
* Re: [syzbot] [virt?] [net?] memory leak in __vsock_create (2)
From: Stefano Garzarella @ 2026-04-27 16:18 UTC (permalink / raw)
To: syzbot
Cc: davem, edumazet, horms, kuba, linux-kernel, netdev, pabeni,
syzkaller-bugs, virtualization
In-Reply-To: <69eacf39.a00a0220.17a17.004d.GAE@google.com>
#syz test: https://github.com/stefano-garzarella/linux.git fix-syzbot-memleak-vsock-create
^ permalink raw reply
* Re: [PATCH RFC v4 14/22] mm: page_reporting: skip redundant zeroing of host-zeroed reported pages
From: David Hildenbrand (Arm) @ 2026-04-27 15:43 UTC (permalink / raw)
To: Zi Yan, Michael S. Tsirkin, linux-kernel
Cc: Andrew Morton, Vlastimil Babka, Brendan Jackman, Michal Hocko,
Suren Baghdasaryan, Jason Wang, Andrea Arcangeli, Gregory Price,
linux-mm, virtualization, Lorenzo Stoakes, Liam R. Howlett,
Mike Rapoport, Johannes Weiner, Matthew Wilcox
In-Reply-To: <DI419PSP5050.15VGMJFDMWBQU@nvidia.com>
On 4/27/26 17:13, Zi Yan wrote:
> On Sun Apr 26, 2026 at 5:48 PM EDT, Michael S. Tsirkin wrote:
>> When a guest reports free pages to the hypervisor via the page reporting
>> framework (used by virtio-balloon and hv_balloon), the host typically
>> zeros those pages when reclaiming their backing memory. However, when
>> those pages are later allocated in the guest, post_alloc_hook()
>> unconditionally zeros them again if __GFP_ZERO is set. This
>> double-zeroing is wasteful, especially for large pages.
>>
>> Avoid redundant zeroing:
>>
>> - Add a host_zeroes_pages flag to page_reporting_dev_info, allowing
>> drivers to declare that their host zeros reported pages on reclaim.
>> A static key (page_reporting_host_zeroes) gates the fast path.
>>
>> - Add PG_zeroed page flag (sharing PG_private bit) to mark pages
>> that have been zeroed by the host. Set it on reported pages during
>> allocation from the buddy in page_del_and_expand().
>>
>> - Thread the zeroed bool through rmqueue -> prep_new_page ->
>> post_alloc_hook, where it skips redundant zeroing for __GFP_ZERO
>> allocations.
>>
>> No driver sets host_zeroes_pages yet; a follow-up patch to
>> virtio_balloon is needed to opt in.
>>
>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>> Assisted-by: Claude:claude-opus-4-6
>> Assisted-by: cursor-agent:GPT-5.4-xhigh
>> ---
>> include/linux/page-flags.h | 9 +++++
>> include/linux/page_reporting.h | 3 ++
>> mm/compaction.c | 6 ++--
>> mm/internal.h | 2 +-
>> mm/page_alloc.c | 66 +++++++++++++++++++++++-----------
>> mm/page_reporting.c | 14 +++++++-
>> mm/page_reporting.h | 12 +++++++
>> 7 files changed, 87 insertions(+), 25 deletions(-)
>>
>> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
>> index f7a0e4af0c73..eef2499cba8b 100644
>> --- a/include/linux/page-flags.h
>> +++ b/include/linux/page-flags.h
>> @@ -135,6 +135,8 @@ enum pageflags {
>> PG_swapcache = PG_owner_priv_1, /* Swap page: swp_entry_t in private */
>> /* Some filesystems */
>> PG_checked = PG_owner_priv_1,
>> + /* Page contents are known to be zero */
>> + PG_zeroed = PG_private,
>
> +willy,
>
> I was discussing with willy and David about removing PG_private and
> repurposing it to PG_folio to identify folios. IIUC, PG_zeroed is only
> set for PageBuddy, so it should not be an issue to set it for allocated
> pages for folio identification. Let me know if I get it wrong.
Right, we can keep using that flag here. Whenever we leave the buddy it gets
cleared. So as part of your work, simply let the buddy use the renamed flag.
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH v12 05/13] blk-mq: add blk_mq_{online|possible}_queue_affinity
From: Sebastian Andrzej Siewior @ 2026-04-27 15:34 UTC (permalink / raw)
To: Aaron Tomlin
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, yphbchou0911, wagi, frederic, longman,
chenridong, hare, kch, ming.lei, tom.leiming, steve, sean,
chjohnst, neelx, mproche, nick.lange, marco.crivellari,
linux-block, linux-kernel, virtualization, linux-nvme, linux-scsi,
megaraidlinux.pdl, mpi3mr-linuxdrv.pdl, MPT-FusionLinux.pdl
In-Reply-To: <20260422185215.100929-6-atomlin@atomlin.com>
On 2026-04-22 14:52:07 [-0400], Aaron Tomlin wrote:
> From: Daniel Wagner <wagi@kernel.org>
>
> Introduce blk_mq_{online|possible}_queue_affinity, which returns the
> queue-to-CPU mapping constraints defined by the block layer. This allows
> other subsystems (e.g., IRQ affinity setup) to respect block layer
> requirements.
>
> It is necessary to provide versions for both the online and possible CPU
> masks because some drivers want to spread their I/O queues only across
> online CPUs, while others prefer to use all possible CPUs. And the mask
> used needs to match with the number of queues requested
> (see blk_num_{online|possible}_queues).
Which driver uses cpu_possible_mask? This mask is assigned at boot time
once the kernel figured how many CPUs are possible based on ACPI or
whatever the system uses. This mask does not change.
I only see drivers/scsi/lpfc/lpfc_init.c using it. Looking at
cpu_possible_mask might not be the right thing. It is usually the same
thing as "online" except on system where ACPI thinks that something
could be added via hotplug _or_ if the admin shuts down a CPU via
cpuhotplug _or_ boots with less (there a command line option for that).
In case cpu_possible_mask != cpu_online_mask the intention is to
allocate memory and setup irqs for the offline CPUs?
> Signed-off-by: Daniel Wagner <wagi@kernel.org>
> Reviewed-by: Hannes Reinecke <hare@suse.de>
> Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Sebastian
^ permalink raw reply
* Re: [PATCH v12 02/13] lib/group_cpus: remove dead !SMP code
From: Sebastian Andrzej Siewior @ 2026-04-27 15:21 UTC (permalink / raw)
To: Aaron Tomlin
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, yphbchou0911, wagi, frederic, longman,
chenridong, hare, kch, ming.lei, tom.leiming, steve, sean,
chjohnst, neelx, mproche, nick.lange, marco.crivellari,
linux-block, linux-kernel, virtualization, linux-nvme, linux-scsi,
megaraidlinux.pdl, mpi3mr-linuxdrv.pdl, MPT-FusionLinux.pdl
In-Reply-To: <20260422185215.100929-3-atomlin@atomlin.com>
On 2026-04-22 14:52:04 [-0400], Aaron Tomlin wrote:
> From: Daniel Wagner <wagi@kernel.org>
>
> The support for the !SMP configuration has been removed from the core by
> commit cac5cefbade9 ("sched/smp: Make SMP unconditional").
>
> While one can technically still compile a uniprocessor kernel, the core
> scheduler now mandates SMP unconditionally, rendering this particular
> !SMP fallback handling redundant. Therefore, remove the #ifdef CONFIG_SMP
> guards and the fallback logic.
>
> Signed-off-by: Daniel Wagner <wagi@kernel.org>
> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
> Reviewed-by: Hannes Reinecke <hare@suse.de>
> [atomlin: Updated commit message to clarify !SMP removal context]
This look unchanged vs previous submission. You could explain why you
want to remove the !SMP case. It looks like the !SMP makes things
easier ;) I don't know how much of this gets removed because of !SMP
code elsewhere.
The description still does not make sense/ is accurate.
> Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
> ---
> lib/group_cpus.c | 20 --------------------
> 1 file changed, 20 deletions(-)
>
> diff --git a/lib/group_cpus.c b/lib/group_cpus.c
> index e6e18d7a49bb..b8d54398f88a 100644
> --- a/lib/group_cpus.c
> +++ b/lib/group_cpus.c
> @@ -9,8 +9,6 @@
> #include <linux/sort.h>
> #include <linux/group_cpus.h>
>
> -#ifdef CONFIG_SMP
> -
> static void grp_spread_init_one(struct cpumask *irqmsk, struct cpumask *nmsk,
> unsigned int cpus_per_grp)
> {
> @@ -564,22 +562,4 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps, unsigned int *nummasks)
> *nummasks = min(nr_present + nr_others, numgrps);
> return masks;
> }
> -#else /* CONFIG_SMP */
> -struct cpumask *group_cpus_evenly(unsigned int numgrps, unsigned int *nummasks)
> -{
> - struct cpumask *masks;
> -
> - if (numgrps == 0)
> - return NULL;
> -
> - masks = kzalloc_objs(*masks, numgrps);
> - if (!masks)
> - return NULL;
> -
> - /* assign all CPUs(cpu 0) to the 1st group only */
> - cpumask_copy(&masks[0], cpu_possible_mask);
> - *nummasks = 1;
> - return masks;
> -}
> -#endif /* CONFIG_SMP */
> EXPORT_SYMBOL_GPL(group_cpus_evenly);
Sebastian
^ permalink raw reply
* Re: [PATCH RFC v4 14/22] mm: page_reporting: skip redundant zeroing of host-zeroed reported pages
From: Michael S. Tsirkin @ 2026-04-27 15:18 UTC (permalink / raw)
To: Zi Yan
Cc: linux-kernel, Andrew Morton, David Hildenbrand, Vlastimil Babka,
Brendan Jackman, Michal Hocko, Suren Baghdasaryan, Jason Wang,
Andrea Arcangeli, Gregory Price, linux-mm, virtualization,
Lorenzo Stoakes, Liam R. Howlett, Mike Rapoport, Johannes Weiner,
Matthew Wilcox
In-Reply-To: <DI419PSP5050.15VGMJFDMWBQU@nvidia.com>
On Mon, Apr 27, 2026 at 11:13:44AM -0400, Zi Yan wrote:
> On Sun Apr 26, 2026 at 5:48 PM EDT, Michael S. Tsirkin wrote:
> > When a guest reports free pages to the hypervisor via the page reporting
> > framework (used by virtio-balloon and hv_balloon), the host typically
> > zeros those pages when reclaiming their backing memory. However, when
> > those pages are later allocated in the guest, post_alloc_hook()
> > unconditionally zeros them again if __GFP_ZERO is set. This
> > double-zeroing is wasteful, especially for large pages.
> >
> > Avoid redundant zeroing:
> >
> > - Add a host_zeroes_pages flag to page_reporting_dev_info, allowing
> > drivers to declare that their host zeros reported pages on reclaim.
> > A static key (page_reporting_host_zeroes) gates the fast path.
> >
> > - Add PG_zeroed page flag (sharing PG_private bit) to mark pages
> > that have been zeroed by the host. Set it on reported pages during
> > allocation from the buddy in page_del_and_expand().
> >
> > - Thread the zeroed bool through rmqueue -> prep_new_page ->
> > post_alloc_hook, where it skips redundant zeroing for __GFP_ZERO
> > allocations.
> >
> > No driver sets host_zeroes_pages yet; a follow-up patch to
> > virtio_balloon is needed to opt in.
> >
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > Assisted-by: Claude:claude-opus-4-6
> > Assisted-by: cursor-agent:GPT-5.4-xhigh
> > ---
> > include/linux/page-flags.h | 9 +++++
> > include/linux/page_reporting.h | 3 ++
> > mm/compaction.c | 6 ++--
> > mm/internal.h | 2 +-
> > mm/page_alloc.c | 66 +++++++++++++++++++++++-----------
> > mm/page_reporting.c | 14 +++++++-
> > mm/page_reporting.h | 12 +++++++
> > 7 files changed, 87 insertions(+), 25 deletions(-)
> >
> > diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
> > index f7a0e4af0c73..eef2499cba8b 100644
> > --- a/include/linux/page-flags.h
> > +++ b/include/linux/page-flags.h
> > @@ -135,6 +135,8 @@ enum pageflags {
> > PG_swapcache = PG_owner_priv_1, /* Swap page: swp_entry_t in private */
> > /* Some filesystems */
> > PG_checked = PG_owner_priv_1,
> > + /* Page contents are known to be zero */
> > + PG_zeroed = PG_private,
>
> +willy,
>
> I was discussing with willy and David about removing PG_private and
> repurposing it to PG_folio to identify folios. IIUC, PG_zeroed is only
> set for PageBuddy, so it should not be an issue to set it for allocated
> pages for folio identification. Let me know if I get it wrong.
>
> Thanks.
>
> --
> Best Regards,
> Yan, Zi
Exactly. Trivial to switch to another bit, of course - most are
unused in the buddy.
--
MST
^ permalink raw reply
* Re: [PATCH RFC v4 14/22] mm: page_reporting: skip redundant zeroing of host-zeroed reported pages
From: Zi Yan @ 2026-04-27 15:13 UTC (permalink / raw)
To: Michael S. Tsirkin, linux-kernel
Cc: Andrew Morton, David Hildenbrand, Vlastimil Babka,
Brendan Jackman, Michal Hocko, Suren Baghdasaryan, Jason Wang,
Andrea Arcangeli, Gregory Price, linux-mm, virtualization,
Lorenzo Stoakes, Liam R. Howlett, Mike Rapoport, Johannes Weiner,
Zi Yan, Matthew Wilcox
In-Reply-To: <788d5a09394ed1456beaab23f75d91846ceeb611.1777223007.git.mst@redhat.com>
On Sun Apr 26, 2026 at 5:48 PM EDT, Michael S. Tsirkin wrote:
> When a guest reports free pages to the hypervisor via the page reporting
> framework (used by virtio-balloon and hv_balloon), the host typically
> zeros those pages when reclaiming their backing memory. However, when
> those pages are later allocated in the guest, post_alloc_hook()
> unconditionally zeros them again if __GFP_ZERO is set. This
> double-zeroing is wasteful, especially for large pages.
>
> Avoid redundant zeroing:
>
> - Add a host_zeroes_pages flag to page_reporting_dev_info, allowing
> drivers to declare that their host zeros reported pages on reclaim.
> A static key (page_reporting_host_zeroes) gates the fast path.
>
> - Add PG_zeroed page flag (sharing PG_private bit) to mark pages
> that have been zeroed by the host. Set it on reported pages during
> allocation from the buddy in page_del_and_expand().
>
> - Thread the zeroed bool through rmqueue -> prep_new_page ->
> post_alloc_hook, where it skips redundant zeroing for __GFP_ZERO
> allocations.
>
> No driver sets host_zeroes_pages yet; a follow-up patch to
> virtio_balloon is needed to opt in.
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> Assisted-by: Claude:claude-opus-4-6
> Assisted-by: cursor-agent:GPT-5.4-xhigh
> ---
> include/linux/page-flags.h | 9 +++++
> include/linux/page_reporting.h | 3 ++
> mm/compaction.c | 6 ++--
> mm/internal.h | 2 +-
> mm/page_alloc.c | 66 +++++++++++++++++++++++-----------
> mm/page_reporting.c | 14 +++++++-
> mm/page_reporting.h | 12 +++++++
> 7 files changed, 87 insertions(+), 25 deletions(-)
>
> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
> index f7a0e4af0c73..eef2499cba8b 100644
> --- a/include/linux/page-flags.h
> +++ b/include/linux/page-flags.h
> @@ -135,6 +135,8 @@ enum pageflags {
> PG_swapcache = PG_owner_priv_1, /* Swap page: swp_entry_t in private */
> /* Some filesystems */
> PG_checked = PG_owner_priv_1,
> + /* Page contents are known to be zero */
> + PG_zeroed = PG_private,
+willy,
I was discussing with willy and David about removing PG_private and
repurposing it to PG_folio to identify folios. IIUC, PG_zeroed is only
set for PageBuddy, so it should not be an issue to set it for allocated
pages for folio identification. Let me know if I get it wrong.
Thanks.
--
Best Regards,
Yan, Zi
^ permalink raw reply
* Re: [PATCH] virtio-mmio: fix device release warning on module unload
From: Johan Hovold @ 2026-04-27 15:01 UTC (permalink / raw)
To: Jason Wang
Cc: Michael S . Tsirkin, Xuan Zhuo, Eugenio Pérez,
Greg Kroah-Hartman, virtualization, linux-kernel, stable,
Pawel Moll
In-Reply-To: <CACGkMEvJ4CZt9mVhn5TRCz5yCYzY_yHNFh8pbT4hOmJoWDiKOA@mail.gmail.com>
On Mon, Apr 27, 2026 at 12:16:47PM +0800, Jason Wang wrote:
> On Fri, Apr 24, 2026 at 6:48 PM Johan Hovold <johan@kernel.org> wrote:
> >
> > Driver core expects devices to be allocated dynamically and complains
> > loudly when a device that lacks a release function is freed.
> >
> > Use __root_device_register() to allocate and register the root device
> > instead of open coding using a static device.
> > -static struct device vm_cmdline_parent = {
> > - .init_name = "virtio-mmio-cmdline",
> > -};
> > +static struct device *vm_cmdline_parent;
>
> vm_cmdline_get() is the .get callback for the device module parameter.
> It is invoked when userspace reads
> /sys/module/virtio_mmio/parameters/device. This function uses
> vm_cmdline_parent unconditionally, without checking whether the device
> has been registered. This would cause NULL pointer dereference.
Indeed, Sashiko flagged this as well. Just sent a v2 here:
https://lore.kernel.org/r/20260427143710.14702-1-johan@kernel.org
Johan
^ permalink raw reply
* [PATCH v2] virtio-mmio: fix device release warning on module unload
From: Johan Hovold @ 2026-04-27 14:37 UTC (permalink / raw)
To: Michael S . Tsirkin, Jason Wang, Xuan Zhuo, Eugenio Pérez,
virtualization, linux-kernel
Cc: Johan Hovold, stable, Pawel Moll
Driver core expects devices to be allocated dynamically and complains
loudly when a device that lacks a release function is freed.
Use __root_device_register() to allocate and register the root device
instead of open coding using a static device.
Note that root_device_register(), which also creates a link to the
module, cannot be used as the device is registered when parsing the
module parameters which happens before the module kobject has been set
up.
Fixes: 81a054ce0b46 ("virtio-mmio: Devices parameter parsing")
Cc: stable@vger.kernel.org # 3.5
Cc: Pawel Moll <pawel.moll@arm.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
---
Changes in v2:
- add sanity check to vm_cmdline_get() to prevent root from
dereferencing an error pointer when reading back the module parameter
through sysfs should root device registration ever fail when the
driver is also built-in
drivers/virtio/virtio_mmio.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 595c2274fbb5..510b7c4efdff 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -662,9 +662,7 @@ static void virtio_mmio_remove(struct platform_device *pdev)
#if defined(CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES)
-static struct device vm_cmdline_parent = {
- .init_name = "virtio-mmio-cmdline",
-};
+static struct device *vm_cmdline_parent;
static int vm_cmdline_parent_registered;
static int vm_cmdline_id;
@@ -672,7 +670,6 @@ static int vm_cmdline_id;
static int vm_cmdline_set(const char *device,
const struct kernel_param *kp)
{
- int err;
struct resource resources[2] = {};
char *str;
long long base, size;
@@ -704,11 +701,10 @@ static int vm_cmdline_set(const char *device,
resources[1].start = resources[1].end = irq;
if (!vm_cmdline_parent_registered) {
- err = device_register(&vm_cmdline_parent);
- if (err) {
- put_device(&vm_cmdline_parent);
+ vm_cmdline_parent = __root_device_register("virtio-mmio-cmdline", NULL);
+ if (IS_ERR(vm_cmdline_parent)) {
pr_err("Failed to register parent device!\n");
- return err;
+ return PTR_ERR(vm_cmdline_parent);
}
vm_cmdline_parent_registered = 1;
}
@@ -719,7 +715,7 @@ static int vm_cmdline_set(const char *device,
(unsigned long long)resources[0].end,
(int)resources[1].start);
- pdev = platform_device_register_resndata(&vm_cmdline_parent,
+ pdev = platform_device_register_resndata(vm_cmdline_parent,
"virtio-mmio", vm_cmdline_id++,
resources, ARRAY_SIZE(resources), NULL, 0);
@@ -743,8 +739,12 @@ static int vm_cmdline_get_device(struct device *dev, void *data)
static int vm_cmdline_get(char *buffer, const struct kernel_param *kp)
{
buffer[0] = '\0';
- device_for_each_child(&vm_cmdline_parent, buffer,
- vm_cmdline_get_device);
+
+ if (vm_cmdline_parent_registered) {
+ device_for_each_child(vm_cmdline_parent, buffer,
+ vm_cmdline_get_device);
+ }
+
return strlen(buffer) + 1;
}
@@ -766,9 +766,9 @@ static int vm_unregister_cmdline_device(struct device *dev,
static void vm_unregister_cmdline_devices(void)
{
if (vm_cmdline_parent_registered) {
- device_for_each_child(&vm_cmdline_parent, NULL,
+ device_for_each_child(vm_cmdline_parent, NULL,
vm_unregister_cmdline_device);
- device_unregister(&vm_cmdline_parent);
+ root_device_unregister(vm_cmdline_parent);
vm_cmdline_parent_registered = 0;
}
}
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] vsock/virtio: fix memory leak in virtio_transport_recv_listen()
From: Stefano Garzarella @ 2026-04-27 13:44 UTC (permalink / raw)
To: Deepanshu Kartikey
Cc: mst, jasowang, xuanzhuo, eperezma, stefanha, davem, edumazet,
kuba, pabeni, horms, virtualization, kvm, netdev, linux-kernel,
syzbot+1b2c9c4a0f8708082678
In-Reply-To: <20260424150310.57228-1-kartikey406@gmail.com>
On Fri, Apr 24, 2026 at 08:33:10PM +0530, Deepanshu Kartikey wrote:
>Two bugs exist in virtio_transport_recv_listen():
Two bugs, two fixes, two patches usually.
>
>1. On the transport assignment error path, sk_acceptq_added() is called
> but sk_acceptq_removed() is never called when vsock_assign_transport()
> fails or assigns a different transport than expected. This causes the
> parent listener's accept backlog counter to be permanently inflated,
> eventually causing sk_acceptq_is_full() to reject legitimate incoming
> connections.
Wait, I can't see this issue. sk_acceptq_added() is called after the
vsock_assign_transport(), so why we should call sk_acceptq_removed()
in the error path of vsock_assign_transport()?
Maybe I'm missing something.
>
>2. There is a race between __vsock_release() and vsock_enqueue_accept().
> __vsock_release() sets sk->sk_shutdown to SHUTDOWN_MASK and flushes
> the accept queue under the parent socket lock. However,
> virtio_transport_recv_listen() checks sk_shutdown and subsequently
> calls vsock_enqueue_accept() without holding the parent socket lock.
Are you sure about this?
virtio_transport_recv_listen() is called only by
virtio_transport_recv_pkt() after calling lock_sock(sk), so I'm really
confused.
> This means a child socket can be enqueued after __vsock_release() has
> already flushed the queue, causing the child socket and its associated
> resources to leak
> permanently. The existing comment in the code hints at this race but
> the fix was never implemented.
Are you referring to:
/* __vsock_release() might have already flushed accept_queue.
* Subsequent enqueues would lead to a memory leak.
*/
if (sk->sk_shutdown == SHUTDOWN_MASK) {
virtio_transport_reset_no_sock(t, skb, sock_net(sk));
return -ESHUTDOWN;
}
In this case I think we are saying that we are doing this check exactly
to avoid that issue.
>
>Fix both issues: add sk_acceptq_removed() on the transport error path,
Again, better to fix the 2 issues with 2 patches (same series is fine).
>and re-check sk->sk_shutdown under the parent socket lock before calling
>vsock_enqueue_accept() to close the race window. The child socket lock
>is released before acquiring the parent socket lock to maintain correct
>lock ordering (parent before child).
>
We are missing the Fixes tag, and I think we can target the `net` tree
with this patch (i.e. [PATCH net]), see:
https://www.kernel.org/doc/html/next/process/maintainer-netdev.html
>Reported-by: syzbot+1b2c9c4a0f8708082678@syzkaller.appspotmail.com
>Closes: https://syzkaller.appspot.com/bug?extid=1b2c9c4a0f8708082678
>Tested-by: syzbot+1b2c9c4a0f8708082678@syzkaller.appspotmail.com
>Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
>---
> net/vmw_vsock/virtio_transport_common.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>
>diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
>index 416d533f493d..fad5fa4a4296 100644
>--- a/net/vmw_vsock/virtio_transport_common.c
>+++ b/net/vmw_vsock/virtio_transport_common.c
>@@ -1578,6 +1578,7 @@ virtio_transport_recv_listen(struct sock *sk, struct sk_buff *skb,
> */
> if (ret || vchild->transport != &t->transport) {
> release_sock(child);
>+ sk_acceptq_removed(sk);
Ditto, are we sure about this?
> virtio_transport_reset_no_sock(t, skb, sock_net(sk));
> sock_put(child);
> return ret;
>@@ -1588,11 +1589,19 @@ virtio_transport_recv_listen(struct sock *sk, struct sk_buff *skb,
> child->sk_write_space(child);
>
> vsock_insert_connected(vchild);
>+ release_sock(child);
>+ lock_sock(sk);
IMO this is a deadlock with the lock_sock(sk) called by the caller.
Also a comment would be helpful here to explain why we're doing this.
>+ if (sk->sk_shutdown == SHUTDOWN_MASK) {
>+ release_sock(sk);
>+ sk_acceptq_removed(sk);
>+ virtio_transport_reset_no_sock(t, skb, sock_net(sk));
>+ sock_put(child);
>+ return -ESHUTDOWN;
Since this is very similar to the error path of
vsock_assign_transport(), I think it would be better to start by
defining a common error path for the function and use labels to exit, so
we can avoid duplicating the code multiple times.
>+ }
> vsock_enqueue_accept(sk, child);
>+ release_sock(sk);
> virtio_transport_send_response(vchild, skb);
>
>- release_sock(child);
>-
TBH I'm really worried about this patch since both fixes are completely
wrong IMO.
Thanks,
Stefano
> sk->sk_data_ready(sk);
> return 0;
> }
>--
>2.43.0
>
^ permalink raw reply
* Re: [PATCH 2/2] drm/hyperv: use VMBUS_RING_SIZE()
From: Hamza Mahfooz @ 2026-04-27 11:51 UTC (permalink / raw)
To: Saurabh Singh Sengar
Cc: linux-kernel@vger.kernel.org, KY Srinivasan, Haiyang Zhang,
Wei Liu, Dexuan Cui, Long Li, Stefano Garzarella, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Himadri Pandya, Michael Kelley, linux-hyperv@vger.kernel.org,
virtualization@lists.linux.dev, netdev@vger.kernel.org,
Saurabh Sengar, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Deepak Rawat,
dri-devel@lists.freedesktop.org, stable@kernel.vger.org
In-Reply-To: <KUZP153MB14445757C6A5DA5DEDA9A09CBE292@KUZP153MB1444.APCP153.PROD.OUTLOOK.COM>
On Sun, Apr 26, 2026 at 05:00:24AM +0000, Saurabh Singh Sengar wrote:
> > Subject: [PATCH 2/2] drm/hyperv: use VMBUS_RING_SIZE()
> >
> > VMBUS ring buffers must be page aligned. So, use VMBUS_RING_SIZE() to
> > ensure they are always aligned and large enough to hold all of the relevant
> > data.
> >
> > Cc: stable@kernel.vger.org
> > Fixes: 76c56a5affeb ("drm/hyperv: Add DRM driver for hyperv synthetic video
> > device")
> > Signed-off-by: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>
> > ---
> > drivers/gpu/drm/hyperv/hyperv_drm_proto.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
> > b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
> > index 051ecc526832..753d97bff76f 100644
> > --- a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
> > +++ b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
> > @@ -10,7 +10,7 @@
> >
> > #include "hyperv_drm.h"
> >
> > -#define VMBUS_RING_BUFSIZE (256 * 1024)
> > +#define VMBUS_RING_BUFSIZE VMBUS_RING_SIZE(256 * 1024)
> > #define VMBUS_VSP_TIMEOUT (10 * HZ)
> >
> > #define SYNTHVID_VERSION(major, minor) ((minor) << 16 | (major))
> > --
> > 2.54.0
>
> Although this lgtm, but this may change the behaviour on ARM64 systems with page size > 4K ?
> Have we tested it ?
Yup, I tested it on an ARM64 windows machine with a 64K page size guest kernel.
>
> Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
Pushed to drm-misc.
>
^ permalink raw reply
* Re: [PATCH v12 00/13] blk: honor isolcpus configuration
From: Florian Bezdeka @ 2026-04-27 10:55 UTC (permalink / raw)
To: Aaron Tomlin, axboe, kbusch, hch, sagi, mst
Cc: aacraid, James.Bottomley, martin.petersen, liyihang9,
kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
chandrakanth.patil, sathya.prakash, sreekanth.reddy,
suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, linux-block, linux-kernel,
virtualization, linux-nvme, linux-scsi, megaraidlinux.pdl,
mpi3mr-linuxdrv.pdl, MPT-FusionLinux.pdl
In-Reply-To: <20260422185215.100929-1-atomlin@atomlin.com>
Hi all,
On Wed, 2026-04-22 at 14:52 -0400, Aaron Tomlin wrote:
> Hi,
>
> I have decided to drive this series forward on behalf of Daniel Wagner, the
> original author. The series has been rebased on v7.0-12635-g6596a02b2078.
>
> Building upon prior iterations, this series introduces critical
> architectural refinements to the mapping and affinity spreading algorithms
> to guarantee thread safety and resilience against concurrent CPU-hotplug
> operations. Previously, the block layer relied on a shared global static
> mask (i.e., blk_hk_online_mask), which proved vulnerable to race conditions
> during rapid hotplug events. This vulnerability was highlighted by the
> kernel test robot, which encountered a NULL pointer dereference during
> rcutorture (cpuhotplug) stress testing due to concurrent mask modification.
>
> To resolve this, the architecture has been fundamentally hardened. The
> global static state has been eradicated. Instead, the IRQ affinity core now
> employs a newly introduced irq_spread_hk_filter(), which safely intersects
> the natively calculated affinity mask with the HK_TYPE_IO_QUEUE mask.
> Crucially, this is achieved using a local, hotplug-safe snapshot via
> data_race(cpu_online_mask). This approach circumvents the hotplug lock
> deadlocks previously identified by Thomas Gleixner, while explicitly
> avoiding CONFIG_CPUMASK_OFFSTACK stack bloat hazards on high-core-count
> systems. A robust fallback mechanism guarantees that should an interrupt
> vector be assigned exclusively to isolated cores, it is safely re-routed to
> the system's online housekeeping CPUs.
>
> Following rigorous testing of multiple queue maps (such as NVMe poll
> queues) alongside isolated CPUs, the tenth iteration resolved a critical
> page fault regression. The multi-queue mapping logic has been corrected to
> strictly maintain absolute hardware queue indices, ensuring faultless queue
> initialisation and preventing out-of-bounds memory access.
>
> Furthermore, following feedback from Ming Lei, the administrative
> documentation for isolcpus=io_queue has undergone a comprehensive overhaul
> to reflect this architectural reality. Previous iterations lacked the
> required technical precision regarding subsystem impact. The expanded
> kernel-parameters.txt now explicitly details that this parameter applies
> strictly to managed IRQs. It thoroughly documents how the block layer
> intercepts multiqueue allocation to match the housekeeping mask, actively
> preventing MSI-X vector exhaustion on massive topologies and forcing queue
> sharing. Most importantly, it cements the structural guarantee: while an
> application on an isolated CPU may freely submit I/O, the hardware
> completion interrupt is strictly and safely offloaded to a housekeeping
> core.
>
> Please let me know your thoughts.
This topic reminds me of a discussion started by Tobias [1] some time
ago about IRQ spreading of network drivers. The problem was (and still
is) that network drivers ignore any CPU isolation when spreading out
device IRQs.
In general we have two different CPU isolation mechanisms:
- The static one, via isolcpus= cmdline parameter
- The dynamic one, via cgroups(v2) cpuset controller
This series is only taking the static "world" into account, right? Are
there any plans to honor the CPU isolations configured the dynamic way?
It has been a while since the last investigations on my end. Last time I
went through the code, the IRQ core was completely decoupled from the
dynamic configuration via cgroups. Are there any plans to fix that gap?
Best regards,
Florian
[1] https://lore.kernel.org/all/a0cad8314124ca98d7c6763e3e08d7192598cf92.camel@siemens.com/
^ permalink raw reply
* Re: [PATCH 7.2 v10 0/2] skip redundant sync IPIs when TLB flush sent them
From: David Hildenbrand (Arm) @ 2026-04-27 8:53 UTC (permalink / raw)
To: Andrew Morton
Cc: Yosry Ahmed, Pasha Tatashin, Lance Yang, peterz, dave.hansen,
dave.hansen, ypodemsk, hughd, will, aneesh.kumar, npiggin, tglx,
mingo, bp, x86, hpa, arnd, ljs, ziy, baolin.wang, Liam.Howlett,
npache, ryan.roberts, dev.jain, baohua, shy828301, riel, jannh,
jgross, seanjc, pbonzini, boris.ostrovsky, virtualization, kvm,
linux-arch, linux-mm, linux-kernel, ioworker0, roman.gushchin
In-Reply-To: <20260425043605.a3a1819fb219c649eab0f3a1@linux-foundation.org>
On 4/25/26 13:36, Andrew Morton wrote:
> On Sat, 25 Apr 2026 07:17:18 +0200 "David Hildenbrand (Arm)" <david@kernel.org> wrote:
>
>>> The usefulness of the mailing list posting is that it makes it easier
>>> to respond and discuss the review. Yes, what Zi did is great, but it
>>> would be nice if contributors/reviewers didn't need to manually quote
>>> Sashiko.
>>
>> I think the most important part is the contributor side. A private posting is
>> sufficient for that.
>
> Thinking through how is this going to work out.
>
> - contributor sends patchset
>
> - akpm looks at the Sashiko scan and thinks "huh, we might be seeing
> a new version soon".
>
> - Now what? Maybe contributor doesn't like AI, maybe contributor
> thinks it was all nonsense. But I don't know this!
Right. In the common case, people will just read the output and process it in a
reasonable way, like some people do today even without any notification.
But there will be cases where people ignore it, I am sure.
>
> So I send the email "I see that Sashiko said stuff - can we expect
> a new version?". Which is no improvement over what's happening now.
That only happens in the scenarios where there is no further feedback from other
reviewers and there won't be a new revision.
That's why I am saying that the AI review on the last upstream posting before
merging is the most important one from a maintainer perspective.
I agree that when we are about to merge something and AI review was not
addressed (no feedback from contributor), that it's a problem.
>
> What I would like to have is some reasonably reliable and prompt means
> by which we all learn contributor's views on the Sashiko scan.
Right. At the same time I don't want full AI review posted to the mailing list
immediately to each and every revision of a patch set.
As first step, I would be fine with having AI review send a review status in
case it went into a problem to everyone as reply to each patch set, just stating
whether it failed to apply, or if something was found etc. Paired with a link
like you would send.
>
> One way to bring this about might be to set suitable reply-to headers
> in the Sashiko->contributor email, along with a few words asking
> contributor to let everyone know the status.
Yes, that's an alternative if we were to send the full AI review to
contributors. Which might make sense in addition to the AI review status (above).
>
> But whatever - let's not overthink this. To start somewhere, let's
> send that private email, spend a few weeks evaluating then perhaps make
> adjustments.
Right, let's do this step by step.
--
Cheers,
David
^ permalink raw reply
* Re: [PATCH] drm/qxl: Fix missing KMS poll cleanup
From: Thomas Zimmermann @ 2026-04-27 8:46 UTC (permalink / raw)
To: Myeonghun Pak, Dave Airlie, Gerd Hoffmann
Cc: Maarten Lankhorst, Maxime Ripard, David Airlie, Simona Vetter,
virtualization, spice-devel, dri-devel, linux-kernel
In-Reply-To: <20260424112543.57819-1-mhun512@gmail.com>
Thanks for your patch.
Am 24.04.26 um 13:25 schrieb Myeonghun Pak:
> drm_kms_helper_poll_init() initializes the output polling work and
> enables polling for the DRM device. qxl enables polling before calling
> drm_dev_register(), but the drm_dev_register() failure path tears down
> the modeset and device state without disabling the polling helper.
>
> The remove path also unregisters and shuts down the DRM device without
> first disabling the polling helper. Add matching drm_kms_helper_poll_fini()
> calls in both paths so the delayed polling work is cancelled before qxl
> tears down the associated modeset/device state.
>
> Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 5ff91e442652 ("qxl: use drm helper hotplug support")
Cc: <stable@vger.kernel.org> # v3.11+
> ---
> drivers/gpu/drm/qxl/qxl_drv.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
> index 2bbb1168a3..1e6a2392d7 100644
> --- a/drivers/gpu/drm/qxl/qxl_drv.c
> +++ b/drivers/gpu/drm/qxl/qxl_drv.c
> @@ -118,12 +118,13 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> /* Complete initialization. */
> ret = drm_dev_register(&qdev->ddev, ent->driver_data);
> if (ret)
> - goto modeset_cleanup;
> + goto poll_fini;
>
> drm_client_setup(&qdev->ddev, NULL);
> return 0;
>
> -modeset_cleanup:
> +poll_fini:
> + drm_kms_helper_poll_fini(&qdev->ddev);
> qxl_modeset_fini(qdev);
> unload:
> qxl_device_fini(qdev);
> @@ -154,6 +155,7 @@ qxl_pci_remove(struct pci_dev *pdev)
> {
> struct drm_device *dev = pci_get_drvdata(pdev);
>
> + drm_kms_helper_poll_fini(dev);
> drm_dev_unregister(dev);
> drm_atomic_helper_shutdown(dev);
> if (pci_is_vga(pdev) && pdev->revision < 5)
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply
* Re: [PATCH] virtio-mmio: fix device release warning on module unload
From: Jason Wang @ 2026-04-27 4:16 UTC (permalink / raw)
To: Johan Hovold
Cc: Michael S . Tsirkin, Xuan Zhuo, Eugenio Pérez,
Greg Kroah-Hartman, virtualization, linux-kernel, stable,
Pawel Moll
In-Reply-To: <20260424104820.2619227-1-johan@kernel.org>
On Fri, Apr 24, 2026 at 6:48 PM Johan Hovold <johan@kernel.org> wrote:
>
> Driver core expects devices to be allocated dynamically and complains
> loudly when a device that lacks a release function is freed.
>
> Use __root_device_register() to allocate and register the root device
> instead of open coding using a static device.
>
> Note that root_device_register(), which also creates a link to the
> module, cannot be used as the device is registered when parsing the
> module parameters which happens before the module kobject has been set
> up.
>
> Fixes: 81a054ce0b46 ("virtio-mmio: Devices parameter parsing")
> Cc: stable@vger.kernel.org # 3.5
> Cc: Pawel Moll <pawel.moll@arm.com>
> Signed-off-by: Johan Hovold <johan@kernel.org>
> ---
> drivers/virtio/virtio_mmio.c | 20 ++++++++------------
> 1 file changed, 8 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
> index 595c2274fbb5..1b580de81e82 100644
> --- a/drivers/virtio/virtio_mmio.c
> +++ b/drivers/virtio/virtio_mmio.c
> @@ -662,9 +662,7 @@ static void virtio_mmio_remove(struct platform_device *pdev)
>
> #if defined(CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES)
>
> -static struct device vm_cmdline_parent = {
> - .init_name = "virtio-mmio-cmdline",
> -};
> +static struct device *vm_cmdline_parent;
vm_cmdline_get() is the .get callback for the device module parameter.
It is invoked when userspace reads
/sys/module/virtio_mmio/parameters/device. This function uses
vm_cmdline_parent unconditionally, without checking whether the device
has been registered. This would cause NULL pointer dereference.
Thanks
^ permalink raw reply
* Re: [PATCH 3/4] scsi: Support scsi_devices without a device wide limit
From: Martin K. Petersen @ 2026-04-27 1:33 UTC (permalink / raw)
To: Hannes Reinecke
Cc: John Garry, Mike Christie, martin.petersen, linux-scsi,
james.bottomley, virtualization, mst, pbonzini, stefanha,
eperezma
In-Reply-To: <3c57a174-ce83-43cd-a46b-d0eea752deda@suse.de>
Hannes,
> Let's see if we can schedule a session at LSF; I really would like to
> get this one sorted out.
Done.
--
Martin K. Petersen
^ permalink raw reply
* Re: [PATCH 2/2] vdpa_sim_net: switch to dynamic root device
From: Jason Wang @ 2026-04-27 1:20 UTC (permalink / raw)
To: Johan Hovold
Cc: Michael S . Tsirkin, Xuan Zhuo, Eugenio Pérez,
virtualization, linux-kernel
In-Reply-To: <20260424104703.2619093-3-johan@kernel.org>
On Fri, Apr 24, 2026 at 6:47 PM Johan Hovold <johan@kernel.org> wrote:
>
> Driver core expects devices to be dynamically allocated and will, for
> example, complain loudly when no release function has been provided.
>
> Use root_device_register() to allocate and register the root device
> instead of open coding using a static device.
>
> Signed-off-by: Johan Hovold <johan@kernel.org>
> ---
Acked-by: Jason Wang <jasowang@redhat.com>
Thanks
^ permalink raw reply
* Re: [PATCH 1/2] vdpa_sim_blk: switch to dynamic root device
From: Jason Wang @ 2026-04-27 1:20 UTC (permalink / raw)
To: Johan Hovold
Cc: Michael S . Tsirkin, Xuan Zhuo, Eugenio Pérez,
virtualization, linux-kernel
In-Reply-To: <20260424104703.2619093-2-johan@kernel.org>
On Fri, Apr 24, 2026 at 6:48 PM Johan Hovold <johan@kernel.org> wrote:
>
> Driver core expects devices to be dynamically allocated and will, for
> example, complain loudly when no release function has been provided.
>
> Use root_device_register() to allocate and register the root device
> instead of open coding using a static device.
>
> Signed-off-by: Johan Hovold <johan@kernel.org>
> ---
Acked-by: Jason Wang <jasowang@redhat.com>
Thanks
^ permalink raw reply
* Re: [PATCH] virtio: fix kernel-doc warnings for virtio_device
From: kenner azevedi @ 2026-04-26 22:29 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: jasowang, xuanzhuo, eperezma, virtualization, linux-kernel
In-Reply-To: <20260319112552-mutt-send-email-mst@kernel.org>
Hi team, good evening.
Is there any update regarding this patch?
Thank you very much.
On Thu, Mar 19, 2026 at 11:26 AM Michael S. Tsirkin <mst@redhat.com> wrote:
>
> On Thu, Mar 12, 2026 at 06:51:39AM -0400, Kenner de Azevedo dos Santos Miranda wrote:
> > The following warnings were reported when running 'make htmldocs':
> >
> > WARNING: ./include/linux/virtio.h:188 struct member 'map'
> > not described in 'virtio_device'
> >
> > WARNING: ./include/linux/virtio.h:188 struct member
> > 'VIRTIO_DECLARE_FEATURES(features' not described in
> > 'virtio_device'
> >
> > WARNING: ./include/linux/virtio.h:188 struct member 'vmap'
> > not described in 'virtio_device'
> >
> > Document the map and vmap fields in struct virtio_device.
> >
> > Also avoid kernel-doc confusion caused by the VIRTIO_DECLARE_FEATURES()
> > macro by documenting the logical @features field.
> >
> > After these changes, running 'make htmldocs' no longer reports warnings
> > for map, vmap, or VIRTIO_DECLARE_FEATURES().
> >
> > Signed-off-by: Kenner de Azevedo dos Santos Miranda <kenner.linuxdev@gmail.com>
>
>
> I will queue this. Thanks!
>
> > ---
> > include/linux/virtio.h | 5 ++++-
> > 1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/linux/virtio.h b/include/linux/virtio.h
> > index 3bbc4cb6a672..074d36453177 100644
> > --- a/include/linux/virtio.h
> > +++ b/include/linux/virtio.h
> > @@ -157,11 +157,13 @@ struct virtio_admin_cmd {
> > * @id: the device type identification (used to match it with a driver).
> > * @config: the configuration ops for this device.
> > * @vringh_config: configuration ops for host vrings.
> > + * @map: virtio specific mapping operations used by the device or transport.
> > * @vqs: the list of virtqueues for this device.
> > * @features: the 64 lower features supported by both driver and device.
> > * @features_array: the full features space supported by both driver and
> > - * device.
> > + * device.
> > * @priv: private pointer for the driver's use.
> > + * @vmap: mapping token passed to virtio mapping helpers and transport ops.
> > * @debugfs_dir: debugfs directory entry.
> > * @debugfs_filter_features: features to be filtered set by debugfs.
> > */
> > @@ -179,6 +181,7 @@ struct virtio_device {
> > const struct vringh_config_ops *vringh_config;
> > const struct virtio_map_ops *map;
> > struct list_head vqs;
> > + /* See @features */
> > VIRTIO_DECLARE_FEATURES(features);
> > void *priv;
> > union virtio_map vmap;
> > --
> > 2.43.0
>
^ permalink raw reply
* [PATCH RFC v4 22/22] virtio_balloon: mark deflated pages as zeroed
From: Michael S. Tsirkin @ 2026-04-26 21:48 UTC (permalink / raw)
To: linux-kernel
Cc: Andrew Morton, David Hildenbrand, Vlastimil Babka,
Brendan Jackman, Michal Hocko, Suren Baghdasaryan, Jason Wang,
Andrea Arcangeli, Gregory Price, linux-mm, virtualization,
Xuan Zhuo, Eugenio Pérez
In-Reply-To: <cover.1777223007.git.mst@redhat.com>
When host_zeroes_pages is set, the host has zeroed the balloon
pages on reclaim. Use put_page_zeroed() during deflation so
the freed pages are marked as zeroed in the buddy allocator,
allowing the next allocation to skip redundant zeroing.
put_page_zeroed() is best-effort: if the balloon is the sole
holder (the common case), the zeroed hint reaches the buddy
allocator via free_frozen_pages_zeroed(). If someone else
holds a reference, the hint is silently lost.
Once balloon pages are converted to frozen pages (no refcount),
this can switch to free_frozen_pages_zeroed() directly.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Assisted-by: Claude:claude-opus-4-6
---
drivers/virtio/virtio_balloon.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 8c15530b51b3..cdc3c960397d 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -304,7 +304,10 @@ static void release_pages_balloon(struct virtio_balloon *vb,
list_for_each_entry_safe(page, next, pages, lru) {
list_del(&page->lru);
- put_page(page); /* balloon reference */
+ if (host_zeroes_pages && !page_poisoning_enabled_static())
+ put_page_zeroed(page);
+ else
+ put_page(page); /* balloon reference */
}
}
--
MST
^ 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