[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20231029225441.789781-43-sashal@kernel.org>
Date: Sun, 29 Oct 2023 18:53:30 -0400
From: Sasha Levin <sashal@...nel.org>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
Cc: Icenowy Zheng <uwu@...nowy.me>,
Huacai Chen <chenhuacai@...ngson.cn>,
Sasha Levin <sashal@...nel.org>, chenhuacai@...nel.org,
kernel@...0n.name, akpm@...ux-foundation.org, bhe@...hat.com,
rppt@...nel.org, willy@...radead.org, zhanghongchen@...ngson.cn,
david@...hat.com, zhoubinbin@...ngson.cn, donmor3000@...mail.com,
yangtiezhu@...ngson.cn, tangyouling@...ngson.cn,
tglx@...utronix.de, loongarch@...ts.linux.dev
Subject: [PATCH AUTOSEL 6.5 43/52] LoongArch: Disable WUC for pgprot_writecombine() like ioremap_wc()
From: Icenowy Zheng <uwu@...nowy.me>
[ Upstream commit 278be83601dd1725d4732241f066d528e160a39d ]
Currently the code disables WUC only disables it for ioremap_wc(), which
is only used when mapping writecombine pages like ioremap() (mapped to
the kernel space). But for VRAM mapped in TTM/GEM, it is mapped with a
crafted pgprot by the pgprot_writecombine() function, in which case WUC
isn't disabled now.
Disable WUC for pgprot_writecombine() (fallback to SUC) if needed, like
ioremap_wc().
This improves the AMDGPU driver's stability (solves some misrendering)
on Loongson-3A5000/3A6000 machines.
Signed-off-by: Icenowy Zheng <uwu@...nowy.me>
Signed-off-by: Huacai Chen <chenhuacai@...ngson.cn>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
arch/loongarch/include/asm/io.h | 5 ++---
arch/loongarch/include/asm/pgtable-bits.h | 4 +++-
arch/loongarch/kernel/setup.c | 10 +++++-----
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/arch/loongarch/include/asm/io.h b/arch/loongarch/include/asm/io.h
index 1c94102200407..0355b64e90ed0 100644
--- a/arch/loongarch/include/asm/io.h
+++ b/arch/loongarch/include/asm/io.h
@@ -54,10 +54,9 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
* @offset: bus address of the memory
* @size: size of the resource to map
*/
-extern pgprot_t pgprot_wc;
-
#define ioremap_wc(offset, size) \
- ioremap_prot((offset), (size), pgprot_val(pgprot_wc))
+ ioremap_prot((offset), (size), \
+ pgprot_val(wc_enabled ? PAGE_KERNEL_WUC : PAGE_KERNEL_SUC))
#define ioremap_cache(offset, size) \
ioremap_prot((offset), (size), pgprot_val(PAGE_KERNEL))
diff --git a/arch/loongarch/include/asm/pgtable-bits.h b/arch/loongarch/include/asm/pgtable-bits.h
index de46a6b1e9f11..7b9ac012cd090 100644
--- a/arch/loongarch/include/asm/pgtable-bits.h
+++ b/arch/loongarch/include/asm/pgtable-bits.h
@@ -105,13 +105,15 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)
return __pgprot(prot);
}
+extern bool wc_enabled;
+
#define pgprot_writecombine pgprot_writecombine
static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
{
unsigned long prot = pgprot_val(_prot);
- prot = (prot & ~_CACHE_MASK) | _CACHE_WUC;
+ prot = (prot & ~_CACHE_MASK) | (wc_enabled ? _CACHE_WUC : _CACHE_SUC);
return __pgprot(prot);
}
diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
index 9d830ab4e3025..1351614042d4e 100644
--- a/arch/loongarch/kernel/setup.c
+++ b/arch/loongarch/kernel/setup.c
@@ -161,19 +161,19 @@ static void __init smbios_parse(void)
}
#ifdef CONFIG_ARCH_WRITECOMBINE
-pgprot_t pgprot_wc = PAGE_KERNEL_WUC;
+bool wc_enabled = true;
#else
-pgprot_t pgprot_wc = PAGE_KERNEL_SUC;
+bool wc_enabled = false;
#endif
-EXPORT_SYMBOL(pgprot_wc);
+EXPORT_SYMBOL(wc_enabled);
static int __init setup_writecombine(char *p)
{
if (!strcmp(p, "on"))
- pgprot_wc = PAGE_KERNEL_WUC;
+ wc_enabled = true;
else if (!strcmp(p, "off"))
- pgprot_wc = PAGE_KERNEL_SUC;
+ wc_enabled = false;
else
pr_warn("Unknown writecombine setting \"%s\".\n", p);
--
2.42.0
Powered by blists - more mailing lists