From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web09.17911.1605663566714724939 for ; Tue, 17 Nov 2020 17:39:26 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=Ve+XFX6H; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: jiewen.yao@intel.com) IronPort-SDR: Sp6tf9tkyZ/KK5xxkY+gwXBAQxsseeBchyyw8hZN9RutTUBoSEhD8FikG4j3a7CM5pYSMMj7dt VetMlMVz6YGw== X-IronPort-AV: E=McAfee;i="6000,8403,9808"; a="167537446" X-IronPort-AV: E=Sophos;i="5.77,486,1596524400"; d="scan'208";a="167537446" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Nov 2020 17:39:25 -0800 IronPort-SDR: v28XTob7VykHD0oZYTuJx/FJ21QJkAn/VlpMPev6/8LxbrmnLnV4Lw2wht6OZGR2tvonUDXzls RaaRpUE7WyFg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,486,1596524400"; d="scan'208";a="476133367" Received: from fmsmsx602.amr.corp.intel.com ([10.18.126.82]) by orsmga004.jf.intel.com with ESMTP; 17 Nov 2020 17:39:24 -0800 Received: from fmsmsx609.amr.corp.intel.com (10.18.126.89) by fmsmsx602.amr.corp.intel.com (10.18.126.82) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 17 Nov 2020 17:39:24 -0800 Received: from FMSEDG603.ED.cps.intel.com (10.1.192.133) by fmsmsx609.amr.corp.intel.com (10.18.126.89) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5 via Frontend Transport; Tue, 17 Nov 2020 17:39:24 -0800 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (104.47.56.174) by edgegateway.intel.com (192.55.55.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.1713.5; Tue, 17 Nov 2020 17:39:20 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=iZEDutqpxyxcnNdlYAEf2gIE3rbgE1klXQ+7tUWGo+7IurfrUZYMzOXD+FQiOsQHtSduJ0cdkatH52QVNX7na8xcfYRSJ68ER37F1y9XzMLQ6rOMJO/oqc5+5fX7S5eim+JuV4PdtcHcjV9BLN+toLCNo1G7/6Vul9/+YFX5mc/N7jXDIA2kiHt/iVec4GL9Uvho6PdVx/xzAq39pJ6MmOsw+Iq3lFhUstQuc1mBCOptD5pWHMoZtR/eSDQd/ALCDYh90yu4Qaw+qxfSAa06PC6E2ncnaqJ0JQyZVvewmY6rwninEPn3n/jCvV0MLgfjQuAhJ3Bzll8qqZiB68oY8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rl/UKlNWKBP+ppWICMVXQGO03xhbU5++yE9UiDnCYN8=; b=UegmkkTT2oirRaX4CNVNTicoxt7hMmi2u/jwS+11yMkvFqzzihuSjhDvAelvLG7b3CQgNTxMueWgR6MOsQzGYARHg+GJsrXMcONGBcrsq7F84rut6ggJ/2mFzJbSJWsbbrtZ9mpWIIX6onIa3lwVrSl0fOS67TcSFzzee13O0jCSe23zXrgHoBqZvsRTVWjvhqKPTt2ztFuVnn6mWj571RZ0VqfFvBieIvdcnT99Y+Dsva0sDfKNSBUtvlWrUl97xFSwQfThUSShB7dVH9R3kfdVtBCugYGwhUUgogaTYeImvbBwYGgGhWHFVFUjua4uXa2RACTlB75PdvmAtn5klA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rl/UKlNWKBP+ppWICMVXQGO03xhbU5++yE9UiDnCYN8=; b=Ve+XFX6Hyi8EzRQlmxDJ2lseXz9D7SNayjDRpdnff8Rh12T+IXmv1e4sOY8jgPMmkItrthQ7RCguMGC/F3M8WsLcJyiXF0y0j85ETbogtWFhC7A+iwv2aA6emByfhJJsIwMJ579vLFABMEv8pug/9sVkCgZnv3rkoH3pwIqsnsk= Received: from CY4PR11MB1288.namprd11.prod.outlook.com (2603:10b6:903:23::8) by CY4PR11MB1733.namprd11.prod.outlook.com (2603:10b6:903:11e::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3541.21; Wed, 18 Nov 2020 01:39:19 +0000 Received: from CY4PR11MB1288.namprd11.prod.outlook.com ([fe80::a188:2994:6c14:aad7]) by CY4PR11MB1288.namprd11.prod.outlook.com ([fe80::a188:2994:6c14:aad7%12]) with mapi id 15.20.3541.028; Wed, 18 Nov 2020 01:39:19 +0000 From: "Yao, Jiewen" To: "Sheng, W" , "devel@edk2.groups.io" CC: "Ni, Ray" , "Chaganty, Rangasai V" , "Huang, Jenny" Subject: Re: [PATCH v3] IntelSiliconPkg/VTd: Add iommu 5 level paging support Thread-Topic: [PATCH v3] IntelSiliconPkg/VTd: Add iommu 5 level paging support Thread-Index: AQHWvUiqP8rAhooazkGUHtUeC8kg4anNGfxA Date: Wed, 18 Nov 2020 01:39:19 +0000 Message-ID: References: <20201118011755.13732-1-w.sheng@intel.com> In-Reply-To: <20201118011755.13732-1-w.sheng@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-version: 11.5.1.3 dlp-product: dlpe-windows dlp-reaction: no-action authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=intel.com; x-originating-ip: [192.198.147.195] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 04328b3f-3439-4bba-451a-08d88b62c49d x-ms-traffictypediagnostic: CY4PR11MB1733: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:9508; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: SuBFEhoDXVm+SmVUdtJKXZhYkrZNkk5ydj0MNznXNZRMFH3aiPdVruBaVF9h4tKO0TXkt//RmPM/jwsz1ezAQrX0qKLOYC6W1xIqS46ndaXwb6u2hh0PrOsXB2KaB50hZA8eoRsvrK565MBvuRjHoYN3dpeViTt3Kvj0InQ5Wxw9/fWEWMLp10QNd7YC++x5meML/h2XvkbXekPwVdSwHvMD2j6E9Ozdx9Zuh1E5rYQzPPcXrXjtCfArnEyRXMNTJB7fydHJiV72w8wh6cUzwD6nxbEmZvukJxlqVNxTop92ueMjIIQ0HbNRCIjR8rtk6QHirN8vewrgzzmZ/kqDVOUdkxJ2G7POx3bq/VgVdZROG5mBomSOGX+OR4L/ot7YBifaK2I5/hygXgjw16CI6Q== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY4PR11MB1288.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(366004)(186003)(64756008)(2906002)(107886003)(26005)(110136005)(55016002)(71200400001)(5660300002)(54906003)(30864003)(9686003)(52536014)(498600001)(66946007)(66556008)(33656002)(66476007)(8676002)(86362001)(4326008)(66446008)(966005)(7696005)(6506007)(8936002)(83380400001)(76116006)(53546011)(559001)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: 2pVV+WmRMhnNj52VqpK2/l55HdejXBs8s4hYmfQuk7muQvo4cnlsrOQ7k4ioy+cNpvs/1DjYRCFV7Y9cnkqBhd6GItXFroMaO1tjDNEkiNKLoFlQDBjqyO2H9oXK8K9wxejvIa3uhUS5a7WkifgZOuVYW9xFkFutdEBzfFsgTHU0oMZGNttbdi/P7n/RlhmnySKMjjroOIOwpx5ngmYGi47senZMQhHNAQkjMe6MkWXYOaP4Tqg77sa0LNMHEBQp21DQ/c7oyy41dL1G1n1LsbDyljKbBGRz9KLOao8AzONWRRxEaQjPGKFcTFV41+fEtLho3vuZHPXFi5GUT6emkLu6YBubRmOVkmxNtBXFdZ5amVv1AHJ3sK0hK4ntRRTv9z9TfEtCt+eO9twKO0Al7Z8X9wld9M923H23VI64lZeamr2F9zUWCGXUJnByVsNYgw7+dEn/uIoFCFopi1qABkxeFJxGZ/lVOWa5amkFcKxdKWvpZ3uZbdTkPfRYHlHWhUFKrROTC0IzP0MpWSDjJEKe5yft4AT+3HyiJo73hFFZXcR2H2Q+Tj+yYRzeALL1MAOV/rbIfWG0XkITw7M5pk3nBkqoRpAZmqc8MAexoxTHF92p0WFWod6CsFG39kuFX0Zj5LLPqlbuEdZ9mcnycQ== MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CY4PR11MB1288.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 04328b3f-3439-4bba-451a-08d88b62c49d X-MS-Exchange-CrossTenant-originalarrivaltime: 18 Nov 2020 01:39:19.3302 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 6dUE/1wls+NCCL7krpeSdpVrAaxhT4Md73SmZN2LSgDTgd4ioCiz43jk6dEn4/Pr2b70tMBIjWNN+ywxSZChug== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR11MB1733 Return-Path: jiewen.yao@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi I have 2 comments: 1) below capability check seems not correct. (SAGAW & BIT3) is for 5 level only. We need check (SAGAW & BIT2) for 4 level. But I do not see the code. Do I m= iss something? if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT3) !=3D 0) { if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT3) !=3D 0) { DEBUG((DEBUG_ERROR, "Force to use 4-level page-table on VTD %d\n", = VtdIndex)); ContextEntry->Bits.AddressWidth =3D 0x2; } if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT4) !=3D 0) { DEBUG((DEBUG_ERROR, "Force to use 5-level page-table on VTD %d\n", = VtdIndex)); ContextEntry->Bits.AddressWidth =3D 0x3; mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D TRUE; } else { if (mAcpiDmarTable->HostAddressWidth > 48) { DEBUG((DEBUG_ERROR, "Using 5-level page-table on VTD %d\n", VtdIn= dex)); ContextEntry->Bits.AddressWidth =3D 0x3; mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D TRUE; } else { DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", VtdIn= dex)); ContextEntry->Bits.AddressWidth =3D 0x2; } } 2) I am wondering, do we really need 2 bit for level selection ? What if force 4 level, but the platform does not support? What if force 5 level, but the platform does not support? # BIT3: Force to use 4 level paging. # BIT4: If iommu support 5 level paging, force to use 5 level paging. # (If both BIT3 and BIT4 are set, force to use 4 level paging.) gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask|1|UINT8|0x0000000= 2 Can we align the solution in DXE/SMM paging solution? > -----Original Message----- > From: Sheng, W > Sent: Wednesday, November 18, 2020 9:18 AM > To: devel@edk2.groups.io > Cc: Ni, Ray ; Chaganty, Rangasai V > ; Yao, Jiewen ; > Huang, Jenny > Subject: [PATCH v3] IntelSiliconPkg/VTd: Add iommu 5 level paging support >=20 > Support iommu 5 level paging for translation table. >=20 > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3067 >=20 > 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 | 287 +++++++++++++++= -- > ---- > .../Feature/VTd/IntelVTdDxe/TranslationTableEx.c | 35 ++- > .../Feature/VTd/IntelVTdDxe/VtdReg.c | 10 +- > Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 3 + > 6 files changed, 258 insertions(+), 100 deletions(-) >=20 > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.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, > mVtdUnitInformation[Index].Segment)); > if (mVtdUnitInformation[Index].ExtRootEntryTable !=3D NULL) { > - DumpDmarExtContextEntryTable > (mVtdUnitInformation[Index].ExtRootEntryTable); > + DumpDmarExtContextEntryTable > (mVtdUnitInformation[Index].ExtRootEntryTable, > 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/DmaProtection.h > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.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/TranslationTable.= c > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.= c > index 201d663d..cb59860a 100644 > --- > a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.= c > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.= c > @@ -128,11 +128,32 @@ CreateContextEntry ( >=20 > DEBUG ((DEBUG_INFO,"Source: S%04x B%02x D%02x F%02x\n", > mVtdUnitInformation[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)= { > + if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT3) !=3D 0) { > + DEBUG((DEBUG_ERROR, "Force to use 4-level page-table on VTD %d\n= ", > VtdIndex)); > + ContextEntry->Bits.AddressWidth =3D 0x2; > + } if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT4) !=3D 0) { > + DEBUG((DEBUG_ERROR, "Force to use 5-level page-table on VTD %d\n= ", > VtdIndex)); > + ContextEntry->Bits.AddressWidth =3D 0x3; > + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D TRUE; > + } else { > + if (mAcpiDmarTable->HostAddressWidth > 48) { > + DEBUG((DEBUG_ERROR, "Using 5-level page-table on VTD %d\n", > VtdIndex)); > + ContextEntry->Bits.AddressWidth =3D 0x3; > + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D TRUE; > + } else { > + DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", > VtdIndex)); > + ContextEntry->Bits.AddressWidth =3D 0x2; > + } > + } > + } else if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) = !=3D > 0) { > + DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", > VtdIndex)); > + ContextEntry->Bits.AddressWidth =3D 0x2; > + } else { > + DEBUG((DEBUG_ERROR, "!!!! Page-table type is not supported on > VTD %d !!!!\n", VtdIndex)); > return EFI_UNSUPPORTED; > } > - ContextEntry->Bits.AddressWidth =3D 0x2; > } >=20 > FlushPageTableMemory (VtdIndex, > (UINTN)mVtdUnitInformation[VtdIndex].RootEntryTable, > EFI_PAGES_TO_SIZE(EntryTablePages)); > @@ -148,6 +169,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 +179,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 +213,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_PAGES_TO_SIZE(1)); > @@ -197,66 +226,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, > Lvl4End)); > + 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, > SIZE_4KB); > - SetSecondLevelPagingEntryAttribute (&Lvl4PtEntry[Index4], > EDKII_IOMMU_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", > Lvl4PagesStart, 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 > *)SecondLevelPagingEntry; > + } 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 > *)SecondLevelPagingEntry; > + } > + > + 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].Uint6= 4, > SIZE_4KB); > + SetSecondLevelPagingEntryAttribute (&Lvl5PtEntry[Index5], > EDKII_IOMMU_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_ADDRESS(Lvl5PtEntry[Index5].Bits.AddressLo, > Lvl5PtEntry[Index5].Bits.AddressHi); > } > - 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_ADDRESS(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].Uint6= 4, > SIZE_4KB); > - SetSecondLevelPagingEntryAttribute (&Lvl3PtEntry[Index3], > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > + FlushPageTableMemory (VtdIndex, (UINTN)Lvl4PtEntry[Index4].Uint6= 4, > SIZE_4KB); > + SetSecondLevelPagingEntryAttribute (&Lvl4PtEntry[Index4], > EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); > } >=20 > - Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, > Lvl3PtEntry[Index3].Bits.AddressHi); > - for (Index2 =3D 0; Index2 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index2++) { > - Lvl2PtEntry[Index2].Uint64 =3D BaseAddress; > - SetSecondLevelPagingEntryAttribute (&Lvl2PtEntry[Index2], > IoMmuAccess); > - Lvl2PtEntry[Index2].Bits.PageSize =3D 1; > - BaseAddress +=3D SIZE_2MB; > + 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; > + } > + DEBUG ((DEBUG_INFO," Lvl4(0x%x): Lvl3Start - 0x%x, Lvl3End - 0x%x= \n", > Index4, Lvl3Start, Lvl3End)); > + > + Lvl3PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(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)AllocateZeroPage= s (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].Uin= t64, > 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.AddressHi); > + for (Index2 =3D 0; Index2 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index2++) { > + Lvl2PtEntry[Index2].Uint64 =3D BaseAddress; > + SetSecondLevelPagingEntryAttribute (&Lvl2PtEntry[Index2], > IoMmuAccess); > + 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], > (UINTN)&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 +338,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 (VtdInd= ex, > SecondLevelPagingEntry, SIZE_4GB, mAbove4GMemoryLimit, IoMmuAccess); > + SecondLevelPagingEntry =3D CreateSecondLevelPagingEntryTable (VtdInd= ex, > SecondLevelPagingEntry, SIZE_4GB, mAbove4GMemoryLimit, IoMmuAccess, > Is5LevelPaging); > if (SecondLevelPagingEntry =3D=3D NULL) { > return NULL; > } > @@ -326,11 +400,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 +435,7 @@ DumpDmarContextEntryTable ( > if (ContextEntry[Index2].Bits.Present =3D=3D 0) { > continue; > } > - DumpSecondLevelPagingEntry ((VOID > *)(UINTN)VTD_64BITS_ADDRESS(ContextEntry[Index2].Bits.SecondLevelPage > TranslationPointerLo, > ContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi)); > + DumpSecondLevelPagingEntry ((VOID > *)(UINTN)VTD_64BITS_ADDRESS(ContextEntry[Index2].Bits.SecondLevelPage > TranslationPointerLo, > ContextEntry[Index2].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 +444,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 +467,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, > Is5LevelPaging - %d\n", SecondLevelPagingEntry, Is5LevelPaging)); >=20 > - DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry Base - 0x%x\n", > SecondLevelPagingEntry)); > + Lvl5IndexEnd =3D Is5LevelPaging ? > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) : 1; > Lvl4PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)SecondLevelPagingEntry; > - for (Index4 =3D 0; Index4 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); 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_ADDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, > Lvl4PtEntry[Index4].Bits.AddressHi); > - 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", > Index3, 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", > Index5, 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_ADDRESS(Lvl5PtEntry[Index5].Bits.AddressLo, > Lvl5PtEntry[Index5].Bits.AddressHi); > + } >=20 > - Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, > Lvl3PtEntry[Index3].Bits.AddressHi); > - 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_ENTRY); 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_ADDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, > Lvl4PtEntry[Index4].Bits.AddressHi); > + 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", > Index3, 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_64BITS_ADDRESS(Lvl2PtEntry[Index2].Bits.AddressLo, > Lvl2PtEntry[Index2].Bits.AddressHi); > - for (Index1 =3D 0; Index1 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index1++) { > - if (Lvl1PtEntry[Index1].Uint64 !=3D 0) { > - DEBUG ((DEBUG_VERBOSE," Lvl1Pt Entry(0x%03x) - 0x%0= 16lx\n", > Index1, Lvl1PtEntry[Index1].Uint64)); > + > + Lvl2PtEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY > *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, > Lvl3PtEntry[Index3].Bits.AddressHi); > + 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)); > + } > + 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_64BITS_ADDRESS(Lvl2PtEntry[Index2].Bits.AddressLo, > Lvl2PtEntry[Index2].Bits.AddressHi); > + for (Index1 =3D 0; Index1 < > SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index1++) { > + if (Lvl1PtEntry[Index1].Uint64 !=3D 0) { > + DEBUG ((DEBUG_VERBOSE," Lvl1Pt Entry(0x%03x) - 0x%0= 16lx\n", > Index1, Lvl1PtEntry[Index1].Uint64)); > + } > } > } > } > @@ -510,6 +606,7 @@ PageAttributeToLength ( > @param[in] VtdIndex The index used to identify a VTd= engine. > @param[in] SecondLevelPagingEntry The second level paging entry in > VTd 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 e= ntry. >=20 > @return The page entry. > @@ -519,6 +616,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 +624,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_ADDRESS_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 +904,7 @@ SetSecondLevelPagingAttribute ( > } >=20 > while (Length !=3D 0) { > - PageEntry =3D GetSecondLevelPageTableEntry (VtdIndex, > SecondLevelPagingEntry, BaseAddress, &PageAttribute); > + PageEntry =3D GetSecondLevelPageTableEntry (VtdIndex, > SecondLevelPagingEntry, BaseAddress, > mVtdUnitInformation[VtdIndex].Is5LevelPaging, &PageAttribute); > if (PageEntry =3D=3D NULL) { > DEBUG ((DEBUG_ERROR, "PageEntry - NULL\n")); > return RETURN_UNSUPPORTED; > @@ -913,7 +1032,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, SourceId.Bits.Device, SourceId.Bits.Function)); > Pt =3D (UINT64)RShiftU64 ((UINT64)(UINTN)SecondLevelPagingEntry, 1= 2); >=20 > @@ -922,7 +1041,7 @@ SetAccessAttribute ( > ExtContextEntry->Bits.DomainIdentifier =3D DomainIdentifier; > ExtContextEntry->Bits.Present =3D 1; > FlushPageTableMemory (VtdIndex, (UINTN)ExtContextEntry, > sizeof(*ExtContextEntry)); > - DumpDmarExtContextEntryTable > (mVtdUnitInformation[VtdIndex].ExtRootEntryTable); > + DumpDmarExtContextEntryTable > (mVtdUnitInformation[VtdIndex].ExtRootEntryTable, > mVtdUnitInformation[VtdIndex].Is5LevelPaging); > mVtdUnitInformation[VtdIndex].HasDirtyContext =3D TRUE; > } else { > SecondLevelPagingEntry =3D (VOID > *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry- > >Bits.SecondLevelPageTranslationPointerLo, ExtContextEntry- > >Bits.SecondLevelPageTranslationPointerHi); > @@ -930,7 +1049,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, SourceId.Bits.Device, SourceId.Bits.Function)); > Pt =3D (UINT64)RShiftU64 ((UINT64)(UINTN)SecondLevelPagingEntry, 1= 2); >=20 > @@ -939,7 +1058,7 @@ SetAccessAttribute ( > ContextEntry->Bits.DomainIdentifier =3D DomainIdentifier; > ContextEntry->Bits.Present =3D 1; > FlushPageTableMemory (VtdIndex, (UINTN)ContextEntry, > sizeof(*ContextEntry)); > - DumpDmarContextEntryTable > (mVtdUnitInformation[VtdIndex].RootEntryTable); > + DumpDmarContextEntryTable > (mVtdUnitInformation[VtdIndex].RootEntryTable, > mVtdUnitInformation[VtdIndex].Is5LevelPaging); > mVtdUnitInformation[VtdIndex].HasDirtyContext =3D TRUE; > } else { > SecondLevelPagingEntry =3D (VOID > *)(UINTN)VTD_64BITS_ADDRESS(ContextEntry- > >Bits.SecondLevelPageTranslationPointerLo, ContextEntry- > >Bits.SecondLevelPageTranslationPointerHi); > @@ -1000,7 +1119,7 @@ AlwaysEnablePageAttribute ( >=20 > if (mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry =3D=3D 0= ) { > DEBUG((DEBUG_INFO, "CreateSecondLevelPagingEntry - %d\n", > VtdIndex)); > - mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry =3D > CreateSecondLevelPagingEntry (VtdIndex, EDKII_IOMMU_ACCESS_READ | > EDKII_IOMMU_ACCESS_WRITE); > + mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry =3D > CreateSecondLevelPagingEntry (VtdIndex, EDKII_IOMMU_ACCESS_READ | > EDKII_IOMMU_ACCESS_WRITE, > mVtdUnitInformation[VtdIndex].Is5LevelPaging); > } >=20 > SecondLevelPagingEntry =3D > mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry; > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableE= x. > c > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableE= x. > c > index 0ed9e3ca..3918eeee 100644 > --- > a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableE= x. > c > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableE= x. > c > @@ -78,11 +78,32 @@ CreateExtContextEntry ( >=20 > DEBUG ((DEBUG_INFO,"DOMAIN: S%04x, B%02x D%02x F%02x\n", > mVtdUnitInformation[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)= { > + if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT3) !=3D 0) { > + DEBUG((DEBUG_ERROR, "Force to use 4-level page-table on VTD %d\n= ", > VtdIndex)); > + ExtContextEntry->Bits.AddressWidth =3D 0x2; > + } if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT4) !=3D 0) { > + DEBUG((DEBUG_ERROR, "Force to use 5-level page-table on VTD %d\n= ", > VtdIndex)); > + ExtContextEntry->Bits.AddressWidth =3D 0x3; > + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D TRUE; > + } else { > + if (mAcpiDmarTable->HostAddressWidth > 48) { > + DEBUG((DEBUG_ERROR, "Using 5-level page-table on VTD %d\n", > VtdIndex)); > + ExtContextEntry->Bits.AddressWidth =3D 0x3; > + mVtdUnitInformation[VtdIndex].Is5LevelPaging =3D TRUE; > + } else { > + DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", > VtdIndex)); > + ExtContextEntry->Bits.AddressWidth =3D 0x2; > + } > + } > + } else if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) = !=3D > 0) { > + DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", > VtdIndex)); > + ExtContextEntry->Bits.AddressWidth =3D 0x2; > + } else { > + DEBUG((DEBUG_ERROR, "!!!! Page-table type is not supported on > VTD %d !!!!\n", VtdIndex)); > return EFI_UNSUPPORTED; > } > - ExtContextEntry->Bits.AddressWidth =3D 0x2; > } >=20 > FlushPageTableMemory (VtdIndex, > (UINTN)mVtdUnitInformation[VtdIndex].ExtRootEntryTable, > EFI_PAGES_TO_SIZE(EntryTablePages)); > @@ -93,11 +114,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 +150,7 @@ DumpDmarExtContextEntryTable ( > if (ExtContextEntry[Index2].Bits.Present =3D=3D 0) { > continue; > } > - DumpSecondLevelPagingEntry ((VOID > *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry[Index2].Bits.SecondLevelPa > geTranslationPointerLo, > ExtContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi)); > + DumpSecondLevelPagingEntry ((VOID > *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry[Index2].Bits.SecondLevelPa > geTranslationPointerLo, > 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 > VTD %d !!!!\n", Index, mVtdUnitInformation[Index].CapReg.Bits.SAGAW)); > return ; > } >=20 > diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec > b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec > index 284820af..8f1edfe2 100644 > --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec > +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec > @@ -95,6 +95,9 @@ > # BIT0: Enable IOMMU during boot (If DMAR table is installed in DXE. = If > VTD_INFO_PPI is installed in PEI.) > # BIT1: Enable IOMMU when transfer control to OS (ExitBootService in > normal boot. EndOfPEI in S3) > # BIT2: Force no IOMMU access attribute request recording before DMAR > table is installed. > + # BIT3: Force to use 4 level paging. > + # BIT4: If iommu support 5 level paging, force to use 5 level paging. > + # (If both BIT3 and BIT4 are set, force to use 4 level paging.) > # @Prompt The policy for VTd driver behavior. >=20 > gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask|1|UINT8|0x000 > 00002 >=20 > -- > 2.16.2.windows.1