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

Commit 494e5b6f authored by Khalid Aziz's avatar Khalid Aziz Committed by David S. Miller
Browse files

sparc: Resolve conflict between sparc v9 and M7 on usage of bit 9 of TTE



sparc: Resolve conflict between sparc v9 and M7 on usage of bit 9 of TTE

Bit 9 of TTE is CV (Cacheable in V-cache) on sparc v9 processor while
the same bit 9 is MCDE (Memory Corruption Detection Enable) on M7
processor. This creates a conflicting usage of the same bit. Kernel
sets TTE.cv bit on all pages for sun4v architecture which works well
for sparc v9 but enables memory corruption detection on M7 processor
which is not the intent. This patch adds code to determine if kernel
is running on M7 processor and takes steps to not enable memory
corruption detection in TTE erroneously.

Signed-off-by: default avatarKhalid Aziz <khalid.aziz@oracle.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f0c1a117
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -308,12 +308,26 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
	"	sllx		%1, 32, %1\n"
	"	or		%0, %1, %0\n"
	"	.previous\n"
	"	.section	.sun_m7_2insn_patch, \"ax\"\n"
	"	.word		661b\n"
	"	sethi		%%uhi(%4), %1\n"
	"	sethi		%%hi(%4), %0\n"
	"	.word		662b\n"
	"	or		%1, %%ulo(%4), %1\n"
	"	or		%0, %%lo(%4), %0\n"
	"	.word		663b\n"
	"	sllx		%1, 32, %1\n"
	"	or		%0, %1, %0\n"
	"	.previous\n"
	: "=r" (mask), "=r" (tmp)
	: "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
	       _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U |
	       _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U),
	  "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
	       _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V |
	       _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V),
	  "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
	       _PAGE_CP_4V | _PAGE_E_4V |
	       _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V));

	return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
@@ -342,9 +356,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
	"	andn		%0, %4, %0\n"
	"	or		%0, %5, %0\n"
	"	.previous\n"
	"	.section	.sun_m7_2insn_patch, \"ax\"\n"
	"	.word		661b\n"
	"	andn		%0, %6, %0\n"
	"	or		%0, %5, %0\n"
	"	.previous\n"
	: "=r" (val)
	: "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U),
	             "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V));
	             "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V),
	             "i" (_PAGE_CP_4V));

	return __pgprot(val);
}
+2 −0
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ struct sun4v_2insn_patch_entry {
};
extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
	__sun4v_2insn_patch_end;
extern struct sun4v_2insn_patch_entry __sun_m7_2insn_patch,
	__sun_m7_2insn_patch_end;


#endif /* !(__ASSEMBLY__) */
+2 −0
Original line number Diff line number Diff line
@@ -69,6 +69,8 @@ void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
			     struct sun4v_1insn_patch_entry *);
void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
			     struct sun4v_2insn_patch_entry *);
void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *,
			     struct sun4v_2insn_patch_entry *);
extern unsigned int dcache_parity_tl1_occurred;
extern unsigned int icache_parity_tl1_occurred;

+21 −0
Original line number Diff line number Diff line
@@ -255,6 +255,24 @@ void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
	}
}

void sun_m7_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
			     struct sun4v_2insn_patch_entry *end)
{
	while (start < end) {
		unsigned long addr = start->addr;

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

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

		start++;
	}
}

static void __init sun4v_patch(void)
{
	extern void sun4v_hvapi_init(void);
@@ -267,6 +285,9 @@ static void __init sun4v_patch(void)

	sun4v_patch_2insn_range(&__sun4v_2insn_patch,
				&__sun4v_2insn_patch_end);
	if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7)
		sun_m7_patch_2insn_range(&__sun_m7_2insn_patch,
					 &__sun_m7_2insn_patch_end);

	sun4v_hvapi_init();
}
+5 −0
Original line number Diff line number Diff line
@@ -138,6 +138,11 @@ SECTIONS
		*(.pause_3insn_patch)
		__pause_3insn_patch_end = .;
	}
	.sun_m7_2insn_patch : {
		__sun_m7_2insn_patch = .;
		*(.sun_m7_2insn_patch)
		__sun_m7_2insn_patch_end = .;
	}
	PERCPU_SECTION(SMP_CACHE_BYTES)

	. = ALIGN(PAGE_SIZE);
Loading