Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp2154868pxb; Mon, 11 Oct 2021 23:55:51 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw7JsjXYmHvn5IF2vf72bOpXiL60OH7tf5uyyZywjW+2ATmo3Fkc+aBo+UHMyoFZmoKzzxb X-Received: by 2002:a17:906:6c8:: with SMTP id v8mr31204152ejb.428.1634021751169; Mon, 11 Oct 2021 23:55:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1634021751; cv=none; d=google.com; s=arc-20160816; b=UlazQDXC8+PHv8gGQYnIbBopMk3kGzDpSHODu4VoqncMlzOv4qxFfIFH3if3ts0TaG oAmV7CtAPTGSrMb2eetpEafYeey+rLp6em9pKgrNwNOy2hjgCf5KTYhtaEQDrW+253I3 fpzvlWsdETGX3ZuC0aMWQcEHLBwICOSOfR7xpI69a/KzOwHf7DNPyMuJj26fRzojoOXA 2GZguliDQWCxoS8va22BeY3RfFfN5hJHiQQDGPXWca/l0r4Pr9QrvGutErZf6rD/AIgz jlj06f1KNAODzcuqDiW4mN0qsSRHVqLkN7I8mED6h92dvUH+uqhQ+Nlc5SdHkiQNw/SG qd+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=g0tYArasr8oWFNs1Jmhkp7snjhybF68hNhg2YnABW1Q=; b=ScUL90vmoOaa/nU+HcHQQNeQs5/A7M1jSxG9pxbAGwhbKNN5uP4HmZd+IV8c074pGc BSEGNwZUqWa2z0tkiWENNMZ1vtEHLic4McuFq6NJRpd9bROPKTFUxlslc57w9CDY0ZER v8biYy48ub/1JQay1D8fUvOpv3UW1dQklVOUlvd2fEsOmT6C7I2rMX6UxW6ZDJk6sADF Zz4OGkVrpwuI8DpQnI6Opp4/aX7bxs3hQUw34WkbjJzDMS3fcsldSl1W/F2c46yw2tyP 7lULIsHop78rRu7qEqyymytQqrlfohgscoIWhOCooMjYP737Q5568mqL2w3B1NB9xYoC SyiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Rcpc8DEw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p1si14406497ejm.741.2021.10.11.23.55.27; Mon, 11 Oct 2021 23:55:51 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Rcpc8DEw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233598AbhJLGza (ORCPT + 99 others); Tue, 12 Oct 2021 02:55:30 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:24910 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233693AbhJLGzX (ORCPT ); Tue, 12 Oct 2021 02:55:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634021602; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g0tYArasr8oWFNs1Jmhkp7snjhybF68hNhg2YnABW1Q=; b=Rcpc8DEwX8hL2emTg3DAbGFKeSCB2iHdnyGtlSQAQl6SeVFiNnecK03zNoF59IkW+ad7Cq c4dg6D6TF9YaUXiWQy9zXKDqIL21SbqfDJXyysHu7yag9plNH3akOKWx+aLvoBWx+/qa0i IHp5aH4GHf/crVupRRen+ZZSfi8UZ10= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-474-q0q7LrV-Moazbaxe_QDSwQ-1; Tue, 12 Oct 2021 02:53:18 -0400 X-MC-Unique: q0q7LrV-Moazbaxe_QDSwQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1FFFD1089A85; Tue, 12 Oct 2021 06:52:54 +0000 (UTC) Received: from localhost.localdomain (ovpn-13-111.pek2.redhat.com [10.72.13.111]) by smtp.corp.redhat.com (Postfix) with ESMTP id A13265F4E6; Tue, 12 Oct 2021 06:52:50 +0000 (UTC) From: Jason Wang To: mst@redhat.com, jasowang@redhat.com Cc: virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, f.hetzelt@tu-berlin.de, david.kaplan@amd.com, konrad.wilk@oracle.com, Thomas Gleixner , Peter Zijlstra , "Paul E . McKenney" Subject: [PATCH V2 06/12] virtio_pci: harden MSI-X interrupts Date: Tue, 12 Oct 2021 14:52:21 +0800 Message-Id: <20211012065227.9953-7-jasowang@redhat.com> In-Reply-To: <20211012065227.9953-1-jasowang@redhat.com> References: <20211012065227.9953-1-jasowang@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We used to synchronize pending MSI-X irq handlers via synchronize_irq(), this may not work for the untrusted device which may keep sending interrupts after reset which may lead unexpected results. Similarly, we should not enable MSI-X interrupt until the device is ready. So this patch fixes those two issues by: 1) switching to use disable_irq() to prevent the virtio interrupt handlers to be called after the device is reset. 2) using IRQF_NO_AUTOEN and enable the MSI-X irq during .ready() This can make sure the virtio interrupt handler won't be called before virtio_device_ready() and after reset. Cc: Thomas Gleixner Cc: Peter Zijlstra Cc: Paul E. McKenney Signed-off-by: Jason Wang --- drivers/virtio/virtio_pci_common.c | 27 +++++++++++++++++++++------ drivers/virtio/virtio_pci_common.h | 6 ++++-- drivers/virtio/virtio_pci_legacy.c | 5 +++-- drivers/virtio/virtio_pci_modern.c | 6 ++++-- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index b35bb2d57f62..0b9523e6dd39 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -24,8 +24,8 @@ MODULE_PARM_DESC(force_legacy, "Force legacy mode for transitional virtio 1 devices"); #endif -/* wait for pending irq handlers */ -void vp_synchronize_vectors(struct virtio_device *vdev) +/* disable irq handlers */ +void vp_disable_vectors(struct virtio_device *vdev) { struct virtio_pci_device *vp_dev = to_vp_device(vdev); int i; @@ -34,7 +34,20 @@ void vp_synchronize_vectors(struct virtio_device *vdev) synchronize_irq(vp_dev->pci_dev->irq); for (i = 0; i < vp_dev->msix_vectors; ++i) - synchronize_irq(pci_irq_vector(vp_dev->pci_dev, i)); + disable_irq(pci_irq_vector(vp_dev->pci_dev, i)); +} + +/* enable irq handlers */ +void vp_enable_vectors(struct virtio_device *vdev) +{ + struct virtio_pci_device *vp_dev = to_vp_device(vdev); + int i; + + if (vp_dev->intx_enabled) + return; + + for (i = 0; i < vp_dev->msix_vectors; ++i) + enable_irq(pci_irq_vector(vp_dev->pci_dev, i)); } /* the notify function used when creating a virt queue */ @@ -141,7 +154,8 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors, snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names, "%s-config", name); err = request_irq(pci_irq_vector(vp_dev->pci_dev, v), - vp_config_changed, 0, vp_dev->msix_names[v], + vp_config_changed, IRQF_NO_AUTOEN, + vp_dev->msix_names[v], vp_dev); if (err) goto error; @@ -160,7 +174,8 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors, snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names, "%s-virtqueues", name); err = request_irq(pci_irq_vector(vp_dev->pci_dev, v), - vp_vring_interrupt, 0, vp_dev->msix_names[v], + vp_vring_interrupt, IRQF_NO_AUTOEN, + vp_dev->msix_names[v], vp_dev); if (err) goto error; @@ -337,7 +352,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, "%s-%s", dev_name(&vp_dev->vdev.dev), names[i]); err = request_irq(pci_irq_vector(vp_dev->pci_dev, msix_vec), - vring_interrupt, 0, + vring_interrupt, IRQF_NO_AUTOEN, vp_dev->msix_names[msix_vec], vqs[i]); if (err) diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h index beec047a8f8d..a235ce9ff6a5 100644 --- a/drivers/virtio/virtio_pci_common.h +++ b/drivers/virtio/virtio_pci_common.h @@ -102,8 +102,10 @@ static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) return container_of(vdev, struct virtio_pci_device, vdev); } -/* wait for pending irq handlers */ -void vp_synchronize_vectors(struct virtio_device *vdev); +/* disable irq handlers */ +void vp_disable_vectors(struct virtio_device *vdev); +/* enable irq handlers */ +void vp_enable_vectors(struct virtio_device *vdev); /* the notify function used when creating a virt queue */ bool vp_notify(struct virtqueue *vq); /* the config->del_vqs() implementation */ diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c index d62e9835aeec..bdf6bc667ab5 100644 --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c @@ -97,8 +97,8 @@ static void vp_reset(struct virtio_device *vdev) /* Flush out the status write, and flush in device writes, * including MSi-X interrupts, if any. */ ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); - /* Flush pending VQ/configuration callbacks. */ - vp_synchronize_vectors(vdev); + /* Disable VQ/configuration callbacks. */ + vp_disable_vectors(vdev); } static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector) @@ -194,6 +194,7 @@ static void del_vq(struct virtio_pci_vq_info *info) } static const struct virtio_config_ops virtio_pci_config_ops = { + .ready = vp_enable_vectors, .get = vp_get, .set = vp_set, .get_status = vp_get_status, diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index 30654d3a0b41..acf0f6b6381d 100644 --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -172,8 +172,8 @@ static void vp_reset(struct virtio_device *vdev) */ while (vp_modern_get_status(mdev)) msleep(1); - /* Flush pending VQ/configuration callbacks. */ - vp_synchronize_vectors(vdev); + /* Disable VQ/configuration callbacks. */ + vp_disable_vectors(vdev); } static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector) @@ -380,6 +380,7 @@ static bool vp_get_shm_region(struct virtio_device *vdev, } static const struct virtio_config_ops virtio_pci_config_nodev_ops = { + .ready = vp_enable_vectors, .get = NULL, .set = NULL, .generation = vp_generation, @@ -397,6 +398,7 @@ static const struct virtio_config_ops virtio_pci_config_nodev_ops = { }; static const struct virtio_config_ops virtio_pci_config_ops = { + .ready = vp_enable_vectors, .get = vp_get, .set = vp_set, .generation = vp_generation, -- 2.25.1