From nobody Sat May 4 08:52:39 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1520509376352335.39687069417073; Thu, 8 Mar 2018 03:42:56 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id D743421ED1C6E; Thu, 8 Mar 2018 03:36:38 -0800 (PST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 83FBA20955F18 for ; Thu, 8 Mar 2018 03:36:37 -0800 (PST) Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2018 03:42:53 -0800 Received: from shwdeopenpsi068.ccr.corp.intel.com ([10.239.158.46]) by orsmga006.jf.intel.com with ESMTP; 08 Mar 2018 03:42:51 -0800 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.93; helo=mga11.intel.com; envelope-from=star.zeng@intel.com; receiver=edk2-devel@lists.01.org X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,440,1515484800"; d="scan'208";a="23944280" From: Star Zeng To: edk2-devel@lists.01.org Date: Thu, 8 Mar 2018 19:42:49 +0800 Message-Id: <1520509370-14484-1-git-send-email-star.zeng@intel.com> X-Mailer: git-send-email 2.7.0.windows.1 Subject: [edk2] [PATCH V2] IntelSiliconPkg/Vtd: Add MapHandleInfo in VtdDxe. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jiewen Yao , Star Zeng MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Jiewen Yao This information is to record which device requested which DMA buffer. It can be used for DMA buffer analysis. Cc: Star Zeng Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jiewen Yao Reviewed-by: Star Zeng --- IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c | 104 +++++++++++++++++= ++++ .../Feature/VTd/IntelVTdDxe/IntelVTdDxe.c | 53 ++++++++--- 2 files changed, 144 insertions(+), 13 deletions(-) diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c b/IntelSilicon= Pkg/Feature/VTd/IntelVTdDxe/BmDma.c index 57e086a64dbc..bf3c1ed99ae2 100644 --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/BmDma.c @@ -18,6 +18,15 @@ #define DMA_MEMORY_TOP MAX_UINTN //#define DMA_MEMORY_TOP 0x0000000001FFFFFFULL =20 +#define MAP_HANDLE_INFO_SIGNATURE SIGNATURE_32 ('H', 'M', 'A', 'P') +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + EFI_HANDLE DeviceHandle; + UINT64 IoMmuAccess; +} MAP_HANDLE_INFO; +#define MAP_HANDLE_INFO_FROM_LINK(a) CR (a, MAP_HANDLE_INFO, Link, MAP_HAN= DLE_INFO_SIGNATURE) + #define MAP_INFO_SIGNATURE SIGNATURE_32 ('D', 'M', 'A', 'P') typedef struct { UINT32 Signature; @@ -27,12 +36,96 @@ typedef struct { UINTN NumberOfPages; EFI_PHYSICAL_ADDRESS HostAddress; EFI_PHYSICAL_ADDRESS DeviceAddress; + LIST_ENTRY HandleList; } MAP_INFO; #define MAP_INFO_FROM_LINK(a) CR (a, MAP_INFO, Link, MAP_INFO_SIGNATURE) =20 LIST_ENTRY gMaps =3D INITIALIZE_LIST_HEAD_VARIABLE(= gMaps); =20 /** + This function fills DeviceHandle/IoMmuAccess to the MAP_HANDLE_INFO, + based upon the DeviceAddress. + + @param[in] DeviceHandle The device who initiates the DMA access re= quest. + @param[in] DeviceAddress The base of device memory address to be us= ed as the DMA memory. + @param[in] Length The length of device memory address to be = used as the DMA memory. + @param[in] IoMmuAccess The IOMMU access. + +**/ +VOID +SyncDeviceHandleToMapInfo ( + IN EFI_HANDLE DeviceHandle, + IN EFI_PHYSICAL_ADDRESS DeviceAddress, + IN UINT64 Length, + IN UINT64 IoMmuAccess + ) +{ + MAP_INFO *MapInfo; + MAP_HANDLE_INFO *MapHandleInfo; + LIST_ENTRY *Link; + EFI_TPL OriginalTpl; + + // + // Find MapInfo according to DeviceAddress + // + OriginalTpl =3D gBS->RaiseTPL (VTD_TPL_LEVEL); + MapInfo =3D NULL; + for (Link =3D GetFirstNode (&gMaps) + ; !IsNull (&gMaps, Link) + ; Link =3D GetNextNode (&gMaps, Link) + ) { + MapInfo =3D MAP_INFO_FROM_LINK (Link); + if (MapInfo->DeviceAddress =3D=3D DeviceAddress) { + break; + } + } + if ((MapInfo =3D=3D NULL) || (MapInfo->DeviceAddress !=3D DeviceAddress)= ) { + DEBUG ((DEBUG_ERROR, "SyncDeviceHandleToMapInfo: DeviceAddress(0x%lx) = - not found\n", DeviceAddress)); + gBS->RestoreTPL (OriginalTpl); + return ; + } + + // + // Find MapHandleInfo according to DeviceHandle + // + MapHandleInfo =3D NULL; + for (Link =3D GetFirstNode (&MapInfo->HandleList) + ; !IsNull (&MapInfo->HandleList, Link) + ; Link =3D GetNextNode (&MapInfo->HandleList, Link) + ) { + MapHandleInfo =3D MAP_HANDLE_INFO_FROM_LINK (Link); + if (MapHandleInfo->DeviceHandle =3D=3D DeviceHandle) { + break; + } + } + if ((MapHandleInfo !=3D NULL) && (MapHandleInfo->DeviceHandle =3D=3D Dev= iceHandle)) { + MapHandleInfo->IoMmuAccess =3D IoMmuAccess; + gBS->RestoreTPL (OriginalTpl); + return ; + } + + // + // No DeviceHandle + // Initialize and insert the MAP_HANDLE_INFO structure + // + MapHandleInfo =3D AllocatePool (sizeof (MAP_HANDLE_INFO)); + if (MapHandleInfo =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "SyncDeviceHandleToMapInfo: %r\n", EFI_OUT_OF_RES= OURCES)); + gBS->RestoreTPL (OriginalTpl); + return ; + } + + MapHandleInfo->Signature =3D MAP_HANDLE_INFO_SIGNATURE; + MapHandleInfo->DeviceHandle =3D DeviceHandle; + MapHandleInfo->IoMmuAccess =3D IoMmuAccess; + + InsertTailList (&MapInfo->HandleList, &MapHandleInfo->Link); + gBS->RestoreTPL (OriginalTpl); + + return ; +} + +/** Provides the controller-specific addresses required to access system mem= ory from a DMA bus master. =20 @@ -156,6 +249,7 @@ IoMmuMap ( MapInfo->NumberOfPages =3D EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes= ); MapInfo->HostAddress =3D PhysicalAddress; MapInfo->DeviceAddress =3D DmaMemoryTop; + InitializeListHead(&MapInfo->HandleList); =20 // // Allocate a buffer below 4GB to map the transfer to. @@ -227,6 +321,7 @@ IoMmuUnmap ( ) { MAP_INFO *MapInfo; + MAP_HANDLE_INFO *MapHandleInfo; LIST_ENTRY *Link; EFI_TPL OriginalTpl; =20 @@ -259,6 +354,15 @@ IoMmuUnmap ( RemoveEntryList (&MapInfo->Link); gBS->RestoreTPL (OriginalTpl); =20 + // + // remove all nodes in MapInfo->HandleList + // + while (!IsListEmpty (&MapInfo->HandleList)) { + MapHandleInfo =3D MAP_HANDLE_INFO_FROM_LINK (MapInfo->HandleList.Forwa= rdLink); + RemoveEntryList (&MapHandleInfo->Link); + FreePool (MapHandleInfo); + } + if (MapInfo->DeviceAddress !=3D MapInfo->HostAddress) { // // If this is a write operation from the Bus Master's point of view, diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c b/IntelS= iliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c index 841a5a9264aa..25d7c80af1d4 100644 --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c @@ -114,6 +114,24 @@ IoMmuFreeBuffer ( ); =20 /** + This function fills DeviceHandle/IoMmuAccess to the MAP_HANDLE_INFO, + based upon the DeviceAddress. + + @param[in] DeviceHandle The device who initiates the DMA access re= quest. + @param[in] DeviceAddress The base of device memory address to be us= ed as the DMA memory. + @param[in] Length The length of device memory address to be = used as the DMA memory. + @param[in] IoMmuAccess The IOMMU access. + +**/ +VOID +SyncDeviceHandleToMapInfo ( + IN EFI_HANDLE DeviceHandle, + IN EFI_PHYSICAL_ADDRESS DeviceAddress, + IN UINT64 Length, + IN UINT64 IoMmuAccess + ); + +/** Convert the DeviceHandle to SourceId and Segment. =20 @param[in] DeviceHandle The device who initiates the DMA access re= quest. @@ -236,21 +254,30 @@ VTdSetAttribute ( // Record the entry to driver global variable. // As such once VTd is activated, the setting can be adopted. // - return RequestAccessAttribute (Segment, SourceId, DeviceAddress, Lengt= h, IoMmuAccess); + Status =3D RequestAccessAttribute (Segment, SourceId, DeviceAddress, L= ength, IoMmuAccess); + } else { + PERF_CODE ( + AsciiSPrint (PerfToken, sizeof(PerfToken), "S%04xB%02xD%02xF%01x", S= egment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function); + Identifier =3D (Segment << 16) | SourceId.Uint16; + PERF_START_EX (gImageHandle, PerfToken, "IntelVTD", 0, Identifier); + ); + + Status =3D SetAccessAttribute (Segment, SourceId, DeviceAddress, Lengt= h, IoMmuAccess); + + PERF_CODE ( + Identifier =3D (Segment << 16) | SourceId.Uint16; + PERF_END_EX (gImageHandle, PerfToken, "IntelVTD", 0, Identifier); + ); } =20 - PERF_CODE ( - AsciiSPrint (PerfToken, sizeof(PerfToken), "S%04xB%02xD%02xF%01x", Seg= ment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function); - Identifier =3D (Segment << 16) | SourceId.Uint16; - PERF_START_EX (gImageHandle, PerfToken, "IntelVTD", 0, Identifier); - ); - - Status =3D SetAccessAttribute (Segment, SourceId, DeviceAddress, Length,= IoMmuAccess); - - PERF_CODE ( - Identifier =3D (Segment << 16) | SourceId.Uint16; - PERF_END_EX (gImageHandle, PerfToken, "IntelVTD", 0, Identifier); - ); + if (!EFI_ERROR(Status)) { + SyncDeviceHandleToMapInfo ( + DeviceHandle, + DeviceAddress, + Length, + IoMmuAccess + ); + } =20 return Status; } --=20 2.7.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel