Skip to content

Commit aae2a3b

Browse files
committed
KVM_SIGNAL_MSI, Implement ioctl
1 parent acbfdf1 commit aae2a3b

10 files changed

Lines changed: 200 additions & 17 deletions

File tree

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_signal_msi.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include <kvm_msi.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_signal_msi.
4142
*
4243
* <!-- inputs/outputs -->
43-
* @param pmut_ioctl_args the arguments provided by userspace
44-
* @return SHIM_SUCCESS on success, SHIM_FAILURE on failure.
44+
* @param pmut_vm the argumento hold vm details of type shim_vm_t
45+
* @param pmut_ioctl_args the arguments provided by userspace
46+
* @return SHIM_SUCCESS on success, SHIM_FAILURE on failure.
4547
*/
46-
NODISCARD int64_t handle_vm_kvm_signal_msi(struct kvm_msi *const pmut_ioctl_args) NOEXCEPT;
48+
NODISCARD int64_t handle_vm_kvm_signal_msi(
49+
struct shim_vm_t *const pmut_vm, struct kvm_msi *const pmut_ioctl_args) NOEXCEPT;
4750

4851
#ifdef __cplusplus
4952
}

shim/include/kvm_msi.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,18 @@
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
{
3539
#endif
3640

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

3945
/**
4046
* @struct kvm_msi
@@ -44,8 +50,17 @@ extern "C"
4450
*/
4551
struct kvm_msi
4652
{
47-
/** @brief replace me with contents from KVM API */
48-
int32_t dummy;
53+
/** @brief For PCI, this is a BFD identifier in the lower 16 bits. */
54+
uint32_t address_lo;
55+
/** @brief address_hi bits 31-8 provide bits 31-8 of the destination id. Bits 7-0 of
56+
address_hi must be zero. */
57+
uint32_t address_hi;
58+
/** @brief a MSI message*/
59+
uint32_t data;
60+
/** @brief A Flag to indicate valid or invalid data */
61+
uint32_t flags;
62+
/** @brief TODO */
63+
uint8_t pad[PAD_SIZE_MSI];
4964
};
5065

5166
#pragma pack(pop)

shim/include/kvm_msi.hpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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_MSI_HPP
26+
#define KVM_MSI_HPP
27+
28+
#include <bsl/array.hpp>
29+
#include <bsl/convert.hpp>
30+
#include <bsl/safe_integral.hpp>
31+
32+
#pragma pack(push, 1)
33+
34+
namespace shim
35+
{
36+
/// @brief defines the size of the padding field
37+
constexpr auto PAD_SIZE_MSI{16_umx};
38+
/// @struct kvm_msi
39+
///
40+
/// <!-- description -->
41+
/// @brief see /include/uapi/linux/kvm.h in Linux for more details.
42+
///
43+
struct kvm_msi final
44+
{
45+
/** @brief For PCI, this is a BFD identifier in the lower 16 bits. */
46+
bsl::uint32 address_lo;
47+
/** @brief address_hi bits 31-8 provide bits 31-8 of the destination id. Bits 7-0 of
48+
address_hi must be zero. */
49+
bsl::uint32 address_hi;
50+
/** @brief a MSI message*/
51+
bsl::uint32 data;
52+
/** @brief A Flag to indicate valid or invalid data */
53+
bsl::uint32 flags;
54+
/** @brief TODO */
55+
bsl::array<bsl::uint8, PAD_SIZE_MSI.get()> pad;
56+
};
57+
}
58+
59+
#pragma pack(pop)
60+
61+
#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_signal_msi HEADERS)
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 signalmsi{mut_vcpu.send(shim::KVM_SIGNAL_MSI)};
52+
integration::verify(signalmsi.is_pos());
53+
integration::verify(signalmsi >= 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
@@ -32,6 +32,7 @@
3232
#include <kvm_cpuid_entry2.hpp>
3333
#include <kvm_fpu.hpp>
3434
#include <kvm_mp_state.hpp>
35+
#include <kvm_msi.hpp>
3536
#include <kvm_msr_entry.hpp>
3637
#include <kvm_msr_list.hpp>
3738
#include <kvm_msrs.hpp>
@@ -232,8 +233,9 @@ namespace shim
232233
// constexpr bsl::safe_umx KVM_SET_ONE_REG{static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0xac, struct kvm_one_reg))};
233234
/// @brief defines KVM's KVM_KVMCLOCK_CTRL IOCTL
234235
constexpr bsl::safe_umx KVM_KVMCLOCK_CTRL{static_cast<bsl::uintmx>(_IO(SHIMIO.get(), 0xad))};
235-
// /// @brief defines KVM's KVM_SIGNAL_MSI IOCTL
236-
// constexpr bsl::safe_umx KVM_SIGNAL_MSI{static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0xa5, struct kvm_msi))};
236+
/// @brief defines KVM's KVM_SIGNAL_MSI IOCTL
237+
constexpr bsl::safe_umx KVM_SIGNAL_MSI{
238+
static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0xa5, struct kvm_msi))};
237239
// /// @brief defines KVM's KVM_CREATE_PIT2 IOCTL
238240
// constexpr bsl::safe_umx KVM_CREATE_PIT2{static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0x77, struct kvm_pit_config))};
239241
// /// @brief defines KVM's KVM_GET_PIT2 IOCTL

shim/linux/src/entry.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include <handle_vm_kvm_create_vcpu.h>
5353
#include <handle_vm_kvm_destroy_vcpu.h>
5454
#include <handle_vm_kvm_set_user_memory_region.h>
55+
#include <handle_vm_kvm_signal_msi.h>
5556
#include <linux/anon_inodes.h>
5657
#include <linux/kernel.h>
5758
#include <linux/miscdevice.h>
@@ -743,10 +744,23 @@ dispatch_vm_kvm_set_user_memory_region(
743744
}
744745

745746
static long
746-
dispatch_vm_kvm_signal_msi(struct kvm_msi *const ioctl_args)
747+
dispatch_vm_kvm_signal_msi(
748+
struct shim_vm_t *const pmut_vm, struct kvm_msi *const pmut_ioctl_args)
747749
{
748-
(void)ioctl_args;
749-
return -EINVAL;
750+
struct kvm_msi mut_args;
751+
uint64_t const size = sizeof(mut_args);
752+
753+
if (platform_copy_from_user(&mut_args, pmut_ioctl_args, size)) {
754+
bferror("platform_copy_from_user failed");
755+
return -EINVAL;
756+
}
757+
758+
if (handle_vm_kvm_signal_msi(pmut_vm, &mut_args)) {
759+
bferror("handle_vm_kvm_signal_msi failed");
760+
return -EINVAL;
761+
}
762+
763+
return 0;
750764
}
751765

752766
static long
@@ -920,7 +934,8 @@ dev_unlocked_ioctl_vm(
920934
}
921935

922936
case KVM_SIGNAL_MSI: {
923-
return dispatch_vm_kvm_signal_msi((struct kvm_msi *)ioctl_args);
937+
return dispatch_vm_kvm_signal_msi(
938+
(struct shim_vm_t *)pmut_mut_vm, (struct kvm_msi *)ioctl_args);
924939
}
925940

926941
case KVM_UNREGISTER_COALESCED_MMIO: {

shim/src/handle_vm_kvm_signal_msi.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,33 @@
2323
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2424
* SOFTWARE.
2525
*/
26-
26+
#include <debug.h>
27+
#include <detect_hypervisor.h>
2728
#include <kvm_msi.h>
2829
#include <mv_types.h>
30+
#include <platform.h>
31+
#include <shim_vm_t.h>
2932

3033
/**
3134
* <!-- description -->
3235
* @brief Handles the execution of kvm_signal_msi.
3336
*
3437
* <!-- inputs/outputs -->
38+
* @param pmut_vm the argumento hold vm details of type shim_vm_t
3539
* @param pmut_ioctl_args the arguments provided by userspace
3640
* @return SHIM_SUCCESS on success, SHIM_FAILURE on failure.
3741
*/
3842
NODISCARD int64_t
39-
handle_vm_kvm_signal_msi(struct kvm_msi *const pmut_ioctl_args) NOEXCEPT
43+
handle_vm_kvm_signal_msi(
44+
struct shim_vm_t *const pmut_vm, struct kvm_msi *const pmut_ioctl_args) NOEXCEPT
4045
{
41-
(void)pmut_ioctl_args;
46+
platform_expects(NULL != pmut_vm);
47+
platform_expects(NULL != pmut_ioctl_args);
48+
49+
if (detect_hypervisor()) {
50+
bferror("The shim is not running in a VM. Did you forget to start MicroV?");
51+
return SHIM_FAILURE;
52+
}
53+
//TODO: Cally the hypercall here after its implementation
4254
return SHIM_SUCCESS;
4355
}

shim/tests/src/test_handle_vm_kvm_signal_msi.cpp

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

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

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

3031
#include <bsl/ut.hpp>
3132

@@ -43,17 +44,34 @@ 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_msi 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_signal_msi(&mut_args));
54+
bsl::ut_check(SHIM_SUCCESS == handle_vm_kvm_signal_msi(&mut_vm, &mut_args));
5255
};
5356
};
5457
};
5558
};
5659

60+
bsl::ut_scenario{"hypervisor not detected"} = []() noexcept {
61+
bsl::ut_given{} = [&]() noexcept {
62+
kvm_msi 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_signal_msi(&mut_vm, &mut_args));
68+
};
69+
bsl::ut_cleanup{} = [&]() noexcept {
70+
g_mut_hypervisor_detected = true;
71+
};
72+
};
73+
};
74+
};
5775
return bsl::ut_success();
5876
}
5977
}

0 commit comments

Comments
 (0)