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