From patchwork Mon Jan 20 15:42:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 11342451 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E72A66C1 for ; Mon, 20 Jan 2020 15:43:26 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CD568217F4 for ; Mon, 20 Jan 2020 15:43:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CD568217F4 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itZC2-0002Ce-Sa; Mon, 20 Jan 2020 15:42:22 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1itZC0-0002CX-Vq for xen-devel@lists.xenproject.org; Mon, 20 Jan 2020 15:42:21 +0000 X-Inumbo-ID: 7029157a-3b9b-11ea-b995-12813bfff9fa Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 7029157a-3b9b-11ea-b995-12813bfff9fa; Mon, 20 Jan 2020 15:42:18 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 2EF3DB15F; Mon, 20 Jan 2020 15:42:17 +0000 (UTC) To: "xen-devel@lists.xenproject.org" From: Jan Beulich Message-ID: <620f37b6-43f2-030e-b259-84a4e9ceb7fc@suse.com> Date: Mon, 20 Jan 2020 16:42:22 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.9.1 MIME-Version: 1.0 Content-Language: en-US Subject: [Xen-devel] [PATCH v2] VT-d: don't pass bridge devices to domain_context_mapping_one() X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Kevin Tian Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" When passed a non-NULL pdev, the function does an owner check when it finds an already existing context mapping. Bridges, however, don't get passed through to guests, and hence their owner is always going to be Dom0, leading to the assigment of all but one of the function of multi- function PCI devices behind bridges to fail. Reported-by: Marek Marczykowski-Górecki Signed-off-by: Jan Beulich Reviewed-by: Roger Pau Monné Reviewed-by: Kevin Tian --- v2: Add comments. --- Note: This was reported as an apparent regression from XSA-302 / -306. So far I haven't been able to figure out how the code would have worked before, i.e. to me it looks like a pre-existing problem. This leaves the risk of the change here papering over another issue. --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1493,18 +1493,28 @@ static int domain_context_mapping(struct if ( find_upstream_bridge(seg, &bus, &devfn, &secbus) < 1 ) break; + /* + * Mapping a bridge should, if anything, pass the struct pci_dev of + * that bridge. Since bridges don't normally get assigned to guests, + * their owner would be the wrong one. Pass NULL instead. + */ ret = domain_context_mapping_one(domain, drhd->iommu, bus, devfn, - pci_get_pdev(seg, bus, devfn)); + NULL); /* * Devices behind PCIe-to-PCI/PCIx bridge may generate different * requester-id. It may originate from devfn=0 on the secondary bus * behind the bridge. Map that id as well if we didn't already. + * + * Somewhat similar as for bridges, we don't want to pass a struct + * pci_dev here - there may not even exist one for this (secbus,0,0) + * tuple. If there is one, without properly working device groups it + * may again not have the correct owner. */ if ( !ret && pdev_type(seg, bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE && (secbus != pdev->bus || pdev->devfn != 0) ) ret = domain_context_mapping_one(domain, drhd->iommu, secbus, 0, - pci_get_pdev(seg, secbus, 0)); + NULL); break;