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@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Dun Tan 2023-02-24 15:25:09 +08:00 committed by mergify[bot]
parent a926c6c49e
commit 14ef21e559

View File

@ -1,7 +1,7 @@
/** @file /** @file
Unit tests of the CpuPageTableLib instance of the CpuPageTableLib class 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 SPDX-License-Identifier: BSD-2-Clause-Patent
**/ **/
@ -697,6 +697,131 @@ TestCaseManualChangeNx (
return UNIT_TEST_PASSED; 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 Initialize the unit test framework, suite, and unit tests for the
sample unit tests and run the unit tests. 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 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 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 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. // Populate the Random Test Cases.
// //