diff mbox series

[08/13] KVM: PPC: Ultravisor: fix mtspr and mfspr

Message ID 1548172784-27414-9-git-send-email-linuxram@us.ibm.com
State Changes Requested
Headers show
Series KVM: PPC: Paravirtualize KVM to support Ultravisor | expand

Commit Message

Ram Pai Jan. 22, 2019, 3:59 p.m. UTC
fix mtspr and mfspr to conditionally  make ucalls if the target register
is previleged.

Signed-off-by: Ram Pai <linuxram@us.ibm.com>
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/reg.h        | 30 ++++++++++++++----
 arch/powerpc/include/asm/ucall-api.h  |  8 ++++-
 arch/powerpc/kernel/paca.c            |  4 +--
 arch/powerpc/oprofile/op_model_pa6t.c |  4 +--
 arch/powerpc/perf/core-book3s.c       |  8 ++---
 arch/powerpc/xmon/xmon.c              | 58 +++++++++++++++++++----------------
 6 files changed, 70 insertions(+), 42 deletions(-)
diff mbox series

Patch

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 3c3588a..eab2c19 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1350,20 +1350,38 @@ 
 #define __MTMSR		"mtmsr"
 #endif
 
+#include <asm/ucall-api.h>
+
 static inline void mtmsr_isync(unsigned long val)
 {
 	asm volatile(__MTMSR " %0; " ASM_FTR_IFCLR("isync", "nop", %1) : :
 			"r" (val), "i" (CPU_FTR_ARCH_206) : "memory");
 }
 
-#define mfspr(rn)	({unsigned long rval; \
-			asm volatile("mfspr %0," __stringify(rn) \
-				: "=r" (rval)); rval;})
+#ifndef mfspr
+static inline __attribute__((always_inline))
+u64 mfspr(const unsigned int spr)
+{
+	u64 val;
+	if (is_uv_register(spr))
+		uv_restricted_spr_read(spr, &val);
+	else
+		asm volatile("mfspr %0,%1" : "=r"(val) : "i"(spr) : "memory");
+	return val;
+}
+#endif
+
 #ifndef mtspr
-#define mtspr(rn, v)	asm volatile("mtspr " __stringify(rn) ",%0" : \
-				     : "r" ((unsigned long)(v)) \
-				     : "memory")
+static inline __attribute__((always_inline))
+void mtspr(const unsigned int rn, unsigned long v)
+{
+	if (is_uv_register(rn))
+		uv_restricted_spr_write(rn, (u64)v);
+	else
+		asm volatile("mtspr %0,%1" : : "i"(rn), "r"(v) : "memory");
+}
 #endif
+
 #define wrtspr(rn)	asm volatile("mtspr " __stringify(rn) ",0" : \
 				     : : "memory")
 
diff --git a/arch/powerpc/include/asm/ucall-api.h b/arch/powerpc/include/asm/ucall-api.h
index ffafd9e..82d8edd 100644
--- a/arch/powerpc/include/asm/ucall-api.h
+++ b/arch/powerpc/include/asm/ucall-api.h
@@ -21,6 +21,12 @@  static inline bool smf_enabled(void)
 	return (smf_state == 2);
 }
 
+static inline bool is_uv_register(u64 reg)
+{
+	return ((reg == SPRN_DAWR || reg == SPRN_DAWRX || reg == SPRN_CIABR) &&
+		smf_enabled());
+}
+
 #define PLPAR_UCALL_BUFSIZE 4
 long plpar_ucall(unsigned long opcode, unsigned long *retbuf, ...);
 
@@ -48,5 +54,5 @@  static inline int uv_restricted_spr_read(u64 reg, u64 *val)
 	return rc;
 }
 
-#endif /* __ASSEMBLY__ */
+#endif	/* __ASSEMBLY__ */
 #endif	/* _ASM_POWERPC_UCALL_API_H */
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 913bfca..37931aa 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -183,9 +183,9 @@  void setup_paca(struct paca_struct *new_paca)
 	 * applied
 	 */
 	if (early_cpu_has_feature(CPU_FTR_HVMODE))
-		mtspr(SPRN_SPRG_HPACA, local_paca);
+		mtspr(SPRN_SPRG_HPACA, (u64)local_paca);
 #endif
-	mtspr(SPRN_SPRG_PACA, local_paca);
+	mtspr(SPRN_SPRG_PACA, (u64)local_paca);
 
 }
 
diff --git a/arch/powerpc/oprofile/op_model_pa6t.c b/arch/powerpc/oprofile/op_model_pa6t.c
index a114a7c..386cd53 100644
--- a/arch/powerpc/oprofile/op_model_pa6t.c
+++ b/arch/powerpc/oprofile/op_model_pa6t.c
@@ -151,9 +151,9 @@  static int pa6t_cpu_setup(struct op_counter_config *ctr)
 	/* program selected programmable events in */
 	mtspr(SPRN_PA6T_MMCR1, mmcr1);
 
-	pr_debug("setup on cpu %d, mmcr0 %016lx\n", smp_processor_id(),
+	pr_debug("setup on cpu %d, mmcr0 %016llx\n", smp_processor_id(),
 		mfspr(SPRN_PA6T_MMCR0));
-	pr_debug("setup on cpu %d, mmcr1 %016lx\n", smp_processor_id(),
+	pr_debug("setup on cpu %d, mmcr1 %016llx\n", smp_processor_id(),
 		mfspr(SPRN_PA6T_MMCR1));
 
 	return 0;
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index b072300..b3cc5cd 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -834,7 +834,7 @@  void perf_event_print_debug(void)
 		pr_info("PMC5:  %08x PMC6: %08x PMC7: %08x PMC8: %08x\n",
 			 pmcs[4], pmcs[5], pmcs[6], pmcs[7]);
 
-	pr_info("MMCR0: %016lx MMCR1: %016lx MMCRA: %016lx\n",
+	pr_info("MMCR0: %016llx MMCR1: %016llx MMCRA: %016llx\n",
 		mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCRA));
 
 	sdar = sier = 0;
@@ -845,13 +845,13 @@  void perf_event_print_debug(void)
 		sier = mfspr(SPRN_SIER);
 
 	if (ppmu->flags & PPMU_ARCH_207S) {
-		pr_info("MMCR2: %016lx EBBHR: %016lx\n",
+		pr_info("MMCR2: %016llx EBBHR: %016llx\n",
 			mfspr(SPRN_MMCR2), mfspr(SPRN_EBBHR));
-		pr_info("EBBRR: %016lx BESCR: %016lx\n",
+		pr_info("EBBRR: %016llx BESCR: %016llx\n",
 			mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
 	}
 #endif
-	pr_info("SIAR:  %016lx SDAR:  %016lx SIER:  %016lx\n",
+	pr_info("SIAR:  %016llx SDAR:  %016lx SIER:  %016lx\n",
 		mfspr(SPRN_SIAR), sdar, sier);
 
 	local_irq_restore(flags);
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 757b849..cf811e6 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -192,8 +192,12 @@  static void xmon_print_symbol(unsigned long address, const char *mid,
 
 #ifdef CONFIG_PPC64
 #define REG		"%.16lx"
+#define REG16		"%.16llx"
+#define REG8		"%.8llx"
 #else
 #define REG		"%.8lx"
+#define REG16		REG
+#define REG8		REG
 #endif
 
 #ifdef __LITTLE_ENDIAN__
@@ -1798,25 +1802,25 @@  static void dump_206_sprs(void)
 
 	/* Actually some of these pre-date 2.06, but whatevs */
 
-	printf("srr0   = %.16lx  srr1  = %.16lx dsisr  = %.8lx\n",
+	printf("srr0   = "REG16"  srr1  = "REG16" dsisr  = "REG8"\n",
 		mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR));
-	printf("dscr   = %.16lx  ppr   = %.16lx pir    = %.8lx\n",
+	printf("dscr   = "REG16"  ppr   = "REG16" pir    = "REG16"\n",
 		mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR));
-	printf("amr    = %.16lx  uamor = %.16lx\n",
+	printf("amr    = "REG16"  uamor = "REG16"\n",
 		mfspr(SPRN_AMR), mfspr(SPRN_UAMOR));
 
 	if (!(mfmsr() & MSR_HV))
 		return;
 
-	printf("sdr1   = %.16lx  hdar  = %.16lx hdsisr = %.8lx\n",
+	printf("sdr1   = "REG16"  hdar  = "REG16" hdsisr = "REG8"\n",
 		mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR));
-	printf("hsrr0  = %.16lx hsrr1  = %.16lx hdec   = %.16lx\n",
+	printf("hsrr0  = "REG16" hsrr1  = "REG16" hdec   = "REG16"\n",
 		mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC));
-	printf("lpcr   = %.16lx  pcr   = %.16lx lpidr  = %.8lx\n",
+	printf("lpcr   = "REG16"  pcr   = "REG16" lpidr  = "REG16"\n",
 		mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID));
-	printf("hsprg0 = %.16lx hsprg1 = %.16lx amor   = %.16lx\n",
+	printf("hsprg0 = "REG16" hsprg1 = "REG16" amor   = "REG16"\n",
 		mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR));
-	printf("dabr   = %.16lx dabrx  = %.16lx\n",
+	printf("dabr   = "REG16" dabrx  = "REG16"\n",
 		mfspr(SPRN_DABR), mfspr(SPRN_DABRX));
 #endif
 }
@@ -1829,39 +1833,39 @@  static void dump_207_sprs(void)
 	if (!cpu_has_feature(CPU_FTR_ARCH_207S))
 		return;
 
-	printf("dpdes  = %.16lx  tir   = %.16lx cir    = %.8lx\n",
+	printf("dpdes  = "REG16"  tir   = "REG16" cir    = "REG8"\n",
 		mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR));
 
-	printf("fscr   = %.16lx  tar   = %.16lx pspb   = %.8lx\n",
+	printf("fscr   = "REG16"  tar   = "REG16" pspb   = "REG16"\n",
 		mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB));
 
 	msr = mfmsr();
 	if (msr & MSR_TM) {
 		/* Only if TM has been enabled in the kernel */
-		printf("tfhar  = %.16lx  tfiar = %.16lx texasr = %.16lx\n",
+		printf("tfhar  = "REG16"  tfiar = "REG16" texasr = "REG16"\n",
 			mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR),
 			mfspr(SPRN_TEXASR));
 	}
 
-	printf("mmcr0  = %.16lx  mmcr1 = %.16lx mmcr2  = %.16lx\n",
+	printf("mmcr0  = "REG16"  mmcr1 = "REG16" mmcr2  = "REG16"\n",
 		mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2));
-	printf("pmc1   = %.8lx pmc2 = %.8lx  pmc3 = %.8lx  pmc4   = %.8lx\n",
+	printf("pmc1   = "REG8" pmc2 = "REG8"  pmc3 = "REG8"  pmc4   = "REG8"\n",
 		mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
 		mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
-	printf("mmcra  = %.16lx   siar = %.16lx pmc5   = %.8lx\n",
+	printf("mmcra  = "REG16"   siar = "REG16" pmc5   = "REG8"\n",
 		mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
-	printf("sdar   = %.16lx   sier = %.16lx pmc6   = %.8lx\n",
+	printf("sdar   = "REG16"   sier = "REG16" pmc6   = "REG16"\n",
 		mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
-	printf("ebbhr  = %.16lx  ebbrr = %.16lx bescr  = %.16lx\n",
+	printf("ebbhr  = "REG16"  ebbrr = "REG16" bescr  = "REG16"\n",
 		mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
-	printf("iamr   = %.16lx\n", mfspr(SPRN_IAMR));
+	printf("iamr   = "REG16"\n", mfspr(SPRN_IAMR));
 
 	if (!(msr & MSR_HV))
 		return;
 
-	printf("hfscr  = %.16lx  dhdes = %.16lx rpr    = %.16lx\n",
+	printf("hfscr  = "REG16"  dhdes = "REG16" rpr    = "REG16"\n",
 		mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR));
-	printf("dawr   = %.16lx  dawrx = %.16lx ciabr  = %.16lx\n",
+	printf("dawr   = "REG16"  dawrx = "REG16" ciabr  = "REG16"\n",
 		mfspr(SPRN_DAWR), mfspr(SPRN_DAWRX), mfspr(SPRN_CIABR));
 #endif
 }
@@ -1874,16 +1878,16 @@  static void dump_300_sprs(void)
 	if (!cpu_has_feature(CPU_FTR_ARCH_300))
 		return;
 
-	printf("pidr   = %.16lx  tidr  = %.16lx\n",
+	printf("pidr   = "REG16"  tidr  = "REG16"\n",
 		mfspr(SPRN_PID), mfspr(SPRN_TIDR));
-	printf("asdr   = %.16lx  psscr = %.16lx\n",
+	printf("asdr   = "REG16"  psscr = "REG16"\n",
 		mfspr(SPRN_ASDR), hv ? mfspr(SPRN_PSSCR)
 					: mfspr(SPRN_PSSCR_PR));
 
 	if (!hv)
 		return;
 
-	printf("ptcr   = %.16lx\n",
+	printf("ptcr   = "REG16"\n",
 		mfspr(SPRN_PTCR));
 #endif
 }
@@ -1930,14 +1934,14 @@  static void super_regs(void)
 		asm("mr %0,1" : "=r" (sp) :);
 		asm("mr %0,2" : "=r" (toc) :);
 
-		printf("msr    = "REG"  sprg0 = "REG"\n",
+		printf("msr    = "REG"  sprg0 = "REG16"\n",
 		       mfmsr(), mfspr(SPRN_SPRG0));
-		printf("pvr    = "REG"  sprg1 = "REG"\n",
+		printf("pvr    = "REG16"  sprg1 = "REG16"\n",
 		       mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
-		printf("dec    = "REG"  sprg2 = "REG"\n",
+		printf("dec    = "REG16"  sprg2 = "REG16"\n",
 		       mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
-		printf("sp     = "REG"  sprg3 = "REG"\n", sp, mfspr(SPRN_SPRG3));
-		printf("toc    = "REG"  dar   = "REG"\n", toc, mfspr(SPRN_DAR));
+		printf("sp     = "REG"  sprg3 = "REG16"\n", sp, mfspr(SPRN_SPRG3));
+		printf("toc    = "REG"  dar   = "REG16"\n", toc, mfspr(SPRN_DAR));
 
 		dump_206_sprs();
 		dump_207_sprs();