Nicholas Piggin <npig...@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 <npig...@gmail.com>

Reviewed-by: Fabiano Rosas <faro...@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

Reply via email to