#include <asm/feature-fixups.h>
 #include <asm/kup.h>
 
-/* PACA save area offsets (exgen, exmc, etc) */
-#define EX_R9          0
-#define EX_R10         8
-#define EX_R11         16
-#define EX_R12         24
-#define EX_R13         32
-#define EX_DAR         40
-#define EX_DSISR       48
-#define EX_CCR         52
-#define EX_CFAR                56
-#define EX_PPR         64
-#define EX_CTR         72
-.if EX_SIZE != 10
-       .error "EX_SIZE is wrong"
-.endif
-
 /*
  * Following are fixed section helper macros.
  *
 
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
 TRAMP_REAL_BEGIN(system_call_kvm)
-       /*
-        * This is a hcall, so register convention is as above, with these
-        * differences:
-        * r13 = PACA
-        * ctr = orig r13
-        * orig r10 saved in PACA
-        */
-        /*
-         * Save the PPR (on systems that support it) before changing to
-         * HMT_MEDIUM. That allows the KVM code to save that value into the
-         * guest state (it is the guest's PPR value).
-         */
-BEGIN_FTR_SECTION
-       mfspr   r10,SPRN_PPR
-       std     r10,HSTATE_PPR(r13)
-END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
-       HMT_MEDIUM
        mfctr   r10
-       SET_SCRATCH0(r10)
-       mfcr    r10
-       std     r12,HSTATE_SCRATCH0(r13)
-       sldi    r12,r10,32
-       ori     r12,r12,0xc00
+       SET_SCRATCH0(r10) /* Save r13 in SCRATCH0 */
 #ifdef CONFIG_RELOCATABLE
        /*
         * Requires __LOAD_FAR_HANDLER beause kvmppc_hcall lives
         */
        __LOAD_FAR_HANDLER(r10, kvmppc_hcall)
        mtctr   r10
-       ld      r10,PACA_EXGEN+EX_R10(r13)
        bctr
 #else
-       ld      r10,PACA_EXGEN+EX_R10(r13)
        b       kvmppc_hcall
 #endif
 #endif
 
-
 /**
  * Interrupt 0xd00 - Trace Interrupt.
  * This is a synchronous interrupt in response to instruction step or
 
 .global        kvmppc_hcall
 .balign IFETCH_ALIGN_BYTES
 kvmppc_hcall:
+       /*
+        * This is a hcall, so register convention is as
+        * Documentation/powerpc/papr_hcalls.rst, with these additions:
+        * R13          = PACA
+        * guest R13 saved in SPRN_SCRATCH0
+        * R10          = free
+        * guest r10 saved in PACA_EXGEN
+        *
+        * This may also be a syscall from PR-KVM userspace that is to be
+        * reflected to the PR guest kernel, so registers may be set up for
+        * a system call rather than hcall. We don't currently clobber
+        * anything here, but the 0xc00 handler has already clobbered CTR
+        * and CR0, so PR-KVM can not support a guest kernel that preserves
+        * those registers across its system calls.
+        */
+        /*
+         * Save the PPR (on systems that support it) before changing to
+         * HMT_MEDIUM. That allows the KVM code to save that value into the
+         * guest state (it is the guest's PPR value).
+         */
+BEGIN_FTR_SECTION
+       mfspr   r10,SPRN_PPR
+       std     r10,HSTATE_PPR(r13)
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
+       HMT_MEDIUM
+       mfcr    r10
+       std     r12,HSTATE_SCRATCH0(r13)
+       sldi    r12,r10,32
+       ori     r12,r12,0xc00
+       ld      r10,PACA_EXGEN+EX_R10(r13)
 
 .global        kvmppc_interrupt
 .balign IFETCH_ALIGN_BYTES