Commit 04ece7b6 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman

KVM: PPC: Book3S 64: Move hcall early register setup to KVM

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: default avatarNicholas Piggin <npiggin@gmail.com>
Reviewed-by: default avatarFabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210528090752.3542186-5-npiggin@gmail.com
parent 31c67cfe
...@@ -35,6 +35,19 @@ ...@@ -35,6 +35,19 @@
/* PACA save area size in u64 units (exgen, exmc, etc) */ /* PACA save area size in u64 units (exgen, exmc, etc) */
#define EX_SIZE 10 #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 * maximum recursive depth of MCE exceptions
*/ */
......
...@@ -21,22 +21,6 @@ ...@@ -21,22 +21,6 @@
#include <asm/feature-fixups.h> #include <asm/feature-fixups.h>
#include <asm/kup.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. * Following are fixed section helper macros.
* *
...@@ -1941,29 +1925,8 @@ EXC_VIRT_END(system_call, 0x4c00, 0x100) ...@@ -1941,29 +1925,8 @@ EXC_VIRT_END(system_call, 0x4c00, 0x100)
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
TRAMP_REAL_BEGIN(system_call_kvm) 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 mfctr r10
SET_SCRATCH0(r10) SET_SCRATCH0(r10) /* Save r13 in SCRATCH0 */
mfcr r10
std r12,HSTATE_SCRATCH0(r13)
sldi r12,r10,32
ori r12,r12,0xc00
#ifdef CONFIG_RELOCATABLE #ifdef CONFIG_RELOCATABLE
/* /*
* Requires __LOAD_FAR_HANDLER beause kvmppc_hcall lives * Requires __LOAD_FAR_HANDLER beause kvmppc_hcall lives
...@@ -1971,15 +1934,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) ...@@ -1971,15 +1934,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
*/ */
__LOAD_FAR_HANDLER(r10, kvmppc_hcall) __LOAD_FAR_HANDLER(r10, kvmppc_hcall)
mtctr r10 mtctr r10
ld r10,PACA_EXGEN+EX_R10(r13)
bctr bctr
#else #else
ld r10,PACA_EXGEN+EX_R10(r13)
b kvmppc_hcall b kvmppc_hcall
#endif #endif
#endif #endif
/** /**
* Interrupt 0xd00 - Trace Interrupt. * Interrupt 0xd00 - Trace Interrupt.
* This is a synchronous interrupt in response to instruction step or * This is a synchronous interrupt in response to instruction step or
......
...@@ -14,6 +14,36 @@ ...@@ -14,6 +14,36 @@
.global kvmppc_hcall .global kvmppc_hcall
.balign IFETCH_ALIGN_BYTES .balign IFETCH_ALIGN_BYTES
kvmppc_hcall: 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 .global kvmppc_interrupt
.balign IFETCH_ALIGN_BYTES .balign IFETCH_ALIGN_BYTES
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment