[PATCH v1 05/15] xen/riscv: implement stub for smp_send_event_check_mask()

Oleksii Kurochko posted 15 patches 1 month, 2 weeks ago
[PATCH v1 05/15] xen/riscv: implement stub for smp_send_event_check_mask()
Posted by Oleksii Kurochko 1 month, 2 weeks ago
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
Re: [PATCH v1 05/15] xen/riscv: implement stub for smp_send_event_check_mask()
Posted by Jan Beulich 1 month ago
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
Re: [PATCH v1 05/15] xen/riscv: implement stub for smp_send_event_check_mask()
Posted by Oleksii Kurochko 4 weeks ago
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
Re: [PATCH v1 05/15] xen/riscv: implement stub for smp_send_event_check_mask()
Posted by Jan Beulich 4 weeks ago
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
Re: [PATCH v1 05/15] xen/riscv: implement stub for smp_send_event_check_mask()
Posted by Oleksii Kurochko 3 weeks, 6 days ago
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
Re: [PATCH v1 05/15] xen/riscv: implement stub for smp_send_event_check_mask()
Posted by Jan Beulich 3 weeks, 6 days ago
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
Re: [PATCH v1 05/15] xen/riscv: implement stub for smp_send_event_check_mask()
Posted by Oleksii Kurochko 3 weeks, 6 days ago
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