mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 08:15:07 -04:00
drm/xe/mmio: Verify MMIO is available
We shouldn't access device registers after the device was unplugged or the MMIO bar (GTTMMADR) was unmapped. Instead of relying on the NPD splat due to zeroed tile->mmio.regs, which might be unreliable anyway as not all xe_mmio structs are using that directly, add an explicit check during all xe_mmio read/write operations to test if xe->mmio.regs are still mapped and safely abort with WARN if not. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Matthew Auld <matthew.auld@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patch.msgid.link/20260622132342.19600-2-michal.wajdeczko@intel.com
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "xe_device.h"
|
||||
#include "xe_gt_sriov_vf.h"
|
||||
#include "xe_sriov.h"
|
||||
#include "xe_tile_printk.h"
|
||||
#include "xe_trace.h"
|
||||
#include "xe_wa.h"
|
||||
|
||||
@@ -128,6 +129,11 @@ void xe_mmio_init(struct xe_mmio *mmio, struct xe_tile *tile, void __iomem *ptr,
|
||||
mmio->tile = tile;
|
||||
}
|
||||
|
||||
static bool mmio_available(struct xe_mmio *mmio)
|
||||
{
|
||||
return !xe_tile_WARN_ON_ONCE(mmio->tile, !mmio->tile->xe->mmio.regs);
|
||||
}
|
||||
|
||||
static void mmio_flush_pending_writes(struct xe_mmio *mmio)
|
||||
{
|
||||
#define DUMMY_REG_OFFSET 0x130030
|
||||
@@ -146,6 +152,9 @@ u8 xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg)
|
||||
u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr);
|
||||
u8 val;
|
||||
|
||||
if (!mmio_available(mmio))
|
||||
return 0;
|
||||
|
||||
mmio_flush_pending_writes(mmio);
|
||||
|
||||
val = readb(mmio->regs + addr);
|
||||
@@ -158,6 +167,9 @@ void xe_mmio_write8(struct xe_mmio *mmio, struct xe_reg reg, u8 val)
|
||||
{
|
||||
u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr);
|
||||
|
||||
if (!mmio_available(mmio))
|
||||
return;
|
||||
|
||||
trace_xe_reg_rw(mmio, true, addr, val, sizeof(val));
|
||||
|
||||
writeb(val, mmio->regs + addr);
|
||||
@@ -168,6 +180,9 @@ u16 xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg)
|
||||
u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr);
|
||||
u16 val;
|
||||
|
||||
if (!mmio_available(mmio))
|
||||
return 0;
|
||||
|
||||
mmio_flush_pending_writes(mmio);
|
||||
|
||||
val = readw(mmio->regs + addr);
|
||||
@@ -180,6 +195,9 @@ void xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val)
|
||||
{
|
||||
u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr);
|
||||
|
||||
if (!mmio_available(mmio))
|
||||
return;
|
||||
|
||||
trace_xe_reg_rw(mmio, true, addr, val, sizeof(val));
|
||||
|
||||
if (!reg.vf && IS_SRIOV_VF(mmio->tile->xe))
|
||||
@@ -194,6 +212,9 @@ u32 xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg)
|
||||
u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr);
|
||||
u32 val;
|
||||
|
||||
if (!mmio_available(mmio))
|
||||
return 0;
|
||||
|
||||
mmio_flush_pending_writes(mmio);
|
||||
|
||||
if (!reg.vf && IS_SRIOV_VF(mmio->tile->xe))
|
||||
|
||||
Reference in New Issue
Block a user