* [kvm-unit-tests PATCH 0/3] riscv: Improve on-cpu and IPI support
@ 2024-08-30 10:12 ` Andrew Jones
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-08-30 10:12 UTC (permalink / raw)
To: kvm-riscv
The first two patches improve general library support for cpumasks and
the on-cpus API. on-cpus can now take cpumasks for input. The last patch
improves support for sending IPIs on riscv using the SBI IPI extension
by supporting a nicer interface of cpuids and cpumasks.
Andrew Jones (3):
lib/cpumask: Fix and simplify a few functions
lib/on-cpus: Introduce on_cpumask and on_cpumask_async
riscv: Introduce SBI IPI convenience functions
lib/cpumask.h | 47 +++++++++++++++++----------------------------
lib/on-cpus.c | 35 +++++++++++++++++++++++++--------
lib/on-cpus.h | 3 +++
lib/riscv/asm/sbi.h | 3 +++
lib/riscv/sbi.c | 43 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 94 insertions(+), 37 deletions(-)
--
2.45.2
^ permalink raw reply [flat|nested] 12+ messages in thread
* [kvm-unit-tests PATCH 0/3] riscv: Improve on-cpu and IPI support
@ 2024-08-30 10:12 ` Andrew Jones
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-08-30 10:12 UTC (permalink / raw)
To: kvm, kvm-riscv; +Cc: atishp, cade.richard, jamestiotio
The first two patches improve general library support for cpumasks and
the on-cpus API. on-cpus can now take cpumasks for input. The last patch
improves support for sending IPIs on riscv using the SBI IPI extension
by supporting a nicer interface of cpuids and cpumasks.
Andrew Jones (3):
lib/cpumask: Fix and simplify a few functions
lib/on-cpus: Introduce on_cpumask and on_cpumask_async
riscv: Introduce SBI IPI convenience functions
lib/cpumask.h | 47 +++++++++++++++++----------------------------
lib/on-cpus.c | 35 +++++++++++++++++++++++++--------
lib/on-cpus.h | 3 +++
lib/riscv/asm/sbi.h | 3 +++
lib/riscv/sbi.c | 43 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 94 insertions(+), 37 deletions(-)
--
2.45.2
^ permalink raw reply [flat|nested] 12+ messages in thread
* [kvm-unit-tests PATCH 1/3] lib/cpumask: Fix and simplify a few functions
2024-08-30 10:12 ` Andrew Jones
@ 2024-08-30 10:12 ` Andrew Jones
-1 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-08-30 10:12 UTC (permalink / raw)
To: kvm-riscv
Simplify cpumask_setall and cpumask_clear by just using memset. Also
simplify cpumask_empty and cpumask_full. This is a fix for
cpumask_empty as it would have reported non-empty for cpumasks that
had uninitialized junk following nr_cpus when nr_cpus < NR_CPUS.
There aren't currently any users of cpumask_empty though so that bug
has never appeared. cpumask_full was just convoluted and can now
follow cpumask_empty's new pattern. I've already yelled at a mirror
to scold the author of the original implementations!
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/cpumask.h | 47 ++++++++++++++++++-----------------------------
1 file changed, 18 insertions(+), 29 deletions(-)
diff --git a/lib/cpumask.h b/lib/cpumask.h
index be1919234d8e..e1e92aacd1f1 100644
--- a/lib/cpumask.h
+++ b/lib/cpumask.h
@@ -6,8 +6,9 @@
*/
#ifndef _CPUMASK_H_
#define _CPUMASK_H_
-#include <asm/setup.h>
#include <bitops.h>
+#include <limits.h>
+#include <asm/setup.h>
#define CPUMASK_NR_LONGS ((NR_CPUS + BITS_PER_LONG - 1) / BITS_PER_LONG)
@@ -49,46 +50,34 @@ static inline int cpumask_test_and_clear_cpu(int cpu, cpumask_t *mask)
static inline void cpumask_setall(cpumask_t *mask)
{
- int i;
- for (i = 0; i < nr_cpus; i += BITS_PER_LONG)
- cpumask_bits(mask)[BIT_WORD(i)] = ~0UL;
- i -= BITS_PER_LONG;
- if ((nr_cpus - i) < BITS_PER_LONG)
- cpumask_bits(mask)[BIT_WORD(i)] = BIT_MASK(nr_cpus - i) - 1;
+ memset(mask, 0xff, sizeof(*mask));
}
static inline void cpumask_clear(cpumask_t *mask)
{
- int i;
- for (i = 0; i < nr_cpus; i += BITS_PER_LONG)
- cpumask_bits(mask)[BIT_WORD(i)] = 0UL;
+ memset(mask, 0, sizeof(*mask));
}
static inline bool cpumask_empty(const cpumask_t *mask)
{
- int i;
- for (i = 0; i < nr_cpus; i += BITS_PER_LONG) {
- if (i < NR_CPUS) { /* silence crazy compiler warning */
- if (cpumask_bits(mask)[BIT_WORD(i)] != 0UL)
- return false;
- }
- }
- return true;
+ unsigned long lastmask = BIT_MASK(nr_cpus) - 1;
+
+ for (int i = 0; i < BIT_WORD(nr_cpus); ++i)
+ if (cpumask_bits(mask)[i])
+ return false;
+
+ return !lastmask || !(cpumask_bits(mask)[BIT_WORD(nr_cpus)] & lastmask);
}
static inline bool cpumask_full(const cpumask_t *mask)
{
- int i;
- for (i = 0; i < nr_cpus; i += BITS_PER_LONG) {
- if (cpumask_bits(mask)[BIT_WORD(i)] != ~0UL) {
- if ((nr_cpus - i) >= BITS_PER_LONG)
- return false;
- if (cpumask_bits(mask)[BIT_WORD(i)]
- != BIT_MASK(nr_cpus - i) - 1)
- return false;
- }
- }
- return true;
+ unsigned long lastmask = BIT_MASK(nr_cpus) - 1;
+
+ for (int i = 0; i < BIT_WORD(nr_cpus); ++i)
+ if (cpumask_bits(mask)[i] != ULONG_MAX)
+ return false;
+
+ return !lastmask || (cpumask_bits(mask)[BIT_WORD(nr_cpus)] & lastmask) == lastmask;
}
static inline int cpumask_weight(const cpumask_t *mask)
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [kvm-unit-tests PATCH 1/3] lib/cpumask: Fix and simplify a few functions
@ 2024-08-30 10:12 ` Andrew Jones
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-08-30 10:12 UTC (permalink / raw)
To: kvm, kvm-riscv; +Cc: atishp, cade.richard, jamestiotio
Simplify cpumask_setall and cpumask_clear by just using memset. Also
simplify cpumask_empty and cpumask_full. This is a fix for
cpumask_empty as it would have reported non-empty for cpumasks that
had uninitialized junk following nr_cpus when nr_cpus < NR_CPUS.
There aren't currently any users of cpumask_empty though so that bug
has never appeared. cpumask_full was just convoluted and can now
follow cpumask_empty's new pattern. I've already yelled at a mirror
to scold the author of the original implementations!
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/cpumask.h | 47 ++++++++++++++++++-----------------------------
1 file changed, 18 insertions(+), 29 deletions(-)
diff --git a/lib/cpumask.h b/lib/cpumask.h
index be1919234d8e..e1e92aacd1f1 100644
--- a/lib/cpumask.h
+++ b/lib/cpumask.h
@@ -6,8 +6,9 @@
*/
#ifndef _CPUMASK_H_
#define _CPUMASK_H_
-#include <asm/setup.h>
#include <bitops.h>
+#include <limits.h>
+#include <asm/setup.h>
#define CPUMASK_NR_LONGS ((NR_CPUS + BITS_PER_LONG - 1) / BITS_PER_LONG)
@@ -49,46 +50,34 @@ static inline int cpumask_test_and_clear_cpu(int cpu, cpumask_t *mask)
static inline void cpumask_setall(cpumask_t *mask)
{
- int i;
- for (i = 0; i < nr_cpus; i += BITS_PER_LONG)
- cpumask_bits(mask)[BIT_WORD(i)] = ~0UL;
- i -= BITS_PER_LONG;
- if ((nr_cpus - i) < BITS_PER_LONG)
- cpumask_bits(mask)[BIT_WORD(i)] = BIT_MASK(nr_cpus - i) - 1;
+ memset(mask, 0xff, sizeof(*mask));
}
static inline void cpumask_clear(cpumask_t *mask)
{
- int i;
- for (i = 0; i < nr_cpus; i += BITS_PER_LONG)
- cpumask_bits(mask)[BIT_WORD(i)] = 0UL;
+ memset(mask, 0, sizeof(*mask));
}
static inline bool cpumask_empty(const cpumask_t *mask)
{
- int i;
- for (i = 0; i < nr_cpus; i += BITS_PER_LONG) {
- if (i < NR_CPUS) { /* silence crazy compiler warning */
- if (cpumask_bits(mask)[BIT_WORD(i)] != 0UL)
- return false;
- }
- }
- return true;
+ unsigned long lastmask = BIT_MASK(nr_cpus) - 1;
+
+ for (int i = 0; i < BIT_WORD(nr_cpus); ++i)
+ if (cpumask_bits(mask)[i])
+ return false;
+
+ return !lastmask || !(cpumask_bits(mask)[BIT_WORD(nr_cpus)] & lastmask);
}
static inline bool cpumask_full(const cpumask_t *mask)
{
- int i;
- for (i = 0; i < nr_cpus; i += BITS_PER_LONG) {
- if (cpumask_bits(mask)[BIT_WORD(i)] != ~0UL) {
- if ((nr_cpus - i) >= BITS_PER_LONG)
- return false;
- if (cpumask_bits(mask)[BIT_WORD(i)]
- != BIT_MASK(nr_cpus - i) - 1)
- return false;
- }
- }
- return true;
+ unsigned long lastmask = BIT_MASK(nr_cpus) - 1;
+
+ for (int i = 0; i < BIT_WORD(nr_cpus); ++i)
+ if (cpumask_bits(mask)[i] != ULONG_MAX)
+ return false;
+
+ return !lastmask || (cpumask_bits(mask)[BIT_WORD(nr_cpus)] & lastmask) == lastmask;
}
static inline int cpumask_weight(const cpumask_t *mask)
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [kvm-unit-tests PATCH 2/3] lib/on-cpus: Introduce on_cpumask and on_cpumask_async
2024-08-30 10:12 ` Andrew Jones
@ 2024-08-30 10:12 ` Andrew Jones
-1 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-08-30 10:12 UTC (permalink / raw)
To: kvm-riscv
Provide functions to launch tasks on a selection of cpus identified
by a cpumask.
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/on-cpus.c | 35 +++++++++++++++++++++++++++--------
lib/on-cpus.h | 3 +++
2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/lib/on-cpus.c b/lib/on-cpus.c
index aed70f7b27b2..892149338419 100644
--- a/lib/on-cpus.c
+++ b/lib/on-cpus.c
@@ -124,24 +124,32 @@ void on_cpu_async(int cpu, void (*func)(void *data), void *data)
smp_send_event();
}
-void on_cpu(int cpu, void (*func)(void *data), void *data)
+void on_cpumask_async(const cpumask_t *mask, void (*func)(void *data), void *data)
{
- on_cpu_async(cpu, func, data);
- cpu_wait(cpu);
+ int cpu, me = smp_processor_id();
+
+ for_each_cpu(cpu, mask) {
+ if (cpu == me)
+ continue;
+ on_cpu_async(cpu, func, data);
+ }
+ if (cpumask_test_cpu(me, mask))
+ func(data);
}
-void on_cpus(void (*func)(void *data), void *data)
+void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data)
{
int cpu, me = smp_processor_id();
- for_each_present_cpu(cpu) {
+ for_each_cpu(cpu, mask) {
if (cpu == me)
continue;
on_cpu_async(cpu, func, data);
}
- func(data);
+ if (cpumask_test_cpu(me, mask))
+ func(data);
- for_each_present_cpu(cpu) {
+ for_each_cpu(cpu, mask) {
if (cpu == me)
continue;
cpumask_set_cpu(me, &on_cpu_info[cpu].waiters);
@@ -149,6 +157,17 @@ void on_cpus(void (*func)(void *data), void *data)
}
while (cpumask_weight(&cpu_idle_mask) < nr_cpus - 1)
smp_wait_for_event();
- for_each_present_cpu(cpu)
+ for_each_cpu(cpu, mask)
cpumask_clear_cpu(me, &on_cpu_info[cpu].waiters);
}
+
+void on_cpu(int cpu, void (*func)(void *data), void *data)
+{
+ on_cpu_async(cpu, func, data);
+ cpu_wait(cpu);
+}
+
+void on_cpus(void (*func)(void *data), void *data)
+{
+ on_cpumask(&cpu_present_mask, func, data);
+}
diff --git a/lib/on-cpus.h b/lib/on-cpus.h
index 41103b0245c7..4bc6236d6b58 100644
--- a/lib/on-cpus.h
+++ b/lib/on-cpus.h
@@ -2,6 +2,7 @@
#ifndef _ON_CPUS_H_
#define _ON_CPUS_H_
#include <stdbool.h>
+#include <cpumask.h>
extern bool cpu0_calls_idle;
@@ -10,5 +11,7 @@ void do_idle(void);
void on_cpu_async(int cpu, void (*func)(void *data), void *data);
void on_cpu(int cpu, void (*func)(void *data), void *data);
void on_cpus(void (*func)(void *data), void *data);
+void on_cpumask_async(const cpumask_t *mask, void (*func)(void *data), void *data);
+void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data);
#endif /* _ON_CPUS_H_ */
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [kvm-unit-tests PATCH 2/3] lib/on-cpus: Introduce on_cpumask and on_cpumask_async
@ 2024-08-30 10:12 ` Andrew Jones
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-08-30 10:12 UTC (permalink / raw)
To: kvm, kvm-riscv; +Cc: atishp, cade.richard, jamestiotio
Provide functions to launch tasks on a selection of cpus identified
by a cpumask.
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/on-cpus.c | 35 +++++++++++++++++++++++++++--------
lib/on-cpus.h | 3 +++
2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/lib/on-cpus.c b/lib/on-cpus.c
index aed70f7b27b2..892149338419 100644
--- a/lib/on-cpus.c
+++ b/lib/on-cpus.c
@@ -124,24 +124,32 @@ void on_cpu_async(int cpu, void (*func)(void *data), void *data)
smp_send_event();
}
-void on_cpu(int cpu, void (*func)(void *data), void *data)
+void on_cpumask_async(const cpumask_t *mask, void (*func)(void *data), void *data)
{
- on_cpu_async(cpu, func, data);
- cpu_wait(cpu);
+ int cpu, me = smp_processor_id();
+
+ for_each_cpu(cpu, mask) {
+ if (cpu == me)
+ continue;
+ on_cpu_async(cpu, func, data);
+ }
+ if (cpumask_test_cpu(me, mask))
+ func(data);
}
-void on_cpus(void (*func)(void *data), void *data)
+void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data)
{
int cpu, me = smp_processor_id();
- for_each_present_cpu(cpu) {
+ for_each_cpu(cpu, mask) {
if (cpu == me)
continue;
on_cpu_async(cpu, func, data);
}
- func(data);
+ if (cpumask_test_cpu(me, mask))
+ func(data);
- for_each_present_cpu(cpu) {
+ for_each_cpu(cpu, mask) {
if (cpu == me)
continue;
cpumask_set_cpu(me, &on_cpu_info[cpu].waiters);
@@ -149,6 +157,17 @@ void on_cpus(void (*func)(void *data), void *data)
}
while (cpumask_weight(&cpu_idle_mask) < nr_cpus - 1)
smp_wait_for_event();
- for_each_present_cpu(cpu)
+ for_each_cpu(cpu, mask)
cpumask_clear_cpu(me, &on_cpu_info[cpu].waiters);
}
+
+void on_cpu(int cpu, void (*func)(void *data), void *data)
+{
+ on_cpu_async(cpu, func, data);
+ cpu_wait(cpu);
+}
+
+void on_cpus(void (*func)(void *data), void *data)
+{
+ on_cpumask(&cpu_present_mask, func, data);
+}
diff --git a/lib/on-cpus.h b/lib/on-cpus.h
index 41103b0245c7..4bc6236d6b58 100644
--- a/lib/on-cpus.h
+++ b/lib/on-cpus.h
@@ -2,6 +2,7 @@
#ifndef _ON_CPUS_H_
#define _ON_CPUS_H_
#include <stdbool.h>
+#include <cpumask.h>
extern bool cpu0_calls_idle;
@@ -10,5 +11,7 @@ void do_idle(void);
void on_cpu_async(int cpu, void (*func)(void *data), void *data);
void on_cpu(int cpu, void (*func)(void *data), void *data);
void on_cpus(void (*func)(void *data), void *data);
+void on_cpumask_async(const cpumask_t *mask, void (*func)(void *data), void *data);
+void on_cpumask(const cpumask_t *mask, void (*func)(void *data), void *data);
#endif /* _ON_CPUS_H_ */
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [kvm-unit-tests PATCH 3/3] riscv: Introduce SBI IPI convenience functions
2024-08-30 10:12 ` Andrew Jones
@ 2024-08-30 10:12 ` Andrew Jones
-1 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-08-30 10:12 UTC (permalink / raw)
To: kvm-riscv
The SBI IPI function interface is a bit painful to use since it
operates on hartids as opposed to cpuids and requires determining a
mask base and a mask. Provide functions allowing IPIs to be sent to
single cpus and to all cpus set in a cpumask in order to simplify
things for unit tests.
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/riscv/asm/sbi.h | 3 +++
lib/riscv/sbi.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/lib/riscv/asm/sbi.h b/lib/riscv/asm/sbi.h
index 4a35cf38da70..e032444dd760 100644
--- a/lib/riscv/asm/sbi.h
+++ b/lib/riscv/asm/sbi.h
@@ -13,6 +13,7 @@
#define SBI_ERR_ALREADY_STOPPED -8
#ifndef __ASSEMBLY__
+#include <cpumask.h>
enum sbi_ext_id {
SBI_EXT_BASE = 0x10,
@@ -67,6 +68,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
void sbi_shutdown(void);
struct sbiret sbi_hart_start(unsigned long hartid, unsigned long entry, unsigned long sp);
struct sbiret sbi_send_ipi(unsigned long hart_mask, unsigned long hart_mask_base);
+struct sbiret sbi_send_ipi_cpu(int cpu);
+struct sbiret sbi_send_ipi_cpumask(const cpumask_t *mask);
struct sbiret sbi_set_timer(unsigned long stime_value);
long sbi_probe(int ext);
diff --git a/lib/riscv/sbi.c b/lib/riscv/sbi.c
index 07660e422cbb..ecc63acdebb7 100644
--- a/lib/riscv/sbi.c
+++ b/lib/riscv/sbi.c
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <libcflat.h>
+#include <cpumask.h>
+#include <limits.h>
#include <asm/sbi.h>
+#include <asm/setup.h>
struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
unsigned long arg1, unsigned long arg2,
@@ -44,6 +47,46 @@ struct sbiret sbi_send_ipi(unsigned long hart_mask, unsigned long hart_mask_base
return sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, hart_mask, hart_mask_base, 0, 0, 0, 0);
}
+struct sbiret sbi_send_ipi_cpu(int cpu)
+{
+ return sbi_send_ipi(1UL, cpus[cpu].hartid);
+}
+
+struct sbiret sbi_send_ipi_cpumask(const cpumask_t *mask)
+{
+ struct sbiret ret;
+ cpumask_t tmp;
+
+ if (cpumask_full(mask))
+ return sbi_send_ipi(0, -1UL);
+
+ cpumask_copy(&tmp, mask);
+
+ while (!cpumask_empty(&tmp)) {
+ unsigned long base = ULONG_MAX;
+ unsigned long mask = 0;
+ int cpu;
+
+ for_each_cpu(cpu, &tmp) {
+ if (base > cpus[cpu].hartid)
+ base = cpus[cpu].hartid;
+ }
+
+ for_each_cpu(cpu, &tmp) {
+ if (cpus[cpu].hartid < base + BITS_PER_LONG) {
+ mask |= 1UL << (cpus[cpu].hartid - base);
+ cpumask_clear_cpu(cpu, &tmp);
+ }
+ }
+
+ ret = sbi_send_ipi(mask, base);
+ if (ret.error)
+ break;
+ }
+
+ return ret;
+}
+
struct sbiret sbi_set_timer(unsigned long stime_value)
{
return sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, 0, 0, 0, 0, 0);
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [kvm-unit-tests PATCH 3/3] riscv: Introduce SBI IPI convenience functions
@ 2024-08-30 10:12 ` Andrew Jones
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-08-30 10:12 UTC (permalink / raw)
To: kvm, kvm-riscv; +Cc: atishp, cade.richard, jamestiotio
The SBI IPI function interface is a bit painful to use since it
operates on hartids as opposed to cpuids and requires determining a
mask base and a mask. Provide functions allowing IPIs to be sent to
single cpus and to all cpus set in a cpumask in order to simplify
things for unit tests.
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/riscv/asm/sbi.h | 3 +++
lib/riscv/sbi.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/lib/riscv/asm/sbi.h b/lib/riscv/asm/sbi.h
index 4a35cf38da70..e032444dd760 100644
--- a/lib/riscv/asm/sbi.h
+++ b/lib/riscv/asm/sbi.h
@@ -13,6 +13,7 @@
#define SBI_ERR_ALREADY_STOPPED -8
#ifndef __ASSEMBLY__
+#include <cpumask.h>
enum sbi_ext_id {
SBI_EXT_BASE = 0x10,
@@ -67,6 +68,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
void sbi_shutdown(void);
struct sbiret sbi_hart_start(unsigned long hartid, unsigned long entry, unsigned long sp);
struct sbiret sbi_send_ipi(unsigned long hart_mask, unsigned long hart_mask_base);
+struct sbiret sbi_send_ipi_cpu(int cpu);
+struct sbiret sbi_send_ipi_cpumask(const cpumask_t *mask);
struct sbiret sbi_set_timer(unsigned long stime_value);
long sbi_probe(int ext);
diff --git a/lib/riscv/sbi.c b/lib/riscv/sbi.c
index 07660e422cbb..ecc63acdebb7 100644
--- a/lib/riscv/sbi.c
+++ b/lib/riscv/sbi.c
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <libcflat.h>
+#include <cpumask.h>
+#include <limits.h>
#include <asm/sbi.h>
+#include <asm/setup.h>
struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
unsigned long arg1, unsigned long arg2,
@@ -44,6 +47,46 @@ struct sbiret sbi_send_ipi(unsigned long hart_mask, unsigned long hart_mask_base
return sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, hart_mask, hart_mask_base, 0, 0, 0, 0);
}
+struct sbiret sbi_send_ipi_cpu(int cpu)
+{
+ return sbi_send_ipi(1UL, cpus[cpu].hartid);
+}
+
+struct sbiret sbi_send_ipi_cpumask(const cpumask_t *mask)
+{
+ struct sbiret ret;
+ cpumask_t tmp;
+
+ if (cpumask_full(mask))
+ return sbi_send_ipi(0, -1UL);
+
+ cpumask_copy(&tmp, mask);
+
+ while (!cpumask_empty(&tmp)) {
+ unsigned long base = ULONG_MAX;
+ unsigned long mask = 0;
+ int cpu;
+
+ for_each_cpu(cpu, &tmp) {
+ if (base > cpus[cpu].hartid)
+ base = cpus[cpu].hartid;
+ }
+
+ for_each_cpu(cpu, &tmp) {
+ if (cpus[cpu].hartid < base + BITS_PER_LONG) {
+ mask |= 1UL << (cpus[cpu].hartid - base);
+ cpumask_clear_cpu(cpu, &tmp);
+ }
+ }
+
+ ret = sbi_send_ipi(mask, base);
+ if (ret.error)
+ break;
+ }
+
+ return ret;
+}
+
struct sbiret sbi_set_timer(unsigned long stime_value)
{
return sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, 0, 0, 0, 0, 0);
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [kvm-unit-tests PATCH 4/3] riscv: Provide helpers for IPIs
2024-08-30 10:12 ` Andrew Jones
@ 2024-08-30 11:01 ` Andrew Jones
-1 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-08-30 11:01 UTC (permalink / raw)
To: kvm-riscv
Provide a few functions to enable/disable/acknowledge IPIs.
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/riscv/asm/csr.h | 3 ++-
lib/riscv/asm/processor.h | 15 +++++++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/lib/riscv/asm/csr.h b/lib/riscv/asm/csr.h
index 24b333e02589..16f5ddd762de 100644
--- a/lib/riscv/asm/csr.h
+++ b/lib/riscv/asm/csr.h
@@ -51,7 +51,8 @@
#define IRQ_S_GEXT 12
#define IRQ_PMU_OVF 13
-#define IE_TIE (_AC(0x1, UL) << IRQ_S_TIMER)
+#define IE_SSIE (_AC(1, UL) << IRQ_S_SOFT)
+#define IE_TIE (_AC(1, UL) << IRQ_S_TIMER)
#define IP_TIP IE_TIE
diff --git a/lib/riscv/asm/processor.h b/lib/riscv/asm/processor.h
index 4c9ad968460d..8989d8d686f9 100644
--- a/lib/riscv/asm/processor.h
+++ b/lib/riscv/asm/processor.h
@@ -32,6 +32,21 @@ static inline void local_irq_disable(void)
csr_clear(CSR_SSTATUS, SR_SIE);
}
+static inline void local_ipi_enable(void)
+{
+ csr_set(CSR_SIE, IE_SSIE);
+}
+
+static inline void local_ipi_disable(void)
+{
+ csr_clear(CSR_SIE, IE_SSIE);
+}
+
+static inline void ipi_ack(void)
+{
+ csr_clear(CSR_SIP, IE_SSIE);
+}
+
void install_exception_handler(unsigned long cause, void (*handler)(struct pt_regs *));
void install_irq_handler(unsigned long cause, void (*handler)(struct pt_regs *));
void do_handle_exception(struct pt_regs *regs);
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [kvm-unit-tests PATCH 4/3] riscv: Provide helpers for IPIs
@ 2024-08-30 11:01 ` Andrew Jones
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-08-30 11:01 UTC (permalink / raw)
To: kvm, kvm-riscv; +Cc: atishp, cade.richard, jamestiotio
Provide a few functions to enable/disable/acknowledge IPIs.
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
lib/riscv/asm/csr.h | 3 ++-
lib/riscv/asm/processor.h | 15 +++++++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/lib/riscv/asm/csr.h b/lib/riscv/asm/csr.h
index 24b333e02589..16f5ddd762de 100644
--- a/lib/riscv/asm/csr.h
+++ b/lib/riscv/asm/csr.h
@@ -51,7 +51,8 @@
#define IRQ_S_GEXT 12
#define IRQ_PMU_OVF 13
-#define IE_TIE (_AC(0x1, UL) << IRQ_S_TIMER)
+#define IE_SSIE (_AC(1, UL) << IRQ_S_SOFT)
+#define IE_TIE (_AC(1, UL) << IRQ_S_TIMER)
#define IP_TIP IE_TIE
diff --git a/lib/riscv/asm/processor.h b/lib/riscv/asm/processor.h
index 4c9ad968460d..8989d8d686f9 100644
--- a/lib/riscv/asm/processor.h
+++ b/lib/riscv/asm/processor.h
@@ -32,6 +32,21 @@ static inline void local_irq_disable(void)
csr_clear(CSR_SSTATUS, SR_SIE);
}
+static inline void local_ipi_enable(void)
+{
+ csr_set(CSR_SIE, IE_SSIE);
+}
+
+static inline void local_ipi_disable(void)
+{
+ csr_clear(CSR_SIE, IE_SSIE);
+}
+
+static inline void ipi_ack(void)
+{
+ csr_clear(CSR_SIP, IE_SSIE);
+}
+
void install_exception_handler(unsigned long cause, void (*handler)(struct pt_regs *));
void install_irq_handler(unsigned long cause, void (*handler)(struct pt_regs *));
void do_handle_exception(struct pt_regs *regs);
--
2.45.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [kvm-unit-tests PATCH 0/3] riscv: Improve on-cpu and IPI support
2024-08-30 10:12 ` Andrew Jones
@ 2024-09-03 13:41 ` Andrew Jones
-1 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-09-03 13:41 UTC (permalink / raw)
To: kvm-riscv
On Fri, Aug 30, 2024 at 12:12:22PM GMT, Andrew Jones wrote:
> The first two patches improve general library support for cpumasks and
> the on-cpus API. on-cpus can now take cpumasks for input. The last patch
> improves support for sending IPIs on riscv using the SBI IPI extension
> by supporting a nicer interface of cpuids and cpumasks.
>
> Andrew Jones (3):
> lib/cpumask: Fix and simplify a few functions
> lib/on-cpus: Introduce on_cpumask and on_cpumask_async
> riscv: Introduce SBI IPI convenience functions
>
> lib/cpumask.h | 47 +++++++++++++++++----------------------------
> lib/on-cpus.c | 35 +++++++++++++++++++++++++--------
> lib/on-cpus.h | 3 +++
> lib/riscv/asm/sbi.h | 3 +++
> lib/riscv/sbi.c | 43 +++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 94 insertions(+), 37 deletions(-)
>
> --
> 2.45.2
Queued on riscv/sbi, https://gitlab.com/jones-drew/kvm-unit-tests/-/commits/riscv%2Fsbi
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [kvm-unit-tests PATCH 0/3] riscv: Improve on-cpu and IPI support
@ 2024-09-03 13:41 ` Andrew Jones
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Jones @ 2024-09-03 13:41 UTC (permalink / raw)
To: kvm, kvm-riscv; +Cc: atishp, cade.richard, jamestiotio
On Fri, Aug 30, 2024 at 12:12:22PM GMT, Andrew Jones wrote:
> The first two patches improve general library support for cpumasks and
> the on-cpus API. on-cpus can now take cpumasks for input. The last patch
> improves support for sending IPIs on riscv using the SBI IPI extension
> by supporting a nicer interface of cpuids and cpumasks.
>
> Andrew Jones (3):
> lib/cpumask: Fix and simplify a few functions
> lib/on-cpus: Introduce on_cpumask and on_cpumask_async
> riscv: Introduce SBI IPI convenience functions
>
> lib/cpumask.h | 47 +++++++++++++++++----------------------------
> lib/on-cpus.c | 35 +++++++++++++++++++++++++--------
> lib/on-cpus.h | 3 +++
> lib/riscv/asm/sbi.h | 3 +++
> lib/riscv/sbi.c | 43 +++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 94 insertions(+), 37 deletions(-)
>
> --
> 2.45.2
Queued on riscv/sbi, https://gitlab.com/jones-drew/kvm-unit-tests/-/commits/riscv%2Fsbi
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2024-09-03 13:41 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-30 10:12 [kvm-unit-tests PATCH 0/3] riscv: Improve on-cpu and IPI support Andrew Jones
2024-08-30 10:12 ` Andrew Jones
2024-08-30 10:12 ` [kvm-unit-tests PATCH 1/3] lib/cpumask: Fix and simplify a few functions Andrew Jones
2024-08-30 10:12 ` Andrew Jones
2024-08-30 10:12 ` [kvm-unit-tests PATCH 2/3] lib/on-cpus: Introduce on_cpumask and on_cpumask_async Andrew Jones
2024-08-30 10:12 ` Andrew Jones
2024-08-30 10:12 ` [kvm-unit-tests PATCH 3/3] riscv: Introduce SBI IPI convenience functions Andrew Jones
2024-08-30 10:12 ` Andrew Jones
2024-08-30 11:01 ` [kvm-unit-tests PATCH 4/3] riscv: Provide helpers for IPIs Andrew Jones
2024-08-30 11:01 ` Andrew Jones
2024-09-03 13:41 ` [kvm-unit-tests PATCH 0/3] riscv: Improve on-cpu and IPI support Andrew Jones
2024-09-03 13:41 ` Andrew Jones
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.