Skip to contentSkip to conversation

MIPS: Workaround bugged BCM4704 & BCM5354 that crash with kmap_coherent()

PATCH Paul Burton 1 participant 1 message Feb 7, 2019 1 message not in the archive MIPS

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

Hi Rafał,

Quoted 30 lines · Rafał Miłecki

From: Rafał Miłecki <[email protected]>

This workarounds what seems to be a hardware bug present in some early Broadcom MIPS CPUs. For some reason using kmap_coherent() for copying a memory causes a "Data bus error" or SoC reboot.

%

arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h +8 -0
index b23ff47ea475..553505dea60b 100644
@@ -80,4 +80,12 @@
 #define cpu_scache_line_size()		0
 #define cpu_has_vz			0
 
+/*
+ * Workaround for the bugged BCM4704 & BCM5354:
+ * copy_from_user_page() + kmap_coherent() causes "Data bus error"
+ * copy_to_user_page() + kmap_coherent() causes immediate reboot
+ */
+#define cpu_has_kmap_coherent		(cpu_data[0].processor_id != 0x29006 && \
+					 cpu_data[0].processor_id != 0x29029)
+
 #endif /* __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H */
arch/mips/mm/init.c +0 -0
index c3b45e248806..67007bf15543 100644

arch/mips/mm/init.c void copy_user_highpage(struct page *to, struct page *from, · line 180

Quoted 8 lines
arch/mips/mm/init.c +1 -1
@@ -174,7 +174,7 @@ void copy_user_highpage(struct page *to, struct page *from,
 	void *vfrom, *vto;
 
 	vto = kmap_atomic(to);
-	if (cpu_has_dc_aliases &&
+	if (cpu_has_kmap_coherent && cpu_has_dc_aliases &&
 	    page_mapcount(from) && !Page_dcache_dirty(from)) {
 		vfrom = kmap_coherent(from, vaddr);
 		copy_page(vto, vfrom);

Won't this introduce cache aliasing problems?

The reason for using kmap_coherent at all is to ensure we use a mapping with the same cache colouring as the user's mapping. If the CPU suffers from dcache aliasing & we don't do that colouring then it seems like this might lead to us reading/copying stale data?

Thanks,
Paul