Commit 53e5b8bb authored by Alexander Graf's avatar Alexander Graf Committed by Avi Kivity
Browse files

KVM: PPC: Make SLB switching code the new segment framework



We just introduced generic segment switching code that only needs to call
small macros to do the actual switching, but keeps most of the entry / exit
code generic.

So let's move the SLB switching code over to use this new mechanism.

Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent b79fcdf6
Loading
Loading
Loading
Loading
+24 −159
Original line number Original line Diff line number Diff line
@@ -44,8 +44,7 @@ slb_exit_skip_ ## num:
 *                                                                            *
 *                                                                            *
 *****************************************************************************/
 *****************************************************************************/


.global kvmppc_handler_trampoline_enter
.macro LOAD_GUEST_SEGMENTS
kvmppc_handler_trampoline_enter:


	/* Required state:
	/* Required state:
	 *
	 *
@@ -53,20 +52,14 @@ kvmppc_handler_trampoline_enter:
	 * R13 = PACA
	 * R13 = PACA
	 * R1 = host R1
	 * R1 = host R1
	 * R2 = host R2
	 * R2 = host R2
	 * R9 = guest IP
	 * R3 = shadow vcpu
	 * R10 = guest MSR
	 * all other volatile GPRS = free
	 * all other GPRS = free
	 * SVCPU[CR]  = guest CR
	 * PACA[KVM_CR] = guest CR
	 * SVCPU[XER] = guest XER
	 * PACA[KVM_XER] = guest XER
	 * SVCPU[CTR] = guest CTR
	 * SVCPU[LR]  = guest LR
	 */
	 */


	mtsrr0	r9
	mtsrr1	r10

	/* Activate guest mode, so faults get handled by KVM */
	li	r11, KVM_GUEST_MODE_GUEST
	stb	r11, PACA_KVM_IN_GUEST(r13)

	/* Remove LPAR shadow entries */
	/* Remove LPAR shadow entries */


#if SLB_NUM_BOLTED == 3
#if SLB_NUM_BOLTED == 3
@@ -101,14 +94,14 @@ kvmppc_handler_trampoline_enter:


	/* Fill SLB with our shadow */
	/* Fill SLB with our shadow */


	lbz	r12, PACA_KVM_SLB_MAX(r13)
	lbz	r12, SVCPU_SLB_MAX(r3)
	mulli	r12, r12, 16
	mulli	r12, r12, 16
	addi	r12, r12, PACA_KVM_SLB
	addi	r12, r12, SVCPU_SLB
	add	r12, r12, r13
	add	r12, r12, r3


	/* for (r11 = kvm_slb; r11 < kvm_slb + kvm_slb_size; r11+=slb_entry) */
	/* for (r11 = kvm_slb; r11 < kvm_slb + kvm_slb_size; r11+=slb_entry) */
	li	r11, PACA_KVM_SLB
	li	r11, SVCPU_SLB
	add	r11, r11, r13
	add	r11, r11, r3


slb_loop_enter:
slb_loop_enter:


@@ -127,34 +120,7 @@ slb_loop_enter_skip:


slb_do_enter:
slb_do_enter:


	/* Enter guest */
.endm

	ld	r0, (PACA_KVM_R0)(r13)
	ld	r1, (PACA_KVM_R1)(r13)
	ld	r2, (PACA_KVM_R2)(r13)
	ld	r3, (PACA_KVM_R3)(r13)
	ld	r4, (PACA_KVM_R4)(r13)
	ld	r5, (PACA_KVM_R5)(r13)
	ld	r6, (PACA_KVM_R6)(r13)
	ld	r7, (PACA_KVM_R7)(r13)
	ld	r8, (PACA_KVM_R8)(r13)
	ld	r9, (PACA_KVM_R9)(r13)
	ld	r10, (PACA_KVM_R10)(r13)
	ld	r12, (PACA_KVM_R12)(r13)

	lwz	r11, (PACA_KVM_CR)(r13)
	mtcr	r11

	lwz	r11, (PACA_KVM_XER)(r13)
	mtxer	r11

	ld	r11, (PACA_KVM_R11)(r13)
	ld	r13, (PACA_KVM_R13)(r13)

	RFI
kvmppc_handler_trampoline_enter_end:




/******************************************************************************
/******************************************************************************
 *                                                                            *
 *                                                                            *
@@ -162,99 +128,22 @@ kvmppc_handler_trampoline_enter_end:
 *                                                                            *
 *                                                                            *
 *****************************************************************************/
 *****************************************************************************/


.global kvmppc_handler_trampoline_exit
.macro LOAD_HOST_SEGMENTS
kvmppc_handler_trampoline_exit:


	/* Register usage at this point:
	/* Register usage at this point:
	 *
	 *
	 * SPRG_SCRATCH0     = guest R13
	 * R1         = host R1
	 * R2         = host R2
	 * R12        = exit handler id
	 * R12        = exit handler id
	 * R13               = PACA
	 * R13        = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64]
	 * PACA.KVM.SCRATCH0 = guest R12
	 * SVCPU.*    = guest *
	 * PACA.KVM.SCRATCH1 = guest CR
	 * SVCPU[CR]  = guest CR
	 * SVCPU[XER] = guest XER
	 * SVCPU[CTR] = guest CTR
	 * SVCPU[LR]  = guest LR
	 *
	 *
	 */
	 */


	/* Save registers */

	std	r0, PACA_KVM_R0(r13)
	std	r1, PACA_KVM_R1(r13)
	std	r2, PACA_KVM_R2(r13)
	std	r3, PACA_KVM_R3(r13)
	std	r4, PACA_KVM_R4(r13)
	std	r5, PACA_KVM_R5(r13)
	std	r6, PACA_KVM_R6(r13)
	std	r7, PACA_KVM_R7(r13)
	std	r8, PACA_KVM_R8(r13)
	std	r9, PACA_KVM_R9(r13)
	std	r10, PACA_KVM_R10(r13)
	std	r11, PACA_KVM_R11(r13)

	/* Restore R1/R2 so we can handle faults */
	ld	r1, PACA_KVM_HOST_R1(r13)
	ld	r2, PACA_KVM_HOST_R2(r13)

	/* Save guest PC and MSR in GPRs */
	mfsrr0	r3
	mfsrr1	r4

	/* Get scratch'ed off registers */
	mfspr	r9, SPRN_SPRG_SCRATCH0
	std	r9, PACA_KVM_R13(r13)

	ld	r8, PACA_KVM_SCRATCH0(r13)
	std	r8, PACA_KVM_R12(r13)

	lwz	r7, PACA_KVM_SCRATCH1(r13)
	stw	r7, PACA_KVM_CR(r13)

	/* Save more register state  */

	mfxer	r6
	stw	r6, PACA_KVM_XER(r13)

	mfdar	r5
	mfdsisr	r6

	/*
	 * In order for us to easily get the last instruction,
	 * we got the #vmexit at, we exploit the fact that the
	 * virtual layout is still the same here, so we can just
	 * ld from the guest's PC address
	 */

	/* We only load the last instruction when it's safe */
	cmpwi	r12, BOOK3S_INTERRUPT_DATA_STORAGE
	beq	ld_last_inst
	cmpwi	r12, BOOK3S_INTERRUPT_PROGRAM
	beq	ld_last_inst

	b	no_ld_last_inst

ld_last_inst:
	/* Save off the guest instruction we're at */

	/* Set guest mode to 'jump over instruction' so if lwz faults
	 * we'll just continue at the next IP. */
	li	r9, KVM_GUEST_MODE_SKIP
	stb	r9, PACA_KVM_IN_GUEST(r13)

	/*    1) enable paging for data */
	mfmsr	r9
	ori	r11, r9, MSR_DR			/* Enable paging for data */
	mtmsr	r11
	/*    2) fetch the instruction */
	li	r0, KVM_INST_FETCH_FAILED	/* In case lwz faults */
	lwz	r0, 0(r3)
	/*    3) disable paging again */
	mtmsr	r9

no_ld_last_inst:

	/* Unset guest mode */
	li	r9, KVM_GUEST_MODE_NONE
	stb	r9, PACA_KVM_IN_GUEST(r13)

	/* Restore bolted entries from the shadow and fix it along the way */
	/* Restore bolted entries from the shadow and fix it along the way */


	/* We don't store anything in entry 0, so we don't need to take care of it */
	/* We don't store anything in entry 0, so we don't need to take care of it */
@@ -275,28 +164,4 @@ no_ld_last_inst:


slb_do_exit:
slb_do_exit:


	/* Register usage at this point:
.endm
	 *
	 * R0         = guest last inst
	 * R1         = host R1
	 * R2         = host R2
	 * R3         = guest PC
	 * R4         = guest MSR
	 * R5         = guest DAR
	 * R6         = guest DSISR
	 * R12        = exit handler id
	 * R13        = PACA
	 * PACA.KVM.* = guest *
	 *
	 */

	/* RFI into the highmem handler */
	mfmsr	r7
	ori	r7, r7, MSR_IR|MSR_DR|MSR_RI	/* Enable paging */
	mtsrr1	r7
	ld	r8, PACA_KVM_VMHANDLER(r13)	/* Highmem handler address */
	mtsrr0	r8

	RFI
kvmppc_handler_trampoline_exit_end:
+1 −1
Original line number Original line Diff line number Diff line
@@ -248,4 +248,4 @@ kvmppc_trampoline_lowmem:
kvmppc_trampoline_enter:
kvmppc_trampoline_enter:
	.long kvmppc_handler_trampoline_enter - _stext
	.long kvmppc_handler_trampoline_enter - _stext


#include "book3s_64_slb.S"
#include "book3s_segment.S"