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.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull RISC-V fixes from Palmer Dabbelt:

- A fix for the CMODX example in the recently added icache flushing
prctl()

- A fix to the perf driver to avoid corrupting event data on counter
overflows when external overflow handlers are in use

- A fix to clear all hardware performance monitor events on boot, to
avoid dangling events firmware or previously booted kernels from
triggering spuriously

- A fix to the perf event probing logic to avoid erroneously reporting
the presence of unimplemented counters. This also prevents some
implemented counters from being reported

- A build fix for the vector sigreturn selftest on clang

- A fix to ftrace, which now requires the previously optional index
argument to ftrace_graph_ret_addr()

- A fix to avoid deadlocking if kexec crash handling triggers in an
interrupt context

* tag 'riscv-for-linus-6.10-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
riscv: kexec: Avoid deadlock in kexec crash path
riscv: stacktrace: fix usage of ftrace_graph_ret_addr()
riscv: selftests: Fix vsetivli args for clang
perf: RISC-V: Check standard event availability
drivers/perf: riscv: Reset the counter to hpmevent mapping while starting cpus
drivers/perf: riscv: Do not update the event data if uptodate
documentation: Fix riscv cmodx example

+49 -18
+2 -2
Documentation/arch/riscv/cmodx.rst
··· 62 62 printf("Value before cmodx: %d\n", value); 63 63 64 64 // Call prctl before first fence.i is called inside modify_instruction 65 - prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX_ON, PR_RISCV_CTX_SW_FENCEI, PR_RISCV_SCOPE_PER_PROCESS); 65 + prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, PR_RISCV_CTX_SW_FENCEI_ON, PR_RISCV_SCOPE_PER_PROCESS); 66 66 modify_instruction(); 67 67 // Call prctl after final fence.i is called in process 68 - prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX_OFF, PR_RISCV_CTX_SW_FENCEI, PR_RISCV_SCOPE_PER_PROCESS); 68 + prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, PR_RISCV_CTX_SW_FENCEI_OFF, PR_RISCV_SCOPE_PER_PROCESS); 69 69 70 70 value = get_value(); 71 71 printf("Value after cmodx: %d\n", value);
+1 -9
arch/riscv/kernel/machine_kexec.c
··· 121 121 122 122 for_each_irq_desc(i, desc) { 123 123 struct irq_chip *chip; 124 - int ret; 125 124 126 125 chip = irq_desc_get_chip(desc); 127 126 if (!chip) 128 127 continue; 129 128 130 - /* 131 - * First try to remove the active state. If this 132 - * fails, try to EOI the interrupt. 133 - */ 134 - ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false); 135 - 136 - if (ret && irqd_irq_inprogress(&desc->irq_data) && 137 - chip->irq_eoi) 129 + if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) 138 130 chip->irq_eoi(&desc->irq_data); 139 131 140 132 if (chip->irq_mask)
+2 -1
arch/riscv/kernel/stacktrace.c
··· 32 32 bool (*fn)(void *, unsigned long), void *arg) 33 33 { 34 34 unsigned long fp, sp, pc; 35 + int graph_idx = 0; 35 36 int level = 0; 36 37 37 38 if (regs) { ··· 69 68 pc = regs->ra; 70 69 } else { 71 70 fp = frame->fp; 72 - pc = ftrace_graph_ret_addr(current, NULL, frame->ra, 71 + pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra, 73 72 &frame->ra); 74 73 if (pc == (unsigned long)ret_from_exception) { 75 74 if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))
+1 -1
arch/riscv/kvm/vcpu_pmu.c
··· 327 327 328 328 event = perf_event_create_kernel_counter(attr, -1, current, kvm_riscv_pmu_overflow, pmc); 329 329 if (IS_ERR(event)) { 330 - pr_err("kvm pmu event creation failed for eidx %lx: %ld\n", eidx, PTR_ERR(event)); 330 + pr_debug("kvm pmu event creation failed for eidx %lx: %ld\n", eidx, PTR_ERR(event)); 331 331 return PTR_ERR(event); 332 332 } 333 333
+1 -1
drivers/perf/riscv_pmu.c
··· 167 167 unsigned long cmask; 168 168 u64 oldval, delta; 169 169 170 - if (!rvpmu->ctr_read) 170 + if (!rvpmu->ctr_read || (hwc->state & PERF_HES_UPTODATE)) 171 171 return 0; 172 172 173 173 cmask = riscv_pmu_ctr_get_width_mask(event);
+41 -3
drivers/perf/riscv_pmu_sbi.c
··· 20 20 #include <linux/cpu_pm.h> 21 21 #include <linux/sched/clock.h> 22 22 #include <linux/soc/andes/irq.h> 23 + #include <linux/workqueue.h> 23 24 24 25 #include <asm/errata_list.h> 25 26 #include <asm/sbi.h> ··· 115 114 }; 116 115 }; 117 116 118 - static const struct sbi_pmu_event_data pmu_hw_event_map[] = { 117 + static struct sbi_pmu_event_data pmu_hw_event_map[] = { 119 118 [PERF_COUNT_HW_CPU_CYCLES] = {.hw_gen_event = { 120 119 SBI_PMU_HW_CPU_CYCLES, 121 120 SBI_PMU_EVENT_TYPE_HW, 0}}, ··· 149 148 }; 150 149 151 150 #define C(x) PERF_COUNT_HW_CACHE_##x 152 - static const struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX] 151 + static struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX] 153 152 [PERF_COUNT_HW_CACHE_OP_MAX] 154 153 [PERF_COUNT_HW_CACHE_RESULT_MAX] = { 155 154 [C(L1D)] = { ··· 293 292 }, 294 293 }, 295 294 }; 295 + 296 + static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata) 297 + { 298 + struct sbiret ret; 299 + 300 + ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, 301 + 0, cmask, 0, edata->event_idx, 0, 0); 302 + if (!ret.error) { 303 + sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, 304 + ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0); 305 + } else if (ret.error == SBI_ERR_NOT_SUPPORTED) { 306 + /* This event cannot be monitored by any counter */ 307 + edata->event_idx = -EINVAL; 308 + } 309 + } 310 + 311 + static void pmu_sbi_check_std_events(struct work_struct *work) 312 + { 313 + for (int i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++) 314 + pmu_sbi_check_event(&pmu_hw_event_map[i]); 315 + 316 + for (int i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++) 317 + for (int j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++) 318 + for (int k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++) 319 + pmu_sbi_check_event(&pmu_cache_event_map[i][j][k]); 320 + } 321 + 322 + static DECLARE_WORK(check_std_events_work, pmu_sbi_check_std_events); 296 323 297 324 static int pmu_sbi_ctr_get_width(int idx) 298 325 { ··· 506 477 int bSoftware; 507 478 u64 raw_config_val; 508 479 int ret; 480 + 481 + /* 482 + * Ensure we are finished checking standard hardware events for 483 + * validity before allowing userspace to configure any events. 484 + */ 485 + flush_work(&check_std_events_work); 509 486 510 487 switch (type) { 511 488 case PERF_TYPE_HARDWARE: ··· 797 762 * which may include counters that are not enabled yet. 798 763 */ 799 764 sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, 800 - 0, pmu->cmask, 0, 0, 0, 0); 765 + 0, pmu->cmask, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0); 801 766 } 802 767 803 768 static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu) ··· 1393 1358 ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node); 1394 1359 if (ret) 1395 1360 goto out_unregister; 1361 + 1362 + /* Asynchronously check which standard events are available */ 1363 + schedule_work(&check_std_events_work); 1396 1364 1397 1365 return 0; 1398 1366
+1 -1
tools/testing/selftests/riscv/sigreturn/sigreturn.c
··· 51 51 52 52 asm(".option push \n\ 53 53 .option arch, +v \n\ 54 - vsetivli x0, 1, e32, ta, ma \n\ 54 + vsetivli x0, 1, e32, m1, ta, ma \n\ 55 55 vmv.s.x v0, %1 \n\ 56 56 # Generate SIGSEGV \n\ 57 57 lw a0, 0(x0) \n\