int arch_vcpu_deinit(struct vmm_vcpu *vcpu) { int rc = VMM_OK; u32 saved_cptr_el2, saved_hstr_el2; /* For both Orphan & Normal VCPUs */ memset(arm_regs(vcpu), 0, sizeof(arch_regs_t)); /* For Orphan VCPUs do nothing else */ if (!vcpu->is_normal) { return VMM_OK; } /* Save CPTR_EL2 and HSTR_EL2 */ saved_cptr_el2 = mrs(cptr_el2); saved_hstr_el2 = mrs(hstr_el2); /* We force disable coprocessor and system traps to be * consistent with arch_vcpu_init() function. */ msr(cptr_el2, 0x0); msr(hstr_el2, 0x0); /* Free Generic Timer Context */ if (arm_feature(vcpu, ARM_FEATURE_GENERIC_TIMER)) { if ((rc = generic_timer_vcpu_context_deinit(vcpu, &arm_gentimer_context(vcpu)))) { goto done; } } /* Free VFP context */ rc = cpu_vcpu_vfp_deinit(vcpu); if (rc) { goto done; } /* Free sysregs context */ rc = cpu_vcpu_sysregs_deinit(vcpu); if (rc) { goto done; } /* Free private context */ vmm_free(vcpu->arch_priv); vcpu->arch_priv = NULL; rc = VMM_OK; done: msr(cptr_el2, saved_cptr_el2); msr(hstr_el2, saved_hstr_el2); return VMM_OK; }
int arch_vcpu_deinit(struct vmm_vcpu *vcpu) { int rc; /* For both Orphan & Normal VCPUs */ memset(arm_regs(vcpu), 0, sizeof(arch_regs_t)); /* For Orphan VCPUs do nothing else */ if (!vcpu->is_normal) { return VMM_OK; } /* Free Generic Timer Context */ if (arm_feature(vcpu, ARM_FEATURE_GENERIC_TIMER)) { if ((rc = generic_timer_vcpu_context_deinit(vcpu, &arm_gentimer_context(vcpu)))) { return rc; } } /* Free VFP context */ rc = cpu_vcpu_vfp_deinit(vcpu); if (rc) { return rc; } /* Free sysregs context */ rc = cpu_vcpu_sysregs_deinit(vcpu); if (rc) { return rc; } /* Free private context */ vmm_free(vcpu->arch_priv); vcpu->arch_priv = NULL; return VMM_OK; }