diff options
author | David Miller <davem@davemloft.net> | 2009-02-18 04:35:23 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-03-13 00:24:04 -0400 |
commit | 958a6f8ccb1964adc3eec84cf401c5baeb4fbca0 (patch) | |
tree | 88dc0089ae4517ac1bb55a39ed15eab10bec5112 /drivers/gpu/drm/radeon/r300_cmdbuf.c | |
parent | f1a2a9b6189f9f5c27672d4d32fec9492c6486b2 (diff) |
drm: radeon: Fix unaligned access in r300_scratch().
In compat mode, the cmdbuf->buf 64-bit address cookie can
potentially be only 32-bit aligned. Dereferencing this as
64-bit causes expensive unaligned traps on platforms like
sparc64.
Use get_unaligned() to fix.
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r300_cmdbuf.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r300_cmdbuf.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c index cace3964feeb..3efa633966e8 100644 --- a/drivers/gpu/drm/radeon/r300_cmdbuf.c +++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include "radeon_drv.h" | 37 | #include "radeon_drv.h" |
38 | #include "r300_reg.h" | 38 | #include "r300_reg.h" |
39 | 39 | ||
40 | #include <asm/unaligned.h> | ||
41 | |||
40 | #define R300_SIMULTANEOUS_CLIPRECTS 4 | 42 | #define R300_SIMULTANEOUS_CLIPRECTS 4 |
41 | 43 | ||
42 | /* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects | 44 | /* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects |
@@ -917,6 +919,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, | |||
917 | { | 919 | { |
918 | u32 *ref_age_base; | 920 | u32 *ref_age_base; |
919 | u32 i, buf_idx, h_pending; | 921 | u32 i, buf_idx, h_pending; |
922 | u64 ptr_addr; | ||
920 | RING_LOCALS; | 923 | RING_LOCALS; |
921 | 924 | ||
922 | if (cmdbuf->bufsz < | 925 | if (cmdbuf->bufsz < |
@@ -930,7 +933,8 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, | |||
930 | 933 | ||
931 | dev_priv->scratch_ages[header.scratch.reg]++; | 934 | dev_priv->scratch_ages[header.scratch.reg]++; |
932 | 935 | ||
933 | ref_age_base = (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf); | 936 | ptr_addr = get_unaligned((u64 *)cmdbuf->buf); |
937 | ref_age_base = (u32 *)(unsigned long)ptr_addr; | ||
934 | 938 | ||
935 | cmdbuf->buf += sizeof(u64); | 939 | cmdbuf->buf += sizeof(u64); |
936 | cmdbuf->bufsz -= sizeof(u64); | 940 | cmdbuf->bufsz -= sizeof(u64); |