aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2017-07-18 01:32:44 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2017-07-18 02:45:11 -0400
commit76fc0cfcc5b0f520062ca6d7225b224d4a8aa828 (patch)
treea864cd3c7a3f4713d916fb11aa4523b56cfa3502
parent101dd590a7fa37954540cf3149a1c502c0acc524 (diff)
powerpc/64s: Fix hypercall entry clobbering r12 input
A previous optimisation incorrectly assumed the PAPR hcall does not use r12, and clobbers it upon entry. In fact it is used as an input. This can result in KVM guests crashing (observed with PR KVM). Instead of using r12 to save r13, tihs patch saves r13 in ctr. This is more costly, but not as slow as using the SPRG. Fixes: acd7d8cef0153 ("powerpc/64s: Optimize hypercall/syscall entry") Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S28
1 files changed, 14 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 4c18a5fbb4bb..124091d306ff 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -824,7 +824,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
824 * r3 volatile parameter and return value for status 824 * r3 volatile parameter and return value for status
825 * r4-r10 volatile input and output value 825 * r4-r10 volatile input and output value
826 * r11 volatile hypercall number and output value 826 * r11 volatile hypercall number and output value
827 * r12 volatile 827 * r12 volatile input and output value
828 * r13-r31 nonvolatile 828 * r13-r31 nonvolatile
829 * LR nonvolatile 829 * LR nonvolatile
830 * CTR volatile 830 * CTR volatile
@@ -834,25 +834,26 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
834 * Other registers nonvolatile 834 * Other registers nonvolatile
835 * 835 *
836 * The intersection of volatile registers that don't contain possible 836 * The intersection of volatile registers that don't contain possible
837 * inputs is: r12, cr0, xer, ctr. We may use these as scratch regs 837 * inputs is: cr0, xer, ctr. We may use these as scratch regs upon entry
838 * upon entry without saving. 838 * without saving, though xer is not a good idea to use, as hardware may
839 * interpret some bits so it may be costly to change them.
839 */ 840 */
840#ifdef CONFIG_KVM_BOOK3S_64_HANDLER 841#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
841 /* 842 /*
842 * There is a little bit of juggling to get syscall and hcall 843 * There is a little bit of juggling to get syscall and hcall
843 * working well. Save r10 in ctr to be restored in case it is a 844 * working well. Save r13 in ctr to avoid using SPRG scratch
844 * hcall. 845 * register.
845 * 846 *
846 * Userspace syscalls have already saved the PPR, hcalls must save 847 * Userspace syscalls have already saved the PPR, hcalls must save
847 * it before setting HMT_MEDIUM. 848 * it before setting HMT_MEDIUM.
848 */ 849 */
849#define SYSCALL_KVMTEST \ 850#define SYSCALL_KVMTEST \
850 mr r12,r13; \ 851 mtctr r13; \
851 GET_PACA(r13); \ 852 GET_PACA(r13); \
852 mtctr r10; \ 853 std r10,PACA_EXGEN+EX_R10(r13); \
853 KVMTEST_PR(0xc00); /* uses r10, branch to do_kvm_0xc00_system_call */ \ 854 KVMTEST_PR(0xc00); /* uses r10, branch to do_kvm_0xc00_system_call */ \
854 HMT_MEDIUM; \ 855 HMT_MEDIUM; \
855 mr r9,r12; \ 856 mfctr r9;
856 857
857#else 858#else
858#define SYSCALL_KVMTEST \ 859#define SYSCALL_KVMTEST \
@@ -935,8 +936,8 @@ EXC_VIRT_END(system_call, 0x4c00, 0x100)
935 * This is a hcall, so register convention is as above, with these 936 * This is a hcall, so register convention is as above, with these
936 * differences: 937 * differences:
937 * r13 = PACA 938 * r13 = PACA
938 * r12 = orig r13 939 * ctr = orig r13
939 * ctr = orig r10 940 * orig r10 saved in PACA
940 */ 941 */
941TRAMP_KVM_BEGIN(do_kvm_0xc00) 942TRAMP_KVM_BEGIN(do_kvm_0xc00)
942 /* 943 /*
@@ -944,14 +945,13 @@ TRAMP_KVM_BEGIN(do_kvm_0xc00)
944 * HMT_MEDIUM. That allows the KVM code to save that value into the 945 * HMT_MEDIUM. That allows the KVM code to save that value into the
945 * guest state (it is the guest's PPR value). 946 * guest state (it is the guest's PPR value).
946 */ 947 */
947 OPT_GET_SPR(r0, SPRN_PPR, CPU_FTR_HAS_PPR) 948 OPT_GET_SPR(r10, SPRN_PPR, CPU_FTR_HAS_PPR)
948 HMT_MEDIUM 949 HMT_MEDIUM
949 OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r0, CPU_FTR_HAS_PPR) 950 OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r10, CPU_FTR_HAS_PPR)
950 mfctr r10 951 mfctr r10
951 SET_SCRATCH0(r12) 952 SET_SCRATCH0(r10)
952 std r9,PACA_EXGEN+EX_R9(r13) 953 std r9,PACA_EXGEN+EX_R9(r13)
953 mfcr r9 954 mfcr r9
954 std r10,PACA_EXGEN+EX_R10(r13)
955 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00) 955 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
956#endif 956#endif
957 957