public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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



      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