From nobody Sun May 12 17:56:15 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=epam.com ARC-Seal: i=1; a=rsa-sha256; t=1689036430; cv=none; d=zohomail.com; s=zohoarc; b=QFLUP52by/gXhN8nXqRFgzcz4upVnMM3o3cCzTFktFqhW6KDIEn0nzuWG4fNLINNinDukX60NVP0vizPQUjvd1soT8/Q3txovvkkeEOUwIEThxlKegD554hy99S1KrEg/30qomkhM6502m+tpFQFN8THtZtbuXU1XwNuvG0tqL4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1689036430; h=Content-ID:Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=Oq7MAyYNyIyiERDgN5/HwhrVdFHh73QKIalzw9eg63s=; b=nEHh3Dh/zPrU44NFmzwKs6xJbbK7CYoiiUr8KEbyJ07dbFEU5K4wNr7eAjuC/cqq/2j6PhH8B/yojua33I/G/hDqs0+Tbm5PKZigyKDzhcMwgO9fn17Znq2FtpVAKCqMwxAn1F7brXHacwOZIP4lJy3BYqRgGunaZFqhnToH5Ak= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1689036430812662.6235237326513; Mon, 10 Jul 2023 17:47:10 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.561504.877929 (Exim 4.92) (envelope-from ) id 1qJ1WK-0001ld-C6; Tue, 11 Jul 2023 00:46:24 +0000 Received: by outflank-mailman (output) from mailman id 561504.877929; Tue, 11 Jul 2023 00:46:24 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qJ1WK-0001lW-9F; Tue, 11 Jul 2023 00:46:24 +0000 Received: by outflank-mailman (input) for mailman id 561504; Tue, 11 Jul 2023 00:46:23 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qJ1WI-0001lQ-Tx for xen-devel@lists.xenproject.org; Tue, 11 Jul 2023 00:46:23 +0000 Received: from mx0b-0039f301.pphosted.com (mx0b-0039f301.pphosted.com [148.163.137.242]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 59e3902f-1f84-11ee-b239-6b7b168915f2; Tue, 11 Jul 2023 02:46:20 +0200 (CEST) Received: from pps.filterd (m0174681.ppops.net [127.0.0.1]) by mx0b-0039f301.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 36AG006M009547; Tue, 11 Jul 2023 00:46:09 GMT Received: from eur05-am6-obe.outbound.protection.outlook.com (mail-am6eur05lp2111.outbound.protection.outlook.com [104.47.18.111]) by mx0b-0039f301.pphosted.com (PPS) with ESMTPS id 3rrbn9unxr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Jul 2023 00:46:08 +0000 Received: from VI1PR03MB3710.eurprd03.prod.outlook.com (2603:10a6:803:31::18) by DB9PR03MB7193.eurprd03.prod.outlook.com (2603:10a6:10:227::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6565.30; Tue, 11 Jul 2023 00:46:05 +0000 Received: from VI1PR03MB3710.eurprd03.prod.outlook.com ([fe80::c192:26de:9053:ab05]) by VI1PR03MB3710.eurprd03.prod.outlook.com ([fe80::c192:26de:9053:ab05%6]) with mapi id 15.20.6565.028; Tue, 11 Jul 2023 00:46:04 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 59e3902f-1f84-11ee-b239-6b7b168915f2 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=bJPJYcqxTCFVvHGHGvIiaYFGlyRS5xWVzdFnALeaLMbYD2O2wuJGP+H8axavqMQE9w2jX0H9P1UpwHA6k/EGVWd52lA5pQKnA4sFS2sp/tBjSG/ZHJ7A2dRjXHIdjyNAwqHBldROZhG4nlbhJULfSXGO+tFYcvAO3mtHdvp9rp47kJfVHKfrLxspCXyZYF7YaNW016UHM+6Y7fAtdqFYH365ogdL2qtLvJ9CojGbvAIsT5PhP9cdYfW0wgWoHW9fhooOXmWRdESuwOZD4v0azCI6DUj62OVcHg7HSMoOkNnel4Y9iwukNMQP/P6WOlkvBLYWVaeNGN4qDdsQ50WNvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Oq7MAyYNyIyiERDgN5/HwhrVdFHh73QKIalzw9eg63s=; b=JeNcy17B76YEwFSEQ5yGmEVQ77ujrMtzJCLKHmathUF/GJsTe9ZBVK0/K9qGGZjaaHlmh4fUfFLWf8tyaZCUOOmR9DauLBvbQ9hMFEl967gf63xqDJr7yGJHBIdl9E20MFA3ZRtVdNpeqRzvXtJKRL0gTYxNFFKFmjY8H0y2lXiQBaBeA0LaySSygy/MeTsojMGzrP4zuNrOaIljTPNkOQNWPZty1+b2NTJ0P2GheUHJo89tk44/v5Xvz9UvJWqo1eIh+Cfalx/yLzcmw4abBlfCpnov5YDM3KsL06PCSZm6NSDDZN3gfL+JgOnMUX+9ODPlifEQksqayU9QlPAplA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=epam.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Oq7MAyYNyIyiERDgN5/HwhrVdFHh73QKIalzw9eg63s=; b=cdRPTxIbiEFWjM19eB/RGnpHpGCkWp5sFnRhMZaUeP+8ACqLbHbQKcHcOLYPiPt1GuSj46knPBd5Ut9FerGsIi8wOW5/g9vWoMB5Re1J+VW1FQkZqSFrjQZ8ArQs/RWXTkRjP/iPljZvWiqWQLzOMEnJotPbHzhfgyGb1iyU3gQbdWwS7GCe4MW+qJLKxrSRGfVl0KFwkT28Ype9TrY8BWMLwQbl6hqOFUoTwhdSt5sluZGbHVd8IV3wFeTq4pDh6n+pustIG3epBFzDfgDG1QtMd3PAbFc60YuPo5aTRaZ6ka0/OjRZK52T2Y3NzHL+OaPatKhGTsgZdxW6lzMT1Q== From: Volodymyr Babchuk To: "xen-devel@lists.xenproject.org" CC: Volodymyr Babchuk , Jan Beulich , Andrew Cooper , =?utf-8?B?Um9nZXIgUGF1IE1vbm7DqQ==?= , Wei Liu , George Dunlap , Julien Grall , Stefano Stabellini , Jun Nakajima , Kevin Tian , Paul Durrant , Oleksandr Tyshchenko , Oleksandr Andrushchenko Subject: [RFC PATCH] pci: introduce per-domain PCI rwlock Thread-Topic: [RFC PATCH] pci: introduce per-domain PCI rwlock Thread-Index: AQHZs5ESsjHhLtlMU0qzCbDGds6cOw== Date: Tue, 11 Jul 2023 00:46:04 +0000 Message-ID: <20230711004537.888185-1-volodymyr_babchuk@epam.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-mailer: git-send-email 2.41.0 x-ms-publictraffictype: Email x-ms-traffictypediagnostic: VI1PR03MB3710:EE_|DB9PR03MB7193:EE_ x-ms-office365-filtering-correlation-id: e1b96924-a563-4e8f-98b6-08db81a834bf x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: YjVXgUF16h9tQ7lIrxSeOcM5UsWLVJjSUAj/NpbRA56uzyLSkUMxV/9w96lVcQpEgyQDWtdBYlFSDlMpRUteib71etnsyD5Hegmkboe7gUwMjsSs0/zamG/cRDcpuoonqzqKtSSpoDHk6hohx2UkyJcp7GAdhB/X11ZxIcsRJDQfMzqI+9f/Nibi8bTJYGaN3DMhbYMDweqzA4umDCcT1RQQlWvc0c/sRi/9HPfzUybbIF0SW4xqpGxHuG0QzH0FPk5ygfQWgzbsd8PrmQEp+IpYGOgu2u13cd5WK0rfIbEFKGb4d8iOXVDvgRMbFsGw3I+W5g1NVGe3SoLFHUfwK2JOFVgEt2YTGGgZLIBmfRqbsjaKkRrGxYqqZof4tSGCkGDX6OgpuAQSeggLQPYBb0gMj5RWZrhJf9EUnxowku3yu5exWPtL52/kMbEW/R4sePpBY5OJSD6+s7etOJAfQtlkcCqVRq+fI6Gzwe7kuytcFlwHeLsNLjMthSeXRPpPaoUXUjoEGDDTY6s5IUby1snKaXwtIgu/YKWoLBiPA9xDlLBS6SqzajaQyqUUfh/AJcLW78QjOHDuUdxNM/ot5s9aqOKmgRFNYzdmrGIcEdJJwbAoK/NlRXTptwmUtuskwfe+WMB6gNHDDeFkdw5Itw== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:VI1PR03MB3710.eurprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230028)(4636009)(376002)(346002)(39860400002)(366004)(396003)(136003)(451199021)(186003)(6506007)(26005)(1076003)(55236004)(2616005)(6512007)(107886003)(83380400001)(64756008)(41300700001)(4326008)(30864003)(66446008)(66556008)(5660300002)(2906002)(7416002)(316002)(8936002)(8676002)(66476007)(6916009)(66946007)(478600001)(6486002)(76116006)(71200400001)(91956017)(54906003)(36756003)(122000001)(38070700005)(38100700002)(86362001)(357404004);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?utf-8?B?VER5cU9nZE1GT0FqRkE1c3pOKzZ1MEFrd0FWdC9RRW9sYmF6bEVaSjNrbXBs?= =?utf-8?B?Y3lVYjFMVFR5YmQ5R2RRMW9lRnEyUXA3di8rakw2cjNjRHpWUkJyMUdCWUcy?= =?utf-8?B?K1hXcjk0dU9tYmg2S0swTWZwZC9GQ3VNWng2UGZpYnNLaFBFVWhuNkdCRkk4?= =?utf-8?B?d290S25JTk56VE5Bb1Bqck93S0xBZGJoQ3pjR1NTWjVRQWJvbmdKcXBURDNa?= =?utf-8?B?Qm1hV0VtMzlPNGFyUTVVV0I0YUg2amtsWC9DTE13Nng5OFJpdWRNSGV3NkxZ?= =?utf-8?B?YnhjK2hQVWJDcXFVZzdMVmJwODREeWpKY29DVzlUV0tNU2NnVGNiMldmVEl4?= =?utf-8?B?OFJCUG9kTTFZWDdiNFljNzVlN2ZLQjBUV0NLaVR4cUZqSU9MZitSNlpidkcx?= =?utf-8?B?dXVTZ25jNWJhc1ErTitJSDI0QXRLeTZLZU9VVnM5enZhampvaDhseFFaNjU2?= =?utf-8?B?bFNDVSt4Rks0Tktzb3VDNEZpTDRVNEJHWE9ZdG5uWVJXODVDNDFubWlBem9r?= =?utf-8?B?YmRFTU1MRitZZ3ZON3lOYitxYUY0b1JBT2orTWgvS3p4UzAzT21pUnZVdndJ?= =?utf-8?B?eHJPSjBlTkdMWkFFQXJISHYwUTRqR1RtRmpmUitiaFNUN1pWL01YK01Od1pq?= =?utf-8?B?NVE5NWljWTZYNHVpOHA4U3NRVzhVRTJVMzB1UW8vandsQWg5QzR4YzRoUDg1?= =?utf-8?B?ajIvaXV5WDNXQzJST2wvMzZmbWdhWllYNy9LV01WMHR0cWV0LzFmdmdyNG04?= =?utf-8?B?MFRQMVpYZmNkcmc1NytVZnFIRk1uaGNaczlRZzN2bTlVTzJPUGxGaWN5OWJm?= =?utf-8?B?ZjlHVVdkdWVTMkdlRkI0TFkxNlFNYUI2eFAvNk9BRzIvWi9jaVlrbGp3TWkv?= =?utf-8?B?YmNWeTh2NXVWdkd0VURlR1c5YXRiS3dZSnFnK1JVNWVnU2hVQ1IwdHF6VGF3?= =?utf-8?B?dFU1TDByOXNQazJZRURZY1ZBeEkwL3ZYVVo3YllxaUJZNzVkMERzcmZ0dkdW?= =?utf-8?B?a2Nmc1BzQVMweWZyWmhUV3NIM2dOT296NkY4VGdabUFhaDRmT05ISnVlRjVZ?= =?utf-8?B?QWdqYis4Tnk3ck15UFM5d3RZaEUzUlQydlNmY3hka3ZvYXM2bG9LaDVkbXRG?= =?utf-8?B?akhycXlmamRrcWlrUkdiWmJhVStEZjc2d1VJT21uaW1kYUkrZnVHUlowV0E5?= =?utf-8?B?SllKbDIxa0xhSTljVjk2R29aeFZHV2l4YmpKUGphRVJYeHhSZ2hObFowL2NQ?= =?utf-8?B?YVgyaWFRQ0VBYm9zUTBFSEJxZVRHaDFWcFkrdGxJK3hBSFN0enk5b1Q2VkpP?= =?utf-8?B?ZlBNaWFhc1h3UEYrT3B2aEFNYy9mamREaXRnV1ZWMWxuSnk5NG50OVhVSjlS?= =?utf-8?B?RnpnbmtyVVJhYVBIaGFpMUc5V2NMR1laMnVIWExCdVZZdFlkMVhIRFBub0ox?= =?utf-8?B?Nks1ckpySldNM2l3eFh3WVg0MmVJS0IxR2s4c3lUVWJFMjB2bDE2eDhJRngv?= =?utf-8?B?REZLMHc2RVc5dnBvZ3RmN000RmVScTRUM1drUUlyQ0xQWnNWS3pJSS9Xb1hI?= =?utf-8?B?c2oyek5UcWEyZzBvaFl0NDNpV213TWN4blRSc2lWWXZkdnZsR3B1THNHTGw4?= =?utf-8?B?UTVxUzNxcy9hTEhMcW90YXdHT0VYUlRmTG9pZHB6VDRtUXJaOUtLcU9jK210?= =?utf-8?B?R3R0NkZMaVN6cGRhU1JPQXVaazdMYjFDblhkaHVUbWpFazBLNGRjYlJOME44?= =?utf-8?B?cUlZb3dFS0tsTGkrckVtb0VNa1Z5RWpTQWU3YllSMXltc1V4dEhwUW13bncz?= =?utf-8?B?dENiZG9QNlZzZTg2OHlpRnhOTVJRcXJSanFLNVdRN1Y2OHRJcE14R0lmMUFB?= =?utf-8?B?U1U4UVFmcjF6NEZMSzdNMlFYTVlNRU80OXZCaUVvLzBBSzdBNC9OVm1Eek5z?= =?utf-8?B?Rkg0cUs1ckNXSUxsSnY0dG8rQS85NHBwMFcvMW1tTFV0OU1aN01MSHFyMy9B?= =?utf-8?B?a1dJMHFKVHdQUnBPd2UrVGxOWjNxYjNhWFhLOHAzNStYQmlSREJBWUJydmda?= =?utf-8?B?eG0rREhtckZ5V2RBZ0dTdVJwa3FoY2FHTnlMTmFma0s0SDBhMVFFSlZFRGc5?= =?utf-8?B?cUZ6NXFodGFiNTQwTG82VFV5b3pBYkNrY1hwNGNaSElvU2EzSGZDSlBaeXp4?= =?utf-8?B?VFE9PQ==?= Content-Type: text/plain; charset="utf-8" Content-ID: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: epam.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: VI1PR03MB3710.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: e1b96924-a563-4e8f-98b6-08db81a834bf X-MS-Exchange-CrossTenant-originalarrivaltime: 11 Jul 2023 00:46:04.2340 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: b41b72d0-4e9f-4c26-8a69-f949f367c91d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: +kA99Zyl2wv0zTc3ulwJ8f7iYlYWVzQdeBTQQZXhTo/nWgg85Ea7Mm4PIRiSlMg14JDxg5lotw5ELHSTDRKngAVk3X0ww94qK25I4p1P69Q= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR03MB7193 X-Proofpoint-ORIG-GUID: Kj1vvoxhZxKhCnqne2mzUBrbrS5hpoVo X-Proofpoint-GUID: Kj1vvoxhZxKhCnqne2mzUBrbrS5hpoVo X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-07-10_18,2023-07-06_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 bulkscore=0 impostorscore=0 mlxlogscore=999 priorityscore=1501 mlxscore=0 lowpriorityscore=0 malwarescore=0 clxscore=1011 suspectscore=0 adultscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2305260000 definitions=main-2307110004 X-ZohoMail-DKIM: pass (identity @epam.com) X-ZM-MESSAGEID: 1689036432561100001 Add per-domain d->pci_lock that protects access to d->pdev_list. Purpose of this lock is to give guarantees to VPCI code that underlying pdev will not disappear under feet. Later it will also protect pdev->vpci structure and pdev access in modify_bars(). Suggested-by: Roger Pau Monn=C3=A9 Suggested-by: Jan Beulich Signed-off-by: Volodymyr Babchuk --- This patch should be part of VPCI series, but I am posting it as a sinle-patch RFC to discuss changes to x86 MM and IOMMU code. I opted to factor out part of the changes from "vpci: introduce per-domain lock to protect vpci structure" commit to ease up review process. --- xen/arch/x86/hvm/hvm.c | 2 + xen/arch/x86/hvm/vmx/vmcs.c | 2 + xen/arch/x86/mm.c | 6 ++ xen/arch/x86/mm/p2m-pod.c | 7 +++ xen/arch/x86/mm/paging.c | 6 ++ xen/common/domain.c | 1 + xen/drivers/passthrough/amd/iommu_cmd.c | 4 +- xen/drivers/passthrough/amd/pci_amd_iommu.c | 15 ++++- xen/drivers/passthrough/pci.c | 70 +++++++++++++++++---- xen/drivers/passthrough/vtd/iommu.c | 19 +++++- xen/include/xen/sched.h | 1 + 11 files changed, 117 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index a67ef79dc0..089fbe38a7 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2381,12 +2381,14 @@ int hvm_set_cr0(unsigned long value, bool may_defer) } } =20 + read_lock(&d->pci_lock); if ( ((value ^ old_value) & X86_CR0_CD) && is_iommu_enabled(d) && hvm_funcs.handle_cd && (!rangeset_is_empty(d->iomem_caps) || !rangeset_is_empty(d->arch.ioport_caps) || has_arch_pdevs(d)) ) alternative_vcall(hvm_funcs.handle_cd, v, value); + read_unlock(&d->pci_lock); =20 hvm_update_cr(v, 0, value); =20 diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index b209563625..88bbcbbd99 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -1889,6 +1889,7 @@ void cf_check vmx_do_resume(void) * 2: execute wbinvd on all dirty pCPUs when guest wbinvd exits. * If VT-d engine can force snooping, we don't need to do these. */ + read_lock(&v->domain->pci_lock); if ( has_arch_pdevs(v->domain) && !iommu_snoop && !cpu_has_wbinvd_exiting ) { @@ -1896,6 +1897,7 @@ void cf_check vmx_do_resume(void) if ( cpu !=3D -1 ) flush_mask(cpumask_of(cpu), FLUSH_CACHE); } + read_unlock(&v->domain->pci_lock); =20 vmx_clear_vmcs(v); vmx_load_vmcs(v); diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index be2b10a391..f1e882a980 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -858,12 +858,15 @@ get_page_from_l1e( return 0; } =20 + read_lock(&l1e_owner->pci_lock); if ( unlikely(l1f & l1_disallow_mask(l1e_owner)) ) { gdprintk(XENLOG_WARNING, "Bad L1 flags %x\n", l1f & l1_disallow_mask(l1e_owner)); + read_unlock(&l1e_owner->pci_lock); return -EINVAL; } + read_unlock(&l1e_owner->pci_lock); =20 valid =3D mfn_valid(_mfn(mfn)); =20 @@ -2142,12 +2145,15 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgen= try_t nl1e, { struct page_info *page =3D NULL; =20 + read_lock(&pt_dom->pci_lock); if ( unlikely(l1e_get_flags(nl1e) & l1_disallow_mask(pt_dom)) ) { gdprintk(XENLOG_WARNING, "Bad L1 flags %x\n", l1e_get_flags(nl1e) & l1_disallow_mask(pt_dom)); + read_unlock(&pt_dom->pci_lock); return -EINVAL; } + read_unlock(&pt_dom->pci_lock); =20 /* Translate foreign guest address. */ if ( cmd !=3D MMU_PT_UPDATE_NO_TRANSLATE && diff --git a/xen/arch/x86/mm/p2m-pod.c b/xen/arch/x86/mm/p2m-pod.c index 9969eb45fa..07e0bedad7 100644 --- a/xen/arch/x86/mm/p2m-pod.c +++ b/xen/arch/x86/mm/p2m-pod.c @@ -349,10 +349,12 @@ p2m_pod_set_mem_target(struct domain *d, unsigned lon= g target) =20 ASSERT( pod_target >=3D p2m->pod.count ); =20 + read_lock(&d->pci_lock); if ( has_arch_pdevs(d) || cache_flush_permitted(d) ) ret =3D -ENOTEMPTY; else ret =3D p2m_pod_set_cache_target(p2m, pod_target, 1/*preemptible*/= ); + read_unlock(&d->pci_lock); =20 out: pod_unlock(p2m); @@ -1401,8 +1403,13 @@ guest_physmap_mark_populate_on_demand(struct domain = *d, unsigned long gfn, if ( !paging_mode_translate(d) ) return -EINVAL; =20 + read_lock(&d->pci_lock); if ( has_arch_pdevs(d) || cache_flush_permitted(d) ) + { + read_unlock(&d->pci_lock); return -ENOTEMPTY; + } + read_unlock(&d->pci_lock); =20 do { rc =3D mark_populate_on_demand(d, gfn, chunk_order); diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c index 34d833251b..fb8f7ff7cf 100644 --- a/xen/arch/x86/mm/paging.c +++ b/xen/arch/x86/mm/paging.c @@ -205,21 +205,27 @@ static int paging_log_dirty_enable(struct domain *d) { int ret; =20 + read_lock(&d->pci_lock); if ( has_arch_pdevs(d) ) { /* * Refuse to turn on global log-dirty mode * if the domain is sharing the P2M with the IOMMU. */ + read_unlock(&d->pci_lock); return -EINVAL; } =20 if ( paging_mode_log_dirty(d) ) + { + read_unlock(&d->pci_lock); return -EINVAL; + } =20 domain_pause(d); ret =3D d->arch.paging.log_dirty.ops->enable(d); domain_unpause(d); + read_unlock(&d->pci_lock); =20 return ret; } diff --git a/xen/common/domain.c b/xen/common/domain.c index caaa402637..5d8a8836da 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -645,6 +645,7 @@ struct domain *domain_create(domid_t domid, =20 #ifdef CONFIG_HAS_PCI INIT_LIST_HEAD(&d->pdev_list); + rwlock_init(&d->pci_lock); #endif =20 /* All error paths can depend on the above setup. */ diff --git a/xen/drivers/passthrough/amd/iommu_cmd.c b/xen/drivers/passthro= ugh/amd/iommu_cmd.c index 40ddf366bb..b67aee31f6 100644 --- a/xen/drivers/passthrough/amd/iommu_cmd.c +++ b/xen/drivers/passthrough/amd/iommu_cmd.c @@ -308,11 +308,12 @@ void amd_iommu_flush_iotlb(u8 devfn, const struct pci= _dev *pdev, flush_command_buffer(iommu, iommu_dev_iotlb_timeout); } =20 -static void amd_iommu_flush_all_iotlbs(const struct domain *d, daddr_t dad= dr, +static void amd_iommu_flush_all_iotlbs(struct domain *d, daddr_t daddr, unsigned int order) { struct pci_dev *pdev; =20 + read_lock(&d->pci_lock); for_each_pdev( d, pdev ) { u8 devfn =3D pdev->devfn; @@ -323,6 +324,7 @@ static void amd_iommu_flush_all_iotlbs(const struct dom= ain *d, daddr_t daddr, } while ( devfn !=3D pdev->devfn && PCI_SLOT(devfn) =3D=3D PCI_SLOT(pdev->devfn) ); } + read_unlock(&d->pci_lock); } =20 /* Flush iommu cache after p2m changes. */ diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c b/xen/drivers/pass= through/amd/pci_amd_iommu.c index 94e3775506..8541b66a93 100644 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c @@ -102,6 +102,8 @@ static bool any_pdev_behind_iommu(const struct domain *= d, { const struct pci_dev *pdev; =20 + ASSERT(rw_is_locked(&d->pci_lock)); + for_each_pdev ( d, pdev ) { if ( pdev =3D=3D exclude ) @@ -467,17 +469,24 @@ static int cf_check reassign_device( =20 if ( !QUARANTINE_SKIP(target, pdev) ) { + read_lock(&target->pci_lock); rc =3D amd_iommu_setup_domain_device(target, iommu, devfn, pdev); if ( rc ) return rc; + read_unlock(&target->pci_lock); } else amd_iommu_disable_domain_device(source, iommu, devfn, pdev); =20 if ( devfn =3D=3D pdev->devfn && pdev->domain !=3D target ) { - list_move(&pdev->domain_list, &target->pdev_list); - pdev->domain =3D target; + write_lock(&pdev->domain->pci_lock); + list_del(&pdev->domain_list); + write_unlock(&pdev->domain->pci_lock); + + write_lock(&target->pci_lock); + list_add(&pdev->domain_list, &target->pdev_list); + write_unlock(&target->pci_lock); } =20 /* @@ -628,12 +637,14 @@ static int cf_check amd_iommu_add_device(u8 devfn, st= ruct pci_dev *pdev) fresh_domid =3D true; } =20 + read_lock(&pdev->domain->pci_lock); ret =3D amd_iommu_setup_domain_device(pdev->domain, iommu, devfn, pdev= ); if ( ret && fresh_domid ) { iommu_free_domid(pdev->arch.pseudo_domid, iommu->domid_map); pdev->arch.pseudo_domid =3D DOMID_INVALID; } + read_unlock(&pdev->domain->pci_lock); =20 return ret; } diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 07d1986d33..1831e1b0c0 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -454,7 +454,9 @@ static void __init _pci_hide_device(struct pci_dev *pde= v) if ( pdev->domain ) return; pdev->domain =3D dom_xen; + write_lock(&dom_xen->pci_lock); list_add(&pdev->domain_list, &dom_xen->pdev_list); + write_unlock(&dom_xen->pci_lock); } =20 int __init pci_hide_device(unsigned int seg, unsigned int bus, @@ -530,7 +532,7 @@ struct pci_dev *pci_get_pdev(const struct domain *d, pc= i_sbdf_t sbdf) { struct pci_dev *pdev; =20 - ASSERT(d || pcidevs_locked()); + ASSERT((d && rw_is_locked(&d->pci_lock)) || pcidevs_locked()); =20 /* * The hardware domain owns the majority of the devices in the system. @@ -748,7 +750,9 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn, if ( !pdev->domain ) { pdev->domain =3D hardware_domain; + write_lock(&hardware_domain->pci_lock); list_add(&pdev->domain_list, &hardware_domain->pdev_list); + write_unlock(&hardware_domain->pci_lock); =20 /* * For devices not discovered by Xen during boot, add vPCI handlers @@ -887,26 +891,62 @@ static int deassign_device(struct domain *d, uint16_t= seg, uint8_t bus, =20 int pci_release_devices(struct domain *d) { - struct pci_dev *pdev, *tmp; - u8 bus, devfn; - int ret; + int combined_ret; + LIST_HEAD(failed_pdevs); =20 pcidevs_lock(); - ret =3D arch_pci_clean_pirqs(d); - if ( ret ) + write_lock(&d->pci_lock); + combined_ret =3D arch_pci_clean_pirqs(d); + if ( combined_ret ) { pcidevs_unlock(); - return ret; + write_unlock(&d->pci_lock); + return combined_ret; } - list_for_each_entry_safe ( pdev, tmp, &d->pdev_list, domain_list ) + + while ( !list_empty(&d->pdev_list) ) { - bus =3D pdev->bus; - devfn =3D pdev->devfn; - ret =3D deassign_device(d, pdev->seg, bus, devfn) ?: ret; + struct pci_dev *pdev =3D list_first_entry(&d->pdev_list, + struct pci_dev, + domain_list); + uint16_t seg =3D pdev->seg; + uint8_t bus =3D pdev->bus; + uint8_t devfn =3D pdev->devfn; + int ret; + + write_unlock(&d->pci_lock); + ret =3D deassign_device(d, seg, bus, devfn); + write_lock(&d->pci_lock); + if ( ret ) + { + bool still_present =3D false; + const struct pci_dev *tmp; + + /* + * We need to check if deassign_device() left our pdev in + * domain's list. As we dropped the lock, we can't be sure + * that list wasn't permutated in some random way, so we + * need to traverse the whole list. + */ + for_each_pdev ( d, tmp ) + { + if ( tmp =3D=3D pdev ) + { + still_present =3D true; + break; + } + } + if ( still_present ) + list_move(&pdev->domain_list, &failed_pdevs); + combined_ret =3D ret; + } } + + list_splice(&failed_pdevs, &d->pdev_list); + write_unlock(&d->pci_lock); pcidevs_unlock(); =20 - return ret; + return combined_ret; } =20 #define PCI_CLASS_BRIDGE_HOST 0x0600 @@ -1125,7 +1165,9 @@ static int __hwdom_init cf_check _setup_hwdom_pci_dev= ices( if ( !pdev->domain ) { pdev->domain =3D ctxt->d; + write_lock(&ctxt->d->pci_lock); list_add(&pdev->domain_list, &ctxt->d->pdev_list); + write_unlock(&ctxt->d->pci_lock); setup_one_hwdom_device(ctxt, pdev); } else if ( pdev->domain =3D=3D dom_xen ) @@ -1487,6 +1529,7 @@ static int iommu_get_device_group( return group_id; =20 pcidevs_lock(); + read_lock(&d->pci_lock); for_each_pdev( d, pdev ) { unsigned int b =3D pdev->bus; @@ -1501,6 +1544,7 @@ static int iommu_get_device_group( sdev_id =3D iommu_call(ops, get_device_group_id, seg, b, df); if ( sdev_id < 0 ) { + read_unlock(&d->pci_lock); pcidevs_unlock(); return sdev_id; } @@ -1511,6 +1555,7 @@ static int iommu_get_device_group( =20 if ( unlikely(copy_to_guest_offset(buf, i, &bdf, 1)) ) { + read_unlock(&d->pci_lock); pcidevs_unlock(); return -EFAULT; } @@ -1518,6 +1563,7 @@ static int iommu_get_device_group( } } =20 + read_unlock(&d->pci_lock); pcidevs_unlock(); =20 return i; diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/= vtd/iommu.c index 0e3062c820..6a36cc18fe 100644 --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -186,6 +186,8 @@ static bool any_pdev_behind_iommu(const struct domain *= d, { const struct pci_dev *pdev; =20 + ASSERT(rw_is_locked(&d->pci_lock)); + for_each_pdev ( d, pdev ) { const struct acpi_drhd_unit *drhd; @@ -2765,6 +2767,7 @@ static int cf_check reassign_device_ownership( =20 if ( !QUARANTINE_SKIP(target, pdev->arch.vtd.pgd_maddr) ) { + read_lock(&target->pci_lock); if ( !has_arch_pdevs(target) ) vmx_pi_hooks_assign(target); =20 @@ -2780,21 +2783,26 @@ static int cf_check reassign_device_ownership( #endif =20 ret =3D domain_context_mapping(target, devfn, pdev); + read_unlock(&target->pci_lock); =20 if ( !ret && pdev->devfn =3D=3D devfn && !QUARANTINE_SKIP(source, pdev->arch.vtd.pgd_maddr) ) { const struct acpi_drhd_unit *drhd =3D acpi_find_matched_drhd_u= nit(pdev); =20 + read_lock(&source->pci_lock); if ( drhd ) check_cleanup_domid_map(source, pdev, drhd->iommu); + read_unlock(&source->pci_lock); } } else { const struct acpi_drhd_unit *drhd; =20 + read_lock(&source->pci_lock); drhd =3D domain_context_unmap(source, devfn, pdev); + read_unlock(&source->pci_lock); ret =3D IS_ERR(drhd) ? PTR_ERR(drhd) : 0; } if ( ret ) @@ -2806,12 +2814,21 @@ static int cf_check reassign_device_ownership( =20 if ( devfn =3D=3D pdev->devfn && pdev->domain !=3D target ) { - list_move(&pdev->domain_list, &target->pdev_list); + write_lock(&pdev->domain->pci_lock); + list_del(&pdev->domain_list); + write_unlock(&pdev->domain->pci_lock); + + write_lock(&target->pci_lock); + list_add(&pdev->domain_list, &target->pdev_list); + write_unlock(&target->pci_lock); + pdev->domain =3D target; } =20 + read_lock(&source->pci_lock); if ( !has_arch_pdevs(source) ) vmx_pi_hooks_deassign(source); + read_unlock(&source->pci_lock); =20 /* * If the device belongs to the hardware domain, and it has RMRR, don't diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 85242a73d3..80dd150bbf 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -460,6 +460,7 @@ struct domain =20 #ifdef CONFIG_HAS_PCI struct list_head pdev_list; + rwlock_t pci_lock; #endif =20 #ifdef CONFIG_HAS_PASSTHROUGH --=20 2.41.0