From nobody Sun Apr 28 23:31:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+67865+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+67865+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1606196316; cv=none; d=zohomail.com; s=zohoarc; b=NDNRdrBme5gScpDGP3GRViajt3ZGMJZywtGLRIazgYtgbFsAUcWy5NZbv1H9SvNziuEn/Mo/TD5KmSn0M6zPEVStPBXH8FBpkDGzAlgPXNbu+ySUMpv7V8yE0W1DqT0fEjLZIjNAwkNB1ksG4rmbGPyTl81RWZdWwXwWnlU82XU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1606196316; h=Cc:Date:From:List-Id:List-Unsubscribe:Message-ID:Reply-To:Sender:Subject:To; bh=64U0uA5atl9XgU2vvxIratLf6yzWVfAopOCGrlJrbs8=; b=dfh3vR39P5IobVjfyGtwIuxqe4Ft48qWCdUtx3l5f1wFR9IKL9/zA1+uMEzweqF4EgH7xmu8prpacM+Gj64sVI5F5FWoRNTPz+SiuhvT+JqydHelpqkP/W9tcPIkyy6DgQxfwjJ+I4ZeqIExkJOt1Q7OS8g5fJjeeZLyVzAXkwU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+67865+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1606196316083917.9739199674104; Mon, 23 Nov 2020 21:38:36 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 7CuGYY1788612xYWhJGoZafx; Mon, 23 Nov 2020 21:38:35 -0800 X-Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web08.47976.1606196314766363246 for ; Mon, 23 Nov 2020 21:38:35 -0800 IronPort-SDR: bFmCu45pS7KMYuolKWCI6LGCuLVVefeEE1HzvYWDiMflV5oLHXy2J9djVkHDWDf8+7bDhKxTA9 Am0wiMDmqMgw== X-IronPort-AV: E=McAfee;i="6000,8403,9814"; a="158934935" X-IronPort-AV: E=Sophos;i="5.78,365,1599548400"; d="scan'208";a="158934935" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Nov 2020 21:38:33 -0800 IronPort-SDR: MvnaMoKyRqzfsiqyJNDodCGMrs//MLAFmm0Bk5n+lQfveWSq2QRyWd2YTCzrpqQVlfM0h9KhbK ae/QPuE88eCg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,365,1599548400"; d="scan'208";a="361732504" X-Received: from shwdesssddpdwei.ccr.corp.intel.com ([10.239.157.46]) by fmsmga004.fm.intel.com with ESMTP; 23 Nov 2020 21:38:31 -0800 From: "Sheng Wei" To: devel@edk2.groups.io Cc: Ray Ni , Rangasai V Chaganty , Jiewen Yao , Jenny Huang Subject: [edk2-devel] [PATCH v5] IntelSiliconPkg/VTd: Add iommu 5 level paging support Date: Tue, 24 Nov 2020 13:38:28 +0800 Message-Id: <20201124053828.25368-1-w.sheng@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,w.sheng@intel.com X-Gm-Message-State: gNVV8OS1ox6Ry0a9wFK0qJnEx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1606196315; bh=fMh9tzw56wsPX+p5RGNopMIN9P6ZP79pn41ln5H3qX0=; h=Cc:Date:From:Reply-To:Subject:To; b=dOUCHfL518noq3JMD/w+NVilv2lVuO5ol3c+oZ3802L8tp+maRq3WfedvivGcslJT6g fDERNgNNQldzt5KW0rlu7nRgZT2s6ATt/gWGMe/gIPAidlXbPW23KCFQ0GJopyxrRdpAs xBT37ru8oULJQMC/iODTCnm8g/B/qPO3bro= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Support iommu 5 level paging for translation table. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3067 Signed-off-by: Sheng Wei Cc: Ray Ni Cc: Rangasai V Chaganty Cc: Jiewen Yao Cc: Jenny Huang --- .../Feature/VTd/IntelVTdDxe/DmaProtection.c | 4 +- .../Feature/VTd/IntelVTdDxe/DmaProtection.h | 19 +- .../Feature/VTd/IntelVTdDxe/TranslationTable.c | 281 +++++++++++++++--= ---- .../Feature/VTd/IntelVTdDxe/TranslationTableEx.c | 31 ++- .../Feature/VTd/IntelVTdDxe/VtdReg.c | 10 +- 5 files changed, 245 insertions(+), 100 deletions(-) diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProte= ction.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtecti= on.c index 9b6135ef..628565ee 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c @@ -523,10 +523,10 @@ SetupVtd ( for (Index =3D 0; Index < mVtdUnitNumber; Index++) { DEBUG ((DEBUG_INFO,"VTD Unit %d (Segment: %04x)\n", Index, mVtdUnitInf= ormation[Index].Segment)); if (mVtdUnitInformation[Index].ExtRootEntryTable !=3D NULL) { - DumpDmarExtContextEntryTable (mVtdUnitInformation[Index].ExtRootEntr= yTable); + DumpDmarExtContextEntryTable (mVtdUnitInformation[Index].ExtRootEntr= yTable, mVtdUnitInformation[Index].Is5LevelPaging); } if (mVtdUnitInformation[Index].RootEntryTable !=3D NULL) { - DumpDmarContextEntryTable (mVtdUnitInformation[Index].RootEntryTable= ); + DumpDmarContextEntryTable (mVtdUnitInformation[Index].RootEntryTable= , mVtdUnitInformation[Index].Is5LevelPaging); } } =20 diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProte= ction.h b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtecti= on.h index a3331db8..f641cea0 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h @@ -77,6 +77,7 @@ typedef struct { BOOLEAN HasDirtyContext; BOOLEAN HasDirtyPages; PCI_DEVICE_INFORMATION PciDeviceInfo; + BOOLEAN Is5LevelPaging; } VTD_UNIT_INFORMATION; =20 // @@ -375,31 +376,37 @@ ParseDmarAcpiTableRmrr ( /** Dump DMAR context entry table. =20 - @param[in] RootEntry DMAR root entry. + @param[in] RootEntry DMAR root entry. + @param[in] Is5LevelPaging If it is the 5 level paging. **/ VOID DumpDmarContextEntryTable ( - IN VTD_ROOT_ENTRY *RootEntry + IN VTD_ROOT_ENTRY *RootEntry, + IN BOOLEAN Is5LevelPaging ); =20 /** Dump DMAR extended context entry table. =20 - @param[in] ExtRootEntry DMAR extended root entry. + @param[in] ExtRootEntry DMAR extended root entry. + @param[in] Is5LevelPaging If it is the 5 level paging. **/ VOID DumpDmarExtContextEntryTable ( - IN VTD_EXT_ROOT_ENTRY *ExtRootEntry + IN VTD_EXT_ROOT_ENTRY *ExtRootEntry, + IN BOOLEAN Is5LevelPaging ); =20 /** Dump DMAR second level paging entry. =20 - @param[in] SecondLevelPagingEntry The second level paging entry. + @param[in] SecondLevelPagingEntry The second level paging entry. + @param[in] Is5LevelPaging If it is the 5 level paging. **/ VOID DumpSecondLevelPagingEntry ( - IN VOID *SecondLevelPagingEntry + IN VOID *SecondLevelPagingEntry, + IN BOOLEAN Is5LevelPaging ); =20 /** diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/Translat= ionTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/Translat= ionTable.c index 201d663d..ede6e0c5 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTabl= e.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTabl= e.c @@ -128,11 +128,26 @@ CreateContextEntry ( =20 DEBUG ((DEBUG_INFO,"Source: S%04x B%02x D%02x F%02x\n", mVtdUnitInform= ation[VtdIndex].Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.= Bits.Function)); =20 - if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) =3D=3D 0)= { - DEBUG((DEBUG_ERROR, "!!!! 4-level page-table is not supported on VTD= %d !!!!\n", VtdIndex)); + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D FALSE; + if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT3) !=3D 0) { + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D TRUE; + if ((mAcpiDmarTable->HostAddressWidth <=3D 48) && + ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) !=3D 0= )) { + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D FALSE; + } + } + } else if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) = =3D=3D 0) { + DEBUG((DEBUG_ERROR, "!!!! Page-table type is not supported on VTD %d= !!!!\n", VtdIndex)); return EFI_UNSUPPORTED; } - ContextEntry->Bits.AddressWidth =3D 0x2; + + if (mVtdUnitInformation[VtdIndex].Is5LevelPaging) { + ContextEntry->Bits.AddressWidth =3D 0x3; + DEBUG((DEBUG_INFO, "Using 5-level page-table on VTD %d\n", VtdIndex)= ); + } else { + ContextEntry->Bits.AddressWidth =3D 0x2; + DEBUG((DEBUG_INFO, "Using 4-level page-table on VTD %d\n", VtdIndex)= ); + } } =20 FlushPageTableMemory (VtdIndex, (UINTN)mVtdUnitInformation[VtdIndex].Roo= tEntryTable, EFI_PAGES_TO_SIZE(EntryTablePages)); @@ -148,6 +163,7 @@ CreateContextEntry ( @param[in] MemoryBase The base of the memory. @param[in] MemoryLimit The limit of the memory. @param[in] IoMmuAccess The IOMMU access. + @param[in] Is5LevelPaging If it is the 5 level paging. =20 @return The second level paging entry. **/ @@ -157,16 +173,23 @@ CreateSecondLevelPagingEntryTable ( IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, IN UINT64 MemoryBase, IN UINT64 MemoryLimit, - IN UINT64 IoMmuAccess + IN UINT64 IoMmuAccess, + IN BOOLEAN Is5LevelPaging ) { + UINTN Index5; UINTN Index4; UINTN Index3; UINTN Index2; + UINTN Lvl5Start; + UINTN Lvl5End; + UINTN Lvl4PagesStart; + UINTN Lvl4PagesEnd; UINTN Lvl4Start; UINTN Lvl4End; UINTN Lvl3Start; UINTN Lvl3End; + VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl5PtEntry; VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl4PtEntry; VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl3PtEntry; VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl2PtEntry; @@ -184,7 +207,7 @@ CreateSecondLevelPagingEntryTable ( if (SecondLevelPagingEntry =3D=3D NULL) { SecondLevelPagingEntry =3D AllocateZeroPages (1); if (SecondLevelPagingEntry =3D=3D NULL) { - DEBUG ((DEBUG_ERROR,"Could not Alloc LVL4 PT. \n")); + DEBUG ((DEBUG_ERROR,"Could not Alloc LVL4 or LVL5 PT. \n")); return NULL; } FlushPageTableMemory (VtdIndex, (UINTN)SecondLevelPagingEntry, EFI_PAG= ES_TO_SIZE(1)); @@ -197,66 +220,109 @@ CreateSecondLevelPagingEntryTable ( return SecondLevelPagingEntry; } =20 - Lvl4Start =3D RShiftU64 (BaseAddress, 39) & 0x1FF; - Lvl4End =3D RShiftU64 (EndAddress - 1, 39) & 0x1FF; + if (Is5LevelPaging) { + Lvl5Start =3D RShiftU64 (BaseAddress, 48) & 0x1FF; + Lvl5End =3D RShiftU64 (EndAddress - 1, 48) & 0x1FF; + DEBUG ((DEBUG_INFO," Lvl5Start - 0x%x, Lvl5End - 0x%x\n", Lvl5Start, = Lvl5End)); =20 - DEBUG ((DEBUG_INFO," Lvl4Start - 0x%x, Lvl4End - 0x%x\n", Lvl4Start, Lv= l4End)); + Lvl4Start =3D RShiftU64 (BaseAddress, 39) & 0x1FF; + Lvl4End =3D RShiftU64 (EndAddress - 1, 39) & 0x1FF; =20 - Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)SecondLevelPagingEntry; - for (Index4 =3D Lvl4Start; Index4 <=3D Lvl4End; Index4++) { - if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { - Lvl4PtEntry[Index4].Uint64 =3D (UINT64)(UINTN)AllocateZeroPages (1); - if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { - DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL4 PAGE FAIL (0x%x)!!!!!!\n= ", Index4)); - ASSERT(FALSE); - return NULL; - } - FlushPageTableMemory (VtdIndex, (UINTN)Lvl4PtEntry[Index4].Uint64, S= IZE_4KB); - SetSecondLevelPagingEntryAttribute (&Lvl4PtEntry[Index4], EDKII_IOMM= U_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); - } + Lvl4PagesStart =3D (Lvl5Start<<9) | Lvl4Start; + Lvl4PagesEnd =3D (Lvl5End<<9) | Lvl4End; + DEBUG ((DEBUG_INFO," Lvl4PagesStart - 0x%x, Lvl4PagesEnd - 0x%x\n", L= vl4PagesStart, Lvl4PagesEnd)); =20 - Lvl3Start =3D RShiftU64 (BaseAddress, 30) & 0x1FF; - if (ALIGN_VALUE_LOW(BaseAddress + SIZE_1GB, SIZE_1GB) <=3D EndAddress)= { - Lvl3End =3D SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) - 1; - } else { - Lvl3End =3D RShiftU64 (EndAddress - 1, 30) & 0x1FF; + Lvl5PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)SecondLevelPagingEntr= y; + } else { + Lvl5Start =3D RShiftU64 (BaseAddress, 48) & 0x1FF; + Lvl5End =3D Lvl5Start; + + Lvl4Start =3D RShiftU64 (BaseAddress, 39) & 0x1FF; + Lvl4End =3D RShiftU64 (EndAddress - 1, 39) & 0x1FF; + DEBUG ((DEBUG_INFO," Lvl4Start - 0x%x, Lvl4End - 0x%x\n", Lvl4Start, = Lvl4End)); + + Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)SecondLevelPagingEntr= y; + } + + for (Index5 =3D Lvl5Start; Index5 <=3D Lvl5End; Index5++) { + if (Is5LevelPaging) { + if (Lvl5PtEntry[Index5].Uint64 =3D=3D 0) { + Lvl5PtEntry[Index5].Uint64 =3D (UINT64)(UINTN)AllocateZeroPages (1= ); + if (Lvl5PtEntry[Index5].Uint64 =3D=3D 0) { + DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL4 PAGE FAIL (0x%x)!!!!!!= \n", Index5)); + ASSERT(FALSE); + return NULL; + } + FlushPageTableMemory (VtdIndex, (UINTN)Lvl5PtEntry[Index5].Uint64,= SIZE_4KB); + SetSecondLevelPagingEntryAttribute (&Lvl5PtEntry[Index5], EDKII_IO= MMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); + } + Lvl4Start =3D Lvl4PagesStart & 0x1FF; + if (((Index5+1)<<9) > Lvl4PagesEnd) { + Lvl4End =3D SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) - 1;; + Lvl4PagesStart =3D (Index5+1)<<9; + } else { + Lvl4End =3D Lvl4PagesEnd & 0x1FF; + } + DEBUG ((DEBUG_INFO," Lvl5(0x%x): Lvl4Start - 0x%x, Lvl4End - 0x%x\n= ", Index5, Lvl4Start, Lvl4End)); + Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_A= DDRESS(Lvl5PtEntry[Index5].Bits.AddressLo, Lvl5PtEntry[Index5].Bits.Address= Hi); } - DEBUG ((DEBUG_INFO," Lvl4(0x%x): Lvl3Start - 0x%x, Lvl3End - 0x%x\n",= Index4, Lvl3Start, Lvl3End)); =20 - Lvl3PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADD= RESS(Lvl4PtEntry[Index4].Bits.AddressLo, Lvl4PtEntry[Index4].Bits.AddressHi= ); - for (Index3 =3D Lvl3Start; Index3 <=3D Lvl3End; Index3++) { - if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { - Lvl3PtEntry[Index3].Uint64 =3D (UINT64)(UINTN)AllocateZeroPages (1= ); - if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { - DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL3 PAGE FAIL (0x%x, 0x%x)= !!!!!!\n", Index4, Index3)); + for (Index4 =3D Lvl4Start; Index4 <=3D Lvl4End; Index4++) { + if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { + Lvl4PtEntry[Index4].Uint64 =3D (UINT64)(UINTN)AllocateZeroPages (1= ); + if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { + DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL4 PAGE FAIL (0x%x)!!!!!!= \n", Index4)); ASSERT(FALSE); return NULL; } - FlushPageTableMemory (VtdIndex, (UINTN)Lvl3PtEntry[Index3].Uint64,= SIZE_4KB); - SetSecondLevelPagingEntryAttribute (&Lvl3PtEntry[Index3], EDKII_IO= MMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); + FlushPageTableMemory (VtdIndex, (UINTN)Lvl4PtEntry[Index4].Uint64,= SIZE_4KB); + SetSecondLevelPagingEntryAttribute (&Lvl4PtEntry[Index4], EDKII_IO= MMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); + } + + Lvl3Start =3D RShiftU64 (BaseAddress, 30) & 0x1FF; + if (ALIGN_VALUE_LOW(BaseAddress + SIZE_1GB, SIZE_1GB) <=3D EndAddres= s) { + Lvl3End =3D SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) - 1; + } else { + Lvl3End =3D RShiftU64 (EndAddress - 1, 30) & 0x1FF; } + DEBUG ((DEBUG_INFO," Lvl4(0x%x): Lvl3Start - 0x%x, Lvl3End - 0x%x\n= ", Index4, Lvl3Start, Lvl3End)); =20 - Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_A= DDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, Lvl3PtEntry[Index3].Bits.Address= Hi); - for (Index2 =3D 0; Index2 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_= ENTRY); Index2++) { - Lvl2PtEntry[Index2].Uint64 =3D BaseAddress; - SetSecondLevelPagingEntryAttribute (&Lvl2PtEntry[Index2], IoMmuAcc= ess); - Lvl2PtEntry[Index2].Bits.PageSize =3D 1; - BaseAddress +=3D SIZE_2MB; + Lvl3PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_A= DDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, Lvl4PtEntry[Index4].Bits.Address= Hi); + for (Index3 =3D Lvl3Start; Index3 <=3D Lvl3End; Index3++) { + if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { + Lvl3PtEntry[Index3].Uint64 =3D (UINT64)(UINTN)AllocateZeroPages = (1); + if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { + DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL3 PAGE FAIL (0x%x, 0x%= x)!!!!!!\n", Index4, Index3)); + ASSERT(FALSE); + return NULL; + } + FlushPageTableMemory (VtdIndex, (UINTN)Lvl3PtEntry[Index3].Uint6= 4, SIZE_4KB); + SetSecondLevelPagingEntryAttribute (&Lvl3PtEntry[Index3], EDKII_= IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); + } + + Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS= _ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, Lvl3PtEntry[Index3].Bits.Addre= ssHi); + for (Index2 =3D 0; Index2 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGIN= G_ENTRY); Index2++) { + Lvl2PtEntry[Index2].Uint64 =3D BaseAddress; + SetSecondLevelPagingEntryAttribute (&Lvl2PtEntry[Index2], IoMmuA= ccess); + Lvl2PtEntry[Index2].Bits.PageSize =3D 1; + BaseAddress +=3D SIZE_2MB; + if (BaseAddress >=3D MemoryLimit) { + break; + } + } + FlushPageTableMemory (VtdIndex, (UINTN)Lvl2PtEntry, SIZE_4KB); if (BaseAddress >=3D MemoryLimit) { break; } } - FlushPageTableMemory (VtdIndex, (UINTN)Lvl2PtEntry, SIZE_4KB); + FlushPageTableMemory (VtdIndex, (UINTN)&Lvl3PtEntry[Lvl3Start], (UIN= TN)&Lvl3PtEntry[Lvl3End + 1] - (UINTN)&Lvl3PtEntry[Lvl3Start]); if (BaseAddress >=3D MemoryLimit) { break; } } - FlushPageTableMemory (VtdIndex, (UINTN)&Lvl3PtEntry[Lvl3Start], (UINTN= )&Lvl3PtEntry[Lvl3End + 1] - (UINTN)&Lvl3PtEntry[Lvl3Start]); - if (BaseAddress >=3D MemoryLimit) { - break; - } + FlushPageTableMemory (VtdIndex, (UINTN)&Lvl4PtEntry[Lvl4Start], (UINTN= )&Lvl4PtEntry[Lvl4End + 1] - (UINTN)&Lvl4PtEntry[Lvl4Start]); } - FlushPageTableMemory (VtdIndex, (UINTN)&Lvl4PtEntry[Lvl4Start], (UINTN)&= Lvl4PtEntry[Lvl4End + 1] - (UINTN)&Lvl4PtEntry[Lvl4Start]); + FlushPageTableMemory (VtdIndex, (UINTN)&Lvl5PtEntry[Lvl5Start], (UINTN)&= Lvl5PtEntry[Lvl5End + 1] - (UINTN)&Lvl5PtEntry[Lvl5Start]); =20 return SecondLevelPagingEntry; } @@ -266,26 +332,28 @@ CreateSecondLevelPagingEntryTable ( =20 @param[in] VtdIndex The index of the VTd engine. @param[in] IoMmuAccess The IOMMU access. + @param[in] Is5LevelPaging If it is the 5 level paging. =20 @return The second level paging entry. **/ VTD_SECOND_LEVEL_PAGING_ENTRY * CreateSecondLevelPagingEntry ( IN UINTN VtdIndex, - IN UINT64 IoMmuAccess + IN UINT64 IoMmuAccess, + IN BOOLEAN Is5LevelPaging ) { VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry; =20 SecondLevelPagingEntry =3D NULL; - SecondLevelPagingEntry =3D CreateSecondLevelPagingEntryTable (VtdIndex, = SecondLevelPagingEntry, 0, mBelow4GMemoryLimit, IoMmuAccess); + SecondLevelPagingEntry =3D CreateSecondLevelPagingEntryTable (VtdIndex, = SecondLevelPagingEntry, 0, mBelow4GMemoryLimit, IoMmuAccess, Is5LevelPaging= ); if (SecondLevelPagingEntry =3D=3D NULL) { return NULL; } =20 if (mAbove4GMemoryLimit !=3D 0) { ASSERT (mAbove4GMemoryLimit > BASE_4GB); - SecondLevelPagingEntry =3D CreateSecondLevelPagingEntryTable (VtdIndex= , SecondLevelPagingEntry, SIZE_4GB, mAbove4GMemoryLimit, IoMmuAccess); + SecondLevelPagingEntry =3D CreateSecondLevelPagingEntryTable (VtdIndex= , SecondLevelPagingEntry, SIZE_4GB, mAbove4GMemoryLimit, IoMmuAccess, Is5Le= velPaging); if (SecondLevelPagingEntry =3D=3D NULL) { return NULL; } @@ -326,11 +394,13 @@ SetupTranslationTable ( /** Dump DMAR context entry table. =20 - @param[in] RootEntry DMAR root entry. + @param[in] RootEntry DMAR root entry. + @param[in] Is5LevelPaging If it is the 5 level paging. **/ VOID DumpDmarContextEntryTable ( - IN VTD_ROOT_ENTRY *RootEntry + IN VTD_ROOT_ENTRY *RootEntry, + IN BOOLEAN Is5LevelPaging ) { UINTN Index; @@ -359,7 +429,7 @@ DumpDmarContextEntryTable ( if (ContextEntry[Index2].Bits.Present =3D=3D 0) { continue; } - DumpSecondLevelPagingEntry ((VOID *)(UINTN)VTD_64BITS_ADDRESS(Contex= tEntry[Index2].Bits.SecondLevelPageTranslationPointerLo, ContextEntry[Index= 2].Bits.SecondLevelPageTranslationPointerHi)); + DumpSecondLevelPagingEntry ((VOID *)(UINTN)VTD_64BITS_ADDRESS(Contex= tEntry[Index2].Bits.SecondLevelPageTranslationPointerLo, ContextEntry[Index= 2].Bits.SecondLevelPageTranslationPointerHi), Is5LevelPaging); } } DEBUG ((DEBUG_INFO,"=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D\n")); @@ -368,17 +438,22 @@ DumpDmarContextEntryTable ( /** Dump DMAR second level paging entry. =20 - @param[in] SecondLevelPagingEntry The second level paging entry. + @param[in] SecondLevelPagingEntry The second level paging entry. + @param[in] Is5LevelPaging If it is the 5 level paging. **/ VOID DumpSecondLevelPagingEntry ( - IN VOID *SecondLevelPagingEntry + IN VOID *SecondLevelPagingEntry, + IN BOOLEAN Is5LevelPaging ) { + UINTN Index5; UINTN Index4; UINTN Index3; UINTN Index2; UINTN Index1; + UINTN Lvl5IndexEnd; + VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl5PtEntry; VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl4PtEntry; VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl3PtEntry; VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl2PtEntry; @@ -386,38 +461,53 @@ DumpSecondLevelPagingEntry ( =20 DEBUG ((DEBUG_VERBOSE,"=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\= n")); DEBUG ((DEBUG_VERBOSE,"DMAR Second Level Page Table:\n")); + DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry Base - 0x%x, Is5LevelPagin= g - %d\n", SecondLevelPagingEntry, Is5LevelPaging)); =20 - DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry Base - 0x%x\n", SecondLeve= lPagingEntry)); + Lvl5IndexEnd =3D Is5LevelPaging ? SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGIN= G_ENTRY) : 1; Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)SecondLevelPagingEntry; - for (Index4 =3D 0; Index4 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTR= Y); Index4++) { - if (Lvl4PtEntry[Index4].Uint64 !=3D 0) { - DEBUG ((DEBUG_VERBOSE," Lvl4Pt Entry(0x%03x) - 0x%016lx\n", Index4,= Lvl4PtEntry[Index4].Uint64)); - } - if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { - continue; - } - Lvl3PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADD= RESS(Lvl4PtEntry[Index4].Bits.AddressLo, Lvl4PtEntry[Index4].Bits.AddressHi= ); - for (Index3 =3D 0; Index3 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_EN= TRY); Index3++) { - if (Lvl3PtEntry[Index3].Uint64 !=3D 0) { - DEBUG ((DEBUG_VERBOSE," Lvl3Pt Entry(0x%03x) - 0x%016lx\n", Ind= ex3, Lvl3PtEntry[Index3].Uint64)); + Lvl5PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)SecondLevelPagingEntry; + + for (Index5 =3D 0; Index5 < Lvl5IndexEnd; Index5++) { + if (Is5LevelPaging) { + if (Lvl5PtEntry[Index5].Uint64 !=3D 0) { + DEBUG ((DEBUG_VERBOSE," Lvl5Pt Entry(0x%03x) - 0x%016lx\n", Index= 5, Lvl5PtEntry[Index5].Uint64)); } - if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { + if (Lvl5PtEntry[Index5].Uint64 =3D=3D 0) { continue; } + Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_A= DDRESS(Lvl5PtEntry[Index5].Bits.AddressLo, Lvl5PtEntry[Index5].Bits.Address= Hi); + } =20 - Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_A= DDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, Lvl3PtEntry[Index3].Bits.Address= Hi); - for (Index2 =3D 0; Index2 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_= ENTRY); Index2++) { - if (Lvl2PtEntry[Index2].Uint64 !=3D 0) { - DEBUG ((DEBUG_VERBOSE," Lvl2Pt Entry(0x%03x) - 0x%016lx\n",= Index2, Lvl2PtEntry[Index2].Uint64)); + for (Index4 =3D 0; Index4 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_EN= TRY); Index4++) { + if (Lvl4PtEntry[Index4].Uint64 !=3D 0) { + DEBUG ((DEBUG_VERBOSE," Lvl4Pt Entry(0x%03x) - 0x%016lx\n", Index= 4, Lvl4PtEntry[Index4].Uint64)); + } + if (Lvl4PtEntry[Index4].Uint64 =3D=3D 0) { + continue; + } + Lvl3PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_A= DDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, Lvl4PtEntry[Index4].Bits.Address= Hi); + for (Index3 =3D 0; Index3 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_= ENTRY); Index3++) { + if (Lvl3PtEntry[Index3].Uint64 !=3D 0) { + DEBUG ((DEBUG_VERBOSE," Lvl3Pt Entry(0x%03x) - 0x%016lx\n", In= dex3, Lvl3PtEntry[Index3].Uint64)); } - if (Lvl2PtEntry[Index2].Uint64 =3D=3D 0) { + if (Lvl3PtEntry[Index3].Uint64 =3D=3D 0) { continue; } - if (Lvl2PtEntry[Index2].Bits.PageSize =3D=3D 0) { - Lvl1PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BI= TS_ADDRESS(Lvl2PtEntry[Index2].Bits.AddressLo, Lvl2PtEntry[Index2].Bits.Add= ressHi); - for (Index1 =3D 0; Index1 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAG= ING_ENTRY); Index1++) { - if (Lvl1PtEntry[Index1].Uint64 !=3D 0) { - DEBUG ((DEBUG_VERBOSE," Lvl1Pt Entry(0x%03x) - 0x%016= lx\n", Index1, Lvl1PtEntry[Index1].Uint64)); + + Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS= _ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, Lvl3PtEntry[Index3].Bits.Addre= ssHi); + for (Index2 =3D 0; Index2 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGIN= G_ENTRY); Index2++) { + if (Lvl2PtEntry[Index2].Uint64 !=3D 0) { + DEBUG ((DEBUG_VERBOSE," Lvl2Pt Entry(0x%03x) - 0x%016lx\n",= Index2, Lvl2PtEntry[Index2].Uint64)); + } + if (Lvl2PtEntry[Index2].Uint64 =3D=3D 0) { + continue; + } + if (Lvl2PtEntry[Index2].Bits.PageSize =3D=3D 0) { + Lvl1PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64= BITS_ADDRESS(Lvl2PtEntry[Index2].Bits.AddressLo, Lvl2PtEntry[Index2].Bits.A= ddressHi); + for (Index1 =3D 0; Index1 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_P= AGING_ENTRY); Index1++) { + if (Lvl1PtEntry[Index1].Uint64 !=3D 0) { + DEBUG ((DEBUG_VERBOSE," Lvl1Pt Entry(0x%03x) - 0x%016= lx\n", Index1, Lvl1PtEntry[Index1].Uint64)); + } } } } @@ -510,6 +600,7 @@ PageAttributeToLength ( @param[in] VtdIndex The index used to identify a VTd e= ngine. @param[in] SecondLevelPagingEntry The second level paging entry in V= Td table for the device. @param[in] Address The address to be checked. + @param[in] Is5LevelPaging If it is the 5 level paging. @param[out] PageAttributes The page attribute of the page ent= ry. =20 @return The page entry. @@ -519,6 +610,7 @@ GetSecondLevelPageTableEntry ( IN UINTN VtdIndex, IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, IN PHYSICAL_ADDRESS Address, + IN BOOLEAN Is5LevelPaging, OUT PAGE_ATTRIBUTE *PageAttribute ) { @@ -526,17 +618,38 @@ GetSecondLevelPageTableEntry ( UINTN Index2; UINTN Index3; UINTN Index4; + UINTN Index5; UINT64 *L1PageTable; UINT64 *L2PageTable; UINT64 *L3PageTable; UINT64 *L4PageTable; + UINT64 *L5PageTable; =20 + Index5 =3D ((UINTN)RShiftU64 (Address, 48)) & PAGING_VTD_INDEX_MASK; Index4 =3D ((UINTN)RShiftU64 (Address, 39)) & PAGING_VTD_INDEX_MASK; Index3 =3D ((UINTN)Address >> 30) & PAGING_VTD_INDEX_MASK; Index2 =3D ((UINTN)Address >> 21) & PAGING_VTD_INDEX_MASK; Index1 =3D ((UINTN)Address >> 12) & PAGING_VTD_INDEX_MASK; =20 - L4PageTable =3D (UINT64 *)SecondLevelPagingEntry; + if (Is5LevelPaging) { + L5PageTable =3D (UINT64 *)SecondLevelPagingEntry; + if (L5PageTable[Index5] =3D=3D 0) { + L5PageTable[Index5] =3D (UINT64)(UINTN)AllocateZeroPages (1); + if (L5PageTable[Index5] =3D=3D 0) { + DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL5 PAGE FAIL (0x%x)!!!!!!\n= ", Index4)); + ASSERT(FALSE); + *PageAttribute =3D PageNone; + return NULL; + } + FlushPageTableMemory (VtdIndex, (UINTN)L5PageTable[Index5], SIZE_4KB= ); + SetSecondLevelPagingEntryAttribute ((VTD_SECOND_LEVEL_PAGING_ENTRY *= )&L5PageTable[Index5], EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); + FlushPageTableMemory (VtdIndex, (UINTN)&L5PageTable[Index5], sizeof(= L5PageTable[Index5])); + } + L4PageTable =3D (UINT64 *)(UINTN)(L5PageTable[Index5] & PAGING_4K_ADDR= ESS_MASK_64); + } else { + L4PageTable =3D (UINT64 *)SecondLevelPagingEntry; + } + if (L4PageTable[Index4] =3D=3D 0) { L4PageTable[Index4] =3D (UINT64)(UINTN)AllocateZeroPages (1); if (L4PageTable[Index4] =3D=3D 0) { @@ -785,7 +898,7 @@ SetSecondLevelPagingAttribute ( } =20 while (Length !=3D 0) { - PageEntry =3D GetSecondLevelPageTableEntry (VtdIndex, SecondLevelPagin= gEntry, BaseAddress, &PageAttribute); + PageEntry =3D GetSecondLevelPageTableEntry (VtdIndex, SecondLevelPagin= gEntry, BaseAddress, mVtdUnitInformation[VtdIndex].Is5LevelPaging, &PageAtt= ribute); if (PageEntry =3D=3D NULL) { DEBUG ((DEBUG_ERROR, "PageEntry - NULL\n")); return RETURN_UNSUPPORTED; @@ -913,7 +1026,7 @@ SetAccessAttribute ( =20 if (ExtContextEntry !=3D NULL) { if (ExtContextEntry->Bits.Present =3D=3D 0) { - SecondLevelPagingEntry =3D CreateSecondLevelPagingEntry (VtdIndex, 0= ); + SecondLevelPagingEntry =3D CreateSecondLevelPagingEntry (VtdIndex, 0= , mVtdUnitInformation[VtdIndex].Is5LevelPaging); DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry - 0x%x (S%04x B%02x D%= 02x F%02x) New\n", SecondLevelPagingEntry, Segment, SourceId.Bits.Bus, Sour= ceId.Bits.Device, SourceId.Bits.Function)); Pt =3D (UINT64)RShiftU64 ((UINT64)(UINTN)SecondLevelPagingEntry, 12); =20 @@ -922,7 +1035,7 @@ SetAccessAttribute ( ExtContextEntry->Bits.DomainIdentifier =3D DomainIdentifier; ExtContextEntry->Bits.Present =3D 1; FlushPageTableMemory (VtdIndex, (UINTN)ExtContextEntry, sizeof(*ExtC= ontextEntry)); - DumpDmarExtContextEntryTable (mVtdUnitInformation[VtdIndex].ExtRootE= ntryTable); + DumpDmarExtContextEntryTable (mVtdUnitInformation[VtdIndex].ExtRootE= ntryTable, mVtdUnitInformation[VtdIndex].Is5LevelPaging); mVtdUnitInformation[VtdIndex].HasDirtyContext =3D TRUE; } else { SecondLevelPagingEntry =3D (VOID *)(UINTN)VTD_64BITS_ADDRESS(ExtCont= extEntry->Bits.SecondLevelPageTranslationPointerLo, ExtContextEntry->Bits.S= econdLevelPageTranslationPointerHi); @@ -930,7 +1043,7 @@ SetAccessAttribute ( } } else if (ContextEntry !=3D NULL) { if (ContextEntry->Bits.Present =3D=3D 0) { - SecondLevelPagingEntry =3D CreateSecondLevelPagingEntry (VtdIndex, 0= ); + SecondLevelPagingEntry =3D CreateSecondLevelPagingEntry (VtdIndex, 0= , mVtdUnitInformation[VtdIndex].Is5LevelPaging); DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry - 0x%x (S%04x B%02x D%= 02x F%02x) New\n", SecondLevelPagingEntry, Segment, SourceId.Bits.Bus, Sour= ceId.Bits.Device, SourceId.Bits.Function)); Pt =3D (UINT64)RShiftU64 ((UINT64)(UINTN)SecondLevelPagingEntry, 12); =20 @@ -939,7 +1052,7 @@ SetAccessAttribute ( ContextEntry->Bits.DomainIdentifier =3D DomainIdentifier; ContextEntry->Bits.Present =3D 1; FlushPageTableMemory (VtdIndex, (UINTN)ContextEntry, sizeof(*Context= Entry)); - DumpDmarContextEntryTable (mVtdUnitInformation[VtdIndex].RootEntryTa= ble); + DumpDmarContextEntryTable (mVtdUnitInformation[VtdIndex].RootEntryTa= ble, mVtdUnitInformation[VtdIndex].Is5LevelPaging); mVtdUnitInformation[VtdIndex].HasDirtyContext =3D TRUE; } else { SecondLevelPagingEntry =3D (VOID *)(UINTN)VTD_64BITS_ADDRESS(Context= Entry->Bits.SecondLevelPageTranslationPointerLo, ContextEntry->Bits.SecondL= evelPageTranslationPointerHi); @@ -1000,7 +1113,7 @@ AlwaysEnablePageAttribute ( =20 if (mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry =3D=3D 0) { DEBUG((DEBUG_INFO, "CreateSecondLevelPagingEntry - %d\n", VtdIndex)); - mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry =3D CreateSe= condLevelPagingEntry (VtdIndex, EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCES= S_WRITE); + mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry =3D CreateSe= condLevelPagingEntry (VtdIndex, EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCES= S_WRITE, mVtdUnitInformation[VtdIndex].Is5LevelPaging); } =20 SecondLevelPagingEntry =3D mVtdUnitInformation[VtdIndex].FixedSecondLeve= lPagingEntry; diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/Translat= ionTableEx.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/Transl= ationTableEx.c index 0ed9e3ca..a4d66bc7 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTabl= eEx.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTabl= eEx.c @@ -78,11 +78,28 @@ CreateExtContextEntry ( =20 DEBUG ((DEBUG_INFO,"DOMAIN: S%04x, B%02x D%02x F%02x\n", mVtdUnitInfor= mation[VtdIndex].Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId= .Bits.Function)); =20 - if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) =3D=3D 0)= { - DEBUG((DEBUG_ERROR, "!!!! 4-level page-table is not supported on VTD= %d !!!!\n", VtdIndex)); + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D FALSE; + if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT3) !=3D 0) { + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D TRUE; + if ((mAcpiDmarTable->HostAddressWidth <=3D 48) && + ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) !=3D 0= )) { + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D FALSE; + } + } + } else if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) = =3D=3D 0) { + DEBUG((DEBUG_ERROR, "!!!! Page-table type is not supported on VTD %d= !!!!\n", VtdIndex)); return EFI_UNSUPPORTED; } - ExtContextEntry->Bits.AddressWidth =3D 0x2; + + if (mVtdUnitInformation[VtdIndex].Is5LevelPaging) { + ExtContextEntry->Bits.AddressWidth =3D 0x3; + DEBUG((DEBUG_INFO, "Using 5-level page-table on VTD %d\n", VtdIndex)= ); + } else { + ExtContextEntry->Bits.AddressWidth =3D 0x2; + DEBUG((DEBUG_INFO, "Using 4-level page-table on VTD %d\n", VtdIndex)= ); + } + + } =20 FlushPageTableMemory (VtdIndex, (UINTN)mVtdUnitInformation[VtdIndex].Ext= RootEntryTable, EFI_PAGES_TO_SIZE(EntryTablePages)); @@ -93,11 +110,13 @@ CreateExtContextEntry ( /** Dump DMAR extended context entry table. =20 - @param[in] ExtRootEntry DMAR extended root entry. + @param[in] ExtRootEntry DMAR extended root entry. + @param[in] Is5LevelPaging If it is the 5 level paging. **/ VOID DumpDmarExtContextEntryTable ( - IN VTD_EXT_ROOT_ENTRY *ExtRootEntry + IN VTD_EXT_ROOT_ENTRY *ExtRootEntry, + IN BOOLEAN Is5LevelPaging ) { UINTN Index; @@ -127,7 +146,7 @@ DumpDmarExtContextEntryTable ( if (ExtContextEntry[Index2].Bits.Present =3D=3D 0) { continue; } - DumpSecondLevelPagingEntry ((VOID *)(UINTN)VTD_64BITS_ADDRESS(ExtCon= textEntry[Index2].Bits.SecondLevelPageTranslationPointerLo, ExtContextEntry= [Index2].Bits.SecondLevelPageTranslationPointerHi)); + DumpSecondLevelPagingEntry ((VOID *)(UINTN)VTD_64BITS_ADDRESS(ExtCon= textEntry[Index2].Bits.SecondLevelPageTranslationPointerLo, ExtContextEntry= [Index2].Bits.SecondLevelPageTranslationPointerHi), Is5LevelPaging); } =20 if (ExtRootEntry[Index].Bits.UpperPresent =3D=3D 0) { diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c= b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c index 699639ba..686d235f 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c @@ -174,8 +174,14 @@ PrepareVtdConfig ( if ((mVtdUnitInformation[Index].CapReg.Bits.SLLPS & BIT0) =3D=3D 0) { DEBUG((DEBUG_WARN, "!!!! 2MB super page is not supported on VTD %d != !!!\n", Index)); } - if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & BIT2) =3D=3D 0) { - DEBUG((DEBUG_ERROR, "!!!! 4-level page-table is not supported on VTD= %d !!!!\n", Index)); + if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & BIT3) !=3D 0) { + DEBUG((DEBUG_INFO, "Support 5-level page-table on VTD %d\n", Index)); + } + if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & BIT2) !=3D 0) { + DEBUG((DEBUG_INFO, "Support 4-level page-table on VTD %d\n", Index)); + } + if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & (BIT3 | BIT2)) =3D= =3D 0) { + DEBUG((DEBUG_ERROR, "!!!! Page-table type 0x%X is not supported on V= TD %d !!!!\n", Index, mVtdUnitInformation[Index].CapReg.Bits.SAGAW)); return ; } =20 --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#67865): https://edk2.groups.io/g/devel/message/67865 Mute This Topic: https://groups.io/mt/78471874/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-