Example #1
0
/*
 * Flatten an expression to a variable.
 */
static expr_t flatten_to_var(expr_t e, context_t cxt)
{
    e = flatten(e, false, cxt);
    if (expr_gettype(e) == EXPRTYPE_VAR)
        return e;
    return context_update(cxt, e);
}
Example #2
0
static int amd_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content,
                             uint64_t supported)
{
    struct vcpu *v = current;
    struct vpmu_struct *vpmu = vcpu_vpmu(v);

    ASSERT(!supported);

    /* For all counters, enable guest only mode for HVM guest */
    if ( (get_pmu_reg_type(msr) == MSR_TYPE_CTRL) &&
        !(is_guest_mode(msr_content)) )
    {
        set_guest_mode(msr_content);
    }

    /* check if the first counter is enabled */
    if ( (get_pmu_reg_type(msr) == MSR_TYPE_CTRL) &&
        is_pmu_enabled(msr_content) && !vpmu_is_set(vpmu, VPMU_RUNNING) )
    {
        if ( !acquire_pmu_ownership(PMU_OWNER_HVM) )
            return 1;
        vpmu_set(vpmu, VPMU_RUNNING);
        apic_write(APIC_LVTPC, PMU_APIC_VECTOR);
        vpmu->hw_lapic_lvtpc = PMU_APIC_VECTOR;

        if ( !((struct amd_vpmu_context *)vpmu->context)->msr_bitmap_set )
            amd_vpmu_set_msr_bitmap(v);
    }

    /* stop saving & restore if guest stops first counter */
    if ( (get_pmu_reg_type(msr) == MSR_TYPE_CTRL) &&
        (is_pmu_enabled(msr_content) == 0) && vpmu_is_set(vpmu, VPMU_RUNNING) )
    {
        apic_write(APIC_LVTPC, PMU_APIC_VECTOR | APIC_LVT_MASKED);
        vpmu->hw_lapic_lvtpc = PMU_APIC_VECTOR | APIC_LVT_MASKED;
        vpmu_reset(vpmu, VPMU_RUNNING);
        if ( ((struct amd_vpmu_context *)vpmu->context)->msr_bitmap_set )
            amd_vpmu_unset_msr_bitmap(v);
        release_pmu_ownship(PMU_OWNER_HVM);
    }

    if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_LOADED)
        || vpmu_is_set(vpmu, VPMU_FROZEN) )
    {
        context_load(v);
        vpmu_set(vpmu, VPMU_CONTEXT_LOADED);
        vpmu_reset(vpmu, VPMU_FROZEN);
    }

    /* Update vpmu context immediately */
    context_update(msr, msr_content);

    /* Write to hw counters */
    wrmsrl(msr, msr_content);
    return 1;
}
Example #3
0
/*
 * Flatten an expression to a primitive expression.
 */
static expr_t flatten_to_primitive(expr_t e, context_t cxt)
{
    e = flatten(e, false, cxt);
    switch (expr_gettype(e))
    {
        case EXPRTYPE_VAR: case EXPRTYPE_BOOL: case EXPRTYPE_NUM:
        case EXPRTYPE_ATOM: case EXPRTYPE_STR:
            return e;
        default:
            break;
    }
    return context_update(cxt, e);
}
Example #4
0
/*
 * Flatten an equality expression `x = y'.  Assumes x and y are already
 * flattened.
 */
static expr_t flatten_eq_to_builtin(exprop_t op, expr_t x, expr_t y,
    bool toplevel, context_t cxt)
{
    if (expr_gettype(x) == EXPRTYPE_VAR && expr_gettype(y) == EXPRTYPE_VAR)
        return expr_make(op, x, y);
    if (expr_gettype(y) == EXPRTYPE_VAR)
    {
        expr_t t = x;
        x = y;
        y = t;
    }
    if (expr_gettype(x) != EXPRTYPE_VAR)
        x = context_update(cxt, x);
    if (!toplevel)
        y = context_update(cxt, y);

    // Special-case handling of constants and variables:
    switch (expr_gettype(y))
    {
        case EXPRTYPE_VAR:
            if (expr_compare(x, y) < 0)
                return expr_make(op, x, y);
            else
                return expr_make(op, y, x);
        case EXPRTYPE_NUM:
            return expr_make(exprop_atom_make(ATOM_INT_EQ_C), x, y);
        case EXPRTYPE_NIL:
            return expr_make(exprop_atom_make(ATOM_NIL_EQ_C), x, y);
        case EXPRTYPE_STR:
            return expr_make(exprop_atom_make(ATOM_STR_EQ_C), x, y);
        case EXPRTYPE_ATOM:
            return expr_make(exprop_atom_make(ATOM_ATOM_EQ_C), x, y);
        case EXPRTYPE_OP:
            break;
        default:
            panic("unexpected expr type (%d)", expr_gettype(y));
    }

    // Special-case handling of add/mul:
    exprop_t fop = expr_op(y);
    switch (fop)
    {
        case EXPROP_ADD:
        {
            expr_t a = expr_arg(y, 0);
            expr_t b = expr_arg(y, 1);
            if (expr_gettype(a) == EXPRTYPE_NUM)
            {
                expr_t t = a; a = b; b = t;
            }
            if (expr_gettype(b) == EXPRTYPE_NUM)
            {
                num_t c = expr_getnum(b);
                if (c < 0)
                    return expr_make(exprop_atom_make(ATOM_INT_EQ_PLUS_C),
                        a, x, expr_num(-c));
                else
                    return expr_make(exprop_atom_make(ATOM_INT_EQ_PLUS_C),
                        x, a, b);
            }
            else
                return expr_make(exprop_atom_make(ATOM_INT_EQ_PLUS), x, a, b);
        }
        case EXPROP_MUL:
        {
            expr_t a = expr_arg(y, 0);
            expr_t b = expr_arg(y, 1);
            if (expr_gettype(a) == EXPRTYPE_NUM)
            {
                expr_t t = a; a = b; b = t;
            }
            if (expr_gettype(b) == EXPRTYPE_NUM)
                return expr_make(exprop_atom_make(ATOM_INT_EQ_MUL_C), x, a, b);
            else
                return expr_make(exprop_atom_make(ATOM_INT_EQ_MUL), x, a, b);
        }
        case EXPROP_POW:
        {
            expr_t a = expr_arg(y, 0);
            expr_t b = expr_arg(y, 1);
            return expr_make(exprop_atom_make(ATOM_INT_EQ_POW_C), x, a, b);
        }
        default:
            break;
    }

    // Generic function calls:
    atom_t atom = expr_sym(y);
    const char *name = atom_name(atom);
    size_t arity = atom_arity(atom);
    size_t len = strlen(name);
    char buf[len + 32];
    typesig_t sig = typeinst_lookup_typesig(atom);
    typeinst_t type = (sig == TYPESIG_DEFAULT? TYPEINST_NUM:
        typeinst_make_ground(sig->type));
    const char *type_name = typeinst_show(type);
    int r = snprintf(buf, sizeof(buf)-1, "%s_eq_call_%s", type_name, name);
    if (r <= 0 || r >= sizeof(buf)-1)
        panic("failed to create function constraint name");

    op = exprop_make(buf, arity+1);
    expr_t args[arity+1];
    expr_args(y, args+1);
    args[0] = x;
    expr_t e = expr(op, args);

    if (sig == TYPESIG_DEFAULT)
        return e;
    atom = expr_sym(e);
    typeinst_t sig_args[arity+1];
    memcpy(sig_args+1, sig->args, arity * sizeof(typeinst_t));
    sig_args[0] = typeinst_make_var(sig->type);
    sig = typeinst_make_typesig(arity+1, TYPEINST_BOOL, sig_args);
    if (!typeinst_declare(atom, sig))
    {
        error("(%s: %zu) failed to declare implied type for %s/%zu",
            cxt->file, cxt->line, atom_name(atom), atom_arity(arity));
        cxt->error = true;
    }
    return e;
}