From nobody Thu Apr 9 21:52:51 2026 Delivered-To: importer@patchew.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; arc=pass (i=1 dmarc=pass fromdomain=amd.com); dmarc=pass(p=quarantine dis=none) header.from=amd.com ARC-Seal: i=2; a=rsa-sha256; t=1775502765; cv=pass; d=zohomail.com; s=zohoarc; b=ES8PKK+1FpxphAnWNGMwPusbetHl7N56hrQck41ODLfKejqPe2RcxP2FqcQlksuw3/K7fVM69KueiWBg3A40tCO+CM+Wfw2XeYoMZZ9AhTWFzvA3kp2I5xZZ2o9ZqZ0EAZKL+LzBuV64c56UtlXKz06WsxetAlgNdX4a5imgm6c= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1775502765; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ra0J8gfBg1ZPmN06zQ8IQV2sjcgKKaR6kipA1wOf7Yw=; b=d1Qj9Gpl6i+CiODi6Of+YUPxlUEZZp++Elmn7yNFMlAn85fS2U2FXvgOE/dULfsp0ypgBlK9SCrg9NBcVpmT2/Kqg1GxWrpvfz8DZyAqTT/3L5rouKkKUfkQxhMuxwWKceBoIiqSyQUZmddXUoJwsxFopgsIZPq9WlsBPm5XasQ= ARC-Authentication-Results: i=2; 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; arc=pass (i=1 dmarc=pass fromdomain=amd.com); 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 1775502765293453.5724584292898; Mon, 6 Apr 2026 12:12:45 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1274354.1560495 (Exim 4.92) (envelope-from ) id 1w9pN5-0008Mh-P5; Mon, 06 Apr 2026 19:12:27 +0000 Received: by outflank-mailman (output) from mailman id 1274354.1560495; Mon, 06 Apr 2026 19:12:27 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w9pN5-0008Ma-LF; Mon, 06 Apr 2026 19:12:27 +0000 Received: by outflank-mailman (input) for mailman id 1274354; Mon, 06 Apr 2026 19:12:26 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w9pN4-0008MF-7o for xen-devel@lists.xenproject.org; Mon, 06 Apr 2026 19:12:26 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1w9pN3-009Kc1-K4 for xen-devel@lists.xenproject.org; Mon, 06 Apr 2026 21:12:25 +0200 Received: from [10.42.69.5] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69d40582-e002-0a2a0a5209dd-0a2a45058d60-20 for ; Mon, 06 Apr 2026 21:12:25 +0200 Received: from [40.93.198.62] (helo=CY7PR03CU001.outbound.protection.outlook.com) by tlsNG-c201ff.mxtls.expurgate.net with ESMTPS (eXpurgate 4.56.0) (envelope-from ) id 69d40597-3760-0a2a45050019-285dc63ef092-3 for ; Mon, 06 Apr 2026 21:12:24 +0200 Received: from DS7PR03CA0309.namprd03.prod.outlook.com (2603:10b6:8:2b::7) by DS0PR12MB6462.namprd12.prod.outlook.com (2603:10b6:8:c6::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17; Mon, 6 Apr 2026 19:12:18 +0000 Received: from DS1PEPF0001708F.namprd03.prod.outlook.com (2603:10b6:8:2b:cafe::e0) by DS7PR03CA0309.outlook.office365.com (2603:10b6:8:2b::7) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9769.32 via Frontend Transport; Mon, 6 Apr 2026 19:12:18 +0000 Received: from satlexmb08.amd.com (165.204.84.17) by DS1PEPF0001708F.mail.protection.outlook.com (10.167.17.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17 via Frontend Transport; Mon, 6 Apr 2026 19:12:18 +0000 Received: from SATLEXMB03.amd.com (10.181.40.144) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.17; Mon, 6 Apr 2026 14:12:17 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 6 Apr 2026 14:12:17 -0500 Received: from ubuntu (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.17 via Frontend Transport; Mon, 6 Apr 2026 14:12:11 -0500 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" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=amd.com header.i="@amd.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=t1GOYhZ8tP/oqiH0UvNBT0K7kPyIK9ZMqoGeu6FpFzKW9M/rw3bh7wviACN+Jb5XWeMKYve2AqW7zJ1lwm/MBo7MI6uDpTFHPIg7fux/DJ/x5rPBsEN3T+iq5YdPAgsHugQUXLLF/p27OEn3vWvmk44+DT/2xgkmqyEScExnO+OSRWEd9lvNWxLl06ilMUuqLBdF75oKdHibeB6yFq+CQ4jxO7NM83z7u+DqS2t6WrK7rXJ/DdPinX+7xZOpEPmXOedAQJNz65wjy0/S0dxzYKyC3ZXXQaa/DYLQbiq518AJo1jclDwg1T/ZVIiZCL5hel1Y/AzJ1hJIf5ukONJ0SQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=ra0J8gfBg1ZPmN06zQ8IQV2sjcgKKaR6kipA1wOf7Yw=; b=Xvra5h38lFH4ejAL0a9ggRqzbF9jf5/kJHgiJpWPsTpTg4SG0ZWFZGYviIHOmHPKxypArMDdihOzd707YX/l92DeZHW/qzRQuQJLSgtwxwy2eddQtf5UHm/zS8lTQGbUkRszoVcINcjoSbu1qY0v0vguISTmWsY0IPw8k0wNnI9Nq4i7sWG0NyaHjYfAzLbOGgHfWC/I1h+MOs+6YyfDl7JTncw0SXp+SiLHtX++DaGsJOddd8ASUyf2CQV/hCwIc7sqKQsqAqUcIdg81muAmyzfpryU9MzZpHT3SP7dHVYqujPwoJxHbEViKfI0fUgrYYxX4NASk6B7Fs0A5onmEg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ra0J8gfBg1ZPmN06zQ8IQV2sjcgKKaR6kipA1wOf7Yw=; b=j3ItKYMNF0u35UBn8d4soHMY8mEPWtSI6SxImv/xg+PRA7sdBLy52KD6IGU+WwJyqC3rttzuFVyZc+/4DXLE1qZcAAk+PR5hJe92vznco0xWC/2AqTpjhpshWeovjnt3R230CbomGBRT+YqNpylSMdpqKf6XAdDEhtfwr3+1848= X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; 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; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C From: Stewart Hildebrand To: CC: Mykyta Poturai , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , "Julien Grall" , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , "Stewart Hildebrand" , Mykyta Poturai Subject: [PATCH v4 1/4] vpci: Use pervcpu ranges for BAR mapping Date: Mon, 6 Apr 2026 15:11:55 -0400 Message-ID: <20260406191203.97662-2-stewart.hildebrand@amd.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260406191203.97662-1-stewart.hildebrand@amd.com> References: <20260406191203.97662-1-stewart.hildebrand@amd.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: None (SATLEXMB03.amd.com: stewart.hildebrand@amd.com does not designate permitted sender hosts) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS1PEPF0001708F:EE_|DS0PR12MB6462:EE_ X-MS-Office365-Filtering-Correlation-Id: fa5b2dc2-93e2-4b79-286e-08de94106bfa X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|82310400026|36860700016|22082099003|18002099003|56012099003|13003099007; X-Microsoft-Antispam-Message-Info: LdFq5eGKg4P8fg+IDLyDQXwpB/GiiYoz+MSXZtijDN+YZ6KBFXs3IaJo1a9G4fUxD4FjOPFXlhxU0FnQwZAWIpwHQ3xdXj1Zus49dydoMzhyFqoUn6LP9kJl2kBvDkHgsEYvls9YVWsN5OBPA/Q7OV1p8EcaCxC87oim5jMeL418PqACiQdBtCv4lv6pUft+veHwnWUPez0I3+CxAzaRs8hSJPKeJUgFqpoOwYCC92pXwJsC5mkJFO/Vrng7kxsjeK/Ta2JzBnHd6fo/fjLS5mVGsj1HT9LRYEAAVcLO3FyqKjGrr69/NFiuwriGLFahXMDopUXSerxg7FhsY6DF3RHbxKt5gpHSiZ7NavVFZhlnYqpRlqLK44hSYXamQSyCblOmQcgrqNuwvJ+NSnrIriqmIbpBIeHh/NseRFe0x82qaNayRyiJWRcDs1Eb+kZ2YOC3VI1A28CVICBap0AkNz5CdgmAooAt71Cir/cODqlzkuJTLakNCPMIm71fHpvFmEo4gtk1psfFpO+JzPai9GITwbcGoSg8fgDgyzMBbxEkQ/JpByKuCbjPo/WV0I/iwr6BEkMugFa373MIDnajmDosPaWoOUY8PRPDmbQ34e8YFwqUJtVJ+6uiT3IWcB2TjdKybsWZ3uzbvFVpX3BjATzVrkTHkmhy4/pjaaB+lOvdAJ4AGvChCmcWNWYzoiKCYRkdeGNpUsuulI538REdiaun/tQ3jJmZfShlvsCjIMk= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(82310400026)(36860700016)(22082099003)(18002099003)(56012099003)(13003099007);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: +uxT6HA7v7tEkDnHfXeiG84qUZrlP6mWQ5AT6sEZt4UAHyztezm7l6e/JwFLRQQ5R8fjnZS5lFseEK7egxjF+SfnuD9em73GkuTExtmnEP2Lkdxh991pbpgYTIzi4Xk0fdrYxPhIXICSag0ti9sL/Sc8AH8/9wnzDQZocvFaleobSqdAG10IyFkr0bRknT/3If63RTheryU8X8tCHcTZn8lz/87jZsWVWTtOCDQyZ4/X5uai/IR2mf8R7wSAZQUoIeRWjR1UmoGk+hY+qNLYARjEBi+M1GT/FzMYgzFR/FCVUTgai2Mcm1zdrhoVKQ2FTTbjnzYFmC7VE2CK8+VOuE7J/DIos/xNZpgNfmxSjcm7AmYyxK2zAHi11G3Fw4sjGQ5VRiPlXJ3JvsNgjqadp6AS6voHANapLjEckabxIEueaxEmK79Sw0Yfjswgv9Kg X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Apr 2026 19:12:18.4559 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: fa5b2dc2-93e2-4b79-286e-08de94106bfa X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS1PEPF0001708F.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB6462 X-purgate-ID: tlsNG-c201ff/1775502745-3053396F-03571682/0/0 X-purgate-type: clean X-purgate-size: 13875 X-ZohoMail-DKIM: pass (identity @amd.com) X-ZM-MESSAGEID: 1775502767132154100 Content-Type: text/plain; charset="utf-8" From: Mykyta Poturai There is no need to store ranges for each PCI device, as they are only used during the mapping/unmapping process and can be reused for each device. This also allows to avoid the need to allocate and destroy rangesets for each device. Move the rangesets from struct vpci_bar to struct vpci_vcpu and perform (de-)allocation with vcpu (de-)allocation. Introduce RANGESET_DESTROY() macro to free a rangeset and set the pointer to NULL. Amends: 622bdd962822 ("vpci/header: handle p2m range sets per BAR") Signed-off-by: Mykyta Poturai Signed-off-by: Stewart Hildebrand --- It seems a bit awkward to introduce various vpci vcpu alloc/dealloc functions here only to undo most of it in the next patch. Thoughts on folding the next patch into this one? v3->v4: * no change v2->v3: * new patch in this series, borrowed from [1] * add Amends tag * remove unused variable i due to rebasing over 998060dd9101 ("vPCI: move vpci_init_capabilities() to a separate file") * enclose entire struct vpci_vcpu inside #ifdef __XEN__ * s/bar_mem/mem/ * use ARRAY_SIZE * put init/destroy in functions * only allocate for domains with vPCI and idle domain * replace 'if ( !mem ) continue;' with ASSERT v1->v2 (in SR-IOV series [1]): * new patch [1] https://lore.kernel.org/xen-devel/cover.1772806036.git.mykyta_poturai@e= pam.com/T/#t --- xen/common/domain.c | 5 +++ xen/drivers/vpci/header.c | 67 ++++++++++++++------------------------ xen/drivers/vpci/vpci.c | 36 +++++++++++++++++--- xen/include/xen/rangeset.h | 7 ++++ xen/include/xen/vpci.h | 10 ++++-- 5 files changed, 75 insertions(+), 50 deletions(-) diff --git a/xen/common/domain.c b/xen/common/domain.c index bb9e210c2895..5ef7db8f0960 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -455,6 +455,8 @@ static int vcpu_teardown(struct vcpu *v) */ static void vcpu_destroy(struct vcpu *v) { + vpci_vcpu_destroy(v); + free_vcpu_struct(v); } =20 @@ -512,6 +514,9 @@ struct vcpu *vcpu_create(struct domain *d, unsigned int= vcpu_id) if ( arch_vcpu_create(v) !=3D 0 ) goto fail_sched; =20 + if ( vpci_vcpu_init(v) ) + goto fail_sched; + d->vcpu[vcpu_id] =3D v; if ( vcpu_id !=3D 0 ) { diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c index a760d8c32fd6..89dce932f3b1 100644 --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -196,6 +196,7 @@ bool vpci_process_pending(struct vcpu *v) for ( i =3D 0; i < ARRAY_SIZE(header->bars); i++ ) { struct vpci_bar *bar =3D &header->bars[i]; + struct rangeset *mem =3D v->vpci.mem[i]; struct map_data data =3D { .d =3D v->domain, .map =3D v->vpci.cmd & PCI_COMMAND_MEMORY, @@ -203,10 +204,10 @@ bool vpci_process_pending(struct vcpu *v) }; int rc; =20 - if ( rangeset_is_empty(bar->mem) ) + if ( rangeset_is_empty(mem) ) continue; =20 - rc =3D rangeset_consume_ranges(bar->mem, map_range, &data); + rc =3D rangeset_consume_ranges(mem, map_range, &data); =20 if ( rc =3D=3D -ERESTART ) { @@ -224,8 +225,8 @@ bool vpci_process_pending(struct vcpu *v) =20 /* Clean all the rangesets */ for ( i =3D 0; i < ARRAY_SIZE(header->bars); i++ ) - if ( !rangeset_is_empty(header->bars[i].mem) ) - rangeset_purge(header->bars[i].mem); + if ( !rangeset_is_empty(v->vpci.mem[i]) ) + rangeset_purge(v->vpci.mem[i]); =20 v->vpci.pdev =3D NULL; =20 @@ -260,13 +261,14 @@ static int __init apply_map(struct domain *d, const s= truct pci_dev *pdev, for ( i =3D 0; i < ARRAY_SIZE(header->bars); i++ ) { struct vpci_bar *bar =3D &header->bars[i]; + struct rangeset *mem =3D current->vpci.mem[i]; struct map_data data =3D { .d =3D d, .map =3D true, .bar =3D bar }; =20 - if ( rangeset_is_empty(bar->mem) ) + if ( rangeset_is_empty(mem) ) continue; =20 - while ( (rc =3D rangeset_consume_ranges(bar->mem, map_range, - &data)) =3D=3D -ERESTART ) + while ( (rc =3D rangeset_consume_ranges(mem, map_range, &data)) = =3D=3D + -ERESTART ) { /* * It's safe to drop and reacquire the lock in this context @@ -331,13 +333,13 @@ static int modify_bars(const struct pci_dev *pdev, ui= nt16_t cmd, bool rom_only) for ( i =3D 0; i < ARRAY_SIZE(header->bars); i++ ) { struct vpci_bar *bar =3D &header->bars[i]; + struct rangeset *mem =3D current->vpci.mem[i]; unsigned long start =3D PFN_DOWN(bar->addr); unsigned long end =3D PFN_DOWN(bar->addr + bar->size - 1); unsigned long start_guest =3D PFN_DOWN(bar->guest_addr); unsigned long end_guest =3D PFN_DOWN(bar->guest_addr + bar->size -= 1); =20 - if ( !bar->mem ) - continue; + ASSERT(mem); =20 if ( !MAPPABLE_BAR(bar) || (rom_only ? bar->type !=3D VPCI_BAR_ROM @@ -354,7 +356,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) continue; } =20 - ASSERT(rangeset_is_empty(bar->mem)); + ASSERT(rangeset_is_empty(mem)); =20 /* * Make sure that the guest set address has the same page offset @@ -369,7 +371,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) return -EINVAL; } =20 - rc =3D rangeset_add_range(bar->mem, start_guest, end_guest); + rc =3D rangeset_add_range(mem, start_guest, end_guest); if ( rc ) { printk(XENLOG_G_WARNING "Failed to add [%lx, %lx]: %d\n", @@ -380,12 +382,12 @@ static int modify_bars(const struct pci_dev *pdev, ui= nt16_t cmd, bool rom_only) /* Check for overlap with the already setup BAR ranges. */ for ( j =3D 0; j < i; j++ ) { - struct vpci_bar *prev_bar =3D &header->bars[j]; + struct rangeset *prev_mem =3D current->vpci.mem[j]; =20 - if ( rangeset_is_empty(prev_bar->mem) ) + if ( rangeset_is_empty(prev_mem) ) continue; =20 - rc =3D rangeset_remove_range(prev_bar->mem, start_guest, end_g= uest); + rc =3D rangeset_remove_range(prev_mem, start_guest, end_guest); if ( rc ) { gprintk(XENLOG_WARNING, @@ -395,7 +397,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) } } =20 - rc =3D pci_sanitize_bar_memory(bar->mem); + rc =3D pci_sanitize_bar_memory(mem); if ( rc ) { gprintk(XENLOG_WARNING, @@ -412,14 +414,14 @@ static int modify_bars(const struct pci_dev *pdev, ui= nt16_t cmd, bool rom_only) unsigned long end =3D PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + vmsix_table_size(pdev->vpci, i) - 1); =20 - for ( j =3D 0; j < ARRAY_SIZE(header->bars); j++ ) + for ( j =3D 0; j < ARRAY_SIZE(current->vpci.mem); j++ ) { - const struct vpci_bar *bar =3D &header->bars[j]; + struct rangeset *mem =3D current->vpci.mem[j]; =20 - if ( rangeset_is_empty(bar->mem) ) + if ( rangeset_is_empty(mem) ) continue; =20 - rc =3D rangeset_remove_range(bar->mem, start, end); + rc =3D rangeset_remove_range(mem, start, end); if ( rc ) { gprintk(XENLOG_WARNING, @@ -469,8 +471,9 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) for ( j =3D 0; j < ARRAY_SIZE(header->bars); j++) { const struct vpci_bar *bar =3D &header->bars[j]; + struct rangeset *mem =3D current->vpci.mem[j]; =20 - if ( !rangeset_overlaps_range(bar->mem, start, end) || + if ( !rangeset_overlaps_range(mem, start, end) || /* * If only the ROM enable bit is toggled check ag= ainst * other BARs in the same device for overlaps, bu= t not @@ -481,7 +484,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) bar->type =3D=3D VPCI_BAR_ROM) ) continue; =20 - rc =3D rangeset_remove_range(bar->mem, start, end); + rc =3D rangeset_remove_range(mem, start, end); if ( rc ) { gprintk(XENLOG_WARNING, @@ -732,18 +735,6 @@ static void cf_check rom_write( } } =20 -static int bar_add_rangeset(const struct pci_dev *pdev, struct vpci_bar *b= ar, - unsigned int i) -{ - char str[32]; - - snprintf(str, sizeof(str), "%pp:BAR%u", &pdev->sbdf, i); - - bar->mem =3D rangeset_new(pdev->domain, str, RANGESETF_no_print); - - return !bar->mem ? -ENOMEM : 0; -} - int vpci_init_header(struct pci_dev *pdev) { uint16_t cmd; @@ -853,10 +844,6 @@ int vpci_init_header(struct pci_dev *pdev) else bars[i].type =3D VPCI_BAR_MEM32; =20 - rc =3D bar_add_rangeset(pdev, &bars[i], i); - if ( rc ) - goto fail; - rc =3D pci_size_mem_bar(pdev->sbdf, reg, &addr, &size, (i =3D=3D num_bars - 1) ? PCI_BAR_LAST : 0); if ( rc < 0 ) @@ -909,12 +896,6 @@ int vpci_init_header(struct pci_dev *pdev) 4, rom); if ( rc ) rom->type =3D VPCI_BAR_EMPTY; - else - { - rc =3D bar_add_rangeset(pdev, rom, num_bars); - if ( rc ) - goto fail; - } } else if ( !is_hwdom ) { diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c index 0ac9ec8b0475..8e6343653078 100644 --- a/xen/drivers/vpci/vpci.c +++ b/xen/drivers/vpci/vpci.c @@ -24,6 +24,37 @@ =20 #ifdef __XEN__ =20 +void vpci_vcpu_destroy(struct vcpu *v) +{ + unsigned int i; + + if ( !has_vpci(v->domain) && !is_idle_domain(v->domain) ) + return; + + for ( i =3D 0; i < ARRAY_SIZE(v->vpci.mem); i++ ) + RANGESET_DESTROY(v->vpci.mem[i]); +} + +int vpci_vcpu_init(struct vcpu *v) +{ + unsigned int i; + + if ( !has_vpci(v->domain) && !is_idle_domain(v->domain) ) + return 0; + + for ( i =3D 0; i < ARRAY_SIZE(v->vpci.mem); i++ ) + { + char str[32]; + + snprintf(str, sizeof(str), "%pv:BAR%u", v, i); + v->vpci.mem[i] =3D rangeset_new(v->domain, str, RANGESETF_no_print= ); + if ( !v->vpci.mem[i] ) + return -ENOMEM; + } + + return 0; +} + #ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT static int assign_virtual_sbdf(struct pci_dev *pdev) { @@ -89,8 +120,6 @@ struct vpci_register *vpci_get_register(const struct vpc= i *vpci, =20 void vpci_deassign_device(struct pci_dev *pdev) { - unsigned int i; - ASSERT(rw_is_write_locked(&pdev->domain->pci_lock)); =20 if ( !has_vpci(pdev->domain) || !pdev->vpci ) @@ -116,9 +145,6 @@ void vpci_deassign_device(struct pci_dev *pdev) } spin_unlock(&pdev->vpci->lock); =20 - for ( i =3D 0; i < ARRAY_SIZE(pdev->vpci->header.bars); i++ ) - rangeset_destroy(pdev->vpci->header.bars[i].mem); - xfree(pdev->vpci); pdev->vpci =3D NULL; } diff --git a/xen/include/xen/rangeset.h b/xen/include/xen/rangeset.h index 817505badf6f..f01e00ec9234 100644 --- a/xen/include/xen/rangeset.h +++ b/xen/include/xen/rangeset.h @@ -40,6 +40,13 @@ struct rangeset *rangeset_new( void rangeset_destroy( struct rangeset *r); =20 +/* Destroy a rangeset, and zero the pointer to it. */ +#define RANGESET_DESTROY(r) \ + ({ \ + rangeset_destroy(r); \ + (r) =3D NULL; \ + }) + /* * Set a limit on the number of ranges that may exist in set @r. * NOTE: This must be called while @r is empty. diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h index 877aa391d178..b55bacbe6e01 100644 --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -19,6 +19,9 @@ */ #define VPCI_MAX_VIRT_DEV (PCI_SLOT(~0) + 1) =20 +void vpci_vcpu_destroy(struct vcpu *v); +int vpci_vcpu_init(struct vcpu *v); + /* Assign vPCI to device by adding handlers. */ int __must_check vpci_assign_device(struct pci_dev *pdev); =20 @@ -54,7 +57,6 @@ struct vpci { uint64_t guest_addr; uint64_t size; uint64_t resizable_sizes; - struct rangeset *mem; enum { VPCI_BAR_EMPTY, VPCI_BAR_IO, @@ -152,14 +154,15 @@ struct vpci { #endif }; =20 +#ifdef __XEN__ struct vpci_vcpu { /* Per-vcpu structure to store state while {un}mapping of PCI BARs. */ const struct pci_dev *pdev; + struct rangeset *mem[ARRAY_SIZE(((struct vpci_header *)NULL)->bars)]; uint16_t cmd; bool rom_only : 1; }; =20 -#ifdef __XEN__ void vpci_dump_msi(void); =20 /* Arch-specific vPCI MSI helpers. */ @@ -204,6 +207,9 @@ bool vpci_ecam_read(pci_sbdf_t sbdf, unsigned int reg, = unsigned int len, #else /* !CONFIG_HAS_VPCI */ struct vpci_vcpu {}; =20 +static inline void vpci_vcpu_destroy(struct vcpu *v) { } +static inline int vpci_vcpu_init(struct vcpu *v) { return 0; } + static inline int vpci_reinit_ext_capabilities(struct pci_dev *pdev) { return 0; --=20 2.53.0 From nobody Thu Apr 9 21:52:51 2026 Delivered-To: importer@patchew.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; arc=pass (i=1 dmarc=pass fromdomain=amd.com); dmarc=pass(p=quarantine dis=none) header.from=amd.com ARC-Seal: i=2; a=rsa-sha256; t=1775502772; cv=pass; d=zohomail.com; s=zohoarc; b=Fm/qMbM5fQe3oXbBr1GVhhf52uToqK8WcoTTzQpBUDNuErXar/NjKQ7yQhf6JMTl9xo/a5y4BobUXPuGIRWL89BWXmq2aZpB9kkVhoW22vLUyad6G7KK0Quxe2noAkqnhdi7fq9WeEv0g3oBxWns2eBJ8xwYIOXpFnHAQ8/mLu0= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1775502772; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=tdGllGUK8TiRaZWvVqFEsyu4uOoRMu93WYGtX/iLMdg=; b=E6WbX6jOJPeI4VrO1FHtmHFQYYexXxju5kuauMLS1GtwEmMMrMJKtfwNBR8hFKvbra/C5vvDJVW4eEFPdRG4UncxHCnRBolBRk1KycRo/+MlMQ6aeg7iHhJXJcRZ2HzgY3WrHRa6cW0gBBD+eoV/ylrOv30cjyNL12qYQsdgDO0= ARC-Authentication-Results: i=2; 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; arc=pass (i=1 dmarc=pass fromdomain=amd.com); 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 1775502772215598.2583323974337; Mon, 6 Apr 2026 12:12:52 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1274358.1560505 (Exim 4.92) (envelope-from ) id 1w9pNF-0000HY-69; Mon, 06 Apr 2026 19:12:37 +0000 Received: by outflank-mailman (output) from mailman id 1274358.1560505; Mon, 06 Apr 2026 19:12:37 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w9pNF-0000HR-32; Mon, 06 Apr 2026 19:12:37 +0000 Received: by outflank-mailman (input) for mailman id 1274358; Mon, 06 Apr 2026 19:12:35 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w9pND-0000GC-B9 for xen-devel@lists.xenproject.org; Mon, 06 Apr 2026 19:12:35 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1w9pNC-001f2t-NL for xen-devel@lists.xenproject.org; Mon, 06 Apr 2026 21:12:34 +0200 Received: from [10.42.69.8] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69d40580-2eae-0a2a0a5409dd-0a2a4508a27a-44 for ; Mon, 06 Apr 2026 21:12:34 +0200 Received: from [52.101.53.59] (helo=BL0PR03CU003.outbound.protection.outlook.com) by tlsNG-c1860d.mxtls.expurgate.net with ESMTPS (eXpurgate 4.56.0) (envelope-from ) id 69d405a0-fab6-0a2a45080019-3465353b4fad-4 for ; Mon, 06 Apr 2026 21:12:34 +0200 Received: from SJ0PR03CA0225.namprd03.prod.outlook.com (2603:10b6:a03:39f::20) by PH0PR12MB5680.namprd12.prod.outlook.com (2603:10b6:510:146::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17; Mon, 6 Apr 2026 19:12:25 +0000 Received: from SJ5PEPF000001F4.namprd05.prod.outlook.com (2603:10b6:a03:39f:cafe::b8) by SJ0PR03CA0225.outlook.office365.com (2603:10b6:a03:39f::20) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9769.32 via Frontend Transport; Mon, 6 Apr 2026 19:12:25 +0000 Received: from satlexmb07.amd.com (165.204.84.17) by SJ5PEPF000001F4.mail.protection.outlook.com (10.167.242.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17 via Frontend Transport; Mon, 6 Apr 2026 19:12:25 +0000 Received: from satlexmb07.amd.com (10.181.42.216) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 6 Apr 2026 14:12:24 -0500 Received: from ubuntu (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.17 via Frontend Transport; Mon, 6 Apr 2026 14:12:23 -0500 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" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=amd.com header.i="@amd.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=vX/KcJpIrMDz8U5t+WAvcidI3IUiYIxR6xW6GnE7Oc9Um5bbcMH6cEVGhjHATt/dbkkk5mEUFuzdhJjpdiVWyki41cZa5vWxzIiDB54Rub3qdBYnt1XjKANqL6sobEI1631rh75yzQKzwlz82+a4krGoeLHUggxp0O3n7BwNuLbv3dIMtGk9PacS5HQl0N4cojI9yLcmnm4BUp390WbW1gZVcMjMoVCnJsHIRu7n7C8Eb9Mps5J1IuaLMFa0KtVc+LB1sUlon6fQUKHa5F6erIF6D27Rqkd/Qf/PhazXW+Hnmh//LZJiflpI+rpJpcMSBiLk/2jhbN3Al5IV33YhMg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=tdGllGUK8TiRaZWvVqFEsyu4uOoRMu93WYGtX/iLMdg=; b=W9iaZ3XVeboi4gxyZe8c5t31WiM4CIOaUdNzKnavKgoX613V3TVugFUbKw0I+KOHmGCwuBupiczYgE94tnS78YOfTCgf3XOQ53h3HWTGGfcZtXasXtuTSpVFsnSy5ijVOecDkiJHp3gzIL4S//YjAo5/s2L0IBmOMnc/FJ8WXTYsPR8ZGiPs4wsK12rclWIveIyxNUdF5P9w44RYy/EPDr3wv+6kBlZvhLoe+9Cv00ZRNnhkmlVexwJ7Yu5BNzMa2I5T6zPpwKAOC1oDacLoAm8ojMVhM3+AHzYO5a/JvJYbamaoyQ0oxzh8TD63qkPDnNvHFZr9+7skA3Zm713U7A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=tdGllGUK8TiRaZWvVqFEsyu4uOoRMu93WYGtX/iLMdg=; b=0qTb0+uRhafBHRHwVP9nqpl9R/tudSlOewmfMjhHbrxMjdVRYo39x5sV0MlxhfW91WZvZqxdigeZTjhYQ2ouXM7vKce2ayxMWMjxEbBvvY2mfA+x3feJB5o4D1sbw/A6jTRS5sKSteSNwB5MCqKZPtm+b9Bw7OXbLegjDwB6DOo= X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; 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; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C From: Stewart Hildebrand To: CC: Stewart Hildebrand , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , "Julien Grall" , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , "Mykyta Poturai" Subject: [PATCH v4 2/4] vpci: allow queueing of mapping operations Date: Mon, 6 Apr 2026 15:11:56 -0400 Message-ID: <20260406191203.97662-3-stewart.hildebrand@amd.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260406191203.97662-1-stewart.hildebrand@amd.com> References: <20260406191203.97662-1-stewart.hildebrand@amd.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001F4:EE_|PH0PR12MB5680:EE_ X-MS-Office365-Filtering-Correlation-Id: 26a4cc13-f6bd-41fc-fab9-08de9410700c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700016|376014|82310400026|56012099003|18002099003|22082099003; X-Microsoft-Antispam-Message-Info: FC/OqTwKNX2oTpQAloN/lICTIwv/HsgAhl7z3DzZ6VM3eFslz/MijlcOvBf4cWTnLquEFBT9WI84WzP/eWoXEaPwNWjGutv26StfewVIvFuvJGaBRWzra8mHHFNH9g3NM62vxIgUUyJHZybMW3veAAoNh2Jbb8W6OIPSswr2PqSYGa+huDDVrkpqpKjrHnqiZ3v5wDrFE7jldOtnTLjJ6QnDh8e5Z0ZaOkueHIkRHhZIJodlYMFbRvnELqp9/uKH71LvLu8SO9Zjjarm1zlWRE9sg8leGGQVFsN4g4zMvRKQXjGXjw6wXEpsmnC+/Pip1rsBcPXIo6581oGNdsF3LQInMPQakkVjyush0IgAONU9D4Y+qYNND4Bmsb796i7ML8psAe4qWkbsvgByE4Qt8uRgu6XERecptmr9AUB5/r1U9/VQFSzNKisyn8hhhDtb8BBZXkpsFfhWW1lEwxVDVRSnmWBpX/SjT6lEtZhETbKaFMoBBDNvdXNQt5S4FZD4Yyxs/pqBUVP0ZOlEvQRyDcSy7xneKUeoRXmfCRWHmkDT98xnuD3Sv0oeDG/PhQPlQ9AiHmwgBnwht+pLV6g+9dAd291saU0x64YX5MYkKJoApv+hnqcUCepT53jve1wg7EEPZd+yd1DgKdLoSAzHTIiqI/gCyHv/kMEHl289XZAI7ZakvP3GE4zJIOFOGo2Q/xw6kpTjlLvZ3lMOiDV5khxoiURcgSaafadp+YEgMUY= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700016)(376014)(82310400026)(56012099003)(18002099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 3XvrUkjh8W/iUp+zpqbnOR7jk1qqNxFh0P3TE/VBbLTecE55CrOM+SvhH2GK1gQc3swr6BCluTSgLf0BifMfDt8aEevu2jHCGcOaj5qgliFoX2B653MXt/ujf5LodjdqT0EYHp2WycundMAQzqGwsYAGUEnZ0QDJsApKq9YFCfQUntzsiw0F+L9bubrtjZRPLn5wU+Fn6y+jb0B7BltOqUFHBWMh8BFdvH/GblidwYcDg589IMw3nY05WujJG3MgTHyw+a8iX+xGwi+D9cxQcaekp5TiwdsvnqbK/lywVWOrGkhpJMDLruHFaEOhDhHnDV6qtUOSjaCXN8xfXPexTNpDJH9atCSQy08EldURibHM4KjLkWtJpyCwZopuxMVESLGAPPytnzN2MACZA7ipu8Qlg5B+4jlyS/rjiOfmZS4KpVqA7RlAz0E55NM+A7m6 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Apr 2026 19:12:25.2126 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 26a4cc13-f6bd-41fc-fab9-08de9410700c X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SJ5PEPF000001F4.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR12MB5680 X-purgate-ID: tlsNG-c1860d/1775502754-F5B54497-CB89D6D1/0/0 X-purgate-type: clean X-purgate-size: 19758 X-ZohoMail-DKIM: pass (identity @amd.com) X-ZM-MESSAGEID: 1775502775017154100 Content-Type: text/plain; charset="utf-8" Introduce vPCI BAR mapping task queue. Store information needed to map/unmap BARs in struct vpci_map_task. Allow queueing of BAR map/unmap operations in a list, thus making it possible to perform multiple p2m operations associated with single PCI device. This is preparatory work for further changes that need to perform multiple unmap/map operations before returning to guest. At the moment, only a single operation will be queued. However, when multiple operations are queued, there is a check in modify_bars() to skip BARs already in the requested state that will no longer be accurate. Remove this check in preparation of upcoming changes. Signed-off-by: Stewart Hildebrand --- apply_map() and vpci_process_map_task() are very similar. Should we try to combine them into a single function? I concede that the dynamic allocation/deallocation of struct vpci_map_task is not ideal. However, to support SR-IOV, there will be a need to queue many mapping operations (one per VF), and statically pre-allocating that much would seem wasteful. Only the hardware and/or control domain would need to queue many operations, and only when configuring SR-IOV. v3->v4: * switch back to dynamically allocated queue elements v2->v3: * base on ("vpci: Use pervcpu ranges for BAR mapping") from [1] * rework with fixed array of map/unmap slots [1] https://lore.kernel.org/xen-devel/cover.1772806036.git.mykyta_poturai@e= pam.com/T/#t v1->v2: * new patch --- xen/common/domain.c | 5 +- xen/drivers/vpci/header.c | 227 ++++++++++++++++++++++++++----------- xen/drivers/vpci/vpci.c | 30 +---- xen/include/xen/rangeset.h | 7 -- xen/include/xen/vpci.h | 21 ++-- 5 files changed, 179 insertions(+), 111 deletions(-) diff --git a/xen/common/domain.c b/xen/common/domain.c index 5ef7db8f0960..b1931be9870b 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -455,8 +455,6 @@ static int vcpu_teardown(struct vcpu *v) */ static void vcpu_destroy(struct vcpu *v) { - vpci_vcpu_destroy(v); - free_vcpu_struct(v); } =20 @@ -514,8 +512,7 @@ struct vcpu *vcpu_create(struct domain *d, unsigned int= vcpu_id) if ( arch_vcpu_create(v) !=3D 0 ) goto fail_sched; =20 - if ( vpci_vcpu_init(v) ) - goto fail_sched; + vpci_vcpu_init(v); =20 d->vcpu[vcpu_id] =3D v; if ( vcpu_id !=3D 0 ) diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c index 89dce932f3b1..146915e28c50 100644 --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -23,6 +23,7 @@ #include #include #include +#include =20 #include =20 @@ -35,7 +36,7 @@ =20 struct map_data { struct domain *d; - const struct vpci_bar *bar; + const struct vpci_bar_map *bar; bool map; }; =20 @@ -174,32 +175,20 @@ static void modify_decoding(const struct pci_dev *pde= v, uint16_t cmd, ASSERT_UNREACHABLE(); } =20 -bool vpci_process_pending(struct vcpu *v) +static int vpci_process_map_task(const struct pci_dev *pdev, + struct vpci_map_task *task) { - const struct pci_dev *pdev =3D v->vpci.pdev; - struct vpci_header *header =3D NULL; unsigned int i; =20 - if ( !pdev ) - return false; - - read_lock(&v->domain->pci_lock); - - if ( !pdev->vpci || (v->domain !=3D pdev->domain) ) - { - v->vpci.pdev =3D NULL; - read_unlock(&v->domain->pci_lock); - return false; - } + ASSERT(rw_is_locked(&pdev->domain->pci_lock)); =20 - header =3D &pdev->vpci->header; - for ( i =3D 0; i < ARRAY_SIZE(header->bars); i++ ) + for ( i =3D 0; i < ARRAY_SIZE(task->bars); i++ ) { - struct vpci_bar *bar =3D &header->bars[i]; - struct rangeset *mem =3D v->vpci.mem[i]; + struct vpci_bar_map *bar =3D &task->bars[i]; + struct rangeset *mem =3D bar->mem; struct map_data data =3D { - .d =3D v->domain, - .map =3D v->vpci.cmd & PCI_COMMAND_MEMORY, + .d =3D pdev->domain, + .map =3D task->cmd & PCI_COMMAND_MEMORY, .bar =3D bar, }; int rc; @@ -210,58 +199,116 @@ bool vpci_process_pending(struct vcpu *v) rc =3D rangeset_consume_ranges(mem, map_range, &data); =20 if ( rc =3D=3D -ERESTART ) - { - read_unlock(&v->domain->pci_lock); - return true; - } + return rc; =20 if ( rc ) { spin_lock(&pdev->vpci->lock); /* Disable memory decoding unconditionally on failure. */ - modify_decoding(pdev, v->vpci.cmd & ~PCI_COMMAND_MEMORY, - false); + modify_decoding(pdev, task->cmd & ~PCI_COMMAND_MEMORY, false); spin_unlock(&pdev->vpci->lock); =20 - /* Clean all the rangesets */ - for ( i =3D 0; i < ARRAY_SIZE(header->bars); i++ ) - if ( !rangeset_is_empty(v->vpci.mem[i]) ) - rangeset_purge(v->vpci.mem[i]); + if ( !is_hardware_domain(pdev->domain) ) + domain_crash(pdev->domain); + + return rc; + } + } + + spin_lock(&pdev->vpci->lock); + modify_decoding(pdev, task->cmd, task->rom_only); + spin_unlock(&pdev->vpci->lock); + + return 0; +} + +static void destroy_map_task(struct vpci_map_task *task) +{ + unsigned int i; + + if ( !task ) + { + ASSERT_UNREACHABLE(); + return; + } + + for ( i =3D 0; i < ARRAY_SIZE(task->bars); i++ ) + rangeset_destroy(task->bars[i].mem); + + xvfree(task); +} + +static void clear_map_queue(struct vcpu *v) +{ + struct vpci_map_task *task; + + while ( (task =3D list_first_entry_or_null(&v->vpci.task_queue, + struct vpci_map_task, + next)) !=3D NULL ) + { + list_del(&task->next); + destroy_map_task(task); + } +} + +bool vpci_process_pending(struct vcpu *v) +{ + const struct pci_dev *pdev =3D v->vpci.pdev; + struct vpci_map_task *task; =20 - v->vpci.pdev =3D NULL; + if ( !pdev ) + return false; =20 + read_lock(&v->domain->pci_lock); + + if ( !pdev->vpci || (v->domain !=3D pdev->domain) ) + { + clear_map_queue(v); + v->vpci.pdev =3D NULL; + read_unlock(&v->domain->pci_lock); + return false; + } + + while ( (task =3D list_first_entry_or_null(&v->vpci.task_queue, + struct vpci_map_task, + next)) !=3D NULL ) + { + int rc =3D vpci_process_map_task(pdev, task); + + if ( rc =3D=3D -ERESTART ) + { read_unlock(&v->domain->pci_lock); + return true; + } =20 - if ( !is_hardware_domain(v->domain) ) - domain_crash(v->domain); + list_del(&task->next); + destroy_map_task(task); =20 - return false; + if ( rc ) + { + clear_map_queue(v); + break; } } v->vpci.pdev =3D NULL; =20 - spin_lock(&pdev->vpci->lock); - modify_decoding(pdev, v->vpci.cmd, v->vpci.rom_only); - spin_unlock(&pdev->vpci->lock); - read_unlock(&v->domain->pci_lock); =20 return false; } =20 static int __init apply_map(struct domain *d, const struct pci_dev *pdev, - uint16_t cmd) + struct vpci_map_task *task) { - struct vpci_header *header =3D &pdev->vpci->header; int rc =3D 0; unsigned int i; =20 ASSERT(rw_is_write_locked(&d->pci_lock)); =20 - for ( i =3D 0; i < ARRAY_SIZE(header->bars); i++ ) + for ( i =3D 0; i < ARRAY_SIZE(task->bars); i++ ) { - struct vpci_bar *bar =3D &header->bars[i]; - struct rangeset *mem =3D current->vpci.mem[i]; + struct vpci_bar_map *bar =3D &task->bars[i]; + struct rangeset *mem =3D bar->mem; struct map_data data =3D { .d =3D d, .map =3D true, .bar =3D bar }; =20 if ( rangeset_is_empty(mem) ) @@ -281,15 +328,52 @@ static int __init apply_map(struct domain *d, const s= truct pci_dev *pdev, } } if ( !rc ) - modify_decoding(pdev, cmd, false); + modify_decoding(pdev, task->cmd, false); =20 return rc; } =20 -static void defer_map(const struct pci_dev *pdev, uint16_t cmd, bool rom_o= nly) +static struct vpci_map_task *alloc_map_task(const struct pci_dev *pdev, + uint16_t cmd, bool rom_only) +{ + struct vpci_map_task *task; + unsigned int i; + + task =3D xvzalloc(struct vpci_map_task); + + if ( !task ) + return NULL; + + for ( i =3D 0; i < ARRAY_SIZE(task->bars); i++ ) + { + if ( !MAPPABLE_BAR(&pdev->vpci->header.bars[i]) ) + continue; + + task->bars[i].mem =3D rangeset_new(pdev->domain, NULL, + RANGESETF_no_print); + + if ( !task->bars[i].mem ) + { + destroy_map_task(task); + return NULL; + } + + task->bars[i].addr =3D pdev->vpci->header.bars[i].addr; + task->bars[i].guest_addr =3D pdev->vpci->header.bars[i].guest_addr; + } + + task->cmd =3D cmd; + task->rom_only =3D rom_only; + + return task; +} + +static void defer_map(const struct pci_dev *pdev, struct vpci_map_task *ta= sk) { struct vcpu *curr =3D current; =20 + ASSERT(!curr->vpci.pdev || curr->vpci.pdev =3D=3D pdev); + /* * FIXME: when deferring the {un}map the state of the device should not * be trusted. For example the enable bit is toggled after the device @@ -297,8 +381,8 @@ static void defer_map(const struct pci_dev *pdev, uint1= 6_t cmd, bool rom_only) * started for the same device if the domain is not well-behaved. */ curr->vpci.pdev =3D pdev; - curr->vpci.cmd =3D cmd; - curr->vpci.rom_only =3D rom_only; + list_add_tail(&task->next, &curr->vpci.task_queue); + /* * Raise a scheduler softirq in order to prevent the guest from resumi= ng * execution with pending mapping operations, to trigger the invocation @@ -313,11 +397,17 @@ static int modify_bars(const struct pci_dev *pdev, ui= nt16_t cmd, bool rom_only) struct pci_dev *tmp; const struct domain *d; const struct vpci_msix *msix =3D pdev->vpci->msix; + struct vpci_map_task *task; unsigned int i, j; int rc; =20 ASSERT(rw_is_write_locked(&pdev->domain->pci_lock)); =20 + task =3D alloc_map_task(pdev, cmd, rom_only); + + if ( !task ) + return -ENOMEM; + /* * Create a rangeset per BAR that represents the current device memory * region and compare it against all the currently active BAR memory @@ -333,19 +423,18 @@ static int modify_bars(const struct pci_dev *pdev, ui= nt16_t cmd, bool rom_only) for ( i =3D 0; i < ARRAY_SIZE(header->bars); i++ ) { struct vpci_bar *bar =3D &header->bars[i]; - struct rangeset *mem =3D current->vpci.mem[i]; + struct rangeset *mem =3D task->bars[i].mem; unsigned long start =3D PFN_DOWN(bar->addr); unsigned long end =3D PFN_DOWN(bar->addr + bar->size - 1); unsigned long start_guest =3D PFN_DOWN(bar->guest_addr); unsigned long end_guest =3D PFN_DOWN(bar->guest_addr + bar->size -= 1); =20 - ASSERT(mem); + if ( !mem ) + continue; =20 if ( !MAPPABLE_BAR(bar) || (rom_only ? bar->type !=3D VPCI_BAR_ROM - : (bar->type =3D=3D VPCI_BAR_ROM && !header->rom_en= abled)) || - /* Skip BARs already in the requested state. */ - bar->enabled =3D=3D !!(cmd & PCI_COMMAND_MEMORY) ) + : (bar->type =3D=3D VPCI_BAR_ROM && !header->rom_en= abled)) ) continue; =20 if ( !pci_check_bar(pdev, _mfn(start), _mfn(end)) ) @@ -368,7 +457,8 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) gprintk(XENLOG_G_WARNING, "%pp: can't map BAR%u - offset mismatch: %#lx vs %#lx\= n", &pdev->sbdf, i, bar->guest_addr, bar->addr); - return -EINVAL; + rc =3D -EINVAL; + goto fail; } =20 rc =3D rangeset_add_range(mem, start_guest, end_guest); @@ -376,13 +466,13 @@ static int modify_bars(const struct pci_dev *pdev, ui= nt16_t cmd, bool rom_only) { printk(XENLOG_G_WARNING "Failed to add [%lx, %lx]: %d\n", start_guest, end_guest, rc); - return rc; + goto fail; } =20 /* Check for overlap with the already setup BAR ranges. */ for ( j =3D 0; j < i; j++ ) { - struct rangeset *prev_mem =3D current->vpci.mem[j]; + struct rangeset *prev_mem =3D task->bars[j].mem; =20 if ( rangeset_is_empty(prev_mem) ) continue; @@ -393,7 +483,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) gprintk(XENLOG_WARNING, "%pp: failed to remove overlapping range [%lx, %lx]= : %d\n", &pdev->sbdf, start_guest, end_guest, rc); - return rc; + goto fail; } } =20 @@ -403,7 +493,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) gprintk(XENLOG_WARNING, "%pp: failed to sanitize BAR#%u memory: %d\n", &pdev->sbdf, i, rc); - return rc; + goto fail; } } =20 @@ -414,9 +504,9 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) unsigned long end =3D PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + vmsix_table_size(pdev->vpci, i) - 1); =20 - for ( j =3D 0; j < ARRAY_SIZE(current->vpci.mem); j++ ) + for ( j =3D 0; j < ARRAY_SIZE(task->bars); j++ ) { - struct rangeset *mem =3D current->vpci.mem[j]; + struct rangeset *mem =3D task->bars[j].mem; =20 if ( rangeset_is_empty(mem) ) continue; @@ -427,7 +517,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) gprintk(XENLOG_WARNING, "%pp: failed to remove MSIX table [%lx, %lx]: %d\n", &pdev->sbdf, start, end, rc); - return rc; + goto fail; } } } @@ -471,7 +561,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) for ( j =3D 0; j < ARRAY_SIZE(header->bars); j++) { const struct vpci_bar *bar =3D &header->bars[j]; - struct rangeset *mem =3D current->vpci.mem[j]; + struct rangeset *mem =3D task->bars[j].mem; =20 if ( !rangeset_overlaps_range(mem, start, end) || /* @@ -490,7 +580,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) gprintk(XENLOG_WARNING, "%pp: failed to remove [%lx, %lx]: %d\n", &pdev->sbdf, start, end, rc); - return rc; + goto fail; } } } @@ -513,12 +603,19 @@ static int modify_bars(const struct pci_dev *pdev, ui= nt16_t cmd, bool rom_only) * will always be to establish mappings and process all the BARs. */ ASSERT((cmd & PCI_COMMAND_MEMORY) && !rom_only); - return apply_map(pdev->domain, pdev, cmd); + rc =3D apply_map(pdev->domain, pdev, task); + destroy_map_task(task); + return rc; } =20 - defer_map(pdev, cmd, rom_only); + defer_map(pdev, task); =20 return 0; + + fail: + destroy_map_task(task); + + return rc; } =20 static void cf_check cmd_write( diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c index 8e6343653078..ce9fb5b357ff 100644 --- a/xen/drivers/vpci/vpci.c +++ b/xen/drivers/vpci/vpci.c @@ -24,35 +24,9 @@ =20 #ifdef __XEN__ =20 -void vpci_vcpu_destroy(struct vcpu *v) +void vpci_vcpu_init(struct vcpu *v) { - unsigned int i; - - if ( !has_vpci(v->domain) && !is_idle_domain(v->domain) ) - return; - - for ( i =3D 0; i < ARRAY_SIZE(v->vpci.mem); i++ ) - RANGESET_DESTROY(v->vpci.mem[i]); -} - -int vpci_vcpu_init(struct vcpu *v) -{ - unsigned int i; - - if ( !has_vpci(v->domain) && !is_idle_domain(v->domain) ) - return 0; - - for ( i =3D 0; i < ARRAY_SIZE(v->vpci.mem); i++ ) - { - char str[32]; - - snprintf(str, sizeof(str), "%pv:BAR%u", v, i); - v->vpci.mem[i] =3D rangeset_new(v->domain, str, RANGESETF_no_print= ); - if ( !v->vpci.mem[i] ) - return -ENOMEM; - } - - return 0; + INIT_LIST_HEAD(&v->vpci.task_queue); } =20 #ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT diff --git a/xen/include/xen/rangeset.h b/xen/include/xen/rangeset.h index f01e00ec9234..817505badf6f 100644 --- a/xen/include/xen/rangeset.h +++ b/xen/include/xen/rangeset.h @@ -40,13 +40,6 @@ struct rangeset *rangeset_new( void rangeset_destroy( struct rangeset *r); =20 -/* Destroy a rangeset, and zero the pointer to it. */ -#define RANGESET_DESTROY(r) \ - ({ \ - rangeset_destroy(r); \ - (r) =3D NULL; \ - }) - /* * Set a limit on the number of ranges that may exist in set @r. * NOTE: This must be called while @r is empty. diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h index b55bacbe6e01..e34f7abe6da2 100644 --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -19,8 +19,7 @@ */ #define VPCI_MAX_VIRT_DEV (PCI_SLOT(~0) + 1) =20 -void vpci_vcpu_destroy(struct vcpu *v); -int vpci_vcpu_init(struct vcpu *v); +void vpci_vcpu_init(struct vcpu *v); =20 /* Assign vPCI to device by adding handlers. */ int __must_check vpci_assign_device(struct pci_dev *pdev); @@ -155,14 +154,23 @@ struct vpci { }; =20 #ifdef __XEN__ -struct vpci_vcpu { +struct vpci_map_task { /* Per-vcpu structure to store state while {un}mapping of PCI BARs. */ - const struct pci_dev *pdev; - struct rangeset *mem[ARRAY_SIZE(((struct vpci_header *)NULL)->bars)]; + struct list_head next; + struct vpci_bar_map { + uint64_t addr; + uint64_t guest_addr; + struct rangeset *mem; + } bars[ARRAY_SIZE(((struct vpci_header *)NULL)->bars)]; uint16_t cmd; bool rom_only : 1; }; =20 +struct vpci_vcpu { + const struct pci_dev *pdev; + struct list_head task_queue; +}; + void vpci_dump_msi(void); =20 /* Arch-specific vPCI MSI helpers. */ @@ -207,8 +215,7 @@ bool vpci_ecam_read(pci_sbdf_t sbdf, unsigned int reg, = unsigned int len, #else /* !CONFIG_HAS_VPCI */ struct vpci_vcpu {}; =20 -static inline void vpci_vcpu_destroy(struct vcpu *v) { } -static inline int vpci_vcpu_init(struct vcpu *v) { return 0; } +static inline void vpci_vcpu_init(struct vcpu *v) { } =20 static inline int vpci_reinit_ext_capabilities(struct pci_dev *pdev) { --=20 2.53.0 From nobody Thu Apr 9 21:52:51 2026 Delivered-To: importer@patchew.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; arc=pass (i=1 dmarc=pass fromdomain=amd.com); dmarc=pass(p=quarantine dis=none) header.from=amd.com ARC-Seal: i=2; a=rsa-sha256; t=1775502778; cv=pass; d=zohomail.com; s=zohoarc; b=UI0r4dul+v7+GTP4YaJuBVXo9YXY/ivD2ZY/kj47esXV17ySyua0xjtNUvRLacI1z4y1WzoRlpKf4gAhEpDTTQgX6TvMkLgqlpUQkKPRTA9dwhde2FeHR5zd6BdYQ2uI69EYU47ybhBQFM0wRqUUfwA0v4WyjjsqzZa3jqxZ5iY= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1775502778; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=vHjkD8mh/45ccq+3hyulqMZKE75dA55AV1KAofnrWsA=; b=cPyoZ3NzknOPKSk3wld+uTTK/Rd9Jf6wIzAvmRJq0nNDhUjtI1f+MKkLheaDmIwG7lCR0PlbX8Ik6M2QX555Bef2IQusT0TwknlTy2nUsfPU6RzBFRUWSYqYTeVJBVtDuLZVA2iN8ZekrWxG7DWRjNdbksduzib+2QXNlUeM36Q= ARC-Authentication-Results: i=2; 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; arc=pass (i=1 dmarc=pass fromdomain=amd.com); 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 1775502778157432.6979373985257; Mon, 6 Apr 2026 12:12:58 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1274363.1560514 (Exim 4.92) (envelope-from ) id 1w9pNK-0000ZT-Fg; Mon, 06 Apr 2026 19:12:42 +0000 Received: by outflank-mailman (output) from mailman id 1274363.1560514; Mon, 06 Apr 2026 19:12:42 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w9pNK-0000ZG-Cf; Mon, 06 Apr 2026 19:12:42 +0000 Received: by outflank-mailman (input) for mailman id 1274363; Mon, 06 Apr 2026 19:12:42 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w9pNJ-0000Yf-TC for xen-devel@lists.xenproject.org; Mon, 06 Apr 2026 19:12:42 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1w9pNJ-00GVO4-9E for xen-devel@lists.xenproject.org; Mon, 06 Apr 2026 21:12:41 +0200 Received: from [10.42.69.12] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69d40584-5cb7-0a2a0a5109dd-0a2a450c8bf6-36 for ; Mon, 06 Apr 2026 21:12:40 +0200 Received: from [52.101.48.17] (helo=MW6PR02CU001.outbound.protection.outlook.com) by tlsNG-d25034.mxtls.expurgate.net with ESMTPS (eXpurgate 4.56.0) (envelope-from ) id 69d405a7-f40c-0a2a450c0019-34653011c6d8-3 for ; Mon, 06 Apr 2026 21:12:40 +0200 Received: from DS7P220CA0084.NAMP220.PROD.OUTLOOK.COM (2603:10b6:8:259::14) by DS0PR12MB6630.namprd12.prod.outlook.com (2603:10b6:8:d2::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17; Mon, 6 Apr 2026 19:12:31 +0000 Received: from DS1PEPF0001708E.namprd03.prod.outlook.com (2603:10b6:8:259:cafe::70) by DS7P220CA0084.outlook.office365.com (2603:10b6:8:259::14) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9769.32 via Frontend Transport; Mon, 6 Apr 2026 19:12:40 +0000 Received: from satlexmb08.amd.com (165.204.84.17) by DS1PEPF0001708E.mail.protection.outlook.com (10.167.17.134) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17 via Frontend Transport; Mon, 6 Apr 2026 19:12:31 +0000 Received: from SATLEXMB03.amd.com (10.181.40.144) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.17; Mon, 6 Apr 2026 14:12:31 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 6 Apr 2026 14:12:30 -0500 Received: from ubuntu (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.17 via Frontend Transport; Mon, 6 Apr 2026 14:12:30 -0500 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" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=amd.com header.i="@amd.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=VjhhFJjbsCbDSZBSlFohGcViA83znlxt0aBeFGhsVJRFSJwrAGG6zJ+EDEDA2/N6xJMrGCUsZqLlaMeNMX4ApERKHRKgkHbG/AMGzmt8TIkQVXwUhQynjFz2HAfMjt5V294tstGwMTVYCnwfXbRkxMxp+zIdqnkMujW53OCKQBwawJWjVQU1TbJldyfIY+nxIIdM+Oa9Xb1mtq+1c1GFCOK0zryEEmyvc2yu/BdUoT3buZ0SN0If7JF0VrWb4JT6otwT1pNFRX5L9E74BLuCkZsg+iuL0i+CuFrvLcarzFG3u/aNlPMkBCUq5UNW9/rVRlSU3G5s0BTQJPL+VeSbvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=vHjkD8mh/45ccq+3hyulqMZKE75dA55AV1KAofnrWsA=; b=QGO9kFTVQsnRqGpF90zB8hpfzmh7uFr7VXWjY2njLRWf+rTeVZKlBjheZEBYhgqd9ynuqUb+3BkN2ZHpWU16cIBZ+y3ktaZGgAL9Kt2OKm2LNhMmOfLT1uiIiKwyIcLOuLTRfXnEOC6fGgyDZ+sclWU5so2/lggO0VzKzqT557HVwcirgR+z9qe8aVhofy+wA9Zn+vewrbeieCpmFuxKgdEHgcf4hAWkpZlsNq8vC6WJN2jRrm28SEOLGuByzJ9MMKA6AHgBWwu8DGzSHozE4YnYbEIo215DX7AglzhPZhwHXqQx+7K4m8HQS69fyga11uyysyGibTSV+3Ndyd5Rng== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=vHjkD8mh/45ccq+3hyulqMZKE75dA55AV1KAofnrWsA=; b=kc+gQYR5IHjcUztCnek9K0AG97VfccnCAum2dbLupGioyy++7zgW0L27NxGzhGytdNtM47QG/berO6Qg0stYj9OH4/UZDkmHNyNousaYqr+CpBmc0uKNaphYsISq1nvYV7u7TA0mIaQETam5+fJLVuWdbaU7cbFh1sSdyxYZrNA= X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; 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; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C From: Stewart Hildebrand To: CC: Stewart Hildebrand , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v4 3/4] vpci: allow BAR map/unmap without affecting memory decoding bit Date: Mon, 6 Apr 2026 15:11:57 -0400 Message-ID: <20260406191203.97662-4-stewart.hildebrand@amd.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260406191203.97662-1-stewart.hildebrand@amd.com> References: <20260406191203.97662-1-stewart.hildebrand@amd.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: None (SATLEXMB03.amd.com: stewart.hildebrand@amd.com does not designate permitted sender hosts) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS1PEPF0001708E:EE_|DS0PR12MB6630:EE_ X-MS-Office365-Filtering-Correlation-Id: 6ca8c865-67e4-4bcf-4710-08de941073d2 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|36860700016|1800799024|82310400026|13003099007|18002099003|56012099003|22082099003; X-Microsoft-Antispam-Message-Info: enR8OMFliM5I6OmSnbwo7PrqfYxN+XH/iTsQGD/qU/5xUxTyprSd6SWqjwNmlCMLqDnay3sb1xc+fgcd4tNOppbtf2Y5UojJyveDOCpH+y9EmnSAYlGmHkPxXwL/wRB/6bJGvkt0aHAqNRWm4xx9MJ2gJNPu/kar494zcuxw8bJ2aV7t6IrrTzVokP46br07aPIgjdHV0ekNbr6NnwVWhOd/e1+LwntYxK6tQcoy51m2lxwRTxaL+qmVpQmQVVdfPmmezltmIJOJbyYXjhgx1NZQ6i5EipMVk36EMTvrIy0tD5OEO6jaPWrybJnw3AnAWjithjsaMhYdEmeaEkrouia/HR+dQC8DKVT17OmWukGR4jl3RnQ4qrYKqZXZaHutCvL4O/pDog0JMWtSey2C+p0oJgNI93shq8+cG09BjFG+jjSt7KSGsuuUeus5wgb/CrjlfWDZemKGIoHUmeXLLW5bEpx/s5kq/T1LPKi3qRhRebZxzqccr9PK2BdeBTl7Zr8sc54wsvLtLFd07msFM1gWwqND7/yacVljhoBSrz1CW+A5VJ0qp5ZuwvO8rGRuMXOLLOW52w8PQnJWDuHDi6ouFjd7GVZw7ufDc3/YG4eC6JKulL46TKrq64/Swe59P6nkN11YWmFTpJhhRHBjBAfkNxD1chmnITLnGdPF+8a8Xb5zrYwQklhuYh6MEqdGzTs4AwmZQCjtLPoarhaR3oah3W/mAyW0uv8bKoyKNktgrD8YJSbEArVnefVIR4S36g3Mfi/P5cgWF++hMaPAvw== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(36860700016)(1800799024)(82310400026)(13003099007)(18002099003)(56012099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 90fzKIoC6c4BCDcstdgw5brz1o+3t0pbXfWQNlcRzbsUkAnz1Qd3ilhi2lJvOC+EUbXE9Kkd8Gl6WtudNYnvHI079c+O157gwCQsxjMqtHctAmxZVVR06HTD9i9EFi+Qy6mpxcUcBG4edpzveXVnPP0F0H+r7VOtsHATAFIuVTU+V+7PiZF+TMXgqop38xj6v/XzyUvmP7KawaGahCKQXdmEWkLTiDDoz8t89UDVkqILcebSokPsk+wt4WtUtNqkn2yUQgR5Pxab4cuPpN2C3hullES9FiKYR+So03pp4fFlJjxGGzYQ/5GUasWFp3IsHfVHIOgLXlZcALJzLTB9Nlri8pzjfecm24RC8CG4lLddD/9rQtI0ve2vzCaeOpAj8gBJ9aAaGq09xT0+EhzFjAG1+nGOtEd/uPRwGl8vVy7DHesFHfeXe3uy2u1DetrG X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Apr 2026 19:12:31.5941 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6ca8c865-67e4-4bcf-4710-08de941073d2 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS1PEPF0001708E.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB6630 X-purgate-ID: tlsNG-d25034/1775502760-81F52A3D-4CA2EAAD/0/0 X-purgate-type: clean X-purgate-size: 7003 X-ZohoMail-DKIM: pass (identity @amd.com) X-ZM-MESSAGEID: 1775502781031154100 Content-Type: text/plain; charset="utf-8" Introduce 'bool map' and allow invoking modify_bars() without changing the memory decoding bit. This will allow hardware domain to reposition BARs without affecting the memory decoding bit. Signed-off-by: Stewart Hildebrand --- This also lays some groundwork to allow domUs to toggle the guest view without affecting hardware, a step toward addressing the FIXME in [1]. [1] https://lore.kernel.org/xen-devel/20250814160358.95543-4-roger.pau@citr= ix.com/ v3->v4: * rebase on dynamically allocated map queue v2->v3: * use bool * switch to task->map in more places v1->v2: * new patch --- xen/drivers/vpci/header.c | 43 +++++++++++++++++++++------------------ xen/include/xen/vpci.h | 1 + 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c index 146915e28c50..20fe380552f4 100644 --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -117,11 +117,12 @@ static int cf_check map_range( * BAR's enable bit has changed with the memory decoding bit already enabl= ed. * If rom_only is not set then it's the memory decoding bit that changed. */ -static void modify_decoding(const struct pci_dev *pdev, uint16_t cmd, - bool rom_only) +static void modify_decoding(const struct pci_dev *pdev, + struct vpci_map_task *task) { struct vpci_header *header =3D &pdev->vpci->header; - bool map =3D cmd & PCI_COMMAND_MEMORY; + bool rom_only =3D task->rom_only; + bool map =3D task->map; unsigned int i; =20 for ( i =3D 0; i < ARRAY_SIZE(header->bars); i++ ) @@ -168,7 +169,7 @@ static void modify_decoding(const struct pci_dev *pdev,= uint16_t cmd, =20 if ( !rom_only ) { - pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd); + pci_conf_write16(pdev->sbdf, PCI_COMMAND, task->cmd); header->bars_mapped =3D map; } else @@ -188,7 +189,7 @@ static int vpci_process_map_task(const struct pci_dev *= pdev, struct rangeset *mem =3D bar->mem; struct map_data data =3D { .d =3D pdev->domain, - .map =3D task->cmd & PCI_COMMAND_MEMORY, + .map =3D task->map, .bar =3D bar, }; int rc; @@ -203,9 +204,11 @@ static int vpci_process_map_task(const struct pci_dev = *pdev, =20 if ( rc ) { - spin_lock(&pdev->vpci->lock); /* Disable memory decoding unconditionally on failure. */ - modify_decoding(pdev, task->cmd & ~PCI_COMMAND_MEMORY, false); + task->cmd &=3D ~PCI_COMMAND_MEMORY; + task->map =3D false; + spin_lock(&pdev->vpci->lock); + modify_decoding(pdev, task); spin_unlock(&pdev->vpci->lock); =20 if ( !is_hardware_domain(pdev->domain) ) @@ -216,7 +219,7 @@ static int vpci_process_map_task(const struct pci_dev *= pdev, } =20 spin_lock(&pdev->vpci->lock); - modify_decoding(pdev, task->cmd, task->rom_only); + modify_decoding(pdev, task); spin_unlock(&pdev->vpci->lock); =20 return 0; @@ -328,13 +331,14 @@ static int __init apply_map(struct domain *d, const s= truct pci_dev *pdev, } } if ( !rc ) - modify_decoding(pdev, task->cmd, false); + modify_decoding(pdev, task); =20 return rc; } =20 static struct vpci_map_task *alloc_map_task(const struct pci_dev *pdev, - uint16_t cmd, bool rom_only) + uint16_t cmd, bool rom_only, + bool map) { struct vpci_map_task *task; unsigned int i; @@ -364,6 +368,7 @@ static struct vpci_map_task *alloc_map_task(const struc= t pci_dev *pdev, =20 task->cmd =3D cmd; task->rom_only =3D rom_only; + task->map =3D map; =20 return task; } @@ -391,7 +396,8 @@ static void defer_map(const struct pci_dev *pdev, struc= t vpci_map_task *task) raise_softirq(SCHEDULE_SOFTIRQ); } =20 -static int modify_bars(const struct pci_dev *pdev, uint16_t cmd, bool rom_= only) +static int modify_bars(const struct pci_dev *pdev, uint16_t cmd, bool rom_= only, + bool map) { struct vpci_header *header =3D &pdev->vpci->header; struct pci_dev *tmp; @@ -403,7 +409,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) =20 ASSERT(rw_is_write_locked(&pdev->domain->pci_lock)); =20 - task =3D alloc_map_task(pdev, cmd, rom_only); + task =3D alloc_map_task(pdev, cmd, rom_only, map); =20 if ( !task ) return -ENOMEM; @@ -602,7 +608,7 @@ static int modify_bars(const struct pci_dev *pdev, uint= 16_t cmd, bool rom_only) * be called iff the memory decoding bit is enabled, thus the oper= ation * will always be to establish mappings and process all the BARs. */ - ASSERT((cmd & PCI_COMMAND_MEMORY) && !rom_only); + ASSERT(map && !rom_only); rc =3D apply_map(pdev->domain, pdev, task); destroy_map_task(task); return rc; @@ -646,7 +652,7 @@ static void cf_check cmd_write( * memory decoding bit has not been changed, so leave everything a= s-is, * hoping the guest will realize and try again. */ - modify_bars(pdev, cmd, false); + modify_bars(pdev, cmd, false, cmd & PCI_COMMAND_MEMORY); else pci_conf_write16(pdev->sbdf, reg, cmd); } @@ -810,11 +816,8 @@ static void cf_check rom_write( header->rom_enabled =3D new_enabled; pci_conf_write32(pdev->sbdf, reg, val); } - /* - * Pass PCI_COMMAND_MEMORY or 0 to signal a map/unmap request, note th= at - * this fabricated command is never going to be written to the registe= r. - */ - else if ( modify_bars(pdev, new_enabled ? PCI_COMMAND_MEMORY : 0, true= ) ) + /* Note that the command value 0 will never be written to the register= */ + else if ( modify_bars(pdev, 0, true, new_enabled) ) /* * No memory has been added or removed from the p2m (because the a= ctual * p2m changes are deferred in defer_map) and the ROM enable bit h= as @@ -1004,7 +1007,7 @@ int vpci_init_header(struct pci_dev *pdev) goto fail; } =20 - return (cmd & PCI_COMMAND_MEMORY) ? modify_bars(pdev, cmd, false) : 0; + return (cmd & PCI_COMMAND_MEMORY) ? modify_bars(pdev, cmd, false, true= ) : 0; =20 fail: pci_conf_write16(pdev->sbdf, PCI_COMMAND, cmd); diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h index e34f7abe6da2..e6d40827a43a 100644 --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -164,6 +164,7 @@ struct vpci_map_task { } bars[ARRAY_SIZE(((struct vpci_header *)NULL)->bars)]; uint16_t cmd; bool rom_only : 1; + bool map : 1; }; =20 struct vpci_vcpu { --=20 2.53.0 From nobody Thu Apr 9 21:52:51 2026 Delivered-To: importer@patchew.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; arc=pass (i=1 dmarc=pass fromdomain=amd.com); dmarc=pass(p=quarantine dis=none) header.from=amd.com ARC-Seal: i=2; a=rsa-sha256; t=1775502787; cv=pass; d=zohomail.com; s=zohoarc; b=edkHYfWgeMTPQ4zqcsDkbKh/DzVC0WA+ehPEN8PqNAj2Tm+Ly3qwOmA03pfbvA48A2TlBpN96gw2CiIpcRAFZp1VL+KaLQClk6LmppxY7m2NO5Asmn/5WAjYm3HC3r4yCs6V0uAisxBAsHdvD8LKnCsrz45kGdQWGDMvDHgCoQY= ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1775502787; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=m5KAxsB5+rjJP69DJz9pK/1jNINXHR3glsZici/9duI=; b=VSvByhs+C4lTUPVH34tlJKaYRXcq8P9bGCZLkXypL9zdZH+kXPXz74P88HEISwF3tauKj5e8PPzQn6R2a6+daRPgCUQRXYmGwRQxlZmG+k5G81mQ4fdU86lMaRcw0QlxIESNzOUR24cpQViWWb/7+LeIRtSCZ3BSQg28kq2f1kQ= ARC-Authentication-Results: i=2; 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; arc=pass (i=1 dmarc=pass fromdomain=amd.com); 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 1775502787370193.70292512023946; Mon, 6 Apr 2026 12:13:07 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1274367.1560523 (Exim 4.92) (envelope-from ) id 1w9pNP-0000vC-UH; Mon, 06 Apr 2026 19:12:47 +0000 Received: by outflank-mailman (output) from mailman id 1274367.1560523; Mon, 06 Apr 2026 19:12:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w9pNP-0000v3-Py; Mon, 06 Apr 2026 19:12:47 +0000 Received: by outflank-mailman (input) for mailman id 1274367; Mon, 06 Apr 2026 19:12:46 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w9pNO-0000th-M9 for xen-devel@lists.xenproject.org; Mon, 06 Apr 2026 19:12:46 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1w9pNO-00DVi8-2C for xen-devel@lists.xenproject.org; Mon, 06 Apr 2026 21:12:46 +0200 Received: from [10.42.69.10] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69d40570-bab6-0a2a0a5309dd-0a2a450acf26-30 for ; Mon, 06 Apr 2026 21:12:45 +0200 Received: from [40.107.208.41] (helo=PH0PR06CU001.outbound.protection.outlook.com) by tlsNG-4011c0.mxtls.expurgate.net with ESMTPS (eXpurgate 4.56.0) (envelope-from ) id 69d405ac-ee98-0a2a450a0019-286bd0296cf3-3 for ; Mon, 06 Apr 2026 21:12:45 +0200 Received: from DS7PR03CA0059.namprd03.prod.outlook.com (2603:10b6:5:3b5::34) by SA0PR12MB4480.namprd12.prod.outlook.com (2603:10b6:806:99::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.10; Mon, 6 Apr 2026 19:12:38 +0000 Received: from DS1PEPF00017091.namprd03.prod.outlook.com (2603:10b6:5:3b5:cafe::ca) by DS7PR03CA0059.outlook.office365.com (2603:10b6:5:3b5::34) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9769.32 via Frontend Transport; Mon, 6 Apr 2026 19:12:38 +0000 Received: from satlexmb08.amd.com (165.204.84.17) by DS1PEPF00017091.mail.protection.outlook.com (10.167.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17 via Frontend Transport; Mon, 6 Apr 2026 19:12:38 +0000 Received: from SATLEXMB03.amd.com (10.181.40.144) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.2562.17; Mon, 6 Apr 2026 14:12:37 -0500 Received: from satlexmb07.amd.com (10.181.42.216) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Mon, 6 Apr 2026 14:12:37 -0500 Received: from ubuntu (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server id 15.2.2562.17 via Frontend Transport; Mon, 6 Apr 2026 14:12:37 -0500 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" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=amd.com header.i="@amd.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=pHVJvIgrD2pktkmpYzJn94ygxj7InypvB0yigxcj6ZeTXuF3h9Ap8ofGOyqbZwsVb9Tn87FUToRQAdEBSj6yPLRBB+BaR2+yG1icjfCfp8+L8ySRxRIwx6+YxkLR7tdO/nt+bHh3yfk6M98wLWiJErLhBokqfpn01yAux1WQmFVrOSzKUWeJW+D5n4qei2+Hx2rSSTuZuRPuwz4kSYvJGTTs/cUvsW8ScrD6AguFOWmocKL1/mf7zbW8WVtA2u0EOToB5jUcnMbuyKaiTmJtntiWim/vSKOlrvJOdgfNWJFYgx296V0chBRE8lFM2mtTZ/ZI49XnNMbSMc1quZLozw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=m5KAxsB5+rjJP69DJz9pK/1jNINXHR3glsZici/9duI=; b=dInQYgcRYjFjzUV75YCdkw2jeIIiatXIHYow8kBFUdDBzWFmUzsuDxLwtnpX32pyzh1NaqQft4i0glPvdTUfL/UghXKJSqiCHqv6Yp0dR4xHXNE8ijBeYZ2F8h7JOsXLu0m7Rc4j1PMj/EihOYdvZ5DrxEf+hq1cCfTKRnvfQg5mqjzXvgu7JXvmYBYgyEDciMHgtD/5+R2Cc0b+9QmDo7wsk+LzR89YFm6C6i6cDK1Vf5jA6rkQuWytkl9MnJnt6u1JQacn4QN5bBd3nIlWAGCkk24SqFy48kTNqCmq/GqIFp5z6b8k/iZJW7suppXnXEwX40Ft0/XCJ0i29R0x6Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=m5KAxsB5+rjJP69DJz9pK/1jNINXHR3glsZici/9duI=; b=UqtzRE6Tf0g20EzKpj2JVg5LJrncHAFtXmi9wPmXlS1giHxlvohP7fwmp3lXNy9sLKu+pAJRlfIqeQu9xrOhrzWl6F2D0Zxk32Ph2WPXo/MlGiZbbqcCw8oohqVBl/T01eATMWE/gV0M8ra8BCzV3GGFTB4pikcjSgZ/66T8Lxg= X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; 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; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C From: Stewart Hildebrand To: CC: Stewart Hildebrand , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v4 4/4] vpci: allow 32-bit BAR writes with memory decoding enabled Date: Mon, 6 Apr 2026 15:11:58 -0400 Message-ID: <20260406191203.97662-5-stewart.hildebrand@amd.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260406191203.97662-1-stewart.hildebrand@amd.com> References: <20260406191203.97662-1-stewart.hildebrand@amd.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: None (SATLEXMB03.amd.com: stewart.hildebrand@amd.com does not designate permitted sender hosts) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS1PEPF00017091:EE_|SA0PR12MB4480:EE_ X-MS-Office365-Filtering-Correlation-Id: 5348181e-dcf2-40d8-6071-08de941077da X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|376014|36860700016|82310400026|13003099007|22082099003|56012099003|18002099003; X-Microsoft-Antispam-Message-Info: G3MX5L2g5IlopSPWZPkdgtwUizEuoqM+dbvxxoSRkBEqa0en1bxNeriAgZ6MJPizkLiMWk7ejZsYjfFvY+y/bSia1rjIMmoqOhavzgZ9BZ6H28siPl9U+IlY4iWUKTeKhpFZ0Mq7P+Nd4GZLWG3Sn8h5tCdErIwiAFqYWcCwbkhnCd/xQP5tDSlR3xbdPWnBqXNaVppfqEoEbKGyvzv0Z8VU60kT6N/hq6gGlxW9EAUD5ruz6N0mratXo/+bM5SJtUMsAjIm2BJW0rSwpT3IlPXUrPBHAEHT1eq5ajUsNYRdc3jx/FQgedF3MRVjQ/0z2h7SlGirXj2wTwLSJ6/BV4nlR/Ff6s3gr98nvH8LRZdOHDk/NCzluRTJjEOYc1nSpZoORT03t6x7cBR3GXUrSaMmTuL491M2sgaeKcptchDL0FNuj6xBWsfR1lWj2oxCANnZSms3tKipHfaXwsbH4pchAzGsh8LZmlFkKfLbRfDAfxO9Jdk2WsRmCPS0pUlWciiqN6US8yzvvHqp1jybJiEXO7e4MyPBIvw5W6do7OGqK102e517riGMR7rWkvcITSGtIFJFCeNE/oCRPJhYhKRDuElNZAKf/s4MyWd1jjW001XEv0cch6XV8User+RyF/VW9V326rBFGt4j24m7y+wCoSbnn642jpbGQiRy+y9R4tM7ejEGaPR/uE6hKmpi6VDcjzUYkFjt+LmZ939FOMlW3ijFJdat99Q/BJ34qs9+adUSO747J0cG1IeTAkLGSpaMODyaEp7efyHeQwRhHQ== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(376014)(36860700016)(82310400026)(13003099007)(22082099003)(56012099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: uBV75Vm1+YeDJLyxJV5iOWAtxOZTFtYmwYCI8VgLM4g+uwdf6PE0s5As3LyoFNcDo2HPHE0B1Caa07unfbLNPre1wuZaF+SuLhSyaYizDHyk9WVbYRVtLZSj6VpBeM8XdN3zyk5NLzPrHBXsI/PSPGBptxusIodjuYah0ZBoLVFyrgVL3BW61zWDSHcJDAoQcVLNbbUPnep3AtOtxWqjn9Z2mQQ6DzjJ6SFo88nZh/pie/BhFLJEAgnSlD9WIR84jopCTSnBoGhSBgEjeYF+W+vq7OGW8WD8ory4plQMYUMSOxXPGIq4qdV9UVgYR0nrdCpqkl5tljBQuKZ2D5dOpxMKZZivJ3STHYaCTMFM0QJqW3PrgtbbC6FWmRZ9r1GWQLItvtBjn4xf4L+xkXdMDO+wgpPebFnNfQ9tDIVcyKC7GjdxvW1MZNoPTog7Q/lA X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Apr 2026 19:12:38.3570 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5348181e-dcf2-40d8-6071-08de941077da X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS1PEPF00017091.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA0PR12MB4480 X-purgate-ID: tlsNG-4011c0/1775502765-0FB450B1-AF63A496/0/0 X-purgate-type: clean X-purgate-size: 3444 X-ZohoMail-DKIM: pass (identity @amd.com) X-ZM-MESSAGEID: 1775502789205154100 Content-Type: text/plain; charset="utf-8" Currently, Xen vPCI refuses BAR writes if the BAR is mapped in p2m. If firmware initializes a 32-bit BAR to a bad address, Linux may try to write a new address to the 32-bit BAR without disabling memory decoding. Since Xen refuses such writes, the BAR (and thus PCI device) will be non-functional. Allow the hardware domain to issue 32-bit BAR writes with memory decoding enabled. This increases the compatibility of PVH dom0 with more hardware. Note that Linux aims at disabling memory decoding before writing 64-bit BARs. Continue to refuse 64-bit BAR writes in Xen while those BARs are mapped for now to avoid mapping half-updated BARs in p2m. Resolves: https://gitlab.com/xen-project/xen/-/issues/197 Signed-off-by: Stewart Hildebrand --- v3->v4: * rebase on dynamically allocated map queue v2->v3: * minor tweaks for fixed number of map/unmap slots v1->v2: * rework on top of queued BAR map/unmap operation machinery RFC->v1: * keep memory decoding enabled in hardware * allow write while memory decoding is enabled for 32-bit BARs only * rework BAR mapping machinery to support unmap-then-map operation --- xen/drivers/vpci/header.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c index 20fe380552f4..dc4f585b4e40 100644 --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -670,6 +670,7 @@ static void cf_check bar_write( { struct vpci_bar *bar =3D data; bool hi =3D false; + uint16_t cmd =3D 0; =20 ASSERT(is_hardware_domain(pdev->domain)); =20 @@ -683,19 +684,29 @@ static void cf_check bar_write( val &=3D PCI_BASE_ADDRESS_MEM_MASK; =20 /* - * Xen only cares whether the BAR is mapped into the p2m, so allow BAR - * writes as long as the BAR is not mapped into the p2m. + * Allow 64-bit BAR writes only when the BAR is not mapped in p2m. Alw= ays + * allow 32-bit BAR writes. */ if ( bar->enabled ) { - /* If the value written is the current one avoid printing a warnin= g. */ - if ( val !=3D (uint32_t)(bar->addr >> (hi ? 32 : 0)) ) - gprintk(XENLOG_WARNING, - "%pp: ignored BAR %zu write while mapped\n", - &pdev->sbdf, bar - pdev->vpci->header.bars + hi); - return; - } + if ( bar->type =3D=3D VPCI_BAR_MEM32 ) + { + if ( val =3D=3D bar->addr ) + return; =20 + cmd =3D pci_conf_read16(pdev->sbdf, PCI_COMMAND); + modify_bars(pdev, cmd, false, false); + } + else + { + /* If the value written is the same avoid printing a warning. = */ + if ( val !=3D (uint32_t)(bar->addr >> (hi ? 32 : 0)) ) + gprintk(XENLOG_WARNING, + "%pp: ignored BAR %zu write while mapped\n", + &pdev->sbdf, bar - pdev->vpci->header.bars + hi); + return; + } + } =20 /* * Update the cached address, so that when memory decoding is enabled @@ -715,6 +726,9 @@ static void cf_check bar_write( } =20 pci_conf_write32(pdev->sbdf, reg, val); + + if ( bar->enabled ) + modify_bars(pdev, cmd, false, true); } =20 static void cf_check guest_mem_bar_write(const struct pci_dev *pdev, --=20 2.53.0