<!-- description --> @brief Dispatches the bootstrap process as needed. Note that the bootstrap callback is only called when starting the hypervisor on root VPs. <!-- inputs/outputs --> @param gs the gs_t to use @param mut_tls the tls_t to use @param mut_sys the bf_syscall_t to use @param intrinsic the intrinsic_t to use @param mut_vp_pool the vp_pool_t to use @param mut_vs_pool the vs_pool_t to
| 58 | /// and friends otherwise |
| 59 | /// |
| 60 | [[nodiscard]] static constexpr auto |
| 61 | dispatch_bootstrap( |
| 62 | gs_t const &gs, |
| 63 | tls_t &mut_tls, |
| 64 | syscall::bf_syscall_t &mut_sys, |
| 65 | intrinsic_t const &intrinsic, |
| 66 | vp_pool_t &mut_vp_pool, |
| 67 | vs_pool_t &mut_vs_pool, |
| 68 | bsl::safe_u16 const &ppid) noexcept -> bsl::errc_type |
| 69 | { |
| 70 | bsl::expects(ppid.is_valid_and_checked()); |
| 71 | bsl::expects(ppid != syscall::BF_INVALID_ID); |
| 72 | |
| 73 | auto const ret{tls_initialize(mut_tls, mut_sys, intrinsic)}; |
| 74 | if (bsl::unlikely(!ret)) { |
| 75 | bsl::print<bsl::V>() << bsl::here(); |
| 76 | return bsl::errc_failure; |
| 77 | } |
| 78 | |
| 79 | /// NOTE: |
| 80 | /// - In order to execcute bf_vs_op_run, which is what executes |
| 81 | /// the hypervisor, we must have a VM, VP and VS. |
| 82 | /// - The root VM is already created for us, so we don't need to |
| 83 | /// create this ourselves. You only need to create VM's if you |
| 84 | /// plan to add guest support with your extensions. |
| 85 | /// |
| 86 | |
| 87 | constexpr auto vmid{syscall::BF_ROOT_VMID}; |
| 88 | |
| 89 | /// NOTE: |
| 90 | /// - The VP in this simple example does nothing, but we still need |
| 91 | /// to create one. The VP is used when you have more than one VS |
| 92 | /// per VP (e.g., if you are implementing HyperV's VSM, or nested |
| 93 | /// virtualization support). Otherwise, you will always have one |
| 94 | /// VS for each VP, and they will appear as the same thing. |
| 95 | /// - The VS is what stores the state associated with the VS. It |
| 96 | /// is the thing that does most of the work, including storing |
| 97 | /// the VMCS/VMCB and other CPU register state that is needed. |
| 98 | /// |
| 99 | |
| 100 | auto const vpid{mut_vp_pool.allocate(gs, mut_tls, mut_sys, intrinsic, vmid)}; |
| 101 | if (bsl::unlikely(vpid.is_invalid())) { |
| 102 | bsl::print<bsl::V>() << bsl::here(); |
| 103 | return bsl::errc_failure; |
| 104 | } |
| 105 | |
| 106 | auto const vsid{mut_vs_pool.allocate(gs, mut_tls, mut_sys, intrinsic, vpid, ppid)}; |
| 107 | if (bsl::unlikely(vsid.is_invalid())) { |
| 108 | bsl::print<bsl::V>() << bsl::here(); |
| 109 | return bsl::errc_failure; |
| 110 | } |
| 111 | |
| 112 | /// NOTE: |
| 113 | /// - Run the newly created VP on behalf of the root VM using the |
| 114 | /// newly created and initialized VS. Note that this version of |
| 115 | /// the run function should only be used when starting the |
| 116 | /// hypervisor, or switching the VM, VP or VS as it is slow. |
| 117 | /// |
no test coverage detected