| From 4749844f8e36ad04ad08d7c0feac5d2c72bac2ae Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 30 Jan 2026 16:56:22 +0000 |
| Subject: drm/xe/mmio: Avoid double-adjust in 64-bit reads |
| |
| From: Shuicheng Lin <shuicheng.lin@intel.com> |
| |
| [ Upstream commit 4a9b4e1fa52a6aaa1adbb7f759048df14afed54c ] |
| |
| xe_mmio_read64_2x32() was adjusting register addresses and then |
| calling xe_mmio_read32(), which applies the adjustment again. |
| This may shift accesses twice if adj_offset < adj_limit. There is |
| no issue currently, as for media gt, adj_offset > adj_limit, so |
| the 2nd adjust will be a no-op. But it may not work in future. |
| |
| To fix it, replace the adjusted-address comparison with a direct |
| sanity check that ensures the MMIO address adjustment cutoff never |
| falls within the 8-byte range of a 64-bit register. And let |
| xe_mmio_read32() handle address translation. |
| |
| v2: rewrite the sanity check in a more natural way. (Matt) |
| v3: Add Fixes tag. (Jani) |
| |
| Fixes: 07431945d8ae ("drm/xe: Avoid 64-bit register reads") |
| Reviewed-by: Matt Roper <matthew.d.roper@intel.com> |
| Cc: Jani Nikula <jani.nikula@intel.com> |
| Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> |
| Signed-off-by: Shuicheng Lin <shuicheng.lin@intel.com> |
| Link: https://patch.msgid.link/20260130165621.471408-2-shuicheng.lin@intel.com |
| Signed-off-by: Matt Roper <matthew.d.roper@intel.com> |
| (cherry picked from commit a30f999681126b128a43137793ac84b6a5b7443f) |
| Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpu/drm/xe/xe_mmio.c | 10 +++++----- |
| 1 file changed, 5 insertions(+), 5 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c |
| index 350dca1f09259..3d59440ec44dd 100644 |
| --- a/drivers/gpu/drm/xe/xe_mmio.c |
| +++ b/drivers/gpu/drm/xe/xe_mmio.c |
| @@ -260,11 +260,11 @@ u64 xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg) |
| struct xe_reg reg_udw = { .addr = reg.addr + 0x4 }; |
| u32 ldw, udw, oldudw, retries; |
| |
| - reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr); |
| - reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr); |
| - |
| - /* we shouldn't adjust just one register address */ |
| - xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4); |
| + /* |
| + * The two dwords of a 64-bit register can never straddle the offset |
| + * adjustment cutoff. |
| + */ |
| + xe_tile_assert(mmio->tile, !in_range(mmio->adj_limit, reg.addr + 1, 7)); |
| |
| oldudw = xe_mmio_read32(mmio, reg_udw); |
| for (retries = 5; retries; --retries) { |
| -- |
| 2.51.0 |
| |