Skip to content

Commit

Permalink
KVM_SIGNAL_MSI, Implement ioctl
Browse files Browse the repository at this point in the history
  • Loading branch information
softickllc committed Jan 25, 2022
1 parent a802c42 commit 549fb81
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 17 deletions.
2 changes: 1 addition & 1 deletion hypercall/include/mv_constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ namespace hypercall
constexpr auto MV_MAP_FLAG_UNCACHEABLE_MINUS{0x0400000000000000_u64};
/// @brief Indicates the map is mapped as WC
constexpr auto MV_MAP_FLAG_WRITE_COMBINING{0x0800000000000000_u64};
/// @brief Indicates the map is mapped as WC+
/// @brief Indicates the map is mapped as WC
constexpr auto MV_MAP_FLAG_WRITE_COMBINING_PLUS{0x1000000000000000_u64};
/// @brief Indicates the map is mapped as WT
constexpr auto MV_MAP_FLAG_WRITE_THROUGH{0x2000000000000000_u64};
Expand Down
9 changes: 6 additions & 3 deletions shim/include/handle_vm_kvm_signal_msi.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include <kvm_msi.h>
#include <mv_types.h>
#include <shim_vm_t.h>

#ifdef __cplusplus
extern "C"
Expand All @@ -40,10 +41,12 @@ extern "C"
* @brief Handles the execution of kvm_signal_msi.
*
* <!-- inputs/outputs -->
* @param pmut_ioctl_args the arguments provided by userspace
* @return SHIM_SUCCESS on success, SHIM_FAILURE on failure.
* @param pmut_vm the argumento hold vm details of type shim_vm_t
* @param pmut_ioctl_args the arguments provided by userspace
* @return SHIM_SUCCESS on success, SHIM_FAILURE on failure.
*/
NODISCARD int64_t handle_vm_kvm_signal_msi(struct kvm_msi *const pmut_ioctl_args) NOEXCEPT;
NODISCARD int64_t handle_vm_kvm_signal_msi(
struct shim_vm_t *const pmut_vm, struct kvm_msi *const pmut_ioctl_args) NOEXCEPT;

#ifdef __cplusplus
}
Expand Down
19 changes: 17 additions & 2 deletions shim/include/kvm_msi.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,18 @@

#include <stdint.h>

#ifdef __clang__
#pragma clang diagnostic ignored "-Wold-style-cast"
#endif

#ifdef __cplusplus
extern "C"
{
#endif

#pragma pack(push, 1)
/** @brief defines the padding size */
#define PAD_SIZE_MSI ((uint32_t)16)

/**
* @struct kvm_msi
Expand All @@ -44,8 +50,17 @@ extern "C"
*/
struct kvm_msi
{
/** @brief replace me with contents from KVM API */
int32_t dummy;
/** @brief For PCI, this is a BFD identifier in the lower 16 bits. */
uint32_t address_lo;
/** @brief address_hi bits 31-8 provide bits 31-8 of the destination id. Bits 7-0 of
address_hi must be zero. */
uint32_t address_hi;
/** @brief a MSI message*/
uint32_t data;
/** @brief A Flag to indicate valid or invalid data */
uint32_t flags;
/** @brief TODO */
uint8_t pad[PAD_SIZE_MSI];
};

#pragma pack(pop)
Expand Down
61 changes: 61 additions & 0 deletions shim/include/kvm_msi.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/// @copyright
/// Copyright (C) 2020 Assured Information Security, Inc.
///
/// @copyright
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// @copyright
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// @copyright
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
/// SOFTWARE.

#ifndef KVM_MSI_HPP
#define KVM_MSI_HPP

#include <bsl/array.hpp>
#include <bsl/convert.hpp>
#include <bsl/safe_integral.hpp>

#pragma pack(push, 1)

namespace shim
{
/// @brief defines the size of the padding field
constexpr auto PAD_SIZE_MSI{16_umx};
/// @struct kvm_msi
///
/// <!-- description -->
/// @brief see /include/uapi/linux/kvm.h in Linux for more details.
///
struct kvm_msi final
{
/** @brief For PCI, this is a BFD identifier in the lower 16 bits. */
bsl::uint32 address_lo;
/** @brief address_hi bits 31-8 provide bits 31-8 of the destination id. Bits 7-0 of
address_hi must be zero. */
bsl::uint32 address_hi;
/** @brief a MSI message*/
bsl::uint32 data;
/** @brief A Flag to indicate valid or invalid data */
bsl::uint32 flags;
/** @brief TODO */
bsl::array<bsl::uint8, PAD_SIZE_MSI.get()> pad;
};
}

#pragma pack(pop)

#endif
1 change: 1 addition & 0 deletions shim/integration/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ microv_add_shim_integration(kvm_get_msr_index_list HEADERS)
microv_add_shim_integration(kvm_get_supported_cpuid HEADERS)
microv_add_shim_integration(kvm_get_msrs HEADERS)
microv_add_shim_integration(kvm_set_msrs HEADERS)
microv_add_shim_integration(kvm_signal_msi HEADERS)
56 changes: 56 additions & 0 deletions shim/integration/kvm_signal_msi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/// @copyright
/// Copyright (C) 2020 Assured Information Security, Inc.
///
/// @copyright
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// @copyright
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// @copyright
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
/// SOFTWARE.

#include <integration_utils.hpp>
#include <ioctl_t.hpp>
#include <shim_platform_interface.hpp>

#include <bsl/convert.hpp>
#include <bsl/enable_color.hpp>
#include <bsl/exit_code.hpp>
#include <bsl/safe_integral.hpp>

/// <!-- description -->
/// @brief Provides the main entry point for this application.
///
/// <!-- inputs/outputs -->
/// @return bsl::exit_success on success, bsl::exit_failure otherwise.
///
[[nodiscard]] auto
main() noexcept -> bsl::exit_code
{
bsl::enable_color();
integration::ioctl_t mut_system_ctl{shim::DEVICE_NAME};
auto const vmfd{mut_system_ctl.send(shim::KVM_CREATE_VM)};
integration::ioctl_t mut_vm{bsl::to_i32(vmfd)};
auto const vcpufd{mut_vm.send(shim::KVM_CREATE_VCPU)};
integration::ioctl_t mut_vcpu{bsl::to_i32(vcpufd)};
constexpr auto mut_ret{0_i64};
{
auto const signalmsi{mut_vcpu.send(shim::KVM_SIGNAL_MSI)};
integration::verify(signalmsi.is_pos());
integration::verify(signalmsi >= mut_ret.get());
}
return bsl::exit_success;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <kvm_cpuid_entry2.hpp>
#include <kvm_fpu.hpp>
#include <kvm_mp_state.hpp>
#include <kvm_msi.hpp>
#include <kvm_msr_entry.hpp>
#include <kvm_msr_list.hpp>
#include <kvm_msrs.hpp>
Expand Down Expand Up @@ -232,8 +233,9 @@ namespace shim
// constexpr bsl::safe_umx KVM_SET_ONE_REG{static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0xac, struct kvm_one_reg))};
/// @brief defines KVM's KVM_KVMCLOCK_CTRL IOCTL
constexpr bsl::safe_umx KVM_KVMCLOCK_CTRL{static_cast<bsl::uintmx>(_IO(SHIMIO.get(), 0xad))};
// /// @brief defines KVM's KVM_SIGNAL_MSI IOCTL
// constexpr bsl::safe_umx KVM_SIGNAL_MSI{static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0xa5, struct kvm_msi))};
/// @brief defines KVM's KVM_SIGNAL_MSI IOCTL
constexpr bsl::safe_umx KVM_SIGNAL_MSI{
static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0xa5, struct kvm_msi))};
// /// @brief defines KVM's KVM_CREATE_PIT2 IOCTL
// constexpr bsl::safe_umx KVM_CREATE_PIT2{static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0x77, struct kvm_pit_config))};
// /// @brief defines KVM's KVM_GET_PIT2 IOCTL
Expand Down
23 changes: 19 additions & 4 deletions shim/linux/src/entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include <handle_vm_kvm_create_vcpu.h>
#include <handle_vm_kvm_destroy_vcpu.h>
#include <handle_vm_kvm_set_user_memory_region.h>
#include <handle_vm_kvm_signal_msi.h>
#include <linux/anon_inodes.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
Expand Down Expand Up @@ -738,10 +739,23 @@ dispatch_vm_kvm_set_user_memory_region(
}

static long
dispatch_vm_kvm_signal_msi(struct kvm_msi *const ioctl_args)
dispatch_vm_kvm_signal_msi(
struct shim_vm_t *const pmut_vm, struct kvm_msi *const pmut_ioctl_args)
{
(void)ioctl_args;
return -EINVAL;
struct kvm_msi mut_args;
uint64_t const size = sizeof(mut_args);

if (platform_copy_from_user(&mut_args, pmut_ioctl_args, size)) {
bferror("platform_copy_from_user failed");
return -EINVAL;
}

if (handle_vm_kvm_signal_msi(pmut_vm, &mut_args)) {
bferror("handle_vm_kvm_signal_msi failed");
return -EINVAL;
}

return 0;
}

static long
Expand Down Expand Up @@ -915,7 +929,8 @@ dev_unlocked_ioctl_vm(
}

case KVM_SIGNAL_MSI: {
return dispatch_vm_kvm_signal_msi((struct kvm_msi *)ioctl_args);
return dispatch_vm_kvm_signal_msi(
(struct shim_vm_t *)pmut_mut_vm, (struct kvm_msi *)ioctl_args);
}

case KVM_UNREGISTER_COALESCED_MMIO: {
Expand Down
18 changes: 15 additions & 3 deletions shim/src/handle_vm_kvm_signal_msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,33 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#include <debug.h>
#include <detect_hypervisor.h>
#include <kvm_msi.h>
#include <mv_types.h>
#include <platform.h>
#include <shim_vm_t.h>

/**
* <!-- description -->
* @brief Handles the execution of kvm_signal_msi.
*
* <!-- inputs/outputs -->
* @param pmut_vm the argumento hold vm details of type shim_vm_t
* @param pmut_ioctl_args the arguments provided by userspace
* @return SHIM_SUCCESS on success, SHIM_FAILURE on failure.
*/
NODISCARD int64_t
handle_vm_kvm_signal_msi(struct kvm_msi *const pmut_ioctl_args) NOEXCEPT
handle_vm_kvm_signal_msi(
struct shim_vm_t *const pmut_vm, struct kvm_msi *const pmut_ioctl_args) NOEXCEPT
{
(void)pmut_ioctl_args;
platform_expects(NULL != pmut_vm);
platform_expects(NULL != pmut_ioctl_args);

if (detect_hypervisor()) {
bferror("The shim is not running in a VM. Did you forget to start MicroV?");
return SHIM_FAILURE;
}
//TODO: Cally the hypercall here after its implementation
return SHIM_SUCCESS;
}
22 changes: 20 additions & 2 deletions shim/tests/src/test_handle_vm_kvm_signal_msi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
/// SOFTWARE.

#include "../../include/handle_vm_kvm_signal_msi.h"
#include "shim_vm_t.h"

#include <helpers.hpp>
#include <kvm_msi.h>
#include <mv_types.h>

#include <bsl/ut.hpp>

Expand All @@ -43,17 +44,34 @@ namespace shim
[[nodiscard]] constexpr auto
tests() noexcept -> bsl::exit_code
{
init_tests();
bsl::ut_scenario{"description"} = []() noexcept {
bsl::ut_given{} = [&]() noexcept {
kvm_msi mut_args{};
shim_vm_t mut_vm{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(SHIM_SUCCESS == handle_vm_kvm_signal_msi(&mut_args));
bsl::ut_check(SHIM_SUCCESS == handle_vm_kvm_signal_msi(&mut_vm, &mut_args));
};
};
};
};

bsl::ut_scenario{"hypervisor not detected"} = []() noexcept {
bsl::ut_given{} = [&]() noexcept {
kvm_msi mut_args{};
shim_vm_t mut_vm{};
bsl::ut_when{} = [&]() noexcept {
g_mut_hypervisor_detected = false;
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(SHIM_FAILURE == handle_vm_kvm_signal_msi(&mut_vm, &mut_args));
};
bsl::ut_cleanup{} = [&]() noexcept {
g_mut_hypervisor_detected = true;
};
};
};
};
return bsl::ut_success();
}
}
Expand Down

0 comments on commit 549fb81

Please sign in to comment.