[Patch V5 09/22] UefiCpuPkg/CpuPageTableLib: Add manual test to check Mask and Attr


duntan
 

Add manual test case to check input Mask and Attribute. The check
steps are:
1.Create Page table to cover [0, 2G]. All fields of MapMask should
be set.
2.Update Page table to set [2G - 8K,2G] from present to non-present.
All fields of MapMask except present should not be set.
3.Still set [2G - 8K, 2G] as not present, this case is permitted.
But set [2G - 8K, 2G] as RW is not permitted.
4.Update Page table to set [2G - 8K, 2G] as present and RW. All
fields of MapMask should be set.

Signed-off-by: Dun Tan <dun.tan@...>
Cc: Eric Dong <eric.dong@...>
Cc: Ray Ni <ray.ni@...>
Cc: Rahul Kumar <rahul1.kumar@...>
Tested-by: Gerd Hoffmann <kraxel@...>
Acked-by: Gerd Hoffmann <kraxel@...>
---
UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 127 insertions(+), 2 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c b/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c
index 3014a03243..52fae1864a 100644
--- a/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c
+++ b/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c
@@ -1,7 +1,7 @@
/** @file
Unit tests of the CpuPageTableLib instance of the CpuPageTableLib class

- Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
@@ -697,6 +697,131 @@ TestCaseManualChangeNx (
return UNIT_TEST_PASSED;
}

+/**
+ Check if the input Mask and Attribute is as expected when creating new page table or
+ updating existing page table.
+
+ @param[in] Context [Optional] An optional parameter that enables:
+ 1) test-case reuse with varied parameters and
+ 2) test-case re-entry for Target tests that need a
+ reboot. This parameter is a VOID* and it is the
+ responsibility of the test author to ensure that the
+ contents are well understood by all test cases that may
+ consume it.
+
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test
+ case was successful.
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+TestCaseToCheckMapMaskAndAttr (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ UINTN PageTable;
+ PAGING_MODE PagingMode;
+ VOID *Buffer;
+ UINTN PageTableBufferSize;
+ IA32_MAP_ATTRIBUTE MapAttribute;
+ IA32_MAP_ATTRIBUTE ExpectedMapAttribute;
+ IA32_MAP_ATTRIBUTE MapMask;
+ RETURN_STATUS Status;
+ IA32_MAP_ENTRY *Map;
+ UINTN MapCount;
+
+ PagingMode = Paging4Level;
+ PageTableBufferSize = 0;
+ PageTable = 0;
+ Buffer = NULL;
+ MapAttribute.Uint64 = 0;
+ MapAttribute.Bits.Present = 1;
+ MapMask.Uint64 = 0;
+ MapMask.Bits.Present = 1;
+ //
+ // Create Page table to cover [0, 2G]. All fields of MapMask should be set.
+ //
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
+ MapMask.Uint64 = MAX_UINT64;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);
+ Buffer = AllocatePages (EFI_SIZE_TO_PAGES (PageTableBufferSize));
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
+
+ //
+ // Update Page table to set [2G - 8K, 2G] from present to non-present. All fields of MapMask except present should not be set.
+ //
+ PageTableBufferSize = 0;
+ MapAttribute.Uint64 = SIZE_2GB - SIZE_8KB;
+ MapMask.Uint64 = 0;
+ MapMask.Bits.Present = 1;
+ MapMask.Bits.ReadWrite = 1;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
+ MapMask.Bits.ReadWrite = 0;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);
+ Buffer = AllocatePages (EFI_SIZE_TO_PAGES (PageTableBufferSize));
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
+
+ //
+ // Still set [2G - 8K, 2G] as not present, this case is permitted. But set [2G - 8K, 2G] as RW is not permitted.
+ //
+ PageTableBufferSize = 0;
+ MapAttribute.Uint64 = 0;
+ MapMask.Uint64 = 0;
+ MapMask.Bits.Present = 1;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
+ MapAttribute.Bits.ReadWrite = 1;
+ MapMask.Bits.ReadWrite = 1;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
+
+ //
+ // Update Page table to set [2G - 8K, 2G] as present and RW. All fields of MapMask should be set.
+ //
+ PageTableBufferSize = 0;
+ MapAttribute.Uint64 = SIZE_2GB - SIZE_8KB;
+ MapAttribute.Bits.ReadWrite = 1;
+ MapAttribute.Bits.Present = 1;
+ MapMask.Uint64 = 0;
+ MapMask.Bits.ReadWrite = 1;
+ MapMask.Bits.Present = 1;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
+ MapMask.Uint64 = MAX_UINT64;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer, &PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
+
+ MapCount = 0;
+ Status = PageTableParse (PageTable, PagingMode, NULL, &MapCount);
+ UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);
+ Map = AllocatePages (EFI_SIZE_TO_PAGES (MapCount* sizeof (IA32_MAP_ENTRY)));
+ Status = PageTableParse (PageTable, PagingMode, Map, &MapCount);
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
+
+ //
+ // There should be two ranges [0, 2G-8k] with RW = 0 and [2G-8k, 2G] with RW = 1
+ //
+ UT_ASSERT_EQUAL (MapCount, 2);
+ UT_ASSERT_EQUAL (Map[0].LinearAddress, 0);
+ UT_ASSERT_EQUAL (Map[0].Length, SIZE_2GB - SIZE_8KB);
+ ExpectedMapAttribute.Uint64 = 0;
+ ExpectedMapAttribute.Bits.Present = 1;
+ UT_ASSERT_EQUAL (Map[0].Attribute.Uint64, ExpectedMapAttribute.Uint64);
+ UT_ASSERT_EQUAL (Map[1].LinearAddress, SIZE_2GB - SIZE_8KB);
+ UT_ASSERT_EQUAL (Map[1].Length, SIZE_8KB);
+ ExpectedMapAttribute.Uint64 = SIZE_2GB - SIZE_8KB;
+ ExpectedMapAttribute.Bits.Present = 1;
+ ExpectedMapAttribute.Bits.ReadWrite = 1;
+ UT_ASSERT_EQUAL (Map[1].Attribute.Uint64, ExpectedMapAttribute.Uint64);
+ return UNIT_TEST_PASSED;
+}
+
/**
Initialize the unit test framework, suite, and unit tests for the
sample unit tests and run the unit tests.
@@ -746,7 +871,7 @@ UefiTestMain (
AddTestCase (ManualTestCase, "Check if the parent entry has different ReadWrite attribute", "Manual Test Case5", TestCaseManualChangeReadWrite, NULL, NULL, NULL);
AddTestCase (ManualTestCase, "Check if the parent entry has different Nx attribute", "Manual Test Case6", TestCaseManualChangeNx, NULL, NULL, NULL);
AddTestCase (ManualTestCase, "Check if the needed size is expected", "Manual Test Case7", TestCaseManualSizeNotMatch, NULL, NULL, NULL);
-
+ AddTestCase (ManualTestCase, "Check MapMask when creating new page table or mapping not-present range", "Manual Test Case8", TestCaseToCheckMapMaskAndAttr, NULL, NULL, NULL);
//
// Populate the Random Test Cases.
//
--
2.31.1.windows.1


Ni, Ray
 

Reviewed-by: Ray Ni <ray.ni@...>

-----Original Message-----
From: Tan, Dun <dun.tan@...>
Sent: Friday, March 24, 2023 2:00 PM
To: devel@edk2.groups.io
Cc: Dong, Eric <eric.dong@...>; Ni, Ray <ray.ni@...>; Kumar,
Rahul R <rahul.r.kumar@...>; Gerd Hoffmann <kraxel@...>
Subject: [Patch V5 09/22] UefiCpuPkg/CpuPageTableLib: Add manual test to
check Mask and Attr

Add manual test case to check input Mask and Attribute. The check
steps are:
1.Create Page table to cover [0, 2G]. All fields of MapMask should
be set.
2.Update Page table to set [2G - 8K,2G] from present to non-present.
All fields of MapMask except present should not be set.
3.Still set [2G - 8K, 2G] as not present, this case is permitted.
But set [2G - 8K, 2G] as RW is not permitted.
4.Update Page table to set [2G - 8K, 2G] as present and RW. All
fields of MapMask should be set.

Signed-off-by: Dun Tan <dun.tan@...>
Cc: Eric Dong <eric.dong@...>
Cc: Ray Ni <ray.ni@...>
Cc: Rahul Kumar <rahul1.kumar@...>
Tested-by: Gerd Hoffmann <kraxel@...>
Acked-by: Gerd Hoffmann <kraxel@...>
---

UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHo
st.c | 129
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++--
1 file changed, 127 insertions(+), 2 deletions(-)

diff --git
a/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTest
Host.c
b/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTest
Host.c
index 3014a03243..52fae1864a 100644
---
a/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTest
Host.c
+++
b/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTest
Host.c
@@ -1,7 +1,7 @@
/** @file
Unit tests of the CpuPageTableLib instance of the CpuPageTableLib class

- Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
@@ -697,6 +697,131 @@ TestCaseManualChangeNx (
return UNIT_TEST_PASSED;
}

+/**
+ Check if the input Mask and Attribute is as expected when creating new
page table or
+ updating existing page table.
+
+ @param[in] Context [Optional] An optional parameter that enables:
+ 1) test-case reuse with varied parameters and
+ 2) test-case re-entry for Target tests that need a
+ reboot. This parameter is a VOID* and it is the
+ responsibility of the test author to ensure that the
+ contents are well understood by all test cases that may
+ consume it.
+
+ @retval UNIT_TEST_PASSED The Unit test has completed and the
test
+ case was successful.
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
+**/
+UNIT_TEST_STATUS
+EFIAPI
+TestCaseToCheckMapMaskAndAttr (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ UINTN PageTable;
+ PAGING_MODE PagingMode;
+ VOID *Buffer;
+ UINTN PageTableBufferSize;
+ IA32_MAP_ATTRIBUTE MapAttribute;
+ IA32_MAP_ATTRIBUTE ExpectedMapAttribute;
+ IA32_MAP_ATTRIBUTE MapMask;
+ RETURN_STATUS Status;
+ IA32_MAP_ENTRY *Map;
+ UINTN MapCount;
+
+ PagingMode = Paging4Level;
+ PageTableBufferSize = 0;
+ PageTable = 0;
+ Buffer = NULL;
+ MapAttribute.Uint64 = 0;
+ MapAttribute.Bits.Present = 1;
+ MapMask.Uint64 = 0;
+ MapMask.Bits.Present = 1;
+ //
+ // Create Page table to cover [0, 2G]. All fields of MapMask should be set.
+ //
+ Status = PageTableMap (&PageTable, PagingMode, Buffer,
&PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
+ MapMask.Uint64 = MAX_UINT64;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer,
&PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);
+ Buffer = AllocatePages (EFI_SIZE_TO_PAGES (PageTableBufferSize));
+ Status = PageTableMap (&PageTable, PagingMode, Buffer,
&PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
+
+ //
+ // Update Page table to set [2G - 8K, 2G] from present to non-present. All
fields of MapMask except present should not be set.
+ //
+ PageTableBufferSize = 0;
+ MapAttribute.Uint64 = SIZE_2GB - SIZE_8KB;
+ MapMask.Uint64 = 0;
+ MapMask.Bits.Present = 1;
+ MapMask.Bits.ReadWrite = 1;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer,
&PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute,
&MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
+ MapMask.Bits.ReadWrite = 0;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer,
&PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute,
&MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);
+ Buffer = AllocatePages (EFI_SIZE_TO_PAGES (PageTableBufferSize));
+ Status = PageTableMap (&PageTable, PagingMode, Buffer,
&PageTableBufferSize, 0, SIZE_2GB, &MapAttribute, &MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
+
+ //
+ // Still set [2G - 8K, 2G] as not present, this case is permitted. But set [2G -
8K, 2G] as RW is not permitted.
+ //
+ PageTableBufferSize = 0;
+ MapAttribute.Uint64 = 0;
+ MapMask.Uint64 = 0;
+ MapMask.Bits.Present = 1;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer,
&PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute,
&MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
+ MapAttribute.Bits.ReadWrite = 1;
+ MapMask.Bits.ReadWrite = 1;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer,
&PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute,
&MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
+
+ //
+ // Update Page table to set [2G - 8K, 2G] as present and RW. All fields of
MapMask should be set.
+ //
+ PageTableBufferSize = 0;
+ MapAttribute.Uint64 = SIZE_2GB - SIZE_8KB;
+ MapAttribute.Bits.ReadWrite = 1;
+ MapAttribute.Bits.Present = 1;
+ MapMask.Uint64 = 0;
+ MapMask.Bits.ReadWrite = 1;
+ MapMask.Bits.Present = 1;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer,
&PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute,
&MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
+ MapMask.Uint64 = MAX_UINT64;
+ Status = PageTableMap (&PageTable, PagingMode, Buffer,
&PageTableBufferSize, SIZE_2GB - SIZE_8KB, SIZE_8KB, &MapAttribute,
&MapMask);
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
+
+ MapCount = 0;
+ Status = PageTableParse (PageTable, PagingMode, NULL, &MapCount);
+ UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);
+ Map = AllocatePages (EFI_SIZE_TO_PAGES (MapCount* sizeof
(IA32_MAP_ENTRY)));
+ Status = PageTableParse (PageTable, PagingMode, Map, &MapCount);
+ UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
+
+ //
+ // There should be two ranges [0, 2G-8k] with RW = 0 and [2G-8k, 2G] with
RW = 1
+ //
+ UT_ASSERT_EQUAL (MapCount, 2);
+ UT_ASSERT_EQUAL (Map[0].LinearAddress, 0);
+ UT_ASSERT_EQUAL (Map[0].Length, SIZE_2GB - SIZE_8KB);
+ ExpectedMapAttribute.Uint64 = 0;
+ ExpectedMapAttribute.Bits.Present = 1;
+ UT_ASSERT_EQUAL (Map[0].Attribute.Uint64,
ExpectedMapAttribute.Uint64);
+ UT_ASSERT_EQUAL (Map[1].LinearAddress, SIZE_2GB - SIZE_8KB);
+ UT_ASSERT_EQUAL (Map[1].Length, SIZE_8KB);
+ ExpectedMapAttribute.Uint64 = SIZE_2GB - SIZE_8KB;
+ ExpectedMapAttribute.Bits.Present = 1;
+ ExpectedMapAttribute.Bits.ReadWrite = 1;
+ UT_ASSERT_EQUAL (Map[1].Attribute.Uint64,
ExpectedMapAttribute.Uint64);
+ return UNIT_TEST_PASSED;
+}
+
/**
Initialize the unit test framework, suite, and unit tests for the
sample unit tests and run the unit tests.
@@ -746,7 +871,7 @@ UefiTestMain (
AddTestCase (ManualTestCase, "Check if the parent entry has different
ReadWrite attribute", "Manual Test Case5",
TestCaseManualChangeReadWrite, NULL, NULL, NULL);
AddTestCase (ManualTestCase, "Check if the parent entry has different Nx
attribute", "Manual Test Case6", TestCaseManualChangeNx, NULL, NULL,
NULL);
AddTestCase (ManualTestCase, "Check if the needed size is expected",
"Manual Test Case7", TestCaseManualSizeNotMatch, NULL, NULL, NULL);
-
+ AddTestCase (ManualTestCase, "Check MapMask when creating new page
table or mapping not-present range", "Manual Test Case8",
TestCaseToCheckMapMaskAndAttr, NULL, NULL, NULL);
//
// Populate the Random Test Cases.
//
--
2.31.1.windows.1