Commit 45fec05f authored by David S. Miller's avatar David S. Miller
Browse files

[SPARC64]: Sanitize %pstate writes for sun4v.



If we're just switching between different alternate global
sets, nop it out on sun4v.  Also, get rid of all of the
alternate global save/restore in the OBP CIF trampoline code.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 314981ac
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -60,8 +60,15 @@ kvmap_itlb_load:
	retry

kvmap_itlb_longpath:
	rdpr	%pstate, %g5

661:	rdpr	%pstate, %g5
	wrpr	%g5, PSTATE_AG | PSTATE_MG, %pstate
	.section .gl_2insn_patch, "ax"
	.word	661b
	nop
	nop
	.previous

	rdpr	%tpc, %g5
	ba,pt	%xcc, sparc64_realfault_common
	 mov	FAULT_CODE_ITLB, %g4
@@ -161,8 +168,15 @@ kvmap_check_obp:
	 nop

kvmap_dtlb_longpath:
	rdpr	%pstate, %g5

661:	rdpr	%pstate, %g5
	wrpr	%g5, PSTATE_AG | PSTATE_MG, %pstate
	.section .gl_2insn_patch, "ax"
	.word	661b
	nop
	nop
	.previous

	rdpr	%tl, %g4
	cmp	%g4, 1
	mov	TLB_TAG_ACCESS, %g4
+20 −6
Original line number Diff line number Diff line
@@ -547,19 +547,33 @@ static void __init per_cpu_patch(void)

static void __init gl_patch(void)
{
	struct gl_1insn_patch_entry *p;
	struct gl_1insn_patch_entry *p1;
	struct gl_2insn_patch_entry *p2;

	if (tlb_type != hypervisor)
		return;

	p = &__gl_1insn_patch;
	while (p < &__gl_1insn_patch_end) {
		unsigned long addr = p->addr;
	p1 = &__gl_1insn_patch;
	while (p1 < &__gl_1insn_patch_end) {
		unsigned long addr = p1->addr;

		*(unsigned int *) (addr +  0) = p->insn;
		*(unsigned int *) (addr +  0) = p1->insn;
		__asm__ __volatile__("flush	%0" : : "r" (addr +  0));

		p++;
		p1++;
	}

	p2 = &__gl_2insn_patch;
	while (p2 < &__gl_2insn_patch_end) {
		unsigned long addr = p2->addr;

		*(unsigned int *) (addr +  0) = p2->insns[0];
		__asm__ __volatile__("flush	%0" : : "r" (addr +  0));

		*(unsigned int *) (addr +  3) = p2->insns[1];
		__asm__ __volatile__("flush	%0" : : "r" (addr +  4));

		p2++;
	}
}

+10 −2
Original line number Diff line number Diff line
@@ -82,9 +82,17 @@ tsb_itlb_load:
	.globl		tsb_do_fault
tsb_do_fault:
	cmp		%g3, FAULT_CODE_DTLB
	rdpr		%pstate, %g5
	bne,pn		%xcc, tsb_do_itlb_fault

661:	rdpr		%pstate, %g5
	wrpr		%g5, PSTATE_AG | PSTATE_MG, %pstate
	.section	.gl_2insn_patch, "ax"
	.word		661b
	nop
	nop
	.previous

	bne,pn		%xcc, tsb_do_itlb_fault
	 nop

tsb_do_dtlb_fault:
	rdpr	%tl, %g4
+3 −0
Original line number Diff line number Diff line
@@ -80,6 +80,9 @@ SECTIONS
  __gl_1insn_patch = .;
  .gl_1insn_patch : { *(.gl_1insn_patch) }
  __gl_1insn_patch_end = .;
  __gl_2insn_patch = .;
  .gl_2insn_patch : { *(.gl_2insn_patch) }
  __gl_2insn_patch_end = .;
  . = ALIGN(8192); 
  __initramfs_start = .;
  .init.ramfs : { *(.init.ramfs) }
+16 −2
Original line number Diff line number Diff line
@@ -444,8 +444,15 @@ xcall_flush_tlb_kernel_range: /* 22 insns */
	 */
	.globl		xcall_sync_tick
xcall_sync_tick:
	rdpr		%pstate, %g2

661:	rdpr		%pstate, %g2
	wrpr		%g2, PSTATE_IG | PSTATE_AG, %pstate
	.section	.gl_2insn_patch, "ax"
	.word		661b
	nop
	nop
	.previous

	rdpr		%pil, %g2
	wrpr		%g0, 15, %pil
	sethi		%hi(109f), %g7
@@ -468,8 +475,15 @@ xcall_sync_tick:
	 */
	.globl		xcall_report_regs
xcall_report_regs:
	rdpr		%pstate, %g2

661:	rdpr		%pstate, %g2
	wrpr		%g2, PSTATE_IG | PSTATE_AG, %pstate
	.section	.gl_2insn_patch, "ax"
	.word		661b
	nop
	nop
	.previous

	rdpr		%pil, %g2
	wrpr		%g0, 15, %pil
	sethi		%hi(109f), %g7
Loading