[PATCH v1 4/7] KVM: PPC: Book3S 64: Move hcall early register setup to KVM
Fabiano Rosas
farosas at linux.ibm.com
Sat Apr 17 04:28:45 AEST 2021
Nicholas Piggin <npiggin at gmail.com> 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 at gmail.com>
Reviewed-by: Fabiano Rosas <farosas at linux.ibm.com>
> ---
> 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
More information about the Linuxppc-dev
mailing list