Skip to content

Commit

Permalink
KVM_IRQ_LINE, Implement Ioctl
Browse files Browse the repository at this point in the history
  • Loading branch information
softickllc committed Jan 25, 2022
1 parent 9401ba2 commit 64daddf
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 14 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
5 changes: 4 additions & 1 deletion shim/include/handle_vm_kvm_irq_line.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include <kvm_irq_level.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_irq_line.
*
* <!-- 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_irq_line(struct kvm_irq_level *const pmut_ioctl_args) NOEXCEPT;
NODISCARD int64_t handle_vm_kvm_irq_line(
struct shim_vm_t *const pmut_vm, struct kvm_irq_level *const pmut_ioctl_args) NOEXCEPT;

#ifdef __cplusplus
}
Expand Down
22 changes: 20 additions & 2 deletions shim/include/kvm_irq_level.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@

#include <stdint.h>

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

#ifdef __cplusplus
extern "C"
{
Expand All @@ -44,8 +48,22 @@ extern "C"
*/
struct kvm_irq_level
{
/** @brief replace me with contents from KVM API */
int32_t dummy;
/**
* <!-- description -->
* @brief TODO
*/
// NOLINTNEXTLINE(bsl-decl-forbidden)
union
{
/** @brief GSI*/
// NOLINTNEXTLINE(bsl-non-safe-integral-types-are-forbidden)
uint32_t irq;
/** @brief not used for KVM_IRQ_LEVEL*/
// NOLINTNEXTLINE(bsl-non-safe-integral-types-are-forbidden)
uint32_t status;
};
/** @brief 0 or 1*/
uint32_t level;
};

#pragma pack(pop)
Expand Down
59 changes: 59 additions & 0 deletions shim/include/kvm_irq_level.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/// @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_IRQ_LEVEL_HPP
#define KVM_IRQ_LEVEL_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_irq_level
///
/// <!-- description -->
/// @brief see /include/uapi/linux/kvm.h in Linux for more details.
///
struct kvm_irq_level final
{
// NOLINTNEXTLINE(bsl-decl-forbidden)
union
{
/** @brief GSI*/
bsl::uint32 irq;
/** @brief not used for KVM_IRQ_LEVEL*/
bsl::uint32 status;
};
/** @brief 0 or 1*/
bsl::uint32 level;
};
}

#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_irq_line HEADERS)
56 changes: 56 additions & 0 deletions shim/integration/kvm_irq_line.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 irqline{mut_vcpu.send(shim::KVM_IRQ_LINE)};
integration::verify(irqline.is_pos());
integration::verify(irqline >= mut_ret.get());
}
return bsl::exit_success;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <kvm_cpuid2.hpp>
#include <kvm_cpuid_entry2.hpp>
#include <kvm_fpu.hpp>
#include <kvm_irq_level.hpp>
#include <kvm_mp_state.hpp>
#include <kvm_msr_entry.hpp>
#include <kvm_msr_list.hpp>
Expand Down Expand Up @@ -163,8 +164,9 @@ namespace shim
static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0x8d, struct kvm_fpu))};
/// @brief defines KVM's KVM_CREATE_IRQCHIP IOCTL
constexpr bsl::safe_umx KVM_CREATE_IRQCHIP{static_cast<bsl::uintmx>(_IO(SHIMIO.get(), 0x60))};
// /// @brief defines KVM's KVM_IRQ_LINE IOCTL
// constexpr bsl::safe_umx KVM_IRQ_LINE{static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0x61, struct kvm_irq_level))};
/// @brief defines KVM's KVM_IRQ_LINE IOCTL
constexpr bsl::safe_umx KVM_IRQ_LINE{
static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0x61, struct kvm_irq_level))};
// /// @brief defines KVM's KVM_GET_IRQCHIP IOCTL
// constexpr bsl::safe_umx KVM_GET_IRQCHIP{static_cast<bsl::uintmx>(_IOWR(SHIMIO.get(), 0x62, struct kvm_irqchip))};
// /// @brief defines KVM's KVM_SET_IRQCHIP IOCTL
Expand Down
25 changes: 21 additions & 4 deletions shim/linux/src/entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <handle_vm_kvm_check_extension.h>
#include <handle_vm_kvm_create_vcpu.h>
#include <handle_vm_kvm_destroy_vcpu.h>
#include <handle_vm_kvm_irq_line.h>
#include <handle_vm_kvm_set_user_memory_region.h>
#include <linux/anon_inodes.h>
#include <linux/kernel.h>
Expand Down Expand Up @@ -616,10 +617,24 @@ dispatch_vm_kvm_ioeventfd(struct kvm_ioeventfd *const ioctl_args)
}

static long
dispatch_vm_kvm_irq_line(struct kvm_irq_level *const ioctl_args)
dispatch_vm_kvm_irq_line(
struct shim_vm_t *const pmut_vm,
struct kvm_irq_level *const pmut_ioctl_args)
{
(void)ioctl_args;
return -EINVAL;
struct kvm_irq_level 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_irq_line(pmut_vm, &mut_args)) {
bferror("handle_vm_kvm_irq_line failed");
return -EINVAL;
}

return 0;
}

static long
Expand Down Expand Up @@ -844,7 +859,9 @@ dev_unlocked_ioctl_vm(
}

case KVM_IRQ_LINE: {
return dispatch_vm_kvm_irq_line((struct kvm_irq_level *)ioctl_args);
return dispatch_vm_kvm_irq_line(
(struct shim_vm_t *)pmut_mut_vm,
(struct kvm_irq_level *)ioctl_args);
}

case KVM_IRQFD: {
Expand Down
17 changes: 15 additions & 2 deletions shim/src/handle_vm_kvm_irq_line.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,33 @@
* SOFTWARE.
*/

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

/**
* <!-- description -->
* @brief Handles the execution of kvm_irq_line.
*
* <!-- 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_irq_line(struct kvm_irq_level *const pmut_ioctl_args) NOEXCEPT
handle_vm_kvm_irq_line(
struct shim_vm_t *const pmut_vm, struct kvm_irq_level *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;
}
23 changes: 21 additions & 2 deletions shim/tests/src/test_handle_vm_kvm_irq_line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
/// SOFTWARE.

#include "../../include/handle_vm_kvm_irq_line.h"
#include "shim_vm_t.h"

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

#include <bsl/ut.hpp>

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

bsl::ut_scenario{"hypervisor not detected"} = []() noexcept {
bsl::ut_given{} = [&]() noexcept {
kvm_irq_level 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_irq_line(&mut_vm, &mut_args));
};
bsl::ut_cleanup{} = [&]() noexcept {
g_mut_hypervisor_detected = true;
};
};
};
Expand Down

0 comments on commit 64daddf

Please sign in to comment.