linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
To: linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH v5 05/33] KVM: PPC: Book3S HV: Extract PMU save/restore operations as C-callable functions
Date: Mon, 8 Oct 2018 13:46:14 +0530	[thread overview]
Message-ID: <be854dce-87cd-571b-32eb-64475cdd84a9@linux.vnet.ibm.com> (raw)
In-Reply-To: <1538976679-1363-6-git-send-email-paulus@ozlabs.org>



On Monday 08 October 2018 11:00 AM, Paul Mackerras wrote:
> This pulls out the assembler code that is responsible for saving and
> restoring the PMU state for the host and guest into separate functions
> so they can be used from an alternate entry path.  The calling
> convention is made compatible with C.

Reviewed-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>

>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
> ---
>   arch/powerpc/include/asm/asm-prototypes.h |   5 +
>   arch/powerpc/kvm/book3s_hv_interrupts.S   |  95 ++++----
>   arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 363 ++++++++++++++++--------------
>   3 files changed, 253 insertions(+), 210 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/asm-prototypes.h b/arch/powerpc/include/asm/asm-prototypes.h
> index 1f4691c..024e8fc 100644
> --- a/arch/powerpc/include/asm/asm-prototypes.h
> +++ b/arch/powerpc/include/asm/asm-prototypes.h
> @@ -150,4 +150,9 @@ extern s32 patch__memset_nocache, patch__memcpy_nocache;
>
>   extern long flush_count_cache;
>
> +void kvmhv_save_host_pmu(void);
> +void kvmhv_load_host_pmu(void);
> +void kvmhv_save_guest_pmu(struct kvm_vcpu *vcpu, bool pmu_in_use);
> +void kvmhv_load_guest_pmu(struct kvm_vcpu *vcpu);
> +
>   #endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */
> diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S
> index 666b91c..a6d1001 100644
> --- a/arch/powerpc/kvm/book3s_hv_interrupts.S
> +++ b/arch/powerpc/kvm/book3s_hv_interrupts.S
> @@ -64,52 +64,7 @@ BEGIN_FTR_SECTION
>   END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
>
>   	/* Save host PMU registers */
> -BEGIN_FTR_SECTION
> -	/* Work around P8 PMAE bug */
> -	li	r3, -1
> -	clrrdi	r3, r3, 10
> -	mfspr	r8, SPRN_MMCR2
> -	mtspr	SPRN_MMCR2, r3		/* freeze all counters using MMCR2 */
> -	isync
> -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> -	li	r3, 1
> -	sldi	r3, r3, 31		/* MMCR0_FC (freeze counters) bit */
> -	mfspr	r7, SPRN_MMCR0		/* save MMCR0 */
> -	mtspr	SPRN_MMCR0, r3		/* freeze all counters, disable interrupts */
> -	mfspr	r6, SPRN_MMCRA
> -	/* Clear MMCRA in order to disable SDAR updates */
> -	li	r5, 0
> -	mtspr	SPRN_MMCRA, r5
> -	isync
> -	lbz	r5, PACA_PMCINUSE(r13)	/* is the host using the PMU? */
> -	cmpwi	r5, 0
> -	beq	31f			/* skip if not */
> -	mfspr	r5, SPRN_MMCR1
> -	mfspr	r9, SPRN_SIAR
> -	mfspr	r10, SPRN_SDAR
> -	std	r7, HSTATE_MMCR0(r13)
> -	std	r5, HSTATE_MMCR1(r13)
> -	std	r6, HSTATE_MMCRA(r13)
> -	std	r9, HSTATE_SIAR(r13)
> -	std	r10, HSTATE_SDAR(r13)
> -BEGIN_FTR_SECTION
> -	mfspr	r9, SPRN_SIER
> -	std	r8, HSTATE_MMCR2(r13)
> -	std	r9, HSTATE_SIER(r13)
> -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> -	mfspr	r3, SPRN_PMC1
> -	mfspr	r5, SPRN_PMC2
> -	mfspr	r6, SPRN_PMC3
> -	mfspr	r7, SPRN_PMC4
> -	mfspr	r8, SPRN_PMC5
> -	mfspr	r9, SPRN_PMC6
> -	stw	r3, HSTATE_PMC1(r13)
> -	stw	r5, HSTATE_PMC2(r13)
> -	stw	r6, HSTATE_PMC3(r13)
> -	stw	r7, HSTATE_PMC4(r13)
> -	stw	r8, HSTATE_PMC5(r13)
> -	stw	r9, HSTATE_PMC6(r13)
> -31:
> +	bl	kvmhv_save_host_pmu
>
>   	/*
>   	 * Put whatever is in the decrementer into the
> @@ -161,3 +116,51 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
>   	ld	r0, PPC_LR_STKOFF(r1)
>   	mtlr	r0
>   	blr
> +
> +_GLOBAL(kvmhv_save_host_pmu)
> +BEGIN_FTR_SECTION
> +	/* Work around P8 PMAE bug */
> +	li	r3, -1
> +	clrrdi	r3, r3, 10
> +	mfspr	r8, SPRN_MMCR2
> +	mtspr	SPRN_MMCR2, r3		/* freeze all counters using MMCR2 */
> +	isync
> +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> +	li	r3, 1
> +	sldi	r3, r3, 31		/* MMCR0_FC (freeze counters) bit */
> +	mfspr	r7, SPRN_MMCR0		/* save MMCR0 */
> +	mtspr	SPRN_MMCR0, r3		/* freeze all counters, disable interrupts */
> +	mfspr	r6, SPRN_MMCRA
> +	/* Clear MMCRA in order to disable SDAR updates */
> +	li	r5, 0
> +	mtspr	SPRN_MMCRA, r5
> +	isync
> +	lbz	r5, PACA_PMCINUSE(r13)	/* is the host using the PMU? */
> +	cmpwi	r5, 0
> +	beq	31f			/* skip if not */
> +	mfspr	r5, SPRN_MMCR1
> +	mfspr	r9, SPRN_SIAR
> +	mfspr	r10, SPRN_SDAR
> +	std	r7, HSTATE_MMCR0(r13)
> +	std	r5, HSTATE_MMCR1(r13)
> +	std	r6, HSTATE_MMCRA(r13)
> +	std	r9, HSTATE_SIAR(r13)
> +	std	r10, HSTATE_SDAR(r13)
> +BEGIN_FTR_SECTION
> +	mfspr	r9, SPRN_SIER
> +	std	r8, HSTATE_MMCR2(r13)
> +	std	r9, HSTATE_SIER(r13)
> +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> +	mfspr	r3, SPRN_PMC1
> +	mfspr	r5, SPRN_PMC2
> +	mfspr	r6, SPRN_PMC3
> +	mfspr	r7, SPRN_PMC4
> +	mfspr	r8, SPRN_PMC5
> +	mfspr	r9, SPRN_PMC6
> +	stw	r3, HSTATE_PMC1(r13)
> +	stw	r5, HSTATE_PMC2(r13)
> +	stw	r6, HSTATE_PMC3(r13)
> +	stw	r7, HSTATE_PMC4(r13)
> +	stw	r8, HSTATE_PMC5(r13)
> +	stw	r9, HSTATE_PMC6(r13)
> +31:	blr
> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index 6752da1..5b2ae34 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -28,6 +28,7 @@
>   #include <asm/exception-64s.h>
>   #include <asm/kvm_book3s_asm.h>
>   #include <asm/book3s/64/mmu-hash.h>
> +#include <asm/export.h>
>   #include <asm/tm.h>
>   #include <asm/opal.h>
>   #include <asm/xive-regs.h>
> @@ -113,45 +114,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
>   	mtspr	SPRN_SPRG_VDSO_WRITE,r3
>
>   	/* Reload the host's PMU registers */
> -	lbz	r4, PACA_PMCINUSE(r13) /* is the host using the PMU? */
> -	cmpwi	r4, 0
> -	beq	23f			/* skip if not */
> -BEGIN_FTR_SECTION
> -	ld	r3, HSTATE_MMCR0(r13)
> -	andi.	r4, r3, MMCR0_PMAO_SYNC | MMCR0_PMAO
> -	cmpwi	r4, MMCR0_PMAO
> -	beql	kvmppc_fix_pmao
> -END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG)
> -	lwz	r3, HSTATE_PMC1(r13)
> -	lwz	r4, HSTATE_PMC2(r13)
> -	lwz	r5, HSTATE_PMC3(r13)
> -	lwz	r6, HSTATE_PMC4(r13)
> -	lwz	r8, HSTATE_PMC5(r13)
> -	lwz	r9, HSTATE_PMC6(r13)
> -	mtspr	SPRN_PMC1, r3
> -	mtspr	SPRN_PMC2, r4
> -	mtspr	SPRN_PMC3, r5
> -	mtspr	SPRN_PMC4, r6
> -	mtspr	SPRN_PMC5, r8
> -	mtspr	SPRN_PMC6, r9
> -	ld	r3, HSTATE_MMCR0(r13)
> -	ld	r4, HSTATE_MMCR1(r13)
> -	ld	r5, HSTATE_MMCRA(r13)
> -	ld	r6, HSTATE_SIAR(r13)
> -	ld	r7, HSTATE_SDAR(r13)
> -	mtspr	SPRN_MMCR1, r4
> -	mtspr	SPRN_MMCRA, r5
> -	mtspr	SPRN_SIAR, r6
> -	mtspr	SPRN_SDAR, r7
> -BEGIN_FTR_SECTION
> -	ld	r8, HSTATE_MMCR2(r13)
> -	ld	r9, HSTATE_SIER(r13)
> -	mtspr	SPRN_MMCR2, r8
> -	mtspr	SPRN_SIER, r9
> -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> -	mtspr	SPRN_MMCR0, r3
> -	isync
> -23:
> +	bl	kvmhv_load_host_pmu
>
>   	/*
>   	 * Reload DEC.  HDEC interrupts were disabled when
> @@ -805,57 +768,12 @@ END_FTR_SECTION(CPU_FTR_TM | CPU_FTR_P9_TM_HV_ASSIST, 0)
>   91:
>   #endif
>
> -	/* Load guest PMU registers */
> -	/* R4 is live here (vcpu pointer) */
> -	li	r3, 1
> -	sldi	r3, r3, 31		/* MMCR0_FC (freeze counters) bit */
> -	mtspr	SPRN_MMCR0, r3		/* freeze all counters, disable ints */
> -	isync
> -BEGIN_FTR_SECTION
> -	ld	r3, VCPU_MMCR(r4)
> -	andi.	r5, r3, MMCR0_PMAO_SYNC | MMCR0_PMAO
> -	cmpwi	r5, MMCR0_PMAO
> -	beql	kvmppc_fix_pmao
> -END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG)
> -	lwz	r3, VCPU_PMC(r4)	/* always load up guest PMU registers */
> -	lwz	r5, VCPU_PMC + 4(r4)	/* to prevent information leak */
> -	lwz	r6, VCPU_PMC + 8(r4)
> -	lwz	r7, VCPU_PMC + 12(r4)
> -	lwz	r8, VCPU_PMC + 16(r4)
> -	lwz	r9, VCPU_PMC + 20(r4)
> -	mtspr	SPRN_PMC1, r3
> -	mtspr	SPRN_PMC2, r5
> -	mtspr	SPRN_PMC3, r6
> -	mtspr	SPRN_PMC4, r7
> -	mtspr	SPRN_PMC5, r8
> -	mtspr	SPRN_PMC6, r9
> -	ld	r3, VCPU_MMCR(r4)
> -	ld	r5, VCPU_MMCR + 8(r4)
> -	ld	r6, VCPU_MMCR + 16(r4)
> -	ld	r7, VCPU_SIAR(r4)
> -	ld	r8, VCPU_SDAR(r4)
> -	mtspr	SPRN_MMCR1, r5
> -	mtspr	SPRN_MMCRA, r6
> -	mtspr	SPRN_SIAR, r7
> -	mtspr	SPRN_SDAR, r8
> -BEGIN_FTR_SECTION
> -	ld	r5, VCPU_MMCR + 24(r4)
> -	ld	r6, VCPU_SIER(r4)
> -	mtspr	SPRN_MMCR2, r5
> -	mtspr	SPRN_SIER, r6
> -BEGIN_FTR_SECTION_NESTED(96)
> -	lwz	r7, VCPU_PMC + 24(r4)
> -	lwz	r8, VCPU_PMC + 28(r4)
> -	ld	r9, VCPU_MMCR + 32(r4)
> -	mtspr	SPRN_SPMC1, r7
> -	mtspr	SPRN_SPMC2, r8
> -	mtspr	SPRN_MMCRS, r9
> -END_FTR_SECTION_NESTED(CPU_FTR_ARCH_300, 0, 96)
> -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> -	mtspr	SPRN_MMCR0, r3
> -	isync
> +	/* Load guest PMU registers; r4 = vcpu pointer here */
> +	mr	r3, r4
> +	bl	kvmhv_load_guest_pmu
>
>   	/* Load up FP, VMX and VSX registers */
> +	ld	r4, HSTATE_KVM_VCPU(r13)
>   	bl	kvmppc_load_fp
>
>   	ld	r14, VCPU_GPR(R14)(r4)
> @@ -1766,83 +1684,12 @@ END_FTR_SECTION(CPU_FTR_TM | CPU_FTR_P9_TM_HV_ASSIST, 0)
>   25:
>   	/* Save PMU registers if requested */
>   	/* r8 and cr0.eq are live here */
> -BEGIN_FTR_SECTION
> -	/*
> -	 * POWER8 seems to have a hardware bug where setting
> -	 * MMCR0[PMAE] along with MMCR0[PMC1CE] and/or MMCR0[PMCjCE]
> -	 * when some counters are already negative doesn't seem
> -	 * to cause a performance monitor alert (and hence interrupt).
> -	 * The effect of this is that when saving the PMU state,
> -	 * if there is no PMU alert pending when we read MMCR0
> -	 * before freezing the counters, but one becomes pending
> -	 * before we read the counters, we lose it.
> -	 * To work around this, we need a way to freeze the counters
> -	 * before reading MMCR0.  Normally, freezing the counters
> -	 * is done by writing MMCR0 (to set MMCR0[FC]) which
> -	 * unavoidably writes MMCR0[PMA0] as well.  On POWER8,
> -	 * we can also freeze the counters using MMCR2, by writing
> -	 * 1s to all the counter freeze condition bits (there are
> -	 * 9 bits each for 6 counters).
> -	 */
> -	li	r3, -1			/* set all freeze bits */
> -	clrrdi	r3, r3, 10
> -	mfspr	r10, SPRN_MMCR2
> -	mtspr	SPRN_MMCR2, r3
> -	isync
> -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> -	li	r3, 1
> -	sldi	r3, r3, 31		/* MMCR0_FC (freeze counters) bit */
> -	mfspr	r4, SPRN_MMCR0		/* save MMCR0 */
> -	mtspr	SPRN_MMCR0, r3		/* freeze all counters, disable ints */
> -	mfspr	r6, SPRN_MMCRA
> -	/* Clear MMCRA in order to disable SDAR updates */
> -	li	r7, 0
> -	mtspr	SPRN_MMCRA, r7
> -	isync
> +	mr	r3, r9
> +	li	r4, 1
>   	beq	21f			/* if no VPA, save PMU stuff anyway */
> -	lbz	r7, LPPACA_PMCINUSE(r8)
> -	cmpwi	r7, 0			/* did they ask for PMU stuff to be saved? */
> -	bne	21f
> -	std	r3, VCPU_MMCR(r9)	/* if not, set saved MMCR0 to FC */
> -	b	22f
> -21:	mfspr	r5, SPRN_MMCR1
> -	mfspr	r7, SPRN_SIAR
> -	mfspr	r8, SPRN_SDAR
> -	std	r4, VCPU_MMCR(r9)
> -	std	r5, VCPU_MMCR + 8(r9)
> -	std	r6, VCPU_MMCR + 16(r9)
> -BEGIN_FTR_SECTION
> -	std	r10, VCPU_MMCR + 24(r9)
> -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> -	std	r7, VCPU_SIAR(r9)
> -	std	r8, VCPU_SDAR(r9)
> -	mfspr	r3, SPRN_PMC1
> -	mfspr	r4, SPRN_PMC2
> -	mfspr	r5, SPRN_PMC3
> -	mfspr	r6, SPRN_PMC4
> -	mfspr	r7, SPRN_PMC5
> -	mfspr	r8, SPRN_PMC6
> -	stw	r3, VCPU_PMC(r9)
> -	stw	r4, VCPU_PMC + 4(r9)
> -	stw	r5, VCPU_PMC + 8(r9)
> -	stw	r6, VCPU_PMC + 12(r9)
> -	stw	r7, VCPU_PMC + 16(r9)
> -	stw	r8, VCPU_PMC + 20(r9)
> -BEGIN_FTR_SECTION
> -	mfspr	r5, SPRN_SIER
> -	std	r5, VCPU_SIER(r9)
> -BEGIN_FTR_SECTION_NESTED(96)
> -	mfspr	r6, SPRN_SPMC1
> -	mfspr	r7, SPRN_SPMC2
> -	mfspr	r8, SPRN_MMCRS
> -	stw	r6, VCPU_PMC + 24(r9)
> -	stw	r7, VCPU_PMC + 28(r9)
> -	std	r8, VCPU_MMCR + 32(r9)
> -	lis	r4, 0x8000
> -	mtspr	SPRN_MMCRS, r4
> -END_FTR_SECTION_NESTED(CPU_FTR_ARCH_300, 0, 96)
> -END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> -22:
> +	lbz	r4, LPPACA_PMCINUSE(r8)
> +21:	bl	kvmhv_save_guest_pmu
> +	ld	r9, HSTATE_KVM_VCPU(r13)
>
>   	/* Restore host values of some registers */
>   BEGIN_FTR_SECTION
> @@ -3388,6 +3235,194 @@ kvmppc_msr_interrupt:
>   	blr
>
>   /*
> + * Load up guest PMU state.  R3 points to the vcpu struct.
> + */
> +_GLOBAL(kvmhv_load_guest_pmu)
> +EXPORT_SYMBOL_GPL(kvmhv_load_guest_pmu)
> +	mr	r4, r3
> +	mflr	r0
> +	li	r3, 1
> +	sldi	r3, r3, 31		/* MMCR0_FC (freeze counters) bit */
> +	mtspr	SPRN_MMCR0, r3		/* freeze all counters, disable ints */
> +	isync
> +BEGIN_FTR_SECTION
> +	ld	r3, VCPU_MMCR(r4)
> +	andi.	r5, r3, MMCR0_PMAO_SYNC | MMCR0_PMAO
> +	cmpwi	r5, MMCR0_PMAO
> +	beql	kvmppc_fix_pmao
> +END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG)
> +	lwz	r3, VCPU_PMC(r4)	/* always load up guest PMU registers */
> +	lwz	r5, VCPU_PMC + 4(r4)	/* to prevent information leak */
> +	lwz	r6, VCPU_PMC + 8(r4)
> +	lwz	r7, VCPU_PMC + 12(r4)
> +	lwz	r8, VCPU_PMC + 16(r4)
> +	lwz	r9, VCPU_PMC + 20(r4)
> +	mtspr	SPRN_PMC1, r3
> +	mtspr	SPRN_PMC2, r5
> +	mtspr	SPRN_PMC3, r6
> +	mtspr	SPRN_PMC4, r7
> +	mtspr	SPRN_PMC5, r8
> +	mtspr	SPRN_PMC6, r9
> +	ld	r3, VCPU_MMCR(r4)
> +	ld	r5, VCPU_MMCR + 8(r4)
> +	ld	r6, VCPU_MMCR + 16(r4)
> +	ld	r7, VCPU_SIAR(r4)
> +	ld	r8, VCPU_SDAR(r4)
> +	mtspr	SPRN_MMCR1, r5
> +	mtspr	SPRN_MMCRA, r6
> +	mtspr	SPRN_SIAR, r7
> +	mtspr	SPRN_SDAR, r8
> +BEGIN_FTR_SECTION
> +	ld	r5, VCPU_MMCR + 24(r4)
> +	ld	r6, VCPU_SIER(r4)
> +	mtspr	SPRN_MMCR2, r5
> +	mtspr	SPRN_SIER, r6
> +BEGIN_FTR_SECTION_NESTED(96)
> +	lwz	r7, VCPU_PMC + 24(r4)
> +	lwz	r8, VCPU_PMC + 28(r4)
> +	ld	r9, VCPU_MMCR + 32(r4)
> +	mtspr	SPRN_SPMC1, r7
> +	mtspr	SPRN_SPMC2, r8
> +	mtspr	SPRN_MMCRS, r9
> +END_FTR_SECTION_NESTED(CPU_FTR_ARCH_300, 0, 96)
> +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> +	mtspr	SPRN_MMCR0, r3
> +	isync
> +	mtlr	r0
> +	blr
> +
> +/*
> + * Reload host PMU state saved in the PACA by kvmhv_save_host_pmu.
> + */
> +_GLOBAL(kvmhv_load_host_pmu)
> +EXPORT_SYMBOL_GPL(kvmhv_load_host_pmu)
> +	mflr	r0
> +	lbz	r4, PACA_PMCINUSE(r13) /* is the host using the PMU? */
> +	cmpwi	r4, 0
> +	beq	23f			/* skip if not */
> +BEGIN_FTR_SECTION
> +	ld	r3, HSTATE_MMCR0(r13)
> +	andi.	r4, r3, MMCR0_PMAO_SYNC | MMCR0_PMAO
> +	cmpwi	r4, MMCR0_PMAO
> +	beql	kvmppc_fix_pmao
> +END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG)
> +	lwz	r3, HSTATE_PMC1(r13)
> +	lwz	r4, HSTATE_PMC2(r13)
> +	lwz	r5, HSTATE_PMC3(r13)
> +	lwz	r6, HSTATE_PMC4(r13)
> +	lwz	r8, HSTATE_PMC5(r13)
> +	lwz	r9, HSTATE_PMC6(r13)
> +	mtspr	SPRN_PMC1, r3
> +	mtspr	SPRN_PMC2, r4
> +	mtspr	SPRN_PMC3, r5
> +	mtspr	SPRN_PMC4, r6
> +	mtspr	SPRN_PMC5, r8
> +	mtspr	SPRN_PMC6, r9
> +	ld	r3, HSTATE_MMCR0(r13)
> +	ld	r4, HSTATE_MMCR1(r13)
> +	ld	r5, HSTATE_MMCRA(r13)
> +	ld	r6, HSTATE_SIAR(r13)
> +	ld	r7, HSTATE_SDAR(r13)
> +	mtspr	SPRN_MMCR1, r4
> +	mtspr	SPRN_MMCRA, r5
> +	mtspr	SPRN_SIAR, r6
> +	mtspr	SPRN_SDAR, r7
> +BEGIN_FTR_SECTION
> +	ld	r8, HSTATE_MMCR2(r13)
> +	ld	r9, HSTATE_SIER(r13)
> +	mtspr	SPRN_MMCR2, r8
> +	mtspr	SPRN_SIER, r9
> +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> +	mtspr	SPRN_MMCR0, r3
> +	isync
> +	mtlr	r0
> +23:	blr
> +
> +/*
> + * Save guest PMU state into the vcpu struct.
> + * r3 = vcpu, r4 = full save flag (PMU in use flag set in VPA)
> + */
> +_GLOBAL(kvmhv_save_guest_pmu)
> +EXPORT_SYMBOL_GPL(kvmhv_save_guest_pmu)
> +	mr	r9, r3
> +	mr	r8, r4
> +BEGIN_FTR_SECTION
> +	/*
> +	 * POWER8 seems to have a hardware bug where setting
> +	 * MMCR0[PMAE] along with MMCR0[PMC1CE] and/or MMCR0[PMCjCE]
> +	 * when some counters are already negative doesn't seem
> +	 * to cause a performance monitor alert (and hence interrupt).
> +	 * The effect of this is that when saving the PMU state,
> +	 * if there is no PMU alert pending when we read MMCR0
> +	 * before freezing the counters, but one becomes pending
> +	 * before we read the counters, we lose it.
> +	 * To work around this, we need a way to freeze the counters
> +	 * before reading MMCR0.  Normally, freezing the counters
> +	 * is done by writing MMCR0 (to set MMCR0[FC]) which
> +	 * unavoidably writes MMCR0[PMA0] as well.  On POWER8,
> +	 * we can also freeze the counters using MMCR2, by writing
> +	 * 1s to all the counter freeze condition bits (there are
> +	 * 9 bits each for 6 counters).
> +	 */
> +	li	r3, -1			/* set all freeze bits */
> +	clrrdi	r3, r3, 10
> +	mfspr	r10, SPRN_MMCR2
> +	mtspr	SPRN_MMCR2, r3
> +	isync
> +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> +	li	r3, 1
> +	sldi	r3, r3, 31		/* MMCR0_FC (freeze counters) bit */
> +	mfspr	r4, SPRN_MMCR0		/* save MMCR0 */
> +	mtspr	SPRN_MMCR0, r3		/* freeze all counters, disable ints */
> +	mfspr	r6, SPRN_MMCRA
> +	/* Clear MMCRA in order to disable SDAR updates */
> +	li	r7, 0
> +	mtspr	SPRN_MMCRA, r7
> +	isync
> +	cmpwi	r8, 0			/* did they ask for PMU stuff to be saved? */
> +	bne	21f
> +	std	r3, VCPU_MMCR(r9)	/* if not, set saved MMCR0 to FC */
> +	b	22f
> +21:	mfspr	r5, SPRN_MMCR1
> +	mfspr	r7, SPRN_SIAR
> +	mfspr	r8, SPRN_SDAR
> +	std	r4, VCPU_MMCR(r9)
> +	std	r5, VCPU_MMCR + 8(r9)
> +	std	r6, VCPU_MMCR + 16(r9)
> +BEGIN_FTR_SECTION
> +	std	r10, VCPU_MMCR + 24(r9)
> +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> +	std	r7, VCPU_SIAR(r9)
> +	std	r8, VCPU_SDAR(r9)
> +	mfspr	r3, SPRN_PMC1
> +	mfspr	r4, SPRN_PMC2
> +	mfspr	r5, SPRN_PMC3
> +	mfspr	r6, SPRN_PMC4
> +	mfspr	r7, SPRN_PMC5
> +	mfspr	r8, SPRN_PMC6
> +	stw	r3, VCPU_PMC(r9)
> +	stw	r4, VCPU_PMC + 4(r9)
> +	stw	r5, VCPU_PMC + 8(r9)
> +	stw	r6, VCPU_PMC + 12(r9)
> +	stw	r7, VCPU_PMC + 16(r9)
> +	stw	r8, VCPU_PMC + 20(r9)
> +BEGIN_FTR_SECTION
> +	mfspr	r5, SPRN_SIER
> +	std	r5, VCPU_SIER(r9)
> +BEGIN_FTR_SECTION_NESTED(96)
> +	mfspr	r6, SPRN_SPMC1
> +	mfspr	r7, SPRN_SPMC2
> +	mfspr	r8, SPRN_MMCRS
> +	stw	r6, VCPU_PMC + 24(r9)
> +	stw	r7, VCPU_PMC + 28(r9)
> +	std	r8, VCPU_MMCR + 32(r9)
> +	lis	r4, 0x8000
> +	mtspr	SPRN_MMCRS, r4
> +END_FTR_SECTION_NESTED(CPU_FTR_ARCH_300, 0, 96)
> +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
> +22:	blr
> +
> +/*
>    * This works around a hardware bug on POWER8E processors, where
>    * writing a 1 to the MMCR0[PMAO] bit doesn't generate a
>    * performance monitor interrupt.  Instead, when we need to have


  reply	other threads:[~2018-10-08  8:18 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-08  5:30 [PATCH v5 00/33] KVM: PPC: Book3S HV: Nested HV virtualization Paul Mackerras
2018-10-08  5:30 ` [PATCH v5 01/33] powerpc: Turn off CPU_FTR_P9_TM_HV_ASSIST in non-hypervisor mode Paul Mackerras
2018-10-08  5:30 ` [PATCH v5 02/33] KVM: PPC: Book3S: Simplify external interrupt handling Paul Mackerras
2018-10-08  5:30 ` [PATCH v5 03/33] KVM: PPC: Book3S HV: Remove left-over code in XICS-on-XIVE emulation Paul Mackerras
2018-10-08  5:30 ` [PATCH v5 04/33] KVM: PPC: Book3S HV: Move interrupt delivery on guest entry to C code Paul Mackerras
2018-10-08  5:30 ` [PATCH v5 05/33] KVM: PPC: Book3S HV: Extract PMU save/restore operations as C-callable functions Paul Mackerras
2018-10-08  8:16   ` Madhavan Srinivasan [this message]
2018-10-08  5:30 ` [PATCH v5 06/33] KVM: PPC: Book3S HV: Simplify real-mode interrupt handling Paul Mackerras
2018-10-09  0:05   ` David Gibson
2018-10-08  5:30 ` [PATCH v5 07/33] KVM: PPC: Book3S: Rework TM save/restore code and make it C-callable Paul Mackerras
2018-10-08  5:30 ` [PATCH v5 08/33] KVM: PPC: Book3S HV: Call kvmppc_handle_exit_hv() with vcore unlocked Paul Mackerras
2018-10-08  5:30 ` [PATCH v5 09/33] KVM: PPC: Book3S HV: Streamlined guest entry/exit path on P9 for radix guests Paul Mackerras
2018-10-09  0:20   ` David Gibson
2018-10-08  5:30 ` [PATCH v5 10/33] KVM: PPC: Book3S HV: Handle hypervisor instruction faults better Paul Mackerras
2018-10-08  5:30 ` [PATCH v5 11/33] KVM: PPC: Book3S HV: Add a debugfs file to dump radix mappings Paul Mackerras
2018-10-08  5:30 ` [PATCH v5 12/33] KVM: PPC: Use ccr field in pt_regs struct embedded in vcpu struct Paul Mackerras
2018-10-08  5:30 ` [PATCH v5 13/33] KVM: PPC: Book3S HV: Clear partition table entry on vm teardown Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 14/33] KVM: PPC: Book3S HV: Make kvmppc_mmu_radix_xlate process/partition table agnostic Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 15/33] KVM: PPC: Book3S HV: Refactor radix page fault handler Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 16/33] KVM: PPC: Book3S HV: Use kvmppc_unmap_pte() in kvm_unmap_radix() Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 17/33] KVM: PPC: Book3S HV: Framework and hcall stubs for nested virtualization Paul Mackerras
2018-10-08 23:30   ` David Gibson
2018-10-08  5:31 ` [PATCH v5 18/33] KVM: PPC: Book3S HV: Nested guest entry via hypercall Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 19/33] KVM: PPC: Book3S HV: Use XICS hypercalls when running as a nested hypervisor Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 20/33] KVM: PPC: Book3S HV: Handle hypercalls correctly when nested Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 21/33] KVM: PPC: Book3S HV: Handle page fault for a nested guest Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 22/33] KVM: PPC: Book3S HV: Introduce rmap to track nested guest mappings Paul Mackerras
2018-10-09  0:26   ` David Gibson
2018-10-08  5:31 ` [PATCH v5 23/33] KVM: PPC: Book3S HV: Implement H_TLB_INVALIDATE hcall Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 24/33] KVM: PPC: Book3S HV: Use hypercalls for TLB invalidation when nested Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 25/33] KVM: PPC: Book3S HV: Invalidate TLB when nested vcpu moves physical cpu Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 26/33] KVM: PPC: Book3S HV: Don't access HFSCR, LPIDR or LPCR when running nested Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 27/33] KVM: PPC: Book3S HV: Add one-reg interface to virtual PTCR register Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 28/33] KVM: PPC: Book3S HV: Sanitise hv_regs on nested guest entry Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 29/33] KVM: PPC: Book3S HV: Handle differing endianness for H_ENTER_NESTED Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 30/33] KVM: PPC: Book3S HV: Allow HV module to load without hypervisor mode Paul Mackerras
2018-10-08 23:31   ` David Gibson
2018-10-08  5:31 ` [PATCH v5 31/33] KVM: PPC: Book3S HV: Add nested shadow page tables to debugfs Paul Mackerras
2018-10-08  5:31 ` [PATCH v5 32/33] KVM: PPC: Book3S HV: Add a VM capability to enable nested virtualization Paul Mackerras
2018-10-08 23:34   ` David Gibson
2018-10-08  5:31 ` [PATCH v5 33/33] KVM: PPC: Book3S HV: Add NO_HASH flag to GET_SMMU_INFO ioctl result Paul Mackerras
2018-10-08 23:34   ` David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=be854dce-87cd-571b-32eb-64475cdd84a9@linux.vnet.ibm.com \
    --to=maddy@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).