The nouveau driver makes a number of unaligned accesses via the ROM16(), ROM32() and ROM64() macros which fault on SPARC (but would be transparently handled by x86 hardware). Making use of get_unaligned() macro fixes the problem for me.<div>
<br></div><div><div>diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h</div><div>index 7ccd28f..92031f6 100644</div><div>--- a/drivers/gpu/drm/nouveau/nouveau_bios.h</div><div>+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h</div>
<div>@@ -26,6 +26,8 @@</div><div><br></div><div> #include "nvreg.h"</div><div><br></div><div>+#include <asm/unaligned.h></div><div>+</div><div> #define DCB_MAX_NUM_ENTRIES 16</div><div> #define DCB_MAX_NUM_I2C_ENTRIES 16</div>
<div> #define DCB_MAX_NUM_GPIO_ENTRIES 32</div><div>@@ -33,10 +35,10 @@</div><div><br></div><div> #define DCB_LOC_ON_CHIP 0</div><div><br></div><div>-#define ROM16(x) le16_to_cpu(*(u16 *)&(x))</div><div>-#define ROM32(x) le32_to_cpu(*(u32 *)&(x))</div>
<div>+#define ROM16(x) le16_to_cpu(get_unaligned((u16 *)&(x)))</div><div>+#define ROM32(x) le32_to_cpu(get_unaligned((u32 *)&(x)))</div><div> #define ROM48(x) ({ u8 *p = &(x); (u64)ROM16(p[4]) << 32 | ROM32(p[0]); })</div>
<div>-#define ROM64(x) le64_to_cpu(*(u64 *)&(x))</div><div>+#define ROM64(x) le64_to_cpu(get_unaligned((u64 *)&(x)))</div><div> #define ROMPTR(d,x) ({ \</div><div> struct nouveau_drm *drm = nouveau_drm((d)); \</div>
<div> ROM16(x) ? &drm->vbios.data[ROM16(x)] : NULL; \</div></div><div><br></div>