From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f172.google.com (mail-pf1-f172.google.com [209.85.210.172]) (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 9C23E3859FB for ; Sat, 25 Apr 2026 07:09:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777100966; cv=none; b=D441W8zscxjapk2W4XGE80dhZnW3gR+8JuRPi/4j0nngKXRmSLOhwtDCTkXZ15Acuh9lRTfaKWDSJw9WWsTZDlDWGJi2pQNt6bFvIPUFu9NGW959Ppq0iTZ9/Q9h6b4kNaUidPHTl+VVKiNQHuGpkdNZPqjqLz9RRKb4t0Js4mM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777100966; c=relaxed/simple; bh=cXVnybCCIkpFfhCV7Pv9o+XLIu3aQHhlNZ/DsOTWcmY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nUX2EpSgXJQogcPaAocHv2I09e9lCVnBhUL7hW3nMvr1N1M0ymr144Q2JpLR08YhMYqMkEu+ObqQguA0q8aEkRBoyJHt/HteDbozT4H/1+9iclNeQEPzo3z/0MyZfExYJ27AdBNkYQxXGFzw4mRtiK1NFuiQEAJqcV/9jHfZooc= 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=G/NMWhZX; arc=none smtp.client-ip=209.85.210.172 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="G/NMWhZX" Received: by mail-pf1-f172.google.com with SMTP id d2e1a72fcca58-82f8b60e54dso5763053b3a.2 for ; Sat, 25 Apr 2026 00:09:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777100958; x=1777705758; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5C0AEzedHj5XKUPA0aaKf/p0DN4DYxSicdzohR/x6tU=; b=G/NMWhZX2syc2IPNHYcNwBcbkwwogZCVOguNH4FAcOxmnx3G/ZAxmj/M1gq+/GZ3wU 7qRFRCNNb+HZzZp3yl0wg3loaJySlY1kE8CdMKE4I3I4efKG15QrXBHQ0RjLRAh6GfMw cq/Oe0ghuYiDKpwrgC+BubRXSnqYbSXIRPri+8L+TWPFvxG0/nwJFtETr68HXUtmTN55 HMepm7HhbBK0K+TtiHqVoAir1ZKQS0MiI6301eJkF8U6qaXneofBz7A4oLBohr3EfKy4 W7piKWeHmjYhBbiMf/AfJ/7XqyUbKtYTBC+7csA4myKsuAB+nQiO8R9o9YLPrg/PrelA BjhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777100958; x=1777705758; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=5C0AEzedHj5XKUPA0aaKf/p0DN4DYxSicdzohR/x6tU=; b=hdXnzeqFDjiYCGXKlgmrpxGCtackPWuYCg19GGlt86v2Cq/yGxj2+da0MJ4EjPSjTY P2CoToXj+L4tXNwlBGuFmDzt/6wroLJWtmVigjrUmmRuQTXHUO0ThoYlUjZBzmdiROaw 0mKYLRzLzGdGBEBGIyn7wzWzgXCirGo0jh9RLjrC8Bwb1/VjW/xdmFJVqOgYciOsSGvC x0RCeIPx5CNKVuber0JJ8bSEFd6O4iiMIHblofBYYCJr88NFPntLvyuLEn6p50BJ3ra9 mQOLMyhP6uHxEGo8jPwrjvCLW7gYKBsGci/oO5W6frmPMY+39mCaDamegSkXV7E7pSi/ q4ag== X-Forwarded-Encrypted: i=1; AFNElJ9utibtgvcHvBy0Rb0TwuTI8A/D1DnDgHPfUd4hdqBQ35qniToYOdy5G2Ow/1MzWVxmlkqXtPx42ZYZ43k=@vger.kernel.org X-Gm-Message-State: AOJu0Yy2SLqqL1f6oiSBU/EkXfJjcB8T8vOV79hP7I/jKDeFiT3yUF21 +HIQxzgGpc6DxyLU8MIUFkUqUTGHdCx4qs+0QLuUGCeB29uHy9U6daic X-Gm-Gg: AeBDievAz4nGqqpTUM1n4rT3j+d1n+Y+UivojBarmIxcBAv/3nvijTrMMo3QclcHlar xCDrJP0L66sJc8WXjGxTsKPHGCHjS3otytbsA5c1HlhNP/GJ0Jxm0bdhg9rZydH4QyxrT3w9n+Z YSW6WiABGbkkMB7nwH3tVQTg+QNA6WwYR/qoTiVnI7wE11gv3ERfM8rzaLHq16L0WLKyh2HVgak 9BgbQSAWMKp3CiRbUwOQTwNomBuTjGMnkonsfaC2FNeGA1gWmfCjjNm3hEojob+sIfpd+SV8Nry oeNWAOhEtInvVHQqJKIeRJGa39c5S6ciX+RfW1vFwJLc8aq3bVDHou6cUpHdSRxC1llnWei21H/ d+Zq2jPshradVrteCqGFlAV+jZn7P7oCboL+38GBcy/B+GEmyHX/HShBnCjXKg47wBf3cV184Ex 2cgNOxJOGtShume76uhq+5ClraX0V4Xyv9VIicASe1 X-Received: by 2002:aa7:88cf:0:b0:82a:17b6:53ca with SMTP id d2e1a72fcca58-82f8c92e436mr36926514b3a.38.1777100957728; Sat, 25 Apr 2026 00:09:17 -0700 (PDT) Received: from jia.. ([114.249.134.218]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-82f8ec24850sm26611107b3a.60.2026.04.25.00.09.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 25 Apr 2026 00:09:17 -0700 (PDT) From: physicalmtea To: Peter Hilber Cc: mst@redhat.com, jasowang@redhat.com, xuanzhuo@linux.alibaba.com, eperezma@redhat.com, virtualization@lists.linux.dev, linux-kernel@vger.kernel.org, JiaJia Subject: [PATCH v3] virtio: rtc: tear down old virtqueues before restore Date: Sat, 25 Apr 2026 15:08:40 +0800 Message-Id: <20260425070840.488634-1-physicalmtea@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: JiaJia 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 can run vp_del_vqs() against a newly allocated vp_dev->vqs array while vdev->vqs still contains the old virtqueues. vp_del_vqs() then looks up queue state through the new array and can dereference a NULL info pointer in vp_del_vq(), crashing the guest kernel during restore. This can also happen during a non-faulty reinitialization, when one of the vp_find_vqs_msix() attempts is unsuccessful before a later attempt would succeed. Delete the stale virtqueues before rebuilding them. If restore fails before virtio_device_ready(), reuse the remove path to stop the device. Once the device is ready, return errors directly instead of deleting the virtqueues again. Fixes: 0623c7592768 ("virtio_rtc: Add module and driver core") Signed-off-by: JiaJia Reviewed-by: Peter Hilber --- v3: - Add Fixes tag. - Add Peter's Reviewed-by tag. - Clarify commit message regarding reinitialization scenarios. Apologies for missing the Fixes tag, and thanks for catching that! I've also updated the commit message to include the scenario you mentioned. drivers/virtio/virtio_rtc_driver.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/virtio/virtio_rtc_driver.c b/drivers/virtio/virtio_rtc_driver.c index a57d5e06e..4419735b0 100644 --- a/drivers/virtio/virtio_rtc_driver.c +++ b/drivers/virtio/virtio_rtc_driver.c @@ -1257,6 +1257,15 @@ static int viortc_init_vqs(struct viortc_dev *viortc) return 0; } +static void __viortc_remove(struct viortc_dev *viortc) +{ + struct virtio_device *vdev = viortc->vdev; + + viortc_clocks_deinit(viortc); + virtio_reset_device(vdev); + vdev->config->del_vqs(vdev); +} + /** * viortc_probe() - probe a virtio_rtc virtio device * @vdev: virtio device @@ -1282,7 +1291,7 @@ static int viortc_probe(struct virtio_device *vdev) ret = viortc_init_vqs(viortc); if (ret) - return ret; + goto err_reset_vdev; virtio_device_ready(vdev); @@ -1329,10 +1338,7 @@ static void viortc_remove(struct virtio_device *vdev) { struct viortc_dev *viortc = vdev->priv; - viortc_clocks_deinit(viortc); - - virtio_reset_device(vdev); - vdev->config->del_vqs(vdev); + __viortc_remove(viortc); } static int viortc_freeze(struct virtio_device *dev) @@ -1353,9 +1359,11 @@ static int viortc_restore(struct virtio_device *dev) bool notify = false; int ret; + dev->config->del_vqs(dev); + ret = viortc_init_vqs(viortc); if (ret) - return ret; + goto err_remove; alarm_viortc_vq = &viortc->vqs[VIORTC_ALARMQ]; alarm_vq = alarm_viortc_vq->vq; @@ -1364,7 +1372,7 @@ 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_remove; notify = virtqueue_kick_prepare(alarm_vq); } @@ -1372,8 +1380,12 @@ static int viortc_restore(struct virtio_device *dev) virtio_device_ready(dev); if (notify && !virtqueue_notify(alarm_vq)) - ret = -EIO; + return -EIO; + + return 0; +err_remove: + __viortc_remove(viortc); return ret; } -- 2.34.1