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.

Merge tag 'riscv-for-linus-6.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull RISC-V fixes from Palmer Dabbelt:

- A pair of fixes to the new module load-time relocation code

- A fix for hwprobe overflowing on rv32

- A fix for to correctly decode C.SWSP and C.SDSP, which manifests in
misaligned access handling

- A fix for a boot-time shadow call stack initialization ordering issue

- A fix for Andes' errata probing, which was calling
riscv_noncoherent_supported() too late in the boot process and
triggering an oops

* tag 'riscv-for-linus-6.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
riscv: errata: andes: Probe for IOCP only once in boot stage
riscv: Fix SMP when shadow call stacks are enabled
dt-bindings: perf: riscv,pmu: drop unneeded quotes
riscv: fix misaligned access handling of C.SWSP and C.SDSP
RISC-V: hwprobe: Always use u64 for extension bits
Support rv32 ULEB128 test
riscv: Correct type casting in module loading
riscv: Safely remove entries from relocation list

+106 -48
+1 -1
Documentation/devicetree/bindings/perf/riscv,pmu.yaml
··· 90 90 bitmap of all MHPMCOUNTERx that can monitor the range of events 91 91 92 92 dependencies: 93 - "riscv,event-to-mhpmevent": [ "riscv,event-to-mhpmcounters" ] 93 + riscv,event-to-mhpmevent: [ "riscv,event-to-mhpmcounters" ] 94 94 95 95 required: 96 96 - compatible
+13 -7
arch/riscv/errata/andes/errata.c
··· 38 38 return ret.error ? 0 : ret.value; 39 39 } 40 40 41 - static bool errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid) 41 + static void errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid) 42 42 { 43 + static bool done; 44 + 43 45 if (!IS_ENABLED(CONFIG_ERRATA_ANDES_CMO)) 44 - return false; 46 + return; 47 + 48 + if (done) 49 + return; 50 + 51 + done = true; 45 52 46 53 if (arch_id != ANDESTECH_AX45MP_MARCHID || impid != ANDESTECH_AX45MP_MIMPID) 47 - return false; 54 + return; 48 55 49 56 if (!ax45mp_iocp_sw_workaround()) 50 - return false; 57 + return; 51 58 52 59 /* Set this just to make core cbo code happy */ 53 60 riscv_cbom_block_size = 1; 54 61 riscv_noncoherent_supported(); 55 - 56 - return true; 57 62 } 58 63 59 64 void __init_or_module andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, 60 65 unsigned long archid, unsigned long impid, 61 66 unsigned int stage) 62 67 { 63 - errata_probe_iocp(stage, archid, impid); 68 + if (stage == RISCV_ALTERNATIVES_BOOT) 69 + errata_probe_iocp(stage, archid, impid); 64 70 65 71 /* we have nothing to patch here ATM so just return back */ 66 72 }
+1 -1
arch/riscv/kernel/head.S
··· 154 154 XIP_FIXUP_OFFSET a3 155 155 add a3, a3, a1 156 156 REG_L sp, (a3) 157 - scs_load_current 158 157 159 158 .Lsecondary_start_common: 160 159 ··· 164 165 call relocate_enable_mmu 165 166 #endif 166 167 call .Lsetup_trap_vector 168 + scs_load_current 167 169 tail smp_callin 168 170 #endif /* CONFIG_SMP */ 169 171
+84 -30
arch/riscv/kernel/module.c
··· 40 40 long buffer); 41 41 }; 42 42 43 - unsigned int initialize_relocation_hashtable(unsigned int num_relocations); 44 - void process_accumulated_relocations(struct module *me); 45 - int add_relocation_to_accumulate(struct module *me, int type, void *location, 46 - unsigned int hashtable_bits, Elf_Addr v); 47 - 48 - struct hlist_head *relocation_hashtable; 49 - 50 - struct list_head used_buckets_list; 51 - 52 43 /* 53 44 * The auipc+jalr instruction pair can reach any PC-relative offset 54 45 * in the range [-2^31 - 2^11, 2^31 - 2^11) ··· 55 64 56 65 static int riscv_insn_rmw(void *location, u32 keep, u32 set) 57 66 { 58 - u16 *parcel = location; 67 + __le16 *parcel = location; 59 68 u32 insn = (u32)le16_to_cpu(parcel[0]) | (u32)le16_to_cpu(parcel[1]) << 16; 60 69 61 70 insn &= keep; ··· 68 77 69 78 static int riscv_insn_rvc_rmw(void *location, u16 keep, u16 set) 70 79 { 71 - u16 *parcel = location; 80 + __le16 *parcel = location; 72 81 u16 insn = le16_to_cpu(*parcel); 73 82 74 83 insn &= keep; ··· 595 604 /* 192-255 nonstandard ABI extensions */ 596 605 }; 597 606 598 - void process_accumulated_relocations(struct module *me) 607 + static void 608 + process_accumulated_relocations(struct module *me, 609 + struct hlist_head **relocation_hashtable, 610 + struct list_head *used_buckets_list) 599 611 { 600 612 /* 601 613 * Only ADD/SUB/SET/ULEB128 should end up here. ··· 618 624 * - Each relocation entry for a location address 619 625 */ 620 626 struct used_bucket *bucket_iter; 627 + struct used_bucket *bucket_iter_tmp; 621 628 struct relocation_head *rel_head_iter; 629 + struct hlist_node *rel_head_iter_tmp; 622 630 struct relocation_entry *rel_entry_iter; 631 + struct relocation_entry *rel_entry_iter_tmp; 623 632 int curr_type; 624 633 void *location; 625 634 long buffer; 626 635 627 - list_for_each_entry(bucket_iter, &used_buckets_list, head) { 628 - hlist_for_each_entry(rel_head_iter, bucket_iter->bucket, node) { 636 + list_for_each_entry_safe(bucket_iter, bucket_iter_tmp, 637 + used_buckets_list, head) { 638 + hlist_for_each_entry_safe(rel_head_iter, rel_head_iter_tmp, 639 + bucket_iter->bucket, node) { 629 640 buffer = 0; 630 641 location = rel_head_iter->location; 631 - list_for_each_entry(rel_entry_iter, 632 - rel_head_iter->rel_entry, head) { 642 + list_for_each_entry_safe(rel_entry_iter, 643 + rel_entry_iter_tmp, 644 + rel_head_iter->rel_entry, 645 + head) { 633 646 curr_type = rel_entry_iter->type; 634 647 reloc_handlers[curr_type].reloc_handler( 635 648 me, &buffer, rel_entry_iter->value); ··· 649 648 kfree(bucket_iter); 650 649 } 651 650 652 - kfree(relocation_hashtable); 651 + kfree(*relocation_hashtable); 653 652 } 654 653 655 - int add_relocation_to_accumulate(struct module *me, int type, void *location, 656 - unsigned int hashtable_bits, Elf_Addr v) 654 + static int add_relocation_to_accumulate(struct module *me, int type, 655 + void *location, 656 + unsigned int hashtable_bits, Elf_Addr v, 657 + struct hlist_head *relocation_hashtable, 658 + struct list_head *used_buckets_list) 657 659 { 658 660 struct relocation_entry *entry; 659 661 struct relocation_head *rel_head; ··· 665 661 unsigned long hash; 666 662 667 663 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 664 + 665 + if (!entry) 666 + return -ENOMEM; 667 + 668 668 INIT_LIST_HEAD(&entry->head); 669 669 entry->type = type; 670 670 entry->value = v; ··· 677 669 678 670 current_head = &relocation_hashtable[hash]; 679 671 680 - /* Find matching location (if any) */ 672 + /* 673 + * Search for the relocation_head for the relocations that happen at the 674 + * provided location 675 + */ 681 676 bool found = false; 682 677 struct relocation_head *rel_head_iter; 683 678 ··· 692 681 } 693 682 } 694 683 684 + /* 685 + * If there has not yet been any relocations at the provided location, 686 + * create a relocation_head for that location and populate it with this 687 + * relocation_entry. 688 + */ 695 689 if (!found) { 696 690 rel_head = kmalloc(sizeof(*rel_head), GFP_KERNEL); 691 + 692 + if (!rel_head) { 693 + kfree(entry); 694 + return -ENOMEM; 695 + } 696 + 697 697 rel_head->rel_entry = 698 698 kmalloc(sizeof(struct list_head), GFP_KERNEL); 699 + 700 + if (!rel_head->rel_entry) { 701 + kfree(entry); 702 + kfree(rel_head); 703 + return -ENOMEM; 704 + } 705 + 699 706 INIT_LIST_HEAD(rel_head->rel_entry); 700 707 rel_head->location = location; 701 708 INIT_HLIST_NODE(&rel_head->node); 702 709 if (!current_head->first) { 703 710 bucket = 704 711 kmalloc(sizeof(struct used_bucket), GFP_KERNEL); 712 + 713 + if (!bucket) { 714 + kfree(entry); 715 + kfree(rel_head); 716 + kfree(rel_head->rel_entry); 717 + return -ENOMEM; 718 + } 719 + 705 720 INIT_LIST_HEAD(&bucket->head); 706 721 bucket->bucket = current_head; 707 - list_add(&bucket->head, &used_buckets_list); 722 + list_add(&bucket->head, used_buckets_list); 708 723 } 709 724 hlist_add_head(&rel_head->node, current_head); 710 725 } ··· 741 704 return 0; 742 705 } 743 706 744 - unsigned int initialize_relocation_hashtable(unsigned int num_relocations) 707 + static unsigned int 708 + initialize_relocation_hashtable(unsigned int num_relocations, 709 + struct hlist_head **relocation_hashtable) 745 710 { 746 711 /* Can safely assume that bits is not greater than sizeof(long) */ 747 712 unsigned long hashtable_size = roundup_pow_of_two(num_relocations); ··· 759 720 760 721 hashtable_size <<= should_double_size; 761 722 762 - relocation_hashtable = kmalloc_array(hashtable_size, 763 - sizeof(*relocation_hashtable), 764 - GFP_KERNEL); 765 - __hash_init(relocation_hashtable, hashtable_size); 723 + *relocation_hashtable = kmalloc_array(hashtable_size, 724 + sizeof(*relocation_hashtable), 725 + GFP_KERNEL); 726 + if (!*relocation_hashtable) 727 + return -ENOMEM; 766 728 767 - INIT_LIST_HEAD(&used_buckets_list); 729 + __hash_init(*relocation_hashtable, hashtable_size); 768 730 769 731 return hashtable_bits; 770 732 } ··· 782 742 Elf_Addr v; 783 743 int res; 784 744 unsigned int num_relocations = sechdrs[relsec].sh_size / sizeof(*rel); 785 - unsigned int hashtable_bits = initialize_relocation_hashtable(num_relocations); 745 + struct hlist_head *relocation_hashtable; 746 + struct list_head used_buckets_list; 747 + unsigned int hashtable_bits; 748 + 749 + hashtable_bits = initialize_relocation_hashtable(num_relocations, 750 + &relocation_hashtable); 751 + 752 + if (hashtable_bits < 0) 753 + return hashtable_bits; 754 + 755 + INIT_LIST_HEAD(&used_buckets_list); 786 756 787 757 pr_debug("Applying relocate section %u to %u\n", relsec, 788 758 sechdrs[relsec].sh_info); ··· 873 823 } 874 824 875 825 if (reloc_handlers[type].accumulate_handler) 876 - res = add_relocation_to_accumulate(me, type, location, hashtable_bits, v); 826 + res = add_relocation_to_accumulate(me, type, location, 827 + hashtable_bits, v, 828 + relocation_hashtable, 829 + &used_buckets_list); 877 830 else 878 831 res = handler(me, location, v); 879 832 if (res) 880 833 return res; 881 834 } 882 835 883 - process_accumulated_relocations(me); 836 + process_accumulated_relocations(me, &relocation_hashtable, 837 + &used_buckets_list); 884 838 885 839 return 0; 886 840 }
+1 -1
arch/riscv/kernel/sys_riscv.c
··· 169 169 pair->value &= ~missing; 170 170 } 171 171 172 - static bool hwprobe_ext0_has(const struct cpumask *cpus, unsigned long ext) 172 + static bool hwprobe_ext0_has(const struct cpumask *cpus, u64 ext) 173 173 { 174 174 struct riscv_hwprobe pair; 175 175
+4 -4
arch/riscv/kernel/tests/module_test/test_uleb128.S
··· 6 6 .text 7 7 .global test_uleb_basic 8 8 test_uleb_basic: 9 - ld a0, second 9 + lw a0, second 10 10 addi a0, a0, -127 11 11 ret 12 12 13 13 .global test_uleb_large 14 14 test_uleb_large: 15 - ld a0, fourth 15 + lw a0, fourth 16 16 addi a0, a0, -0x07e8 17 17 ret 18 18 ··· 22 22 second: 23 23 .reloc second, R_RISCV_SET_ULEB128, second 24 24 .reloc second, R_RISCV_SUB_ULEB128, first 25 - .dword 0 25 + .word 0 26 26 third: 27 27 .space 1000 28 28 fourth: 29 29 .reloc fourth, R_RISCV_SET_ULEB128, fourth 30 30 .reloc fourth, R_RISCV_SUB_ULEB128, third 31 - .dword 0 31 + .word 0
+2 -4
arch/riscv/kernel/traps_misaligned.c
··· 550 550 } else if ((insn & INSN_MASK_C_SD) == INSN_MATCH_C_SD) { 551 551 len = 8; 552 552 val.data_ulong = GET_RS2S(insn, regs); 553 - } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP && 554 - ((insn >> SH_RD) & 0x1f)) { 553 + } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP) { 555 554 len = 8; 556 555 val.data_ulong = GET_RS2C(insn, regs); 557 556 #endif 558 557 } else if ((insn & INSN_MASK_C_SW) == INSN_MATCH_C_SW) { 559 558 len = 4; 560 559 val.data_ulong = GET_RS2S(insn, regs); 561 - } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP && 562 - ((insn >> SH_RD) & 0x1f)) { 560 + } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP) { 563 561 len = 4; 564 562 val.data_ulong = GET_RS2C(insn, regs); 565 563 } else if ((insn & INSN_MASK_C_FSD) == INSN_MATCH_C_FSD) {