#include <sys/ioctl.h>
+#define MAX_REGISTER_COUNT (MAX_CONST(ARRAY_SIZE(STANDARD_REGISTER_NAMES), \
+ MAX_CONST(ARRAY_SIZE(SPECIAL_REGISTER_NAMES), \
+ ARRAY_SIZE(FPU_REGISTER_NAMES))))
+
static enum hv_register_name STANDARD_REGISTER_NAMES[18] = {
HV_X64_REGISTER_RAX,
HV_X64_REGISTER_RBX,
int cpu_fd = mshv_vcpufd(cpu);
int vp_index = cpu->cpu_index;
size_t in_sz, assocs_sz;
- hv_input_set_vp_registers *in;
+ hv_input_set_vp_registers *in = cpu->accel->hvcall_args.input_page;
struct mshv_root_hvcall args = {0};
int ret;
in_sz = sizeof(hv_input_set_vp_registers) + assocs_sz;
/* fill the input struct */
- in = g_malloc0(in_sz);
+ memset(in, 0, sizeof(hv_input_set_vp_registers));
in->vp_index = vp_index;
memcpy(in->elements, assocs, assocs_sz);
/* perform the call */
ret = mshv_hvcall(cpu_fd, &args);
- g_free(in);
if (ret < 0) {
error_report("Failed to set registers");
return -1;
{
int cpu_fd = mshv_vcpufd(cpu);
int vp_index = cpu->cpu_index;
- hv_input_get_vp_registers *in;
- hv_register_value *values;
+ hv_input_get_vp_registers *in = cpu->accel->hvcall_args.input_page;
+ hv_register_value *values = cpu->accel->hvcall_args.output_page;
size_t in_sz, names_sz, values_sz;
int i, ret;
struct mshv_root_hvcall args = {0};
in_sz = sizeof(hv_input_get_vp_registers) + names_sz;
/* fill the input struct */
- in = g_malloc0(in_sz);
+ memset(in, 0, sizeof(hv_input_get_vp_registers));
in->vp_index = vp_index;
for (i = 0; i < n_regs; i++) {
in->names[i] = assocs[i].name;
}
- /* allocate value output buffer */
+ /* determine size of value output buffer */
values_sz = n_regs * sizeof(union hv_register_value);
- values = g_malloc0(values_sz);
/* create the hvcall envelope */
args.code = HVCALL_GET_VP_REGISTERS;
/* perform the call */
ret = mshv_hvcall(cpu_fd, &args);
- g_free(in);
if (ret < 0) {
- g_free(values);
error_report("Failed to retrieve registers");
return -1;
}
/* assert we got all registers */
if (args.reps != n_regs) {
- g_free(values);
error_report("Failed to retrieve registers: expected %zu elements"
", got %u", n_regs, args.reps);
return -1;
for (i = 0; i < n_regs; i++) {
assocs[i].value = values[i];
}
- g_free(values);
return 0;
}
{
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
+ AccelCPUState *state = cpu->accel;
+ size_t page = HV_HYP_PAGE_SIZE;
+ void *mem = qemu_memalign(page, 2 * page);
+
+ /* sanity check, to make sure we don't overflow the page */
+ QEMU_BUILD_BUG_ON((MAX_REGISTER_COUNT
+ * sizeof(hv_register_assoc)
+ + sizeof(hv_input_get_vp_registers)
+ > HV_HYP_PAGE_SIZE));
+
+ state->hvcall_args.base = mem;
+ state->hvcall_args.input_page = mem;
+ state->hvcall_args.output_page = (uint8_t *)mem + page;
env->emu_mmio_buf = g_new(char, 4096);
}
{
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
+ AccelCPUState *state = cpu->accel;
+ g_free(state->hvcall_args.base);
+ state->hvcall_args = (MshvHvCallArgs){0};
g_clear_pointer(&env->emu_mmio_buf, g_free);
}