From: Ben Segal <bpsega...@gmail.com>

This patch fix a bug in the host memory polling macro. The bug is that the
memory being polled can be written by the device, which always writes it
in LE. However, if the host is running Linux in BE mode, we need to
convert the value that was written by the device before matching it to the
required value that the caller has given to the macro.

Signed-off-by: Ben Segal <bpsega...@gmail.com>
Reviewed-by: Oded Gabbay <oded.gab...@gmail.com>
Signed-off-by: Oded Gabbay <oded.gab...@gmail.com>
---
 drivers/misc/habanalabs/command_submission.c |  2 +-
 drivers/misc/habanalabs/firmware_if.c        |  3 ++-
 drivers/misc/habanalabs/goya/goya.c          |  5 +++--
 drivers/misc/habanalabs/habanalabs.h         | 16 ++++++++++++++--
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/misc/habanalabs/command_submission.c 
b/drivers/misc/habanalabs/command_submission.c
index 6ad83d5ef4b0..f00d1c32f6d6 100644
--- a/drivers/misc/habanalabs/command_submission.c
+++ b/drivers/misc/habanalabs/command_submission.c
@@ -683,7 +683,7 @@ int hl_cs_ioctl(struct hl_fpriv *hpriv, void *data)
 
                rc = hl_poll_timeout_memory(hdev,
                        &ctx->thread_ctx_switch_wait_token, tmp, (tmp == 1),
-                       100, jiffies_to_usecs(hdev->timeout_jiffies));
+                       100, jiffies_to_usecs(hdev->timeout_jiffies), false);
 
                if (rc == -ETIMEDOUT) {
                        dev_err(hdev->dev,
diff --git a/drivers/misc/habanalabs/firmware_if.c 
b/drivers/misc/habanalabs/firmware_if.c
index 61112eda4dd2..ea2ca67fbfbf 100644
--- a/drivers/misc/habanalabs/firmware_if.c
+++ b/drivers/misc/habanalabs/firmware_if.c
@@ -97,7 +97,8 @@ int hl_fw_send_cpu_message(struct hl_device *hdev, u32 
hw_queue_id, u32 *msg,
        }
 
        rc = hl_poll_timeout_memory(hdev, &pkt->fence, tmp,
-                               (tmp == ARMCP_PACKET_FENCE_VAL), 1000, timeout);
+                               (tmp == ARMCP_PACKET_FENCE_VAL), 1000,
+                               timeout, true);
 
        hl_hw_queue_inc_ci_kernel(hdev, hw_queue_id);
 
diff --git a/drivers/misc/habanalabs/goya/goya.c 
b/drivers/misc/habanalabs/goya/goya.c
index 1a2c062a57d4..a0e181714891 100644
--- a/drivers/misc/habanalabs/goya/goya.c
+++ b/drivers/misc/habanalabs/goya/goya.c
@@ -2864,7 +2864,8 @@ static int goya_send_job_on_qman0(struct hl_device *hdev, 
struct hl_cs_job *job)
        }
 
        rc = hl_poll_timeout_memory(hdev, fence_ptr, tmp,
-                               (tmp == GOYA_QMAN0_FENCE_VAL), 1000, timeout);
+                               (tmp == GOYA_QMAN0_FENCE_VAL), 1000,
+                               timeout, true);
 
        hl_hw_queue_inc_ci_kernel(hdev, GOYA_QUEUE_ID_DMA_0);
 
@@ -2945,7 +2946,7 @@ int goya_test_queue(struct hl_device *hdev, u32 
hw_queue_id)
        }
 
        rc = hl_poll_timeout_memory(hdev, fence_ptr, tmp, (tmp == fence_val),
-                                       1000, GOYA_TEST_QUEUE_WAIT_USEC);
+                                       1000, GOYA_TEST_QUEUE_WAIT_USEC, true);
 
        hl_hw_queue_inc_ci_kernel(hdev, hw_queue_id);
 
diff --git a/drivers/misc/habanalabs/habanalabs.h 
b/drivers/misc/habanalabs/habanalabs.h
index 10da9940ee0d..6a4c64b97f38 100644
--- a/drivers/misc/habanalabs/habanalabs.h
+++ b/drivers/misc/habanalabs/habanalabs.h
@@ -1062,9 +1062,17 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val);
 /*
  * address in this macro points always to a memory location in the
  * host's (server's) memory. That location is updated asynchronously
- * either by the direct access of the device or by another core
+ * either by the direct access of the device or by another core.
+ *
+ * To work both in LE and BE architectures, we need to distinguish between the
+ * two states (device or another core updates the memory location). Therefore,
+ * if mem_written_by_device is true, the host memory being polled will be
+ * updated directly by the device. If false, the host memory being polled will
+ * be updated by host CPU. Required so host knows whether or not the memory
+ * might need to be byte-swapped before returning value to caller.
  */
-#define hl_poll_timeout_memory(hdev, addr, val, cond, sleep_us, timeout_us) \
+#define hl_poll_timeout_memory(hdev, addr, val, cond, sleep_us, timeout_us, \
+                               mem_written_by_device) \
 ({ \
        ktime_t __timeout; \
        /* timeout should be longer when working with simulator */ \
@@ -1077,10 +1085,14 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val);
                /* Verify we read updates done by other cores or by device */ \
                mb(); \
                (val) = *((u32 *) (uintptr_t) (addr)); \
+               if (mem_written_by_device) \
+                       (val) = le32_to_cpu(val); \
                if (cond) \
                        break; \
                if (timeout_us && ktime_compare(ktime_get(), __timeout) > 0) { \
                        (val) = *((u32 *) (uintptr_t) (addr)); \
+                       if (mem_written_by_device) \
+                               (val) = le32_to_cpu(val); \
                        break; \
                } \
                if (sleep_us) \
-- 
2.17.1

Reply via email to