When the vcpu is created, call mmap to configure access to the register page.
In case the call to mmap fails, we log an error and continue with the
previous logic (using hypercalls).

Update CPUArchState to store a pointer to the mmapped hv_vp_register_page.

Signed-off-by: Doru Blânzeanu <[email protected]>
---
 target/i386/cpu.h           |  5 +++++
 target/i386/mshv/mshv-cpu.c | 22 ++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 16de67e546..fd4c3712b1 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2019,6 +2019,11 @@ typedef struct CPUArchState {
     uint64_t msr_bndcfgs;
     uint64_t efer;
 
+#ifdef CONFIG_MSHV
+    /* Shared register page */
+    struct hv_vp_register_page *regs_page;
+#endif
+
     /* Beginning of state preserved by INIT (dummy marker).  */
     struct {} start_init_save;
 
diff --git a/target/i386/mshv/mshv-cpu.c b/target/i386/mshv/mshv-cpu.c
index 9defd05db6..3a3c269c33 100644
--- a/target/i386/mshv/mshv-cpu.c
+++ b/target/i386/mshv/mshv-cpu.c
@@ -1587,6 +1587,7 @@ void mshv_arch_init_vcpu(CPUState *cpu)
     CPUX86State *env = &x86_cpu->env;
     AccelCPUState *state = cpu->accel;
     size_t page = HV_HYP_PAGE_SIZE;
+    void *regs_page;
     void *mem = qemu_memalign(page, 2 * page);
 
     /* sanity check, to make sure we don't overflow the page */
@@ -1595,6 +1596,22 @@ void mshv_arch_init_vcpu(CPUState *cpu)
                       + sizeof(hv_input_get_vp_registers)
                       > HV_HYP_PAGE_SIZE));
 
+
+    /* mmap the registers page */
+    regs_page = mmap(NULL, page, PROT_READ | PROT_WRITE,
+                    MAP_SHARED, mshv_vcpufd(cpu),
+                    MSHV_VP_MMAP_OFFSET_REGISTERS * page);
+    if (regs_page == MAP_FAILED) {
+        /*
+         * Error is not fatal, but we won't be able to use the
+         * fast path for register access
+         */
+        error_report("register page mmap failed: %s", strerror(errno));
+        env->regs_page = NULL;
+    } else {
+        env->regs_page = (struct hv_vp_register_page *) regs_page;
+    }
+
     state->hvcall_args.base = mem;
     state->hvcall_args.input_page = mem;
     state->hvcall_args.output_page = (uint8_t *)mem + page;
@@ -1608,6 +1625,11 @@ void mshv_arch_destroy_vcpu(CPUState *cpu)
     CPUX86State *env = &x86_cpu->env;
     AccelCPUState *state = cpu->accel;
 
+    /* Unmap the register page */
+    if (env->regs_page) {
+        munmap(env->regs_page, HV_HYP_PAGE_SIZE);
+        env->regs_page = NULL;
+    }
     g_free(state->hvcall_args.base);
     state->hvcall_args = (MshvHvCallArgs){0};
     g_clear_pointer(&env->emu_mmio_buf, g_free);
-- 
2.53.0


Reply via email to