Skip to content

Commit c64a025

Browse files
committed
KVM_IRQ_LINE, Implement Ioctl
1 parent acbfdf1 commit c64a025

File tree

10 files changed

+202
-14
lines changed

10 files changed

+202
-14
lines changed

hypercall/include/mv_constants.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ namespace hypercall
129129
constexpr auto MV_MAP_FLAG_UNCACHEABLE_MINUS{0x0400000000000000_u64};
130130
/// @brief Indicates the map is mapped as WC
131131
constexpr auto MV_MAP_FLAG_WRITE_COMBINING{0x0800000000000000_u64};
132-
/// @brief Indicates the map is mapped as WC+
132+
/// @brief Indicates the map is mapped as WC
133133
constexpr auto MV_MAP_FLAG_WRITE_COMBINING_PLUS{0x1000000000000000_u64};
134134
/// @brief Indicates the map is mapped as WT
135135
constexpr auto MV_MAP_FLAG_WRITE_THROUGH{0x2000000000000000_u64};

shim/include/handle_vm_kvm_irq_line.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include <kvm_irq_level.h>
3131
#include <mv_types.h>
32+
#include <shim_vm_t.h>
3233

3334
#ifdef __cplusplus
3435
extern "C"
@@ -40,10 +41,12 @@ extern "C"
4041
* @brief Handles the execution of kvm_irq_line.
4142
*
4243
* <!-- inputs/outputs -->
44+
* @param pmut_vm the argumento hold vm details of type shim_vm_t
4345
* @param pmut_ioctl_args the arguments provided by userspace
4446
* @return SHIM_SUCCESS on success, SHIM_FAILURE on failure.
4547
*/
46-
NODISCARD int64_t handle_vm_kvm_irq_line(struct kvm_irq_level *const pmut_ioctl_args) NOEXCEPT;
48+
NODISCARD int64_t handle_vm_kvm_irq_line(
49+
struct shim_vm_t *const pmut_vm, struct kvm_irq_level *const pmut_ioctl_args) NOEXCEPT;
4750

4851
#ifdef __cplusplus
4952
}

shim/include/kvm_irq_level.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929

3030
#include <stdint.h>
3131

32+
#ifdef __clang__
33+
#pragma clang diagnostic ignored "-Wold-style-cast"
34+
#endif
35+
3236
#ifdef __cplusplus
3337
extern "C"
3438
{
@@ -44,8 +48,22 @@ extern "C"
4448
*/
4549
struct kvm_irq_level
4650
{
47-
/** @brief replace me with contents from KVM API */
48-
int32_t dummy;
51+
/**
52+
* <!-- description -->
53+
* @brief TODO
54+
*/
55+
// NOLINTNEXTLINE(bsl-decl-forbidden)
56+
union
57+
{
58+
/** @brief GSI*/
59+
// NOLINTNEXTLINE(bsl-non-safe-integral-types-are-forbidden)
60+
uint32_t irq;
61+
/** @brief not used for KVM_IRQ_LEVEL*/
62+
// NOLINTNEXTLINE(bsl-non-safe-integral-types-are-forbidden)
63+
uint32_t status;
64+
};
65+
/** @brief 0 or 1*/
66+
uint32_t level;
4967
};
5068

5169
#pragma pack(pop)

shim/include/kvm_irq_level.hpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/// @copyright
2+
/// Copyright (C) 2020 Assured Information Security, Inc.
3+
///
4+
/// @copyright
5+
/// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
/// of this software and associated documentation files (the "Software"), to deal
7+
/// in the Software without restriction, including without limitation the rights
8+
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
/// copies of the Software, and to permit persons to whom the Software is
10+
/// furnished to do so, subject to the following conditions:
11+
///
12+
/// @copyright
13+
/// The above copyright notice and this permission notice shall be included in
14+
/// all copies or substantial portions of the Software.
15+
///
16+
/// @copyright
17+
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
/// SOFTWARE.
24+
25+
#ifndef KVM_IRQ_LEVEL_HPP
26+
#define KVM_IRQ_LEVEL_HPP
27+
28+
#include <bsl/convert.hpp>
29+
#include <bsl/safe_integral.hpp>
30+
31+
#pragma pack(push, 1)
32+
33+
namespace shim
34+
{
35+
/// @brief defines the size of the padding field
36+
constexpr auto PAD_SIZE_MSI{16_umx};
37+
/// @struct kvm_irq_level
38+
///
39+
/// <!-- description -->
40+
/// @brief see /include/uapi/linux/kvm.h in Linux for more details.
41+
///
42+
struct kvm_irq_level final
43+
{
44+
// NOLINTNEXTLINE(bsl-decl-forbidden)
45+
union
46+
{
47+
/** @brief GSI*/
48+
bsl::uint32 irq;
49+
/** @brief not used for KVM_IRQ_LEVEL*/
50+
bsl::uint32 status;
51+
};
52+
/** @brief 0 or 1*/
53+
bsl::uint32 level;
54+
};
55+
}
56+
57+
#pragma pack(pop)
58+
59+
#endif

shim/integration/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,4 @@ microv_add_shim_integration(kvm_get_supported_cpuid HEADERS)
5050
microv_add_shim_integration(kvm_get_msrs HEADERS)
5151
microv_add_shim_integration(kvm_set_msrs HEADERS)
5252
microv_add_shim_integration(kvm_create_irqchip HEADERS)
53+
microv_add_shim_integration(kvm_irq_line HEADERS)

shim/integration/kvm_irq_line.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/// @copyright
2+
/// Copyright (C) 2020 Assured Information Security, Inc.
3+
///
4+
/// @copyright
5+
/// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
/// of this software and associated documentation files (the "Software"), to deal
7+
/// in the Software without restriction, including without limitation the rights
8+
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
/// copies of the Software, and to permit persons to whom the Software is
10+
/// furnished to do so, subject to the following conditions:
11+
///
12+
/// @copyright
13+
/// The above copyright notice and this permission notice shall be included in
14+
/// all copies or substantial portions of the Software.
15+
///
16+
/// @copyright
17+
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
/// SOFTWARE.
24+
25+
#include <integration_utils.hpp>
26+
#include <ioctl_t.hpp>
27+
#include <shim_platform_interface.hpp>
28+
29+
#include <bsl/convert.hpp>
30+
#include <bsl/enable_color.hpp>
31+
#include <bsl/exit_code.hpp>
32+
#include <bsl/safe_integral.hpp>
33+
34+
/// <!-- description -->
35+
/// @brief Provides the main entry point for this application.
36+
///
37+
/// <!-- inputs/outputs -->
38+
/// @return bsl::exit_success on success, bsl::exit_failure otherwise.
39+
///
40+
[[nodiscard]] auto
41+
main() noexcept -> bsl::exit_code
42+
{
43+
bsl::enable_color();
44+
integration::ioctl_t mut_system_ctl{shim::DEVICE_NAME};
45+
auto const vmfd{mut_system_ctl.send(shim::KVM_CREATE_VM)};
46+
integration::ioctl_t mut_vm{bsl::to_i32(vmfd)};
47+
auto const vcpufd{mut_vm.send(shim::KVM_CREATE_VCPU)};
48+
integration::ioctl_t mut_vcpu{bsl::to_i32(vcpufd)};
49+
constexpr auto mut_ret{0_i64};
50+
{
51+
auto const irqline{mut_vcpu.send(shim::KVM_IRQ_LINE)};
52+
integration::verify(irqline.is_pos());
53+
integration::verify(irqline >= mut_ret.get());
54+
}
55+
return bsl::exit_success;
56+
}

shim/linux/include/platform_interface/shim_platform_interface.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <kvm_cpuid2.hpp>
3232
#include <kvm_cpuid_entry2.hpp>
3333
#include <kvm_fpu.hpp>
34+
#include <kvm_irq_level.hpp>
3435
#include <kvm_mp_state.hpp>
3536
#include <kvm_msr_entry.hpp>
3637
#include <kvm_msr_list.hpp>
@@ -163,8 +164,9 @@ namespace shim
163164
static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0x8d, struct kvm_fpu))};
164165
/// @brief defines KVM's KVM_CREATE_IRQCHIP IOCTL
165166
constexpr bsl::safe_umx KVM_CREATE_IRQCHIP{static_cast<bsl::uintmx>(_IO(SHIMIO.get(), 0x60))};
166-
// /// @brief defines KVM's KVM_IRQ_LINE IOCTL
167-
// constexpr bsl::safe_umx KVM_IRQ_LINE{static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0x61, struct kvm_irq_level))};
167+
/// @brief defines KVM's KVM_IRQ_LINE IOCTL
168+
constexpr bsl::safe_umx KVM_IRQ_LINE{
169+
static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0x61, struct kvm_irq_level))};
168170
// /// @brief defines KVM's KVM_GET_IRQCHIP IOCTL
169171
// constexpr bsl::safe_umx KVM_GET_IRQCHIP{static_cast<bsl::uintmx>(_IOWR(SHIMIO.get(), 0x62, struct kvm_irqchip))};
170172
// /// @brief defines KVM's KVM_SET_IRQCHIP IOCTL

shim/linux/src/entry.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include <handle_vm_kvm_create_irqchip.h>
5252
#include <handle_vm_kvm_create_vcpu.h>
5353
#include <handle_vm_kvm_destroy_vcpu.h>
54+
#include <handle_vm_kvm_irq_line.h>
5455
#include <handle_vm_kvm_set_user_memory_region.h>
5556
#include <linux/anon_inodes.h>
5657
#include <linux/kernel.h>
@@ -621,10 +622,24 @@ dispatch_vm_kvm_ioeventfd(struct kvm_ioeventfd *const ioctl_args)
621622
}
622623

623624
static long
624-
dispatch_vm_kvm_irq_line(struct kvm_irq_level *const ioctl_args)
625+
dispatch_vm_kvm_irq_line(
626+
struct shim_vm_t *const pmut_vm,
627+
struct kvm_irq_level *const pmut_ioctl_args)
625628
{
626-
(void)ioctl_args;
627-
return -EINVAL;
629+
struct kvm_irq_level mut_args;
630+
uint64_t const size = sizeof(mut_args);
631+
632+
if (platform_copy_from_user(&mut_args, pmut_ioctl_args, size)) {
633+
bferror("platform_copy_from_user failed");
634+
return -EINVAL;
635+
}
636+
637+
if (handle_vm_kvm_irq_line(pmut_vm, &mut_args)) {
638+
bferror("handle_vm_kvm_irq_line failed");
639+
return -EINVAL;
640+
}
641+
642+
return 0;
628643
}
629644

630645
static long
@@ -849,7 +864,9 @@ dev_unlocked_ioctl_vm(
849864
}
850865

851866
case KVM_IRQ_LINE: {
852-
return dispatch_vm_kvm_irq_line((struct kvm_irq_level *)ioctl_args);
867+
return dispatch_vm_kvm_irq_line(
868+
(struct shim_vm_t *)pmut_mut_vm,
869+
(struct kvm_irq_level *)ioctl_args);
853870
}
854871

855872
case KVM_IRQFD: {

shim/src/handle_vm_kvm_irq_line.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,33 @@
2424
* SOFTWARE.
2525
*/
2626

27+
#include <debug.h>
28+
#include <detect_hypervisor.h>
2729
#include <kvm_irq_level.h>
2830
#include <mv_types.h>
31+
#include <platform.h>
32+
#include <shim_vm_t.h>
2933

3034
/**
3135
* <!-- description -->
3236
* @brief Handles the execution of kvm_irq_line.
3337
*
3438
* <!-- inputs/outputs -->
39+
* @param pmut_vm the argumento hold vm details of type shim_vm_t
3540
* @param pmut_ioctl_args the arguments provided by userspace
3641
* @return SHIM_SUCCESS on success, SHIM_FAILURE on failure.
3742
*/
3843
NODISCARD int64_t
39-
handle_vm_kvm_irq_line(struct kvm_irq_level *const pmut_ioctl_args) NOEXCEPT
44+
handle_vm_kvm_irq_line(
45+
struct shim_vm_t *const pmut_vm, struct kvm_irq_level *const pmut_ioctl_args) NOEXCEPT
4046
{
41-
(void)pmut_ioctl_args;
47+
platform_expects(NULL != pmut_vm);
48+
platform_expects(NULL != pmut_ioctl_args);
49+
50+
if (detect_hypervisor()) {
51+
bferror("The shim is not running in a VM. Did you forget to start MicroV?");
52+
return SHIM_FAILURE;
53+
}
54+
//TODO: Cally the hypercall here after its implementation
4255
return SHIM_SUCCESS;
4356
}

shim/tests/src/test_handle_vm_kvm_irq_line.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@
2323
/// SOFTWARE.
2424

2525
#include "../../include/handle_vm_kvm_irq_line.h"
26+
#include "shim_vm_t.h"
2627

28+
#include <helpers.hpp>
2729
#include <kvm_irq_level.h>
28-
#include <mv_types.h>
2930

3031
#include <bsl/ut.hpp>
3132

@@ -43,12 +44,30 @@ namespace shim
4344
[[nodiscard]] constexpr auto
4445
tests() noexcept -> bsl::exit_code
4546
{
47+
init_tests();
4648
bsl::ut_scenario{"description"} = []() noexcept {
4749
bsl::ut_given{} = [&]() noexcept {
4850
kvm_irq_level mut_args{};
51+
shim_vm_t mut_vm{};
4952
bsl::ut_when{} = [&]() noexcept {
5053
bsl::ut_then{} = [&]() noexcept {
51-
bsl::ut_check(SHIM_SUCCESS == handle_vm_kvm_irq_line(&mut_args));
54+
bsl::ut_check(SHIM_SUCCESS == handle_vm_kvm_irq_line(&mut_vm, &mut_args));
55+
};
56+
};
57+
};
58+
};
59+
60+
bsl::ut_scenario{"hypervisor not detected"} = []() noexcept {
61+
bsl::ut_given{} = [&]() noexcept {
62+
kvm_irq_level mut_args{};
63+
shim_vm_t mut_vm{};
64+
bsl::ut_when{} = [&]() noexcept {
65+
g_mut_hypervisor_detected = false;
66+
bsl::ut_then{} = [&]() noexcept {
67+
bsl::ut_check(SHIM_FAILURE == handle_vm_kvm_irq_line(&mut_vm, &mut_args));
68+
};
69+
bsl::ut_cleanup{} = [&]() noexcept {
70+
g_mut_hypervisor_detected = true;
5271
};
5372
};
5473
};

0 commit comments

Comments
 (0)