forked from Minki/linux
KVM: PPC: Book3S: Change interrupt call to reduce scratch space use on HV
Change the calling convention to put the trap number together with CR in two halves of r12, which frees up HSTATE_SCRATCH2 in the HV handler. The 64-bit PR handler entry translates the calling convention back to match the previous call convention (i.e., shared with 32-bit), for simplicity. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Acked-by: Paul Mackerras <paulus@ozlabs.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
49def18533
commit
d3918e7fd4
@ -233,7 +233,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
|
||||
|
||||
#endif
|
||||
|
||||
#define __KVM_HANDLER_PROLOG(area, n) \
|
||||
#define __KVM_HANDLER(area, h, n) \
|
||||
BEGIN_FTR_SECTION_NESTED(947) \
|
||||
ld r10,area+EX_CFAR(r13); \
|
||||
std r10,HSTATE_CFAR(r13); \
|
||||
@ -243,30 +243,28 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
|
||||
std r10,HSTATE_PPR(r13); \
|
||||
END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \
|
||||
ld r10,area+EX_R10(r13); \
|
||||
stw r9,HSTATE_SCRATCH1(r13); \
|
||||
ld r9,area+EX_R9(r13); \
|
||||
std r12,HSTATE_SCRATCH0(r13); \
|
||||
|
||||
#define __KVM_HANDLER(area, h, n) \
|
||||
__KVM_HANDLER_PROLOG(area, n) \
|
||||
li r12,n; \
|
||||
sldi r12,r9,32; \
|
||||
ori r12,r12,(n); \
|
||||
ld r9,area+EX_R9(r13); \
|
||||
b kvmppc_interrupt
|
||||
|
||||
#define __KVM_HANDLER_SKIP(area, h, n) \
|
||||
cmpwi r10,KVM_GUEST_MODE_SKIP; \
|
||||
ld r10,area+EX_R10(r13); \
|
||||
beq 89f; \
|
||||
stw r9,HSTATE_SCRATCH1(r13); \
|
||||
BEGIN_FTR_SECTION_NESTED(948) \
|
||||
ld r9,area+EX_PPR(r13); \
|
||||
std r9,HSTATE_PPR(r13); \
|
||||
ld r10,area+EX_PPR(r13); \
|
||||
std r10,HSTATE_PPR(r13); \
|
||||
END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \
|
||||
ld r9,area+EX_R9(r13); \
|
||||
ld r10,area+EX_R10(r13); \
|
||||
std r12,HSTATE_SCRATCH0(r13); \
|
||||
li r12,n; \
|
||||
sldi r12,r9,32; \
|
||||
ori r12,r12,(n); \
|
||||
ld r9,area+EX_R9(r13); \
|
||||
b kvmppc_interrupt; \
|
||||
89: mtocrf 0x80,r9; \
|
||||
ld r9,area+EX_R9(r13); \
|
||||
ld r10,area+EX_R10(r13); \
|
||||
b kvmppc_skip_##h##interrupt
|
||||
|
||||
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
|
||||
|
@ -1057,19 +1057,18 @@ hdec_soon:
|
||||
kvmppc_interrupt_hv:
|
||||
/*
|
||||
* Register contents:
|
||||
* R12 = interrupt vector
|
||||
* R12 = (guest CR << 32) | interrupt vector
|
||||
* R13 = PACA
|
||||
* guest CR, R12 saved in shadow VCPU SCRATCH1/0
|
||||
* guest R12 saved in shadow VCPU SCRATCH0
|
||||
* guest R13 saved in SPRN_SCRATCH0
|
||||
*/
|
||||
std r9, HSTATE_SCRATCH2(r13)
|
||||
|
||||
std r9, HSTATE_SCRATCH1(r13)
|
||||
lbz r9, HSTATE_IN_GUEST(r13)
|
||||
cmpwi r9, KVM_GUEST_MODE_HOST_HV
|
||||
beq kvmppc_bad_host_intr
|
||||
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
|
||||
cmpwi r9, KVM_GUEST_MODE_GUEST
|
||||
ld r9, HSTATE_SCRATCH2(r13)
|
||||
ld r9, HSTATE_SCRATCH1(r13)
|
||||
beq kvmppc_interrupt_pr
|
||||
#endif
|
||||
/* We're now back in the host but in guest MMU context */
|
||||
@ -1089,13 +1088,14 @@ kvmppc_interrupt_hv:
|
||||
std r6, VCPU_GPR(R6)(r9)
|
||||
std r7, VCPU_GPR(R7)(r9)
|
||||
std r8, VCPU_GPR(R8)(r9)
|
||||
ld r0, HSTATE_SCRATCH2(r13)
|
||||
ld r0, HSTATE_SCRATCH1(r13)
|
||||
std r0, VCPU_GPR(R9)(r9)
|
||||
std r10, VCPU_GPR(R10)(r9)
|
||||
std r11, VCPU_GPR(R11)(r9)
|
||||
ld r3, HSTATE_SCRATCH0(r13)
|
||||
lwz r4, HSTATE_SCRATCH1(r13)
|
||||
std r3, VCPU_GPR(R12)(r9)
|
||||
/* CR is in the high half of r12 */
|
||||
srdi r4, r12, 32
|
||||
stw r4, VCPU_CR(r9)
|
||||
BEGIN_FTR_SECTION
|
||||
ld r3, HSTATE_CFAR(r13)
|
||||
@ -1114,6 +1114,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||
mfspr r11, SPRN_SRR1
|
||||
std r10, VCPU_SRR0(r9)
|
||||
std r11, VCPU_SRR1(r9)
|
||||
/* trap is in the low half of r12, clear CR from the high half */
|
||||
clrldi r12, r12, 32
|
||||
andi. r0, r12, 2 /* need to read HSRR0/1? */
|
||||
beq 1f
|
||||
mfspr r10, SPRN_HSRR0
|
||||
|
@ -167,20 +167,31 @@ kvmppc_handler_trampoline_enter_end:
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
.global kvmppc_handler_trampoline_exit
|
||||
kvmppc_handler_trampoline_exit:
|
||||
|
||||
.global kvmppc_interrupt_pr
|
||||
kvmppc_interrupt_pr:
|
||||
/* 64-bit entry. Register usage at this point:
|
||||
*
|
||||
* SPRG_SCRATCH0 = guest R13
|
||||
* R12 = (guest CR << 32) | exit handler id
|
||||
* R13 = PACA
|
||||
* HSTATE.SCRATCH0 = guest R12
|
||||
*/
|
||||
#ifdef CONFIG_PPC64
|
||||
/* Match 32-bit entry */
|
||||
rotldi r12, r12, 32 /* Flip R12 halves for stw */
|
||||
stw r12, HSTATE_SCRATCH1(r13) /* CR is now in the low half */
|
||||
srdi r12, r12, 32 /* shift trap into low half */
|
||||
#endif
|
||||
|
||||
.global kvmppc_handler_trampoline_exit
|
||||
kvmppc_handler_trampoline_exit:
|
||||
/* Register usage at this point:
|
||||
*
|
||||
* SPRG_SCRATCH0 = guest R13
|
||||
* R12 = exit handler id
|
||||
* R13 = shadow vcpu (32-bit) or PACA (64-bit)
|
||||
* SPRG_SCRATCH0 = guest R13
|
||||
* R12 = exit handler id
|
||||
* R13 = shadow vcpu (32-bit) or PACA (64-bit)
|
||||
* HSTATE.SCRATCH0 = guest R12
|
||||
* HSTATE.SCRATCH1 = guest CR
|
||||
*
|
||||
*/
|
||||
|
||||
/* Save registers */
|
||||
|
Loading…
Reference in New Issue
Block a user