Skip to content

Commit 9bb9565

Browse files
committed
Merge tag 'riscv-for-linus-6.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux
Pull RISC-V fixes from Paul Walmsley: - Close a race during boot between userspace vDSO usage and some late-initialized vDSO data - Improve performance on systems with non-CPU-cache-coherent DMA-capable peripherals by enabling write combining on pgprot_dmacoherent() allocations - Add human-readable detail for RISC-V IPI tracing - Provide more information to zsmalloc on 64-bit RISC-V to improve allocation - Silence useless boot messages about CPUs that have been disabled in DT - Resolve some compiler and smatch warnings and remove a redundant macro * tag 'riscv-for-linus-6.18-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: riscv: hwprobe: avoid uninitialized variable use in hwprobe_arch_id() riscv: cpufeature: avoid uninitialized variable in has_thead_homogeneous_vlenb() riscv: hwprobe: Fix stale vDSO data for late-initialized keys at boot riscv: add a forward declaration for cpuinfo_op RISC-V: Don't print details of CPUs disabled in DT riscv: Remove the PER_CPU_OFFSET_SHIFT macro riscv: mm: Define MAX_POSSIBLE_PHYSMEM_BITS for zsmalloc riscv: Register IPI IRQs with unique names ACPI: RIMT: Fix unused function warnings when CONFIG_IOMMU_API is disabled RISC-V: Define pgprot_dmacoherent() for non-coherent devices
2 parents 27c0b5c + b7776a8 commit 9bb9565

File tree

13 files changed

+168
-100
lines changed

13 files changed

+168
-100
lines changed

arch/riscv/include/asm/asm.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,9 @@
8484
.endm
8585

8686
#ifdef CONFIG_SMP
87-
#ifdef CONFIG_32BIT
88-
#define PER_CPU_OFFSET_SHIFT 2
89-
#else
90-
#define PER_CPU_OFFSET_SHIFT 3
91-
#endif
92-
9387
.macro asm_per_cpu dst sym tmp
9488
lw \tmp, TASK_TI_CPU_NUM(tp)
95-
slli \tmp, \tmp, PER_CPU_OFFSET_SHIFT
89+
slli \tmp, \tmp, RISCV_LGPTR
9690
la \dst, __per_cpu_offset
9791
add \dst, \dst, \tmp
9892
REG_L \tmp, 0(\dst)

arch/riscv/include/asm/cpufeature.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ struct riscv_isainfo {
3131

3232
DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
3333

34+
extern const struct seq_operations cpuinfo_op;
35+
3436
/* Per-cpu ISA extensions. */
3537
extern struct riscv_isainfo hart_isa[NR_CPUS];
3638

arch/riscv/include/asm/hwprobe.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,11 @@ static inline bool riscv_hwprobe_pair_cmp(struct riscv_hwprobe *pair,
4242
return pair->value == other_pair->value;
4343
}
4444

45+
#ifdef CONFIG_MMU
46+
void riscv_hwprobe_register_async_probe(void);
47+
void riscv_hwprobe_complete_async_probe(void);
48+
#else
49+
static inline void riscv_hwprobe_register_async_probe(void) {}
50+
static inline void riscv_hwprobe_complete_async_probe(void) {}
51+
#endif
4552
#endif

arch/riscv/include/asm/pgtable-64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ typedef struct {
6969

7070
#define PTRS_PER_PMD (PAGE_SIZE / sizeof(pmd_t))
7171

72+
#define MAX_POSSIBLE_PHYSMEM_BITS 56
73+
7274
/*
7375
* rv64 PTE format:
7476
* | 63 | 62 61 | 60 54 | 53 10 | 9 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0

arch/riscv/include/asm/pgtable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,8 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
654654
return __pgprot(prot);
655655
}
656656

657+
#define pgprot_dmacoherent pgprot_writecombine
658+
657659
/*
658660
* Both Svade and Svadu control the hardware behavior when the PTE A/D bits need to be set. By
659661
* default the M-mode firmware enables the hardware updating scheme when only Svadu is present in

arch/riscv/include/asm/vdso/arch_data.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ struct vdso_arch_data {
1212

1313
/* Boolean indicating all CPUs have the same static hwprobe values. */
1414
__u8 homogeneous_cpus;
15+
16+
/*
17+
* A gate to check and see if the hwprobe data is actually ready, as
18+
* probing is deferred to avoid boot slowdowns.
19+
*/
20+
__u8 ready;
1521
};
1622

1723
#endif /* __RISCV_ASM_VDSO_ARCH_DATA_H */

arch/riscv/kernel/cpu.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,8 @@ int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned lo
6262
return -ENODEV;
6363
}
6464

65-
if (!of_device_is_available(node)) {
66-
pr_info("CPU with hartid=%lu is not available\n", *hart);
65+
if (!of_device_is_available(node))
6766
return -ENODEV;
68-
}
6967

7068
if (of_property_read_string(node, "riscv,isa-base", &isa))
7169
goto old_interface;

arch/riscv/kernel/cpufeature.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -932,9 +932,9 @@ static int has_thead_homogeneous_vlenb(void)
932932
{
933933
int cpu;
934934
u32 prev_vlenb = 0;
935-
u32 vlenb;
935+
u32 vlenb = 0;
936936

937-
/* Ignore thead,vlenb property if xtheavector is not enabled in the kernel */
937+
/* Ignore thead,vlenb property if xtheadvector is not enabled in the kernel */
938938
if (!IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR))
939939
return 0;
940940

arch/riscv/kernel/smp.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ enum ipi_message_type {
4040
IPI_MAX
4141
};
4242

43+
static const char * const ipi_names[] = {
44+
[IPI_RESCHEDULE] = "Rescheduling interrupts",
45+
[IPI_CALL_FUNC] = "Function call interrupts",
46+
[IPI_CPU_STOP] = "CPU stop interrupts",
47+
[IPI_CPU_CRASH_STOP] = "CPU stop (for crash dump) interrupts",
48+
[IPI_IRQ_WORK] = "IRQ work interrupts",
49+
[IPI_TIMER] = "Timer broadcast interrupts",
50+
[IPI_CPU_BACKTRACE] = "CPU backtrace interrupts",
51+
[IPI_KGDB_ROUNDUP] = "KGDB roundup interrupts",
52+
};
53+
4354
unsigned long __cpuid_to_hartid_map[NR_CPUS] __ro_after_init = {
4455
[0 ... NR_CPUS-1] = INVALID_HARTID
4556
};
@@ -199,7 +210,7 @@ void riscv_ipi_set_virq_range(int virq, int nr)
199210
/* Request IPIs */
200211
for (i = 0; i < nr_ipi; i++) {
201212
err = request_percpu_irq(ipi_virq_base + i, handle_IPI,
202-
"IPI", &ipi_dummy_dev);
213+
ipi_names[i], &ipi_dummy_dev);
203214
WARN_ON(err);
204215

205216
ipi_desc[i] = irq_to_desc(ipi_virq_base + i);
@@ -210,17 +221,6 @@ void riscv_ipi_set_virq_range(int virq, int nr)
210221
riscv_ipi_enable();
211222
}
212223

213-
static const char * const ipi_names[] = {
214-
[IPI_RESCHEDULE] = "Rescheduling interrupts",
215-
[IPI_CALL_FUNC] = "Function call interrupts",
216-
[IPI_CPU_STOP] = "CPU stop interrupts",
217-
[IPI_CPU_CRASH_STOP] = "CPU stop (for crash dump) interrupts",
218-
[IPI_IRQ_WORK] = "IRQ work interrupts",
219-
[IPI_TIMER] = "Timer broadcast interrupts",
220-
[IPI_CPU_BACKTRACE] = "CPU backtrace interrupts",
221-
[IPI_KGDB_ROUNDUP] = "KGDB roundup interrupts",
222-
};
223-
224224
void show_ipi_stats(struct seq_file *p, int prec)
225225
{
226226
unsigned int cpu, i;

arch/riscv/kernel/sys_hwprobe.c

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
* more details.
66
*/
77
#include <linux/syscalls.h>
8+
#include <linux/completion.h>
9+
#include <linux/atomic.h>
10+
#include <linux/once.h>
811
#include <asm/cacheflush.h>
912
#include <asm/cpufeature.h>
1013
#include <asm/hwprobe.h>
@@ -28,6 +31,11 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair,
2831
bool first = true;
2932
int cpu;
3033

34+
if (pair->key != RISCV_HWPROBE_KEY_MVENDORID &&
35+
pair->key != RISCV_HWPROBE_KEY_MIMPID &&
36+
pair->key != RISCV_HWPROBE_KEY_MARCHID)
37+
goto out;
38+
3139
for_each_cpu(cpu, cpus) {
3240
u64 cpu_id;
3341

@@ -58,6 +66,7 @@ static void hwprobe_arch_id(struct riscv_hwprobe *pair,
5866
}
5967
}
6068

69+
out:
6170
pair->value = id;
6271
}
6372

@@ -454,28 +463,32 @@ static int hwprobe_get_cpus(struct riscv_hwprobe __user *pairs,
454463
return 0;
455464
}
456465

457-
static int do_riscv_hwprobe(struct riscv_hwprobe __user *pairs,
458-
size_t pair_count, size_t cpusetsize,
459-
unsigned long __user *cpus_user,
460-
unsigned int flags)
461-
{
462-
if (flags & RISCV_HWPROBE_WHICH_CPUS)
463-
return hwprobe_get_cpus(pairs, pair_count, cpusetsize,
464-
cpus_user, flags);
466+
#ifdef CONFIG_MMU
465467

466-
return hwprobe_get_values(pairs, pair_count, cpusetsize,
467-
cpus_user, flags);
468+
static DECLARE_COMPLETION(boot_probes_done);
469+
static atomic_t pending_boot_probes = ATOMIC_INIT(1);
470+
471+
void riscv_hwprobe_register_async_probe(void)
472+
{
473+
atomic_inc(&pending_boot_probes);
468474
}
469475

470-
#ifdef CONFIG_MMU
476+
void riscv_hwprobe_complete_async_probe(void)
477+
{
478+
if (atomic_dec_and_test(&pending_boot_probes))
479+
complete(&boot_probes_done);
480+
}
471481

472-
static int __init init_hwprobe_vdso_data(void)
482+
static int complete_hwprobe_vdso_data(void)
473483
{
474484
struct vdso_arch_data *avd = vdso_k_arch_data;
475485
u64 id_bitsmash = 0;
476486
struct riscv_hwprobe pair;
477487
int key;
478488

489+
if (unlikely(!atomic_dec_and_test(&pending_boot_probes)))
490+
wait_for_completion(&boot_probes_done);
491+
479492
/*
480493
* Initialize vDSO data with the answers for the "all CPUs" case, to
481494
* save a syscall in the common case.
@@ -503,13 +516,52 @@ static int __init init_hwprobe_vdso_data(void)
503516
* vDSO should defer to the kernel for exotic cpu masks.
504517
*/
505518
avd->homogeneous_cpus = id_bitsmash != 0 && id_bitsmash != -1;
519+
520+
/*
521+
* Make sure all the VDSO values are visible before we look at them.
522+
* This pairs with the implicit "no speculativly visible accesses"
523+
* barrier in the VDSO hwprobe code.
524+
*/
525+
smp_wmb();
526+
avd->ready = true;
527+
return 0;
528+
}
529+
530+
static int __init init_hwprobe_vdso_data(void)
531+
{
532+
struct vdso_arch_data *avd = vdso_k_arch_data;
533+
534+
/*
535+
* Prevent the vDSO cached values from being used, as they're not ready
536+
* yet.
537+
*/
538+
avd->ready = false;
506539
return 0;
507540
}
508541

509542
arch_initcall_sync(init_hwprobe_vdso_data);
510543

544+
#else
545+
546+
static int complete_hwprobe_vdso_data(void) { return 0; }
547+
511548
#endif /* CONFIG_MMU */
512549

550+
static int do_riscv_hwprobe(struct riscv_hwprobe __user *pairs,
551+
size_t pair_count, size_t cpusetsize,
552+
unsigned long __user *cpus_user,
553+
unsigned int flags)
554+
{
555+
DO_ONCE_SLEEPABLE(complete_hwprobe_vdso_data);
556+
557+
if (flags & RISCV_HWPROBE_WHICH_CPUS)
558+
return hwprobe_get_cpus(pairs, pair_count, cpusetsize,
559+
cpus_user, flags);
560+
561+
return hwprobe_get_values(pairs, pair_count, cpusetsize,
562+
cpus_user, flags);
563+
}
564+
513565
SYSCALL_DEFINE5(riscv_hwprobe, struct riscv_hwprobe __user *, pairs,
514566
size_t, pair_count, size_t, cpusetsize, unsigned long __user *,
515567
cpus, unsigned int, flags)

0 commit comments

Comments
 (0)