Skip to content

Commit 76fc0cf

Browse files
npigginmpe
authored andcommitted
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: acd7d8c ("powerpc/64s: Optimize hypercall/syscall entry") Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent 101dd59 commit 76fc0cf

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
824824
* r3 volatile parameter and return value for status
825825
* r4-r10 volatile input and output value
826826
* r11 volatile hypercall number and output value
827-
* r12 volatile
827+
* r12 volatile input and output value
828828
* r13-r31 nonvolatile
829829
* LR nonvolatile
830830
* CTR volatile
@@ -834,25 +834,26 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
834834
* Other registers nonvolatile
835835
*
836836
* The intersection of volatile registers that don't contain possible
837-
* inputs is: r12, cr0, xer, ctr. We may use these as scratch regs
838-
* upon entry without saving.
837+
* inputs is: cr0, xer, ctr. We may use these as scratch regs upon entry
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.
839840
*/
840841
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
841842
/*
842843
* 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-
* hcall.
844+
* working well. Save r13 in ctr to avoid using SPRG scratch
845+
* register.
845846
*
846847
* Userspace syscalls have already saved the PPR, hcalls must save
847848
* it before setting HMT_MEDIUM.
848849
*/
849850
#define SYSCALL_KVMTEST \
850-
mr r12,r13; \
851+
mtctr r13; \
851852
GET_PACA(r13); \
852-
mtctr r10; \
853+
std r10,PACA_EXGEN+EX_R10(r13); \
853854
KVMTEST_PR(0xc00); /* uses r10, branch to do_kvm_0xc00_system_call */ \
854855
HMT_MEDIUM; \
855-
mr r9,r12; \
856+
mfctr r9;
856857

857858
#else
858859
#define SYSCALL_KVMTEST \
@@ -935,23 +936,22 @@ EXC_VIRT_END(system_call, 0x4c00, 0x100)
935936
* This is a hcall, so register convention is as above, with these
936937
* differences:
937938
* r13 = PACA
938-
* r12 = orig r13
939-
* ctr = orig r10
939+
* ctr = orig r13
940+
* orig r10 saved in PACA
940941
*/
941942
TRAMP_KVM_BEGIN(do_kvm_0xc00)
942943
/*
943944
* Save the PPR (on systems that support it) before changing to
944945
* HMT_MEDIUM. That allows the KVM code to save that value into the
945946
* guest state (it is the guest's PPR value).
946947
*/
947-
OPT_GET_SPR(r0, SPRN_PPR, CPU_FTR_HAS_PPR)
948+
OPT_GET_SPR(r10, SPRN_PPR, CPU_FTR_HAS_PPR)
948949
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)
950951
mfctr r10
951-
SET_SCRATCH0(r12)
952+
SET_SCRATCH0(r10)
952953
std r9,PACA_EXGEN+EX_R9(r13)
953954
mfcr r9
954-
std r10,PACA_EXGEN+EX_R10(r13)
955955
KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
956956
#endif
957957

0 commit comments

Comments
 (0)