Skip to content

Commit 8f7e001

Browse files
RISC-V: Clean up the Zicbom block size probing
This fixes two issues: I truncated the warning's hart ID when porting to the 64-bit hart ID code, and the original code's warning handling could fire on an uninitialized hart ID. The biggest change here is that riscv_cbom_block_size is no longer initialized, as IMO the default isn't sane: there's nothing in the ISA that mandates any specific cache block size, so falling back to one will just silently produce the wrong answer on some systems. This also changes the probing order so the cache block size is known before enabling Zicbom support. CC: [email protected] CC: Andrew Jones <[email protected]> CC: Heiko Stuebner <[email protected]> CC: Atish Patra <[email protected]> Fixes: 3aefb2e ("riscv: implement Zicbom-based CMO instructions + the t-head variant") Fixes: 1631ba1 ("riscv: Add support for non-coherent devices using zicbom extension") Reported-by: kernel test robot <[email protected]> Reported-by: Conor Dooley <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]> [Conor: fixed the redefinition errors] Tested-by: Conor Dooley <[email protected]> Signed-off-by: Conor Dooley <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 20e0fba commit 8f7e001

File tree

4 files changed

+16
-11
lines changed

4 files changed

+16
-11
lines changed

arch/riscv/errata/thead/errata.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ static bool errata_probe_cmo(unsigned int stage,
3737
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
3838
return false;
3939

40+
riscv_cbom_block_size = L1_CACHE_BYTES;
4041
riscv_noncoherent_supported();
4142
return true;
4243
#else

arch/riscv/include/asm/cacheflush.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
4343
#endif /* CONFIG_SMP */
4444

4545
#ifdef CONFIG_RISCV_ISA_ZICBOM
46+
extern unsigned int riscv_cbom_block_size;
4647
void riscv_init_cbom_blocksize(void);
4748
#else
4849
static inline void riscv_init_cbom_blocksize(void) { }

arch/riscv/kernel/setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,8 @@ void __init setup_arch(char **cmdline_p)
296296
setup_smp();
297297
#endif
298298

299-
riscv_fill_hwcap();
300299
riscv_init_cbom_blocksize();
300+
riscv_fill_hwcap();
301301
apply_boot_alternatives();
302302
}
303303

arch/riscv/mm/dma-noncoherent.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include <linux/of_device.h>
1313
#include <asm/cacheflush.h>
1414

15-
static unsigned int riscv_cbom_block_size = L1_CACHE_BYTES;
15+
unsigned int riscv_cbom_block_size;
1616
static bool noncoherent_supported;
1717

1818
void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
@@ -79,38 +79,41 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
7979
void riscv_init_cbom_blocksize(void)
8080
{
8181
struct device_node *node;
82+
unsigned long cbom_hartid;
83+
u32 val, probed_block_size;
8284
int ret;
83-
u32 val;
8485

86+
probed_block_size = 0;
8587
for_each_of_cpu_node(node) {
8688
unsigned long hartid;
87-
int cbom_hartid;
8889

8990
ret = riscv_of_processor_hartid(node, &hartid);
9091
if (ret)
9192
continue;
9293

93-
if (hartid < 0)
94-
continue;
95-
9694
/* set block-size for cbom extension if available */
9795
ret = of_property_read_u32(node, "riscv,cbom-block-size", &val);
9896
if (ret)
9997
continue;
10098

101-
if (!riscv_cbom_block_size) {
102-
riscv_cbom_block_size = val;
99+
if (!probed_block_size) {
100+
probed_block_size = val;
103101
cbom_hartid = hartid;
104102
} else {
105-
if (riscv_cbom_block_size != val)
106-
pr_warn("cbom-block-size mismatched between harts %d and %lu\n",
103+
if (probed_block_size != val)
104+
pr_warn("cbom-block-size mismatched between harts %lu and %lu\n",
107105
cbom_hartid, hartid);
108106
}
109107
}
108+
109+
if (probed_block_size)
110+
riscv_cbom_block_size = probed_block_size;
110111
}
111112
#endif
112113

113114
void riscv_noncoherent_supported(void)
114115
{
116+
WARN(!riscv_cbom_block_size,
117+
"Non-coherent DMA support enabled without a block size\n");
115118
noncoherent_supported = true;
116119
}

0 commit comments

Comments
 (0)