With the following paging structure that maps [0, 2G] with ReadWrite
bit set.
PML4[0] --> PDPTE[0] --> PDE[0-255]
\-> PDPTE[1] --> PDE[0-255]
If ReadWrite bit is cleared in PML4[0] and PageTableMap() is called
to change [0, 2M] as writable, today's logic doesn't inherit the
parent entry's attributes when determining the child entry's
attributes. It just sets the PDPTE[0].PDE[0].ReadWrite bit.
But since the PML4[0].ReadWrite is 0, [0, 2M] is still read-only.
The change fixes the bug.
If the inheritable attributes in ParentPagingEntry conflicts with the
requested attributes, let the child entries take the parent attributes
and loosen the attribute in the parent entry.
E.g.: when PDPTE[0].ReadWrite = 0 but caller wants to map [0-2MB as
ReadWrite = 1 (PDE[0].ReadWrite = 1), we need to change
PDPTE[0].ReadWrite = 1 and let all PDE[0-255].ReadWrite = 0 first.
Then change PDE[0].ReadWrite = 1.
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Today's logic wrongly treats the non-leaf entry as leaf entry and
updates its paging attributes.
The patch fixes the bug to only update paging attributes for
non-present entries or leaf entries.
Signed-off-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
When PageTableMap() is called to create non 1:1 mapping
such as [0, 1G) to [8K, 1G+8K), it should split the page entry to the
4K page level, but old logic has a bug that it just uses 1G page
entry.
The patch fixes the bug.
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
The patch replaces
LinearAddress + Offset == RegionStart
with
((LinearAddress + Offset) & RegionMask) == 0
The replace should not cause any behavior change.
Because:
1. In first loop of while when LinearAddress + Offset == RegionStart,
because the lower "BitStart" bits of RegionStart are all-zero,
all lower "BitStart" bits of (LinearAddress + Offset) are all-zero.
Because all lower "BitStart" bits of RegionMask is all-one and
bits are all-zero, ((LinearAddress + Offset) & RegionMask) == 0.
2. In following loops of the while, even RegionStart is increased
by RegionLength, the lower "BitStart" bits are still all-zero.
So the two expressions still semantically equal to each other.
Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
When LinearAddress or Length is not aligned on 4KB, PageTableMap()
should return Invalid Parameter.
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
The lib includes two APIs:
* PageTableMap
It creates/updates mapping from LA to PA.
The implementation only supports paging structures used in 64bit
mode now. PAE paging structure support will be added in future.
* PageTableParse
It parses the page table and returns the mapping relations in an
array of IA32_MAP_ENTRY.
It passed some stress tests. These test code will be upstreamed in
other patches following edk2 Unit Test framework.
Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>