Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

riscv: pgtable: Use riscv_has_extension_unlikely

Use riscv_has_extension_unlikely() to check for RISCV_ISA_EXT_SVVPTC,
replacing the use of asm goto with ALTERNATIVE.

The "unlikely" variant is used to match the behavior of the original
implementation using ALTERNATIVE("nop", "j %l[svvptc]", ...).

Note that this makes the check for RISCV_ISA_EXT_SVVPTC a runtime one if
RISCV_ALTERNATIVE=n, but it should still be worthwhile to do so given
that TLB flushes are relatively slow.

Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
Link: https://patch.msgid.link/20251020-riscv-altn-helper-wip-v4-1-ef941c87669a@iscas.ac.cn
Signed-off-by: Paul Walmsley <pjw@kernel.org>

authored by

Vivian Wang and committed by
Paul Walmsley
0a067ae2 c9a71610

+17 -20
+7 -8
arch/riscv/include/asm/pgtable.h
··· 496 496 struct vm_area_struct *vma, unsigned long address, 497 497 pte_t *ptep, unsigned int nr) 498 498 { 499 - asm goto(ALTERNATIVE("nop", "j %l[svvptc]", 0, RISCV_ISA_EXT_SVVPTC, 1) 500 - : : : : svvptc); 499 + /* 500 + * Svvptc guarantees that the new valid pte will be visible within 501 + * a bounded timeframe, so when the uarch does not cache invalid 502 + * entries, we don't have to do anything. 503 + */ 504 + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SVVPTC)) 505 + return; 501 506 502 507 /* 503 508 * The kernel assumes that TLBs don't cache invalid entries, but ··· 514 509 while (nr--) 515 510 local_flush_tlb_page(address + nr * PAGE_SIZE); 516 511 517 - svvptc:; 518 - /* 519 - * Svvptc guarantees that the new valid pte will be visible within 520 - * a bounded timeframe, so when the uarch does not cache invalid 521 - * entries, we don't have to do anything. 522 - */ 523 512 } 524 513 #define update_mmu_cache(vma, addr, ptep) \ 525 514 update_mmu_cache_range(NULL, vma, addr, ptep, 1)
+10 -12
arch/riscv/mm/pgtable.c
··· 9 9 unsigned long address, pte_t *ptep, 10 10 pte_t entry, int dirty) 11 11 { 12 - asm goto(ALTERNATIVE("nop", "j %l[svvptc]", 0, RISCV_ISA_EXT_SVVPTC, 1) 13 - : : : : svvptc); 12 + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SVVPTC)) { 13 + if (!pte_same(ptep_get(ptep), entry)) { 14 + __set_pte_at(vma->vm_mm, ptep, entry); 15 + /* Here only not svadu is impacted */ 16 + flush_tlb_page(vma, address); 17 + return true; 18 + } 19 + 20 + return false; 21 + } 14 22 15 23 if (!pte_same(ptep_get(ptep), entry)) 16 24 __set_pte_at(vma->vm_mm, ptep, entry); ··· 27 19 * the case that the PTE changed and the spurious fault case. 28 20 */ 29 21 return true; 30 - 31 - svvptc: 32 - if (!pte_same(ptep_get(ptep), entry)) { 33 - __set_pte_at(vma->vm_mm, ptep, entry); 34 - /* Here only not svadu is impacted */ 35 - flush_tlb_page(vma, address); 36 - return true; 37 - } 38 - 39 - return false; 40 22 } 41 23 42 24 int ptep_test_and_clear_young(struct vm_area_struct *vma,