Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
btwise
OpenCorePKG_MOD
提交
399f05c3
O
OpenCorePKG_MOD
项目概览
btwise
/
OpenCorePKG_MOD
通知
26
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
OpenCorePKG_MOD
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
399f05c3
编写于
8月 16, 2020
作者:
V
vit9696
提交者:
GitHub
8月 16, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
OcMemoryLib: Fix MAT processing for SyncRuntimePermissions (#100)
closes acidanthera/bugtracker#1096
上级
b0e86b3a
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
197 addition
and
126 deletion
+197
-126
Changelog.md
Changelog.md
+1
-0
Library/OcMemoryLib/MemoryAttributes.c
Library/OcMemoryLib/MemoryAttributes.c
+196
-126
未找到文件。
Changelog.md
浏览文件 @
399f05c3
...
...
@@ -13,6 +13,7 @@ OpenCore Changelog
-
Fixed solving some symbols to zero in 11.0 kext inject
-
Reduced OpenCanopy size by restricting boot management access
-
Added
`BuiltinText`
variant for
`TextRenderer`
for older laptops
-
Fixed
`SyncRuntimePermissions`
creating invalid MAT table
#### v0.6.0
-
Fixed sound corruption with AudioDxe
...
...
Library/OcMemoryLib/MemoryAttributes.c
浏览文件 @
399f05c3
...
...
@@ -162,6 +162,84 @@ OcSplitMemoryEntryByAttribute (
return
EFI_SUCCESS
;
}
STATIC
EFI_STATUS
OcExpandAttributeWrite
(
IN
OUT
EFI_MEMORY_ATTRIBUTES_TABLE
*
MemoryAttributesTable
,
IN
OUT
EFI_MEMORY_DESCRIPTOR
*
MemoryAttributesEntry
OPTIONAL
,
IN
UINTN
MaxDescriptors
,
IN
EFI_MEMORY_DESCRIPTOR
*
MemoryMapEntry
,
IN
EFI_PHYSICAL_ADDRESS
CurrentMapAddress
)
{
EFI_PHYSICAL_ADDRESS
NextMatAddress
;
//
// Simply abort on failing to write any new entry.
//
if
(
MemoryAttributesTable
->
NumberOfEntries
>=
MaxDescriptors
)
{
return
EFI_OUT_OF_RESOURCES
;
}
if
(
MemoryAttributesEntry
!=
NULL
)
{
//
// Insert to the middle of MAT table at current MAT entry position.
// Assert that this MAT entry follows this map entry.
//
ASSERT
(
MemoryAttributesEntry
->
PhysicalStart
>
CurrentMapAddress
);
//
// Create a free MAT entry inbetween.
//
CopyMem
(
NEXT_MEMORY_DESCRIPTOR
(
MemoryAttributesEntry
,
MemoryAttributesTable
->
DescriptorSize
),
MemoryAttributesEntry
,
MemoryAttributesTable
->
NumberOfEntries
*
MemoryAttributesTable
->
DescriptorSize
-
((
UINTN
)
MemoryAttributesEntry
-
(
UINTN
)
MemoryAttributesTable
-
sizeof
(
*
MemoryAttributesTable
))
);
//
// Calculate the location of the next MAT entry to get the size of this one.
// This MAT entry will either:
// - fill the whole gap right away, by reaching the next MAT entry.
// MA: [ GAP ][ MAT ]
// MM: [ MAP ]
// - fill part of the gap up to MAP entry end.
// MA: [ GAP ][ MAT ]
// MM: [ MAP ][ OTHER MAP ]
//
NextMatAddress
=
LAST_DESCRIPTOR_ADDR
(
MemoryMapEntry
)
+
1
;
if
(
MemoryAttributesEntry
->
PhysicalStart
<
NextMatAddress
)
{
NextMatAddress
=
MemoryAttributesEntry
->
PhysicalStart
;
}
}
else
{
//
// Append to the end of MAT table.
//
MemoryAttributesEntry
=
(
VOID
*
)
((
UINTN
)
MemoryAttributesTable
+
sizeof
(
*
MemoryAttributesTable
)
+
MemoryAttributesTable
->
NumberOfEntries
*
MemoryAttributesTable
->
DescriptorSize
);
NextMatAddress
=
LAST_DESCRIPTOR_ADDR
(
MemoryMapEntry
)
+
1
;
}
//
// Write the new attribute.
//
MemoryAttributesEntry
->
Type
=
OcRealMemoryType
(
MemoryMapEntry
);
MemoryAttributesEntry
->
PhysicalStart
=
CurrentMapAddress
;
MemoryAttributesEntry
->
VirtualStart
=
0
;
MemoryAttributesEntry
->
NumberOfPages
=
EFI_SIZE_TO_PAGES
(
NextMatAddress
-
CurrentMapAddress
);
MemoryAttributesEntry
->
Attribute
=
EFI_MEMORY_RUNTIME
;
if
(
MemoryAttributesEntry
->
Type
==
EfiRuntimeServicesCode
)
{
MemoryAttributesEntry
->
Attribute
|=
EFI_MEMORY_RO
;
}
else
{
MemoryAttributesEntry
->
Attribute
|=
EFI_MEMORY_XP
;
}
++
MemoryAttributesTable
->
NumberOfEntries
;
return
EFI_SUCCESS
;
}
/**
Expand attributes table by adding memory map runtime entries into it.
Requires sorted memory map.
...
...
@@ -190,147 +268,129 @@ OcExpandAttributesByMap (
EFI_STATUS
Status
;
UINTN
MapIndex
;
UINTN
MatIndex
;
EFI_PHYSICAL_ADDRESS
Las
tMapAddress
;
EFI_PHYSICAL_ADDRESS
Nex
tMapAddress
;
EFI_PHYSICAL_ADDRESS
LastMatAddress
;
EFI_PHYSICAL_ADDRESS
NewNextGluedAddress
;
EFI_PHYSICAL_ADDRESS
NextGluedAddress
;
BOOLEAN
LastMat
;
EFI_PHYSICAL_ADDRESS
CurrentMapAddress
;
MatIndex
=
0
;
Status
=
EFI_NOT_FOUND
;
for
(
MapIndex
=
0
;
MapIndex
<
MemoryMapDescriptors
;
++
MapIndex
)
{
if
(
MemoryMap
->
Type
==
EfiRuntimeServicesCode
||
MemoryMap
->
Type
==
EfiRuntimeServicesData
)
{
//
// Skip MAP entries, which are not RTCode or RTData.
//
if
(
MemoryMap
->
Type
!=
EfiRuntimeServicesCode
&&
MemoryMap
->
Type
!=
EfiRuntimeServicesData
)
{
goto
NEXT_MEMORY_MAP_DESCRIPTOR
;
}
LastMapAddress
=
LAST_DESCRIPTOR_ADDR
(
MemoryMap
);
NextGluedAddress
=
MemoryMap
->
PhysicalStart
;
LastMat
=
FALSE
;
NextMapAddress
=
LAST_DESCRIPTOR_ADDR
(
MemoryMap
)
+
1
;
CurrentMapAddress
=
MemoryMap
->
PhysicalStart
;
while
(
MatIndex
<
MemoryAttributesTable
->
NumberOfEntries
&&
!
LastMat
)
{
//
// Process MAT with RT code or RT data type, which is the last one or resides at MAP entry or after.
//
LastMatAddress
=
LAST_DESCRIPTOR_ADDR
(
MemoryAttributesEntry
);
LastMat
=
MatIndex
+
1
==
MemoryAttributesTable
->
NumberOfEntries
;
if
((
MemoryMap
->
Type
==
EfiRuntimeServicesCode
||
MemoryMap
->
Type
==
EfiRuntimeServicesData
)
&&
(
LastMatAddress
>=
MemoryMap
->
PhysicalStart
||
LastMat
))
{
//
// MAT is a suffix of MAP (MAT ends at MAP end).
//
if
(
NextGluedAddress
==
MemoryAttributesEntry
->
PhysicalStart
&&
LastMatAddress
==
LastMapAddress
)
{
//
// Completed iterating over this MAP entry.
//
break
;
}
//
// Iterate MAT entries till we are over them or till
// we finish iterating this MAP entry memory.
//
while
(
MatIndex
<
MemoryAttributesTable
->
NumberOfEntries
&&
CurrentMapAddress
<
NextMapAddress
)
{
//
// Skip MAT entries, which are not RTCode or RTData.
//
if
(
MemoryAttributesEntry
->
Type
!=
EfiRuntimeServicesCode
&&
MemoryAttributesEntry
->
Type
!=
EfiRuntimeServicesData
)
{
goto
NEXT_MEMORY_ATTRIBUTE_DESCRIPTOR
;
}
//
// MAT is a prefix or an infix of MAP:
// 1. MAT entry at the beginning of MAP entry.
// 2. MAT entry continuing previous MAT entry within MAP entry.
// If this MAT is last, we have a hole in the end.
//
if
(
NextGluedAddress
==
MemoryAttributesEntry
->
PhysicalStart
&&
!
LastMat
)
{
//
// MAT is required to be smaller or equal than MAP by UEFI spec.
//
ASSERT
(
MemoryAttributesEntry
->
NumberOfPages
<=
MemoryMap
->
NumberOfPages
);
NextGluedAddress
=
LastMatAddress
+
1
;
}
else
{
//
// Have a hole between neighbouring MAT entries, 3 variants:
// - MAT is within MAP (but starts later).
// - MAT starts after MAP.
// - No MAT fully covers MAP end (this is the last MAT entry).
// Need to insert a new MAT entry to cover the hole.
//
if
(
MemoryAttributesTable
->
NumberOfEntries
>=
MaxDescriptors
)
{
return
EFI_OUT_OF_RESOURCES
;
}
//
// Skip MAT entries which end before this MAP entry. This should
// not happen normally, as each MAT entry is supposed to be within
// a single RTCode/RTData MAP entry according to UEFI spec, and
// our memory map is sorted.
//
LastMatAddress
=
LAST_DESCRIPTOR_ADDR
(
MemoryAttributesEntry
);
if
(
LastMatAddress
<
MemoryMap
->
PhysicalStart
)
{
goto
NEXT_MEMORY_ATTRIBUTE_DESCRIPTOR
;
}
if
(
!
LastMat
)
{
//
// Append to the middle.
// Choose the next processed address. This is the closest boundary for us:
// - First MAT address, when MAT is within MAP.
// - Last MAP address, when MAT starts after MAP.
//
NewNextGluedAddress
=
MIN
(
MemoryAttributesEntry
->
PhysicalStart
,
LastMapAddress
+
1
);
//
// Copy existing attributes to the right.
//
ASSERT
(
MemoryAttributesEntry
->
PhysicalStart
>
NextGluedAddress
);
CopyMem
(
NEXT_MEMORY_DESCRIPTOR
(
MemoryAttributesEntry
,
MemoryAttributesTable
->
DescriptorSize
),
MemoryAttributesEntry
,
(
MemoryAttributesTable
->
NumberOfEntries
-
MatIndex
)
*
MemoryAttributesTable
->
DescriptorSize
);
}
else
{
//
// Append to the end.
// Next processed address is the end of MAP.
// There are no MATs left to copy.
//
NewNextGluedAddress
=
LastMapAddress
+
1
;
//
// If current MAT is a prefix or an infix of MAP, take it into account.
//
if
(
MemoryAttributesEntry
->
PhysicalStart
==
NextGluedAddress
)
{
NextGluedAddress
=
LastMatAddress
+
1
;
}
else
{
ASSERT
(
MemoryAttributesEntry
->
PhysicalStart
<
NextGluedAddress
);
}
//
// Update current entry the new the last entry we are about to write.
//
MemoryAttributesEntry
=
NEXT_MEMORY_DESCRIPTOR
(
MemoryAttributesEntry
,
MemoryAttributesTable
->
DescriptorSize
);
++
MatIndex
;
}
//
// Write the new attribute.
//
MemoryAttributesEntry
->
Type
=
OcRealMemoryType
(
MemoryMap
);
MemoryAttributesEntry
->
PhysicalStart
=
NextGluedAddress
;
MemoryAttributesEntry
->
VirtualStart
=
0
;
MemoryAttributesEntry
->
NumberOfPages
=
EFI_SIZE_TO_PAGES
(
NewNextGluedAddress
-
NextGluedAddress
);
MemoryAttributesEntry
->
Attribute
=
EFI_MEMORY_RUNTIME
;
if
(
MemoryAttributesEntry
->
Type
==
EfiRuntimeServicesCode
)
{
MemoryAttributesEntry
->
Attribute
|=
EFI_MEMORY_RO
;
}
else
{
MemoryAttributesEntry
->
Attribute
|=
EFI_MEMORY_XP
;
}
//
// Update the next processed address.
// Increase the amount of MAT entries in the table.
// Report success.
//
NextGluedAddress
=
NewNextGluedAddress
;
++
MemoryAttributesTable
->
NumberOfEntries
;
Status
=
EFI_SUCCESS
;
//
// Done processing MATs.
//
if
(
NextGluedAddress
==
LastMapAddress
+
1
)
{
break
;
}
}
}
//
// Advance MAP iterator if we found a MAT entry that follows the
// current MAP entry address.
//
if
(
CurrentMapAddress
==
MemoryAttributesEntry
->
PhysicalStart
)
{
//
// Process next MAT.
// Do not increment if it is the last MAT, as we need to fill holes in the end.
// MAT is required to be smaller or equal than MAP by UEFI spec.
// For now just assert on this, but if we find anybody violating this,
// we will have to adapt this code.
//
if
(
!
LastMat
)
{
MemoryAttributesEntry
=
NEXT_MEMORY_DESCRIPTOR
(
MemoryAttributesEntry
,
MemoryAttributesTable
->
DescriptorSize
);
++
MatIndex
;
}
ASSERT
(
MemoryAttributesEntry
->
NumberOfPages
<=
MemoryMap
->
NumberOfPages
);
CurrentMapAddress
=
LastMatAddress
+
1
;
goto
NEXT_MEMORY_ATTRIBUTE_DESCRIPTOR
;
}
//
// At this step we have a hole between the current MAP entry address
// and the MAT entry. Fill it in.
//
Status
=
OcExpandAttributeWrite
(
MemoryAttributesTable
,
MemoryAttributesEntry
,
MaxDescriptors
,
MemoryMap
,
CurrentMapAddress
);
if
(
EFI_ERROR
(
Status
))
{
return
Status
;
}
//
// Advance MAP iterator with the entry we have just added and continue
// processing the next MAT entry.
//
CurrentMapAddress
=
LAST_DESCRIPTOR_ADDR
(
MemoryAttributesEntry
)
+
1
;
NEXT_MEMORY_ATTRIBUTE_DESCRIPTOR:
MemoryAttributesEntry
=
NEXT_MEMORY_DESCRIPTOR
(
MemoryAttributesEntry
,
MemoryAttributesTable
->
DescriptorSize
);
++
MatIndex
;
}
//
// We completed to process this MAP entry, proceed to the next one.
//
if
(
CurrentMapAddress
==
NextMapAddress
)
{
goto
NEXT_MEMORY_MAP_DESCRIPTOR
;
}
//
// We have finished processing all the available MAT entries,
// but this MAP entry has more memory, which is not reflected
// in the MAT table. Add this memory and continue processing
// the next MAP entry.
//
ASSERT
(
CurrentMapAddress
<
NextMapAddress
);
ASSERT
(
MatIndex
==
MemoryAttributesTable
->
NumberOfEntries
);
Status
=
OcExpandAttributeWrite
(
MemoryAttributesTable
,
NULL
,
MaxDescriptors
,
MemoryMap
,
CurrentMapAddress
);
if
(
EFI_ERROR
(
Status
))
{
return
Status
;
}
//
// Increment MatIndex to ensure that we no longer enter the MAT entry
// loop on the next iteration. Do not care updating CurrentMapAddress
// as we will overwrite it immediate on the next MAP entry iteration.
// Do not care updating MemoryAttribute as we will no longer use it.
//
++
MatIndex
;
NEXT_MEMORY_MAP_DESCRIPTOR:
MemoryMap
=
NEXT_MEMORY_DESCRIPTOR
(
MemoryMap
,
DescriptorSize
...
...
@@ -382,6 +442,16 @@ OcRebuildAttributes (
return
EFI_UNSUPPORTED
;
}
//
// MAT is normally sorted, and so far nobody had issues
// caused by unsorted MAT, but we do not want to risk.
//
OcSortMemoryMap
(
MemoryAttributesTable
->
NumberOfEntries
*
MemoryAttributesTable
->
DescriptorSize
,
MemoryAttributesEntry
,
MemoryAttributesTable
->
DescriptorSize
);
//
// Some boards create entry duplicates and lose all non-PE entries
// after loading runtime drivers after EndOfDxe.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录