summaryrefslogtreecommitdiff
path: root/target-i386/hax-all.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-i386/hax-all.c')
-rw-r--r--target-i386/hax-all.c181
1 files changed, 147 insertions, 34 deletions
diff --git a/target-i386/hax-all.c b/target-i386/hax-all.c
index 916fcd47c1..10fec180a3 100644
--- a/target-i386/hax-all.c
+++ b/target-i386/hax-all.c
@@ -26,6 +26,7 @@
#include "strings.h"
#include "hax-i386.h"
+#include "hax-slot.h"
#include "hw/boards.h"
#include "sysemu/accel.h"
#include "exec/address-spaces.h"
@@ -371,7 +372,8 @@ struct hax_vm *hax_vm_create(struct hax_state *hax)
}
hax->vm = vm;
- dprint("End of VM create, id %d\n", vm->id);
+ hax_slot_init_registry();
+
return vm;
error:
@@ -384,6 +386,7 @@ int hax_vm_destroy(struct hax_vm *vm)
{
int i;
+ hax_slot_free_registry();
for (i = 0; i < HAX_MAX_VCPU; i++)
if (vm->vcpus[i])
{
@@ -396,6 +399,41 @@ int hax_vm_destroy(struct hax_vm *vm)
return 0;
}
+static void hax_set_phys_mem(MemoryRegionSection *section)
+{
+ MemoryRegion *mr = section->mr;
+ hwaddr start_pa = section->offset_within_address_space;
+ ram_addr_t size = int128_get64(section->size);
+ unsigned int delta;
+ void *host_ptr;
+ int flags;
+
+ /* We only care about RAM and ROM */
+ if (!memory_region_is_ram(mr)) {
+ return;
+ }
+
+ /* Adjust start_pa and size so that they are page-aligned. (Cf
+ * kvm_set_phys_mem() in kvm-all.c).
+ */
+ delta = TARGET_PAGE_SIZE - (start_pa & ~TARGET_PAGE_MASK);
+ delta &= ~TARGET_PAGE_MASK;
+ if (delta > size) {
+ return;
+ }
+ start_pa += delta;
+ size -= delta;
+ size &= TARGET_PAGE_MASK;
+ if (!size || start_pa & ~TARGET_PAGE_MASK) {
+ return;
+ }
+
+ host_ptr = memory_region_get_ram_ptr(mr) + section->offset_within_region
+ + delta;
+ flags = memory_region_is_rom(mr) ? 1 : 0;
+ hax_slot_register(start_pa, size, (uintptr_t) host_ptr, flags);
+}
+
static void
hax_region_add(MemoryListener *listener, MemoryRegionSection *section)
{
@@ -405,7 +443,7 @@ hax_region_add(MemoryListener *listener, MemoryRegionSection *section)
static void
hax_region_del(MemoryListener *listener, MemoryRegionSection *section)
{
- hax_set_phys_mem(section);
+ // Memory mappings will be removed at VM close.
}
@@ -417,11 +455,17 @@ hax_region_del(MemoryListener *listener, MemoryRegionSection *section)
static void hax_log_sync(MemoryListener *listener, MemoryRegionSection *section)
{
MemoryRegion *mr = section->mr;
+
+ if (!memory_region_is_ram(mr)) {
+ /* Skip MMIO regions */
+ return;
+ }
+
unsigned long c;
unsigned int len = ((int128_get64(section->size) / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) /
HOST_LONG_BITS;
unsigned long bitmap[len];
- int i, j;
+ unsigned int i, j;
for (i = 0; i < len; i++) {
bitmap[i] = 1;
@@ -767,13 +811,6 @@ static int hax_vcpu_hax_exec(CPUArchState *env, int ug_platform)
break;
}
-#if 0
- if (cpu->hax_vcpu_dirty) {
- hax_vcpu_sync_state(env, 1);
- cpu->hax_vcpu_dirty = 0;
- }
-#endif
-
hax_vcpu_interrupt(env);
if (!ug_platform)
{
@@ -863,37 +900,52 @@ static int hax_vcpu_hax_exec(CPUArchState *env, int ug_platform)
return ret;
}
-#if 0
-static void do_hax_cpu_synchronize_state(void *_env)
+static void do_hax_cpu_synchronize_state(void *arg)
{
- CPUArchState *env = _env;
- CPUState *cpu = ENV_GET_CPU(env);
- if (!cpu->hax_vcpu_dirty) {
- hax_vcpu_sync_state(env, 0);
- cpu->hax_vcpu_dirty = 1;
- }
+ CPUState *cpu = arg;
+ CPUArchState *env = cpu->env_ptr;
+
+ hax_arch_get_registers(env);
+ cpu->hax_vcpu_dirty = true;
}
-static void hax_cpu_synchronize_state(CPUState *cpu)
+void hax_cpu_synchronize_state(CPUState *cpu)
{
- if (!cpu->hax_vcpu_dirty) {
- run_on_cpu(cpu, do_hax_cpu_synchronize_state, cpu);
- }
+ /* TODO: Do not sync if cpu->hax_vcpu_dirty is true. (Cf
+ * kvm_cpu_synchronize_state() in kvm-all.c)
+ * This would require that this flag be updated properly and consistently
+ * wherever a vCPU state sync between QEMU and HAX takes place. For now,
+ * just perform the sync regardless of hax_vcpu_dirty.
+ */
+ run_on_cpu(cpu, do_hax_cpu_synchronize_state, cpu);
}
-#endif
-void hax_cpu_synchronize_post_reset(CPUState *cpu)
+static void do_hax_cpu_synchronize_post_reset(void *arg)
{
- CPUArchState *env = (CPUArchState *)(cpu->env_ptr);
+ CPUState *cpu = arg;
+ CPUArchState *env = cpu->env_ptr;
+
hax_vcpu_sync_state(env, 1);
- cpu->hax_vcpu_dirty = 0;
+ cpu->hax_vcpu_dirty = false;
}
-void hax_cpu_synchronize_post_init(CPUState *cpu)
+void hax_cpu_synchronize_post_reset(CPUState * cpu)
{
- CPUArchState *env = (CPUArchState *)(cpu->env_ptr);
+ run_on_cpu(cpu, do_hax_cpu_synchronize_post_reset, cpu);
+}
+
+static void do_hax_cpu_synchronize_post_init(void *arg)
+{
+ CPUState *cpu = arg;
+ CPUArchState *env = cpu->env_ptr;
+
hax_vcpu_sync_state(env, 1);
- cpu->hax_vcpu_dirty = 0;
+ cpu->hax_vcpu_dirty = false;
+}
+
+void hax_cpu_synchronize_post_init(CPUState * cpu)
+{
+ run_on_cpu(cpu, do_hax_cpu_synchronize_post_init, cpu);
}
/*
@@ -1145,7 +1197,16 @@ static int hax_sync_vcpu_register(CPUArchState *env, int set)
hax_getput_reg(&regs._rdi, &env->regs[R_EDI], set);
hax_getput_reg(&regs._rsp, &env->regs[R_ESP], set);
hax_getput_reg(&regs._rbp, &env->regs[R_EBP], set);
-
+#ifdef TARGET_X86_64
+ hax_getput_reg(&regs._r8, &env->regs[8], set);
+ hax_getput_reg(&regs._r9, &env->regs[9], set);
+ hax_getput_reg(&regs._r10, &env->regs[10], set);
+ hax_getput_reg(&regs._r11, &env->regs[11], set);
+ hax_getput_reg(&regs._r12, &env->regs[12], set);
+ hax_getput_reg(&regs._r13, &env->regs[13], set);
+ hax_getput_reg(&regs._r14, &env->regs[14], set);
+ hax_getput_reg(&regs._r15, &env->regs[15], set);
+#endif
hax_getput_reg(&regs._rflags, &env->eflags, set);
hax_getput_reg(&regs._rip, &env->eip, set);
@@ -1173,8 +1234,14 @@ static int hax_sync_vcpu_register(CPUArchState *env, int set)
if (ret < 0)
return -1;
}
+
+ // it should be done after get_msrs, since it needs
+ // EFER synchonization
+#if 0
if (!set)
hax_setup_qemu_emulator(env);
+#endif
+
return 0;
}
@@ -1196,6 +1263,14 @@ static int hax_get_msrs(CPUArchState *env)
msrs[n++].entry = MSR_IA32_SYSENTER_ESP;
msrs[n++].entry = MSR_IA32_SYSENTER_EIP;
msrs[n++].entry = MSR_IA32_TSC;
+#ifdef TARGET_X86_64
+ msrs[n++].entry = MSR_EFER;
+ msrs[n++].entry = MSR_STAR;
+ msrs[n++].entry = MSR_LSTAR;
+ msrs[n++].entry = MSR_CSTAR;
+ msrs[n++].entry = MSR_FMASK;
+ msrs[n++].entry = MSR_KERNELGSBASE;
+#endif
md.nr_msr = n;
ret = hax_sync_msr(env, &md, 0);
if (ret < 0)
@@ -1215,6 +1290,26 @@ static int hax_get_msrs(CPUArchState *env)
case MSR_IA32_TSC:
env->tsc = msrs[i].value;
break;
+#ifdef TARGET_X86_64
+ case MSR_EFER:
+ env->efer = msrs[i].value;
+ break;
+ case MSR_STAR:
+ env->star = msrs[i].value;
+ break;
+ case MSR_LSTAR:
+ env->lstar = msrs[i].value;
+ break;
+ case MSR_CSTAR:
+ env->cstar = msrs[i].value;
+ break;
+ case MSR_FMASK:
+ env->fmask = msrs[i].value;
+ break;
+ case MSR_KERNELGSBASE:
+ env->kernelgsbase = msrs[i].value;
+ break;
+#endif
}
}
@@ -1233,6 +1328,14 @@ static int hax_set_msrs(CPUArchState *env)
hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
hax_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
+#ifdef TARGET_X86_64
+ hax_msr_entry_set(&msrs[n++], MSR_EFER, env->efer);
+ hax_msr_entry_set(&msrs[n++], MSR_STAR, env->star);
+ hax_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
+ hax_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
+ hax_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
+ hax_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase);
+#endif
md.nr_msr = n;
md.done = 0;
@@ -1255,9 +1358,13 @@ static int hax_get_fpu(CPUArchState *env)
for (i = 0; i < 8; ++i)
env->fptags[i] = !((fpu.ftw >> i) & 1);
memcpy(env->fpregs, fpu.st_mm, sizeof(env->fpregs));
+ for (i = 0; i < 8; ++i) {
+ memcpy(&env->xmm_regs[i], fpu.mmx_1[i], sizeof(fpu.mmx_1[i]));
+ }
+ for (i = 0; i < 8; ++i) {
+ memcpy(&env->xmm_regs[8 + i], fpu.mmx_2[i], sizeof(fpu.mmx_2[i]));
+ }
- memcpy(env->xmm_regs, fpu.mmx_1, sizeof(fpu.mmx_1));
- memcpy((ZMMReg *)(env->xmm_regs) + 8, fpu.mmx_2, sizeof(fpu.mmx_2));
env->mxcsr = fpu.mxcsr;
return 0;
@@ -1277,8 +1384,12 @@ static int hax_set_fpu(CPUArchState *env)
fpu.ftw |= (!env->fptags[i]) << i;
memcpy(fpu.st_mm, env->fpregs, sizeof (env->fpregs));
- memcpy(fpu.mmx_1, env->xmm_regs, sizeof (fpu.mmx_1));
- memcpy(fpu.mmx_2, (ZMMReg *)(env->xmm_regs) + 8, sizeof (fpu.mmx_2));
+ for (i = 0; i < 8; i++) {
+ memcpy(fpu.mmx_1[i], &env->xmm_regs[i], sizeof(fpu.mmx_1[i]));
+ }
+ for (i = 0; i < 8; i++) {
+ memcpy(fpu.mmx_2[i], &env->xmm_regs[i + 8], sizeof(fpu.mmx_2[i]));
+ }
fpu.mxcsr = env->mxcsr;
@@ -1301,6 +1412,8 @@ static int hax_arch_get_registers(CPUArchState *env)
if (ret < 0)
return ret;
+ hax_setup_qemu_emulator(env);
+
return 0;
}