Skip to content

Commit 17d3810

Browse files
paulusmackgregkh
authored andcommitted
KVM: PPC: Book3S HV: Reload HTM registers explicitly
Commit 46a704f ("KVM: PPC: Book3S HV: Preserve userspace HTM state properly", 2017-06-15) added code which assumes that the kernel is able to handle a TM (transactional memory) unavailable interrupt from userspace by reloading the TM-related registers and enabling TM for the process. That ability was added in the 4.9 kernel; earlier kernel versions simply panic on getting the TM unavailable interrupt. Since commit 46a704f has been backported to the 4.4 stable tree as commit 824b950, 4.4.75 and subsequent versions are vulnerable to a userspace-triggerable panic. This patch fixes the problem by explicitly reloading the TM-related registers before returning to userspace, rather than disabling TM for the process. Commit 46a704f also failed to enable TM for the kernel, leading to a TM unavailable interrupt in the kernel, causing an oops. This fixes that problem too, by enabling TM before accessing the TM registers. That problem is fixed upstream by the patch "KVM: PPC: Book3S HV: Enable TM before accessing TM registers". Fixes: 824b950 ("KVM: PPC: Book3S HV: Preserve userspace HTM state properly") Signed-off-by: Paul Mackerras <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent f5b29db commit 17d3810

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

arch/powerpc/kvm/book3s_hv.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2711,10 +2711,11 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
27112711
run->fail_entry.hardware_entry_failure_reason = 0;
27122712
return -EINVAL;
27132713
}
2714+
/* Enable TM so we can read the TM SPRs */
2715+
mtmsr(mfmsr() | MSR_TM);
27142716
current->thread.tm_tfhar = mfspr(SPRN_TFHAR);
27152717
current->thread.tm_tfiar = mfspr(SPRN_TFIAR);
27162718
current->thread.tm_texasr = mfspr(SPRN_TEXASR);
2717-
current->thread.regs->msr &= ~MSR_TM;
27182719
}
27192720
#endif
27202721

@@ -2782,6 +2783,19 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
27822783
}
27832784
mtspr(SPRN_VRSAVE, user_vrsave);
27842785

2786+
/*
2787+
* Since we don't do lazy TM reload, we need to reload
2788+
* the TM registers here.
2789+
*/
2790+
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2791+
if (cpu_has_feature(CPU_FTR_TM) && current->thread.regs &&
2792+
(current->thread.regs->msr & MSR_TM)) {
2793+
mtspr(SPRN_TFHAR, current->thread.tm_tfhar);
2794+
mtspr(SPRN_TFIAR, current->thread.tm_tfiar);
2795+
mtspr(SPRN_TEXASR, current->thread.tm_texasr);
2796+
}
2797+
#endif
2798+
27852799
out:
27862800
vcpu->arch.state = KVMPPC_VCPU_NOTREADY;
27872801
atomic_dec(&vcpu->kvm->arch.vcpus_running);

0 commit comments

Comments
 (0)