55 * Copyright (c) 2020 Western Digital Corporation or its affiliates.
66 */
77
8+ #include <linux/bits.h>
89#include <linux/init.h>
910#include <linux/pm.h>
1011#include <linux/reboot.h>
@@ -85,7 +86,7 @@ static unsigned long __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mas
8586 pr_warn ("Unable to send any request to hartid > BITS_PER_LONG for SBI v0.1\n" );
8687 break ;
8788 }
88- hmask |= 1 << hartid ;
89+ hmask |= BIT ( hartid ) ;
8990 }
9091
9192 return hmask ;
@@ -160,7 +161,7 @@ static int __sbi_send_ipi_v01(const struct cpumask *cpu_mask)
160161{
161162 unsigned long hart_mask ;
162163
163- if (!cpu_mask )
164+ if (!cpu_mask || cpumask_empty ( cpu_mask ) )
164165 cpu_mask = cpu_online_mask ;
165166 hart_mask = __sbi_v01_cpumask_to_hartmask (cpu_mask );
166167
@@ -176,7 +177,7 @@ static int __sbi_rfence_v01(int fid, const struct cpumask *cpu_mask,
176177 int result = 0 ;
177178 unsigned long hart_mask ;
178179
179- if (!cpu_mask )
180+ if (!cpu_mask || cpumask_empty ( cpu_mask ) )
180181 cpu_mask = cpu_online_mask ;
181182 hart_mask = __sbi_v01_cpumask_to_hartmask (cpu_mask );
182183
@@ -249,26 +250,37 @@ static void __sbi_set_timer_v02(uint64_t stime_value)
249250
250251static int __sbi_send_ipi_v02 (const struct cpumask * cpu_mask )
251252{
252- unsigned long hartid , cpuid , hmask = 0 , hbase = 0 ;
253+ unsigned long hartid , cpuid , hmask = 0 , hbase = 0 , htop = 0 ;
253254 struct sbiret ret = {0 };
254255 int result ;
255256
256- if (!cpu_mask )
257+ if (!cpu_mask || cpumask_empty ( cpu_mask ) )
257258 cpu_mask = cpu_online_mask ;
258259
259260 for_each_cpu (cpuid , cpu_mask ) {
260261 hartid = cpuid_to_hartid_map (cpuid );
261- if (hmask && ((hbase + BITS_PER_LONG ) <= hartid )) {
262- ret = sbi_ecall (SBI_EXT_IPI , SBI_EXT_IPI_SEND_IPI ,
263- hmask , hbase , 0 , 0 , 0 , 0 );
264- if (ret .error )
265- goto ecall_failed ;
266- hmask = 0 ;
267- hbase = 0 ;
262+ if (hmask ) {
263+ if (hartid + BITS_PER_LONG <= htop ||
264+ hbase + BITS_PER_LONG <= hartid ) {
265+ ret = sbi_ecall (SBI_EXT_IPI ,
266+ SBI_EXT_IPI_SEND_IPI , hmask ,
267+ hbase , 0 , 0 , 0 , 0 );
268+ if (ret .error )
269+ goto ecall_failed ;
270+ hmask = 0 ;
271+ } else if (hartid < hbase ) {
272+ /* shift the mask to fit lower hartid */
273+ hmask <<= hbase - hartid ;
274+ hbase = hartid ;
275+ }
268276 }
269- if (!hmask )
277+ if (!hmask ) {
270278 hbase = hartid ;
271- hmask |= 1UL << (hartid - hbase );
279+ htop = hartid ;
280+ } else if (hartid > htop ) {
281+ htop = hartid ;
282+ }
283+ hmask |= BIT (hartid - hbase );
272284 }
273285
274286 if (hmask ) {
@@ -344,25 +356,35 @@ static int __sbi_rfence_v02(int fid, const struct cpumask *cpu_mask,
344356 unsigned long start , unsigned long size ,
345357 unsigned long arg4 , unsigned long arg5 )
346358{
347- unsigned long hartid , cpuid , hmask = 0 , hbase = 0 ;
359+ unsigned long hartid , cpuid , hmask = 0 , hbase = 0 , htop = 0 ;
348360 int result ;
349361
350- if (!cpu_mask )
362+ if (!cpu_mask || cpumask_empty ( cpu_mask ) )
351363 cpu_mask = cpu_online_mask ;
352364
353365 for_each_cpu (cpuid , cpu_mask ) {
354366 hartid = cpuid_to_hartid_map (cpuid );
355- if (hmask && ((hbase + BITS_PER_LONG ) <= hartid )) {
356- result = __sbi_rfence_v02_call (fid , hmask , hbase ,
357- start , size , arg4 , arg5 );
358- if (result )
359- return result ;
360- hmask = 0 ;
361- hbase = 0 ;
367+ if (hmask ) {
368+ if (hartid + BITS_PER_LONG <= htop ||
369+ hbase + BITS_PER_LONG <= hartid ) {
370+ result = __sbi_rfence_v02_call (fid , hmask ,
371+ hbase , start , size , arg4 , arg5 );
372+ if (result )
373+ return result ;
374+ hmask = 0 ;
375+ } else if (hartid < hbase ) {
376+ /* shift the mask to fit lower hartid */
377+ hmask <<= hbase - hartid ;
378+ hbase = hartid ;
379+ }
362380 }
363- if (!hmask )
381+ if (!hmask ) {
364382 hbase = hartid ;
365- hmask |= 1UL << (hartid - hbase );
383+ htop = hartid ;
384+ } else if (hartid > htop ) {
385+ htop = hartid ;
386+ }
387+ hmask |= BIT (hartid - hbase );
366388 }
367389
368390 if (hmask ) {
0 commit comments