|
@@ -2908,6 +2908,8 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
|
|
|
int r;
|
|
|
int srcu_idx;
|
|
|
unsigned long ebb_regs[3] = {}; /* shut up GCC */
|
|
|
+ unsigned long user_tar = 0;
|
|
|
+ unsigned int user_vrsave;
|
|
|
|
|
|
if (!vcpu->arch.sane) {
|
|
|
run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
|
@@ -2935,12 +2937,14 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
|
|
|
|
|
|
flush_all_to_thread(current);
|
|
|
|
|
|
- /* Save userspace EBB register values */
|
|
|
+ /* Save userspace EBB and other register values */
|
|
|
if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
|
|
|
ebb_regs[0] = mfspr(SPRN_EBBHR);
|
|
|
ebb_regs[1] = mfspr(SPRN_EBBRR);
|
|
|
ebb_regs[2] = mfspr(SPRN_BESCR);
|
|
|
+ user_tar = mfspr(SPRN_TAR);
|
|
|
}
|
|
|
+ user_vrsave = mfspr(SPRN_VRSAVE);
|
|
|
|
|
|
vcpu->arch.wqp = &vcpu->arch.vcore->wq;
|
|
|
vcpu->arch.pgdir = current->mm->pgd;
|
|
@@ -2968,12 +2972,15 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
|
|
|
}
|
|
|
} while (is_kvmppc_resume_guest(r));
|
|
|
|
|
|
- /* Restore userspace EBB register values */
|
|
|
+ /* Restore userspace EBB and other register values */
|
|
|
if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
|
|
|
mtspr(SPRN_EBBHR, ebb_regs[0]);
|
|
|
mtspr(SPRN_EBBRR, ebb_regs[1]);
|
|
|
mtspr(SPRN_BESCR, ebb_regs[2]);
|
|
|
+ mtspr(SPRN_TAR, user_tar);
|
|
|
+ mtspr(SPRN_FSCR, current->thread.fscr);
|
|
|
}
|
|
|
+ mtspr(SPRN_VRSAVE, user_vrsave);
|
|
|
|
|
|
out:
|
|
|
vcpu->arch.state = KVMPPC_VCPU_NOTREADY;
|