Received: by 2002:a05:6a10:6d10:0:0:0:0 with SMTP id gq16csp2673365pxb; Sun, 24 Apr 2022 23:02:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxhCw1aHfEbu8bsUuwRlVdxelWou1rDy0/DY+VrA+ZqsYVkW0C4jsTYPKenp7oZldKuppJe X-Received: by 2002:a17:903:40c5:b0:15d:1f27:5e2c with SMTP id t5-20020a17090340c500b0015d1f275e2cmr1235650pld.141.1650866528963; Sun, 24 Apr 2022 23:02:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1650866528; cv=none; d=google.com; s=arc-20160816; b=flhRcFtuUmehDJsY/2iguxrevW3nwcspFSlzk36adHXhnzkfGvjDFLWSPmI1tyyGBq xYJiPy/KOtQX2ZlIzb681Fe0sqkTORJy4BK6C+8fax5jY2m8trpsQ6PtBtYzcKOTI2aa EPJBdhzYPnjeHvPhL35ABpjGCL4Bst1ITK8pgDCAIicUEB3JVtEIcqThH4hye/+xPGuQ +Mpt3UpJFj5MxW/NfOkaBoV6eMwVuZ9C8b1NHAcQ9Wwsn4O3pOFdhnBn8i3rNlrq/6ec QunZjXNRb8DGZe9aRaTmQwqCHry32SBQxqBzrC8zqeBFH7uvfyfqD93emjUvpoH8wUx2 I8lw== 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=227dRco3LciEMlYpAOelI9La2vayTwzPn6lkq/Y4WKA=; b=QMPY2nJefZn2XCSxO8M7wkbk+TOA4dk/133zmmDCNoji+8QAGkj28z/X2DqSid8cf2 1y0x6H90dv41/xwq8dTHGOq4itZ2iNw1aUCAQwR14TlRh51QIb+cs+ZdI++q1aFAGk2u T2pk73hNkpDPfebQRaRYkXERrFOq1AD/nvotHP3ucDp27yRyoaSgLVk9XsSma/8NDVFK L1dNkAjw4JjQwP+o7oijXAgq0IuCIiQwSiTD+dg+LG3SPc6/0OfuNo1+VueJlN0cODpN LWTa8OWYlXun9cCoHbmv6yz8aTV5Qs5/8Z6g1c5f0Tka4/2HyFw2ZD3Rn1RvTqDe0QcP lvJg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=S19VNlsQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y5-20020a17090a1f4500b001ca97924abdsi14590870pjy.115.2022.04.24.23.01.53; Sun, 24 Apr 2022 23:02:08 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=S19VNlsQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S240553AbiDYCty (ORCPT + 99 others); Sun, 24 Apr 2022 22:49:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37858 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240505AbiDYCtX (ORCPT ); Sun, 24 Apr 2022 22:49:23 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3E17869290 for ; Sun, 24 Apr 2022 19:46:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1650854769; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=227dRco3LciEMlYpAOelI9La2vayTwzPn6lkq/Y4WKA=; b=S19VNlsQq5VUeGC/qwbMpS72xzQG5SqLwN6rx4oLFQlZZrw1TvA96wXKkSQx+Zj6AZ5cQb W3QH1uHhmYH2Uo+EIQwriZJMo2e1n6vkh1Ikml+ga6X6ou2IE/p8UEpX8aScV0yZPnDjWl o4XxACl6QGq9kDnaum1DgwBprrldz4c= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-653-knYGpcPIMFW66DIkLynGAw-1; Sun, 24 Apr 2022 22:46:04 -0400 X-MC-Unique: knYGpcPIMFW66DIkLynGAw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 248AB82A682; Mon, 25 Apr 2022 02:46:03 +0000 (UTC) Received: from localhost.localdomain (ovpn-13-160.pek2.redhat.com [10.72.13.160]) by smtp.corp.redhat.com (Postfix) with ESMTP id A91C97B7C; Mon, 25 Apr 2022 02:45:54 +0000 (UTC) From: Jason Wang To: jasowang@redhat.com, mst@redhat.com, linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: sgarzare@redhat.com, eperezma@redhat.com, lulu@redhat.com, tglx@linutronix.de, peterz@infradead.org, paulmck@kernel.org, maz@kernel.org, pasic@linux.ibm.com, cohuck@redhat.com Subject: [PATCH V3 8/9] virtio: harden vring IRQ Date: Mon, 25 Apr 2022 10:44:17 +0800 Message-Id: <20220425024418.8415-9-jasowang@redhat.com> In-Reply-To: <20220425024418.8415-1-jasowang@redhat.com> References: <20220425024418.8415-1-jasowang@redhat.com> MIME-Version: 1.0 Content-type: text/plain Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This is a rework on the previous IRQ hardening that is done for virtio-pci where several drawbacks were found and were reverted: 1) try to use IRQF_NO_AUTOEN which is not friendly to affinity managed IRQ that is used by some device such as virtio-blk 2) done only for PCI transport The vq->broken is re-used in this patch for implementing the IRQ hardening. The vq->broken is set to true during both initialization and reset. And the vq->broken is set to false in virtio_device_ready(). Then vring_interrupt can check and return when vq->broken is true. And in this case, switch to return IRQ_NONE to let the interrupt core aware of such invalid interrupt to prevent IRQ storm. The reason of using a per queue variable instead of a per device one is that we may need it for per queue reset hardening in the future. Note that the hardening is only done for vring interrupt since the config interrupt hardening is already done in commit 22b7050a024d7 ("virtio: defer config changed notifications"). But the method that is used by config interrupt can't be reused by the vring interrupt handler because it uses spinlock to do the synchronization which is expensive. Cc: Thomas Gleixner Cc: Peter Zijlstra Cc: "Paul E. McKenney" Cc: Marc Zyngier Cc: Halil Pasic Cc: Cornelia Huck Signed-off-by: Jason Wang --- drivers/virtio/virtio.c | 15 ++++++++++++--- drivers/virtio/virtio_ring.c | 11 +++++++---- include/linux/virtio_config.h | 12 ++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 8dde44ea044a..f575df1f85d0 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -220,6 +220,15 @@ static int virtio_features_ok(struct virtio_device *dev) * */ void virtio_reset_device(struct virtio_device *dev) { + /* + * The below virtio_synchronize_cbs() guarantees that any + * interrupt for this line arriving after + * virtio_synchronize_vqs() has completed is guaranteed to see + * driver_ready == false. + */ + virtio_break_device(dev, true); + virtio_synchronize_cbs(dev); + dev->config->reset(dev); } EXPORT_SYMBOL_GPL(virtio_reset_device); @@ -428,6 +437,9 @@ int register_virtio_device(struct virtio_device *dev) dev->config_enabled = false; dev->config_change_pending = false; + INIT_LIST_HEAD(&dev->vqs); + spin_lock_init(&dev->vqs_list_lock); + /* We always start by resetting the device, in case a previous * driver messed it up. This also tests that code path a little. */ virtio_reset_device(dev); @@ -435,9 +447,6 @@ int register_virtio_device(struct virtio_device *dev) /* Acknowledge that we've seen the device. */ virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); - INIT_LIST_HEAD(&dev->vqs); - spin_lock_init(&dev->vqs_list_lock); - /* * device_add() causes the bus infrastructure to look for a matching * driver. diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 6da13495a70c..12f5fe2ee8ef 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1690,7 +1690,7 @@ static struct virtqueue *vring_create_virtqueue_packed( vq->we_own_ring = true; vq->notify = notify; vq->weak_barriers = weak_barriers; - vq->broken = false; + vq->broken = true; vq->last_used_idx = 0; vq->event_triggered = false; vq->num_added = 0; @@ -2136,8 +2136,11 @@ irqreturn_t vring_interrupt(int irq, void *_vq) return IRQ_NONE; } - if (unlikely(vq->broken)) - return IRQ_HANDLED; + if (unlikely(vq->broken)) { + dev_warn_once(&vq->vq.vdev->dev, + "virtio vring IRQ raised before DRIVER_OK"); + return IRQ_NONE; + } /* Just a hint for performance: so it's ok that this can be racy! */ if (vq->event) @@ -2179,7 +2182,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index, vq->we_own_ring = false; vq->notify = notify; vq->weak_barriers = weak_barriers; - vq->broken = false; + vq->broken = true; vq->last_used_idx = 0; vq->event_triggered = false; vq->num_added = 0; diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 14fe89ff99c7..3e2bc8aff51e 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h @@ -255,6 +255,18 @@ void virtio_device_ready(struct virtio_device *dev) unsigned status = dev->config->get_status(dev); BUG_ON(status & VIRTIO_CONFIG_S_DRIVER_OK); + + /* + * The virtio_synchronize_cbs() makes sure vring_interrupt() + * will see the driver specific setup if it sees vq->broken + * as false. + */ + virtio_synchronize_cbs(dev); + virtio_break_device(dev, false); + /* + * The transport is expected ensure the visibility of + * vq->broken before setting VIRTIO_CONFIG_S_DRIVER_OK. + */ dev->config->set_status(dev, status | VIRTIO_CONFIG_S_DRIVER_OK); } -- 2.25.1