[PATCH 2/2] powerpc/pseries/svm: Disable BHRB/EBB/PMU access

maddy maddy at linux.ibm.com
Tue Jan 7 15:08:45 AEDT 2020



On 12/27/19 10:59 AM, Sukadev Bhattiprolu wrote:
> Sukadev Bhattiprolu [sukadev at linux.ibm.com] wrote:
>> Ultravisor disables some CPU features like BHRB, EBB and PMU in
>> secure virtual machines (SVMs). Skip accessing those registers
>> in SVMs to avoid getting a Program Interrupt.
> Here is an updated patch that explicitly includes <asm/svm.h> in
> in some files to fix build errors reported by <lkp at intel.org>.
> ---
>
> From: Sukadev Bhattiprolu <sukadev at linux.vnet.ibm.com>
> Date: Thu, 16 May 2019 20:57:12 -0500
> Subject: [PATCH 2/2] powerpc/pseries/svm: Disable BHRB/EBB/PMU access
>
> Ultravisor disables some CPU features like BHRB, EBB and PMU in
> secure virtual machines (SVMs). Skip accessing those registers
> in SVMs to avoid getting a Program Interrupt.
>
> Signed-off-by: Sukadev Bhattiprolu <sukadev at linux.ibm.com>
> ---
> Changelog[v2]
> 	- [Michael Ellerman] Optimize the code using FW_FEATURE_SVM
> 	- Merged EBB/BHRB and PMU patches into one and reorganized code.
> 	- Fix some build errors reported by <lkp at intel.org>
> ---
>   arch/powerpc/kernel/cpu_setup_power.S   | 21 ++++++++++++++++
>   arch/powerpc/kernel/process.c           | 23 ++++++++++-------
>   arch/powerpc/kvm/book3s_hv.c            | 33 ++++++++++++++++---------
>   arch/powerpc/kvm/book3s_hv_rmhandlers.S | 32 +++++++++++++++---------
>   arch/powerpc/kvm/book3s_hv_tm_builtin.c | 21 ++++++++++------
>   arch/powerpc/perf/core-book3s.c         |  6 +++++
>   arch/powerpc/xmon/xmon.c                | 30 +++++++++++++---------
>   7 files changed, 114 insertions(+), 52 deletions(-)
>
> diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
> index a460298c7ddb..9e895d8db468 100644
> --- a/arch/powerpc/kernel/cpu_setup_power.S
> +++ b/arch/powerpc/kernel/cpu_setup_power.S
> @@ -206,14 +206,35 @@ __init_PMU_HV_ISA207:
>   	blr
>
>   __init_PMU:
> +#ifdef CONFIG_PPC_SVM
> +	/*
> +	 * SVM's are restricted from accessing PMU, so skip.
> +	 */
> +	mfmsr   r5
> +	rldicl  r5, r5, 64-MSR_S_LG, 62
> +	cmpwi   r5,1
> +	beq     skip1

I know all MMCR* are loaded with 0. But
it is better if PEF code load the MMCR0
with freeze bits on. I will send a separate
patch to handle in the non-svm case.

Rest looks good.
Acked-by: Madhavan Srinivasan <maddy at linux.ibm.com>

> +#endif
>   	li	r5,0
>   	mtspr	SPRN_MMCRA,r5
>   	mtspr	SPRN_MMCR0,r5
>   	mtspr	SPRN_MMCR1,r5
>   	mtspr	SPRN_MMCR2,r5
> +skip1:
>   	blr
>
>   __init_PMU_ISA207:
> +
> +#ifdef CONFIG_PPC_SVM
> +	/*
> +	 * SVM's are restricted from accessing PMU, so skip.
> +	*/
> +	mfmsr   r5
> +	rldicl  r5, r5, 64-MSR_S_LG, 62
> +	cmpwi   r5,1
> +	beq     skip2
> +#endif
>   	li	r5,0
>   	mtspr	SPRN_MMCRS,r5
> +skip2:
>   	blr
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index 639ceae7da9d..83c7c4119305 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -64,6 +64,7 @@
>   #include <asm/asm-prototypes.h>
>   #include <asm/stacktrace.h>
>   #include <asm/hw_breakpoint.h>
> +#include <asm/svm.h>
>
>   #include <linux/kprobes.h>
>   #include <linux/kdebug.h>
> @@ -1059,9 +1060,11 @@ static inline void save_sprs(struct thread_struct *t)
>   		t->dscr = mfspr(SPRN_DSCR);
>
>   	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
> -		t->bescr = mfspr(SPRN_BESCR);
> -		t->ebbhr = mfspr(SPRN_EBBHR);
> -		t->ebbrr = mfspr(SPRN_EBBRR);
> +		if (!is_secure_guest()) {
> +			t->bescr = mfspr(SPRN_BESCR);
> +			t->ebbhr = mfspr(SPRN_EBBHR);
> +			t->ebbrr = mfspr(SPRN_EBBRR);
> +		}
>
>   		t->fscr = mfspr(SPRN_FSCR);
>
> @@ -1097,12 +1100,14 @@ static inline void restore_sprs(struct thread_struct *old_thread,
>   	}
>
>   	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
> -		if (old_thread->bescr != new_thread->bescr)
> -			mtspr(SPRN_BESCR, new_thread->bescr);
> -		if (old_thread->ebbhr != new_thread->ebbhr)
> -			mtspr(SPRN_EBBHR, new_thread->ebbhr);
> -		if (old_thread->ebbrr != new_thread->ebbrr)
> -			mtspr(SPRN_EBBRR, new_thread->ebbrr);
> +		if (!is_secure_guest()) {
> +			if (old_thread->bescr != new_thread->bescr)
> +				mtspr(SPRN_BESCR, new_thread->bescr);
> +			if (old_thread->ebbhr != new_thread->ebbhr)
> +				mtspr(SPRN_EBBHR, new_thread->ebbhr);
> +			if (old_thread->ebbrr != new_thread->ebbrr)
> +				mtspr(SPRN_EBBRR, new_thread->ebbrr);
> +		}
>
>   		if (old_thread->fscr != new_thread->fscr)
>   			mtspr(SPRN_FSCR, new_thread->fscr);
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 709cf1fd4cf4..29a2640108d1 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -42,6 +42,7 @@
>   #include <linux/module.h>
>   #include <linux/compiler.h>
>   #include <linux/of.h>
> +#include <asm/svm.h>
>
>   #include <asm/ftrace.h>
>   #include <asm/reg.h>
> @@ -3568,9 +3569,11 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
>   	mtspr(SPRN_PSPB, vcpu->arch.pspb);
>   	mtspr(SPRN_FSCR, vcpu->arch.fscr);
>   	mtspr(SPRN_TAR, vcpu->arch.tar);
> -	mtspr(SPRN_EBBHR, vcpu->arch.ebbhr);
> -	mtspr(SPRN_EBBRR, vcpu->arch.ebbrr);
> -	mtspr(SPRN_BESCR, vcpu->arch.bescr);
> +	if (!is_secure_guest()) {
> +		mtspr(SPRN_EBBHR, vcpu->arch.ebbhr);
> +		mtspr(SPRN_EBBRR, vcpu->arch.ebbrr);
> +		mtspr(SPRN_BESCR, vcpu->arch.bescr);
> +	}
>   	mtspr(SPRN_WORT, vcpu->arch.wort);
>   	mtspr(SPRN_TIDR, vcpu->arch.tid);
>   	mtspr(SPRN_DAR, vcpu->arch.shregs.dar);
> @@ -3641,9 +3644,11 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
>   	vcpu->arch.pspb = mfspr(SPRN_PSPB);
>   	vcpu->arch.fscr = mfspr(SPRN_FSCR);
>   	vcpu->arch.tar = mfspr(SPRN_TAR);
> -	vcpu->arch.ebbhr = mfspr(SPRN_EBBHR);
> -	vcpu->arch.ebbrr = mfspr(SPRN_EBBRR);
> -	vcpu->arch.bescr = mfspr(SPRN_BESCR);
> +	if (!is_secure_guest()) {
> +		vcpu->arch.ebbhr = mfspr(SPRN_EBBHR);
> +		vcpu->arch.ebbrr = mfspr(SPRN_EBBRR);
> +		vcpu->arch.bescr = mfspr(SPRN_BESCR);
> +	}
>   	vcpu->arch.wort = mfspr(SPRN_WORT);
>   	vcpu->arch.tid = mfspr(SPRN_TIDR);
>   	vcpu->arch.amr = mfspr(SPRN_AMR);
> @@ -4272,9 +4277,11 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
>
>   	/* Save userspace EBB and other register values */
>   	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
> -		ebb_regs[0] = mfspr(SPRN_EBBHR);
> -		ebb_regs[1] = mfspr(SPRN_EBBRR);
> -		ebb_regs[2] = mfspr(SPRN_BESCR);
> +		if (!is_secure_guest()) {
> +			ebb_regs[0] = mfspr(SPRN_EBBHR);
> +			ebb_regs[1] = mfspr(SPRN_EBBRR);
> +			ebb_regs[2] = mfspr(SPRN_BESCR);
> +		}
>   		user_tar = mfspr(SPRN_TAR);
>   	}
>   	user_vrsave = mfspr(SPRN_VRSAVE);
> @@ -4320,9 +4327,11 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
>
>   	/* Restore userspace EBB and other register values */
>   	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
> -		mtspr(SPRN_EBBHR, ebb_regs[0]);
> -		mtspr(SPRN_EBBRR, ebb_regs[1]);
> -		mtspr(SPRN_BESCR, ebb_regs[2]);
> +		if (!is_secure_guest()) {
> +			mtspr(SPRN_EBBHR, ebb_regs[0]);
> +			mtspr(SPRN_EBBRR, ebb_regs[1]);
> +			mtspr(SPRN_BESCR, ebb_regs[2]);
> +		}
>   		mtspr(SPRN_TAR, user_tar);
>   		mtspr(SPRN_FSCR, current->thread.fscr);
>   	}
> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index faebcbb8c4db..7cc73c832482 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -810,15 +810,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
>   	mtspr	SPRN_CIABR, r7
>   	mtspr	SPRN_TAR, r8
>   	ld	r5, VCPU_IC(r4)
> -	ld	r8, VCPU_EBBHR(r4)
>   	mtspr	SPRN_IC, r5
> -	mtspr	SPRN_EBBHR, r8
> -	ld	r5, VCPU_EBBRR(r4)
> -	ld	r6, VCPU_BESCR(r4)
> +
> +BEGIN_FTR_SECTION
> +	ld	r5, VCPU_EBBHR(r4)
> +	ld	r6, VCPU_EBBRR(r4)
> +	ld	r7, VCPU_BESCR(r4)
> +	mtspr	SPRN_EBBHR, r5
> +	mtspr	SPRN_EBBRR, r6
> +	mtspr	SPRN_BESCR, r7
> +END_FW_FTR_SECTION_IFCLR(FW_FEATURE_SVM)
> +
>   	lwz	r7, VCPU_GUEST_PID(r4)
>   	ld	r8, VCPU_WORT(r4)
> -	mtspr	SPRN_EBBRR, r5
> -	mtspr	SPRN_BESCR, r6
>   	mtspr	SPRN_PID, r7
>   	mtspr	SPRN_WORT, r8
>   BEGIN_FTR_SECTION
> @@ -1615,14 +1619,18 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
>   	mfspr	r7, SPRN_TAR
>   	std	r5, VCPU_IC(r9)
>   	std	r7, VCPU_TAR(r9)
> -	mfspr	r8, SPRN_EBBHR
> -	std	r8, VCPU_EBBHR(r9)
> -	mfspr	r5, SPRN_EBBRR
> -	mfspr	r6, SPRN_BESCR
> +
> +BEGIN_FTR_SECTION
> +	mfspr	r5, SPRN_EBBHR
> +	mfspr	r6, SPRN_EBBRR
> +	mfspr	r7, SPRN_BESCR
> +	std	r5, VCPU_EBBHR(r9)
> +	std	r6, VCPU_EBBRR(r9)
> +	std	r7, VCPU_BESCR(r9)
> +END_FW_FTR_SECTION_IFCLR(FW_FEATURE_SVM)
> +
>   	mfspr	r7, SPRN_PID
>   	mfspr	r8, SPRN_WORT
> -	std	r5, VCPU_EBBRR(r9)
> -	std	r6, VCPU_BESCR(r9)
>   	stw	r7, VCPU_GUEST_PID(r9)
>   	std	r8, VCPU_WORT(r9)
>   BEGIN_FTR_SECTION
> diff --git a/arch/powerpc/kvm/book3s_hv_tm_builtin.c b/arch/powerpc/kvm/book3s_hv_tm_builtin.c
> index 217246279dfa..46257a464f99 100644
> --- a/arch/powerpc/kvm/book3s_hv_tm_builtin.c
> +++ b/arch/powerpc/kvm/book3s_hv_tm_builtin.c
> @@ -10,6 +10,7 @@
>   #include <asm/kvm_book3s_64.h>
>   #include <asm/reg.h>
>   #include <asm/ppc-opcode.h>
> +#include <asm/svm.h>
>
>   /*
>    * This handles the cases where the guest is in real suspend mode
> @@ -45,14 +46,18 @@ int kvmhv_p9_tm_emulation_early(struct kvm_vcpu *vcpu)
>   		if (!(vcpu->arch.hfscr & HFSCR_EBB) ||
>   		    ((msr & MSR_PR) && !(mfspr(SPRN_FSCR) & FSCR_EBB)))
>   			return 0;
> -		bescr = mfspr(SPRN_BESCR);
> -		/* expect to see a S->T transition requested */
> -		if (((bescr >> 30) & 3) != 2)
> -			return 0;
> -		bescr &= ~BESCR_GE;
> -		if (instr & (1 << 11))
> -			bescr |= BESCR_GE;
> -		mtspr(SPRN_BESCR, bescr);
> +
> +		if (!is_secure_guest()) {
> +			bescr = mfspr(SPRN_BESCR);
> +			/* expect to see a S->T transition requested */
> +			if (((bescr >> 30) & 3) != 2)
> +				return 0;
> +			bescr &= ~BESCR_GE;
> +			if (instr & (1 << 11))
> +				bescr |= BESCR_GE;
> +			mtspr(SPRN_BESCR, bescr);
> +		}
> +
>   		msr = (msr & ~MSR_TS_MASK) | MSR_TS_T;
>   		vcpu->arch.shregs.msr = msr;
>   		vcpu->arch.cfar = vcpu->arch.regs.nip - 4;
> diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
> index ca92e01d0bd1..52384b4c2bd6 100644
> --- a/arch/powerpc/perf/core-book3s.c
> +++ b/arch/powerpc/perf/core-book3s.c
> @@ -17,6 +17,7 @@
>   #include <asm/firmware.h>
>   #include <asm/ptrace.h>
>   #include <asm/code-patching.h>
> +#include <asm/svm.h>
>
>   #ifdef CONFIG_PPC64
>   #include "internal.h"
> @@ -813,6 +814,11 @@ void perf_event_print_debug(void)
>   		return;
>   	}
>
> +	if (is_secure_guest()) {
> +		pr_info("Performance monitor access disabled in SVM.\n");
> +		return;
> +	}
> +
>   	if (!ppmu->n_counter)
>   		return;
>
> diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
> index d83364ebc5c5..35fd3edb1949 100644
> --- a/arch/powerpc/xmon/xmon.c
> +++ b/arch/powerpc/xmon/xmon.c
> @@ -53,6 +53,7 @@
>   #include <asm/firmware.h>
>   #include <asm/code-patching.h>
>   #include <asm/sections.h>
> +#include <asm/svm.h>
>
>   #ifdef CONFIG_PPC64
>   #include <asm/hvcall.h>
> @@ -1861,17 +1862,24 @@ static void dump_207_sprs(void)
>   			mfspr(SPRN_TEXASR));
>   	}
>
> -	printf("mmcr0  = %.16lx  mmcr1 = %.16lx mmcr2  = %.16lx\n",
> -		mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2));
> -	printf("pmc1   = %.8lx pmc2 = %.8lx  pmc3 = %.8lx  pmc4   = %.8lx\n",
> -		mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
> -		mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
> -	printf("mmcra  = %.16lx   siar = %.16lx pmc5   = %.8lx\n",
> -		mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
> -	printf("sdar   = %.16lx   sier = %.16lx pmc6   = %.8lx\n",
> -		mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
> -	printf("ebbhr  = %.16lx  ebbrr = %.16lx bescr  = %.16lx\n",
> -		mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
> +	if (!is_secure_guest()) {
> +		printf("mmcr0  = %.16lx  mmcr1 = %.16lx mmcr2  = %.16lx\n",
> +			mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1),
> +			mfspr(SPRN_MMCR2));
> +		printf("pmc1   = %.8lx pmc2 = %.8lx  pmc3 = %.8lx  pmc4   = %.8lx\n",
> +			mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
> +			mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
> +		printf("mmcra  = %.16lx   siar = %.16lx pmc5   = %.8lx\n",
> +			mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
> +		printf("sdar   = %.16lx   sier = %.16lx pmc6   = %.8lx\n",
> +			mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
> +
> +		printf("ebbhr  = %.16lx  ebbrr = %.16lx bescr  = %.16lx\n",
> +			mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR),
> +			mfspr(SPRN_BESCR));
> +	}
> +
> +
>   	printf("iamr   = %.16lx\n", mfspr(SPRN_IAMR));
>
>   	if (!(msr & MSR_HV))



More information about the Linuxppc-dev mailing list