Skip to content

Commit f544fe0

Browse files
author
Brendan Kerrigan
committed
Add portio emulation handling for the in{b,w,l} instructions
Signed-off-by: Brendan Kerrigan <[email protected]>
1 parent db7587d commit f544fe0

File tree

2 files changed

+58
-11
lines changed

2 files changed

+58
-11
lines changed

vmm/src/x64/amd/dispatch_vmexit_io.hpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,31 @@
4444

4545
namespace microv
4646
{
47+
/// <!-- description -->
48+
/// @brief Handle emulation of port IO read/write accesses
49+
///
50+
/// <!-- input/outputs -->
51+
/// @param mut_sys the bf_syscall_t to use
52+
/// @param pmut_mut_exit_io mv_exit_io_t pointer to use
53+
/// @param data_mask bitmask to apply to either the read or
54+
/// write
55+
/// @return void
56+
///
57+
[[nodiscard]] constexpr auto
58+
handle_io(
59+
syscall::bf_syscall_t &mut_sys,
60+
hypercall::mv_exit_io_t *pmut_mut_exit_io,
61+
bsl::safe_u64 const &data_mask) noexcept
62+
{
63+
auto const rax{mut_sys.bf_tls_rax()};
64+
if (hypercall::MV_EXIT_IO_OUT == pmut_mut_exit_io->type) {
65+
pmut_mut_exit_io->data = (data_mask & rax).get();
66+
}
67+
else {
68+
mut_sys.bf_tls_set_rax((data_mask & pmut_mut_exit_io->data));
69+
}
70+
}
71+
4772
/// <!-- description -->
4873
/// @brief Dispatches IO VMExits.
4974
///
@@ -128,14 +153,13 @@ namespace microv
128153
mut_exit_io->type = hypercall::MV_EXIT_IO_OUT.get();
129154
}
130155
else {
131-
bsl::error() << "MV_EXIT_IO_IN not implemented\n" << bsl::here();
132-
return bsl::errc_failure;
156+
mut_exit_io->type = hypercall::MV_EXIT_IO_IN.get();
133157
}
134158

135159
if (((exitinfo1 & sz32_mask) >> sz32_shft).is_pos()) {
136160
constexpr auto data_mask{0x00000000FFFFFFFF_u64};
137161
mut_exit_io->size = hypercall::mv_bit_size_t::mv_bit_size_t_32;
138-
mut_exit_io->data = (data_mask & rax).get();
162+
handle_io(mut_sys, mut_exit_io.get(), data_mask);
139163
}
140164
else {
141165
bsl::touch();
@@ -144,7 +168,7 @@ namespace microv
144168
if (((exitinfo1 & sz16_mask) >> sz16_shft).is_pos()) {
145169
constexpr auto data_mask{0x000000000000FFFF_u64};
146170
mut_exit_io->size = hypercall::mv_bit_size_t::mv_bit_size_t_16;
147-
mut_exit_io->data = (data_mask & rax).get();
171+
handle_io(mut_sys, mut_exit_io.get(), data_mask);
148172
}
149173
else {
150174
bsl::touch();
@@ -153,7 +177,7 @@ namespace microv
153177
if (((exitinfo1 & sz08_mask) >> sz08_shft).is_pos()) {
154178
constexpr auto data_mask{0x00000000000000FF_u64};
155179
mut_exit_io->size = hypercall::mv_bit_size_t::mv_bit_size_t_8;
156-
mut_exit_io->data = (data_mask & rax).get();
180+
handle_io(mut_sys, mut_exit_io.get(), data_mask);
157181
}
158182
else {
159183
bsl::touch();

vmm/src/x64/intel/dispatch_vmexit_io.hpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,31 @@
4343

4444
namespace microv
4545
{
46+
/// <!-- description -->
47+
/// @brief Handle emulation of port IO read/write accesses
48+
///
49+
/// <!-- input/outputs -->
50+
/// @param mut_sys the bf_syscall_t to use
51+
/// @param pmut_mut_exit_io mv_exit_io_t pointer to use
52+
/// @param data_mask bitmask to apply to either the read or
53+
/// write
54+
/// @return void
55+
///
56+
[[nodiscard]] constexpr auto
57+
handle_io(
58+
syscall::bf_syscall_t &mut_sys,
59+
hypercall::mv_exit_io_t *pmut_mut_exit_io,
60+
bsl::safe_u64 const &data_mask) noexcept
61+
{
62+
auto const rax{mut_sys.bf_tls_rax()};
63+
if (hypercall::MV_EXIT_IO_OUT == pmut_mut_exit_io->type) {
64+
pmut_mut_exit_io->data = (data_mask & rax).get();
65+
}
66+
else {
67+
mut_sys.bf_tls_set_rax((data_mask & pmut_mut_exit_io->data));
68+
}
69+
}
70+
4671
/// <!-- description -->
4772
/// @brief Dispatches IO VMExits.
4873
///
@@ -91,7 +116,6 @@ namespace microv
91116
constexpr auto exitqual_idx{syscall::bf_reg_t::bf_reg_t_exit_qualification};
92117
auto const exitqual{mut_sys.bf_vs_op_read(vsid, exitqual_idx)};
93118

94-
auto const rax{mut_sys.bf_tls_rax()};
95119
auto const rcx{mut_sys.bf_tls_rcx()};
96120
auto const rdx{mut_sys.bf_tls_rdx()};
97121

@@ -131,8 +155,7 @@ namespace microv
131155
mut_exit_io->type = hypercall::MV_EXIT_IO_OUT.get();
132156
}
133157
else {
134-
bsl::error() << "MV_EXIT_IO_IN not implemented\n" << bsl::here();
135-
return bsl::errc_failure;
158+
mut_exit_io->type = hypercall::MV_EXIT_IO_IN.get();
136159
}
137160

138161
constexpr auto bytes1{0_u64};
@@ -142,7 +165,7 @@ namespace microv
142165
if (bytes4 == ((exitqual & size_mask) >> size_shft)) {
143166
constexpr auto data_mask{0x00000000FFFFFFFF_u64};
144167
mut_exit_io->size = hypercall::mv_bit_size_t::mv_bit_size_t_32;
145-
mut_exit_io->data = (data_mask & rax).get();
168+
handle_io(mut_sys, mut_exit_io.get(), data_mask);
146169
}
147170
else {
148171
bsl::touch();
@@ -151,7 +174,7 @@ namespace microv
151174
if (bytes2 == ((exitqual & size_mask) >> size_shft)) {
152175
constexpr auto data_mask{0x000000000000FFFF_u64};
153176
mut_exit_io->size = hypercall::mv_bit_size_t::mv_bit_size_t_16;
154-
mut_exit_io->data = (data_mask & rax).get();
177+
handle_io(mut_sys, mut_exit_io.get(), data_mask);
155178
}
156179
else {
157180
bsl::touch();
@@ -160,7 +183,7 @@ namespace microv
160183
if (bytes1 == ((exitqual & size_mask) >> size_shft)) {
161184
constexpr auto data_mask{0x00000000000000FF_u64};
162185
mut_exit_io->size = hypercall::mv_bit_size_t::mv_bit_size_t_8;
163-
mut_exit_io->data = (data_mask & rax).get();
186+
handle_io(mut_sys, mut_exit_io.get(), data_mask);
164187
}
165188
else {
166189
bsl::touch();

0 commit comments

Comments
 (0)