diff options
Diffstat (limited to 'target-i386/hax-all.c')
-rw-r--r-- | target-i386/hax-all.c | 181 |
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(®s._rdi, &env->regs[R_EDI], set); hax_getput_reg(®s._rsp, &env->regs[R_ESP], set); hax_getput_reg(®s._rbp, &env->regs[R_EBP], set); - +#ifdef TARGET_X86_64 + hax_getput_reg(®s._r8, &env->regs[8], set); + hax_getput_reg(®s._r9, &env->regs[9], set); + hax_getput_reg(®s._r10, &env->regs[10], set); + hax_getput_reg(®s._r11, &env->regs[11], set); + hax_getput_reg(®s._r12, &env->regs[12], set); + hax_getput_reg(®s._r13, &env->regs[13], set); + hax_getput_reg(®s._r14, &env->regs[14], set); + hax_getput_reg(®s._r15, &env->regs[15], set); +#endif hax_getput_reg(®s._rflags, &env->eflags, set); hax_getput_reg(®s._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; } |