1 | /** @file
|
---|
2 | This module sets default policy for attributes of EfiACPIMemoryNVS and EfiReservedMemoryType.
|
---|
3 |
|
---|
4 | This module sets EFI_MEMORY_XP for attributes of EfiACPIMemoryNVS and EfiReservedMemoryType
|
---|
5 | in UEFI memory map, if and only of PropertiesTable is published and has BIT0 set.
|
---|
6 |
|
---|
7 | Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
---|
8 | This program and the accompanying materials
|
---|
9 | are licensed and made available under the terms and conditions of the BSD License
|
---|
10 | which accompanies this distribution. The full text of the license may be found at
|
---|
11 | http://opensource.org/licenses/bsd-license.php
|
---|
12 |
|
---|
13 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
---|
14 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
---|
15 |
|
---|
16 | **/
|
---|
17 |
|
---|
18 | #include <Uefi.h>
|
---|
19 | #include <Library/DebugLib.h>
|
---|
20 | #include <Library/UefiBootServicesTableLib.h>
|
---|
21 | #include <Library/DxeServicesTableLib.h>
|
---|
22 | #include <Library/UefiLib.h>
|
---|
23 | #include <Library/MemoryAllocationLib.h>
|
---|
24 | #include <Guid/EventGroup.h>
|
---|
25 | #include <Guid/PropertiesTable.h>
|
---|
26 |
|
---|
27 | /**
|
---|
28 | Converts a number of EFI_PAGEs to a size in bytes.
|
---|
29 |
|
---|
30 | NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only.
|
---|
31 |
|
---|
32 | @param Pages The number of EFI_PAGES.
|
---|
33 |
|
---|
34 | @return The number of bytes associated with the number of EFI_PAGEs specified
|
---|
35 | by Pages.
|
---|
36 | **/
|
---|
37 | UINT64
|
---|
38 | EfiPagesToSize (
|
---|
39 | IN UINT64 Pages
|
---|
40 | )
|
---|
41 | {
|
---|
42 | return LShiftU64 (Pages, EFI_PAGE_SHIFT);
|
---|
43 | }
|
---|
44 |
|
---|
45 | /**
|
---|
46 | Set memory attributes according to default policy.
|
---|
47 |
|
---|
48 | @param MemoryMap A pointer to the buffer in which firmware places the current memory map.
|
---|
49 | @param MemoryMapSize Size, in bytes, of the MemoryMap buffer.
|
---|
50 | @param DescriptorSize size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
|
---|
51 | **/
|
---|
52 | VOID
|
---|
53 | SetMemorySpaceAttributesDefault (
|
---|
54 | IN EFI_MEMORY_DESCRIPTOR *MemoryMap,
|
---|
55 | IN UINTN MemoryMapSize,
|
---|
56 | IN UINTN DescriptorSize
|
---|
57 | )
|
---|
58 | {
|
---|
59 | EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
|
---|
60 | EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
|
---|
61 | EFI_STATUS Status;
|
---|
62 |
|
---|
63 | DEBUG ((EFI_D_INFO, "SetMemorySpaceAttributesDefault\n"));
|
---|
64 |
|
---|
65 | MemoryMapEntry = MemoryMap;
|
---|
66 | MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize);
|
---|
67 | while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
|
---|
68 | if (MemoryMapEntry->PhysicalStart < BASE_1MB) {
|
---|
69 | //
|
---|
70 | // Do not touch memory space below 1MB
|
---|
71 | //
|
---|
72 | MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
---|
73 | continue;
|
---|
74 | }
|
---|
75 | switch (MemoryMapEntry->Type) {
|
---|
76 | case EfiRuntimeServicesCode:
|
---|
77 | case EfiRuntimeServicesData:
|
---|
78 | //
|
---|
79 | // should be handled later;
|
---|
80 | //
|
---|
81 | break;
|
---|
82 | case EfiReservedMemoryType:
|
---|
83 | case EfiACPIMemoryNVS:
|
---|
84 | //
|
---|
85 | // Handle EfiReservedMemoryType and EfiACPIMemoryNVS, because there might be firmware executable there.
|
---|
86 | //
|
---|
87 | DEBUG ((EFI_D_INFO, "SetMemorySpaceAttributes - %016lx - %016lx (%016lx) ...\n",
|
---|
88 | MemoryMapEntry->PhysicalStart,
|
---|
89 | MemoryMapEntry->PhysicalStart + EfiPagesToSize (MemoryMapEntry->NumberOfPages),
|
---|
90 | MemoryMapEntry->Attribute
|
---|
91 | ));
|
---|
92 | Status = gDS->SetMemorySpaceCapabilities (
|
---|
93 | MemoryMapEntry->PhysicalStart,
|
---|
94 | EfiPagesToSize (MemoryMapEntry->NumberOfPages),
|
---|
95 | MemoryMapEntry->Attribute | EFI_MEMORY_XP
|
---|
96 | );
|
---|
97 | DEBUG ((EFI_D_INFO, "SetMemorySpaceCapabilities - %r\n", Status));
|
---|
98 | break;
|
---|
99 | }
|
---|
100 |
|
---|
101 | MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
|
---|
102 | }
|
---|
103 |
|
---|
104 | return ;
|
---|
105 | }
|
---|
106 |
|
---|
107 | /**
|
---|
108 | Update memory attributes according to default policy.
|
---|
109 |
|
---|
110 | @param[in] Event The Event this notify function registered to.
|
---|
111 | @param[in] Context Pointer to the context data registered to the Event.
|
---|
112 | **/
|
---|
113 | VOID
|
---|
114 | EFIAPI
|
---|
115 | UpdateMemoryAttributesDefault (
|
---|
116 | EFI_EVENT Event,
|
---|
117 | VOID *Context
|
---|
118 | )
|
---|
119 | {
|
---|
120 | EFI_STATUS Status;
|
---|
121 | EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
---|
122 | UINTN MemoryMapSize;
|
---|
123 | UINTN MapKey;
|
---|
124 | UINTN DescriptorSize;
|
---|
125 | UINT32 DescriptorVersion;
|
---|
126 | EFI_PROPERTIES_TABLE *PropertiesTable;
|
---|
127 |
|
---|
128 | DEBUG ((EFI_D_INFO, "UpdateMemoryAttributesDefault\n"));
|
---|
129 | Status = EfiGetSystemConfigurationTable (&gEfiPropertiesTableGuid, (VOID **) &PropertiesTable);
|
---|
130 | if (EFI_ERROR (Status)) {
|
---|
131 | goto Done;
|
---|
132 | }
|
---|
133 |
|
---|
134 | ASSERT (PropertiesTable != NULL);
|
---|
135 |
|
---|
136 | DEBUG ((EFI_D_INFO, "MemoryProtectionAttribute - 0x%016lx\n", PropertiesTable->MemoryProtectionAttribute));
|
---|
137 | if ((PropertiesTable->MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
|
---|
138 | goto Done;
|
---|
139 | }
|
---|
140 |
|
---|
141 | //
|
---|
142 | // Get the EFI memory map.
|
---|
143 | //
|
---|
144 | MemoryMapSize = 0;
|
---|
145 | MemoryMap = NULL;
|
---|
146 | Status = gBS->GetMemoryMap (
|
---|
147 | &MemoryMapSize,
|
---|
148 | MemoryMap,
|
---|
149 | &MapKey,
|
---|
150 | &DescriptorSize,
|
---|
151 | &DescriptorVersion
|
---|
152 | );
|
---|
153 | ASSERT (Status == EFI_BUFFER_TOO_SMALL);
|
---|
154 | do {
|
---|
155 | MemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (MemoryMapSize);
|
---|
156 | ASSERT (MemoryMap != NULL);
|
---|
157 | Status = gBS->GetMemoryMap (
|
---|
158 | &MemoryMapSize,
|
---|
159 | MemoryMap,
|
---|
160 | &MapKey,
|
---|
161 | &DescriptorSize,
|
---|
162 | &DescriptorVersion
|
---|
163 | );
|
---|
164 | if (EFI_ERROR (Status)) {
|
---|
165 | FreePool (MemoryMap);
|
---|
166 | }
|
---|
167 | } while (Status == EFI_BUFFER_TOO_SMALL);
|
---|
168 | ASSERT_EFI_ERROR (Status);
|
---|
169 |
|
---|
170 | SetMemorySpaceAttributesDefault (MemoryMap, MemoryMapSize, DescriptorSize);
|
---|
171 |
|
---|
172 | Done:
|
---|
173 | gBS->CloseEvent (Event);
|
---|
174 |
|
---|
175 | return ;
|
---|
176 | }
|
---|
177 |
|
---|
178 | /**
|
---|
179 | The entrypoint of properties table attribute driver.
|
---|
180 |
|
---|
181 | @param ImageHandle The firmware allocated handle for the EFI image.
|
---|
182 | @param SystemTable A pointer to the EFI System Table.
|
---|
183 |
|
---|
184 | @retval EFI_SUCCESS It always returns EFI_SUCCESS.
|
---|
185 |
|
---|
186 | **/
|
---|
187 | EFI_STATUS
|
---|
188 | EFIAPI
|
---|
189 | InitializePropertiesTableAttributesDxe (
|
---|
190 | IN EFI_HANDLE ImageHandle,
|
---|
191 | IN EFI_SYSTEM_TABLE *SystemTable
|
---|
192 | )
|
---|
193 | {
|
---|
194 | EFI_STATUS Status;
|
---|
195 | EFI_EVENT ReadyToBootEvent;
|
---|
196 |
|
---|
197 | Status = gBS->CreateEventEx (
|
---|
198 | EVT_NOTIFY_SIGNAL,
|
---|
199 | TPL_CALLBACK,
|
---|
200 | UpdateMemoryAttributesDefault,
|
---|
201 | NULL,
|
---|
202 | &gEfiEventReadyToBootGuid,
|
---|
203 | &ReadyToBootEvent
|
---|
204 | );
|
---|
205 | ASSERT_EFI_ERROR (Status);
|
---|
206 |
|
---|
207 | return EFI_SUCCESS;
|
---|
208 | }
|
---|