int kvm_arch_init_vcpu(CPUState *cs)

{

    int i, ret, arraylen;

    uint64_t v;

    struct kvm_one_reg r;

    struct kvm_reg_list rl;

    struct kvm_reg_list *rlp;

    ARMCPU *cpu = ARM_CPU(cs);



    if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {

        fprintf(stderr, "KVM is not supported for this guest CPU type\n");

        return -EINVAL;

    }



    /* Determine init features for this CPU */

    memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));

    if (cpu->start_powered_off) {

        cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;

    }

    if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {

        cpu->psci_version = 2;

        cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;

    }



    /* Do KVM_ARM_VCPU_INIT ioctl */

    ret = kvm_arm_vcpu_init(cs);

    if (ret) {

        return ret;

    }



    /* Query the kernel to make sure it supports 32 VFP

     * registers: QEMU's "cortex-a15" CPU is always a

     * VFP-D32 core. The simplest way to do this is just

     * to attempt to read register d31.

     */

    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31;

    r.addr = (uintptr_t)(&v);

    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);

    if (ret == -ENOENT) {

        return -EINVAL;

    }



    /* Populate the cpreg list based on the kernel's idea

     * of what registers exist (and throw away the TCG-created list).

     */

    rl.n = 0;

    ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, &rl);

    if (ret != -E2BIG) {

        return ret;

    }

    rlp = g_malloc(sizeof(struct kvm_reg_list) + rl.n * sizeof(uint64_t));

    rlp->n = rl.n;

    ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, rlp);

    if (ret) {

        goto out;

    }

    /* Sort the list we get back from the kernel, since cpreg_tuples

     * must be in strictly ascending order.

     */

    qsort(&rlp->reg, rlp->n, sizeof(rlp->reg[0]), compare_u64);



    for (i = 0, arraylen = 0; i < rlp->n; i++) {

        if (!reg_syncs_via_tuple_list(rlp->reg[i])) {

            continue;

        }

        switch (rlp->reg[i] & KVM_REG_SIZE_MASK) {

        case KVM_REG_SIZE_U32:

        case KVM_REG_SIZE_U64:

            break;

        default:

            fprintf(stderr, "Can't handle size of register in kernel list\n");

            ret = -EINVAL;

            goto out;

        }



        arraylen++;

    }



    cpu->cpreg_indexes = g_renew(uint64_t, cpu->cpreg_indexes, arraylen);

    cpu->cpreg_values = g_renew(uint64_t, cpu->cpreg_values, arraylen);

    cpu->cpreg_vmstate_indexes = g_renew(uint64_t, cpu->cpreg_vmstate_indexes,

                                         arraylen);

    cpu->cpreg_vmstate_values = g_renew(uint64_t, cpu->cpreg_vmstate_values,

                                        arraylen);

    cpu->cpreg_array_len = arraylen;

    cpu->cpreg_vmstate_array_len = arraylen;



    for (i = 0, arraylen = 0; i < rlp->n; i++) {

        uint64_t regidx = rlp->reg[i];

        if (!reg_syncs_via_tuple_list(regidx)) {

            continue;

        }

        cpu->cpreg_indexes[arraylen] = regidx;

        arraylen++;

    }

    assert(cpu->cpreg_array_len == arraylen);



    if (!write_kvmstate_to_list(cpu)) {

        /* Shouldn't happen unless kernel is inconsistent about

         * what registers exist.

         */

        fprintf(stderr, "Initial read of kernel register state failed\n");

        ret = -EINVAL;

        goto out;

    }



    /* Save a copy of the initial register values so that we can

     * feed it back to the kernel on VCPU reset.

     */

    cpu->cpreg_reset_values = g_memdup(cpu->cpreg_values,

                                       cpu->cpreg_array_len *

                                       sizeof(cpu->cpreg_values[0]));



out:

    g_free(rlp);

    return ret;

}

int kvm_arch_init_vcpu(CPUState *cs)

{

    int i, ret, arraylen;

    uint64_t v;

    struct kvm_one_reg r;

    struct kvm_reg_list rl;

    struct kvm_reg_list *rlp;

    ARMCPU *cpu = ARM_CPU(cs);



    if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {

        fprintf(stderr, "KVM is not supported for this guest CPU type\n");

        return -EINVAL;

    }



    

    memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));

    if (cpu->start_powered_off) {

        cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;

    }

    if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {

        cpu->psci_version = 2;

        cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;

    }



    

    ret = kvm_arm_vcpu_init(cs);

    if (ret) {

        return ret;

    }



    









    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31;

    r.addr = (uintptr_t)(&v);

    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);

    if (ret == -ENOENT) {

        return -EINVAL;

    }



    





    rl.n = 0;

    ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, &rl);

    if (ret != -E2BIG) {

        return ret;

    }

    rlp = g_malloc(sizeof(struct kvm_reg_list) + rl.n * sizeof(uint64_t));

    rlp->n = rl.n;

    ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, rlp);

    if (ret) {

        goto out;

    }

    





    qsort(&rlp->reg, rlp->n, sizeof(rlp->reg[0]), compare_u64);



    for (i = 0, arraylen = 0; i < rlp->n; i++) {

        if (!reg_syncs_via_tuple_list(rlp->reg[i])) {

            continue;

        }

        switch (rlp->reg[i] & KVM_REG_SIZE_MASK) {

        case KVM_REG_SIZE_U32:

        case KVM_REG_SIZE_U64:

            break;

        default:

            fprintf(stderr, "Can't handle size of register in kernel list\n");

            ret = -EINVAL;

            goto out;

        }



        arraylen++;

    }



    cpu->cpreg_indexes = g_renew(uint64_t, cpu->cpreg_indexes, arraylen);

    cpu->cpreg_values = g_renew(uint64_t, cpu->cpreg_values, arraylen);

    cpu->cpreg_vmstate_indexes = g_renew(uint64_t, cpu->cpreg_vmstate_indexes,

                                         arraylen);

    cpu->cpreg_vmstate_values = g_renew(uint64_t, cpu->cpreg_vmstate_values,

                                        arraylen);

    cpu->cpreg_array_len = arraylen;

    cpu->cpreg_vmstate_array_len = arraylen;



    for (i = 0, arraylen = 0; i < rlp->n; i++) {

        uint64_t regidx = rlp->reg[i];

        if (!reg_syncs_via_tuple_list(regidx)) {

            continue;

        }

        cpu->cpreg_indexes[arraylen] = regidx;

        arraylen++;

    }

    assert(cpu->cpreg_array_len == arraylen);



    if (!write_kvmstate_to_list(cpu)) {

        





        fprintf(stderr, "Initial read of kernel register state failed\n");

        ret = -EINVAL;

        goto out;

    }



    





    cpu->cpreg_reset_values = g_memdup(cpu->cpreg_values,

                                       cpu->cpreg_array_len *

                                       sizeof(cpu->cpreg_values[0]));



out:

    g_free(rlp);

    return ret;

}

int FUNC_0(CPUState *VAR_0)

{

    int VAR_1, VAR_2, VAR_3;

    uint64_t v;

    struct kvm_one_reg VAR_4;

    struct kvm_reg_list VAR_5;

    struct kvm_reg_list *VAR_6;

    ARMCPU *cpu = ARM_CPU(VAR_0);



    if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {

        fprintf(stderr, "KVM is not supported for this guest CPU type\n");

        return -EINVAL;

    }



    

    memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features));

    if (cpu->start_powered_off) {

        cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;

    }

    if (kvm_check_extension(VAR_0->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {

        cpu->psci_version = 2;

        cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;

    }



    

    VAR_2 = kvm_arm_vcpu_init(VAR_0);

    if (VAR_2) {

        return VAR_2;

    }



    









    VAR_4.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31;

    VAR_4.addr = (uintptr_t)(&v);

    VAR_2 = kvm_vcpu_ioctl(VAR_0, KVM_GET_ONE_REG, &VAR_4);

    if (VAR_2 == -ENOENT) {

        return -EINVAL;

    }



    





    VAR_5.n = 0;

    VAR_2 = kvm_vcpu_ioctl(VAR_0, KVM_GET_REG_LIST, &VAR_5);

    if (VAR_2 != -E2BIG) {

        return VAR_2;

    }

    VAR_6 = g_malloc(sizeof(struct kvm_reg_list) + VAR_5.n * sizeof(uint64_t));

    VAR_6->n = VAR_5.n;

    VAR_2 = kvm_vcpu_ioctl(VAR_0, KVM_GET_REG_LIST, VAR_6);

    if (VAR_2) {

        goto out;

    }

    





    qsort(&VAR_6->reg, VAR_6->n, sizeof(VAR_6->reg[0]), compare_u64);



    for (VAR_1 = 0, VAR_3 = 0; VAR_1 < VAR_6->n; VAR_1++) {

        if (!reg_syncs_via_tuple_list(VAR_6->reg[VAR_1])) {

            continue;

        }

        switch (VAR_6->reg[VAR_1] & KVM_REG_SIZE_MASK) {

        case KVM_REG_SIZE_U32:

        case KVM_REG_SIZE_U64:

            break;

        default:

            fprintf(stderr, "Can't handle size of register in kernel list\n");

            VAR_2 = -EINVAL;

            goto out;

        }



        VAR_3++;

    }



    cpu->cpreg_indexes = g_renew(uint64_t, cpu->cpreg_indexes, VAR_3);

    cpu->cpreg_values = g_renew(uint64_t, cpu->cpreg_values, VAR_3);

    cpu->cpreg_vmstate_indexes = g_renew(uint64_t, cpu->cpreg_vmstate_indexes,

                                         VAR_3);

    cpu->cpreg_vmstate_values = g_renew(uint64_t, cpu->cpreg_vmstate_values,

                                        VAR_3);

    cpu->cpreg_array_len = VAR_3;

    cpu->cpreg_vmstate_array_len = VAR_3;



    for (VAR_1 = 0, VAR_3 = 0; VAR_1 < VAR_6->n; VAR_1++) {

        uint64_t regidx = VAR_6->reg[VAR_1];

        if (!reg_syncs_via_tuple_list(regidx)) {

            continue;

        }

        cpu->cpreg_indexes[VAR_3] = regidx;

        VAR_3++;

    }

    assert(cpu->cpreg_array_len == VAR_3);



    if (!write_kvmstate_to_list(cpu)) {

        





        fprintf(stderr, "Initial read of kernel register state failed\n");

        VAR_2 = -EINVAL;

        goto out;

    }



    





    cpu->cpreg_reset_values = g_memdup(cpu->cpreg_values,

                                       cpu->cpreg_array_len *

                                       sizeof(cpu->cpreg_values[0]));



out:

    g_free(VAR_6);

    return VAR_2;

}

int FUNC_0(CPUState *VAR_0)
{ int VAR_1, VAR_2, VAR_3; uint64_t v; struct kvm_one_reg VAR_4; struct kvm_reg_list VAR_5; struct kvm_reg_list *VAR_6; ARMCPU *cpu = ARM_CPU(VAR_0); if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) { fprintf(stderr, "KVM is not supported for this guest CPU type\n"); return -EINVAL; } memset(cpu->kvm_init_features, 0, sizeof(cpu->kvm_init_features)); if (cpu->start_powered_off) { cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF; } if (kvm_check_extension(VAR_0->kvm_state, KVM_CAP_ARM_PSCI_0_2)) { cpu->psci_version = 2; cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2; } VAR_2 = kvm_arm_vcpu_init(VAR_0); if (VAR_2) { return VAR_2; } VAR_4.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31; VAR_4.addr = (uintptr_t)(&v); VAR_2 = kvm_vcpu_ioctl(VAR_0, KVM_GET_ONE_REG, &VAR_4); if (VAR_2 == -ENOENT) { return -EINVAL; } VAR_5.n = 0; VAR_2 = kvm_vcpu_ioctl(VAR_0, KVM_GET_REG_LIST, &VAR_5); if (VAR_2 != -E2BIG) { return VAR_2; } VAR_6 = g_malloc(sizeof(struct kvm_reg_list) + VAR_5.n * sizeof(uint64_t)); VAR_6->n = VAR_5.n; VAR_2 = kvm_vcpu_ioctl(VAR_0, KVM_GET_REG_LIST, VAR_6); if (VAR_2) { goto out; } qsort(&VAR_6->reg, VAR_6->n, sizeof(VAR_6->reg[0]), compare_u64); for (VAR_1 = 0, VAR_3 = 0; VAR_1 < VAR_6->n; VAR_1++) { if (!reg_syncs_via_tuple_list(VAR_6->reg[VAR_1])) { continue; } switch (VAR_6->reg[VAR_1] & KVM_REG_SIZE_MASK) { case KVM_REG_SIZE_U32:
case KVM_REG_SIZE_U64:
break; default:
fprintf(stderr, "Can't handle size of register in kernel list\n"); VAR_2 = -EINVAL; goto out; } VAR_3++; } cpu->cpreg_indexes = g_renew(uint64_t, cpu->cpreg_indexes, VAR_3); cpu->cpreg_values = g_renew(uint64_t, cpu->cpreg_values, VAR_3); cpu->cpreg_vmstate_indexes = g_renew(uint64_t, cpu->cpreg_vmstate_indexes,
VAR_3); cpu->cpreg_vmstate_values = g_renew(uint64_t, cpu->cpreg_vmstate_values,
VAR_3); cpu->cpreg_array_len = VAR_3; cpu->cpreg_vmstate_array_len = VAR_3; for (VAR_1 = 0, VAR_3 = 0; VAR_1 < VAR_6->n; VAR_1++) { uint64_t regidx = VAR_6->reg[VAR_1]; if (!reg_syncs_via_tuple_list(regidx)) { continue; } cpu->cpreg_indexes[VAR_3] = regidx; VAR_3++; } assert(cpu->cpreg_array_len == VAR_3); if (!write_kvmstate_to_list(cpu)) { fprintf(stderr, "Initial read of kernel register state failed\n"); VAR_2 = -EINVAL; goto out; } cpu->cpreg_reset_values = g_memdup(cpu->cpreg_values,
cpu->cpreg_array_len *
sizeof(cpu->cpreg_values[0])); out:
g_free(VAR_6); return VAR_2; }