Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 673b189a authored by Paul Mackerras's avatar Paul Mackerras Committed by Benjamin Herrenschmidt
Browse files

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: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent b3e6b5df
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -60,16 +60,15 @@
#define EXC_HV	H
#define EXC_STD

#define __EXCEPTION_PROLOG_1(area, h)					\
#define EXCEPTION_PROLOG_1(area)					\
	GET_PACA(r13);							\
	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
	std	r10,area+EX_R10(r13);					\
	std	r11,area+EX_R11(r13);					\
	std	r12,area+EX_R12(r13);					\
	mfspr	r9,SPRN_SPRG_##h##SCRATCH0;				\
	GET_SCRATCH0(r9);						\
	std	r9,area+EX_R13(r13);					\
	mfcr	r9
#define EXCEPTION_PROLOG_1(area, h) __EXCEPTION_PROLOG_1(area, h)

#define __EXCEPTION_PROLOG_PSERIES_1(label, h)				\
	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
@@ -85,7 +84,7 @@
	__EXCEPTION_PROLOG_PSERIES_1(label, h)

#define EXCEPTION_PROLOG_PSERIES(area, label, h)			\
	EXCEPTION_PROLOG_1(area, h);					\
	EXCEPTION_PROLOG_1(area);					\
	EXCEPTION_PROLOG_PSERIES_1(label, h);

/*
@@ -156,7 +155,7 @@
label##_pSeries:					\
	HMT_MEDIUM;					\
	DO_KVM	vec;					\
	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
	SET_SCRATCH0(r13);		/* save r13 */		\
	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD)

#define STD_EXCEPTION_HV(loc, vec, label)		\
@@ -165,13 +164,13 @@ label##_pSeries: \
label##_hv:						\
	HMT_MEDIUM;					\
	DO_KVM	vec;					\
	mtspr	SPRN_SPRG_HSCRATCH0,r13;/* save r13 */	\
	SET_SCRATCH0(r13);	/* save r13 */		\
	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV)

#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h)			\
	HMT_MEDIUM;							\
	DO_KVM	vec;							\
	mtspr	SPRN_SPRG_##h##SCRATCH0,r13;    /* save r13 */		\
	SET_SCRATCH0(r13);    /* save r13 */				\
	GET_PACA(r13);							\
	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
	std	r10,PACA_EXGEN+EX_R10(r13);				\
@@ -179,7 +178,7 @@ label##_hv: \
	mfcr	r9;							\
	cmpwi	r10,0;							\
	beq	masked_##h##interrupt;					\
	mfspr	r10,SPRN_SPRG_##h##SCRATCH0;				\
	GET_SCRATCH0(r10);						\
	std	r10,PACA_EXGEN+EX_R13(r13);				\
	std	r11,PACA_EXGEN+EX_R11(r13);				\
	std	r12,PACA_EXGEN+EX_R12(r13);				\
+14 −0
Original line number Diff line number Diff line
@@ -802,6 +802,20 @@
	FTR_SECTION_ELSE_NESTED(66);			\
	mtspr	SPRN_SPRG_HPACA,rX;			\
	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

#ifdef CONFIG_PPC_BOOK3E_64
+13 −13
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ __start_interrupts:
_machine_check_pSeries:
	HMT_MEDIUM
	DO_KVM	0x200
	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
	SET_SCRATCH0(r13)
	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)

	. = 0x300
@@ -51,7 +51,7 @@ _machine_check_pSeries:
data_access_pSeries:
	HMT_MEDIUM
	DO_KVM	0x300
	mtspr	SPRN_SPRG_SCRATCH0,r13
	SET_SCRATCH0(r13)
BEGIN_FTR_SECTION
	GET_PACA(r13)
	std	r9,PACA_EXSLB+EX_R9(r13)
@@ -67,7 +67,7 @@ BEGIN_FTR_SECTION
	std	r11,PACA_EXGEN+EX_R11(r13)
	ld	r11,PACA_EXSLB+EX_R9(r13)
	std	r12,PACA_EXGEN+EX_R12(r13)
	mfspr	r12,SPRN_SPRG_SCRATCH0
	GET_SCRATCH0(r12)
	std	r10,PACA_EXGEN+EX_R10(r13)
	std	r11,PACA_EXGEN+EX_R9(r13)
	std	r12,PACA_EXGEN+EX_R13(r13)
@@ -81,7 +81,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
data_access_slb_pSeries:
	HMT_MEDIUM
	DO_KVM	0x380
	mtspr	SPRN_SPRG_SCRATCH0,r13
	SET_SCRATCH0(r13)
	GET_PACA(r13)
	std	r3,PACA_EXSLB+EX_R3(r13)
	mfspr	r3,SPRN_DAR
@@ -95,7 +95,7 @@ data_access_slb_pSeries:
	std	r10,PACA_EXSLB+EX_R10(r13)
	std	r11,PACA_EXSLB+EX_R11(r13)
	std	r12,PACA_EXSLB+EX_R12(r13)
	mfspr	r10,SPRN_SPRG_SCRATCH0
	GET_SCRATCH0(r10)
	std	r10,PACA_EXSLB+EX_R13(r13)
	mfspr	r12,SPRN_SRR1		/* and SRR1 */
#ifndef CONFIG_RELOCATABLE
@@ -120,7 +120,7 @@ data_access_slb_pSeries:
instruction_access_slb_pSeries:
	HMT_MEDIUM
	DO_KVM	0x480
	mtspr	SPRN_SPRG_SCRATCH0,r13
	SET_SCRATCH0(r13)
	GET_PACA(r13)
	std	r3,PACA_EXSLB+EX_R3(r13)
	mfspr	r3,SPRN_SRR0		/* SRR0 is faulting address */
@@ -134,7 +134,7 @@ instruction_access_slb_pSeries:
	std	r10,PACA_EXSLB+EX_R10(r13)
	std	r11,PACA_EXSLB+EX_R11(r13)
	std	r12,PACA_EXSLB+EX_R12(r13)
	mfspr	r10,SPRN_SPRG_SCRATCH0
	GET_SCRATCH0(r10)
	std	r10,PACA_EXSLB+EX_R13(r13)
	mfspr	r12,SPRN_SRR1		/* and SRR1 */
#ifndef CONFIG_RELOCATABLE
@@ -272,7 +272,7 @@ masked_interrupt:
	rotldi	r10,r10,16
	mtspr	SPRN_SRR1,r10
	ld	r10,PACA_EXGEN+EX_R10(r13)
	mfspr	r13,SPRN_SPRG_SCRATCH0
	GET_SCRATCH0(r13)
	rfid
	b	.

@@ -285,7 +285,7 @@ masked_Hinterrupt:
	rotldi	r10,r10,16
	mtspr	SPRN_HSRR1,r10
	ld	r10,PACA_EXGEN+EX_R10(r13)
	mfspr	r13,SPRN_SPRG_HSCRATCH0
	GET_SCRATCH0(r13)
	hrfid
	b	.

@@ -293,7 +293,7 @@ masked_Hinterrupt:
do_stab_bolted_pSeries:
	std	r11,PACA_EXSLB+EX_R11(r13)
	std	r12,PACA_EXSLB+EX_R12(r13)
	mfspr	r10,SPRN_SPRG_SCRATCH0
	GET_SCRATCH0(r10)
	std	r10,PACA_EXSLB+EX_R13(r13)
	EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD)

@@ -305,14 +305,14 @@ do_stab_bolted_pSeries:
      .align 7
system_reset_fwnmi:
	HMT_MEDIUM
	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
	SET_SCRATCH0(r13)		/* save r13 */
	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD)

	.globl machine_check_fwnmi
      .align 7
machine_check_fwnmi:
	HMT_MEDIUM
	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
	SET_SCRATCH0(r13)		/* save r13 */
	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)

#endif /* CONFIG_PPC_PSERIES */
@@ -327,7 +327,7 @@ slb_miss_user_pseries:
	std	r10,PACA_EXGEN+EX_R10(r13)
	std	r11,PACA_EXGEN+EX_R11(r13)
	std	r12,PACA_EXGEN+EX_R12(r13)
	mfspr	r10,SPRG_SCRATCH0
	GET_SCRATCH0(r10)
	ld	r11,PACA_EXSLB+EX_R9(r13)
	ld	r12,PACA_EXSLB+EX_R3(r13)
	std	r10,PACA_EXGEN+EX_R13(r13)
+3 −3
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@
.global 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
@@ -89,7 +89,7 @@ kvmppc_trampoline_\intno:
	lwz	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
	mtcr	r12
	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 */

	/* 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)
	mtcr	r12
	PPC_LL	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
	mfspr	r13, SPRN_SPRG_SCRATCH0
	GET_SCRATCH0(r13)

	/* And get back into the code */
	RFI
+1 −1
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ kvmppc_handler_trampoline_exit:
	PPC_STL	r4, (SHADOW_VCPU_OFF + SVCPU_SHADOW_SRR1)(r13)

	/* Get scratch'ed off registers */
	mfspr	r9, SPRN_SPRG_SCRATCH0
	GET_SCRATCH0(r9)
	PPC_LL	r8, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
	lwz	r7, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)

Loading