From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C17A2701C4 for ; Fri, 17 Apr 2026 13:50:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.179 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776433808; cv=none; b=OOyTVVU7wqAjNJIDr/nGY4Ur6S5xTRDatiJikpfcVh0nlze0IFZbK3MsBbwNEZhWDDyjVHGKf/Mfyq1gOuxBNe8Rtxs6ZRGunjULkbb1lZvOnKSTJ6GmrfeUPZwerA0oI+na/NcXbfjAUxymLMILU5u7zLv5GqTNpBhB+4tI/Fg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776433808; c=relaxed/simple; bh=fo4xhoC9NzPbZRZBW63KZnbvMyUJGRXLR+fuMV1h24I=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Content-Type; b=jweLwySlEJDKHNWH4jzxVvXprGTF4DxuXArNOmTL2t/XKH9EuRySUB6GI+QVJxAmx1ScVd/vlbY7G4iK4jdR1YfjfHnqVk8xThGvilb76lXN6KZIYoi9pcN7HEHJN/0145aTibuClYGVu6ivAfq7lmnyP5cEAZ9RNbaemS/hv9k= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lye4FkxZ; arc=none smtp.client-ip=209.85.210.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lye4FkxZ" Received: by mail-pf1-f179.google.com with SMTP id d2e1a72fcca58-824c9da9928so396246b3a.3 for ; Fri, 17 Apr 2026 06:50:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776433807; x=1777038607; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=C2i44n+1eaFoKthvoHXkc0Qb+3fUcYde9FhFl3lRY+w=; b=lye4FkxZ1wYPqHnwi+XhS6rAVEUxQT1GE7xzh8CUDJUemmwQ64ZiYWFYY/0Rjhemb/ n71Au4WY7iMtTTvz2u12zWUrVHJAh0QERkMNwg1/lyK8V/d+2llt+6SEMp2inznE2JBv lyIbo75jLAImL3RF0zLDN8SDgQf0hAEuIxmp01v7pB90lxe/X4OcSSH0n1abznTkLO97 RSC/DCqibYJBmD80RmnbC9p/Xm2w0qrZDpHWg9BhxNOSMI74Z8+PduoioHAeyia4a9Vl 3CWwIUlLysGlJL0DVR5L+svRmc5oj2F6HPbYLiFd5SUrO7sc5RiHiOkK+BL0vCFo/dW8 yxgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776433807; x=1777038607; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=C2i44n+1eaFoKthvoHXkc0Qb+3fUcYde9FhFl3lRY+w=; b=Mps4USvu7xvjALiDTEUng+LKspCi4TCCNG0uFr4jrHgeuG03fqPr8Az8ZaoceY2NQC B3EsEaoVJyIGSjtomsTNabzNrFvL/r88jBPDVXRnSfCTu00DEAOamK+OHkJiFp4PSjPh 6CaZnArbM6cCJEU4N5WcqF98t5uKHRlXstRIujk24GXThu2YBpLanALILTgS4zWkKKaF I20e0y27J81wwaUJPIFU1qHoEamAOywinIX4ygf/0u++qY0phMhYkeVEVlWplY7VzIWT Tu3H6v0N1tAlHquYWHk8ZSxzZ3EodDzTaCFUrgFCtQ6+5WBUxGZq41o1jba8QuhNsDTm ycRw== X-Forwarded-Encrypted: i=1; AFNElJ9HVrLZIt+2kV59ZaqnuxvJwKStsupr0DwULr7iP0ec22DDo4TuMaVHKsYajQHj97JjYgbxut2/l8AVTAQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzaW45yizNorzFeHlN/jhap6eXTpYirWEY4aEWLpeadm47F8GdI st8aoHrOrQL9EowPGW1To6G9hQYwMiEZyrnUoT3leqcMm0Srez21UsH9 X-Gm-Gg: AeBDieuk2X89DBZ6YkWtACwqIZ4qegRSVzoZhnsbklNpzhW+D7LTQG4SiDSaVpqODsV PJBvFOvs4pVYKNnBjjvp74uKlgdOHC8pbXdsNv9O9sExi3/3SVBz2eMpXahV1f9odeF63Qm5a+t jMVUW9J0lH+vZap3NwrF+sNyyyyANI91ZuZsattz7X6IRvlibpy/81tJmPe1UXvG4Mj9nVHhl5d FKFcT7En7mNhdNkVn3kDLvt//uCp/W6RW6GKGnsgI5qkYfcRbCOXnYSnt3h5qRnmmk3KEmFKB7r xjqaEeSDE79qiTCtZI1eT8Ky2se2R+iQUPu1CWtd2npysNFDUdMlrOGxo5rW+HyiLvmHuxCCYs+ SCbY54AzELEKy3RlO+++lxLMW+oV25xGE26z7uw5VoQvpGcG8xWL1cfDD1ubObvZkk+wfnMmfDQ lQ29vuOQJdW5FNcQZ9tZjR8spyZXT06GedknhPRg0s+JeY4NB7Sw== X-Received: by 2002:a05:6a00:148e:b0:82c:9cd2:fee5 with SMTP id d2e1a72fcca58-82f8c87e28amr2673000b3a.7.1776433806291; Fri, 17 Apr 2026 06:50:06 -0700 (PDT) Received: from [127.0.1.1] ([188.253.126.210]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-82f8e9d6adbsm2877558b3a.18.2026.04.17.06.50.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Apr 2026 06:50:05 -0700 (PDT) From: JiaJia To: Peter Hilber , Michael S. Tsirkin , Jason Wang Cc: Xuan Zhuo , Eugenio Pérez , virtualization@lists.linux.dev, linux-kernel@vger.kernel.org, JiaJia Subject: [PATCH] virtio: rtc: tear down old virtqueues before restore Date: Fri, 17 Apr 2026 17:08:31 +0800 Message-Id: <20260417214953.793956-1-physicalmtea@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit virtio_device_restore() resets the device and restores the negotiated features before calling ->restore(). viortc_freeze() intentionally leaves the existing virtqueues in place so the alarm queue can still wake the system, but viortc_restore() immediately calls viortc_init_vqs() without first deleting those old queues. If virtqueue reinitialization fails on virtio-pci, the transport error path runs vp_del_vqs() against a new vp_dev->vqs array while vdev->vqs still holds the old virtqueues. vp_del_vqs() then looks up queue state through that new array and can dereference a NULL info pointer in vp_del_vq(), crashing the guest kernel during restore. Delete any old virtqueues before rebuilding them, and clear the cached queue pointers so later message requests fail cleanly if restore does not complete. Signed-off-by: JiaJia --- Runtime evidence from a standard hibernation test_resume run on a guest with virtio-rtc-pci (no fault injection): KASAN null-ptr-deref report in vp_del_vq.isra.0+0x70/0xd0 Call trace: vp_del_vq.isra.0+0x70/0xd0 vp_del_vqs+0xec/0x358 vp_find_vqs_msix+0x24c/0x6a8 vp_find_vqs+0x88/0x360 vp_modern_find_vqs+0x20/0x90 viortc_init_vqs+0xd0/0x128 viortc_restore+0x28/0xb8 virtio_device_restore_priv+0x184/0x288 virtio_pci_restore+0x44/0x58 drivers/virtio/virtio_rtc_driver.c | 38 ++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/virtio/virtio_rtc_driver.c b/drivers/virtio/virtio_rtc_driver.c index a57d5e06e..c1adde27d 100644 --- a/drivers/virtio/virtio_rtc_driver.c +++ b/drivers/virtio/virtio_rtc_driver.c @@ -427,6 +427,15 @@ static int viortc_msg_xfer(struct viortc_vq *vq, struct viortc_msg *msg, sg_init_one(out_sg, msg->req, msg->req_size); sg_init_one(in_sg, msg->resp, msg->resp_cap); + if (!vq->vq) { + /* + * Keep runtime interfaces in a safe failed state if restore + * teardown removed the virtqueues. + */ + viortc_msg_release(msg); + return -ENODEV; + } + spin_lock_irqsave(&vq->lock, flags); ret = virtqueue_add_sgs(vq->vq, sgs, 1, 1, msg, GFP_ATOMIC); @@ -478,6 +487,17 @@ static int viortc_msg_xfer(struct viortc_vq *vq, struct viortc_msg *msg, return 0; } +static void viortc_del_vqs(struct viortc_dev *viortc) +{ + struct virtio_device *vdev = viortc->vdev; + unsigned int i; + + vdev->config->del_vqs(vdev); + + for (i = 0; i < ARRAY_SIZE(viortc->vqs); i++) + viortc->vqs[i].vq = NULL; +} + /* * common message handle macros for messages of different types */ @@ -1316,7 +1336,7 @@ static int viortc_probe(struct virtio_device *vdev) err_reset_vdev: virtio_reset_device(vdev); - vdev->config->del_vqs(vdev); + viortc_del_vqs(viortc); return ret; } @@ -1332,7 +1352,7 @@ static void viortc_remove(struct virtio_device *vdev) viortc_clocks_deinit(viortc); virtio_reset_device(vdev); - vdev->config->del_vqs(vdev); + viortc_del_vqs(viortc); } static int viortc_freeze(struct virtio_device *dev) @@ -1353,9 +1373,11 @@ static int viortc_restore(struct virtio_device *dev) bool notify = false; int ret; + viortc_del_vqs(viortc); + ret = viortc_init_vqs(viortc); if (ret) - return ret; + goto err_del_vqs; alarm_viortc_vq = &viortc->vqs[VIORTC_ALARMQ]; alarm_vq = alarm_viortc_vq->vq; @@ -1364,16 +1386,22 @@ static int viortc_restore(struct virtio_device *dev) ret = viortc_populate_vq(viortc, alarm_viortc_vq, VIORTC_ALARMQ_BUF_CAP, false); if (ret) - return ret; + goto err_del_vqs; notify = virtqueue_kick_prepare(alarm_vq); } virtio_device_ready(dev); - if (notify && !virtqueue_notify(alarm_vq)) + if (notify && !virtqueue_notify(alarm_vq)) { ret = -EIO; + goto err_del_vqs; + } + + return ret; +err_del_vqs: + viortc_del_vqs(viortc); return ret; } -- 2.34.1