aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/Kconfig1
-rw-r--r--arch/riscv/Kconfig.erratas4
-rw-r--r--arch/riscv/errata/thead/errata.c1
-rw-r--r--arch/riscv/include/asm/cacheflush.h5
-rw-r--r--arch/riscv/kernel/setup.c2
-rw-r--r--arch/riscv/kernel/signal.c2
-rw-r--r--arch/riscv/mm/dma-noncoherent.c23
7 files changed, 25 insertions, 13 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index ed66c31e4655..59d18881f35b 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -386,6 +386,7 @@ config RISCV_ISA_C
config RISCV_ISA_SVPBMT
bool "SVPBMT extension support"
depends on 64BIT && MMU
+ depends on !XIP_KERNEL
select RISCV_ALTERNATIVE
default y
help
diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas
index 6850e9389930..f3623df23b5f 100644
--- a/arch/riscv/Kconfig.erratas
+++ b/arch/riscv/Kconfig.erratas
@@ -46,7 +46,7 @@ config ERRATA_THEAD
config ERRATA_THEAD_PBMT
bool "Apply T-Head memory type errata"
- depends on ERRATA_THEAD && 64BIT
+ depends on ERRATA_THEAD && 64BIT && MMU
select RISCV_ALTERNATIVE_EARLY
default y
help
@@ -57,7 +57,7 @@ config ERRATA_THEAD_PBMT
config ERRATA_THEAD_CMO
bool "Apply T-Head cache management errata"
- depends on ERRATA_THEAD
+ depends on ERRATA_THEAD && MMU
select RISCV_DMA_NONCOHERENT
default y
help
diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c
index 202c83f677b2..96648c176f37 100644
--- a/arch/riscv/errata/thead/errata.c
+++ b/arch/riscv/errata/thead/errata.c
@@ -37,6 +37,7 @@ static bool errata_probe_cmo(unsigned int stage,
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
return false;
+ riscv_cbom_block_size = L1_CACHE_BYTES;
riscv_noncoherent_supported();
return true;
#else
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
index a60acaecfeda..273ece6b622f 100644
--- a/arch/riscv/include/asm/cacheflush.h
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -42,6 +42,11 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
#endif /* CONFIG_SMP */
+/*
+ * The T-Head CMO errata internally probe the CBOM block size, but otherwise
+ * don't depend on Zicbom.
+ */
+extern unsigned int riscv_cbom_block_size;
#ifdef CONFIG_RISCV_ISA_ZICBOM
void riscv_init_cbom_blocksize(void);
#else
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index 95ef6e2bf45c..2dfc463b86bb 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -296,8 +296,8 @@ void __init setup_arch(char **cmdline_p)
setup_smp();
#endif
- riscv_fill_hwcap();
riscv_init_cbom_blocksize();
+ riscv_fill_hwcap();
apply_boot_alternatives();
}
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index 5a2de6b6f882..5c591123c440 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -124,6 +124,8 @@ SYSCALL_DEFINE0(rt_sigreturn)
if (restore_altstack(&frame->uc.uc_stack))
goto badframe;
+ regs->cause = -1UL;
+
return regs->a0;
badframe:
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
index cd2225304c82..e3f9bdf47c5f 100644
--- a/arch/riscv/mm/dma-noncoherent.c
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -12,7 +12,7 @@
#include <linux/of_device.h>
#include <asm/cacheflush.h>
-static unsigned int riscv_cbom_block_size = L1_CACHE_BYTES;
+unsigned int riscv_cbom_block_size;
static bool noncoherent_supported;
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,
void riscv_init_cbom_blocksize(void)
{
struct device_node *node;
+ unsigned long cbom_hartid;
+ u32 val, probed_block_size;
int ret;
- u32 val;
+ probed_block_size = 0;
for_each_of_cpu_node(node) {
unsigned long hartid;
- int cbom_hartid;
ret = riscv_of_processor_hartid(node, &hartid);
if (ret)
continue;
- if (hartid < 0)
- continue;
-
/* set block-size for cbom extension if available */
ret = of_property_read_u32(node, "riscv,cbom-block-size", &val);
if (ret)
continue;
- if (!riscv_cbom_block_size) {
- riscv_cbom_block_size = val;
+ if (!probed_block_size) {
+ probed_block_size = val;
cbom_hartid = hartid;
} else {
- if (riscv_cbom_block_size != val)
- pr_warn("cbom-block-size mismatched between harts %d and %lu\n",
+ if (probed_block_size != val)
+ pr_warn("cbom-block-size mismatched between harts %lu and %lu\n",
cbom_hartid, hartid);
}
}
+
+ if (probed_block_size)
+ riscv_cbom_block_size = probed_block_size;
}
#endif
void riscv_noncoherent_supported(void)
{
+ WARN(!riscv_cbom_block_size,
+ "Non-coherent DMA support enabled without a block size\n");
noncoherent_supported = true;
}