From 112f2bed57349dcc08acc583db47b4d696e032bb Mon Sep 17 00:00:00 2001 From: Rian Quinn Date: Fri, 24 Sep 2021 08:05:26 -0600 Subject: [PATCH] Add clear() to init on Intel This patch clears the VMCS on init for Intel, which is needed because the memory that is given to the the VMCS might have come from an old VMCS that was still cached in hardware. --- kernel/src/dispatch_syscall_vs_op.hpp | 4 ++-- kernel/src/vs_pool_t.hpp | 10 +++++++--- kernel/src/x64/amd/vs_t.hpp | 10 +++++++--- kernel/src/x64/intel/vs_t.hpp | 16 +++++++++++++--- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/kernel/src/dispatch_syscall_vs_op.hpp b/kernel/src/dispatch_syscall_vs_op.hpp index b5bd2ec1..78521f2e 100644 --- a/kernel/src/dispatch_syscall_vs_op.hpp +++ b/kernel/src/dispatch_syscall_vs_op.hpp @@ -384,7 +384,7 @@ namespace mk return syscall::BF_STATUS_INVALID_INPUT_REG1; } - auto const ret{mut_vs_pool.clear(intrinsic, vsid)}; + auto const ret{mut_vs_pool.clear(mut_tls, intrinsic, vsid)}; if (bsl::unlikely(!ret)) { bsl::print() << bsl::here(); return syscall::BF_STATUS_FAILURE_UNKNOWN; @@ -430,7 +430,7 @@ namespace mk return syscall::BF_STATUS_FAILURE_UNKNOWN; } - auto const ret{mut_vs_pool.migrate(mut_intrinsic, ppid, vsid)}; + auto const ret{mut_vs_pool.migrate(mut_tls, mut_intrinsic, ppid, vsid)}; if (bsl::unlikely(!ret)) { bsl::print() << bsl::here(); return syscall::BF_STATUS_FAILURE_UNKNOWN; diff --git a/kernel/src/vs_pool_t.hpp b/kernel/src/vs_pool_t.hpp index 0937d14f..75d48071 100644 --- a/kernel/src/vs_pool_t.hpp +++ b/kernel/src/vs_pool_t.hpp @@ -263,6 +263,7 @@ namespace mk /// @brief Migrates the requested vs_t from one PP to another /// /// + /// @param mut_tls the current TLS block /// @param mut_intrinsic the intrinsic_t to use /// @param ppid the ID of the PP to migrate to /// @param vsid the ID of the vs_t to migrate @@ -271,11 +272,12 @@ namespace mk /// [[nodiscard]] constexpr auto migrate( + tls_t &mut_tls, intrinsic_t &mut_intrinsic, bsl::safe_u16 const &ppid, bsl::safe_u16 const &vsid) noexcept -> bsl::errc_type { - return this->get_vs(vsid)->migrate(mut_intrinsic, ppid); + return this->get_vs(vsid)->migrate(mut_tls, mut_intrinsic, ppid); } /// @@ -458,15 +460,17 @@ namespace mk /// values stored in the vs_t. /// /// + /// @param mut_tls the current TLS block /// @param intrinsic the intrinsic_t to use /// @param vsid the ID of the vs_t to clear /// @return Returns bsl::errc_success on success, bsl::errc_failure /// and friends otherwise /// [[nodiscard]] constexpr auto - clear(intrinsic_t const &intrinsic, bsl::safe_u16 const &vsid) noexcept -> bsl::errc_type + clear(tls_t &mut_tls, intrinsic_t const &intrinsic, bsl::safe_u16 const &vsid) noexcept + -> bsl::errc_type { - return this->get_vs(vsid)->clear(intrinsic); + return this->get_vs(vsid)->clear(mut_tls, intrinsic); } /// diff --git a/kernel/src/x64/amd/vs_t.hpp b/kernel/src/x64/amd/vs_t.hpp index a898e1df..b983e2eb 100644 --- a/kernel/src/x64/amd/vs_t.hpp +++ b/kernel/src/x64/amd/vs_t.hpp @@ -452,19 +452,21 @@ namespace mk /// @brief Migrates this vs_t from one PP to another /// /// + /// @param tls the current TLS block /// @param intrinsic the intrinsic_t to use /// @param ppid the ID of the PP to migrate to /// @return Returns bsl::errc_success on success, bsl::errc_failure /// and friends otherwise /// [[nodiscard]] constexpr auto - migrate(intrinsic_t const &intrinsic, bsl::safe_u16 const &ppid) noexcept -> bsl::errc_type + migrate(tls_t const &tls, intrinsic_t const &intrinsic, bsl::safe_u16 const &ppid) noexcept + -> bsl::errc_type { bsl::expects(allocated_status_t::allocated == m_allocated); bsl::expects(ppid.is_valid_and_checked()); bsl::expects(ppid != syscall::BF_INVALID_ID); - auto const ret{this->clear(intrinsic)}; + auto const ret{this->clear(tls, intrinsic)}; if (bsl::unlikely(!ret)) { bsl::print() << bsl::here(); return ret; @@ -2367,13 +2369,15 @@ namespace mk /// values stored in the vs_t. /// /// + /// @param tls the current TLS block /// @param intrinsic the intrinsic_t to use /// @return Returns bsl::errc_success on success, bsl::errc_failure /// and friends otherwise /// [[nodiscard]] constexpr auto - clear(intrinsic_t const &intrinsic) noexcept -> bsl::errc_type + clear(tls_t const &tls, intrinsic_t const &intrinsic) noexcept -> bsl::errc_type { + bsl::discard(tls); bsl::discard(intrinsic); bsl::expects(allocated_status_t::allocated == m_allocated); diff --git a/kernel/src/x64/intel/vs_t.hpp b/kernel/src/x64/intel/vs_t.hpp index 9c4a7663..9c0d6d47 100644 --- a/kernel/src/x64/intel/vs_t.hpp +++ b/kernel/src/x64/intel/vs_t.hpp @@ -481,6 +481,9 @@ namespace mk m_vmcs->revision_id = bsl::to_u32_unsafe(revision_id).get(); this->ensure_this_vs_is_loaded(mut_tls, mut_intrinsic); + bsl::expects(mut_intrinsic.vmcl(&m_vmcs_phys)); + bsl::expects(mut_intrinsic.vmld(&m_vmcs_phys)); + auto const es{mut_intrinsic.es_selector()}; bsl::expects(mut_intrinsic.vmwr16(VMCS_HOST_ES_SELECTOR, es)); auto const cs{mut_intrinsic.cs_selector()}; @@ -831,19 +834,21 @@ namespace mk /// @brief Migrates this vs_t from one PP to another /// /// + /// @param mut_tls the current TLS block /// @param intrinsic the intrinsic_t to use /// @param ppid the ID of the PP to migrate to /// @return Returns bsl::errc_success on success, bsl::errc_failure /// and friends otherwise /// [[nodiscard]] constexpr auto - migrate(intrinsic_t const &intrinsic, bsl::safe_u16 const &ppid) noexcept -> bsl::errc_type + migrate(tls_t &mut_tls, intrinsic_t const &intrinsic, bsl::safe_u16 const &ppid) noexcept + -> bsl::errc_type { bsl::expects(allocated_status_t::allocated == m_allocated); bsl::expects(ppid.is_valid_and_checked()); bsl::expects(ppid != syscall::BF_INVALID_ID); - auto const ret{this->clear(intrinsic)}; + auto const ret{this->clear(mut_tls, intrinsic)}; if (bsl::unlikely(!ret)) { bsl::print() << bsl::here(); return ret; @@ -3137,12 +3142,13 @@ namespace mk /// values stored in the vs_t. /// /// + /// @param mut_tls the current TLS block /// @param intrinsic the intrinsic_t to use /// @return Returns bsl::errc_success on success, bsl::errc_failure /// and friends otherwise /// [[nodiscard]] constexpr auto - clear(intrinsic_t const &intrinsic) noexcept -> bsl::errc_type + clear(tls_t &mut_tls, intrinsic_t const &intrinsic) noexcept -> bsl::errc_type { bsl::discard(intrinsic); bsl::expects(allocated_status_t::allocated == m_allocated); @@ -3160,6 +3166,10 @@ namespace mk bsl::expects(intrinsic.vmcl(&m_vmcs_phys)); m_vmcs_missing_registers.launched = {}; + if (this->id() == mut_tls.loaded_vsid) { + mut_tls.loaded_vsid = syscall::BF_INVALID_ID.get(); + } + return bsl::errc_success; }