From: Gao Xiang hsiangkao@redhat.com
commit 3c597282887fd55181578996dca52ce697d985a5 upstream.
Hongyu reported "id != index" in z_erofs_onlinepage_fixup() with specific aarch64 environment easily, which wasn't shown before.
After digging into that, I found that high 32 bits of page->private was set to 0xaaaaaaaa rather than 0 (due to z_erofs_onlinepage_init behavior with specific compiler options). Actually we only use low 32 bits to keep the page information since page->private is only 4 bytes on most 32-bit platforms. However z_erofs_onlinepage_fixup() uses the upper 32 bits by mistake.
Let's fix it now.
Reported-and-tested-by: Hongyu Jin hongyu.jin@unisoc.com Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support") Cc: stable@vger.kernel.org # 4.19+ Reviewed-by: Chao Yu yuchao0@huawei.com Link: https://lore.kernel.org/r/20200618234349.22553-1-hsiangkao@aol.com Signed-off-by: Gao Xiang hsiangkao@redhat.com --- This fix has been merged into Linus's tree just now (today). Since the patch could not directly be applied to 4.19, manually handle this.
drivers/staging/erofs/unzip_vle.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/staging/erofs/unzip_vle.h b/drivers/staging/erofs/unzip_vle.h index 684ff06fc7bf..630fd1f4f123 100644 --- a/drivers/staging/erofs/unzip_vle.h +++ b/drivers/staging/erofs/unzip_vle.h @@ -169,22 +169,22 @@ static inline void z_erofs_onlinepage_init(struct page *page) static inline void z_erofs_onlinepage_fixup(struct page *page, uintptr_t index, bool down) { - unsigned long *p, o, v, id; -repeat: - p = &page_private(page); - o = READ_ONCE(*p); + union z_erofs_onlinepage_converter u = { .v = &page_private(page) }; + int orig, orig_index, val;
- id = o >> Z_EROFS_ONLINEPAGE_INDEX_SHIFT; - if (id) { +repeat: + orig = atomic_read(u.o); + orig_index = orig >> Z_EROFS_ONLINEPAGE_INDEX_SHIFT; + if (orig_index) { if (!index) return;
- BUG_ON(id != index); + DBG_BUGON(orig_index != index); }
- v = (index << Z_EROFS_ONLINEPAGE_INDEX_SHIFT) | - ((o & Z_EROFS_ONLINEPAGE_COUNT_MASK) + (unsigned)down); - if (cmpxchg(p, o, v) != o) + val = (index << Z_EROFS_ONLINEPAGE_INDEX_SHIFT) | + ((orig & Z_EROFS_ONLINEPAGE_COUNT_MASK) + (unsigned int)down); + if (atomic_cmpxchg(u.o, orig, val) != orig) goto repeat; }
Hi Greg, Sasha
On Thu, Jun 25, 2020 at 01:19:39PM +0800, Gao Xiang via Linux-erofs wrote:
From: Gao Xiang hsiangkao@redhat.com
commit 3c597282887fd55181578996dca52ce697d985a5 upstream.
Hongyu reported "id != index" in z_erofs_onlinepage_fixup() with specific aarch64 environment easily, which wasn't shown before.
After digging into that, I found that high 32 bits of page->private was set to 0xaaaaaaaa rather than 0 (due to z_erofs_onlinepage_init behavior with specific compiler options). Actually we only use low 32 bits to keep the page information since page->private is only 4 bytes on most 32-bit platforms. However z_erofs_onlinepage_fixup() uses the upper 32 bits by mistake.
Let's fix it now.
Reported-and-tested-by: Hongyu Jin hongyu.jin@unisoc.com Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support") Cc: stable@vger.kernel.org # 4.19+ Reviewed-by: Chao Yu yuchao0@huawei.com Link: https://lore.kernel.org/r/20200618234349.22553-1-hsiangkao@aol.com Signed-off-by: Gao Xiang hsiangkao@redhat.com
This fix has been merged into Linus's tree just now (today). Since the patch could not directly be applied to 4.19, manually handle this.
Could this patch be applied to all next version stable versions (4.19, 5.4 as well as 5.7) after 5.8-rc3 is out...
It's some important fix on specific compiler options and should be fixed ASAP.
Without this patch, unexpected behaviors would happen conditionally and break the filesystem from working. Apart from 4.19 patch, both 5.4 and 5.7 patches are quite trivial ones (can be cherry-picked directly).
Could kindly consider this and it's just a little heads-up... Sorry for the noise if it's already in queue... Thanks!
Thanks, Gao Xiang
On Mon, Jun 29, 2020 at 08:33:13AM +0800, Gao Xiang wrote:
Hi Greg, Sasha
On Thu, Jun 25, 2020 at 01:19:39PM +0800, Gao Xiang via Linux-erofs wrote:
From: Gao Xiang hsiangkao@redhat.com
commit 3c597282887fd55181578996dca52ce697d985a5 upstream.
Hongyu reported "id != index" in z_erofs_onlinepage_fixup() with specific aarch64 environment easily, which wasn't shown before.
After digging into that, I found that high 32 bits of page->private was set to 0xaaaaaaaa rather than 0 (due to z_erofs_onlinepage_init behavior with specific compiler options). Actually we only use low 32 bits to keep the page information since page->private is only 4 bytes on most 32-bit platforms. However z_erofs_onlinepage_fixup() uses the upper 32 bits by mistake.
Let's fix it now.
Reported-and-tested-by: Hongyu Jin hongyu.jin@unisoc.com Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support") Cc: stable@vger.kernel.org # 4.19+ Reviewed-by: Chao Yu yuchao0@huawei.com Link: https://lore.kernel.org/r/20200618234349.22553-1-hsiangkao@aol.com Signed-off-by: Gao Xiang hsiangkao@redhat.com
This fix has been merged into Linus's tree just now (today). Since the patch could not directly be applied to 4.19, manually handle this.
Could this patch be applied to all next version stable versions (4.19, 5.4 as well as 5.7) after 5.8-rc3 is out...
It's some important fix on specific compiler options and should be fixed ASAP.
Without this patch, unexpected behaviors would happen conditionally and break the filesystem from working. Apart from 4.19 patch, both 5.4 and 5.7 patches are quite trivial ones (can be cherry-picked directly).
Could kindly consider this and it's just a little heads-up... Sorry for the noise if it's already in queue...
Please let us catch up on patches, there's been a lot of them recently for some reason...
greg k-h
linux-stable-mirror@lists.linaro.org