Skip to content

Commit 4b74077

Browse files
Merge patch series "RISC-V: Apply Zicboz to clear_page"
Andrew Jones <ajones@ventanamicro.com> says: When the Zicboz extension is available we can more rapidly zero naturally aligned Zicboz block sized chunks of memory. As pages are always page aligned and are larger than any Zicboz block size will be, then clear_page() appears to be a good candidate for the extension. While cycle count and energy consumption should also be considered, we can be pretty certain that implementing clear_page() with the Zicboz extension is a win by comparing the new dynamic instruction count with its current count[1]. Doing so we see that the new count is just over a quarter of the old count (see patch6's commit message for more details). For those of you who reviewed v1[2], you may be looking for the memset() patches. As pointed out in v1, and a couple follow-up emails, it's not clear that patching memset() is a win yet. When I get a chance to test on real hardware with a comprehensive benchmark collection then I can post the memset() patches separately (assuming the benchmarks show it's worthwhile). * b4-shazam-merge: RISC-V: KVM: Expose Zicboz to the guest RISC-V: KVM: Provide UAPI for Zicboz block size RISC-V: Use Zicboz in clear_page when available RISC-V: cpufeatures: Put the upper 16 bits of patch ID to work RISC-V: Add Zicboz detection and block size parsing dt-bindings: riscv: Document cboz-block-size RISC-V: Factor out body of riscv_init_cbom_blocksize loop RISC-V: alternatives: Support patching multiple insns in assembly Link: https://lore.kernel.org/r/20230224162631.405473-1-ajones@ventanamicro.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2 parents 73bde0c + b20f679 commit 4b74077

16 files changed

Lines changed: 219 additions & 36 deletions

File tree

Documentation/devicetree/bindings/riscv/cpus.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ properties:
7272
description:
7373
The blocksize in bytes for the Zicbom cache operations.
7474

75+
riscv,cboz-block-size:
76+
$ref: /schemas/types.yaml#/definitions/uint32
77+
description:
78+
The blocksize in bytes for the Zicboz cache operations.
79+
7580
riscv,isa:
7681
description:
7782
Identifies the specific RISC-V instruction set architecture

arch/riscv/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,19 @@ config RISCV_ISA_ZICBOM
476476

477477
If you don't know what to do here, say Y.
478478

479+
config RISCV_ISA_ZICBOZ
480+
bool "Zicboz extension support for faster zeroing of memory"
481+
depends on !XIP_KERNEL && MMU
482+
select RISCV_ALTERNATIVE
483+
default y
484+
help
485+
Enable the use of the ZICBOZ extension (cbo.zero instruction)
486+
when available.
487+
488+
The Zicboz extension is used for faster zeroing of memory.
489+
490+
If you don't know what to do here, say Y.
491+
479492
config TOOLCHAIN_HAS_ZIHINTPAUSE
480493
bool
481494
default y

arch/riscv/include/asm/alternative-macros.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
.4byte \patch_id
1515
.endm
1616

17-
.macro ALT_NEW_CONTENT vendor_id, patch_id, enable = 1, new_c : vararg
17+
.macro ALT_NEW_CONTENT vendor_id, patch_id, enable = 1, new_c
1818
.if \enable
1919
.pushsection .alternative, "a"
2020
ALT_ENTRY 886b, 888f, \vendor_id, \patch_id, 889f - 888f
@@ -41,13 +41,13 @@
4141
\old_c
4242
.option pop
4343
887 :
44-
ALT_NEW_CONTENT \vendor_id, \patch_id, \enable, \new_c
44+
ALT_NEW_CONTENT \vendor_id, \patch_id, \enable, "\new_c"
4545
.endm
4646

4747
.macro ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, patch_id_1, enable_1, \
4848
new_c_2, vendor_id_2, patch_id_2, enable_2
4949
ALTERNATIVE_CFG "\old_c", "\new_c_1", \vendor_id_1, \patch_id_1, \enable_1
50-
ALT_NEW_CONTENT \vendor_id_2, \patch_id_2, \enable_2, \new_c_2
50+
ALT_NEW_CONTENT \vendor_id_2, \patch_id_2, \enable_2, "\new_c_2"
5151
.endm
5252

5353
#define __ALTERNATIVE_CFG(...) ALTERNATIVE_CFG __VA_ARGS__

arch/riscv/include/asm/alternative.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@
1313
#ifdef CONFIG_RISCV_ALTERNATIVE
1414

1515
#include <linux/init.h>
16+
#include <linux/kernel.h>
1617
#include <linux/types.h>
1718
#include <linux/stddef.h>
1819
#include <asm/hwcap.h>
1920

21+
#define PATCH_ID_CPUFEATURE_ID(p) lower_16_bits(p)
22+
#define PATCH_ID_CPUFEATURE_VALUE(p) upper_16_bits(p)
23+
2024
#define RISCV_ALTERNATIVES_BOOT 0 /* alternatives applied during regular boot */
2125
#define RISCV_ALTERNATIVES_MODULE 1 /* alternatives applied during module-init */
2226
#define RISCV_ALTERNATIVES_EARLY_BOOT 2 /* alternatives applied before mmu start */

arch/riscv/include/asm/cacheflush.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
5050
#endif /* CONFIG_SMP */
5151

5252
extern unsigned int riscv_cbom_block_size;
53-
void riscv_init_cbom_blocksize(void);
53+
extern unsigned int riscv_cboz_block_size;
54+
void riscv_init_cbo_blocksizes(void);
5455

5556
#ifdef CONFIG_RISCV_DMA_NONCOHERENT
5657
void riscv_noncoherent_supported(void);

arch/riscv/include/asm/hwcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#define RISCV_ISA_EXT_ZICBOM 31
4444
#define RISCV_ISA_EXT_ZIHINTPAUSE 32
4545
#define RISCV_ISA_EXT_SVNAPOT 33
46+
#define RISCV_ISA_EXT_ZICBOZ 34
4647

4748
#define RISCV_ISA_EXT_MAX 64
4849
#define RISCV_ISA_EXT_NAME_LEN_MAX 32

arch/riscv/include/asm/insn-def.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,8 @@
192192
INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \
193193
RS1(base), SIMM12(2))
194194

195+
#define CBO_zero(base) \
196+
INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \
197+
RS1(base), SIMM12(4))
198+
195199
#endif /* __ASM_INSN_DEF_H */

arch/riscv/include/asm/page.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,14 @@
4444

4545
#ifndef __ASSEMBLY__
4646

47+
#ifdef CONFIG_RISCV_ISA_ZICBOZ
48+
void clear_page(void *page);
49+
#else
4750
#define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE)
51+
#endif
4852
#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE)
4953

50-
#define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE)
54+
#define clear_user_page(pgaddr, vaddr, page) clear_page(pgaddr)
5155
#define copy_user_page(vto, vfrom, vaddr, topg) \
5256
memcpy((vto), (vfrom), PAGE_SIZE)
5357

arch/riscv/include/uapi/asm/kvm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct kvm_riscv_config {
5252
unsigned long mvendorid;
5353
unsigned long marchid;
5454
unsigned long mimpid;
55+
unsigned long zicboz_block_size;
5556
};
5657

5758
/* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
@@ -105,6 +106,7 @@ enum KVM_RISCV_ISA_EXT_ID {
105106
KVM_RISCV_ISA_EXT_SVINVAL,
106107
KVM_RISCV_ISA_EXT_ZIHINTPAUSE,
107108
KVM_RISCV_ISA_EXT_ZICBOM,
109+
KVM_RISCV_ISA_EXT_ZICBOZ,
108110
KVM_RISCV_ISA_EXT_MAX,
109111
};
110112

arch/riscv/kernel/cpu.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ arch_initcall(riscv_cpuinfo_init);
186186
*/
187187
static struct riscv_isa_ext_data isa_ext_arr[] = {
188188
__RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
189+
__RISCV_ISA_EXT_DATA(zicboz, RISCV_ISA_EXT_ZICBOZ),
189190
__RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
190191
__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
191192
__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),

0 commit comments

Comments
 (0)