]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Include/Register/Intel/StmApi.h
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Include / Register / Intel / StmApi.h
1 /** @file
2 STM API definition
3
4 Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 @par Specification Reference:
8 SMI Transfer Monitor (STM) User Guide Revision 1.00
9
10 **/
11
12 #ifndef _INTEL_STM_API_H_
13 #define _INTEL_STM_API_H_
14
15 #include <Register/Intel/StmStatusCode.h>
16 #include <Register/Intel/StmResourceDescriptor.h>
17 #include <Register/Intel/ArchitecturalMsr.h>
18
19 #pragma pack (1)
20
21 /**
22 STM Header Structures
23 **/
24
25 typedef struct {
26 UINT32 Intel64ModeSupported : 1; /// > bitfield
27 UINT32 EptSupported : 1; /// > bitfield
28 UINT32 Reserved : 30; /// > must be 0
29 } STM_FEAT;
30
31 #define STM_SPEC_VERSION_MAJOR 1
32 #define STM_SPEC_VERSION_MINOR 0
33
34 typedef struct {
35 UINT8 StmSpecVerMajor;
36 UINT8 StmSpecVerMinor;
37 ///
38 /// Must be zero
39 ///
40 UINT16 Reserved;
41 UINT32 StaticImageSize;
42 UINT32 PerProcDynamicMemorySize;
43 UINT32 AdditionalDynamicMemorySize;
44 STM_FEAT StmFeatures;
45 UINT32 NumberOfRevIDs;
46 UINT32 StmSmmRevID[1];
47 ///
48 /// The total STM_HEADER should be 4K.
49 ///
50 } SOFTWARE_STM_HEADER;
51
52 typedef struct {
53 MSEG_HEADER HwStmHdr;
54 SOFTWARE_STM_HEADER SwStmHdr;
55 } STM_HEADER;
56
57 /**
58 VMCALL API Numbers
59 API number convention: BIOS facing VMCALL interfaces have bit 16 clear
60 **/
61
62 /**
63 StmMapAddressRange enables a SMM guest to create a non-1:1 virtual to
64 physical mapping of an address range into the SMM guest's virtual
65 memory space.
66
67 @param EAX #STM_API_MAP_ADDRESS_RANGE (0x00000001)
68 @param EBX Low 32 bits of physical address of caller allocated
69 STM_MAP_ADDRESS_RANGE_DESCRIPTOR structure.
70 @param ECX High 32 bits of physical address of caller allocated
71 STM_MAP_ADDRESS_RANGE_DESCRIPTOR structure. If Intel64Mode is
72 clear (0), ECX must be 0.
73
74 @note All fields of STM_MAP_ADDRESS_RANGE_DESCRIPTOR are inputs only. They
75 are not modified by StmMapAddressRange.
76
77 @retval CF 0
78 No error, EAX set to STM_SUCCESS.
79 The memory range was mapped as requested.
80 @retval CF 1
81 An error occurred, EAX holds relevant error value.
82 @retval EAX #ERROR_STM_SECURITY_VIOLATION
83 The requested mapping contains a protected resource.
84 @retval EAX #ERROR_STM_CACHE_TYPE_NOT_SUPPORTED
85 The requested cache type could not be satisfied.
86 @retval EAX #ERROR_STM_PAGE_NOT_FOUND
87 Page count must not be zero.
88 @retval EAX #ERROR_STM_FUNCTION_NOT_SUPPORTED
89 STM supports EPT and has not implemented StmMapAddressRange().
90 @retval EAX #ERROR_STM_UNSPECIFIED
91 An unspecified error occurred.
92
93 @note All other registers unmodified.
94 **/
95 #define STM_API_MAP_ADDRESS_RANGE 0x00000001
96
97 /**
98 STM Map Address Range Descriptor for #STM_API_MAP_ADDRESS_RANGE VMCALL
99 **/
100 typedef struct {
101 UINT64 PhysicalAddress;
102 UINT64 VirtualAddress;
103 UINT32 PageCount;
104 UINT32 PatCacheType;
105 } STM_MAP_ADDRESS_RANGE_DESCRIPTOR;
106
107 /**
108 Define values for PatCacheType field of #STM_MAP_ADDRESS_RANGE_DESCRIPTOR
109 @{
110 **/
111 #define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_ST_UC 0x00
112 #define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WC 0x01
113 #define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WT 0x04
114 #define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WP 0x05
115 #define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WB 0x06
116 #define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_UC 0x07
117 #define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_FOLLOW_MTRR 0xFFFFFFFF
118 /// @}
119
120 /**
121 StmUnmapAddressRange enables a SMM guest to remove mappings from its page
122 table.
123
124 If TXT_PROCESSOR_SMM_DESCRIPTOR.EptEnabled bit is set by the STM, BIOS can
125 control its own page tables. In this case, the STM implementation may
126 optionally return ERROR_STM_FUNCTION_NOT_SUPPORTED.
127
128 @param EAX #STM_API_UNMAP_ADDRESS_RANGE (0x00000002)
129 @param EBX Low 32 bits of virtual address of caller allocated
130 STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR structure.
131 @param ECX High 32 bits of virtual address of caller allocated
132 STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR structure. If Intel64Mode is
133 clear (0), ECX must be zero.
134
135 @retval CF 0
136 No error, EAX set to STM_SUCCESS. The memory range was unmapped
137 as requested.
138 @retval CF 1
139 An error occurred, EAX holds relevant error value.
140 @retval EAX #ERROR_STM_FUNCTION_NOT_SUPPORTED
141 STM supports EPT and has not implemented StmUnmapAddressRange().
142 @retval EAX #ERROR_STM_UNSPECIFIED
143 An unspecified error occurred.
144
145 @note All other registers unmodified.
146 **/
147 #define STM_API_UNMAP_ADDRESS_RANGE 0x00000002
148
149 /**
150 STM Unmap Address Range Descriptor for #STM_API_UNMAP_ADDRESS_RANGE VMCALL
151 **/
152 typedef struct {
153 UINT64 VirtualAddress;
154 UINT32 Length;
155 } STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR;
156
157 /**
158 Since the normal OS environment runs with a different set of page tables than
159 the SMM guest, virtual mappings will certainly be different. In order to do a
160 guest virtual to host physical translation of an address from the normal OS
161 code (EIP for example), it is necessary to walk the page tables governing the
162 OS page mappings. Since the SMM guest has no direct access to the page tables,
163 it must ask the STM to do this page table walk. This is supported via the
164 StmAddressLookup VMCALL. All OS page table formats need to be supported,
165 (e.g. PAE, PSE, Intel64, EPT, etc.)
166
167 StmAddressLookup takes a CR3 value and a virtual address from the interrupted
168 code as input and returns the corresponding physical address. It also
169 optionally maps the physical address into the SMM guest's virtual address
170 space. This new mapping persists ONLY for the duration of the SMI and if
171 needed in subsequent SMIs it must be remapped. PAT cache types follow the
172 interrupted environment's page table.
173
174 If EPT is enabled, OS CR3 only provides guest physical address information,
175 but the SMM guest might also need to know the host physical address. Since
176 SMM does not have direct access rights to EPT (it is protected by the STM),
177 SMM can input InterruptedEptp to let STM help to walk through it, and output
178 the host physical address.
179
180 @param EAX #STM_API_ADDRESS_LOOKUP (0x00000003)
181 @param EBX Low 32 bits of virtual address of caller allocated
182 STM_ADDRESS_LOOKUP_DESCRIPTOR structure.
183 @param ECX High 32 bits of virtual address of caller allocated
184 STM_ADDRESS_LOOKUP_DESCRIPTOR structure. If Intel64Mode is
185 clear (0), ECX must be zero.
186
187 @retval CF 0
188 No error, EAX set to STM_SUCCESS. PhysicalAddress contains the
189 host physical address determined by walking the interrupted SMM
190 guest's page tables. SmmGuestVirtualAddress contains the SMM
191 guest's virtual mapping of the requested address.
192 @retval CF 1
193 An error occurred, EAX holds relevant error value.
194 @retval EAX #ERROR_STM_SECURITY_VIOLATION
195 The requested page was a protected page.
196 @retval EAX #ERROR_STM_PAGE_NOT_FOUND
197 The requested virtual address did not exist in the page given
198 page table.
199 @retval EAX #ERROR_STM_BAD_CR3
200 The CR3 input was invalid. CR3 values must be from one of the
201 interrupted guest, or from the interrupted guest of another
202 processor.
203 @retval EAX #ERROR_STM_PHYSICAL_OVER_4G
204 The resulting physical address is greater than 4G and no virtual
205 address was supplied. The STM could not determine what address
206 within the SMM guest's virtual address space to do the mapping.
207 STM_ADDRESS_LOOKUP_DESCRIPTOR field PhysicalAddress contains the
208 physical address determined by walking the interrupted
209 environment's page tables.
210 @retval EAX #ERROR_STM_VIRTUAL_SPACE_TOO_SMALL
211 A specific virtual mapping was requested, but
212 SmmGuestVirtualAddress + Length exceeds 4G and the SMI handler
213 is running in 32 bit mode.
214 @retval EAX #ERROR_STM_UNSPECIFIED
215 An unspecified error occurred.
216
217 @note All other registers unmodified.
218 **/
219 #define STM_API_ADDRESS_LOOKUP 0x00000003
220
221 /**
222 STM Lookup Address Range Descriptor for #STM_API_ADDRESS_LOOKUP VMCALL
223 **/
224 typedef struct {
225 UINT64 InterruptedGuestVirtualAddress;
226 UINT32 Length;
227 UINT64 InterruptedCr3;
228 UINT64 InterruptedEptp;
229 UINT32 MapToSmmGuest : 2;
230 UINT32 InterruptedCr4Pae : 1;
231 UINT32 InterruptedCr4Pse : 1;
232 UINT32 InterruptedIa32eMode : 1;
233 UINT32 Reserved1 : 27;
234 UINT32 Reserved2;
235 UINT64 PhysicalAddress;
236 UINT64 SmmGuestVirtualAddress;
237 } STM_ADDRESS_LOOKUP_DESCRIPTOR;
238
239 /**
240 Define values for the MapToSmmGuest field of #STM_ADDRESS_LOOKUP_DESCRIPTOR
241 @{
242 **/
243 #define STM_ADDRESS_LOOKUP_DESCRIPTOR_DO_NOT_MAP 0
244 #define STM_ADDRESS_LOOKUP_DESCRIPTOR_ONE_TO_ONE 1
245 #define STM_ADDRESS_LOOKUP_DESCRIPTOR_VIRTUAL_ADDRESS_SPECIFIED 3
246 /// @}
247
248 /**
249 When returning from a protection exception (see section 6.2), the SMM guest
250 can instruct the STM to take one of two paths. It can either request a value
251 be logged to the TXT.ERRORCODE register and subsequently reset the machine
252 (indicating it couldn't resolve the problem), or it can request that the STM
253 resume the SMM guest again with the specified register state.
254
255 Unlike other VMCALL interfaces, StmReturnFromProtectionException behaves more
256 like a jump or an IRET instruction than a "call". It does not return directly
257 to the caller, but indirectly to a different location specified on the
258 caller's stack (see section 6.2) or not at all.
259
260 If the SMM guest STM protection exception handler itself causes a protection
261 exception (e.g. a single nested exception), or more than 100 un-nested
262 exceptions occur within the scope of a single SMI event, the STM must write
263 STM_CRASH_PROTECTION_EXCEPTION_FAILURE to the TXT.ERRORCODE register and
264 assert TXT.CMD.SYS_RESET. The reason for these restrictions is to simplify
265 the code requirements while still enabling a reasonable debugging capability.
266
267 @param EAX #STM_API_RETURN_FROM_PROTECTION_EXCEPTION (0x00000004)
268 @param EBX If 0, resume SMM guest using register state found on exception
269 stack. If in range 0x01..0x0F, EBX contains a BIOS error code
270 which the STM must record in the TXT.ERRORCODE register and
271 subsequently reset the system via TXT.CMD.SYS_RESET. The value
272 of the TXT.ERRORCODE register is calculated as follows:
273
274 TXT.ERRORCODE = (EBX & 0x0F) | STM_CRASH_BIOS_PANIC
275
276 Values 0x10..0xFFFFFFFF are reserved, do not use.
277
278 **/
279 #define STM_API_RETURN_FROM_PROTECTION_EXCEPTION 0x00000004
280
281 /**
282 VMCALL API Numbers
283 API number convention: MLE facing VMCALL interfaces have bit 16 set.
284
285 The STM configuration lifecycle is as follows:
286 1. SENTER->SINIT->MLE: MLE begins execution with SMI disabled (masked).
287 2. MLE invokes #STM_API_INITIALIZE_PROTECTION VMCALL to prepare STM for
288 setup of initial protection profile. This is done on a single CPU and
289 has global effect.
290 3. MLE invokes #STM_API_PROTECT_RESOURCE VMCALL to define the initial
291 protection profile. The protection profile is global across all CPUs.
292 4. MLE invokes #STM_API_START VMCALL to enable the STM to begin receiving
293 SMI events. This must be done on every logical CPU.
294 5. MLE may invoke #STM_API_PROTECT_RESOURCE VMCALL or
295 #STM_API_UNPROTECT_RESOURCE VMCALL during runtime as many times as
296 necessary.
297 6. MLE invokes #STM_API_STOP VMCALL to disable the STM. SMI is again masked
298 following #STM_API_STOP VMCALL.
299 **/
300
301 /**
302 StartStmVmcall() is used to configure an STM that is present in MSEG. SMIs
303 should remain disabled from the invocation of GETSEC[SENTER] until they are
304 re-enabled by StartStmVMCALL(). When StartStmVMCALL() returns, SMI is
305 enabled and the STM has been started and is active. Prior to invoking
306 StartStmVMCALL(), the MLE root should first invoke
307 InitializeProtectionVMCALL() followed by as many iterations of
308 ProtectResourceVMCALL() as necessary to establish the initial protection
309 profile. StartStmVmcall() must be invoked on all processor threads.
310
311 @param EAX #STM_API_START (0x00010001)
312 @param EDX STM configuration options. These provide the MLE with the
313 ability to pass configuration parameters to the STM.
314
315 @retval CF 0
316 No error, EAX set to STM_SUCCESS. The STM has been configured
317 and is now active and the guarding all requested resources.
318 @retval CF 1
319 An error occurred, EAX holds relevant error value.
320 @retval EAX #ERROR_STM_ALREADY_STARTED
321 The STM is already configured and active. STM remains active and
322 guarding previously enabled resource list.
323 @retval EAX #ERROR_STM_WITHOUT_SMX_UNSUPPORTED
324 The StartStmVMCALL() was invoked from VMX root mode, but outside
325 of SMX. This error code indicates the STM or platform does not
326 support the STM outside of SMX. The SMI handler remains active
327 and operates in legacy mode. See Appendix C
328 @retval EAX #ERROR_STM_UNSUPPORTED_MSR_BIT
329 The CPU doesn't support the MSR bit. The STM is not active.
330 @retval EAX #ERROR_STM_UNSPECIFIED
331 An unspecified error occurred.
332
333 @note All other registers unmodified.
334 **/
335 #define STM_API_START (BIT16 | 1)
336
337 /**
338 Bit values for EDX input parameter to #STM_API_START VMCALL
339 @{
340 **/
341 #define STM_CONFIG_SMI_UNBLOCKING_BY_VMX_OFF BIT0
342 /// @}
343
344 /**
345 The StopStmVMCALL() is invoked by the MLE to teardown an active STM. This is
346 normally done as part of a full teardown of the SMX environment when the
347 system is being shut down. At the time the call is invoked, SMI is enabled
348 and the STM is active. When the call returns, the STM has been stopped and
349 all STM context is discarded and SMI is disabled.
350
351 @param EAX #STM_API_STOP (0x00010002)
352
353 @retval CF 0
354 No error, EAX set to STM_SUCCESS. The STM has been stopped and
355 is no longer processing SMI events. SMI is blocked.
356 @retval CF 1
357 An error occurred, EAX holds relevant error value.
358 @retval EAX #ERROR_STM_STOPPED
359 The STM was not active.
360 @retval EAX #ERROR_STM_UNSPECIFIED
361 An unspecified error occurred.
362
363 @note All other registers unmodified.
364 **/
365 #define STM_API_STOP (BIT16 | 2)
366
367 /**
368 The ProtectResourceVMCALL() is invoked by the MLE root to request protection
369 of specific resources. The request is defined by a STM_RESOURCE_LIST, which
370 may contain more than one resource descriptor. Each resource descriptor is
371 processed separately by the STM. Whether or not protection for any specific
372 resource is granted is returned by the STM via the ReturnStatus bit in the
373 associated STM_RSC_DESC_HEADER.
374
375 @param EAX #STM_API_PROTECT_RESOURCE (0x00010003)
376 @param EBX Low 32 bits of physical address of caller allocated
377 STM_RESOURCE_LIST. Bits 11:0 are ignored and assumed to be zero,
378 making the buffer 4K aligned.
379 @param ECX High 32 bits of physical address of caller allocated
380 STM_RESOURCE_LIST.
381
382 @note All fields of STM_RESOURCE_LIST are inputs only, except for the
383 ReturnStatus bit. On input, the ReturnStatus bit must be clear. On
384 return, the ReturnStatus bit is set for each resource request granted,
385 and clear for each resource request denied. There are no other fields
386 modified by ProtectResourceVMCALL(). The STM_RESOURCE_LIST must be
387 contained entirely within a single 4K page.
388
389 @retval CF 0
390 No error, EAX set to STM_SUCCESS. The STM has successfully
391 merged the entire protection request into the active protection
392 profile. There is therefore no need to check the ReturnStatus
393 bits in the STM_RESOURCE_LIST.
394 @retval CF 1
395 An error occurred, EAX holds relevant error value.
396 @retval EAX #ERROR_STM_UNPROTECTABLE_RESOURCE
397 At least one of the requested resource protections intersects a
398 BIOS required resource. Therefore, the caller must walk through
399 the STM_RESOURCE_LIST to determine which of the requested
400 resources was not granted protection. The entire list must be
401 traversed since there may be multiple failures.
402 @retval EAX #ERROR_STM_MALFORMED_RESOURCE_LIST
403 The resource list could not be parsed correctly, or did not
404 terminate before crossing a 4K page boundary. The caller must
405 walk through the STM_RESOURCE_LIST to determine which of the
406 requested resources was not granted protection. The entire list
407 must be traversed since there may be multiple failures.
408 @retval EAX #ERROR_STM_OUT_OF_RESOURCES
409 The STM has encountered an internal error and cannot complete
410 the request.
411 @retval EAX #ERROR_STM_UNSPECIFIED
412 An unspecified error occurred.
413
414 @note All other registers unmodified.
415 **/
416 #define STM_API_PROTECT_RESOURCE (BIT16 | 3)
417
418 /**
419 The UnProtectResourceVMCALL() is invoked by the MLE root to request that the
420 STM allow the SMI handler access to the specified resources.
421
422 @param EAX #STM_API_UNPROTECT_RESOURCE (0x00010004)
423 @param EBX Low 32 bits of physical address of caller allocated
424 STM_RESOURCE_LIST. Bits 11:0 are ignored and assumed to be zero,
425 making the buffer 4K aligned.
426 @param ECX High 32 bits of physical address of caller allocated
427 STM_RESOURCE_LIST.
428
429 @note All fields of STM_RESOURCE_LIST are inputs only, except for the
430 ReturnStatus bit. On input, the ReturnStatus bit must be clear. On
431 return, the ReturnStatus bit is set for each resource processed. For
432 a properly formed STM_RESOURCE_LIST, this should be all resources
433 listed. There are no other fields modified by
434 UnProtectResourceVMCALL(). The STM_RESOURCE_LIST must be contained
435 entirely within a single 4K page.
436
437 @retval CF 0
438 No error, EAX set to STM_SUCCESS. The requested resources are
439 not being guarded by the STM.
440 @retval CF 1
441 An error occurred, EAX holds relevant error value.
442 @retval EAX #ERROR_STM_MALFORMED_RESOURCE_LIST
443 The resource list could not be parsed correctly, or did not
444 terminate before crossing a 4K page boundary. The caller must
445 walk through the STM_RESOURCE_LIST to determine which of the
446 requested resources were not able to be unprotected. The entire
447 list must be traversed since there may be multiple failures.
448 @retval EAX #ERROR_STM_UNSPECIFIED
449 An unspecified error occurred.
450
451 @note All other registers unmodified.
452 **/
453 #define STM_API_UNPROTECT_RESOURCE (BIT16 | 4)
454
455 /**
456 The GetBiosResourcesVMCALL() is invoked by the MLE root to request the list
457 of BIOS required resources from the STM.
458
459 @param EAX #STM_API_GET_BIOS_RESOURCES (0x00010005)
460 @param EBX Low 32 bits of physical address of caller allocated destination
461 buffer. Bits 11:0 are ignored and assumed to be zero, making the
462 buffer 4K aligned.
463 @param ECX High 32 bits of physical address of caller allocated destination
464 buffer.
465 @param EDX Indicates which page of the BIOS resource list to copy into the
466 destination buffer. The first page is indicated by 0, the second
467 page by 1, etc.
468
469 @retval CF 0
470 No error, EAX set to STM_SUCCESS. The destination buffer
471 contains the BIOS required resources. If the page retrieved is
472 the last page, EDX will be cleared to 0. If there are more pages
473 to retrieve, EDX is incremented to the next page index. Calling
474 software should iterate on GetBiosResourcesVMCALL() until EDX is
475 returned cleared to 0.
476 @retval CF 1
477 An error occurred, EAX holds relevant error value.
478 @retval EAX #ERROR_STM_PAGE_NOT_FOUND
479 The page index supplied in EDX input was out of range.
480 @retval EAX #ERROR_STM_UNSPECIFIED
481 An unspecified error occurred.
482 @retval EDX Page index of next page to read. A return of EDX=0 signifies
483 that the entire list has been read.
484 @note EDX is both an input and an output register.
485
486 @note All other registers unmodified.
487 **/
488 #define STM_API_GET_BIOS_RESOURCES (BIT16 | 5)
489
490 /**
491 The ManageVmcsDatabaseVMCALL() is invoked by the MLE root to add or remove an
492 MLE guest (including the MLE root) from the list of protected domains.
493
494 @param EAX #STM_API_MANAGE_VMCS_DATABASE (0x00010006)
495 @param EBX Low 32 bits of physical address of caller allocated
496 STM_VMCS_DATABASE_REQUEST. Bits 11:0 are ignored and assumed to
497 be zero, making the buffer 4K aligned.
498 @param ECX High 32 bits of physical address of caller allocated
499 STM_VMCS_DATABASE_REQUEST.
500
501 @note All fields of STM_VMCS_DATABASE_REQUEST are inputs only. They are not
502 modified by ManageVmcsDatabaseVMCALL().
503
504 @retval CF 0
505 No error, EAX set to STM_SUCCESS.
506 @retval CF 1
507 An error occurred, EAX holds relevant error value.
508 @retval EAX #ERROR_STM_INVALID_VMCS
509 Indicates a request to remove a VMCS from the database was made,
510 but the referenced VMCS was not found in the database.
511 @retval EAX #ERROR_STM_VMCS_PRESENT
512 Indicates a request to add a VMCS to the database was made, but
513 the referenced VMCS was already present in the database.
514 @retval EAX #ERROR_INVALID_PARAMETER
515 Indicates non-zero reserved field.
516 @retval EAX #ERROR_STM_UNSPECIFIED
517 An unspecified error occurred
518
519 @note All other registers unmodified.
520 **/
521 #define STM_API_MANAGE_VMCS_DATABASE (BIT16 | 6)
522
523 /**
524 STM VMCS Database Request for #STM_API_MANAGE_VMCS_DATABASE VMCALL
525 **/
526 typedef struct {
527 ///
528 /// bits 11:0 are reserved and must be 0
529 ///
530 UINT64 VmcsPhysPointer;
531 UINT32 DomainType : 4;
532 UINT32 XStatePolicy : 2;
533 UINT32 DegradationPolicy : 4;
534 ///
535 /// Must be 0
536 ///
537 UINT32 Reserved1 : 22;
538 UINT32 AddOrRemove;
539 } STM_VMCS_DATABASE_REQUEST;
540
541 /**
542 Values for the DomainType field of #STM_VMCS_DATABASE_REQUEST
543 @{
544 **/
545 #define DOMAIN_UNPROTECTED 0
546 #define DOMAIN_DISALLOWED_IO_OUT BIT0
547 #define DOMAIN_DISALLOWED_IO_IN BIT1
548 #define DOMAIN_INTEGRITY BIT2
549 #define DOMAIN_CONFIDENTIALITY BIT3
550 #define DOMAIN_INTEGRITY_PROT_OUT_IN (DOMAIN_INTEGRITY)
551 #define DOMAIN_FULLY_PROT_OUT_IN (DOMAIN_CONFIDENTIALITY | DOMAIN_INTEGRITY)
552 #define DOMAIN_FULLY_PROT (DOMAIN_FULLY_PROT_OUT_IN | DOMAIN_DISALLOWED_IO_IN | DOMAIN_DISALLOWED_IO_OUT)
553 /// @}
554
555 /**
556 Values for the XStatePolicy field of #STM_VMCS_DATABASE_REQUEST
557 @{
558 **/
559 #define XSTATE_READWRITE 0x00
560 #define XSTATE_READONLY 0x01
561 #define XSTATE_SCRUB 0x03
562 /// @}
563
564 /**
565 Values for the AddOrRemove field of #STM_VMCS_DATABASE_REQUEST
566 @{
567 **/
568 #define STM_VMCS_DATABASE_REQUEST_ADD 1
569 #define STM_VMCS_DATABASE_REQUEST_REMOVE 0
570 /// @}
571
572 /**
573 InitializeProtectionVMCALL() prepares the STM for setup of the initial
574 protection profile which is subsequently communicated via one or more
575 invocations of ProtectResourceVMCALL(), prior to invoking StartStmVMCALL().
576 It is only necessary to invoke InitializeProtectionVMCALL() on one processor
577 thread. InitializeProtectionVMCALL() does not alter whether SMIs are masked
578 or unmasked. The STM should return back to the MLE with "Blocking by SMI" set
579 to 1 in the GUEST_INTERRUPTIBILITY field for the VMCS the STM created for the
580 MLE guest.
581
582 @param EAX #STM_API_INITIALIZE_PROTECTION (0x00010007)
583
584 @retval CF 0
585 No error, EAX set to STM_SUCCESS, EBX bits set to indicate STM
586 capabilities as defined below. The STM has set up an empty
587 protection profile, except for the resources that it sets up to
588 protect itself. The STM must not allow the SMI handler to map
589 any pages from the MSEG Base to the top of TSEG. The STM must
590 also not allow SMI handler access to those MSRs which the STM
591 requires for its own protection.
592 @retval CF 1
593 An error occurred, EAX holds relevant error value.
594 @retval EAX #ERROR_STM_ALREADY_STARTED
595 The STM is already configured and active. The STM remains active
596 and guarding the previously enabled resource list.
597 @retval EAX #ERROR_STM_UNPROTECTABLE
598 The STM determines that based on the platform configuration, the
599 STM is unable to protect itself. For example, the BIOS required
600 resource list contains memory pages in MSEG.
601 @retval EAX #ERROR_STM_UNSPECIFIED
602 An unspecified error occurred.
603
604 @note All other registers unmodified.
605 **/
606 #define STM_API_INITIALIZE_PROTECTION (BIT16 | 7)
607
608 /**
609 Byte granular support bits returned in EBX from #STM_API_INITIALIZE_PROTECTION
610 @{
611 **/
612 #define STM_RSC_BGI BIT1
613 #define STM_RSC_BGM BIT2
614 #define STM_RSC_MSR BIT3
615 /// @}
616
617 /**
618 The ManageEventLogVMCALL() is invoked by the MLE root to control the logging
619 feature. It consists of several sub-functions to facilitate establishment of
620 the log itself, configuring what events will be logged, and functions to
621 start, stop, and clear the log.
622
623 @param EAX #STM_API_MANAGE_EVENT_LOG (0x00010008)
624 @param EBX Low 32 bits of physical address of caller allocated
625 STM_EVENT_LOG_MANAGEMENT_REQUEST. Bits 11:0 are ignored and
626 assumed to be zero, making the buffer 4K aligned.
627 @param ECX High 32 bits of physical address of caller allocated
628 STM_EVENT_LOG_MANAGEMENT_REQUEST.
629
630 @retval CF=0
631 No error, EAX set to STM_SUCCESS.
632 @retval CF=1
633 An error occurred, EAX holds relevant error value. See subfunction
634 descriptions below for details.
635
636 @note All other registers unmodified.
637 **/
638 #define STM_API_MANAGE_EVENT_LOG (BIT16 | 8)
639
640 ///
641 /// STM Event Log Management Request for #STM_API_MANAGE_EVENT_LOG VMCALL
642 ///
643 typedef struct {
644 UINT32 SubFunctionIndex;
645 union {
646 struct {
647 UINT32 PageCount;
648 //
649 // number of elements is PageCount
650 //
651 UINT64 Pages[];
652 } LogBuffer;
653 //
654 // bitmap of EVENT_TYPE
655 //
656 UINT32 EventEnableBitmap;
657 } Data;
658 } STM_EVENT_LOG_MANAGEMENT_REQUEST;
659
660 /**
661 Defines values for the SubFunctionIndex field of
662 #STM_EVENT_LOG_MANAGEMENT_REQUEST
663 @{
664 **/
665 #define STM_EVENT_LOG_MANAGEMENT_REQUEST_NEW_LOG 1
666 #define STM_EVENT_LOG_MANAGEMENT_REQUEST_CONFIGURE_LOG 2
667 #define STM_EVENT_LOG_MANAGEMENT_REQUEST_START_LOG 3
668 #define STM_EVENT_LOG_MANAGEMENT_REQUEST_STOP_LOG 4
669 #define STM_EVENT_LOG_MANAGEMENT_REQUEST_CLEAR_LOG 5
670 #define STM_EVENT_LOG_MANAGEMENT_REQUEST_DELETE_LOG 6
671 /// @}
672
673 /**
674 Log Entry Header
675 **/
676 typedef struct {
677 UINT32 EventSerialNumber;
678 UINT16 Type;
679 UINT16 Lock : 1;
680 UINT16 Valid : 1;
681 UINT16 ReadByMle : 1;
682 UINT16 Wrapped : 1;
683 UINT16 Reserved : 12;
684 } LOG_ENTRY_HEADER;
685
686 /**
687 Enum values for the Type field of #LOG_ENTRY_HEADER
688 **/
689 typedef enum {
690 EvtLogStarted,
691 EvtLogStopped,
692 EvtLogInvalidParameterDetected,
693 EvtHandledProtectionException,
694 ///
695 /// unhandled protection exceptions result in reset & cannot be logged
696 ///
697 EvtBiosAccessToUnclaimedResource,
698 EvtMleResourceProtectionGranted,
699 EvtMleResourceProtectionDenied,
700 EvtMleResourceUnprotect,
701 EvtMleResourceUnprotectError,
702 EvtMleDomainTypeDegraded,
703 ///
704 /// add more here
705 ///
706 EvtMleMax,
707 ///
708 /// Not used
709 ///
710 EvtInvalid = 0xFFFFFFFF,
711 } EVENT_TYPE;
712
713 typedef struct {
714 UINT32 Reserved;
715 } ENTRY_EVT_LOG_STARTED;
716
717 typedef struct {
718 UINT32 Reserved;
719 } ENTRY_EVT_LOG_STOPPED;
720
721 typedef struct {
722 UINT32 VmcallApiNumber;
723 } ENTRY_EVT_LOG_INVALID_PARAM;
724
725 typedef struct {
726 STM_RSC Resource;
727 } ENTRY_EVT_LOG_HANDLED_PROTECTION_EXCEPTION;
728
729 typedef struct {
730 STM_RSC Resource;
731 } ENTRY_EVT_BIOS_ACCESS_UNCLAIMED_RSC;
732
733 typedef struct {
734 STM_RSC Resource;
735 } ENTRY_EVT_MLE_RSC_PROT_GRANTED;
736
737 typedef struct {
738 STM_RSC Resource;
739 } ENTRY_EVT_MLE_RSC_PROT_DENIED;
740
741 typedef struct {
742 STM_RSC Resource;
743 } ENTRY_EVT_MLE_RSC_UNPROT;
744
745 typedef struct {
746 STM_RSC Resource;
747 } ENTRY_EVT_MLE_RSC_UNPROT_ERROR;
748
749 typedef struct {
750 UINT64 VmcsPhysPointer;
751 UINT8 ExpectedDomainType;
752 UINT8 DegradedDomainType;
753 } ENTRY_EVT_MLE_DOMAIN_TYPE_DEGRADED;
754
755 typedef union {
756 ENTRY_EVT_LOG_STARTED Started;
757 ENTRY_EVT_LOG_STOPPED Stopped;
758 ENTRY_EVT_LOG_INVALID_PARAM InvalidParam;
759 ENTRY_EVT_LOG_HANDLED_PROTECTION_EXCEPTION HandledProtectionException;
760 ENTRY_EVT_BIOS_ACCESS_UNCLAIMED_RSC BiosUnclaimedRsc;
761 ENTRY_EVT_MLE_RSC_PROT_GRANTED MleRscProtGranted;
762 ENTRY_EVT_MLE_RSC_PROT_DENIED MleRscProtDenied;
763 ENTRY_EVT_MLE_RSC_UNPROT MleRscUnprot;
764 ENTRY_EVT_MLE_RSC_UNPROT_ERROR MleRscUnprotError;
765 ENTRY_EVT_MLE_DOMAIN_TYPE_DEGRADED MleDomainTypeDegraded;
766 } LOG_ENTRY_DATA;
767
768 typedef struct {
769 LOG_ENTRY_HEADER Hdr;
770 LOG_ENTRY_DATA Data;
771 } STM_LOG_ENTRY;
772
773 /**
774 Maximum STM Log Entry Size
775 **/
776 #define STM_LOG_ENTRY_SIZE 256
777
778 /**
779 STM Protection Exception Stack Frame Structures
780 **/
781
782 typedef struct {
783 UINT32 Rdi;
784 UINT32 Rsi;
785 UINT32 Rbp;
786 UINT32 Rdx;
787 UINT32 Rcx;
788 UINT32 Rbx;
789 UINT32 Rax;
790 UINT32 Cr3;
791 UINT32 Cr2;
792 UINT32 Cr0;
793 UINT32 VmcsExitInstructionInfo;
794 UINT32 VmcsExitInstructionLength;
795 UINT64 VmcsExitQualification;
796 ///
797 /// An TXT_SMM_PROTECTION_EXCEPTION_TYPE num value
798 ///
799 UINT32 ErrorCode;
800 UINT32 Rip;
801 UINT32 Cs;
802 UINT32 Rflags;
803 UINT32 Rsp;
804 UINT32 Ss;
805 } STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32;
806
807 typedef struct {
808 UINT64 R15;
809 UINT64 R14;
810 UINT64 R13;
811 UINT64 R12;
812 UINT64 R11;
813 UINT64 R10;
814 UINT64 R9;
815 UINT64 R8;
816 UINT64 Rdi;
817 UINT64 Rsi;
818 UINT64 Rbp;
819 UINT64 Rdx;
820 UINT64 Rcx;
821 UINT64 Rbx;
822 UINT64 Rax;
823 UINT64 Cr8;
824 UINT64 Cr3;
825 UINT64 Cr2;
826 UINT64 Cr0;
827 UINT64 VmcsExitInstructionInfo;
828 UINT64 VmcsExitInstructionLength;
829 UINT64 VmcsExitQualification;
830 ///
831 /// An TXT_SMM_PROTECTION_EXCEPTION_TYPE num value
832 ///
833 UINT64 ErrorCode;
834 UINT64 Rip;
835 UINT64 Cs;
836 UINT64 Rflags;
837 UINT64 Rsp;
838 UINT64 Ss;
839 } STM_PROTECTION_EXCEPTION_STACK_FRAME_X64;
840
841 typedef union {
842 STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32 *Ia32StackFrame;
843 STM_PROTECTION_EXCEPTION_STACK_FRAME_X64 *X64StackFrame;
844 } STM_PROTECTION_EXCEPTION_STACK_FRAME;
845
846 /**
847 Enum values for the ErrorCode field in
848 #STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32 and
849 #STM_PROTECTION_EXCEPTION_STACK_FRAME_X64
850 **/
851 typedef enum {
852 TxtSmmPageViolation = 1,
853 TxtSmmMsrViolation,
854 TxtSmmRegisterViolation,
855 TxtSmmIoViolation,
856 TxtSmmPciViolation
857 } TXT_SMM_PROTECTION_EXCEPTION_TYPE;
858
859 /**
860 TXT Pocessor SMM Descriptor (PSD) structures
861 **/
862
863 typedef struct {
864 UINT64 SpeRip;
865 UINT64 SpeRsp;
866 UINT16 SpeSs;
867 UINT16 PageViolationException : 1;
868 UINT16 MsrViolationException : 1;
869 UINT16 RegisterViolationException : 1;
870 UINT16 IoViolationException : 1;
871 UINT16 PciViolationException : 1;
872 UINT16 Reserved1 : 11;
873 UINT32 Reserved2;
874 } STM_PROTECTION_EXCEPTION_HANDLER;
875
876 typedef struct {
877 UINT8 ExecutionDisableOutsideSmrr : 1;
878 UINT8 Intel64Mode : 1;
879 UINT8 Cr4Pae : 1;
880 UINT8 Cr4Pse : 1;
881 UINT8 Reserved1 : 4;
882 } STM_SMM_ENTRY_STATE;
883
884 typedef struct {
885 UINT8 SmramToVmcsRestoreRequired : 1; /// > BIOS restore hint
886 UINT8 ReinitializeVmcsRequired : 1; /// > BIOS request
887 UINT8 Reserved2 : 6;
888 } STM_SMM_RESUME_STATE;
889
890 typedef struct {
891 UINT8 DomainType : 4; /// > STM input to BIOS on each SMI
892 UINT8 XStatePolicy : 2; /// > STM input to BIOS on each SMI
893 UINT8 EptEnabled : 1;
894 UINT8 Reserved3 : 1;
895 } STM_SMM_STATE;
896
897 #define TXT_SMM_PSD_OFFSET 0xfb00
898 #define TXT_PROCESSOR_SMM_DESCRIPTOR_SIGNATURE SIGNATURE_64('T', 'X', 'T', 'P', 'S', 'S', 'I', 'G')
899 #define TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MAJOR 1
900 #define TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MINOR 0
901
902 typedef struct {
903 UINT64 Signature;
904 UINT16 Size;
905 UINT8 SmmDescriptorVerMajor;
906 UINT8 SmmDescriptorVerMinor;
907 UINT32 LocalApicId;
908 STM_SMM_ENTRY_STATE SmmEntryState;
909 STM_SMM_RESUME_STATE SmmResumeState;
910 STM_SMM_STATE StmSmmState;
911 UINT8 Reserved4;
912 UINT16 SmmCs;
913 UINT16 SmmDs;
914 UINT16 SmmSs;
915 UINT16 SmmOtherSegment;
916 UINT16 SmmTr;
917 UINT16 Reserved5;
918 UINT64 SmmCr3;
919 UINT64 SmmStmSetupRip;
920 UINT64 SmmStmTeardownRip;
921 UINT64 SmmSmiHandlerRip;
922 UINT64 SmmSmiHandlerRsp;
923 UINT64 SmmGdtPtr;
924 UINT32 SmmGdtSize;
925 UINT32 RequiredStmSmmRevId;
926 STM_PROTECTION_EXCEPTION_HANDLER StmProtectionExceptionHandler;
927 UINT64 Reserved6;
928 UINT64 BiosHwResourceRequirementsPtr;
929 // extend area
930 UINT64 AcpiRsdp;
931 UINT8 PhysicalAddressBits;
932 } TXT_PROCESSOR_SMM_DESCRIPTOR;
933
934 #pragma pack ()
935
936 #endif