diff options
author | Joshua Bakita <bakitajoshua@gmail.com> | 2023-07-18 10:49:19 -0400 |
---|---|---|
committer | Joshua Bakita <bakitajoshua@gmail.com> | 2023-07-18 10:49:19 -0400 |
commit | a1598f27a124cb0b5263276f7098ae3a68460b61 (patch) | |
tree | 8593b040bb609a67b8bab8dad745b59cbe8f16c9 /nvdebug.h | |
parent | 073e8978334a07e0053ee08310743ddf3046d7d2 (diff) |
Fail reads which return the flag value for a non-existent register
Also check for read success in get_runlist_iter().
Diffstat (limited to 'nvdebug.h')
-rw-r--r-- | nvdebug.h | 30 |
1 files changed, 21 insertions, 9 deletions
@@ -960,30 +960,42 @@ static inline int file2parentgpuidx(const struct file *f) { | |||
960 | // Similar to nvgpu_readl() | 960 | // Similar to nvgpu_readl() |
961 | // (except we don't try to resolve situations where regs is NULL) | 961 | // (except we don't try to resolve situations where regs is NULL) |
962 | static inline u32 nvdebug_readl(struct nvdebug_state *s, u32 r) { | 962 | static inline u32 nvdebug_readl(struct nvdebug_state *s, u32 r) { |
963 | u32 ret; | ||
963 | if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { | 964 | if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { |
964 | printk(KERN_ERR "[nvdebug] Attempted nvgpu_readl on non-existent registers!\n"); | 965 | printk(KERN_ERR "[nvdebug] nvdebug_readl: Unable to read; registers unavailable. Is GPU on?\n"); |
965 | return -1; | 966 | return -1; |
966 | } | 967 | } |
967 | return readl(s->regs + r); | 968 | ret = readl(s->regs + r); |
969 | // It seems like the GPU returns this as a flag value for bad addresses | ||
970 | if (ret == 0xbadf5040) { | ||
971 | printk(KERN_ERR "[nvdebug] nvdebug_readl: Unable to read from register offset %#x; bad data\n", r); | ||
972 | return -1; | ||
973 | } | ||
974 | return ret; | ||
968 | } | 975 | } |
969 | 976 | ||
970 | // quadword version of nvdebug_readl() | 977 | // quadword version of nvdebug_readl() |
971 | static inline u64 nvdebug_readq(struct nvdebug_state *s, u32 r) { | 978 | static inline u64 nvdebug_readq(struct nvdebug_state *s, u32 r) { |
972 | u64 ret; | 979 | u64 ret; |
973 | if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { | 980 | if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { |
974 | printk(KERN_ERR "[nvdebug] Attempted nvgpu_readl on non-existent registers!\n"); | 981 | printk(KERN_ERR "[nvdebug] nvdebug_readq: Unable to read; registers unavailable. Is GPU on?\n"); |
975 | return -1; | 982 | return -1; |
976 | } | 983 | } |
977 | // readq seems to always return the uppermost 32 bits as 0, so workaround with readl | 984 | // readq seems to always return the uppermost 32 bits as 0, so workaround with readl |
978 | ret = readl(s->regs + r); | 985 | ret = readl(s->regs + r); |
979 | ret |= ((u64)readl(s->regs + r + 4)) << 32; | 986 | ret |= ((u64)readl(s->regs + r + 4)) << 32; |
987 | // It seems like the GPU returns this as a flag value for bad addresses | ||
988 | if ((ret & 0xffffffffull) == 0xbadf5040ull) { | ||
989 | printk(KERN_ERR "[nvdebug] nvdebug_readq: Unable to read from register offset %#x; bad data\n", r); | ||
990 | return -1; | ||
991 | } | ||
980 | return ret; | 992 | return ret; |
981 | } | 993 | } |
982 | 994 | ||
983 | // Similar to nvgpu_writel() | 995 | // Similar to nvgpu_writel() |
984 | static inline void nvdebug_writel(struct nvdebug_state *s, u32 r, u32 v) { | 996 | static inline void nvdebug_writel(struct nvdebug_state *s, u32 r, u32 v) { |
985 | if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { | 997 | if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { |
986 | printk(KERN_ERR "[nvdebug] Attempted nvgpu_writel on non-existent registers!\n"); | 998 | printk(KERN_ERR "[nvdebug] nvdebug_writel: Unable to write; registers unavailable. Is GPU on?\n"); |
987 | return; | 999 | return; |
988 | } | 1000 | } |
989 | writel_relaxed(v, s->regs + r); | 1001 | writel_relaxed(v, s->regs + r); |
@@ -994,9 +1006,9 @@ static inline void nvdebug_writel(struct nvdebug_state *s, u32 r, u32 v) { | |||
994 | // XXX: This probably doesn't work XXX: Untested | 1006 | // XXX: This probably doesn't work XXX: Untested |
995 | static inline void nvdebug_writeq(struct nvdebug_state *s, u32 r, u64 v) { | 1007 | static inline void nvdebug_writeq(struct nvdebug_state *s, u32 r, u64 v) { |
996 | if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { | 1008 | if (unlikely(!s->regs || (s->g && !gk20a_regs(s->g)))) { |
997 | printk(KERN_ERR "[nvdebug] Attempted nvgpu_writel on non-existent registers!\n"); | 1009 | printk(KERN_ERR "[nvdebug] nvdebug_writeq: Unable to write; registers unavailable. Is GPU on?\n"); |
998 | return; | 1010 | return; |
999 | } | 1011 | } |
1000 | writeq_relaxed(v, s->regs + r); | 1012 | writeq_relaxed(v, s->regs + r); |
1001 | wmb(); | 1013 | wmb(); |
1002 | } | 1014 | } |