Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp244909imm; Tue, 18 Sep 2018 21:00:26 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYfLF+f/yCXdWgEHeWB+Fqw0r+jSaXTYJG0oy5xrIBp1MIFDmqB6M6ezoe+AMmGrK5jIZU6 X-Received: by 2002:a17:902:24e1:: with SMTP id l30-v6mr32403943plg.315.1537329626555; Tue, 18 Sep 2018 21:00:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1537329626; cv=none; d=google.com; s=arc-20160816; b=oiM50DpVoBey/ZOPPs8vXKIjJ0qVzH8MXky6bwah//w+uxrsmKsQmjEO/jBcRCpByC spabHiSY6F974ffaTODMmuQzKn1Opq6dRlVmGr+FGVYqsQBYrhvwjavEFG6dulxGJW+o fkPwynyGWfiMM/9WpFHGiTHgWXT0VPnzi7fv0xak9j5zNkwOIM8ZlUaKrMLXP4d5/3dM E2oAORSbNk3JHV324rVeJRq8qPCf8M5s6IQxTvnHpTrmxcRjeYQSFvzdzchyZTQKkJVo Dnm0h85KSxUZ0vbzsfndajTKOtFQmVUAIi5WnyTseG5RKZUDoxMfHp2mAHmVpT5QsKCR CY1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date; bh=yashrTfKAsOKcRU7PO663QYICy8uZJbtqcfp/yzTQNs=; b=fFMHP7mQV3uw8upm/F/u07rRde7YHwXQT3v4G36qGJE1bGVVZ5zYZMCNt3XR6XnU9H DGZFjD3g7Nzo3GT/LFn/3YDiVK6JdyplIpQf/JQoF+GWqQo5RVzR0eHR75UjoccuKkJR H8qUEXCINrWlB6bdXA+zKYPE6pkJX9v8F58pMTXnR+KtMBFjHDB13qIryB1uZNVW5Wyu AmDVDZmjRWSjEM7ExlR7WMbX8NXFyOxPpIAmwC4taUYjf11I6Wa8V8fipm4uDu00sLfG 9psw9Q0QJ0aKHzzwXkEDIAWL8Nnkhwx4+NlsQa1azuf2mpceknntE3NHaI9aPgRcQHuh 6OTA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 30-v6si19486016pgt.678.2018.09.18.21.00.10; Tue, 18 Sep 2018 21:00:26 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728194AbeISJf4 (ORCPT + 99 others); Wed, 19 Sep 2018 05:35:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39698 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726019AbeISJf4 (ORCPT ); Wed, 19 Sep 2018 05:35:56 -0400 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 22B9E30014B0; Wed, 19 Sep 2018 03:59:59 +0000 (UTC) Received: from t450s.home (ovpn-116-77.phx2.redhat.com [10.3.116.77]) by smtp.corp.redhat.com (Postfix) with ESMTP id 15607308BDA0; Wed, 19 Sep 2018 03:59:58 +0000 (UTC) Date: Tue, 18 Sep 2018 21:59:57 -0600 From: Alex Williamson To: "Raj, Ashok" Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org, Joerg Roedel , Bjorn Helgaas , Gage Eads , Alan Cox Subject: Re: [PATCH] vfio/pci: Some buggy virtual functions incorrectly report 1 for intx. Message-ID: <20180918215957.0d155684@t450s.home> In-Reply-To: <20180912174618.GA19551@araj-mobl1.jf.intel.com> References: <1533843426-79170-1-git-send-email-ashok.raj@intel.com> <20180809134417.50de7fe7@t450s.home> <20180912174618.GA19551@araj-mobl1.jf.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.84 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Wed, 19 Sep 2018 03:59:59 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 12 Sep 2018 10:46:19 -0700 "Raj, Ashok" wrote: > On Thu, Aug 09, 2018 at 01:44:17PM -0600, Alex Williamson wrote: > > On Thu, 9 Aug 2018 12:37:06 -0700 > > Ashok Raj wrote: > > > > > PCI_INTERRUPT_PIN should always read 0 for SRIOV Virtual > > > Functions. > > > > > > Some SRIOV devices have some bugs in RTL and VF's end up reading 1 > > > instead of 0 for the PIN. > > > > Hi Ashok, > > > > One question, can we identify which VFs are known to have this > > issue so that users (and downstreams) can know how to prioritize > > this patch? > > Hi Alex > > Sorry it took some time to hunt this down. > > The offending VF has a device ID : 0x270C > The corresponding PF has a device ID: 0x270B. Ok, I interpret Alan's previous comment about the patch[1] to suggest a structure a bit more like that below. IOW, we know that 8086:270c inspires this change, but once it's included we won't know who else relies on it. We can perhaps encourage better hardware validation, or at least better tracking of who needs this with a warning and whitelist. Testing, especially positive and negative testing against the warning, and reviews welcome. Thanks, Alex [1]https://lkml.org/lkml/2018/8/10/462 commit d780da26a81c6f47522ae0aeff03abd4d08b89b5 Author: Alex Williamson Date: Tue Sep 18 21:27:57 2018 -0600 vfio/pci: Mask buggy SR-IOV VF INTx support The SR-IOV spec requires that VFs must report zero for the INTx pin register as VFs are precluded from INTx support. It's much easier for the host kernel to understand whether a device is a VF and therefore whether a non-zero pin register value is bogus than it is to do the same in userspace. Override the INTx count for such devices and virtualize the pin register to provide a consistent view of the device to the user. As this is clearly a spec violation, warn about it to support hardware validation, but also provide a known whitelist as it doesn't do much good to continue complaining if the hardware vendor doesn't plan to fix it. Known devices with this issue: 8086:270c Signed-off-by: Alex Williamson diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index cddb453a1ba5..8af3f6f35f32 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -430,14 +430,41 @@ static int vfio_pci_open(void *device_data) return ret; } +static const struct pci_device_id known_bogus_vf_intx_pin[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x270c) }, + {} +}; + static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) { if (irq_type == VFIO_PCI_INTX_IRQ_INDEX) { u8 pin; + + if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx) + return 0; + pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin); - if (IS_ENABLED(CONFIG_VFIO_PCI_INTX) && !vdev->nointx && pin) - return 1; + /* + * Per SR-IOV spec rev 1.1, 3.4.1.18 the interrupt pin register + * does not apply to VFs and VFs must implement this register + * as read-only with value zero. Userspace is not readily + * able to identify a device as a VF and thus that the pin + * definition on the device is bogus should a device violate + * this requirement. For such devices, override the bogus + * value and provide a warning to support hardware validation + * (or be quite if it's known). PCI config space emulation + * will virtualize this register for all VFs. + */ + if (pin && vdev->pdev->is_virtfn) { + if (!pci_match_id(known_bogus_vf_intx_pin, vdev->pdev)) + dev_warn_once(&vdev->pdev->dev, + "VF reports bogus INTx pin %d\n", + pin); + return 0; + } + + return pin ? 1 : 0; } else if (irq_type == VFIO_PCI_MSI_IRQ_INDEX) { u8 pos; u16 flags; diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index 62023b4a373b..25130fa6e265 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -1678,7 +1678,8 @@ int vfio_config_init(struct vfio_pci_device *vdev) *(__le16 *)&vconfig[PCI_DEVICE_ID] = cpu_to_le16(pdev->device); } - if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx) + if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx || + pdev->is_virtfn) vconfig[PCI_INTERRUPT_PIN] = 0; ret = vfio_cap_init(vdev);