From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.100; helo=mga07.intel.com; envelope-from=jiewen.yao@intel.com; receiver=edk2-devel@lists.01.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 38AA5222A54FF for ; Wed, 3 Jan 2018 22:09:58 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 Jan 2018 22:15:01 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,506,1508828400"; d="scan'208";a="17355624" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by orsmga003.jf.intel.com with ESMTP; 03 Jan 2018 22:15:00 -0800 Received: from fmsmsx157.amr.corp.intel.com (10.18.116.73) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 3 Jan 2018 22:15:00 -0800 Received: from shsmsx104.ccr.corp.intel.com (10.239.4.70) by FMSMSX157.amr.corp.intel.com (10.18.116.73) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 3 Jan 2018 22:15:00 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.189]) by SHSMSX104.ccr.corp.intel.com ([169.254.5.152]) with mapi id 14.03.0319.002; Thu, 4 Jan 2018 14:14:59 +0800 From: "Yao, Jiewen" To: "Zeng, Star" , "edk2-devel@lists.01.org" Thread-Topic: [PATCH] IntelSiliconPkg IntelVTdDxe: Support early SetAttributes() Thread-Index: AQHThQzd/lpRQEuUB0mMLf3+iB4qDqNjPIbg Date: Thu, 4 Jan 2018 06:14:58 +0000 Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503AA6FDCF@shsmsx102.ccr.corp.intel.com> References: <1515036827-17944-1-git-send-email-star.zeng@intel.com> In-Reply-To: <1515036827-17944-1-git-send-email-star.zeng@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMjJjZDQ2NjQtZmM4ZC00ODhlLWI1NzYtZTRjNjlhZTZjNTk5IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjIuNS4xOCIsIlRydXN0ZWRMYWJlbEhhc2giOiJ4dXIrQnJ3TzhQZ2Rna0o3MFBXcHg5dGRcLzdLOXZvNHdOOEtyc3VOZUJCVDlLSUdQK2I1UjdQbHV1cVFiQm04ayJ9 x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.0.0.116 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH] IntelSiliconPkg IntelVTdDxe: Support early SetAttributes() 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: , X-List-Received-Date: Thu, 04 Jan 2018 06:09:58 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Jiewen.yao@intel.com > -----Original Message----- > From: Zeng, Star > Sent: Thursday, January 4, 2018 11:34 AM > To: edk2-devel@lists.01.org > Cc: Zeng, Star ; Yao, Jiewen > Subject: [PATCH] IntelSiliconPkg IntelVTdDxe: Support early SetAttributes= () >=20 > Support early SetAttributes() before DMAR table is installed. >=20 > Cc: Jiewen Yao > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Star Zeng > --- > .../Feature/VTd/IntelVTdDxe/DmaProtection.c | 147 > +++++++++++++++++++++ > .../Feature/VTd/IntelVTdDxe/DmaProtection.h | 46 ++++++- > .../Feature/VTd/IntelVTdDxe/DmarAcpiTable.c | 2 +- > .../Feature/VTd/IntelVTdDxe/IntelVTdDxe.c | 10 +- > 4 files changed, 202 insertions(+), 3 deletions(-) >=20 > diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c > b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c > index 013823cc161f..665afe71703d 100644 > --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c > +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c > @@ -18,6 +18,151 @@ UINT64 > mAbove4GMemoryLimit; >=20 > EDKII_PLATFORM_VTD_POLICY_PROTOCOL *mPlatformVTdPolicy; >=20 > +VTD_ACCESS_REQUEST *mAccessRequest =3D NULL; > +UINTN mAccessRequestCount =3D 0; > +UINTN mAccessRequestMaxCount =3D 0; > + > +/** > + Append VTd Access Request to global. > + > + @param[in] Segment The Segment used to identify a VTd > engine. > + @param[in] SourceId The SourceId used to identify a VTd > engine and table entry. > + @param[in] BaseAddress The base of device memory address to be > used 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. > + > + @retval EFI_SUCCESS The IoMmuAccess is set for the memory > range specified by BaseAddress and Length. > + @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size > aligned. > + @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned. > + @retval EFI_INVALID_PARAMETER Length is 0. > + @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal > combination of access. > + @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not > supported by the IOMMU. > + @retval EFI_UNSUPPORTED The IOMMU does not support the > memory range specified by BaseAddress and Length. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to modify the IOMMU access. > + @retval EFI_DEVICE_ERROR The IOMMU device reported an error > while attempting the operation. > + > +**/ > +EFI_STATUS > +RequestAccessAttribute ( > + IN UINT16 Segment, > + IN VTD_SOURCE_ID SourceId, > + IN UINT64 BaseAddress, > + IN UINT64 Length, > + IN UINT64 IoMmuAccess > + ) > +{ > + VTD_ACCESS_REQUEST *NewAccessRequest; > + UINTN Index; > + > + // > + // Optimization for memory. > + // > + // If the last record is to IoMmuAccess=3D0, > + // Check previous records and remove the matched entry. > + // > + if (IoMmuAccess =3D=3D 0) { > + for (Index =3D 0; Index < mAccessRequestCount; Index++) { > + if ((mAccessRequest[Index].Segment =3D=3D Segment) && > + (mAccessRequest[Index].SourceId.Uint16 =3D=3D SourceId.Uint16)= && > + (mAccessRequest[Index].BaseAddress =3D=3D BaseAddress) && > + (mAccessRequest[Index].Length =3D=3D Length) && > + (mAccessRequest[Index].IoMmuAccess !=3D 0)) { > + // > + // Remove this record [Index]. > + // No need to add the new record. > + // > + if (Index !=3D mAccessRequestCount - 1) { > + CopyMem ( > + &mAccessRequest[Index], > + &mAccessRequest[Index + 1], > + sizeof (VTD_ACCESS_REQUEST) * (mAccessRequestCount - 1 - > Index) > + ); > + } > + ZeroMem (&mAccessRequest[mAccessRequestCount - 1], > sizeof(VTD_ACCESS_REQUEST)); > + mAccessRequestCount--; > + return EFI_SUCCESS; > + } > + } > + } > + > + if (mAccessRequestCount >=3D mAccessRequestMaxCount) { > + NewAccessRequest =3D AllocateZeroPool (sizeof(*NewAccessRequest) * > (mAccessRequestMaxCount + MAX_VTD_ACCESS_REQUEST)); > + if (NewAccessRequest =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + mAccessRequestMaxCount +=3D MAX_VTD_ACCESS_REQUEST; > + if (mAccessRequest !=3D NULL) { > + CopyMem (NewAccessRequest, mAccessRequest, > sizeof(*NewAccessRequest) * mAccessRequestCount); > + FreePool (mAccessRequest); > + mAccessRequest =3D NewAccessRequest; > + } > + } > + > + ASSERT (mAccessRequestCount < mAccessRequestMaxCount); > + > + mAccessRequest[mAccessRequestCount].Segment =3D Segment; > + mAccessRequest[mAccessRequestCount].SourceId =3D SourceId; > + mAccessRequest[mAccessRequestCount].BaseAddress =3D BaseAddress; > + mAccessRequest[mAccessRequestCount].Length =3D Length; > + mAccessRequest[mAccessRequestCount].IoMmuAccess =3D IoMmuAccess; > + > + mAccessRequestCount++; > + > + return EFI_SUCCESS; > +} > + > +/** > + Process Access Requests from before DMAR table is installed. > + > +**/ > +VOID > +ProcessRequestedAccessAttribute ( > + VOID > + ) > +{ > + UINTN Index; > + EFI_STATUS Status; > + > + DEBUG ((DEBUG_INFO, "ProcessRequestedAccessAttribute ...\n")); > + > + for (Index =3D 0; Index < mAccessRequestCount; Index++) { > + DEBUG (( > + DEBUG_INFO, > + "PCI(S%x.B%x.D%x.F%x) ", > + mAccessRequest[Index].Segment, > + mAccessRequest[Index].SourceId.Bits.Bus, > + mAccessRequest[Index].SourceId.Bits.Device, > + mAccessRequest[Index].SourceId.Bits.Function > + )); > + DEBUG (( > + DEBUG_INFO, > + "(0x%lx~0x%lx) - %lx\n", > + mAccessRequest[Index].BaseAddress, > + mAccessRequest[Index].Length, > + mAccessRequest[Index].IoMmuAccess > + )); > + Status =3D SetAccessAttribute ( > + mAccessRequest[Index].Segment, > + mAccessRequest[Index].SourceId, > + mAccessRequest[Index].BaseAddress, > + mAccessRequest[Index].Length, > + mAccessRequest[Index].IoMmuAccess > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "SetAccessAttribute %r: ", Status)); > + } > + } > + > + if (mAccessRequest !=3D NULL) { > + FreePool (mAccessRequest); > + } > + mAccessRequest =3D NULL; > + mAccessRequestCount =3D 0; > + mAccessRequestMaxCount =3D 0; > + > + DEBUG ((DEBUG_INFO, "ProcessRequestedAccessAttribute Done\n")); > +} > + > /** > return the UEFI memory information. >=20 > @@ -370,6 +515,8 @@ SetupVtd ( >=20 > ParseDmarAcpiTableRmrr (); >=20 > + ProcessRequestedAccessAttribute (); > + > for (Index =3D 0; Index < mVtdUnitNumber; Index++) { > DEBUG ((DEBUG_INFO,"VTD Unit %d (Segment: %04x)\n", Index, > mVtdUnitInformation[Index].Segment)); > if (mVtdUnitInformation[Index].ExtRootEntryTable !=3D NULL) { > diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h > b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h > index bc14ff9a6631..767531e4a93f 100644 > --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h > +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h > @@ -1,6 +1,6 @@ > /** @file >=20 > - Copyright (c) 2017, Intel Corporation. All rights reserved.
> + Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
> This program and the accompanying materials > are licensed and made available under the terms and conditions of the = BSD > License > which accompanies this distribution. The full text of the license may= be > found at > @@ -84,6 +84,21 @@ typedef struct { > PCI_DEVICE_INFORMATION PciDeviceInfo; > } VTD_UNIT_INFORMATION; >=20 > +// > +// This is the initial max ACCESS request. > +// The number may be enlarged later. > +// > +#define MAX_VTD_ACCESS_REQUEST 0x100 > + > +typedef struct { > + UINT16 Segment; > + VTD_SOURCE_ID SourceId; > + UINT64 BaseAddress; > + UINT64 Length; > + UINT64 IoMmuAccess; > +} VTD_ACCESS_REQUEST; > + > + > /** > The scan bus callback function. >=20 > @@ -561,4 +576,33 @@ GetPciBusDeviceFunction ( > OUT UINT8 *Function > ); >=20 > +/** > + Append VTd Access Request to global. > + > + @param[in] Segment The Segment used to identify a VTd > engine. > + @param[in] SourceId The SourceId used to identify a VTd > engine and table entry. > + @param[in] BaseAddress The base of device memory address to be > used 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. > + > + @retval EFI_SUCCESS The IoMmuAccess is set for the memory > range specified by BaseAddress and Length. > + @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size > aligned. > + @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned. > + @retval EFI_INVALID_PARAMETER Length is 0. > + @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal > combination of access. > + @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not > supported by the IOMMU. > + @retval EFI_UNSUPPORTED The IOMMU does not support the > memory range specified by BaseAddress and Length. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to modify the IOMMU access. > + @retval EFI_DEVICE_ERROR The IOMMU device reported an error > while attempting the operation. > + > +**/ > +EFI_STATUS > +RequestAccessAttribute ( > + IN UINT16 Segment, > + IN VTD_SOURCE_ID SourceId, > + IN UINT64 BaseAddress, > + IN UINT64 Length, > + IN UINT64 IoMmuAccess > + ); > + > #endif > diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c > b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c > index b16bd93d53f1..b981bcdb3aa0 100644 > --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c > +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c > @@ -27,7 +27,7 @@ typedef struct { >=20 > #pragma pack() >=20 > -EFI_ACPI_DMAR_HEADER *mAcpiDmarTable; > +EFI_ACPI_DMAR_HEADER *mAcpiDmarTable =3D NULL; >=20 > /** > Dump DMAR DeviceScopeEntry. > diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c > b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c > index 570b47cf7364..841a5a9264aa 100644 > --- a/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c > +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.c > @@ -1,7 +1,7 @@ > /** @file > Intel VTd driver. >=20 > - Copyright (c) 2017, Intel Corporation. All rights reserved.
> + Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
> This program and the accompanying materials > are licensed and made available under the terms and conditions of the = BSD > License > which accompanies this distribution. The full text of the license may= be > found at > @@ -231,6 +231,14 @@ VTdSetAttribute ( > DEBUG ((DEBUG_VERBOSE, "PCI(S%x.B%x.D%x.F%x) ", Segment, > SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function)); > DEBUG ((DEBUG_VERBOSE, "(0x%lx~0x%lx) - %lx\n", DeviceAddress, Length, > IoMmuAccess)); >=20 > + if (mAcpiDmarTable =3D=3D NULL) { > + // > + // Record the entry to driver global variable. > + // As such once VTd is activated, the setting can be adopted. > + // > + return RequestAccessAttribute (Segment, SourceId, DeviceAddress, Len= gth, > IoMmuAccess); > + } > + > PERF_CODE ( > AsciiSPrint (PerfToken, sizeof(PerfToken), "S%04xB%02xD%02xF%01x", > Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function)= ; > Identifier =3D (Segment << 16) | SourceId.Uint16; > -- > 2.7.0.windows.1