Since SMP is not yet supported, it is acceptable to implement
smp_send_event_check_mask() as a stub.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
xen/arch/riscv/smp.c | 8 ++++++++
xen/arch/riscv/stubs.c | 5 -----
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/xen/arch/riscv/smp.c b/xen/arch/riscv/smp.c
index 4ca6a4e89200..e727fdb09612 100644
--- a/xen/arch/riscv/smp.c
+++ b/xen/arch/riscv/smp.c
@@ -1,3 +1,4 @@
+#include <xen/cpumask.h>
#include <xen/smp.h>
/*
@@ -13,3 +14,10 @@
struct pcpu_info pcpu_info[NR_CPUS] = { [0 ... NR_CPUS - 1] = {
.processor_id = NR_CPUS,
}};
+
+void smp_send_event_check_mask(const cpumask_t *mask)
+{
+#if CONFIG_NR_CPUS > 1
+# error "smp_send_event_check_mask() unimplemented"
+#endif
+}
diff --git a/xen/arch/riscv/stubs.c b/xen/arch/riscv/stubs.c
index eab826e8c3ae..6ebb5139de69 100644
--- a/xen/arch/riscv/stubs.c
+++ b/xen/arch/riscv/stubs.c
@@ -65,11 +65,6 @@ int arch_monitor_domctl_event(struct domain *d,
/* smp.c */
-void smp_send_event_check_mask(const cpumask_t *mask)
-{
- BUG_ON("unimplemented");
-}
-
void smp_send_call_function_mask(const cpumask_t *mask)
{
BUG_ON("unimplemented");
--
2.52.0
On 24.12.2025 18:03, Oleksii Kurochko wrote:
> --- a/xen/arch/riscv/smp.c
> +++ b/xen/arch/riscv/smp.c
> @@ -1,3 +1,4 @@
> +#include <xen/cpumask.h>
> #include <xen/smp.h>
>
> /*
> @@ -13,3 +14,10 @@
> struct pcpu_info pcpu_info[NR_CPUS] = { [0 ... NR_CPUS - 1] = {
> .processor_id = NR_CPUS,
> }};
> +
> +void smp_send_event_check_mask(const cpumask_t *mask)
> +{
> +#if CONFIG_NR_CPUS > 1
> +# error "smp_send_event_check_mask() unimplemented"
> +#endif
> +}
CONFIG_NR_CPUS is 64 by default for 64-bit arch-es, from all I can tell, also
for RISC-V. And there's no "override" in riscv64_defconfig. How is the above
going to work in CI? Then again I must be overlooking something, as the config
used in CI has CONFIG_NR_CPUS=1. Just that I can't tell why that is.
And no, I'm not meaning to ask that you override NR_CPUS (and wherever such an
override would live, I think it would better be dropped rather sooner than
later). Instead an option may be this:
void smp_send_event_check_mask(const cpumask_t *mask)
{
#if CONFIG_NR_CPUS > 1
BUG_ON(!cpumask_subset(mask, cpumask_of(0)));
#endif
}
(I can't tell off the top of my head whether an empty mask may be passed to this
function. If not, cpumask_equal() could be used as well.)
Of course the #if may then not be necessary at all, and a TODO comment may want
putting there instead.
Jan
On 1/7/26 4:47 PM, Jan Beulich wrote:
> On 24.12.2025 18:03, Oleksii Kurochko wrote:
>> --- a/xen/arch/riscv/smp.c
>> +++ b/xen/arch/riscv/smp.c
>> @@ -1,3 +1,4 @@
>> +#include <xen/cpumask.h>
>> #include <xen/smp.h>
>>
>> /*
>> @@ -13,3 +14,10 @@
>> struct pcpu_info pcpu_info[NR_CPUS] = { [0 ... NR_CPUS - 1] = {
>> .processor_id = NR_CPUS,
>> }};
>> +
>> +void smp_send_event_check_mask(const cpumask_t *mask)
>> +{
>> +#if CONFIG_NR_CPUS > 1
>> +# error "smp_send_event_check_mask() unimplemented"
>> +#endif
>> +}
> CONFIG_NR_CPUS is 64 by default for 64-bit arch-es, from all I can tell, also
> for RISC-V. And there's no "override" in riscv64_defconfig. How is the above
> going to work in CI? Then again I must be overlooking something, as the config
> used in CI has CONFIG_NR_CPUS=1. Just that I can't tell why that is.
It is 1 because of the defintion of NR_CPUS in KConfig:
config NR_CPUS
int "Maximum number of CPUs"
range 1 1 if ARM && MPU
range 1 16383
.... ( all other range props are condtional and there is no RISC-V in dependency)
so for RISC-V "range 1 16383" used and CONFIG_NR_CPUS is set to the minimal of this range,
so it is 1.
>
> And no, I'm not meaning to ask that you override NR_CPUS (and wherever such an
> override would live, I think it would better be dropped rather sooner than
> later). Instead an option may be this:
>
> void smp_send_event_check_mask(const cpumask_t *mask)
> {
> #if CONFIG_NR_CPUS > 1
> BUG_ON(!cpumask_subset(mask, cpumask_of(0)));
> #endif
> }
>
> (I can't tell off the top of my head whether an empty mask may be passed to this
> function. If not, cpumask_equal() could be used as well.)
I will double-check. Thanks for such hint.
>
> Of course the #if may then not be necessary at all, and a TODO comment may want
> putting there instead.
With suggested above approach, I think it isn't really needed to use #if.
Thanks!
~ Oleksii
On 12.01.2026 17:53, Oleksii Kurochko wrote:
> On 1/7/26 4:47 PM, Jan Beulich wrote:
>> On 24.12.2025 18:03, Oleksii Kurochko wrote:
>>> @@ -13,3 +14,10 @@
>>> struct pcpu_info pcpu_info[NR_CPUS] = { [0 ... NR_CPUS - 1] = {
>>> .processor_id = NR_CPUS,
>>> }};
>>> +
>>> +void smp_send_event_check_mask(const cpumask_t *mask)
>>> +{
>>> +#if CONFIG_NR_CPUS > 1
>>> +# error "smp_send_event_check_mask() unimplemented"
>>> +#endif
>>> +}
>> CONFIG_NR_CPUS is 64 by default for 64-bit arch-es, from all I can tell, also
>> for RISC-V. And there's no "override" in riscv64_defconfig. How is the above
>> going to work in CI? Then again I must be overlooking something, as the config
>> used in CI has CONFIG_NR_CPUS=1. Just that I can't tell why that is.
>
> It is 1 because of the defintion of NR_CPUS in KConfig:
> config NR_CPUS
> int "Maximum number of CPUs"
> range 1 1 if ARM && MPU
> range 1 16383
> .... ( all other range props are condtional and there is no RISC-V in dependency)
> so for RISC-V "range 1 16383" used and CONFIG_NR_CPUS is set to the minimal of this range,
> so it is 1.
I fear I don't follow: Why would the lowest value be picked, rather than the
specified default (which would be 64 for RV64)? That's what I thought the
default values are there (among other purposes).
Jan
On 1/12/26 6:05 PM, Jan Beulich wrote:
> On 12.01.2026 17:53, Oleksii Kurochko wrote:
>> On 1/7/26 4:47 PM, Jan Beulich wrote:
>>> On 24.12.2025 18:03, Oleksii Kurochko wrote:
>>>> @@ -13,3 +14,10 @@
>>>> struct pcpu_info pcpu_info[NR_CPUS] = { [0 ... NR_CPUS - 1] = {
>>>> .processor_id = NR_CPUS,
>>>> }};
>>>> +
>>>> +void smp_send_event_check_mask(const cpumask_t *mask)
>>>> +{
>>>> +#if CONFIG_NR_CPUS > 1
>>>> +# error "smp_send_event_check_mask() unimplemented"
>>>> +#endif
>>>> +}
>>> CONFIG_NR_CPUS is 64 by default for 64-bit arch-es, from all I can tell, also
>>> for RISC-V. And there's no "override" in riscv64_defconfig. How is the above
>>> going to work in CI? Then again I must be overlooking something, as the config
>>> used in CI has CONFIG_NR_CPUS=1. Just that I can't tell why that is.
>> It is 1 because of the defintion of NR_CPUS in KConfig:
>> config NR_CPUS
>> int "Maximum number of CPUs"
>> range 1 1 if ARM && MPU
>> range 1 16383
>> .... ( all other range props are condtional and there is no RISC-V in dependency)
>> so for RISC-V "range 1 16383" used and CONFIG_NR_CPUS is set to the minimal of this range,
>> so it is 1.
> I fear I don't follow: Why would the lowest value be picked, rather than the
> specified default (which would be 64 for RV64)? That's what I thought the
> default values are there (among other purposes).
But there is no default for RISC-V for config NR_CPUS:
config NR_CPUS
int "Maximum number of CPUs"
range 1 1 if ARM && MPU
range 1 16383
default "256" if X86
default "1" if ARM && MPU
default "8" if ARM && RCAR3
default "4" if ARM && QEMU
default "4" if ARM && MPSOC
default "128" if ARM
help
...
So a value from range [1, 16383] is chosen and based on the code of sym_validate_range():
...
val = strtoll(sym->curr.val, NULL, base);
val2 = sym_get_range_val(prop->expr->left.sym, base);
if (val >= val2) {
val2 = sym_get_range_val(prop->expr->right.sym, base);
if (val <= val2)
return;
}
if (sym->type == S_INT)
sprintf(str, "%lld", val2);
else
sprintf(str, "0x%llx", val2);
sym->curr.val = xstrdup(str);
First initialization of val2 it is the left value of the range [1, 16383],so it is 1
and val is 0 (I assume so that it is by initialization 0), thereby val2 = 1 will be
used as a value for NR_CPUS.
I also experimented by trying to update it to the range|2 16383|, and|CONFIG_NR_CPUS|
became 2.
~ Oleksii
On 13.01.2026 10:58, Oleksii Kurochko wrote:
>
> On 1/12/26 6:05 PM, Jan Beulich wrote:
>> On 12.01.2026 17:53, Oleksii Kurochko wrote:
>>> On 1/7/26 4:47 PM, Jan Beulich wrote:
>>>> On 24.12.2025 18:03, Oleksii Kurochko wrote:
>>>>> @@ -13,3 +14,10 @@
>>>>> struct pcpu_info pcpu_info[NR_CPUS] = { [0 ... NR_CPUS - 1] = {
>>>>> .processor_id = NR_CPUS,
>>>>> }};
>>>>> +
>>>>> +void smp_send_event_check_mask(const cpumask_t *mask)
>>>>> +{
>>>>> +#if CONFIG_NR_CPUS > 1
>>>>> +# error "smp_send_event_check_mask() unimplemented"
>>>>> +#endif
>>>>> +}
>>>> CONFIG_NR_CPUS is 64 by default for 64-bit arch-es, from all I can tell, also
>>>> for RISC-V. And there's no "override" in riscv64_defconfig. How is the above
>>>> going to work in CI? Then again I must be overlooking something, as the config
>>>> used in CI has CONFIG_NR_CPUS=1. Just that I can't tell why that is.
>>> It is 1 because of the defintion of NR_CPUS in KConfig:
>>> config NR_CPUS
>>> int "Maximum number of CPUs"
>>> range 1 1 if ARM && MPU
>>> range 1 16383
>>> .... ( all other range props are condtional and there is no RISC-V in dependency)
>>> so for RISC-V "range 1 16383" used and CONFIG_NR_CPUS is set to the minimal of this range,
>>> so it is 1.
>> I fear I don't follow: Why would the lowest value be picked, rather than the
>> specified default (which would be 64 for RV64)? That's what I thought the
>> default values are there (among other purposes).
>
> But there is no default for RISC-V for config NR_CPUS:
>
> config NR_CPUS
> int "Maximum number of CPUs"
> range 1 1 if ARM && MPU
> range 1 16383
> default "256" if X86
> default "1" if ARM && MPU
> default "8" if ARM && RCAR3
> default "4" if ARM && QEMU
> default "4" if ARM && MPSOC
> default "128" if ARM
> help
> ...
Oh, indeed, that's what I was overlooking.
> So a value from range [1, 16383] is chosen and based on the code of sym_validate_range():
> ...
> val = strtoll(sym->curr.val, NULL, base);
> val2 = sym_get_range_val(prop->expr->left.sym, base);
> if (val >= val2) {
> val2 = sym_get_range_val(prop->expr->right.sym, base);
> if (val <= val2)
> return;
> }
> if (sym->type == S_INT)
> sprintf(str, "%lld", val2);
> else
> sprintf(str, "0x%llx", val2);
> sym->curr.val = xstrdup(str);
>
> First initialization of val2 it is the left value of the range [1, 16383],so it is 1
> and val is 0 (I assume so that it is by initialization 0), thereby val2 = 1 will be
> used as a value for NR_CPUS.
But is this behavior documented anywhere? Wouldn't RISC-V (and PPC) better
gain suitable defaults, making explicit what is wanted (for the time being)?
E.g.
config NR_CPUS
int "Maximum number of CPUs"
range 1 1 if ARM && MPU
range 1 16383
default "256" if X86
default "1" if !ARM || MPU
default "8" if RCAR3
default "4" if QEMU
default "4" if MPSOC
default "128"
Jan
On 1/13/26 11:22 AM, Jan Beulich wrote:
> On 13.01.2026 10:58, Oleksii Kurochko wrote:
>> On 1/12/26 6:05 PM, Jan Beulich wrote:
>>> On 12.01.2026 17:53, Oleksii Kurochko wrote:
>>>> On 1/7/26 4:47 PM, Jan Beulich wrote:
>>>>> On 24.12.2025 18:03, Oleksii Kurochko wrote:
>>>>>> @@ -13,3 +14,10 @@
>>>>>> struct pcpu_info pcpu_info[NR_CPUS] = { [0 ... NR_CPUS - 1] = {
>>>>>> .processor_id = NR_CPUS,
>>>>>> }};
>>>>>> +
>>>>>> +void smp_send_event_check_mask(const cpumask_t *mask)
>>>>>> +{
>>>>>> +#if CONFIG_NR_CPUS > 1
>>>>>> +# error "smp_send_event_check_mask() unimplemented"
>>>>>> +#endif
>>>>>> +}
>>>>> CONFIG_NR_CPUS is 64 by default for 64-bit arch-es, from all I can tell, also
>>>>> for RISC-V. And there's no "override" in riscv64_defconfig. How is the above
>>>>> going to work in CI? Then again I must be overlooking something, as the config
>>>>> used in CI has CONFIG_NR_CPUS=1. Just that I can't tell why that is.
>>>> It is 1 because of the defintion of NR_CPUS in KConfig:
>>>> config NR_CPUS
>>>> int "Maximum number of CPUs"
>>>> range 1 1 if ARM && MPU
>>>> range 1 16383
>>>> .... ( all other range props are condtional and there is no RISC-V in dependency)
>>>> so for RISC-V "range 1 16383" used and CONFIG_NR_CPUS is set to the minimal of this range,
>>>> so it is 1.
>>> I fear I don't follow: Why would the lowest value be picked, rather than the
>>> specified default (which would be 64 for RV64)? That's what I thought the
>>> default values are there (among other purposes).
>> But there is no default for RISC-V for config NR_CPUS:
>>
>> config NR_CPUS
>> int "Maximum number of CPUs"
>> range 1 1 if ARM && MPU
>> range 1 16383
>> default "256" if X86
>> default "1" if ARM && MPU
>> default "8" if ARM && RCAR3
>> default "4" if ARM && QEMU
>> default "4" if ARM && MPSOC
>> default "128" if ARM
>> help
>> ...
> Oh, indeed, that's what I was overlooking.
>
>> So a value from range [1, 16383] is chosen and based on the code of sym_validate_range():
>> ...
>> val = strtoll(sym->curr.val, NULL, base);
>> val2 = sym_get_range_val(prop->expr->left.sym, base);
>> if (val >= val2) {
>> val2 = sym_get_range_val(prop->expr->right.sym, base);
>> if (val <= val2)
>> return;
>> }
>> if (sym->type == S_INT)
>> sprintf(str, "%lld", val2);
>> else
>> sprintf(str, "0x%llx", val2);
>> sym->curr.val = xstrdup(str);
>>
>> First initialization of val2 it is the left value of the range [1, 16383],so it is 1
>> and val is 0 (I assume so that it is by initialization 0), thereby val2 = 1 will be
>> used as a value for NR_CPUS.
> But is this behavior documented anywhere?
I wasn't able to find that and it was a reason why I checked the code.
> Wouldn't RISC-V (and PPC) better
> gain suitable defaults, making explicit what is wanted (for the time being)?
> E.g.
>
> config NR_CPUS
> int "Maximum number of CPUs"
> range 1 1 if ARM && MPU
> range 1 16383
> default "256" if X86
> default "1" if !ARM || MPU
> default "8" if RCAR3
> default "4" if QEMU
> default "4" if MPSOC
> default "128"
Maybe, it would be better.
~ Oleksii
© 2016 - 2026 Red Hat, Inc.