From: "Yao, Jiewen" <jiewen.yao@intel.com>
To: "Zeng, Star" <star.zeng@intel.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH] IntelSiliconPkg IntelVTdDxe: Support early SetAttributes()
Date: Thu, 4 Jan 2018 06:14:58 +0000 [thread overview]
Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503AA6FDCF@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <1515036827-17944-1-git-send-email-star.zeng@intel.com>
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 <star.zeng@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>
> Subject: [PATCH] IntelSiliconPkg IntelVTdDxe: Support early SetAttributes()
>
> Support early SetAttributes() before DMAR table is installed.
>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Star Zeng <star.zeng@intel.com>
> ---
> .../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(-)
>
> 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;
>
> EDKII_PLATFORM_VTD_POLICY_PROTOCOL *mPlatformVTdPolicy;
>
> +VTD_ACCESS_REQUEST *mAccessRequest = NULL;
> +UINTN mAccessRequestCount = 0;
> +UINTN mAccessRequestMaxCount = 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=0,
> + // Check previous records and remove the matched entry.
> + //
> + if (IoMmuAccess == 0) {
> + for (Index = 0; Index < mAccessRequestCount; Index++) {
> + if ((mAccessRequest[Index].Segment == Segment) &&
> + (mAccessRequest[Index].SourceId.Uint16 == SourceId.Uint16) &&
> + (mAccessRequest[Index].BaseAddress == BaseAddress) &&
> + (mAccessRequest[Index].Length == Length) &&
> + (mAccessRequest[Index].IoMmuAccess != 0)) {
> + //
> + // Remove this record [Index].
> + // No need to add the new record.
> + //
> + if (Index != 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 >= mAccessRequestMaxCount) {
> + NewAccessRequest = AllocateZeroPool (sizeof(*NewAccessRequest) *
> (mAccessRequestMaxCount + MAX_VTD_ACCESS_REQUEST));
> + if (NewAccessRequest == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + mAccessRequestMaxCount += MAX_VTD_ACCESS_REQUEST;
> + if (mAccessRequest != NULL) {
> + CopyMem (NewAccessRequest, mAccessRequest,
> sizeof(*NewAccessRequest) * mAccessRequestCount);
> + FreePool (mAccessRequest);
> + mAccessRequest = NewAccessRequest;
> + }
> + }
> +
> + ASSERT (mAccessRequestCount < mAccessRequestMaxCount);
> +
> + mAccessRequest[mAccessRequestCount].Segment = Segment;
> + mAccessRequest[mAccessRequestCount].SourceId = SourceId;
> + mAccessRequest[mAccessRequestCount].BaseAddress = BaseAddress;
> + mAccessRequest[mAccessRequestCount].Length = Length;
> + mAccessRequest[mAccessRequestCount].IoMmuAccess = 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 = 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 = 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 != NULL) {
> + FreePool (mAccessRequest);
> + }
> + mAccessRequest = NULL;
> + mAccessRequestCount = 0;
> + mAccessRequestMaxCount = 0;
> +
> + DEBUG ((DEBUG_INFO, "ProcessRequestedAccessAttribute Done\n"));
> +}
> +
> /**
> return the UEFI memory information.
>
> @@ -370,6 +515,8 @@ SetupVtd (
>
> ParseDmarAcpiTableRmrr ();
>
> + ProcessRequestedAccessAttribute ();
> +
> for (Index = 0; Index < mVtdUnitNumber; Index++) {
> DEBUG ((DEBUG_INFO,"VTD Unit %d (Segment: %04x)\n", Index,
> mVtdUnitInformation[Index].Segment));
> if (mVtdUnitInformation[Index].ExtRootEntryTable != 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
>
> - Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
> 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;
>
> +//
> +// 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.
>
> @@ -561,4 +576,33 @@ GetPciBusDeviceFunction (
> OUT UINT8 *Function
> );
>
> +/**
> + 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 {
>
> #pragma pack()
>
> -EFI_ACPI_DMAR_HEADER *mAcpiDmarTable;
> +EFI_ACPI_DMAR_HEADER *mAcpiDmarTable = NULL;
>
> /**
> 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.
>
> - Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
> + Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
> 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));
>
> + if (mAcpiDmarTable == NULL) {
> + //
> + // Record the entry to driver global variable.
> + // As such once VTd is activated, the setting can be adopted.
> + //
> + return RequestAccessAttribute (Segment, SourceId, DeviceAddress, Length,
> IoMmuAccess);
> + }
> +
> PERF_CODE (
> AsciiSPrint (PerfToken, sizeof(PerfToken), "S%04xB%02xD%02xF%01x",
> Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function);
> Identifier = (Segment << 16) | SourceId.Uint16;
> --
> 2.7.0.windows.1
prev parent reply other threads:[~2018-01-04 6:09 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-04 3:33 [PATCH] IntelSiliconPkg IntelVTdDxe: Support early SetAttributes() Star Zeng
2018-01-04 6:14 ` Yao, Jiewen [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=74D8A39837DF1E4DA445A8C0B3885C503AA6FDCF@shsmsx102.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox