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