Пример #1
0
void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
{
    uintptr_t ra = GETPC();

    if ((a0 & 0xf) != 0) {
        raise_exception_ra(env, EXCP0D_GPF, ra);
    } else {
#ifndef CONFIG_ATOMIC128
        cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
#else
        int eflags = cpu_cc_compute_all(env, CC_OP);

        Int128 cmpv = int128_make128(env->regs[R_EAX], env->regs[R_EDX]);
        Int128 newv = int128_make128(env->regs[R_EBX], env->regs[R_ECX]);

        int mem_idx = cpu_mmu_index(env, false);
        TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
        Int128 oldv = helper_atomic_cmpxchgo_le_mmu(env, a0, cmpv,
                                                    newv, oi, ra);

        if (int128_eq(oldv, cmpv)) {
            eflags |= CC_Z;
        } else {
            env->regs[R_EAX] = int128_getlo(oldv);
            env->regs[R_EDX] = int128_gethi(oldv);
            eflags &= ~CC_Z;
        }
        CC_SRC = eflags;
#endif
    }
}
Пример #2
0
void helper_bndck(CPUX86State *env, uint32_t fail)
{
    if (unlikely(fail)) {
        env->bndcs_regs.sts = 1;
        raise_exception_ra(env, EXCP05_BOUND, GETPC());
    }
}
Пример #3
0
void helper_sti_vm(CPUX86State *env)
{
    env->eflags |= VIF_MASK;
    if (env->eflags & VIP_MASK) {
        raise_exception_ra(env, EXCP0D_GPF, GETPC());
    }
}
Пример #4
0
void helper_monitor(CPUX86State *env, target_ulong ptr)
{
    if ((uint32_t)env->regs[R_ECX] != 0) {
        raise_exception_ra(env, EXCP0D_GPF, GETPC());
    }
    /* XXX: store address? */
    cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC());
}
Пример #5
0
void helper_rdpmc(CPUX86State *env)
{
    if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
        raise_exception_ra(env, EXCP0D_GPF, GETPC());
    }
    cpu_svm_check_intercept_param(env, SVM_EXIT_RDPMC, 0, GETPC());

    /* currently unimplemented */
    qemu_log_mask(LOG_UNIMP, "x86: unimplemented rdpmc\n");
    raise_exception_err(env, EXCP06_ILLOP, 0);
}
Пример #6
0
void helper_boundl(CPUX86State *env, target_ulong a0, int v)
{
    int low, high;

    low = cpu_ldl_data_ra(env, a0, GETPC());
    high = cpu_ldl_data_ra(env, a0 + 4, GETPC());
    if (v < low || v > high) {
        if (env->hflags & HF_MPX_EN_MASK) {
            env->bndcs_regs.sts = 0;
        }
        raise_exception_ra(env, EXCP05_BOUND, GETPC());
    }
}
Пример #7
0
void helper_rdtsc(CPUX86State *env)
{
    uint64_t val;

    if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
        raise_exception_ra(env, EXCP0D_GPF, GETPC());
    }
    cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0);

    val = cpu_get_tsc(env) + env->tsc_offset;
    env->regs[R_EAX] = (uint32_t)(val);
    env->regs[R_EDX] = (uint32_t)(val >> 32);
}
Пример #8
0
static uint32_t lookup_bte32(CPUX86State *env, uint32_t base, uintptr_t ra)
{
    uint32_t bndcsr, bde, bt;

    if ((env->hflags & HF_CPL_MASK) == 3) {
        bndcsr = env->bndcs_regs.cfgu;
    } else {
        bndcsr = env->msr_bndcfgs;
    }

    bde = (extract32(base, 12, 20) << 2) + (bndcsr & TARGET_PAGE_MASK);
    bt = cpu_ldl_data_ra(env, bde, ra);
    if ((bt & 1) == 0) {
        env->bndcs_regs.sts = bde | 2;
        raise_exception_ra(env, EXCP05_BOUND, ra);
    }

    return (extract32(base, 2, 10) << 4) + (bt & ~3);
}
Пример #9
0
static uint64_t lookup_bte64(CPUX86State *env, uint64_t base, uintptr_t ra)
{
    uint64_t bndcsr, bde, bt;

    if ((env->hflags & HF_CPL_MASK) == 3) {
        bndcsr = env->bndcs_regs.cfgu;
    } else {
        bndcsr = env->msr_bndcfgs;
    }

    bde = (extract64(base, 20, 28) << 3) + (extract64(bndcsr, 20, 44) << 12);
    bt = cpu_ldq_data_ra(env, bde, ra);
    if ((bt & 1) == 0) {
        env->bndcs_regs.sts = bde | 2;
        raise_exception_ra(env, EXCP05_BOUND, ra);
    }

    return (extract64(base, 3, 17) << 5) + (bt & ~7);
}
Пример #10
0
void helper_mwait(CPUX86State *env, int next_eip_addend)
{
    CPUState *cs;
    X86CPU *cpu;

    if ((uint32_t)env->regs[R_ECX] != 0) {
        raise_exception_ra(env, EXCP0D_GPF, GETPC());
    }
    cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0, GETPC());
    env->eip += next_eip_addend;

    cpu = x86_env_get_cpu(env);
    cs = CPU(cpu);
    /* XXX: not complete but not completely erroneous */
    if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
        do_pause(cpu);
    } else {
        do_hlt(cpu);
    }
}
Пример #11
0
void helper_rdtsc(CPUX86State *env)
{
    uint64_t val;

    if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
        raise_exception_ra(env, EXCP0D_GPF, GETPC());
    }
    cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0, GETPC());

#ifdef CONFIG_SOFTMMU
    RR_DO_RECORD_OR_REPLAY(
        /*action=*/val = cpu_get_tsc(env) + env->tsc_offset,
        /*record=*/rr_input_8(&val),
        /*replay=*/rr_input_8(&val),
        /*location=*/RR_CALLSITE_RDTSC);
#else
        val = cpu_get_tsc(env) + env->tsc_offset;
#endif

    env->regs[R_EAX] = (uint32_t)(val);
    env->regs[R_EDX] = (uint32_t)(val >> 32);
}
Пример #12
0
void helper_cmpxchg16b_unlocked(CPUX86State *env, target_ulong a0)
{
    uintptr_t ra = GETPC();
    Int128 oldv, cmpv, newv;
    uint64_t o0, o1;
    int eflags;
    bool success;

    if ((a0 & 0xf) != 0) {
        raise_exception_ra(env, EXCP0D_GPF, GETPC());
    }
    eflags = cpu_cc_compute_all(env, CC_OP);

    cmpv = int128_make128(env->regs[R_EAX], env->regs[R_EDX]);
    newv = int128_make128(env->regs[R_EBX], env->regs[R_ECX]);

    o0 = cpu_ldq_data_ra(env, a0 + 0, ra);
    o1 = cpu_ldq_data_ra(env, a0 + 8, ra);

    oldv = int128_make128(o0, o1);
    success = int128_eq(oldv, cmpv);
    if (!success) {
        newv = oldv;
    }

    cpu_stq_data_ra(env, a0 + 0, int128_getlo(newv), ra);
    cpu_stq_data_ra(env, a0 + 8, int128_gethi(newv), ra);

    if (success) {
        eflags |= CC_Z;
    } else {
        env->regs[R_EAX] = int128_getlo(oldv);
        env->regs[R_EDX] = int128_gethi(oldv);
        eflags &= ~CC_Z;
    }
    CC_SRC = eflags;
}