Skip to content

Commit 9c088a5

Browse files
arndbrodrigovivi
authored andcommitted
drm/xe: fix devcoredump chunk alignmnent calculation
The device core dumps are copied in 1.5GB chunks, which leads to a link-time error on 32-bit builds because of the 64-bit division not getting trivially turned into mask and shift operations: ERROR: modpost: "__moddi3" [drivers/gpu/drm/xe/xe.ko] undefined! On top of this, I noticed that the ALIGN_DOWN() usage here cannot work because that is only defined for power-of-two alignments. Change ALIGN_DOWN into an explicit div_u64_rem() that avoids the link error and hopefully produces the right results. Doing a 1.5GB kvmalloc() does seem a bit suspicious as well, e.g. this will clearly fail on any 32-bit platform and is also likely to run out of memory on 64-bit systems under memory pressure, so using a much smaller power-of-two chunk size might be a good idea instead. v2: - Always call div_u64_rem (Matt) Reported-by: kernel test robot <[email protected]> Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/ Fixes: c4a2e5f ("drm/xe: Add devcoredump chunking") Signed-off-by: Arnd Bergmann <[email protected]> Signed-off-by: Matthew Brost <[email protected]> Reviewed-by: Rodrigo Vivi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent dba7d17 commit 9c088a5

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

drivers/gpu/drm/xe/xe_devcoredump.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
177177
struct xe_devcoredump *coredump = data;
178178
struct xe_devcoredump_snapshot *ss;
179179
ssize_t byte_copied;
180+
u32 chunk_offset;
181+
ssize_t new_chunk_position;
180182

181183
if (!coredump)
182184
return -ENODEV;
@@ -201,10 +203,14 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
201203
return 0;
202204
}
203205

206+
new_chunk_position = div_u64_rem(offset,
207+
XE_DEVCOREDUMP_CHUNK_MAX,
208+
&chunk_offset);
209+
204210
if (offset >= ss->read.chunk_position + XE_DEVCOREDUMP_CHUNK_MAX ||
205211
offset < ss->read.chunk_position) {
206-
ss->read.chunk_position =
207-
ALIGN_DOWN(offset, XE_DEVCOREDUMP_CHUNK_MAX);
212+
ss->read.chunk_position = new_chunk_position *
213+
XE_DEVCOREDUMP_CHUNK_MAX;
208214

209215
__xe_devcoredump_read(ss->read.buffer,
210216
XE_DEVCOREDUMP_CHUNK_MAX,
@@ -213,8 +219,7 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
213219

214220
byte_copied = count < ss->read.size - offset ? count :
215221
ss->read.size - offset;
216-
memcpy(buffer, ss->read.buffer +
217-
(offset % XE_DEVCOREDUMP_CHUNK_MAX), byte_copied);
222+
memcpy(buffer, ss->read.buffer + chunk_offset, byte_copied);
218223

219224
mutex_unlock(&coredump->lock);
220225

0 commit comments

Comments
 (0)