On Thu, 14 Aug 2025, Teddy Astie wrote: > Hello, > > Le 13/08/2025 à 20:07, Dmytro Prokopchuk1 a écrit : > > Misra Rule 11.1 states: "Conversions shall not be performed between a > > pointer to a function and any other type." > > > > The violation occurs in the macro: > > __typeof__(**(ptr)) *const o_ = (o); \ > > __typeof__(**(ptr)) *n_ = (n); \ > > ((__typeof__(*(ptr)))__cmpxchg(ptr, (unsigned long)o_, \ > > (unsigned long)n_, sizeof(*(ptr)))); \ > > }) > > when it is used for handling function pointers of type: > > typedef void (*)(struct vcpu *, unsigned int). > > The issue happens because the '__cmpxchg()' function returns an 'unsigned > > long', which is then converted back into a function pointer, causing a > > violation of Rule 11.1. In this particular usage, the return value of the > > macro 'cmpxchgptr()' is not required. To address the violation, the macro > > has been replaced to discard the return value of '__cmpxchg()', preventing > > the conversion. > > > > Signed-off-by: Dmytro Prokopchuk <dmytro_prokopch...@epam.com> > > --- > > Probably separate macro is too much for this single case. > > > > And the following will be enought: > > __cmpxchg(&xen_consumers[i], (unsigned long)NULL, (unsigned long)fn, > > sizeof(*(&xen_consumers[i]))); > > --- > > xen/common/event_channel.c | 15 +++++++++++++-- > > 1 file changed, 13 insertions(+), 2 deletions(-) > > > > diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c > > index 67700b050a..2094338b28 100644 > > --- a/xen/common/event_channel.c > > +++ b/xen/common/event_channel.c > > @@ -93,6 +93,17 @@ static void cf_check default_xen_notification_fn( > > vcpu_wake(v); > > } > > > > +/* > > + * A slightly more updated variant of cmpxchgptr() where old value > > + * is not returned. > > + */ > > +#define cmpxchgptr_noret(ptr, o, n) ({ \ > > + __typeof__(**(ptr)) *const o_ = (o); \ > > + __typeof__(**(ptr)) *n_ = (n); \ > > + (void)__cmpxchg(ptr, (unsigned long)o_, \ > > + (unsigned long)n_, sizeof(*(ptr))); \ > > +}) > > + > > /* > > * Given a notification function, return the value to stash in > > * the evtchn->xen_consumer field. > > @@ -106,9 +117,9 @@ static uint8_t > > get_xen_consumer(xen_event_channel_notification_t fn) > > > > for ( i = 0; i < ARRAY_SIZE(xen_consumers); i++ ) > > { > > - /* Use cmpxchgptr() in lieu of a global lock. */ > > + /* Use cmpxchgptr_noret() in lieu of a global lock. */ > > if ( xen_consumers[i] == NULL ) > > - cmpxchgptr(&xen_consumers[i], NULL, fn); > > + cmpxchgptr_noret(&xen_consumers[i], NULL, fn); > > if ( xen_consumers[i] == fn ) > > break; > > } > > AFAICS, Rule 11.1 has a deviation which allows this specific case. > > In docs/misra/deviations.rst > > * - R11.1 > > - The conversion from a function pointer to unsigned long or (void \*) > > does > > not lose any information, provided that the target type has enough bits > > to store it. > > - Tagged as `safe` for ECLAIR. > > Here, we are constructing a function pointer from a unsigned long. I > assume this rule goes the other way it says, and allow converting a > unsigned long into a function pointer as long as its value is a valid > function pointer.
You are right, we should need to update the deviation instead here: -doc_begin="The conversion from a function pointer to unsigned long or (void *) does not lose any information, provided that the target type has enough bits to store it." -config=MC3A2.R11.1,casts+={safe, "from(type(canonical(__function_pointer_types))) &&to(type(canonical(builtin(unsigned long)||pointer(builtin(void))))) &&relation(definitely_preserves_value)" } -doc_end