/** * kvm_reset_vcpu - sets core registers and sys_regs to reset value * @vcpu: The VCPU pointer * * This function finds the right table above and sets the registers on * the virtual CPU struct to their architecturally defined reset * values. */ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) { const struct kvm_irq_level *cpu_vtimer_irq; const struct kvm_regs *cpu_reset; switch (vcpu->arch.target) { default: if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) { if (!cpu_has_32bit_el1()) return -EINVAL; cpu_reset = &default_regs_reset32; } else { cpu_reset = &default_regs_reset; } cpu_vtimer_irq = &default_vtimer_irq; break; } /* Reset core registers */ memcpy(vcpu_gp_regs(vcpu), cpu_reset, sizeof(*cpu_reset)); /* Reset system registers */ kvm_reset_sys_regs(vcpu); /* Reset PMU */ kvm_pmu_vcpu_reset(vcpu); /* Reset timer */ return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq); }
/* * Return the SPSR for the current mode of the virtual CPU. */ unsigned long *vcpu_spsr32(const struct kvm_vcpu *vcpu) { unsigned long mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK; switch (mode) { case COMPAT_PSR_MODE_SVC: mode = KVM_SPSR_SVC; break; case COMPAT_PSR_MODE_ABT: mode = KVM_SPSR_ABT; break; case COMPAT_PSR_MODE_UND: mode = KVM_SPSR_UND; break; case COMPAT_PSR_MODE_IRQ: mode = KVM_SPSR_IRQ; break; case COMPAT_PSR_MODE_FIQ: mode = KVM_SPSR_FIQ; break; default: BUG(); } return (unsigned long *)&vcpu_gp_regs(vcpu)->spsr[mode]; }
void vcpu_write_spsr32(struct kvm_vcpu *vcpu, unsigned long v) { int spsr_idx = vcpu_spsr32_mode(vcpu); if (!vcpu->arch.sysregs_loaded_on_cpu) { vcpu_gp_regs(vcpu)->spsr[spsr_idx] = v; return; } switch (spsr_idx) { case KVM_SPSR_SVC: write_sysreg_el1(v, spsr); case KVM_SPSR_ABT: write_sysreg(v, spsr_abt); case KVM_SPSR_UND: write_sysreg(v, spsr_und); case KVM_SPSR_IRQ: write_sysreg(v, spsr_irq); case KVM_SPSR_FIQ: write_sysreg(v, spsr_fiq); } }
unsigned long vcpu_read_spsr32(const struct kvm_vcpu *vcpu) { int spsr_idx = vcpu_spsr32_mode(vcpu); if (!vcpu->arch.sysregs_loaded_on_cpu) return vcpu_gp_regs(vcpu)->spsr[spsr_idx]; switch (spsr_idx) { case KVM_SPSR_SVC: return read_sysreg_el1(spsr); case KVM_SPSR_ABT: return read_sysreg(spsr_abt); case KVM_SPSR_UND: return read_sysreg(spsr_und); case KVM_SPSR_IRQ: return read_sysreg(spsr_irq); case KVM_SPSR_FIQ: return read_sysreg(spsr_fiq); default: BUG(); } }