RISC-V Fixes for 6.9-rc6
* A fix for TASK_SIZE on rv64/NOMMU, to reflect the lack of user/kernel separation. * A fix to avoid loading rv64/NOMMU kernel past the start of RAM. * A fix for RISCV_HWPROBE_EXT_ZVFHMIN on ilp32 to avoid signed integer overflow in the bitmask. * The sud_test kselftest has been fixed to properly swizzle the syscall number into the return register, which are not the same on RISC-V. * A fix for a build warning in the perf tools on rv32. * A fix for the CBO selftests, to avoid non-constants leaking into the inline asm. * A pair of fixes for T-Head PBMT errata probing, which has been renamed MAE by the vendor. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAmYr5BMTHHBhbG1lckBk YWJiZWx0LmNvbQAKCRAuExnzX7sYiVx+D/90GjeSGgPT25uJnGWIETJD/yn4V1IY RQ0/4J5ET+/VnzcZXRrBtrTSuy7YDbIhXMIABMl9hP1vkXcF9BvPxqKys1MdgATf mlqRt6Ue1N1HO7HRxWSq7oTHTR5omg0MGykbmL+1yl/EBu6d45wEU23TQSWRGM27 O1IjjcjMGh3McoxSsczkSShuHi2NWox4vbRIOdNJyVC0wszzj5a/yLU7ZcPjGwsG hb33tEw2S8wd59aStUXHXRYFqxe8q42wx5F5ODpp5PILwmbXWY2f8VcHwJPjUHCz clS/7ogdrJHtlxc0td1QPSlw0IZEf7kqIHKgKdj9HwDG2LutrZNEX3iiJVrw1F6k fLbbwSKcVk17kkx+WqEk+c4ePLSfsKQqb5GyZKqMVMjgpToLraquQc7dIpzIhpxO gj+Xs6mGDz3Vo6luOKhcjaP+dyRF3W9a6Ufc0InwQHsJwHb8rI0iSo8Kw5mZMHa1 iok8+z5lXpOkvXlBOGwpndObFqCDOyeP0v8Qf/+GC0c9MulRv+I1i2zjki5p7B9g 9u8iEuMvkLvGEIYQxNUk5L/PJ98MGrwsHtjucNCuJNH4i5euH0RFXtKsKaM0O6bO NOq/kj/7ElQ+RyB5Q58G/fLmRtexqHbSsULY92uwzzTiVS2S/tZ32uBU+rACG2G7 mzHuKBo4jRKS9Q== =LONm -----END PGP SIGNATURE----- Merge tag 'riscv-for-linus-6.9-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux Pull RISC-V fixes from Palmer Dabbelt: - A fix for TASK_SIZE on rv64/NOMMU, to reflect the lack of user/kernel separation - A fix to avoid loading rv64/NOMMU kernel past the start of RAM - A fix for RISCV_HWPROBE_EXT_ZVFHMIN on ilp32 to avoid signed integer overflow in the bitmask - The sud_test kselftest has been fixed to properly swizzle the syscall number into the return register, which are not the same on RISC-V - A fix for a build warning in the perf tools on rv32 - A fix for the CBO selftests, to avoid non-constants leaking into the inline asm - A pair of fixes for T-Head PBMT errata probing, which has been renamed MAE by the vendor * tag 'riscv-for-linus-6.9-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: RISC-V: selftests: cbo: Ensure asm operands match constraints, take 2 perf riscv: Fix the warning due to the incompatible type riscv: T-Head: Test availability bit before enabling MAE errata riscv: thead: Rename T-Head PBMT to MAE selftests: sud_test: return correct emulated syscall value on RISC-V riscv: hwprobe: fix invalid sign extension for RISCV_HWPROBE_EXT_ZVFHMIN riscv: Fix loading 64-bit NOMMU kernels past the start of RAM riscv: Fix TASK_SIZE on 64-bit NOMMU
This commit is contained in:
commit
57865f3970
|
@ -82,14 +82,14 @@ config ERRATA_THEAD
|
||||||
|
|
||||||
Otherwise, please say "N" here to avoid unnecessary overhead.
|
Otherwise, please say "N" here to avoid unnecessary overhead.
|
||||||
|
|
||||||
config ERRATA_THEAD_PBMT
|
config ERRATA_THEAD_MAE
|
||||||
bool "Apply T-Head memory type errata"
|
bool "Apply T-Head's memory attribute extension (XTheadMae) errata"
|
||||||
depends on ERRATA_THEAD && 64BIT && MMU
|
depends on ERRATA_THEAD && 64BIT && MMU
|
||||||
select RISCV_ALTERNATIVE_EARLY
|
select RISCV_ALTERNATIVE_EARLY
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
This will apply the memory type errata to handle the non-standard
|
This will apply the memory attribute extension errata to handle the
|
||||||
memory type bits in page-table-entries on T-Head SoCs.
|
non-standard PTE utilization on T-Head SoCs (XTheadMae).
|
||||||
|
|
||||||
If you don't know what to do here, say "Y".
|
If you don't know what to do here, say "Y".
|
||||||
|
|
||||||
|
|
|
@ -19,20 +19,26 @@
|
||||||
#include <asm/patch.h>
|
#include <asm/patch.h>
|
||||||
#include <asm/vendorid_list.h>
|
#include <asm/vendorid_list.h>
|
||||||
|
|
||||||
static bool errata_probe_pbmt(unsigned int stage,
|
#define CSR_TH_SXSTATUS 0x5c0
|
||||||
unsigned long arch_id, unsigned long impid)
|
#define SXSTATUS_MAEE _AC(0x200000, UL)
|
||||||
|
|
||||||
|
static bool errata_probe_mae(unsigned int stage,
|
||||||
|
unsigned long arch_id, unsigned long impid)
|
||||||
{
|
{
|
||||||
if (!IS_ENABLED(CONFIG_ERRATA_THEAD_PBMT))
|
if (!IS_ENABLED(CONFIG_ERRATA_THEAD_MAE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (arch_id != 0 || impid != 0)
|
if (arch_id != 0 || impid != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT ||
|
if (stage != RISCV_ALTERNATIVES_EARLY_BOOT &&
|
||||||
stage == RISCV_ALTERNATIVES_MODULE)
|
stage != RISCV_ALTERNATIVES_MODULE)
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
return false;
|
if (!(csr_read(CSR_TH_SXSTATUS) & SXSTATUS_MAEE))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -140,8 +146,8 @@ static u32 thead_errata_probe(unsigned int stage,
|
||||||
{
|
{
|
||||||
u32 cpu_req_errata = 0;
|
u32 cpu_req_errata = 0;
|
||||||
|
|
||||||
if (errata_probe_pbmt(stage, archid, impid))
|
if (errata_probe_mae(stage, archid, impid))
|
||||||
cpu_req_errata |= BIT(ERRATA_THEAD_PBMT);
|
cpu_req_errata |= BIT(ERRATA_THEAD_MAE);
|
||||||
|
|
||||||
errata_probe_cmo(stage, archid, impid);
|
errata_probe_cmo(stage, archid, impid);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ERRATA_THEAD
|
#ifdef CONFIG_ERRATA_THEAD
|
||||||
#define ERRATA_THEAD_PBMT 0
|
#define ERRATA_THEAD_MAE 0
|
||||||
#define ERRATA_THEAD_PMU 1
|
#define ERRATA_THEAD_PMU 1
|
||||||
#define ERRATA_THEAD_NUMBER 2
|
#define ERRATA_THEAD_NUMBER 2
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,20 +53,20 @@ asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID, \
|
||||||
* in the default case.
|
* in the default case.
|
||||||
*/
|
*/
|
||||||
#define ALT_SVPBMT_SHIFT 61
|
#define ALT_SVPBMT_SHIFT 61
|
||||||
#define ALT_THEAD_PBMT_SHIFT 59
|
#define ALT_THEAD_MAE_SHIFT 59
|
||||||
#define ALT_SVPBMT(_val, prot) \
|
#define ALT_SVPBMT(_val, prot) \
|
||||||
asm(ALTERNATIVE_2("li %0, 0\t\nnop", \
|
asm(ALTERNATIVE_2("li %0, 0\t\nnop", \
|
||||||
"li %0, %1\t\nslli %0,%0,%3", 0, \
|
"li %0, %1\t\nslli %0,%0,%3", 0, \
|
||||||
RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT, \
|
RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT, \
|
||||||
"li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID, \
|
"li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID, \
|
||||||
ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \
|
ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE) \
|
||||||
: "=r"(_val) \
|
: "=r"(_val) \
|
||||||
: "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT), \
|
: "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT), \
|
||||||
"I"(prot##_THEAD >> ALT_THEAD_PBMT_SHIFT), \
|
"I"(prot##_THEAD >> ALT_THEAD_MAE_SHIFT), \
|
||||||
"I"(ALT_SVPBMT_SHIFT), \
|
"I"(ALT_SVPBMT_SHIFT), \
|
||||||
"I"(ALT_THEAD_PBMT_SHIFT))
|
"I"(ALT_THEAD_MAE_SHIFT))
|
||||||
|
|
||||||
#ifdef CONFIG_ERRATA_THEAD_PBMT
|
#ifdef CONFIG_ERRATA_THEAD_MAE
|
||||||
/*
|
/*
|
||||||
* IO/NOCACHE memory types are handled together with svpbmt,
|
* IO/NOCACHE memory types are handled together with svpbmt,
|
||||||
* so on T-Head chips, check if no other memory type is set,
|
* so on T-Head chips, check if no other memory type is set,
|
||||||
|
@ -83,11 +83,11 @@ asm volatile(ALTERNATIVE( \
|
||||||
"slli t3, t3, %3\n\t" \
|
"slli t3, t3, %3\n\t" \
|
||||||
"or %0, %0, t3\n\t" \
|
"or %0, %0, t3\n\t" \
|
||||||
"2:", THEAD_VENDOR_ID, \
|
"2:", THEAD_VENDOR_ID, \
|
||||||
ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \
|
ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE) \
|
||||||
: "+r"(_val) \
|
: "+r"(_val) \
|
||||||
: "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_PBMT_SHIFT), \
|
: "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_MAE_SHIFT), \
|
||||||
"I"(_PAGE_PMA_THEAD >> ALT_THEAD_PBMT_SHIFT), \
|
"I"(_PAGE_PMA_THEAD >> ALT_THEAD_MAE_SHIFT), \
|
||||||
"I"(ALT_THEAD_PBMT_SHIFT) \
|
"I"(ALT_THEAD_MAE_SHIFT) \
|
||||||
: "t3")
|
: "t3")
|
||||||
#else
|
#else
|
||||||
#define ALT_THEAD_PMA(_val)
|
#define ALT_THEAD_PMA(_val)
|
||||||
|
|
|
@ -89,7 +89,7 @@ typedef struct page *pgtable_t;
|
||||||
#define PTE_FMT "%08lx"
|
#define PTE_FMT "%08lx"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
#if defined(CONFIG_64BIT) && defined(CONFIG_MMU)
|
||||||
/*
|
/*
|
||||||
* We override this value as its generic definition uses __pa too early in
|
* We override this value as its generic definition uses __pa too early in
|
||||||
* the boot process (before kernel_map.va_pa_offset is set).
|
* the boot process (before kernel_map.va_pa_offset is set).
|
||||||
|
|
|
@ -896,7 +896,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
|
||||||
#define PAGE_SHARED __pgprot(0)
|
#define PAGE_SHARED __pgprot(0)
|
||||||
#define PAGE_KERNEL __pgprot(0)
|
#define PAGE_KERNEL __pgprot(0)
|
||||||
#define swapper_pg_dir NULL
|
#define swapper_pg_dir NULL
|
||||||
#define TASK_SIZE 0xffffffffUL
|
#define TASK_SIZE _AC(-1, UL)
|
||||||
#define VMALLOC_START _AC(0, UL)
|
#define VMALLOC_START _AC(0, UL)
|
||||||
#define VMALLOC_END TASK_SIZE
|
#define VMALLOC_END TASK_SIZE
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ struct riscv_hwprobe {
|
||||||
#define RISCV_HWPROBE_EXT_ZFHMIN (1 << 28)
|
#define RISCV_HWPROBE_EXT_ZFHMIN (1 << 28)
|
||||||
#define RISCV_HWPROBE_EXT_ZIHINTNTL (1 << 29)
|
#define RISCV_HWPROBE_EXT_ZIHINTNTL (1 << 29)
|
||||||
#define RISCV_HWPROBE_EXT_ZVFH (1 << 30)
|
#define RISCV_HWPROBE_EXT_ZVFH (1 << 30)
|
||||||
#define RISCV_HWPROBE_EXT_ZVFHMIN (1 << 31)
|
#define RISCV_HWPROBE_EXT_ZVFHMIN (1ULL << 31)
|
||||||
#define RISCV_HWPROBE_EXT_ZFA (1ULL << 32)
|
#define RISCV_HWPROBE_EXT_ZFA (1ULL << 32)
|
||||||
#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
|
#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
|
||||||
#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
|
#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
|
||||||
|
|
|
@ -231,7 +231,7 @@ static void __init setup_bootmem(void)
|
||||||
* In 64-bit, any use of __va/__pa before this point is wrong as we
|
* In 64-bit, any use of __va/__pa before this point is wrong as we
|
||||||
* did not know the start of DRAM before.
|
* did not know the start of DRAM before.
|
||||||
*/
|
*/
|
||||||
if (IS_ENABLED(CONFIG_64BIT))
|
if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU))
|
||||||
kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base;
|
kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -41,7 +41,7 @@ static char *_get_cpuid(void)
|
||||||
char *mimpid = NULL;
|
char *mimpid = NULL;
|
||||||
char *cpuid = NULL;
|
char *cpuid = NULL;
|
||||||
int read;
|
int read;
|
||||||
unsigned long line_sz;
|
size_t line_sz;
|
||||||
FILE *cpuinfo;
|
FILE *cpuinfo;
|
||||||
|
|
||||||
cpuinfo = fopen(CPUINFO, "r");
|
cpuinfo = fopen(CPUINFO, "r");
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "hwprobe.h"
|
#include "hwprobe.h"
|
||||||
#include "../../kselftest.h"
|
#include "../../kselftest.h"
|
||||||
|
|
||||||
#define MK_CBO(fn) cpu_to_le32((fn) << 20 | 10 << 15 | 2 << 12 | 0 << 7 | 15)
|
#define MK_CBO(fn) le32_bswap((uint32_t)(fn) << 20 | 10 << 15 | 2 << 12 | 0 << 7 | 15)
|
||||||
|
|
||||||
static char mem[4096] __aligned(4096) = { [0 ... 4095] = 0xa5 };
|
static char mem[4096] __aligned(4096) = { [0 ... 4095] = 0xa5 };
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,16 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <asm/hwprobe.h>
|
#include <asm/hwprobe.h>
|
||||||
|
|
||||||
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
|
# define le32_bswap(_x) \
|
||||||
|
((((_x) & 0x000000ffU) << 24) | \
|
||||||
|
(((_x) & 0x0000ff00U) << 8) | \
|
||||||
|
(((_x) & 0x00ff0000U) >> 8) | \
|
||||||
|
(((_x) & 0xff000000U) >> 24))
|
||||||
|
#else
|
||||||
|
# define le32_bswap(_x) (_x)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rather than relying on having a new enough libc to define this, just do it
|
* Rather than relying on having a new enough libc to define this, just do it
|
||||||
* ourselves. This way we don't need to be coupled to a new-enough libc to
|
* ourselves. This way we don't need to be coupled to a new-enough libc to
|
||||||
|
|
|
@ -158,6 +158,20 @@ static void handle_sigsys(int sig, siginfo_t *info, void *ucontext)
|
||||||
|
|
||||||
/* In preparation for sigreturn. */
|
/* In preparation for sigreturn. */
|
||||||
SYSCALL_DISPATCH_OFF(glob_sel);
|
SYSCALL_DISPATCH_OFF(glob_sel);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The tests for argument handling assume that `syscall(x) == x`. This
|
||||||
|
* is a NOP on x86 because the syscall number is passed in %rax, which
|
||||||
|
* happens to also be the function ABI return register. Other
|
||||||
|
* architectures may need to swizzle the arguments around.
|
||||||
|
*/
|
||||||
|
#if defined(__riscv)
|
||||||
|
/* REG_A7 is not defined in libc headers */
|
||||||
|
# define REG_A7 (REG_A0 + 7)
|
||||||
|
|
||||||
|
((ucontext_t *)ucontext)->uc_mcontext.__gregs[REG_A0] =
|
||||||
|
((ucontext_t *)ucontext)->uc_mcontext.__gregs[REG_A7];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(dispatch_and_return)
|
TEST(dispatch_and_return)
|
||||||
|
|
Loading…
Reference in New Issue