From: Ahmad Masri <[email protected]>

All wil6210 device memory access should be 4 bytes aligned. In io
blob wil6210 did not force alignment for read function, this caused
alignment fault on some platforms.
Fixing that by accessing all 4 lower bytes and return to host the
requested data.

Signed-off-by: Ahmad Masri <[email protected]>
Signed-off-by: Maya Erez <[email protected]>
---
 drivers/net/wireless/ath/wil6210/debugfs.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c 
b/drivers/net/wireless/ath/wil6210/debugfs.c
index 099a04b..20dd4d0 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -664,10 +664,10 @@ static ssize_t wil_read_file_ioblob(struct file *file, 
char __user *user_buf,
        enum { max_count = 4096 };
        struct wil_blob_wrapper *wil_blob = file->private_data;
        struct wil6210_priv *wil = wil_blob->wil;
-       loff_t pos = *ppos;
+       loff_t aligned_pos, pos = *ppos;
        size_t available = wil_blob->blob.size;
        void *buf;
-       size_t ret;
+       size_t unaligned_bytes, aligned_count, ret;
        int rc;
 
        if (test_bit(wil_status_suspending, wil_blob->wil->status) ||
@@ -685,7 +685,12 @@ static ssize_t wil_read_file_ioblob(struct file *file, 
char __user *user_buf,
        if (count > max_count)
                count = max_count;
 
-       buf = kmalloc(count, GFP_KERNEL);
+       /* set pos to 4 bytes aligned */
+       unaligned_bytes = pos % 4;
+       aligned_pos = pos - unaligned_bytes;
+       aligned_count = count + unaligned_bytes;
+
+       buf = kmalloc(aligned_count, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
 
@@ -696,9 +701,9 @@ static ssize_t wil_read_file_ioblob(struct file *file, char 
__user *user_buf,
        }
 
        wil_memcpy_fromio_32(buf, (const void __iomem *)
-                            wil_blob->blob.data + pos, count);
+                            wil_blob->blob.data + aligned_pos, aligned_count);
 
-       ret = copy_to_user(user_buf, buf, count);
+       ret = copy_to_user(user_buf, buf + unaligned_bytes, count);
 
        wil_pm_runtime_put(wil);
 
-- 
1.9.1

Reply via email to