Message ID | 20200206115731.13552-5-n54@gmx.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Implements the NetBSD Virtual Machine Monitor accelerator | expand |
Tested-by: Jared McNeill <jmcneill@invisible.ca> On Thu, 6 Feb 2020, Kamil Rytarowski wrote: > From: Maxime Villard <max@m00nbsd.net> > > Implements the NVMM accelerator cpu enlightenments to actually use the nvmm-all > accelerator on NetBSD platforms. > > Signed-off-by: Maxime Villard <max@m00nbsd.net> > Signed-off-by: Kamil Rytarowski <n54@gmx.com> > Reviewed-by: Sergio Lopez <slp@redhat.com> > Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> > --- > cpus.c | 58 +++++++++++++++++++++++++++++++++++++++ > include/sysemu/hw_accel.h | 14 ++++++++++ > target/i386/helper.c | 2 +- > 3 files changed, 73 insertions(+), 1 deletion(-) > > diff --git a/cpus.c b/cpus.c > index b4f8b84b61..f833da4a60 100644 > --- a/cpus.c > +++ b/cpus.c > @@ -42,6 +42,7 @@ > #include "sysemu/hax.h" > #include "sysemu/hvf.h" > #include "sysemu/whpx.h" > +#include "sysemu/nvmm.h" > #include "exec/exec-all.h" > > #include "qemu/thread.h" > @@ -1670,6 +1671,48 @@ static void *qemu_whpx_cpu_thread_fn(void *arg) > return NULL; > } > > +static void *qemu_nvmm_cpu_thread_fn(void *arg) > +{ > + CPUState *cpu = arg; > + int r; > + > + assert(nvmm_enabled()); > + > + rcu_register_thread(); > + > + qemu_mutex_lock_iothread(); > + qemu_thread_get_self(cpu->thread); > + cpu->thread_id = qemu_get_thread_id(); > + current_cpu = cpu; > + > + r = nvmm_init_vcpu(cpu); > + if (r < 0) { > + fprintf(stderr, "nvmm_init_vcpu failed: %s\n", strerror(-r)); > + exit(1); > + } > + > + /* signal CPU creation */ > + cpu->created = true; > + qemu_cond_signal(&qemu_cpu_cond); > + > + do { > + if (cpu_can_run(cpu)) { > + r = nvmm_vcpu_exec(cpu); > + if (r == EXCP_DEBUG) { > + cpu_handle_guest_debug(cpu); > + } > + } > + qemu_wait_io_event(cpu); > + } while (!cpu->unplug || cpu_can_run(cpu)); > + > + nvmm_destroy_vcpu(cpu); > + cpu->created = false; > + qemu_cond_signal(&qemu_cpu_cond); > + qemu_mutex_unlock_iothread(); > + rcu_unregister_thread(); > + return NULL; > +} > + > #ifdef _WIN32 > static void CALLBACK dummy_apc_func(ULONG_PTR unused) > { > @@ -2038,6 +2081,19 @@ static void qemu_whpx_start_vcpu(CPUState *cpu) > #endif > } > > +static void qemu_nvmm_start_vcpu(CPUState *cpu) > +{ > + char thread_name[VCPU_THREAD_NAME_SIZE]; > + > + cpu->thread = g_malloc0(sizeof(QemuThread)); > + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); > + qemu_cond_init(cpu->halt_cond); > + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/NVMM", > + cpu->cpu_index); > + qemu_thread_create(cpu->thread, thread_name, qemu_nvmm_cpu_thread_fn, > + cpu, QEMU_THREAD_JOINABLE); > +} > + > static void qemu_dummy_start_vcpu(CPUState *cpu) > { > char thread_name[VCPU_THREAD_NAME_SIZE]; > @@ -2078,6 +2134,8 @@ void qemu_init_vcpu(CPUState *cpu) > qemu_tcg_init_vcpu(cpu); > } else if (whpx_enabled()) { > qemu_whpx_start_vcpu(cpu); > + } else if (nvmm_enabled()) { > + qemu_nvmm_start_vcpu(cpu); > } else { > qemu_dummy_start_vcpu(cpu); > } > diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h > index 0ec2372477..dbfa7a02f9 100644 > --- a/include/sysemu/hw_accel.h > +++ b/include/sysemu/hw_accel.h > @@ -15,6 +15,7 @@ > #include "sysemu/hax.h" > #include "sysemu/kvm.h" > #include "sysemu/whpx.h" > +#include "sysemu/nvmm.h" > > static inline void cpu_synchronize_state(CPUState *cpu) > { > @@ -27,6 +28,9 @@ static inline void cpu_synchronize_state(CPUState *cpu) > if (whpx_enabled()) { > whpx_cpu_synchronize_state(cpu); > } > + if (nvmm_enabled()) { > + nvmm_cpu_synchronize_state(cpu); > + } > } > > static inline void cpu_synchronize_post_reset(CPUState *cpu) > @@ -40,6 +44,10 @@ static inline void cpu_synchronize_post_reset(CPUState *cpu) > if (whpx_enabled()) { > whpx_cpu_synchronize_post_reset(cpu); > } > + if (nvmm_enabled()) { > + nvmm_cpu_synchronize_post_reset(cpu); > + } > + > } > > static inline void cpu_synchronize_post_init(CPUState *cpu) > @@ -53,6 +61,9 @@ static inline void cpu_synchronize_post_init(CPUState *cpu) > if (whpx_enabled()) { > whpx_cpu_synchronize_post_init(cpu); > } > + if (nvmm_enabled()) { > + nvmm_cpu_synchronize_post_init(cpu); > + } > } > > static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) > @@ -66,6 +77,9 @@ static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) > if (whpx_enabled()) { > whpx_cpu_synchronize_pre_loadvm(cpu); > } > + if (nvmm_enabled()) { > + nvmm_cpu_synchronize_pre_loadvm(cpu); > + } > } > > #endif /* QEMU_HW_ACCEL_H */ > diff --git a/target/i386/helper.c b/target/i386/helper.c > index c3a6e4fabe..2e79d61329 100644 > --- a/target/i386/helper.c > +++ b/target/i386/helper.c > @@ -981,7 +981,7 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) > X86CPU *cpu = env_archcpu(env); > CPUState *cs = env_cpu(env); > > - if (kvm_enabled() || whpx_enabled()) { > + if (kvm_enabled() || whpx_enabled() || nvmm_enabled()) { > env->tpr_access_type = access; > > cpu_interrupt(cs, CPU_INTERRUPT_TPR); > -- > 2.25.0 > >
diff --git a/cpus.c b/cpus.c index b4f8b84b61..f833da4a60 100644 --- a/cpus.c +++ b/cpus.c @@ -42,6 +42,7 @@ #include "sysemu/hax.h" #include "sysemu/hvf.h" #include "sysemu/whpx.h" +#include "sysemu/nvmm.h" #include "exec/exec-all.h" #include "qemu/thread.h" @@ -1670,6 +1671,48 @@ static void *qemu_whpx_cpu_thread_fn(void *arg) return NULL; } +static void *qemu_nvmm_cpu_thread_fn(void *arg) +{ + CPUState *cpu = arg; + int r; + + assert(nvmm_enabled()); + + rcu_register_thread(); + + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + cpu->thread_id = qemu_get_thread_id(); + current_cpu = cpu; + + r = nvmm_init_vcpu(cpu); + if (r < 0) { + fprintf(stderr, "nvmm_init_vcpu failed: %s\n", strerror(-r)); + exit(1); + } + + /* signal CPU creation */ + cpu->created = true; + qemu_cond_signal(&qemu_cpu_cond); + + do { + if (cpu_can_run(cpu)) { + r = nvmm_vcpu_exec(cpu); + if (r == EXCP_DEBUG) { + cpu_handle_guest_debug(cpu); + } + } + qemu_wait_io_event(cpu); + } while (!cpu->unplug || cpu_can_run(cpu)); + + nvmm_destroy_vcpu(cpu); + cpu->created = false; + qemu_cond_signal(&qemu_cpu_cond); + qemu_mutex_unlock_iothread(); + rcu_unregister_thread(); + return NULL; +} + #ifdef _WIN32 static void CALLBACK dummy_apc_func(ULONG_PTR unused) { @@ -2038,6 +2081,19 @@ static void qemu_whpx_start_vcpu(CPUState *cpu) #endif } +static void qemu_nvmm_start_vcpu(CPUState *cpu) +{ + char thread_name[VCPU_THREAD_NAME_SIZE]; + + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/NVMM", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, qemu_nvmm_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); +} + static void qemu_dummy_start_vcpu(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; @@ -2078,6 +2134,8 @@ void qemu_init_vcpu(CPUState *cpu) qemu_tcg_init_vcpu(cpu); } else if (whpx_enabled()) { qemu_whpx_start_vcpu(cpu); + } else if (nvmm_enabled()) { + qemu_nvmm_start_vcpu(cpu); } else { qemu_dummy_start_vcpu(cpu); } diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h index 0ec2372477..dbfa7a02f9 100644 --- a/include/sysemu/hw_accel.h +++ b/include/sysemu/hw_accel.h @@ -15,6 +15,7 @@ #include "sysemu/hax.h" #include "sysemu/kvm.h" #include "sysemu/whpx.h" +#include "sysemu/nvmm.h" static inline void cpu_synchronize_state(CPUState *cpu) { @@ -27,6 +28,9 @@ static inline void cpu_synchronize_state(CPUState *cpu) if (whpx_enabled()) { whpx_cpu_synchronize_state(cpu); } + if (nvmm_enabled()) { + nvmm_cpu_synchronize_state(cpu); + } } static inline void cpu_synchronize_post_reset(CPUState *cpu) @@ -40,6 +44,10 @@ static inline void cpu_synchronize_post_reset(CPUState *cpu) if (whpx_enabled()) { whpx_cpu_synchronize_post_reset(cpu); } + if (nvmm_enabled()) { + nvmm_cpu_synchronize_post_reset(cpu); + } + } static inline void cpu_synchronize_post_init(CPUState *cpu) @@ -53,6 +61,9 @@ static inline void cpu_synchronize_post_init(CPUState *cpu) if (whpx_enabled()) { whpx_cpu_synchronize_post_init(cpu); } + if (nvmm_enabled()) { + nvmm_cpu_synchronize_post_init(cpu); + } } static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) @@ -66,6 +77,9 @@ static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) if (whpx_enabled()) { whpx_cpu_synchronize_pre_loadvm(cpu); } + if (nvmm_enabled()) { + nvmm_cpu_synchronize_pre_loadvm(cpu); + } } #endif /* QEMU_HW_ACCEL_H */ diff --git a/target/i386/helper.c b/target/i386/helper.c index c3a6e4fabe..2e79d61329 100644 --- a/target/i386/helper.c +++ b/target/i386/helper.c @@ -981,7 +981,7 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) X86CPU *cpu = env_archcpu(env); CPUState *cs = env_cpu(env); - if (kvm_enabled() || whpx_enabled()) { + if (kvm_enabled() || whpx_enabled() || nvmm_enabled()) { env->tpr_access_type = access; cpu_interrupt(cs, CPU_INTERRUPT_TPR);