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