04b67ef
Subject:    [PATCH 2/2] KVM: PPC: Book3S HV: Save/restore TM state in H_CEDE
04b67ef
From:       Paul Mackerras <paulus@ozlabs.org>
04b67ef
Date:       2016-07-28 6:11:19
04b67ef
04b67ef
It turns out that if the guest does a H_CEDE while the CPU is in
04b67ef
a transactional state, and the H_CEDE does a nap, and the nap
04b67ef
loses the architected state of the CPU (which is is allowed to do),
04b67ef
then we lose the checkpointed state of the virtual CPU.  In addition,
04b67ef
the transactional-memory state recorded in the MSR gets reset back
04b67ef
to non-transactional, and when we try to return to the guest, we take
04b67ef
a TM bad thing type of program interrupt because we are trying to
04b67ef
transition from non-transactional to transactional with a hrfid
04b67ef
instruction, which is not permitted.
04b67ef
04b67ef
The result of the program interrupt occurring at that point is that
04b67ef
the host CPU will hang in an infinite loop with interrupts disabled.
04b67ef
Thus this is a denial of service vulnerability in the host which can
04b67ef
be triggered by any guest (and depending on the guest kernel, it can
04b67ef
potentially triggered by unprivileged userspace in the guest).
04b67ef
04b67ef
This vulnerability has been assigned the ID CVE-2016-5412.
04b67ef
04b67ef
To fix this, we save the TM state before napping and restore it
04b67ef
on exit from the nap, when handling a H_CEDE in real mode.  The
04b67ef
case where H_CEDE exits to host virtual mode is already OK (as are
04b67ef
other hcalls which exit to host virtual mode) because the exit
04b67ef
path saves the TM state.
04b67ef
04b67ef
Cc: stable@vger.kernel.org # v3.15+
04b67ef
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
04b67ef
---
04b67ef
 arch/powerpc/kvm/book3s_hv_rmhandlers.S | 13 +++++++++++++
04b67ef
 1 file changed, 13 insertions(+)
04b67ef
04b67ef
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
04b67ef
index cfa4031..543124f 100644
04b67ef
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
04b67ef
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
04b67ef
@@ -2093,6 +2093,13 @@ _GLOBAL(kvmppc_h_cede)		/* r3 = vcpu pointer, r11 = msr, r13 = paca */
04b67ef
 	/* save FP state */
04b67ef
 	bl	kvmppc_save_fp
04b67ef
 
04b67ef
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
04b67ef
+BEGIN_FTR_SECTION
04b67ef
+	ld	r9, HSTATE_KVM_VCPU(r13)
04b67ef
+	bl	kvmppc_save_tm
04b67ef
+END_FTR_SECTION_IFSET(CPU_FTR_TM)
04b67ef
+#endif
04b67ef
+
04b67ef
 	/*
04b67ef
 	 * Set DEC to the smaller of DEC and HDEC, so that we wake
04b67ef
 	 * no later than the end of our timeslice (HDEC interrupts
04b67ef
@@ -2169,6 +2176,12 @@ kvm_end_cede:
04b67ef
 	bl	kvmhv_accumulate_time
04b67ef
 #endif
04b67ef
 
04b67ef
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
04b67ef
+BEGIN_FTR_SECTION
04b67ef
+	bl	kvmppc_restore_tm
04b67ef
+END_FTR_SECTION_IFSET(CPU_FTR_TM)
04b67ef
+#endif
04b67ef
+
04b67ef
 	/* load up FP state */
04b67ef
 	bl	kvmppc_load_fp
04b67ef
 
04b67ef
-- 
04b67ef
2.8.0.rc3