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

Pull RISC-V fixes from Palmer Dabbelt:
"A set of three fixes, all aimed at fixing some fallout from the recent
sparse hart ID support"

* tag 'riscv-for-linus-5.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
RISC-V: Fix IPI/RFENCE hmask on non-monotonic hartid ordering
RISC-V: Fix handling of empty cpu masks
RISC-V: Fix hartid mask handling for hartid 31 and up

+47 -25
+47 -25
arch/riscv/kernel/sbi.c
··· 5 5 * Copyright (c) 2020 Western Digital Corporation or its affiliates. 6 6 */ 7 7 8 + #include <linux/bits.h> 8 9 #include <linux/init.h> 9 10 #include <linux/pm.h> 10 11 #include <linux/reboot.h> ··· 86 85 pr_warn("Unable to send any request to hartid > BITS_PER_LONG for SBI v0.1\n"); 87 86 break; 88 87 } 89 - hmask |= 1 << hartid; 88 + hmask |= BIT(hartid); 90 89 } 91 90 92 91 return hmask; ··· 161 160 { 162 161 unsigned long hart_mask; 163 162 164 - if (!cpu_mask) 163 + if (!cpu_mask || cpumask_empty(cpu_mask)) 165 164 cpu_mask = cpu_online_mask; 166 165 hart_mask = __sbi_v01_cpumask_to_hartmask(cpu_mask); 167 166 ··· 177 176 int result = 0; 178 177 unsigned long hart_mask; 179 178 180 - if (!cpu_mask) 179 + if (!cpu_mask || cpumask_empty(cpu_mask)) 181 180 cpu_mask = cpu_online_mask; 182 181 hart_mask = __sbi_v01_cpumask_to_hartmask(cpu_mask); 183 182 ··· 250 249 251 250 static int __sbi_send_ipi_v02(const struct cpumask *cpu_mask) 252 251 { 253 - unsigned long hartid, cpuid, hmask = 0, hbase = 0; 252 + unsigned long hartid, cpuid, hmask = 0, hbase = 0, htop = 0; 254 253 struct sbiret ret = {0}; 255 254 int result; 256 255 257 - if (!cpu_mask) 256 + if (!cpu_mask || cpumask_empty(cpu_mask)) 258 257 cpu_mask = cpu_online_mask; 259 258 260 259 for_each_cpu(cpuid, cpu_mask) { 261 260 hartid = cpuid_to_hartid_map(cpuid); 262 - if (hmask && ((hbase + BITS_PER_LONG) <= hartid)) { 263 - ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, 264 - hmask, hbase, 0, 0, 0, 0); 265 - if (ret.error) 266 - goto ecall_failed; 267 - hmask = 0; 268 - hbase = 0; 261 + if (hmask) { 262 + if (hartid + BITS_PER_LONG <= htop || 263 + hbase + BITS_PER_LONG <= hartid) { 264 + ret = sbi_ecall(SBI_EXT_IPI, 265 + SBI_EXT_IPI_SEND_IPI, hmask, 266 + hbase, 0, 0, 0, 0); 267 + if (ret.error) 268 + goto ecall_failed; 269 + hmask = 0; 270 + } else if (hartid < hbase) { 271 + /* shift the mask to fit lower hartid */ 272 + hmask <<= hbase - hartid; 273 + hbase = hartid; 274 + } 269 275 } 270 - if (!hmask) 276 + if (!hmask) { 271 277 hbase = hartid; 272 - hmask |= 1UL << (hartid - hbase); 278 + htop = hartid; 279 + } else if (hartid > htop) { 280 + htop = hartid; 281 + } 282 + hmask |= BIT(hartid - hbase); 273 283 } 274 284 275 285 if (hmask) { ··· 356 344 unsigned long start, unsigned long size, 357 345 unsigned long arg4, unsigned long arg5) 358 346 { 359 - unsigned long hartid, cpuid, hmask = 0, hbase = 0; 347 + unsigned long hartid, cpuid, hmask = 0, hbase = 0, htop = 0; 360 348 int result; 361 349 362 - if (!cpu_mask) 350 + if (!cpu_mask || cpumask_empty(cpu_mask)) 363 351 cpu_mask = cpu_online_mask; 364 352 365 353 for_each_cpu(cpuid, cpu_mask) { 366 354 hartid = cpuid_to_hartid_map(cpuid); 367 - if (hmask && ((hbase + BITS_PER_LONG) <= hartid)) { 368 - result = __sbi_rfence_v02_call(fid, hmask, hbase, 369 - start, size, arg4, arg5); 370 - if (result) 371 - return result; 372 - hmask = 0; 373 - hbase = 0; 355 + if (hmask) { 356 + if (hartid + BITS_PER_LONG <= htop || 357 + hbase + BITS_PER_LONG <= hartid) { 358 + result = __sbi_rfence_v02_call(fid, hmask, 359 + hbase, start, size, arg4, arg5); 360 + if (result) 361 + return result; 362 + hmask = 0; 363 + } else if (hartid < hbase) { 364 + /* shift the mask to fit lower hartid */ 365 + hmask <<= hbase - hartid; 366 + hbase = hartid; 367 + } 374 368 } 375 - if (!hmask) 369 + if (!hmask) { 376 370 hbase = hartid; 377 - hmask |= 1UL << (hartid - hbase); 371 + htop = hartid; 372 + } else if (hartid > htop) { 373 + htop = hartid; 374 + } 375 + hmask |= BIT(hartid - hbase); 378 376 } 379 377 380 378 if (hmask) {