Эх сурвалжийг харах

powerpc: Always use SPRN_SPRG_HSCRATCH0 when running in HV mode

This uses feature sections to arrange that we always use HSPRG1
as the scratch register in the interrupt entry code rather than
SPRG2 when we're running in hypervisor mode on POWER7.  This will
ensure that we don't trash the guest's SPRG2 when we are running
KVM guests.  To simplify the code, we define GET_SCRATCH0() and
SET_SCRATCH0() macros like the GET_PACA/SET_PACA macros.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Paul Mackerras 14 жил өмнө
parent
commit
673b189a2e

+ 7 - 8
arch/powerpc/include/asm/exception-64s.h

@@ -60,16 +60,15 @@
 #define EXC_HV	H
 #define EXC_HV	H
 #define EXC_STD
 #define EXC_STD
 
 
-#define __EXCEPTION_PROLOG_1(area, h)					\
+#define EXCEPTION_PROLOG_1(area)					\
 	GET_PACA(r13);							\
 	GET_PACA(r13);							\
 	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
 	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
 	std	r10,area+EX_R10(r13);					\
 	std	r10,area+EX_R10(r13);					\
 	std	r11,area+EX_R11(r13);					\
 	std	r11,area+EX_R11(r13);					\
 	std	r12,area+EX_R12(r13);					\
 	std	r12,area+EX_R12(r13);					\
-	mfspr	r9,SPRN_SPRG_##h##SCRATCH0;				\
+	GET_SCRATCH0(r9);						\
 	std	r9,area+EX_R13(r13);					\
 	std	r9,area+EX_R13(r13);					\
 	mfcr	r9
 	mfcr	r9
-#define EXCEPTION_PROLOG_1(area, h) __EXCEPTION_PROLOG_1(area, h)
 
 
 #define __EXCEPTION_PROLOG_PSERIES_1(label, h)				\
 #define __EXCEPTION_PROLOG_PSERIES_1(label, h)				\
 	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
 	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
@@ -85,7 +84,7 @@
 	__EXCEPTION_PROLOG_PSERIES_1(label, h)
 	__EXCEPTION_PROLOG_PSERIES_1(label, h)
 
 
 #define EXCEPTION_PROLOG_PSERIES(area, label, h)			\
 #define EXCEPTION_PROLOG_PSERIES(area, label, h)			\
-	EXCEPTION_PROLOG_1(area, h);					\
+	EXCEPTION_PROLOG_1(area);					\
 	EXCEPTION_PROLOG_PSERIES_1(label, h);
 	EXCEPTION_PROLOG_PSERIES_1(label, h);
 
 
 /*
 /*
@@ -156,7 +155,7 @@
 label##_pSeries:					\
 label##_pSeries:					\
 	HMT_MEDIUM;					\
 	HMT_MEDIUM;					\
 	DO_KVM	vec;					\
 	DO_KVM	vec;					\
-	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
+	SET_SCRATCH0(r13);		/* save r13 */		\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD)
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD)
 
 
 #define STD_EXCEPTION_HV(loc, vec, label)		\
 #define STD_EXCEPTION_HV(loc, vec, label)		\
@@ -165,13 +164,13 @@ label##_pSeries:					\
 label##_hv:						\
 label##_hv:						\
 	HMT_MEDIUM;					\
 	HMT_MEDIUM;					\
 	DO_KVM	vec;					\
 	DO_KVM	vec;					\
-	mtspr	SPRN_SPRG_HSCRATCH0,r13;/* save r13 */	\
+	SET_SCRATCH0(r13);	/* save r13 */		\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV)
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV)
 
 
 #define __MASKABLE_EXCEPTION_PSERIES(vec, label, h)			\
 #define __MASKABLE_EXCEPTION_PSERIES(vec, label, h)			\
 	HMT_MEDIUM;							\
 	HMT_MEDIUM;							\
 	DO_KVM	vec;							\
 	DO_KVM	vec;							\
-	mtspr	SPRN_SPRG_##h##SCRATCH0,r13;    /* save r13 */		\
+	SET_SCRATCH0(r13);    /* save r13 */				\
 	GET_PACA(r13);							\
 	GET_PACA(r13);							\
 	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
 	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
 	std	r10,PACA_EXGEN+EX_R10(r13);				\
 	std	r10,PACA_EXGEN+EX_R10(r13);				\
@@ -179,7 +178,7 @@ label##_hv:						\
 	mfcr	r9;							\
 	mfcr	r9;							\
 	cmpwi	r10,0;							\
 	cmpwi	r10,0;							\
 	beq	masked_##h##interrupt;					\
 	beq	masked_##h##interrupt;					\
-	mfspr	r10,SPRN_SPRG_##h##SCRATCH0;				\
+	GET_SCRATCH0(r10);						\
 	std	r10,PACA_EXGEN+EX_R13(r13);				\
 	std	r10,PACA_EXGEN+EX_R13(r13);				\
 	std	r11,PACA_EXGEN+EX_R11(r13);				\
 	std	r11,PACA_EXGEN+EX_R11(r13);				\
 	std	r12,PACA_EXGEN+EX_R12(r13);				\
 	std	r12,PACA_EXGEN+EX_R12(r13);				\

+ 14 - 0
arch/powerpc/include/asm/reg.h

@@ -802,6 +802,20 @@
 	FTR_SECTION_ELSE_NESTED(66);			\
 	FTR_SECTION_ELSE_NESTED(66);			\
 	mtspr	SPRN_SPRG_HPACA,rX;			\
 	mtspr	SPRN_SPRG_HPACA,rX;			\
 	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
 	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+
+#define GET_SCRATCH0(rX)				\
+	BEGIN_FTR_SECTION_NESTED(66);			\
+	mfspr	rX,SPRN_SPRG_SCRATCH0;			\
+	FTR_SECTION_ELSE_NESTED(66);			\
+	mfspr	rX,SPRN_SPRG_HSCRATCH0;			\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+
+#define SET_SCRATCH0(rX)				\
+	BEGIN_FTR_SECTION_NESTED(66);			\
+	mtspr	SPRN_SPRG_SCRATCH0,rX;			\
+	FTR_SECTION_ELSE_NESTED(66);			\
+	mtspr	SPRN_SPRG_HSCRATCH0,rX;			\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
 #endif
 #endif
 
 
 #ifdef CONFIG_PPC_BOOK3E_64
 #ifdef CONFIG_PPC_BOOK3E_64

+ 13 - 13
arch/powerpc/kernel/exceptions-64s.S

@@ -43,7 +43,7 @@ __start_interrupts:
 _machine_check_pSeries:
 _machine_check_pSeries:
 	HMT_MEDIUM
 	HMT_MEDIUM
 	DO_KVM	0x200
 	DO_KVM	0x200
-	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
+	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
 
 
 	. = 0x300
 	. = 0x300
@@ -51,7 +51,7 @@ _machine_check_pSeries:
 data_access_pSeries:
 data_access_pSeries:
 	HMT_MEDIUM
 	HMT_MEDIUM
 	DO_KVM	0x300
 	DO_KVM	0x300
-	mtspr	SPRN_SPRG_SCRATCH0,r13
+	SET_SCRATCH0(r13)
 BEGIN_FTR_SECTION
 BEGIN_FTR_SECTION
 	GET_PACA(r13)
 	GET_PACA(r13)
 	std	r9,PACA_EXSLB+EX_R9(r13)
 	std	r9,PACA_EXSLB+EX_R9(r13)
@@ -67,7 +67,7 @@ BEGIN_FTR_SECTION
 	std	r11,PACA_EXGEN+EX_R11(r13)
 	std	r11,PACA_EXGEN+EX_R11(r13)
 	ld	r11,PACA_EXSLB+EX_R9(r13)
 	ld	r11,PACA_EXSLB+EX_R9(r13)
 	std	r12,PACA_EXGEN+EX_R12(r13)
 	std	r12,PACA_EXGEN+EX_R12(r13)
-	mfspr	r12,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r12)
 	std	r10,PACA_EXGEN+EX_R10(r13)
 	std	r10,PACA_EXGEN+EX_R10(r13)
 	std	r11,PACA_EXGEN+EX_R9(r13)
 	std	r11,PACA_EXGEN+EX_R9(r13)
 	std	r12,PACA_EXGEN+EX_R13(r13)
 	std	r12,PACA_EXGEN+EX_R13(r13)
@@ -81,7 +81,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
 data_access_slb_pSeries:
 data_access_slb_pSeries:
 	HMT_MEDIUM
 	HMT_MEDIUM
 	DO_KVM	0x380
 	DO_KVM	0x380
-	mtspr	SPRN_SPRG_SCRATCH0,r13
+	SET_SCRATCH0(r13)
 	GET_PACA(r13)
 	GET_PACA(r13)
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_DAR
 	mfspr	r3,SPRN_DAR
@@ -95,7 +95,7 @@ data_access_slb_pSeries:
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 #ifndef CONFIG_RELOCATABLE
 #ifndef CONFIG_RELOCATABLE
@@ -120,7 +120,7 @@ data_access_slb_pSeries:
 instruction_access_slb_pSeries:
 instruction_access_slb_pSeries:
 	HMT_MEDIUM
 	HMT_MEDIUM
 	DO_KVM	0x480
 	DO_KVM	0x480
-	mtspr	SPRN_SPRG_SCRATCH0,r13
+	SET_SCRATCH0(r13)
 	GET_PACA(r13)
 	GET_PACA(r13)
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_SRR0		/* SRR0 is faulting address */
 	mfspr	r3,SPRN_SRR0		/* SRR0 is faulting address */
@@ -134,7 +134,7 @@ instruction_access_slb_pSeries:
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 #ifndef CONFIG_RELOCATABLE
 #ifndef CONFIG_RELOCATABLE
@@ -272,7 +272,7 @@ masked_interrupt:
 	rotldi	r10,r10,16
 	rotldi	r10,r10,16
 	mtspr	SPRN_SRR1,r10
 	mtspr	SPRN_SRR1,r10
 	ld	r10,PACA_EXGEN+EX_R10(r13)
 	ld	r10,PACA_EXGEN+EX_R10(r13)
-	mfspr	r13,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r13)
 	rfid
 	rfid
 	b	.
 	b	.
 
 
@@ -285,7 +285,7 @@ masked_Hinterrupt:
 	rotldi	r10,r10,16
 	rotldi	r10,r10,16
 	mtspr	SPRN_HSRR1,r10
 	mtspr	SPRN_HSRR1,r10
 	ld	r10,PACA_EXGEN+EX_R10(r13)
 	ld	r10,PACA_EXGEN+EX_R10(r13)
-	mfspr	r13,SPRN_SPRG_HSCRATCH0
+	GET_SCRATCH0(r13)
 	hrfid
 	hrfid
 	b	.
 	b	.
 
 
@@ -293,7 +293,7 @@ masked_Hinterrupt:
 do_stab_bolted_pSeries:
 do_stab_bolted_pSeries:
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD)
 	EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD)
 
 
@@ -305,14 +305,14 @@ do_stab_bolted_pSeries:
       .align 7
       .align 7
 system_reset_fwnmi:
 system_reset_fwnmi:
 	HMT_MEDIUM
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
+	SET_SCRATCH0(r13)		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD)
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD)
 
 
 	.globl machine_check_fwnmi
 	.globl machine_check_fwnmi
       .align 7
       .align 7
 machine_check_fwnmi:
 machine_check_fwnmi:
 	HMT_MEDIUM
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
+	SET_SCRATCH0(r13)		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
 
 
 #endif /* CONFIG_PPC_PSERIES */
 #endif /* CONFIG_PPC_PSERIES */
@@ -327,7 +327,7 @@ slb_miss_user_pseries:
 	std	r10,PACA_EXGEN+EX_R10(r13)
 	std	r10,PACA_EXGEN+EX_R10(r13)
 	std	r11,PACA_EXGEN+EX_R11(r13)
 	std	r11,PACA_EXGEN+EX_R11(r13)
 	std	r12,PACA_EXGEN+EX_R12(r13)
 	std	r12,PACA_EXGEN+EX_R12(r13)
-	mfspr	r10,SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	ld	r11,PACA_EXSLB+EX_R9(r13)
 	ld	r11,PACA_EXSLB+EX_R9(r13)
 	ld	r12,PACA_EXSLB+EX_R3(r13)
 	ld	r12,PACA_EXSLB+EX_R3(r13)
 	std	r10,PACA_EXGEN+EX_R13(r13)
 	std	r10,PACA_EXGEN+EX_R13(r13)

+ 3 - 3
arch/powerpc/kvm/book3s_rmhandlers.S

@@ -70,7 +70,7 @@
 .global kvmppc_trampoline_\intno
 .global kvmppc_trampoline_\intno
 kvmppc_trampoline_\intno:
 kvmppc_trampoline_\intno:
 
 
-	mtspr	SPRN_SPRG_SCRATCH0, r13		/* Save r13 */
+	SET_SCRATCH0(r13)		/* Save r13 */
 
 
 	/*
 	/*
 	 * First thing to do is to find out if we're coming
 	 * First thing to do is to find out if we're coming
@@ -89,7 +89,7 @@ kvmppc_trampoline_\intno:
 	lwz	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 	lwz	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 	mtcr	r12
 	mtcr	r12
 	PPC_LL	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
 	PPC_LL	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
-	mfspr	r13, SPRN_SPRG_SCRATCH0		/* r13 = original r13 */
+	GET_SCRATCH0(r13)			/* r13 = original r13 */
 	b	kvmppc_resume_\intno		/* Get back original handler */
 	b	kvmppc_resume_\intno		/* Get back original handler */
 
 
 	/* Now we know we're handling a KVM guest */
 	/* Now we know we're handling a KVM guest */
@@ -157,7 +157,7 @@ kvmppc_handler_skip_ins:
 	lwz	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 	lwz	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 	mtcr	r12
 	mtcr	r12
 	PPC_LL	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
 	PPC_LL	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
-	mfspr	r13, SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r13)
 
 
 	/* And get back into the code */
 	/* And get back into the code */
 	RFI
 	RFI

+ 1 - 1
arch/powerpc/kvm/book3s_segment.S

@@ -168,7 +168,7 @@ kvmppc_handler_trampoline_exit:
 	PPC_STL	r4, (SHADOW_VCPU_OFF + SVCPU_SHADOW_SRR1)(r13)
 	PPC_STL	r4, (SHADOW_VCPU_OFF + SVCPU_SHADOW_SRR1)(r13)
 
 
 	/* Get scratch'ed off registers */
 	/* Get scratch'ed off registers */
-	mfspr	r9, SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r9)
 	PPC_LL	r8, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
 	PPC_LL	r8, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
 	lwz	r7, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 	lwz	r7, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 
 

+ 1 - 1
arch/powerpc/platforms/iseries/exception.S

@@ -155,7 +155,7 @@ BEGIN_FTR_SECTION
 	std	r12,PACA_EXGEN+EX_R13(r13)
 	std	r12,PACA_EXGEN+EX_R13(r13)
 	EXCEPTION_PROLOG_ISERIES_1
 	EXCEPTION_PROLOG_ISERIES_1
 FTR_SECTION_ELSE
 FTR_SECTION_ELSE
-	EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD)
+	EXCEPTION_PROLOG_1(PACA_EXGEN)
 	EXCEPTION_PROLOG_ISERIES_1
 	EXCEPTION_PROLOG_ISERIES_1
 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
 	b	data_access_common
 	b	data_access_common

+ 2 - 2
arch/powerpc/platforms/iseries/exception.h

@@ -39,7 +39,7 @@
 label##_iSeries:							\
 label##_iSeries:							\
 	HMT_MEDIUM;							\
 	HMT_MEDIUM;							\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
-	EXCEPTION_PROLOG_1(area, EXC_STD);				\
+	EXCEPTION_PROLOG_1(area);					\
 	EXCEPTION_PROLOG_ISERIES_1;					\
 	EXCEPTION_PROLOG_ISERIES_1;					\
 	b	label##_common
 	b	label##_common
 
 
@@ -48,7 +48,7 @@ label##_iSeries:							\
 label##_iSeries:							\
 label##_iSeries:							\
 	HMT_MEDIUM;							\
 	HMT_MEDIUM;							\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
 	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
-	EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD);			\
+	EXCEPTION_PROLOG_1(PACA_EXGEN);					\
 	lbz	r10,PACASOFTIRQEN(r13);					\
 	lbz	r10,PACASOFTIRQEN(r13);					\
 	cmpwi	0,r10,0;						\
 	cmpwi	0,r10,0;						\
 	beq-	label##_iSeries_masked;					\
 	beq-	label##_iSeries_masked;					\