Пример #1
0
Файл: kvm.c Проект: 3a9LL/panda
int kvm_arch_put_registers(CPUState *env, int level)
{
    struct kvm_regs regs;
    int ret;
    int i;

    ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
    if (ret < 0)
        return ret;

    regs.ctr = env->ctr;
    regs.lr  = env->lr;
    regs.xer = env->xer;
    regs.msr = env->msr;
    regs.pc = env->nip;

    regs.srr0 = env->spr[SPR_SRR0];
    regs.srr1 = env->spr[SPR_SRR1];

    regs.sprg0 = env->spr[SPR_SPRG0];
    regs.sprg1 = env->spr[SPR_SPRG1];
    regs.sprg2 = env->spr[SPR_SPRG2];
    regs.sprg3 = env->spr[SPR_SPRG3];
    regs.sprg4 = env->spr[SPR_SPRG4];
    regs.sprg5 = env->spr[SPR_SPRG5];
    regs.sprg6 = env->spr[SPR_SPRG6];
    regs.sprg7 = env->spr[SPR_SPRG7];

    regs.pid = env->spr[SPR_BOOKE_PID];

    for (i = 0;i < 32; i++)
        regs.gpr[i] = env->gpr[i];

    ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);
    if (ret < 0)
        return ret;

    if (env->tlb_dirty) {
        kvm_sw_tlb_put(env);
        env->tlb_dirty = false;
    }

    return ret;
}
Пример #2
0
int kvm_arch_put_registers(CPUState *cs, int level)
{
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    CPUPPCState *env = &cpu->env;
    struct kvm_regs regs;
    int ret;
    int i;

    ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
    if (ret < 0) {
        return ret;
    }

    regs.ctr = env->ctr;
    regs.lr  = env->lr;
    regs.xer = cpu_read_xer(env);
    regs.msr = env->msr;
    regs.pc = env->nip;

    regs.srr0 = env->spr[SPR_SRR0];
    regs.srr1 = env->spr[SPR_SRR1];

    regs.sprg0 = env->spr[SPR_SPRG0];
    regs.sprg1 = env->spr[SPR_SPRG1];
    regs.sprg2 = env->spr[SPR_SPRG2];
    regs.sprg3 = env->spr[SPR_SPRG3];
    regs.sprg4 = env->spr[SPR_SPRG4];
    regs.sprg5 = env->spr[SPR_SPRG5];
    regs.sprg6 = env->spr[SPR_SPRG6];
    regs.sprg7 = env->spr[SPR_SPRG7];

    regs.pid = env->spr[SPR_BOOKE_PID];

    for (i = 0;i < 32; i++)
        regs.gpr[i] = env->gpr[i];

    ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
    if (ret < 0)
        return ret;

    kvm_put_fp(cs);

    if (env->tlb_dirty) {
        kvm_sw_tlb_put(cpu);
        env->tlb_dirty = false;
    }

    if (cap_segstate && (level >= KVM_PUT_RESET_STATE)) {
        struct kvm_sregs sregs;

        sregs.pvr = env->spr[SPR_PVR];

        sregs.u.s.sdr1 = env->spr[SPR_SDR1];

        /* Sync SLB */
#ifdef TARGET_PPC64
        for (i = 0; i < 64; i++) {
            sregs.u.s.ppc64.slb[i].slbe = env->slb[i].esid;
            sregs.u.s.ppc64.slb[i].slbv = env->slb[i].vsid;
        }
#endif

        /* Sync SRs */
        for (i = 0; i < 16; i++) {
            sregs.u.s.ppc32.sr[i] = env->sr[i];
        }

        /* Sync BATs */
        for (i = 0; i < 8; i++) {
            /* Beware. We have to swap upper and lower bits here */
            sregs.u.s.ppc32.dbat[i] = ((uint64_t)env->DBAT[0][i] << 32)
                | env->DBAT[1][i];
            sregs.u.s.ppc32.ibat[i] = ((uint64_t)env->IBAT[0][i] << 32)
                | env->IBAT[1][i];
        }

        ret = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs);
        if (ret) {
            return ret;
        }
    }

    if (cap_hior && (level >= KVM_PUT_RESET_STATE)) {
        kvm_put_one_spr(cs, KVM_REG_PPC_HIOR, SPR_HIOR);
    }

    if (cap_one_reg) {
        int i;

        /* We deliberately ignore errors here, for kernels which have
         * the ONE_REG calls, but don't support the specific
         * registers, there's a reasonable chance things will still
         * work, at least until we try to migrate. */
        for (i = 0; i < 1024; i++) {
            uint64_t id = env->spr_cb[i].one_reg_id;

            if (id != 0) {
                kvm_put_one_spr(cs, id, i);
            }
        }
    }

    return ret;
}
Пример #3
0
int kvm_arch_put_registers(CPUState *cs, int level)
{
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    CPUPPCState *env = &cpu->env;
    struct kvm_regs regs;
    int ret;
    int i;

    ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
    if (ret < 0) {
        return ret;
    }

    regs.ctr = env->ctr;
    regs.lr  = env->lr;
    regs.xer = env->xer;
    regs.msr = env->msr;
    regs.pc = env->nip;

    regs.srr0 = env->spr[SPR_SRR0];
    regs.srr1 = env->spr[SPR_SRR1];

    regs.sprg0 = env->spr[SPR_SPRG0];
    regs.sprg1 = env->spr[SPR_SPRG1];
    regs.sprg2 = env->spr[SPR_SPRG2];
    regs.sprg3 = env->spr[SPR_SPRG3];
    regs.sprg4 = env->spr[SPR_SPRG4];
    regs.sprg5 = env->spr[SPR_SPRG5];
    regs.sprg6 = env->spr[SPR_SPRG6];
    regs.sprg7 = env->spr[SPR_SPRG7];

    regs.pid = env->spr[SPR_BOOKE_PID];

    for (i = 0;i < 32; i++)
        regs.gpr[i] = env->gpr[i];

    ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
    if (ret < 0)
        return ret;

    if (env->tlb_dirty) {
        kvm_sw_tlb_put(cpu);
        env->tlb_dirty = false;
    }

    if (cap_segstate && (level >= KVM_PUT_RESET_STATE)) {
        struct kvm_sregs sregs;

        sregs.pvr = env->spr[SPR_PVR];

        sregs.u.s.sdr1 = env->spr[SPR_SDR1];

        /* Sync SLB */
#ifdef TARGET_PPC64
        for (i = 0; i < 64; i++) {
            sregs.u.s.ppc64.slb[i].slbe = env->slb[i].esid;
            sregs.u.s.ppc64.slb[i].slbv = env->slb[i].vsid;
        }
#endif

        /* Sync SRs */
        for (i = 0; i < 16; i++) {
            sregs.u.s.ppc32.sr[i] = env->sr[i];
        }

        /* Sync BATs */
        for (i = 0; i < 8; i++) {
            /* Beware. We have to swap upper and lower bits here */
            sregs.u.s.ppc32.dbat[i] = ((uint64_t)env->DBAT[0][i] << 32)
                | env->DBAT[1][i];
            sregs.u.s.ppc32.ibat[i] = ((uint64_t)env->IBAT[0][i] << 32)
                | env->IBAT[1][i];
        }

        ret = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs);
        if (ret) {
            return ret;
        }
    }

    if (cap_hior && (level >= KVM_PUT_RESET_STATE)) {
        uint64_t hior = env->spr[SPR_HIOR];
        struct kvm_one_reg reg = {
            .id = KVM_REG_PPC_HIOR,
            .addr = (uintptr_t) &hior,
        };

        ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
        if (ret) {
            return ret;
        }
    }

    return ret;
}