github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/common/include/vmm_startup.h (about) 1 /* 2 * Copyright (c) 2013 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 #ifndef _UVMM_STARTUP_H_ 16 #define _UVMM_STARTUP_H_ 17 18 // uVMM Startup Definitions 19 // This files contains definitions of the interaction between the uVMM and its 20 // loader. 21 22 #include "vmm_defs.h" 23 #include "vmm_arch_defs.h" 24 25 #pragma PACK_ON 26 27 28 // uVMM Startup Constants 29 // Note: Constants that are related to specific structures below are defined 30 // near their respective structures. 31 // Default size for uVMM footprint in memory, that should be 32 // allocated by the loader. Includes the uVMM executable image and work 33 // area, but not the 32bit-to-64bit Thunk image. 34 35 // JLM: add this for total memory 36 #define UVMM_DEFAULT_FOOTPRINT 75 MEGABYTES 37 38 // Default size for uVMM stack, in pages 39 40 #define UVMM_DEFAULT_STACK_SIZE_PAGES 10 41 42 43 // uVMM Startup Structure Types 44 // These structures are used both in 32-bit and 64-bit modes, therefore: 45 // - Structure sizes are 64-bit aligned 46 // - All pointers are defined as 64-bit, and must be set so their higher 32 bits 47 // are 0 (< 4GB). This ensures their usability in both 32-bit and 64-bit modes. 48 // - All pointers are in a loader virtual memory space (if applicable). 49 // Major terms: 50 // Primary guest - the guest that owns the platform and platform was 51 // booted originally to run this guest 52 // Secondary guest - the guest that is used to perform some dedicated tasks 53 // on behalf of the primary guest 54 // Following is the structure hierarchy (---> denotes a pointer): 55 // VMM_STARTUP_STRUCT 56 // +---- VMM_MEMORY_LAYOUT vmm_memory_layout[] 57 // +---> INT15_E820_MEMORY_MAP physical_memory_layout_E820 58 // +---> VMM_GUEST_STARTUP primary_guest_startup_state 59 // | +---> VMM_GUEST_CPU_STARTUP_STATE cpu_states_array[] 60 // | | +---- VMM_GP_REGISTERS gp 61 // | | +---- VMM_XMM_REGISTERS xmm 62 // | | +---- VMM_SEGMENTS seg 63 // | | +---- VMM_CONTROL_REGISTERS control 64 // | | +---- VMM_MODEL_SPECIFIC_REGISTERS msr 65 // | +---> VMM_GUEST_DEVICE devices_array[] 66 // +---> VMM_GUEST_STARTUP secondary_guests_startup_state_array[] 67 // | +... as above 68 // +---- VMM_DEBUG_PARAMS debug_params 69 // +---- VMM_DEBUG_PORT_PARAMS port 70 // VMM_APPLICATION_PARAMS_STRUCT 71 72 73 // VMM_MEMORY_LAYOUT 74 // VMM bounding box - vmm memory layout as it was built by loader 75 // Data about sizes is part of installer info 76 // Vmm image occupies area [base_address .. base_address+image_size] 77 // Area [base_address+image_size .. base_address+total_size] is used for 78 // vmm heaps and stacks 79 typedef struct _VMM_MEMORY_LAYOUT 80 { 81 UINT32 total_size; 82 UINT32 image_size; // the VMM image is loaded at the area start 83 UINT64 base_address; 84 UINT64 entry_point; 85 } PACKED VMM_MEMORY_LAYOUT; 86 87 88 // VMM_GUEST_CPU_STARTUP_STATE: Initial Guest CPU State 89 // Specified per each active CPU for each guest, and will be put into Guest VMCS 90 // at guest launch time. All addresses are absolute values that should be put in 91 // VMCS. 92 // If for some guest CPU VMM_GUEST_CPU_STARTUP_STATE is not specified, 93 // this guest CPU is put into the Wait-for-SIPI state. 94 // VMM_GUEST_CPU_STARTUP_STATE must be specified for at least first processor 95 // (BSP) of each guest. 96 // Guest initial entry point should be set as the CS:RIP pair: 97 // - CS is specified in the seg[IA32_SEG_CS].selector value 98 // - RIP is specified in the gp[IA32_REG_RIP] value 99 // These values are specified as: 100 // 101 // 1. If guest paging is active CS:RIP is in the GVA notation 102 // 2. If guest is in protected non-paged mode CS:RIP is in the GPA notation 103 // 3. If guest is in the real mode CS:RIP is in the GPA notation and CS 104 // specifies the GPA value of the segment base, shifted right 4 bits. 105 // 106 107 108 #define VMM_GUEST_CPU_STARTUP_STATE_VERSION 1 109 110 // This structure should be aligned on 8 byte 111 #define VMM_GUEST_CPU_STARTUP_STATE_ALIGNMENT 8 112 113 typedef struct _VMM_GUEST_CPU_STARTUP_STATE 114 { 115 UINT16 size_of_this_struct; 116 UINT16 version_of_this_struct; 117 UINT32 reserved_1; 118 119 /* 64-bit aligned */ 120 // there are additional registers in the CPU that are not passed here. 121 // it is assumed that for the new guest the state of such registers is 122 // the same, as it was at the VMM entry point. 123 124 VMM_GP_REGISTERS gp; 125 VMM_XMM_REGISTERS xmm; 126 VMM_SEGMENTS seg; 127 VMM_CONTROL_REGISTERS control; 128 VMM_MODEL_SPECIFIC_REGISTERS msr; 129 }PACKED VMM_GUEST_CPU_STARTUP_STATE; 130 131 132 // VMM_GUEST_DEVICE: Guest Devices 133 // Describes virtualized, hidden or attached device 134 // If device is assinged to this guest is may be exposed using its real 135 // id or virtualized id. 136 // If the same real_vendor_id/real_device_id is specified for 137 // number of guests, this device will be exposed to each of this guests. 138 // If VT-d is active, this device will be hidden from all other guests. 139 // If VT-d is not active, it will be exposed using "unsupported vendor/device id" 140 // *** THIS FEATURE IS NOT CURRENTLY SUPPORTED *** 141 142 #define VMM_GUEST_DEVICE_VERSION 1 143 144 typedef struct _VMM_GUEST_DEVICE 145 { 146 UINT16 size_of_this_struct; 147 UINT16 version_of_this_struct; 148 UINT32 reserved_1; 149 150 // Real device data 151 UINT16 real_vendor_id; 152 UINT16 real_device_id; 153 154 // Virtual device data 155 UINT16 virtual_vendor_id; 156 UINT16 virtual_device_id; 157 } PACKED VMM_GUEST_DEVICE; 158 159 160 // VMM_GUEST_STARTUP: Describes One Guest 161 162 #define VMM_GUEST_STARTUP_VERSION 1 163 164 // Guest flags 165 166 // 1 - allow execution of 'int' instructions in real mode 167 // 0 - stop guest scheduling on first 'int' intruction execution in real mode 168 #define VMM_GUEST_FLAG_REAL_BIOS_ACCESS_ENABLE BIT_VALUE(0) 169 170 // 1 - start the guest as soon as possible without any additional request 171 // 0 - start the guest on a specific request of some other guest 172 // using the appropriate VmCall( guest_magic_number ) 173 // at least one guest have to be configured as 'start_immediately' 174 #define VMM_GUEST_FLAG_LAUNCH_IMMEDIATELY BIT_VALUE(1) 175 176 // 1 - image is compressed. Should be uncompressed before execution. 177 #define VMM_GUEST_FLAG_IMAGE_COMPRESSED BIT_VALUE(2) 178 179 // This structure should be aligned on 8 bytes 180 #define VMM_GUEST_STARTUP_ALIGNMENT 8 181 #define MAXEXCLUDEDREGIONS 32 182 typedef struct _VMM_GUEST_STARTUP { 183 UINT16 size_of_this_struct; 184 UINT16 version_of_this_struct; 185 186 // set of flags that define policies for this guest, see definition 187 // above 188 UINT32 flags; 189 190 /* 64-bit aligned */ 191 192 // guest unique id in the current application. 193 UINT32 guest_magic_number; 194 195 // set bit to 1 for each physical CPU, where GuestCPU should run. 196 // Guest should have num_of_virtual_CPUs == num of 1-bits in the mask 197 // ex. 0x3 means that guest has 2 CPUs that run on physical-0 and 198 // physical-1 CPUs 199 // 200 // if -1 - run on all available CPUs 201 // 202 // if number of 1 bits is more than cpu_states_count, all other guest 203 // CPUs will be initialized in the Wait-for-SIPI state. 204 // 205 // if 1 is set for bit-number greater than physically available CPU count, 206 // the whole guest is discarded. The only exception is -1. 207 UINT32 cpu_affinity; 208 209 /* 64-bit aligned */ 210 211 // number of VMM_GUEST_CPU_STATE structures provided. 212 // if number of VMM_GUEST_CPU_STATE structures is less than number 213 // of processors used by this guest, all other processors will 214 // be initialized in the Wait-for-SIPI state 215 UINT32 cpu_states_count; 216 217 /* 64-bit aligned */ 218 219 // number of virtualized or hidden devices for specific guest 220 // if count == 0 - guest is deviceless, 221 // except the case that the guest is also signed as default_device_owner 222 UINT32 devices_count; 223 224 // guest image as loaded by the loader 225 // For primary guest it must be zeroed 226 UINT32 image_size; 227 UINT64 image_address; 228 229 /* 64-bit aligned */ 230 231 // amount of physical memory for this guest 232 // For primary guest it must be zeroed 233 UINT32 physical_memory_size; 234 235 // load address of the image in the guest physical memory 236 // For primary guest it must be zeroed 237 UINT32 image_offset_in_guest_physical_memory; 238 239 // pointer to an array of initial CPU states for guest CPUs 240 // First entry is for the guest BSP processor, that is a least-numbered 241 // 1 bit in the cpu_affinity. At least one such structure has to exist. 242 // Guest CPUs that does not have this structure are started in the 243 // Wait-for-SIPI state. 244 // VMM_GUEST_CPU_STARTUP_STATE* 245 UINT64 cpu_states_array; 246 247 // pointer to an array of guest devices 248 // VMM_GUEST_DEVICE* 249 UINT64 devices_array; 250 }PACKED VMM_GUEST_STARTUP; 251 252 253 // VMM_DEBUG_PARAMS: Debug Parameters 254 // Controls various parameters for VMM debug 255 // Note: There are no 'size' and 'version' fields in VMM_DEBUG_PARAMS, since 256 // this strucure is included in VMM_STURTUP_STRUCT. Set the version 257 // there! 258 259 // VMM_DEBUG_PORT_TYPE: Type of debug port 260 261 typedef enum _VMM_DEBUG_PORT_TYPE 262 { 263 // No debug port is used 264 VMM_DEBUG_PORT_NONE = 0, 265 266 // The debug port is a generic 16450-compatible serial controller 267 VMM_DEBUG_PORT_SERIAL, 268 269 VMM_DEBUG_PORT_TYPE_LAST 270 } VMM_DEBUG_PORT_TYPE; 271 272 // VMM_DEBUG_PORT_IDENT_TYPE: How the debug port is identified 273 274 #define VMM_DEBUG_PORT_IDENT_PCI_INDEX_MAX 15 // See below 275 276 typedef enum _VMM_DEBUG_PORT_IDENT_TYPE 277 { 278 // No debug port is identified, use the VMM default 279 VMM_DEBUG_PORT_IDENT_DEFAULT = 0, 280 281 // The debug port is identified using its h/w base address in the I/O space 282 VMM_DEBUG_PORT_IDENT_IO, 283 284 // The debug port is identified as the N'th debug port (of type 285 // VMM_DEBUG_PORT_TYPE) on the PCI bus. 286 // Range is 0 to VMM_DEBUG_PORT_IDENT_PCI_INDEX_MAX 287 // **** NOTES: 1. This is not directly supported by uVMM yet. 288 // 2. Loaders may support this, but must detect devices and 289 // convert to VMM_DEBUG_PORT_IDENT_IO before invoking uVMM 290 VMM_DEBUG_PORT_IDENT_PCI_INDEX, 291 292 VMM_DEBUG_PORT_IDENT_LAST 293 } VMM_DEBUG_PORT_IDENT_TYPE; 294 295 // VMM_DEBUG_PORT_VIRT_MODE: How the debug port is virtualized 296 297 typedef enum _VMM_DEBUG_PORT_VIRT_MODE 298 { 299 // No virtaulization 300 VMM_DEBUG_PORT_VIRT_NONE = 0, 301 302 // Hide the port. Reads return all 1, writes do nothing. This mode is 303 // useful when all the guests are expected to discover the port before they 304 // attempt to use it. 305 VMM_DEBUG_PORT_VIRT_HIDE, 306 307 // Port acts as /dev/null: Status reads emulate ready for output, no 308 // available input. Writes do nothing. This modes may be useful for late 309 // launch, to avoid hanging the primary guest if it tries to use the same 310 // port. 311 // **** THIS MODE IS NOT SUPPORTED YET **** 312 VMM_DEBUG_PORT_VIRT_NULL, 313 314 VMM_DEBUG_PORT_VIRT_LAST 315 } VMM_DEBUG_PORT_VIRT_MODE; 316 317 318 // This structure should be aligned on 8 byte 319 #define VMM_DEBUG_PORT_PARAMS_ALIGNMENT 8 320 321 #define VMM_DEBUG_PORT_SERIAL_IO_BASE_DEFAULT 0x3F8 // std com1 322 323 typedef struct _VMM_DEBUG_PORT_PARAMS 324 { 325 UINT8 type; // VMM_DEBUG_PORT_TYPE 326 UINT8 virt_mode; // VMM_DEBUG_PORT_VIRT_MODE 327 UINT8 reserved_1; 328 UINT8 ident_type; // VMM_DEBUG_PORT_IDENT_TYPE 329 union 330 { 331 UINT16 io_base; // For use with ident_type == VMM_DEBUG_PORT_IDENT_IO 332 UINT32 index; // For use with ident_type == VMM_DEBUG_PORT_IDENT_PCI_INDEX 333 UINT32 ident32; // Dummy filler 334 } ident; 335 336 /* 64-bit aligned */ 337 } PACKED VMM_DEBUG_PORT_PARAMS; 338 339 // This structure should be aligned on 8 byte 340 #define VMM_DEBUG_PARAMS_ALIGNMENT 8 341 342 typedef struct _VMM_DEBUG_PARAMS 343 { 344 // Global level filter for debug printouts. Only messages whose level are 345 // lower or equal than this value are printed. 346 // 0 : Only top-priority messages (e.g., fatal errors) are printed 347 // 1 : In addition to the above, error messages are printed (default) 348 // 2 : In addition to the above, warnings are printed 349 // 3 : In addition to the above, informational messages are printed 350 // 4 : In addition to the above, trace messages are printed 351 UINT8 verbosity; 352 UINT8 reserved[7]; 353 354 /* 64-bit aligned */ 355 356 // Main debug port: used for logging, CLI etc. 357 VMM_DEBUG_PORT_PARAMS port; 358 359 /* 64-bit aligned */ 360 361 // Auxiliary debug port: used for GDB 362 VMM_DEBUG_PORT_PARAMS aux_port; 363 364 /* 64-bit aligned */ 365 366 // Global bit-mask filter for debug printouts. Each bit in the mask 367 // enables printing of one class (documented separately) of printout. 368 // All 0's : nothing is printed 369 // All 1's : everything is printed 370 UINT64 mask; 371 372 /* 64-bit aligned */ 373 374 // Physical address of debug buffer used during deadloop 375 UINT64 debug_data; 376 377 /* 64-bit aligned */ 378 379 } PACKED VMM_DEBUG_PARAMS; 380 381 382 // VMM_STARTUP_STRUCT: Startup Parameters 383 // Top level structure that describes VMM layout, guests, etc. 384 // Passed to VMM entry point. 385 386 387 #define VMM_STARTUP_STRUCT_VERSION 5 388 389 // Minimal version number of VMM_STARTUP_STRUCT that includes VMM_DEBUG_PARAMS. 390 // This is required for proper version checking on VMM initialization, as older 391 // versions don't have this structure and VMM must use defaults. 392 #define VMM_STARTUP_STRUCT_MIN_VERSION_WITH_DEBUG 2 393 394 395 // Startup capability flags (max 16 bits) 396 397 #define VMM_STARTUP_ACPI_DISCOVERY_CAPABILITY BIT_VALUE(0) 398 399 // 1 - the VMM is launched in a post-os-launch mode 400 // 0 - the VMM is launched in a pre-os-launch mode 401 #define VMM_STARTUP_POST_OS_LAUNCH_MODE BIT_VALUE(1) 402 403 // Images used by uVMM 404 typedef enum _UVMM_IMAGE_INDEX 405 { 406 uvmm_image = 0, 407 thunk_image, 408 uvmm_images_count 409 } UVMM_IMAGE_INDEX; 410 411 // This structure should be aligned on 8 byte 412 #define VMM_STARTUP_STRUCT_ALIGNMENT 8 413 414 typedef struct _VMM_STARTUP_STRUCT { 415 UINT16 size_of_this_struct; 416 UINT16 version_of_this_struct; 417 418 // number of processors/cores at install time. 419 // used to verify correctness of the bootstrap process 420 UINT16 number_of_processors_at_install_time; 421 422 // number of processors/cores as was discovered by vmm loader 423 // used to verify correctness of the bootstrap process 424 UINT16 number_of_processors_at_boot_time; 425 426 /* 64-bit aligned */ 427 428 // number of secondary Guests 429 UINT16 number_of_secondary_guests; 430 431 // size of stack for VMM per processor. In 4K pages. 432 UINT16 size_of_vmm_stack; 433 434 // values to be used by VMM to hide devices if VT-d is not accessable 435 // **** THIS FEATURE IS CURRENTLY NOT SUPPORTED **** 436 UINT16 unsupported_vendor_id; 437 UINT16 unsupported_device_id; 438 439 /* 64-bit aligned */ 440 441 // set of flags, that define policies for the VMM as a whole 442 UINT32 flags; 443 444 // magic number of the guest, that owns all platform devices 445 // that were not assigned to any guest 446 UINT32 default_device_owner; 447 448 /* 64-bit aligned */ 449 450 // magic number of the guest, that serves as OSPM. 451 // SMM code is executed in the context of this guest 452 UINT32 acpi_owner; 453 454 // magic number of the guest, that process platform NMIs. 455 UINT32 nmi_owner; 456 457 /* 64-bit aligned */ 458 459 // vmm memory layout 460 UINT64 num_excluded_regions; 461 VMM_MEMORY_LAYOUT vmm_memory_layout[MAXEXCLUDEDREGIONS]; 462 463 // pointer to the int 15 E820 BIOS table 464 // INT15_E820_MEMORY_MAP* 465 // Loader must convert the table into the E820 extended format 466 // (each entry 24 bytes long). If BIOS-returned entry was 20 bytes long 467 // the extended attributes should be set to 0x1. 468 UINT64 physical_memory_layout_E820; 469 470 /* 64-bit aligned */ 471 // pointer to the primary guest state 472 // VMM_GUEST_STARTUP* 473 UINT64 primary_guest_startup_state; 474 475 /* 64-bit aligned */ 476 // pointer to the array of secondary guest states 477 // size of array is number_of_secondary_guests 478 // VMM_GUEST_STARTUP* 479 UINT64 secondary_guests_startup_state_array; 480 481 /* 64-bit aligned */ 482 // Debug parameters 483 VMM_DEBUG_PARAMS debug_params; 484 485 /* 64-bit aligned */ 486 // Active cpu local apic ids 487 UINT8 cpu_local_apic_ids[ALIGN_FORWARD(VMM_MAX_CPU_SUPPORTED, 8)]; 488 }PACKED VMM_STARTUP_STRUCT; 489 490 491 // VMM_APPLICATION_PARAMS_STRUCT: Application Parameters 492 // 493 // Top level structure that describes application parameters. 494 // Used to pass application-related install data from installer to VMM-based app. 495 496 #define VMM_APPLICATION_PARAMS_STRUCT_VERSION 1 497 498 typedef struct _VMM_APPLICATION_PARAMS_STRUCT { 499 UINT32 size_of_this_struct; // overall, including all params 500 UINT32 number_of_params; // number of params that will follow 501 502 // random generated id to avoid vmm shutdown by others 503 UINT64 session_id; 504 // page entry list for the additional heap 505 UINT64 address_entry_list; 506 UINT64 entry_number; 507 // this is per parameter 508 // VMM_GUID guid_of_param1; 509 // struct param1; 510 // VMM_GUID guid_of_param2; 511 // struct param2; 512 #ifdef USE_ACPI 513 UINT64 fadt_gpa; 514 #ifdef ENABLE_VTD 515 UINT64 dmar_gpa; 516 #endif 517 #endif //ifdef USE_ACPI 518 } VMM_APPLICATION_PARAMS_STRUCT; 519 520 521 // VMM entry point itself. Must be called by VMM loader once for each 522 // processor/core in the platform. Parameters to the entry point are different 523 // for BSP (boot strap processor) and for each AP (application processor) 524 // The order of the calls between processors is not defined, assuming that 525 // this function will be called on all number_of_processors defined in the 526 // VMM_STARTUP_STRUCT. 527 // Never returns. 528 529 void vmm_main( 530 // logical local apic ID of the current processor 531 // 0 - BSP, != 0 - AP 532 UINT32 local_apic_id, 533 534 // VMM_STARTUP_STRUCT should be passed only for BSP 535 // VMM_STARTUP_STRUCT* 536 UINT64 startup_data, 537 538 // VMM_APPLICATION_PARAMS_STRUCT should be passed only for BSP 539 // VMM_APPLICATION_PARAMS_STRUCT* 540 UINT64 application_params, 541 542 // must be 0 543 UINT64 reserved 544 ); 545 546 547 #pragma PACK_OFF 548 549 #endif // _UVMM_STARTUP_H_ 550