Commit e2762743 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

KVM: PPC: Book3S 64: Minimise hcall handler calling convention differences



This sets up the same calling convention from interrupt entry to
KVM interrupt handler for system calls as exists for other interrupt
types.

This is a better API, it uses a save area rather than SPR, and it has
more registers free to use. Using a single common API helps maintain
it, and it becomes easier to use in C in a later patch.

Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Reviewed-by: default avatarAlexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210528090752.3542186-8-npiggin@gmail.com
parent 1b5821c6
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -1869,8 +1869,27 @@ EXC_VIRT_END(system_call, 0x4c00, 0x100)

#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
TRAMP_REAL_BEGIN(kvm_hcall)
	std	r9,PACA_EXGEN+EX_R9(r13)
	std	r11,PACA_EXGEN+EX_R11(r13)
	std	r12,PACA_EXGEN+EX_R12(r13)
	mfcr	r9
	mfctr	r10
	SET_SCRATCH0(r10) /* Save r13 in SCRATCH0 */
	std	r10,PACA_EXGEN+EX_R13(r13)
	li	r10,0
	std	r10,PACA_EXGEN+EX_CFAR(r13)
	std	r10,PACA_EXGEN+EX_CTR(r13)
	 /*
	  * 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,PACA_EXGEN+EX_PPR(r13)
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)

	HMT_MEDIUM

#ifdef CONFIG_RELOCATABLE
	/*
	 * Requires __LOAD_FAR_HANDLER beause kvmppc_hcall lives
+25 −36
Original line number Diff line number Diff line
@@ -11,16 +11,10 @@
 * These are branched to from interrupt handlers in exception-64s.S which set
 * IKVM_REAL or IKVM_VIRT, if HSTATE_IN_GUEST was found to be non-zero.
 */
.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
 * Documentation/powerpc/papr_hcalls.rst.
 *
 * 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
@@ -28,23 +22,19 @@ kvmppc_hcall:
 * 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.
 *
 * The state of registers is as kvmppc_interrupt, except CFAR is not
 * saved, R13 is not in SCRATCH0, and R10 does not contain the trap.
 */
	 /*
	  * 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)
	b	do_kvm_interrupt
.global	kvmppc_hcall
.balign IFETCH_ALIGN_BYTES
kvmppc_hcall:
	ld	r10,PACA_EXGEN+EX_R13(r13)
	SET_SCRATCH0(r10)
	li	r10,0xc00
	/* Now we look like kvmppc_interrupt */
	li	r11,PACA_EXGEN
	b	.Lgot_save_area

/*
 * KVM interrupt entry occurs after GEN_INT_ENTRY runs, and follows that
@@ -67,12 +57,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
kvmppc_interrupt:
	li	r11,PACA_EXGEN
	cmpdi	r10,0x200
	bgt+	1f
	bgt+	.Lgot_save_area
	li	r11,PACA_EXMC
	beq	1f
	beq	.Lgot_save_area
	li	r11,PACA_EXNMI
1:	add	r11,r11,r13

.Lgot_save_area:
	add	r11,r11,r13
BEGIN_FTR_SECTION
	ld	r12,EX_CFAR(r11)
	std	r12,HSTATE_CFAR(r13)
@@ -91,7 +81,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
	ld	r10,EX_R10(r11)
	ld	r11,EX_R11(r11)

do_kvm_interrupt:
	/*
	 * Hcalls and other interrupts come here after normalising register
	 * contents and save locations: