mirror of
https://github.com/torvalds/linux.git
synced 2026-09-13 15:40:03 +02:00
RISC-V updates for v7.3-rc3
- Revert a bad fix, likely LLM-generated, in the pointer masking code
that confused the RISC-V hardware pointer masking implementation
with the Linux kernel tagged address feature
- Fix unexpected faults caused by kprobe instruction slot writes when
!CONFIG_STRICT_MODULE_RWX
- Fix unexpected faults on minimal configurations during runtime code
patching on !CONFIG_STRICT_MODULE_RWX systems
- Fix a misplaced variable clear causing incorrect reuse of previous
values in the RISC-V hardware feature probing code
- Fix two bugs in the PMU SBI perf code on rv32: use BIT_ULL rather
than BIT on 64-bit masks; and use a bitmap rather than an unsigned
long on a quantity that can exceed 32 bits
And a few miscellaneous cleanups:
- Avoid a potential dereference-before-NULL-pointer-check bug in the
PMU SBI perf driver
- Simplify the rv32 bug table code by using
CONFIG_GENERIC_BUG_RELATIVE_POINTERS (following x86 and PPC)
- Report the RISC-V standard ISA extensions Z[v]fhmin when support is
claimed for the superset RISC-V standard ISA extensions Z[v]fh; and
simplify our FPU test code to only check for the presence of the D
extension
- Use an existing kernel string helper in place of some open-coded
code in kernel/usercfi.c
- Fix some yamllint issues in the RISC-V DT bindings for CPUs
- Convert one use of __ASSEMBLY__ to __ASSEMBLER__ that snuck into the
RISC-V CFI selftest code
- Update the translation for the simplified Chinese translation of the
RISC-V kernel patch acceptance policy
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEElRDoIDdEz9/svf2Kx4+xDQu9KksFAmqghcoACgkQx4+xDQu9
KkvmEQ/7BVmPFuoR6OLNk2Eu8Exqen6a41KxdM/B91NJBEbBM60GAyejjWDXWmm0
K21yhRu58RGbfg2kKUJMvawzwIfuDswxCS31VtpDKnTrmP4HQz1Yvnh2M7jH9D2d
/wJCIYcJ0hJx0yDIZOUhU24aoy63ZXRygp8nTOgjkAxhkF31w+MJxTPDD0Ir7Eai
y4sRMTCabMonmyA0qozfnMoXaO3FkPv9l7pw/LHfqUYjaLNQyMHiiDPrRj1oNZPD
GQFUWykRgMccMW6kIgTJrjmzn7+vEJ7UZ/fvOD97+rGeaoyE19vcW8owUQWp6Hgb
Jq3WyS9HImrpCBTr079ht5lhu3ZucpAEP6sK5v/m4GOlBv1HdYHUS6JH0qo4DnXZ
aFrxg7WXxaFZ8dD3P8ErZkXy5Vid3+ZlpK//AOfWAqxX7q6c4K1w3lJm4bPKyNBX
vh3ASQr5oEj3KpGbihsrX2lVB/5LVP3pWTcH5f6rBBYiVFMMhWKLJXA3pjiRFN7v
ZXClKh5MznvS6ycMp5pXVYpVn2Kk+Y/mywsDqNRUigHwppkxI9MTJBq8+qcOiM9I
a7mHna4XHVVu0+B4/JMhkWgnGYRjFD6bsGzxPZODLFcmBUxmsoa5+HOENLAGdQ1w
s/Z2HmDO8yL37DxLq5O2aF3KNPSkXNBl+upQwj5lTTzR/bmghjc=
=oMU+
-----END PGP SIGNATURE-----
Merge tag 'riscv-for-linus-7.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux
Pull RISC-V fixes from Paul Walmsley:
"From a RISC-V point of view, there's one notable fix here, reverting
an earlier bogus fix to the pointer masking code. Fortunately the
practical impact appears to be small.
- Revert a bad fix, likely LLM-generated, in the pointer masking code
that confused the RISC-V hardware pointer masking implementation
with the Linux kernel tagged address feature
- Fix unexpected faults caused by kprobe instruction slot writes when
!CONFIG_STRICT_MODULE_RWX
- Fix unexpected faults on minimal configurations during runtime code
patching on !CONFIG_STRICT_MODULE_RWX systems
- Fix a misplaced variable clear causing incorrect reuse of previous
values in the RISC-V hardware feature probing code
- Fix two bugs in the PMU SBI perf code on rv32: use BIT_ULL rather
than BIT on 64-bit masks; and use a bitmap rather than an unsigned
long on a quantity that can exceed 32 bits
And a few miscellaneous cleanups:
- Avoid a potential dereference-before-NULL-pointer-check bug in the
PMU SBI perf driver
- Use CONFIG_GENERIC_BUG_RELATIVE_POINTERS to simplify the rv32 bug
table code (like x86 and PPC)
- Report the RISC-V standard ISA extensions Z[v]fhmin when support is
claimed for the superset RISC-V standard ISA extensions Z[v]fh; and
simplify our FPU test code to only check for the presence of the D
extension
- Use an existing kernel string helper in place of some open-coded
code in kernel/usercfi.c
- Fix some yamllint issues in the RISC-V DT bindings for CPUs
- Convert one use of __ASSEMBLY__ to __ASSEMBLER__ that snuck into
the RISC-V CFI selftest code
- Update the translation for the simplified Chinese translation of
the RISC-V kernel patch acceptance policy"
* tag 'riscv-for-linus-7.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
riscv: skip software algning code for HAVE_EFFICIENT_UNALIGNED_ACCESS
kselftest/riscv: Replace __ASSEMBLY__ with __ASSEMBLER__
docs/zh_CN: Update arch/riscv/patch-acceptance.rst translation
dt-bindings: riscv: cpus: Fix yamllint style issues
riscv: hwprobe: simplify has_fpu() to check D extension only
perf: RISC-V: check cpu_hw_evt before dereference in overflow IRQ
riscv: report Zfhmin/Zvfhmin when Zfh/Zvfh are present
perf: RISC-V: store available counter mask as bitmap
perf: RISC-V: use BIT_ULL for u64 overflow masks
riscv: bug: Make RV32 use GENERIC_BUG_RELATIVE_POINTERS
riscv: hwprobe: initialize pair->value in hwprobe_one_pair()
riscv: use string helper in setup_global_riscv_enable()
Revert "riscv: Reset pmm when PR_TAGGED_ADDR_ENABLE is not set"
riscv: patch: skip fixmap mapping when kernel text is already writable
riscv: mm: make EXECMEM_KPROBES writable without CONFIG_STRICT_MODULE_RWX
This commit is contained in:
commit
827751b699
|
|
@ -155,7 +155,8 @@ The following keys are defined:
|
|||
defined in version 1.0 of the RISC-V Cryptography Extensions Volume II.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_EXT_ZFH`: The Zfh extension version 1.0 is supported
|
||||
as defined in the RISC-V ISA manual.
|
||||
as defined in the RISC-V ISA manual. Zfh is a superset of Zfhmin, so
|
||||
RISCV_HWPROBE_EXT_ZFHMIN is reported whenever RISCV_HWPROBE_EXT_ZFH is.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_EXT_ZFHMIN`: The Zfhmin extension version 1.0 is
|
||||
supported as defined in the RISC-V ISA manual.
|
||||
|
|
@ -164,8 +165,9 @@ The following keys are defined:
|
|||
is supported as defined in the RISC-V ISA manual.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_EXT_ZVFH`: The Zvfh extension is supported as
|
||||
defined in the RISC-V Vector manual starting from commit e2ccd0548d6c
|
||||
("Remove draft warnings from Zvfh[min]").
|
||||
defined in the RISC-V Vector manual starting from commit e2ccd0548d6c
|
||||
("Remove draft warnings from Zvfh[min]"). Zvfh is a superset of Zvfhmin,
|
||||
so RISCV_HWPROBE_EXT_ZVFHMIN is reported whenever RISCV_HWPROBE_EXT_ZVFH is.
|
||||
|
||||
* :c:macro:`RISCV_HWPROBE_EXT_ZVFHMIN`: The Zvfhmin extension is supported as
|
||||
defined in the RISC-V Vector manual starting from commit e2ccd0548d6c
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@ properties:
|
|||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
VLEN/8, the vector register length in bytes. This property is required on
|
||||
thead systems where the vector register length is not identical on all harts, or
|
||||
the vlenb CSR is not available.
|
||||
thead systems where the vector register length is not identical on all
|
||||
harts, or the vlenb CSR is not available.
|
||||
|
||||
# RISC-V has multiple properties for cache op block sizes as the sizes
|
||||
# differ between individual CBO extensions
|
||||
|
|
@ -151,8 +151,8 @@ anyOf:
|
|||
- riscv,isa-base
|
||||
|
||||
dependencies:
|
||||
riscv,isa-base: [ "riscv,isa-extensions" ]
|
||||
riscv,isa-extensions: [ "riscv,isa-base" ]
|
||||
riscv,isa-base: ["riscv,isa-extensions"]
|
||||
riscv,isa-extensions: ["riscv,isa-base"]
|
||||
|
||||
required:
|
||||
- interrupt-controller
|
||||
|
|
|
|||
|
|
@ -15,19 +15,41 @@ arch/riscv 开发者维护指南
|
|||
|
||||
概述
|
||||
----
|
||||
RISC-V指令集体系结构是公开开发的:
|
||||
RISC-V 指令集体系结构是公开开发的:
|
||||
正在进行的草案可供所有人查看和测试实现。新模块或者扩展草案可能会在开发过程中发
|
||||
生更改---有时以不兼容的方式对以前的草案进行更改。这种灵活性可能会给RISC-V Linux
|
||||
维护者带来挑战。Linux开发过程更喜欢经过良好检查和测试的代码,而不是试验代码。我
|
||||
们希望推广同样的规则到即将被内核合并的RISC-V相关代码。
|
||||
生更改 --- 有时以不兼容的方式对以前的草案进行更改。这种灵活性可能会给 RISC-V
|
||||
Linux 维护者带来挑战。Linux 维护者不赞成频繁的变更,且 Linux 开发过程更喜欢经过
|
||||
良好检查和测试的代码,而不是试验代码。我们希望推广同样的规则到即将被内核合并的
|
||||
RISC-V 相关代码。
|
||||
|
||||
Patchwork
|
||||
---------
|
||||
|
||||
RISC-V 有一个 patchwork 实例,可以在那里查看补丁的状态:
|
||||
|
||||
https://patchwork.kernel.org/project/linux-riscv/list/
|
||||
|
||||
如果你的补丁不在默认视图中出现,那么 RISC-V 维护者很有可能已要求修改,或者希望
|
||||
将其应用到另一个代码树上。
|
||||
|
||||
自动化流程会在该 patchwork 实例上运行,在每个补丁到达时立刻对其进行构建/测试。
|
||||
自动化流程会根据补丁是否被识别为修复,选用 RISC-V `for-next` 或 `fixes` 分支
|
||||
当前的 HEAD;若上述均应用失败,则使用 RISC-V `master` 分支。补丁系列被应用到的具
|
||||
体提交将标注在 patchwork 上。任何检查未通过的补丁通常不会被应用,并且在大多数情
|
||||
况下将需要重新提交。
|
||||
|
||||
附加的提交检查单
|
||||
----------------
|
||||
我们仅接受相关标准已经被RISC-V基金会标准为“已批准”或“已冻结”的扩展或模块的补丁。
|
||||
(开发者当然可以维护自己的Linux内核树,其中包含所需代码扩展草案的代码。)
|
||||
我们仅接受针对新模块或扩展的补丁,前提是这些模块或扩展的规范被列为未来不太可能发
|
||||
生不兼容的变更。对于来自 RISC-V 基金会的规范,这意味着“已冻结”或“已批准”,对于
|
||||
UEFI 论坛的规范,这意味着已发布的 ECR。(开发者当然可以维护自己的 Linux 内核树,
|
||||
其中包含他们所需的任何扩展草案的代码。)
|
||||
|
||||
此外,RISC-V规范允许爱好者创建自己的自定义扩展。这些自定义拓展不需要通过RISC-V
|
||||
基金会的任何审核或批准。为了避免将爱好者一些特别的RISC-V拓展添加进内核代码带来
|
||||
的维护复杂性和对性能的潜在影响,我们将只接受RISC-V基金会正式冻结或批准的的扩展
|
||||
补丁。(开发者当然可以维护自己的Linux内核树,其中包含他们想要的任何自定义扩展
|
||||
的代码。)
|
||||
此外,RISC-V 规范允许实现者创建自己的自定义扩展。这些自定义扩展不需要通过 RISC-V
|
||||
基金会的任何审核或批准流程。为了避免因添加实现者特定的 RISC-V 扩展带来的维护复杂
|
||||
性和对性能的潜在影响,我们将只考虑符合以下任一条件的扩展补丁:
|
||||
|
||||
- 已由 RISC-V 基金会正式冻结或批准
|
||||
- 已按照标准 Linux 惯例,在广泛可用的硬件中实现
|
||||
|
||||
(实现者当然可以维护自己的 Linux 内核树,其中包含他们所需的任何自定义扩展的代码。)
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ config STACKTRACE_SUPPORT
|
|||
config GENERIC_BUG
|
||||
def_bool y
|
||||
depends on BUG
|
||||
select GENERIC_BUG_RELATIVE_POINTERS if 64BIT
|
||||
select GENERIC_BUG_RELATIVE_POINTERS
|
||||
|
||||
config GENERIC_BUG_RELATIVE_POINTERS
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -29,13 +29,8 @@
|
|||
|
||||
typedef u32 bug_insn_t;
|
||||
|
||||
#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
||||
#define __BUG_ENTRY_ADDR RISCV_INT " 1b - ."
|
||||
#define __BUG_ENTRY_FILE(file) RISCV_INT " " file " - ."
|
||||
#else
|
||||
#define __BUG_ENTRY_ADDR RISCV_PTR " 1b"
|
||||
#define __BUG_ENTRY_FILE(file) RISCV_PTR " " file
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||
#define __BUG_ENTRY(file, line, flags) \
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ static inline void __switch_to_fpu(struct task_struct *prev,
|
|||
|
||||
static __always_inline bool has_fpu(void)
|
||||
{
|
||||
return riscv_has_extension_likely(RISCV_ISA_EXT_F) ||
|
||||
riscv_has_extension_likely(RISCV_ISA_EXT_D);
|
||||
/* D extension depends on F, so checking D alone is sufficient. */
|
||||
return riscv_has_extension_likely(RISCV_ISA_EXT_D);
|
||||
}
|
||||
#else
|
||||
static __always_inline bool has_fpu(void) { return false; }
|
||||
|
|
|
|||
|
|
@ -412,6 +412,19 @@ static const unsigned int riscv_zvbb_exts[] = {
|
|||
RISCV_ISA_EXT_ZVKB
|
||||
};
|
||||
|
||||
/*
|
||||
* The RISC-V ISA manual specifies that Zfh implies Zfhmin and Zvfh implies
|
||||
* Zvfhmin. Report the implied subset extensions whenever the supersets are
|
||||
* detected (see https://github.com/riscv/riscv-isa-manual/pull/3070).
|
||||
*/
|
||||
static const unsigned int riscv_zfh_exts[] = {
|
||||
RISCV_ISA_EXT_ZFHMIN
|
||||
};
|
||||
|
||||
static const unsigned int riscv_zvfh_exts[] = {
|
||||
RISCV_ISA_EXT_ZVFHMIN
|
||||
};
|
||||
|
||||
#define RISCV_ISA_EXT_ZVE64F_IMPLY_LIST \
|
||||
RISCV_ISA_EXT_ZVE64X, \
|
||||
RISCV_ISA_EXT_ZVE32F, \
|
||||
|
|
@ -550,7 +563,8 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
|||
__RISCV_ISA_EXT_DATA(zawrs, RISCV_ISA_EXT_ZAWRS),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zfa, RISCV_ISA_EXT_ZFA, riscv_ext_f_depends),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zfbfmin, RISCV_ISA_EXT_ZFBFMIN, riscv_ext_f_depends),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zfh, RISCV_ISA_EXT_ZFH, riscv_ext_f_depends),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zfh, RISCV_ISA_EXT_ZFH,
|
||||
riscv_zfh_exts, riscv_ext_f_depends),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zfhmin, RISCV_ISA_EXT_ZFHMIN, riscv_ext_f_depends),
|
||||
__RISCV_ISA_EXT_DATA(zca, RISCV_ISA_EXT_ZCA),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zcb, RISCV_ISA_EXT_ZCB, riscv_ext_zca_depends),
|
||||
|
|
@ -586,7 +600,9 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
|||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zve64x, RISCV_ISA_EXT_ZVE64X, riscv_zve64x_exts, riscv_ext_vector_x_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfmin, RISCV_ISA_EXT_ZVFBFMIN, riscv_vector_f_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvfbfwma, RISCV_ISA_EXT_ZVFBFWMA, riscv_ext_zvfbfwma_validate),
|
||||
__RISCV_ISA_EXT_DATA(zvfh, RISCV_ISA_EXT_ZVFH),
|
||||
__RISCV_ISA_EXT_SUPERSET_VALIDATE(zvfh, RISCV_ISA_EXT_ZVFH,
|
||||
riscv_zvfh_exts,
|
||||
riscv_ext_vector_float_validate),
|
||||
__RISCV_ISA_EXT_DATA(zvfhmin, RISCV_ISA_EXT_ZVFHMIN),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvkb, RISCV_ISA_EXT_ZVKB, riscv_ext_vector_crypto_validate),
|
||||
__RISCV_ISA_EXT_DATA_VALIDATE(zvkg, RISCV_ISA_EXT_ZVKG, riscv_ext_vector_crypto_validate),
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap)
|
|||
phys_addr_t phys;
|
||||
|
||||
if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) {
|
||||
if (!IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
|
||||
return addr;
|
||||
phys = __pa_symbol(addr);
|
||||
} else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) {
|
||||
struct page *page = vmalloc_to_page(addr);
|
||||
|
|
|
|||
|
|
@ -349,10 +349,8 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
|
|||
if (arg & PR_TAGGED_ADDR_ENABLE && (tagged_addr_disabled || !pmlen))
|
||||
return -EINVAL;
|
||||
|
||||
if (!(arg & PR_TAGGED_ADDR_ENABLE)) {
|
||||
if (!(arg & PR_TAGGED_ADDR_ENABLE))
|
||||
pmlen = PMLEN_0;
|
||||
pmm = ENVCFG_PMM_PMLEN_0;
|
||||
}
|
||||
|
||||
if (mmap_write_lock_killable(mm))
|
||||
return -EINTR;
|
||||
|
|
|
|||
|
|
@ -297,6 +297,8 @@ static u64 hwprobe_vec_misaligned(const struct cpumask *cpus)
|
|||
static void hwprobe_one_pair(struct riscv_hwprobe *pair,
|
||||
const struct cpumask *cpus)
|
||||
{
|
||||
pair->value = 0;
|
||||
|
||||
switch (pair->key) {
|
||||
case RISCV_HWPROBE_KEY_MVENDORID:
|
||||
case RISCV_HWPROBE_KEY_MARCHID:
|
||||
|
|
@ -331,17 +333,14 @@ static void hwprobe_one_pair(struct riscv_hwprobe *pair,
|
|||
break;
|
||||
|
||||
case RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE:
|
||||
pair->value = 0;
|
||||
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOZ))
|
||||
pair->value = riscv_cboz_block_size;
|
||||
break;
|
||||
case RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE:
|
||||
pair->value = 0;
|
||||
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOM))
|
||||
pair->value = riscv_cbom_block_size;
|
||||
break;
|
||||
case RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE:
|
||||
pair->value = 0;
|
||||
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOP))
|
||||
pair->value = riscv_cbop_block_size;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -525,9 +525,8 @@ static int __init setup_global_riscv_enable(char *str)
|
|||
|
||||
if (riscv_nousercfi)
|
||||
pr_info("RISC-V user CFI disabled via cmdline - shadow stack status : %s, landing pad status : %s\n",
|
||||
(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI) ? "disabled" :
|
||||
"enabled", (riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI) ?
|
||||
"disabled" : "enabled");
|
||||
str_disabled_enabled(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_BCFI),
|
||||
str_disabled_enabled(riscv_nousercfi & CMDLINE_DISABLE_RISCV_USERCFI_FCFI));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
|
|||
li a3, 9*SZREG-1 /* size must >= (word_copy stride + SZREG-1) */
|
||||
bltu a2, a3, .Lbyte_copy_tail
|
||||
|
||||
#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
/*
|
||||
* Copy first bytes until dst is aligned to word boundary.
|
||||
* a0 - start of dst
|
||||
|
|
@ -103,7 +104,7 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
|
|||
/* a1 - start of src */
|
||||
andi a3, a1, SZREG-1
|
||||
bnez a3, .Lshift_copy
|
||||
|
||||
#endif
|
||||
.Lword_copy:
|
||||
/*
|
||||
* Both src and dst are aligned, unrolled word copy
|
||||
|
|
@ -137,6 +138,7 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
|
|||
addi t0, t0, 8*SZREG /* revert to original value */
|
||||
j .Lbyte_copy_tail
|
||||
|
||||
#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
.Lshift_copy:
|
||||
|
||||
/*
|
||||
|
|
@ -189,6 +191,7 @@ SYM_FUNC_START(fallback_scalar_usercopy_sum_enabled)
|
|||
|
||||
/* Revert src to original unaligned value */
|
||||
add a1, a1, a3
|
||||
#endif
|
||||
|
||||
.Lbyte_copy_tail:
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1465,7 +1465,9 @@ struct execmem_info __init *execmem_arch_setup(void)
|
|||
[EXECMEM_KPROBES] = {
|
||||
.start = VMALLOC_START,
|
||||
.end = VMALLOC_END,
|
||||
.pgprot = PAGE_KERNEL_READ_EXEC,
|
||||
.pgprot = IS_ENABLED(CONFIG_STRICT_MODULE_RWX) ?
|
||||
PAGE_KERNEL_READ_EXEC :
|
||||
PAGE_KERNEL_EXEC,
|
||||
.alignment = 1,
|
||||
},
|
||||
[EXECMEM_BPF] = {
|
||||
|
|
|
|||
|
|
@ -110,8 +110,9 @@ static void pmu_legacy_init(struct riscv_pmu *pmu)
|
|||
{
|
||||
pr_info("Legacy PMU implementation is available\n");
|
||||
|
||||
pmu->cmask = BIT(RISCV_PMU_LEGACY_CYCLE) |
|
||||
BIT(RISCV_PMU_LEGACY_INSTRET);
|
||||
bitmap_zero(pmu->cmask, RISCV_MAX_COUNTERS);
|
||||
set_bit(RISCV_PMU_LEGACY_CYCLE, pmu->cmask);
|
||||
set_bit(RISCV_PMU_LEGACY_INSTRET, pmu->cmask);
|
||||
pmu->ctr_start = pmu_legacy_ctr_start;
|
||||
pmu->ctr_stop = NULL;
|
||||
pmu->event_map = pmu_legacy_event_map;
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ static unsigned int riscv_pmu_irq_mask;
|
|||
static unsigned int riscv_pmu_irq;
|
||||
|
||||
/* Cache the available counters in a bitmask */
|
||||
static unsigned long cmask;
|
||||
static DECLARE_BITMAP(cmask, RISCV_MAX_COUNTERS);
|
||||
|
||||
static int pmu_event_find_cache(u64 config);
|
||||
struct sbi_pmu_event_data {
|
||||
|
|
@ -359,16 +359,38 @@ static int pmu_sbi_check_event_info(void)
|
|||
return result;
|
||||
}
|
||||
|
||||
static struct sbiret pmu_sbi_ctr_cfg_match(unsigned long cbase,
|
||||
unsigned long ctr_mask,
|
||||
unsigned long cflags,
|
||||
unsigned long event_idx,
|
||||
u64 config)
|
||||
{
|
||||
#if defined(CONFIG_32BIT)
|
||||
return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase,
|
||||
ctr_mask, cflags, event_idx, config, config >> 32);
|
||||
#else
|
||||
return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase,
|
||||
ctr_mask, cflags, event_idx, config, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
|
||||
{
|
||||
struct sbiret ret;
|
||||
struct sbiret ret = { .error = SBI_ERR_NOT_SUPPORTED };
|
||||
int i;
|
||||
|
||||
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH,
|
||||
0, cmask, 0, edata->event_idx, 0, 0);
|
||||
if (!ret.error) {
|
||||
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
|
||||
ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
|
||||
} else if (ret.error == SBI_ERR_NOT_SUPPORTED) {
|
||||
for (i = 0; i < BITS_TO_LONGS(RISCV_MAX_COUNTERS); i++) {
|
||||
if (!cmask[i])
|
||||
continue;
|
||||
ret = pmu_sbi_ctr_cfg_match(i * BITS_PER_LONG, cmask[i], 0,
|
||||
edata->event_idx, 0);
|
||||
if (!ret.error) {
|
||||
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
|
||||
ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ret.error == SBI_ERR_NOT_SUPPORTED) {
|
||||
/* This event cannot be monitored by any counter */
|
||||
edata->event_idx = -ENOENT;
|
||||
}
|
||||
|
|
@ -488,10 +510,10 @@ int riscv_pmu_get_hpm_info(u32 *hw_ctr_width, u32 *num_hw_ctr)
|
|||
union sbi_pmu_ctr_info *info;
|
||||
u32 hpm_width = 0, hpm_count = 0;
|
||||
|
||||
if (!cmask)
|
||||
if (bitmap_empty(cmask, RISCV_MAX_COUNTERS))
|
||||
return -EINVAL;
|
||||
|
||||
for_each_set_bit(i, &cmask, RISCV_MAX_COUNTERS) {
|
||||
for_each_set_bit(i, cmask, RISCV_MAX_COUNTERS) {
|
||||
info = &pmu_ctr_list[i];
|
||||
if (!info)
|
||||
continue;
|
||||
|
|
@ -540,8 +562,8 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event)
|
|||
struct riscv_pmu *rvpmu = to_riscv_pmu(event->pmu);
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(rvpmu->hw_events);
|
||||
struct sbiret ret;
|
||||
int idx;
|
||||
uint64_t cbase = 0, cmask = rvpmu->cmask;
|
||||
int idx, i;
|
||||
u64 cbase = 0, cmask = 0;
|
||||
unsigned long cflags = 0;
|
||||
|
||||
cflags = pmu_sbi_get_filter_flags(event);
|
||||
|
|
@ -562,14 +584,21 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event)
|
|||
}
|
||||
|
||||
/* retrieve the available counter index */
|
||||
#if defined(CONFIG_32BIT)
|
||||
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase,
|
||||
cmask, cflags, hwc->event_base, hwc->config,
|
||||
hwc->config >> 32);
|
||||
#else
|
||||
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase,
|
||||
cmask, cflags, hwc->event_base, hwc->config, 0);
|
||||
#endif
|
||||
if (cmask) {
|
||||
ret = pmu_sbi_ctr_cfg_match(cbase, cmask, cflags, hwc->event_base,
|
||||
hwc->config);
|
||||
} else {
|
||||
ret.error = SBI_ERR_NOT_SUPPORTED;
|
||||
for (i = 0; i < BITS_TO_LONGS(RISCV_MAX_COUNTERS); i++) {
|
||||
if (!rvpmu->cmask[i])
|
||||
continue;
|
||||
cbase = i * BITS_PER_LONG;
|
||||
ret = pmu_sbi_ctr_cfg_match(cbase, rvpmu->cmask[i], cflags,
|
||||
hwc->event_base, hwc->config);
|
||||
if (!ret.error)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret.error) {
|
||||
pr_debug("Not able to find a counter for event %lx config %llx\n",
|
||||
hwc->event_base, hwc->config);
|
||||
|
|
@ -577,7 +606,7 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event)
|
|||
}
|
||||
|
||||
idx = ret.value;
|
||||
if (!test_bit(idx, &rvpmu->cmask) || !pmu_ctr_list[idx].value)
|
||||
if (!test_bit(idx, rvpmu->cmask) || !pmu_ctr_list[idx].value)
|
||||
return -ENOENT;
|
||||
|
||||
/* Additional sanity check for the counter id */
|
||||
|
|
@ -881,7 +910,7 @@ static int pmu_sbi_get_ctrinfo(int nctr, unsigned long *mask)
|
|||
/* The logical counter ids are not expected to be contiguous */
|
||||
continue;
|
||||
|
||||
*mask |= BIT(i);
|
||||
set_bit(i, mask);
|
||||
|
||||
cinfo.value = ret.value;
|
||||
if (cinfo.type == SBI_PMU_CTR_TYPE_FW)
|
||||
|
|
@ -898,12 +927,19 @@ static int pmu_sbi_get_ctrinfo(int nctr, unsigned long *mask)
|
|||
|
||||
static inline void pmu_sbi_stop_all(struct riscv_pmu *pmu)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* No need to check the error because we are disabling all the counters
|
||||
* which may include counters that are not enabled yet.
|
||||
*/
|
||||
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
|
||||
0, pmu->cmask, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
|
||||
for (i = 0; i < BITS_TO_LONGS(RISCV_MAX_COUNTERS); i++) {
|
||||
if (!pmu->cmask[i])
|
||||
continue;
|
||||
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
|
||||
i * BITS_PER_LONG, pmu->cmask[i],
|
||||
SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
|
||||
|
|
@ -1002,7 +1038,7 @@ static inline void pmu_sbi_start_ovf_ctrs_snapshot(struct cpu_hw_events *cpu_hw_
|
|||
struct riscv_pmu_snapshot_data *sdata = cpu_hw_evt->snapshot_addr;
|
||||
|
||||
for_each_set_bit(idx, cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS) {
|
||||
if (ctr_ovf_mask & BIT(idx)) {
|
||||
if (ctr_ovf_mask & BIT_ULL(idx)) {
|
||||
event = cpu_hw_evt->events[idx];
|
||||
hwc = &event->hw;
|
||||
max_period = riscv_pmu_ctr_get_width_mask(event);
|
||||
|
|
@ -1050,11 +1086,13 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
|
|||
u64 overflowed_ctrs = 0;
|
||||
struct cpu_hw_events *cpu_hw_evt = dev;
|
||||
u64 start_clock = sched_clock();
|
||||
struct riscv_pmu_snapshot_data *sdata = cpu_hw_evt->snapshot_addr;
|
||||
struct riscv_pmu_snapshot_data *sdata;
|
||||
|
||||
if (WARN_ON_ONCE(!cpu_hw_evt))
|
||||
return IRQ_NONE;
|
||||
|
||||
sdata = cpu_hw_evt->snapshot_addr;
|
||||
|
||||
/* Firmware counter don't support overflow yet */
|
||||
fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS);
|
||||
if (fidx == RISCV_MAX_COUNTERS) {
|
||||
|
|
@ -1109,14 +1147,14 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
|
|||
hidx = info->csr - CSR_CYCLE;
|
||||
|
||||
/* check if the corresponding bit is set in scountovf or overflow mask in shmem */
|
||||
if (!(overflow & BIT(hidx)))
|
||||
if (!(overflow & BIT_ULL(hidx)))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Keep a track of overflowed counters so that they can be started
|
||||
* with updated initial value.
|
||||
*/
|
||||
overflowed_ctrs |= BIT(lidx);
|
||||
overflowed_ctrs |= BIT_ULL(lidx);
|
||||
hw_evt = &event->hw;
|
||||
/* Update the event states here so that we know the state while reading */
|
||||
hw_evt->state |= PERF_HES_STOPPED;
|
||||
|
|
@ -1451,7 +1489,7 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
/* cache all the information about counters now */
|
||||
if (pmu_sbi_get_ctrinfo(num_counters, &cmask))
|
||||
if (pmu_sbi_get_ctrinfo(num_counters, cmask))
|
||||
goto out_free;
|
||||
|
||||
ret = pmu_sbi_setup_irqs(pmu, pdev);
|
||||
|
|
@ -1464,7 +1502,7 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
|
|||
|
||||
pmu->pmu.attr_groups = riscv_pmu_attr_groups;
|
||||
pmu->pmu.parent = &pdev->dev;
|
||||
pmu->cmask = cmask;
|
||||
bitmap_copy(pmu->cmask, cmask, RISCV_MAX_COUNTERS);
|
||||
pmu->ctr_start = pmu_sbi_ctr_start;
|
||||
pmu->ctr_stop = pmu_sbi_ctr_stop;
|
||||
pmu->event_map = pmu_sbi_event_map;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ struct riscv_pmu {
|
|||
|
||||
irqreturn_t (*handle_irq)(int irq_num, void *dev);
|
||||
|
||||
unsigned long cmask;
|
||||
DECLARE_BITMAP(cmask, RISCV_MAX_COUNTERS);
|
||||
u64 (*ctr_read)(struct perf_event *event);
|
||||
int (*ctr_get_idx)(struct perf_event *event);
|
||||
int (*ctr_get_width)(int idx);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
|
||||
#define CSR_SSP 0x011
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
#ifdef __ASSEMBLER__
|
||||
#define __ASM_STR(x) x
|
||||
#else
|
||||
#define __ASM_STR(x) #x
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ int main(int argc, char **argv)
|
|||
long out;
|
||||
|
||||
ksft_print_header();
|
||||
ksft_set_plan(5);
|
||||
ksft_set_plan(6);
|
||||
|
||||
/* Fake the CPU_SET ops. */
|
||||
cpus = -1;
|
||||
|
|
@ -62,5 +62,23 @@ int main(int argc, char **argv)
|
|||
pairs[1].key == 1 && pairs[1].value != 0xAAAA,
|
||||
"Unknown key overwritten with -1 and doesn't block other elements\n");
|
||||
|
||||
pairs[0].key = RISCV_HWPROBE_KEY_IMA_EXT_0;
|
||||
out = riscv_hwprobe(pairs, 1, 0, 0, 0);
|
||||
if (out != 0)
|
||||
ksft_exit_fail_msg("hwprobe(IMA_EXT_0) failed with %ld\n", out);
|
||||
|
||||
/*
|
||||
* The RISC-V ISA manual specifies that Zfh implies Zfhmin and Zvfh
|
||||
* implies Zvfhmin, so hwprobe must report the implied subset
|
||||
* extensions whenever the supersets are present.
|
||||
*/
|
||||
if ((pairs[0].value & RISCV_HWPROBE_EXT_ZFH) &&
|
||||
!(pairs[0].value & RISCV_HWPROBE_EXT_ZFHMIN))
|
||||
ksft_exit_fail_msg("Zfh reported without implied Zfhmin\n");
|
||||
if ((pairs[0].value & RISCV_HWPROBE_EXT_ZVFH) &&
|
||||
!(pairs[0].value & RISCV_HWPROBE_EXT_ZVFHMIN))
|
||||
ksft_exit_fail_msg("Zvfh reported without implied Zvfhmin\n");
|
||||
ksft_test_result_pass("Zfh/Zvfh imply Zfhmin/Zvfhmin\n");
|
||||
|
||||
ksft_finished();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user