Skip to content

Commit b673f2b

Browse files
committed
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
2 parents dd9d739 + c562ba7 commit b673f2b

File tree

7 files changed

+49
-18
lines changed

7 files changed

+49
-18
lines changed

Documentation/arch/riscv/cmodx.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ cmodx.c::
6262
printf("Value before cmodx: %d\n", value);
6363

6464
// 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);
6666
modify_instruction();
6767
// 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);
6969

7070
value = get_value();
7171
printf("Value after cmodx: %d\n", value);

arch/riscv/kernel/machine_kexec.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,20 +121,12 @@ static void machine_kexec_mask_interrupts(void)
121121

122122
for_each_irq_desc(i, desc) {
123123
struct irq_chip *chip;
124-
int ret;
125124

126125
chip = irq_desc_get_chip(desc);
127126
if (!chip)
128127
continue;
129128

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))
138130
chip->irq_eoi(&desc->irq_data);
139131

140132
if (chip->irq_mask)

arch/riscv/kernel/stacktrace.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
3232
bool (*fn)(void *, unsigned long), void *arg)
3333
{
3434
unsigned long fp, sp, pc;
35+
int graph_idx = 0;
3536
int level = 0;
3637

3738
if (regs) {
@@ -68,7 +69,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
6869
pc = regs->ra;
6970
} else {
7071
fp = frame->fp;
71-
pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
72+
pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra,
7273
&frame->ra);
7374
if (pc == (unsigned long)ret_from_exception) {
7475
if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))

arch/riscv/kvm/vcpu_pmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ static long kvm_pmu_create_perf_event(struct kvm_pmc *pmc, struct perf_event_att
327327

328328
event = perf_event_create_kernel_counter(attr, -1, current, kvm_riscv_pmu_overflow, pmc);
329329
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));
331331
return PTR_ERR(event);
332332
}
333333

drivers/perf/riscv_pmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ u64 riscv_pmu_event_update(struct perf_event *event)
167167
unsigned long cmask;
168168
u64 oldval, delta;
169169

170-
if (!rvpmu->ctr_read)
170+
if (!rvpmu->ctr_read || (hwc->state & PERF_HES_UPTODATE))
171171
return 0;
172172

173173
cmask = riscv_pmu_ctr_get_width_mask(event);

drivers/perf/riscv_pmu_sbi.c

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/cpu_pm.h>
2121
#include <linux/sched/clock.h>
2222
#include <linux/soc/andes/irq.h>
23+
#include <linux/workqueue.h>
2324

2425
#include <asm/errata_list.h>
2526
#include <asm/sbi.h>
@@ -114,7 +115,7 @@ struct sbi_pmu_event_data {
114115
};
115116
};
116117

117-
static const struct sbi_pmu_event_data pmu_hw_event_map[] = {
118+
static struct sbi_pmu_event_data pmu_hw_event_map[] = {
118119
[PERF_COUNT_HW_CPU_CYCLES] = {.hw_gen_event = {
119120
SBI_PMU_HW_CPU_CYCLES,
120121
SBI_PMU_EVENT_TYPE_HW, 0}},
@@ -148,7 +149,7 @@ static const struct sbi_pmu_event_data pmu_hw_event_map[] = {
148149
};
149150

150151
#define C(x) PERF_COUNT_HW_CACHE_##x
151-
static const struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
152+
static struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
152153
[PERF_COUNT_HW_CACHE_OP_MAX]
153154
[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
154155
[C(L1D)] = {
@@ -293,6 +294,34 @@ static const struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_M
293294
},
294295
};
295296

297+
static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
298+
{
299+
struct sbiret ret;
300+
301+
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH,
302+
0, cmask, 0, edata->event_idx, 0, 0);
303+
if (!ret.error) {
304+
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
305+
ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
306+
} else if (ret.error == SBI_ERR_NOT_SUPPORTED) {
307+
/* This event cannot be monitored by any counter */
308+
edata->event_idx = -EINVAL;
309+
}
310+
}
311+
312+
static void pmu_sbi_check_std_events(struct work_struct *work)
313+
{
314+
for (int i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++)
315+
pmu_sbi_check_event(&pmu_hw_event_map[i]);
316+
317+
for (int i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++)
318+
for (int j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++)
319+
for (int k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++)
320+
pmu_sbi_check_event(&pmu_cache_event_map[i][j][k]);
321+
}
322+
323+
static DECLARE_WORK(check_std_events_work, pmu_sbi_check_std_events);
324+
296325
static int pmu_sbi_ctr_get_width(int idx)
297326
{
298327
return pmu_ctr_list[idx].width;
@@ -478,6 +507,12 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
478507
u64 raw_config_val;
479508
int ret;
480509

510+
/*
511+
* Ensure we are finished checking standard hardware events for
512+
* validity before allowing userspace to configure any events.
513+
*/
514+
flush_work(&check_std_events_work);
515+
481516
switch (type) {
482517
case PERF_TYPE_HARDWARE:
483518
if (config >= PERF_COUNT_HW_MAX)
@@ -762,7 +797,7 @@ static inline void pmu_sbi_stop_all(struct riscv_pmu *pmu)
762797
* which may include counters that are not enabled yet.
763798
*/
764799
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
765-
0, pmu->cmask, 0, 0, 0, 0);
800+
0, pmu->cmask, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
766801
}
767802

768803
static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
@@ -1359,6 +1394,9 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
13591394
if (ret)
13601395
goto out_unregister;
13611396

1397+
/* Asynchronously check which standard events are available */
1398+
schedule_work(&check_std_events_work);
1399+
13621400
return 0;
13631401

13641402
out_unregister:

tools/testing/selftests/riscv/sigreturn/sigreturn.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static int vector_sigreturn(int data, void (*handler)(int, siginfo_t *, void *))
5151

5252
asm(".option push \n\
5353
.option arch, +v \n\
54-
vsetivli x0, 1, e32, ta, ma \n\
54+
vsetivli x0, 1, e32, m1, ta, ma \n\
5555
vmv.s.x v0, %1 \n\
5656
# Generate SIGSEGV \n\
5757
lw a0, 0(x0) \n\

0 commit comments

Comments
 (0)