Nicholas Piggin <npiggin@xxxxxxxxx> writes: > System calls / hcalls have a different calling convention than > other interrupts, so there is code in the KVMTEST to massage these > into the same form as other interrupt handlers. > > Move this work into the KVM hcall handler. This means teaching KVM > a little more about the low level interrupt handler setup, PACA save > areas, etc., although that's not obviously worse than the current > approach of coming up with an entirely different interrupt register > / save convention. > > Signed-off-by: Nicholas Piggin <npiggin@xxxxxxxxx> Reviewed-by: Fabiano Rosas <farosas@xxxxxxxxxxxxx> > --- > arch/powerpc/include/asm/exception-64s.h | 13 ++++++++ > arch/powerpc/kernel/exceptions-64s.S | 42 +----------------------- > arch/powerpc/kvm/book3s_64_entry.S | 30 +++++++++++++++++ > 3 files changed, 44 insertions(+), 41 deletions(-) > > diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h > index c1a8aac01cf9..bb6f78fcf981 100644 > --- a/arch/powerpc/include/asm/exception-64s.h > +++ b/arch/powerpc/include/asm/exception-64s.h > @@ -35,6 +35,19 @@ > /* PACA save area size in u64 units (exgen, exmc, etc) */ > #define EX_SIZE 10 > > +/* PACA save area offsets */ > +#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 > + > /* > * maximum recursive depth of MCE exceptions > */ > diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S > index 9467fd1038f9..1bfd0d7af09e 100644 > --- a/arch/powerpc/kernel/exceptions-64s.S > +++ b/arch/powerpc/kernel/exceptions-64s.S > @@ -21,22 +21,6 @@ > #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. > * > @@ -1964,29 +1948,8 @@ EXC_VIRT_END(system_call, 0x4c00, 0x100) > > #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 > @@ -1994,15 +1957,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) > */ > __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 > diff --git a/arch/powerpc/kvm/book3s_64_entry.S b/arch/powerpc/kvm/book3s_64_entry.S > index c21fa64059ef..f527e16707db 100644 > --- a/arch/powerpc/kvm/book3s_64_entry.S > +++ b/arch/powerpc/kvm/book3s_64_entry.S > @@ -14,6 +14,36 @@ > .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