From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM02-BL2-obe.outbound.protection.outlook.com (mail-bl2nam02on062b.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe46::62b]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 542D720081A89 for ; Mon, 17 Apr 2017 12:58:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=xFDTFldsjYmambFZJNKXROh9N9FUOc+1pR2AWMMrwOI=; b=KG8yuSTmnFerdIX/wwOkV+uY/JViPxBMiiQU5Rqbet9p4j+VSP8e4/uxInGNixSsR6uaDxNkJTjKPY+SgT0jbMbCfE+8PKvvtPTZJ11U+TaQXLuCPQRjmxsC8jpnsLoMjqcemRqOOFRSFuwlVOGpplzFKugCsql6r7x+DgScurk= Received: from DM5PR12MB1243.namprd12.prod.outlook.com (10.168.237.22) by DM5PR1201MB0138.namprd12.prod.outlook.com (10.174.106.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1019.17; Mon, 17 Apr 2017 19:58:01 +0000 Received: from DM5PR12MB1243.namprd12.prod.outlook.com ([10.168.237.22]) by DM5PR12MB1243.namprd12.prod.outlook.com ([10.168.237.22]) with mapi id 15.01.1034.013; Mon, 17 Apr 2017 19:58:00 +0000 From: "Duran, Leo" To: 'Jiewen Yao' , "edk2-devel@lists.01.org" CC: Ruiyu Ni , "Singh, Brijesh" , Ard Biesheuvel Thread-Topic: [RFC] [PATCH V3 3/3] MdeModulePkg/PciBus: Add IOMMU support. Thread-Index: AQHSrRIH7tMXp6x7MUGuy/0eWHp/EaHKCRgw Date: Mon, 17 Apr 2017 19:58:00 +0000 Message-ID: References: <1491289579-15888-1-git-send-email-jiewen.yao@intel.com> <1491289579-15888-4-git-send-email-jiewen.yao@intel.com> In-Reply-To: <1491289579-15888-4-git-send-email-jiewen.yao@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=amd.com; x-originating-ip: [165.204.77.1] x-microsoft-exchange-diagnostics: 1; DM5PR1201MB0138; 7:CRkpKQMAYRL9lXivtJyFkxdCdKIU2HVtRqFJfBjh6iKTsQyoJ9dRbD7qgP/DjSzem8LXG/tecVPzL70pg85UPoDGewxrNkcArEEgtGGJFD1lPHsD2UnxnAwWs2zIG8Cz3zv0Xh5u6DqExK/ML3kB+V7rkPjgk8vuZe0kw3Sb5WdYzULccTofhzaI4VVYAhuZqu6YncodT6wud3PRSq28Jtlj7L+L62KJLlu39dIJPcM3Ss2qkSKs8KcAUkYwCveIMiiWi0zRvWo1NKa3FORhTaq8/qi1UdKIMLrKfnjdLSz21ceja29syJMdkkf73750QntOQtu1Lm8X1ElHyNkJMA==; 20:Cxi2Lm2rsG0M1F0PQRMUNQoCNfYHpFXsUlhdi/U8YQULgV4HKF9cmZa5/Fedsi2H3glRjeyxIAA/ujI7zhgSXfVdVM3wLEGzUO0egw7hTfRz5BeHgzEJLC9lZ2l3t78NekVRenzYj/K8tZA0MQbSja2HKGfiZsvtGpi5Z/92Ajl7kvufyC1PQNjNti9yc1IfZhHHlRT9d21qnyBqnWnhmm86YmJq1nPFsfj6IM0aXMU9EoqAgP2OwRtwhnlsi/Zk x-forefront-antispam-report: SFV:SKI; SCL:-1SFV:NSPM; SFS:(10009020)(6009001)(39450400003)(39860400002)(39840400002)(39400400002)(39850400002)(377454003)(13464003)(86362001)(189998001)(50986999)(8676002)(122556002)(229853002)(5660300001)(2900100001)(81166006)(8936002)(55016002)(74316002)(6246003)(3280700002)(53546009)(33656002)(77096006)(7696004)(305945005)(54356999)(3660700001)(102836003)(6116002)(2906002)(76176999)(25786009)(4326008)(66066001)(53936002)(6506006)(53946003)(2501003)(54906002)(6436002)(38730400002)(2950100002)(9686003)(99286003)(7736002)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM5PR1201MB0138; H:DM5PR12MB1243.namprd12.prod.outlook.com; FPR:; SPF:None; MLV:sfv; LANG:en; x-ms-office365-filtering-correlation-id: 7e20ee5c-894e-4d2c-4c87-08d485cc0d39 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(2017030254075)(48565401081)(201703131423075)(201703031133081)(201702281549075); SRVR:DM5PR1201MB0138; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(767451399110)(162533806227266)(228905959029699); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040450)(601004)(2401047)(8121501046)(5005006)(93006095)(93001095)(10201501046)(3002001)(6055026)(6041248)(20161123560025)(20161123555025)(20161123564025)(20161123562025)(201703131423075)(201702281528075)(201703061421075)(6072148); SRVR:DM5PR1201MB0138; BCL:0; PCL:0; RULEID:; SRVR:DM5PR1201MB0138; x-forefront-prvs: 02801ACE41 spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-originalarrivaltime: 17 Apr 2017 19:58:00.5792 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR1201MB0138 Subject: Re: [RFC] [PATCH V3 3/3] MdeModulePkg/PciBus: Add IOMMU support. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Apr 2017 19:58:03 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Yao, Regarding RootBridgeIoMap() I'm wondering if may be possible to simplify the logic requiring flags "Nee= dMap" and "NeedAllocateNonExisting"? For example, it seems like (NeedAllocateNonExisting=3D=3DTRUE) implies (gIo= MmuProtocol !=3D NULL), but that did not seem obvious at a glance. Leo. > -----Original Message----- > From: Jiewen Yao [mailto:jiewen.yao@intel.com] > Sent: Tuesday, April 04, 2017 2:06 AM > To: edk2-devel@lists.01.org > Cc: Ruiyu Ni ; Duran, Leo ; > Singh, Brijesh ; Ard Biesheuvel > > Subject: [RFC] [PATCH V3 3/3] MdeModulePkg/PciBus: Add IOMMU support. >=20 > The responsibility of PciBus driver is to set IOMMU attribute, because on= ly > PciBus knows which device submits DMA access request. >=20 > PciBus driver guarantee that the request to PciHostBridge is IOMMU page > aligned memory, as such PciHostBridge can allocate non-existent memory fo= r > device memory, to satisfy remap requirement. >=20 > PciBus driver does not assume device address is same as the mapped host > address, because IOMMU may remap it. >=20 > Cc: Ruiyu Ni > Cc: Leo Duran > Cc: Brijesh Singh > Cc: Ard Biesheuvel > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Jiewen Yao > --- > MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 12 ++ > MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 19 ++ > MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 1 + > MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 225 > +++++++++++++++++++- > 4 files changed, 247 insertions(+), 10 deletions(-) >=20 > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c > index f3be47a..c9ee4de 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c > @@ -42,6 +42,8 @@ UINT64 gAllZero = =3D 0; >=20 > EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol; > EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol; > +EDKII_IOMMU_PROTOCOL *gIoMmuProtocol; > +UINTN mIoMmuPageSize =3D 1; >=20 >=20 > GLOBAL_REMOVE_IF_UNREFERENCED > EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest =3D { @@ - > 256,6 +258,16 @@ PciBusDriverBindingStart ( > } >=20 > gBS->LocateProtocol ( > + &gEdkiiIoMmuProtocolGuid, > + NULL, > + (VOID **) &gIoMmuProtocol > + ); > + if (gIoMmuProtocol !=3D NULL) { > + gIoMmuProtocol->GetPageSize (gIoMmuProtocol, &mIoMmuPageSize); > + ASSERT ((mIoMmuPageSize & (mIoMmuPageSize - 1)) =3D=3D 0); } > + > + gBS->LocateProtocol ( > &gEfiIncompatiblePciDeviceSupportProtocolGuid, > NULL, > (VOID **) &gIncompatiblePciDeviceSupport diff --git > a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > index 39ba8b9..185d89c 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h > @@ -32,6 +32,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY > KIND, EITHER EXPRESS OR IMPLIED. > #include > #include > #include > +#include >=20 > #include > #include @@ -289,6 +290,8 @@ struct > _PCI_IO_DEVICE { > // This field is used to support this case. > // > UINT16 BridgeIoAlignment; > + > + LIST_ENTRY Maps; > }; >=20 > #define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \ @@ -304,6 +307,20 @@ > struct _PCI_IO_DEVICE { > CR (a, PCI_IO_DEVICE, LoadFile2, PCI_IO_DEVICE_SIGNATURE) >=20 >=20 > +#define PCI_IO_MAP_INFO_SIGNATURE SIGNATURE_32 ('p', 'm', 'a', 'p') > +typedef struct { > + UINT32 Signature; > + LIST_ENTRY Link; > + EFI_PCI_IO_PROTOCOL_OPERATION Operation; > + VOID *HostAddress; > + EFI_PHYSICAL_ADDRESS DeviceAddress; > + UINTN NumberOfBytes; > + VOID *AlignedHostAddress; > + UINTN AlignedNumberOfBytes; > + VOID *MappedHostAddress; > + VOID *PciRootBridgeIoMapping; > +} PCI_IO_MAP_INFO; > +#define PCI_IO_MAP_INFO_FROM_LINK(a) CR (a, PCI_IO_MAP_INFO, > Link, > +PCI_IO_MAP_INFO_SIGNATURE) >=20 > // > // Global Variables > @@ -321,6 +338,8 @@ extern EFI_PCI_PLATFORM_PROTOCOL > *gPciPlatformProtocol; > extern EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtoco= l; > extern BOOLEAN mReserveIsaAliases; > extern BOOLEAN mReserveVgaAliases; > +extern EDKII_IOMMU_PROTOCOL *gIoMmuProtocol; > +extern UINTN mIoMmuPageSize; >=20 > /** > Macro that checks whether device is a GFX device. > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > index a3ab11f..5da094f 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > @@ -95,6 +95,7 @@ > gEfiPciRootBridgeIoProtocolGuid ## TO_START > gEfiIncompatiblePciDeviceSupportProtocolGuid ## > SOMETIMES_CONSUMES > gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES > + gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES >=20 > [FeaturePcd] > gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## > CONSUMES > diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c > b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c > index f72598d..31b8c32 100644 > --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c > +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c > @@ -58,6 +58,7 @@ InitializePciIoInstance ( > ) > { > CopyMem (&PciIoDevice->PciIo, &mPciIoInterface, sizeof > (EFI_PCI_IO_PROTOCOL)); > + InitializeListHead (&PciIoDevice->Maps); > } >=20 > /** > @@ -936,6 +937,28 @@ PciIoCopyMem ( > } >=20 > /** > + Return if a value is aligned. > + > + @param Value the value to be checked > + @param Alignment the alignment to be checked with. > + > + @retval TRUE The value is aligned > + @retval FALSE The value is not aligned. > +**/ > +BOOLEAN > +InternalIsAlgined ( > + IN UINTN Value, > + IN UINTN Alignment > + ) > +{ > + if (Value =3D=3D ALIGN_VALUE(Value, Alignment)) { > + return TRUE; > + } else { > + return FALSE; > + } > +} > + > +/** > Provides the PCI controller-specific addresses needed to access system > memory. >=20 > @param This A pointer to the EFI_PCI_IO_PROTOCOL ins= tance. > @@ -967,6 +990,9 @@ PciIoMap ( > { > EFI_STATUS Status; > PCI_IO_DEVICE *PciIoDevice; > + PCI_IO_MAP_INFO *PciIoMapInfo; > + UINT64 IoMmuAttribute; > + EFI_STATUS RemapStatus; >=20 > PciIoDevice =3D PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); >=20 > @@ -982,15 +1008,60 @@ PciIoMap ( > Operation =3D (EFI_PCI_IO_PROTOCOL_OPERATION) (Operation + > EfiPciOperationBusMasterRead64); > } >=20 > - Status =3D PciIoDevice->PciRootBridgeIo->Map ( > - PciIoDevice->PciRootBridgeIo, > - (EFI_PCI_ROOT_BRIDGE_IO_PROTOC= OL_OPERATION) > Operation, > - HostAddress, > - NumberOfBytes, > - DeviceAddress, > - Mapping > - ); > - > + if (gIoMmuProtocol !=3D NULL) { > + PciIoMapInfo =3D AllocatePool (sizeof(*PciIoMapInfo)); > + if (PciIoMapInfo =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + PciIoMapInfo->Signature =3D PCI_IO_MAP_INFO_SIGNATURE; > + PciIoMapInfo->Operation =3D Operation; > + PciIoMapInfo->NumberOfBytes =3D *NumberOfBytes; > + PciIoMapInfo->DeviceAddress =3D *DeviceAddress; > + PciIoMapInfo->HostAddress =3D HostAddress; > + // > + // For non common buffer, we always allocate a new memory if IOMMU > exists. > + // because the original memory might not be DMA capable. > + // > + // For common buffer, it is not needed, because common buffer alloca= te > via PciIoAllocateBuffer. > + // We cannot use AllocateAlignedPages here, because there might be > more restriction in PciIoAllocateBuffer(). > + // > + PciIoMapInfo->AlignedNumberOfBytes =3D ALIGN_VALUE (PciIoMapInfo- > >NumberOfBytes, mIoMmuPageSize); > + if (PciIoMapInfo->Operation !=3D > EfiPciIoOperationBusMasterCommonBuffer) { > + PciIoMapInfo->AlignedHostAddress =3D AllocateAlignedPages > (EFI_SIZE_TO_PAGES(PciIoMapInfo->AlignedNumberOfBytes), > mIoMmuPageSize); > + if (PciIoMapInfo->AlignedHostAddress =3D=3D NULL) { > + FreePool (PciIoMapInfo); > + return EFI_OUT_OF_RESOURCES; > + } > + } else { > + // > + // For common buffer, the HostAddress must be allocated via > PciIoAllocateBuffer. > + // > + if (!InternalIsAlgined((UINTN)PciIoMapInfo->HostAddress, > mIoMmuPageSize)) { > + FreePool (PciIoMapInfo); > + DEBUG ((DEBUG_ERROR, "PciIoMap - map unaligned common buffer > with IOMMU\n")); > + return EFI_UNSUPPORTED; > + } > + PciIoMapInfo->AlignedHostAddress =3D PciIoMapInfo->HostAddress; > + } > + PciIoMapInfo->PciRootBridgeIoMapping =3D NULL; > + Status =3D PciIoDevice->PciRootBridgeIo->Map ( > + PciIoDevice->PciRootBridgeIo= , > + > (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation, > + PciIoMapInfo->AlignedHostAdd= ress, > + &PciIoMapInfo->AlignedNumber= OfBytes, > + &PciIoMapInfo->DeviceAddress= , > + &PciIoMapInfo->PciRootBridge= IoMapping > + ); } else { > + Status =3D PciIoDevice->PciRootBridgeIo->Map ( > + PciIoDevice->PciRootBridgeIo= , > + > (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation, > + HostAddress, > + NumberOfBytes, > + DeviceAddress, > + Mapping > + ); } > if (EFI_ERROR (Status)) { > REPORT_STATUS_CODE_WITH_DEVICE_PATH ( > EFI_ERROR_CODE | EFI_ERROR_MINOR, @@ -999,6 +1070,63 @@ > PciIoMap ( > ); > } >=20 > + if (gIoMmuProtocol !=3D NULL) { > + if (EFI_ERROR(Status)) { > + if (PciIoMapInfo->Operation !=3D > EfiPciIoOperationBusMasterCommonBuffer) { > + FreePages (PciIoMapInfo->AlignedHostAddress, > EFI_SIZE_TO_PAGES(PciIoMapInfo->AlignedNumberOfBytes)); > + } > + FreePool (PciIoMapInfo); > + } else { > + *DeviceAddress =3D PciIoMapInfo->DeviceAddress; > + *Mapping =3D PciIoMapInfo; > + > + switch (Operation) { > + case EfiPciIoOperationBusMasterRead: > + IoMmuAttribute =3D EDKII_IOMMU_ATTRIBUTE_READ; > + break; > + case EfiPciIoOperationBusMasterWrite: > + IoMmuAttribute =3D EDKII_IOMMU_ATTRIBUTE_WRITE; > + break; > + case EfiPciIoOperationBusMasterCommonBuffer: > + IoMmuAttribute =3D EDKII_IOMMU_ATTRIBUTE_READ | > EDKII_IOMMU_ATTRIBUTE_WRITE; > + break; > + default: > + ASSERT(FALSE); > + return EFI_INVALID_PARAMETER; > + } > + // > + // PciHostBridge should map IOMMU page aligned HostAddress. > + // > + gIoMmuProtocol->SetAttribute ( > + gIoMmuProtocol, > + PciIoDevice->Handle, > + PciIoMapInfo->DeviceAddress, > + PciIoMapInfo->AlignedNumberOfBytes, > + IoMmuAttribute > + ); > + // > + // We need do copy mem after IoMmu->SetAttribute(), > + // because it might change IOMMU state. > + // > + RemapStatus =3D gIoMmuProtocol->GetRemapAddress ( > + gIoMmuProtocol, > + PciIoDevice->Handle, > + PciIoMapInfo->DeviceAddress, > + &PciIoMapInfo->MappedHostAddress > + ); > + if (EFI_ERROR(RemapStatus)) { > + PciIoMapInfo->MappedHostAddress =3D (VOID *)(UINTN)PciIoMapInfo- > >DeviceAddress; > + } > + if (Operation =3D=3D EfiPciIoOperationBusMasterRead) { > + CopyMem ( > + PciIoMapInfo->MappedHostAddress, > + PciIoMapInfo->HostAddress, > + PciIoMapInfo->NumberOfBytes > + ); > + } > + InsertTailList (&PciIoDevice->Maps, &PciIoMapInfo->Link); > + } > + } > return Status; > } >=20 > @@ -1021,9 +1149,48 @@ PciIoUnmap ( > { > EFI_STATUS Status; > PCI_IO_DEVICE *PciIoDevice; > + PCI_IO_MAP_INFO *PciIoMapInfo; > + LIST_ENTRY *Link; >=20 > PciIoDevice =3D PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); >=20 > + PciIoMapInfo =3D NULL; > + if (gIoMmuProtocol !=3D NULL) { > + PciIoMapInfo =3D NULL; > + for (Link =3D GetFirstNode (&PciIoDevice->Maps) > + ; !IsNull (&PciIoDevice->Maps, Link) > + ; Link =3D GetNextNode (&PciIoDevice->Maps, Link) > + ) { > + PciIoMapInfo =3D PCI_IO_MAP_INFO_FROM_LINK (Link); > + if (PciIoMapInfo =3D=3D Mapping) { > + break; > + } > + } > + // > + // Mapping is not a valid value returned by Map() > + // > + if (PciIoMapInfo !=3D Mapping) { > + DEBUG ((DEBUG_INFO, "PciIoUnmap - PciIoMapInfo not found!\n")); > + return EFI_INVALID_PARAMETER; > + } > + RemoveEntryList (&PciIoMapInfo->Link); > + Mapping =3D PciIoMapInfo->PciRootBridgeIoMapping; > + > + // > + // PciHostBridge should map IOMMU page aligned HostAddress. > + // > + // We need do copy mem before PciRootBridgeIo->Unmap(), > + // because it might free mapped host address. > + // > + if (PciIoMapInfo->Operation =3D=3D EfiPciIoOperationBusMasterWrite) = { > + CopyMem ( > + PciIoMapInfo->HostAddress, > + PciIoMapInfo->MappedHostAddress, > + PciIoMapInfo->NumberOfBytes > + ); > + } > + } > + > Status =3D PciIoDevice->PciRootBridgeIo->Unmap ( > PciIoDevice->PciRootBridgeIo, > Mapping @@ -1037,6 +1204,25 @@= PciIoUnmap ( > ); > } >=20 > + if (gIoMmuProtocol !=3D NULL) { > + if (!EFI_ERROR(Status)) { > + // > + // PciHostBridge should map IOMMU page aligned HostAddress. > + // > + gIoMmuProtocol->SetAttribute ( > + gIoMmuProtocol, > + PciIoDevice->Handle, > + PciIoMapInfo->DeviceAddress, > + PciIoMapInfo->AlignedNumberOfBytes, > + 0 > + ); > + if (PciIoMapInfo->Operation !=3D > EfiPciIoOperationBusMasterCommonBuffer) { > + FreePages (PciIoMapInfo->AlignedHostAddress, > EFI_SIZE_TO_PAGES(PciIoMapInfo->AlignedNumberOfBytes)); > + } > + FreePool (PciIoMapInfo); > + } > + } > + > return Status; > } >=20 > @@ -1073,6 +1259,7 @@ PciIoAllocateBuffer ( { > EFI_STATUS Status; > PCI_IO_DEVICE *PciIoDevice; > + UINTN Size; >=20 > if ((Attributes & > (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | > EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) !=3D 0){ @@ -1085,6 +1272,12 @@ > PciIoAllocateBuffer ( > Attributes |=3D EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE; > } >=20 > + if (gIoMmuProtocol !=3D NULL) { > + Size =3D EFI_PAGES_TO_SIZE(Pages); > + Size =3D ALIGN_VALUE(Size, mIoMmuPageSize); > + Pages =3D EFI_SIZE_TO_PAGES (Size); > + } > + > Status =3D PciIoDevice->PciRootBridgeIo->AllocateBuffer ( > PciIoDevice->PciRootBridgeIo, > Type, @@ -1101,7 +1294,9 @@ Pc= iIoAllocateBuffer ( > PciIoDevice->DevicePath > ); > } > - > + // > + // No need to set attribute here, it is done in Map. > + // > return Status; > } >=20 > @@ -1127,9 +1322,16 @@ PciIoFreeBuffer ( { > EFI_STATUS Status; > PCI_IO_DEVICE *PciIoDevice; > + UINTN Size; >=20 > PciIoDevice =3D PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); >=20 > + if (gIoMmuProtocol !=3D NULL) { > + Size =3D EFI_PAGES_TO_SIZE(Pages); > + Size =3D ALIGN_VALUE(Size, mIoMmuPageSize); > + Pages =3D EFI_SIZE_TO_PAGES (Size); > + } > + > Status =3D PciIoDevice->PciRootBridgeIo->FreeBuffer ( > PciIoDevice->PciRootBridgeIo, > Pages, @@ -1144,6 +1346,9 @@ P= ciIoFreeBuffer ( > ); > } >=20 > + // > + // No need to set attribute here, it is done in Unmap. > + // > return Status; > } >=20 > -- > 2.7.4.windows.1