Skip to content

Commit 15eac0c

Browse files
committed
KVM_SET_GSI_ROUTING: Add scaffolding and initial integration tests
1 parent 747bd75 commit 15eac0c

File tree

9 files changed

+287
-14
lines changed

9 files changed

+287
-14
lines changed

shim/include/handle_vm_kvm_set_gsi_routing.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ extern "C"
4040
* @brief Handles the execution of kvm_set_gsi_routing.
4141
*
4242
* <!-- inputs/outputs -->
43+
* @param pmut_vm the argumento hold vm details of type shim_vm_t
4344
* @param pmut_ioctl_args the arguments provided by userspace
4445
* @return SHIM_SUCCESS on success, SHIM_FAILURE on failure.
4546
*/
46-
NODISCARD int64_t
47-
handle_vm_kvm_set_gsi_routing(struct kvm_irq_routing *const pmut_ioctl_args) NOEXCEPT;
47+
NODISCARD int64_t handle_vm_kvm_set_gsi_routing(
48+
struct shim_vm_t *const pmut_vm, struct kvm_irq_routing *const pmut_ioctl_args) NOEXCEPT;
4849

4950
#ifdef __cplusplus
5051
}

shim/include/kvm_irq_routing.h

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,115 @@
2727
#ifndef KVM_IRQ_ROUTING_H
2828
#define KVM_IRQ_ROUTING_H
2929

30+
#define KVM_ENTRY ((uint32_t)0)
31+
#define KVM_PAD ((uint32_t)8)
32+
3033
#include <stdint.h>
3134

35+
#define KVM_IRQ_ROUTING_IRQCHIP 1
36+
#define KVM_IRQ_ROUTING_MSI 2
37+
#define KVM_IRQ_ROUTING_S390_ADAPTER 3
38+
39+
#ifdef __clang__
40+
#pragma clang diagnostic ignored "-Wold-style-cast"
41+
#pragma clang diagnostic ignored "-Wzero-length-array"
42+
#endif
43+
3244
#ifdef __cplusplus
3345
extern "C"
3446
{
3547
#endif
3648

3749
#pragma pack(push, 1)
3850

51+
/**
52+
* @struct kvm_irq_routing_irqchip
53+
*
54+
* <!-- description -->
55+
* @brief see /include/uapi/linux/kvm.h in Linux for more details.
56+
*/
57+
//NOLINTNEXTLINE
58+
struct kvm_irq_routing_irqchip
59+
{
60+
/** @brief TODO */
61+
uint32_t irqchip;
62+
/** @brief TODO */
63+
uint32_t pin;
64+
};
65+
66+
/**
67+
* @struct kvm_irq_routing_msi
68+
*
69+
* <!-- description -->
70+
* @brief see /include/uapi/linux/kvm.h in Linux for more details.
71+
*/
72+
//NOLINTNEXTLINE
73+
struct kvm_irq_routing_msi
74+
{
75+
/** @brief TODO */
76+
uint32_t address_lo;
77+
/** @brief TODO */
78+
uint32_t address_hi;
79+
/** @brief TODO */
80+
uint32_t data;
81+
/** @brief TODO */
82+
uint32_t pad;
83+
};
84+
85+
/**
86+
* @struct kvm_irq_routing_s390_adapter
87+
*
88+
* <!-- description -->
89+
* @brief see /include/uapi/linux/kvm.h in Linux for more details.
90+
*/
91+
//NOLINTNEXTLINE
92+
struct kvm_irq_routing_s390_adapter
93+
{
94+
/** @brief TODO */
95+
uint64_t ind_addr;
96+
/** @brief TODO */
97+
uint64_t summary_addr;
98+
/** @brief TODO */
99+
uint64_t ind_offset;
100+
/** @brief TODO */
101+
uint32_t summary_offset;
102+
/** @brief TODO */
103+
uint32_t adapter_id;
104+
};
105+
106+
/**
107+
* @struct kvm_irq_routing_entry
108+
*
109+
* <!-- description -->
110+
* @brief see /include/uapi/linux/kvm.h in Linux for more details.
111+
*/
112+
struct kvm_irq_routing_entry //NOLINT
113+
{
114+
/** @brief TODO */
115+
uint32_t gsi;
116+
/** @brief TODO */
117+
uint32_t type;
118+
/** @brief TODO */
119+
uint32_t flags;
120+
/** @brief TODO */
121+
uint32_t pad;
122+
/** @brief TODO */
123+
//NOLINTNEXTLINE
124+
union
125+
{
126+
/** @brief TODO */
127+
struct kvm_irq_routing_irqchip irqchip;
128+
/** @brief TODO */
129+
struct kvm_irq_routing_msi msi;
130+
/** @brief TODO */
131+
struct kvm_irq_routing_s390_adapter adapter;
132+
/** @brief TODO */
133+
uint32_t pad[KVM_PAD];
134+
} /** @brief TODO */ u;
135+
};
136+
/** TODO: REMOVE ABOVE STRUCTURE: The above structures are part of other branches as of now,
137+
* they will be available to include here once respective branches are merged with master. */
138+
39139
/**
40140
* @struct kvm_irq_routing
41141
*
@@ -44,8 +144,12 @@ extern "C"
44144
*/
45145
struct kvm_irq_routing
46146
{
47-
/** @brief replace me with contents from KVM API */
48-
int32_t dummy;
147+
/** @brief TODO */
148+
uint32_t nr;
149+
/** @brief TODO */
150+
uint32_t flags;
151+
/** @brief TODO */
152+
struct kvm_irq_routing_entry entries[KVM_ENTRY];
49153
};
50154

51155
#pragma pack(pop)

shim/include/kvm_irq_routing.hpp

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+
#ifndef KVM_IRQ_ROUTING_HPP
26+
#define KVM_IRQ_ROUTING_HPP
27+
28+
#include <bsl/safe_integral.hpp>
29+
30+
#pragma pack(push, 1)
31+
32+
namespace shim
33+
{
34+
/// @brief defines the size of the padding field
35+
/// @struct kvm_irq_routing
36+
///
37+
/// <!-- description -->
38+
/// @brief see /include/uapi/linux/kvm.h in Linux for more details.
39+
///
40+
41+
struct kvm_irq_routing final
42+
{
43+
44+
/** @brief TODO */
45+
bsl::uint32 nr;
46+
/** @brief TODO */
47+
bsl::uint32 flags;
48+
/** @brief TODO */
49+
// TODO: Below structure to be uncommented when all other branches of IOCTL are merged with master.
50+
//struct kvm_irq_routing_entry entries[KVM_ENTRY];
51+
};
52+
}
53+
54+
#pragma pack(pop)
55+
56+
#endif

shim/integration/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,4 @@ microv_add_shim_integration(kvm_get_irqchip HEADERS)
5555
microv_add_shim_integration(kvm_set_irqchip HEADERS)
5656
microv_add_shim_integration(kvm_get_lapic HEADERS)
5757
microv_add_shim_integration(kvm_set_lapic HEADERS)
58+
microv_add_shim_integration(kvm_irq_routing 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 irqrouting{mut_vcpu.send(shim::KVM_SET_GSI_ROUTING)};
52+
integration::verify(irqrouting.is_pos());
53+
integration::verify(irqrouting >= mut_ret.get());
54+
}
55+
return bsl::exit_success;
56+
}

shim/linux/include/platform_interface/shim_platform_interface.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@
3131
#include <kvm_cpuid2.hpp>
3232
#include <kvm_cpuid_entry2.hpp>
3333
#include <kvm_fpu.hpp>
34+
<<<<<<< HEAD
3435
#include <kvm_irqchip.hpp>
36+
=======
37+
#include <kvm_irq_routing.hpp>
38+
>>>>>>> KVM_SET_GSI_ROUTING: Add scaffolding and initial integration tests
3539
#include <kvm_mp_state.hpp>
3640
#include <kvm_msr_entry.hpp>
3741
#include <kvm_msr_list.hpp>
@@ -215,8 +219,9 @@ namespace shim
215219
/// @brief defines KVM's KVM_GET_SUPPORTED_CPUID IOCTL
216220
constexpr bsl::safe_umx KVM_GET_SUPPORTED_CPUID{static_cast<bsl::uintmx>(_IOWR_LIST(
217221
SHIMIO.get(), 0x05, struct kvm_cpuid2, struct kvm_cpuid_entry2[CPUID2_MAX_ENTRIES.get()]))};
218-
// /// @brief defines KVM's KVM_SET_GSI_ROUTING IOCTL
219-
// constexpr bsl::safe_umx KVM_SET_GSI_ROUTING{static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0x6a, struct kvm_irq_routing))};
222+
/// @brief defines KVM's KVM_SET_GSI_ROUTING IOCTL
223+
constexpr bsl::safe_umx KVM_SET_GSI_ROUTING{
224+
static_cast<bsl::uintmx>(_IOW(SHIMIO.get(), 0x6a, struct kvm_irq_routing))};
220225
/// @brief defines KVM's KVM_GET_TSC_KHZ IOCTL
221226
constexpr bsl::safe_umx KVM_GET_TSC_KHZ{static_cast<bsl::uintmx>(_IO(SHIMIO.get(), 0xa3))};
222227
/// @brief defines KVM's KVM_SET_TSC_KHZ IOCTL

shim/linux/src/entry.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include <handle_vm_kvm_destroy_vcpu.h>
5757
#include <handle_vm_kvm_get_irqchip.h>
5858
#include <handle_vm_kvm_set_irqchip.h>
59+
#include <handle_vm_kvm_set_gsi_routing.h>
5960
#include <handle_vm_kvm_set_user_memory_region.h>
6061
#include <linux/anon_inodes.h>
6162
#include <linux/kernel.h>
@@ -709,10 +710,24 @@ dispatch_vm_kvm_set_device_attr(struct kvm_device_attr *const ioctl_args)
709710
}
710711

711712
static long
712-
dispatch_vm_kvm_set_gsi_routing(struct kvm_irq_routing *const ioctl_args)
713+
dispatch_vm_kvm_set_gsi_routing(
714+
struct shim_vm_t *const pmut_vm,
715+
struct kvm_irq_routing *const pmut_ioctl_args)
713716
{
714-
(void)ioctl_args;
715-
return -EINVAL;
717+
struct kvm_irq_routing mut_args;
718+
uint64_t const size = sizeof(mut_args);
719+
720+
if (platform_copy_from_user(&mut_args, pmut_ioctl_args, size)) {
721+
bferror("platform_copy_from_user failed");
722+
return -EINVAL;
723+
}
724+
725+
if (handle_vm_kvm_set_gsi_routing(pmut_vm, &mut_args)) {
726+
bferror("handle_vm_kvm_set_gsi_routing failed");
727+
return -EINVAL;
728+
}
729+
730+
return 0;
716731
}
717732

718733
static long
@@ -936,7 +951,9 @@ dev_unlocked_ioctl_vm(
936951

937952
case KVM_SET_GSI_ROUTING: {
938953
return dispatch_vm_kvm_set_gsi_routing(
954+
(struct shim_vm_t *)pmut_mut_vm,
939955
(struct kvm_irq_routing *)ioctl_args);
956+
;
940957
}
941958

942959
case KVM_SET_IDENTITY_MAP_ADDR: {

shim/src/handle_vm_kvm_set_gsi_routing.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_routing.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_set_gsi_routing.
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_set_gsi_routing(struct kvm_irq_routing *const pmut_ioctl_args) NOEXCEPT
44+
handle_vm_kvm_set_gsi_routing(
45+
struct shim_vm_t *const pmut_vm, struct kvm_irq_routing *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
}

0 commit comments

Comments
 (0)