From 315fb3aca5b9eb6e7c79c103362dc8340590721d Mon Sep 17 00:00:00 2001 From: SeokYeon Hwang Date: Thu, 3 Nov 2016 20:09:08 +0900 Subject: [PATCH] yagl: sync with CPUState on HAX CPUState should contain some special register and state not only KVM but also HAX. Especially, "HF_LMA_MASK" on hflags is very important flag for walking page table on 64bit environments. Change-Id: I432804d684c009de0a7c79d560f5a869918bb1a5 Signed-off-by: SeokYeon Hwang --- hw/yagl/yagl_process.c | 21 +++++++++++++++------ hw/yagl/yagl_process.h | 3 ++- hw/yagl/yagl_thread.c | 18 +++++++++++++----- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/hw/yagl/yagl_process.c b/hw/yagl/yagl_process.c index eb74031..16bff17 100644 --- a/hw/yagl/yagl_process.c +++ b/hw/yagl/yagl_process.c @@ -34,6 +34,7 @@ #include "yagl_stats.h" #include "yagl_object_map.h" #include "sysemu/kvm.h" +#include "sysemu/hax.h" struct yagl_process_state *yagl_process_state_create(struct yagl_server_state *ss, @@ -47,13 +48,21 @@ struct yagl_process_state ps->object_map = yagl_object_map_create(); QLIST_INIT(&ps->threads); -#ifdef CONFIG_KVM - if (kvm_enabled()) { - cpu_synchronize_state(current_cpu); +#if defined (CONFIG_KVM) || defined (CONFIG_HAX) + if (kvm_enabled() || hax_enabled()) { + if (kvm_enabled()) { + cpu_synchronize_state(current_cpu); + } else { +#ifdef CONFIG_HAX + hax_cpu_synchronize_state(current_cpu); +#endif + } + CPUX86State *env = current_cpu->env_ptr; memcpy(&ps->cr[0], - &((CPUX86State *)current_cpu->env_ptr)->cr[0], - sizeof(ps->cr)); - ps->hflags = ((CPUX86State *)current_cpu->env_ptr)->hflags; + &((CPUX86State *)current_cpu->env_ptr)->cr[0], + sizeof(ps->cr)); + ps->hflags = env->hflags; + ps->efer = env->efer; } #endif diff --git a/hw/yagl/yagl_process.h b/hw/yagl/yagl_process.h index 4cbae52..0768f07 100644 --- a/hw/yagl/yagl_process.h +++ b/hw/yagl/yagl_process.h @@ -55,9 +55,10 @@ struct yagl_process_state QLIST_HEAD(, yagl_thread_state) threads; -#ifdef CONFIG_KVM +#if defined (CONFIG_KVM) || defined (CONFIG_HAX) target_ulong cr[5]; uint32_t hflags; + uint64_t efer; #endif }; diff --git a/hw/yagl/yagl_thread.c b/hw/yagl/yagl_thread.c index 82a8d80..9481f48 100644 --- a/hw/yagl/yagl_thread.c +++ b/hw/yagl/yagl_thread.c @@ -53,14 +53,22 @@ struct yagl_thread_work_item uint32_t out_arrays_size; }; -#ifdef CONFIG_KVM +#if defined (CONFIG_KVM) || defined (CONFIG_HAX) static __inline void yagl_cpu_synchronize_state(struct yagl_process_state *ps) { - if (kvm_enabled()) { + if (kvm_enabled() || hax_enabled()) { + CPUX86State *env = current_cpu->env_ptr; memcpy(&((CPUX86State *)current_cpu->env_ptr)->cr[0], - &ps->cr[0], - sizeof(ps->cr)); - ((CPUX86State *)current_cpu->env_ptr)->hflags = ps->hflags; + &ps->cr[0], + sizeof(ps->cr)); + env->hflags = ps->hflags; + + // FIXME: Somtimes "hflags" is not synced propery on HAX. + // It can be bug on synchronizing CPU state + env->efer = ps->efer; + if (env->efer & MSR_EFER_LMA) { + env->hflags |= HF_LMA_MASK; + } } } #else -- 2.7.4