|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 2/2] xen/multicall: Change nr_calls to uniformly be unsigned long
On Fri, 21 Jun 2024, Andrew Cooper wrote:
> Right now, the non-compat declaration and definition of do_multicall()
> differing types for the nr_calls parameter.
>
> This is a MISRA rule 8.3 violation, but it's also time-bomb waiting for the
> first 128bit architecture (RISC-V looks as if it might get there first).
>
> Worse, the type chosen here has a side effect of truncating the guest
> parameter, because Xen still doesn't have a clean hypercall ABI definition.
>
> Switch uniformly to using unsigned long.
>
> This addresses the MISRA violation, and while it is a guest-visible ABI
> change, it's only in the corner case where the guest kernel passed a
> bogus-but-correct-when-truncated value. I can't find any any users of
> mutilcall which pass a bad size to begin with, so this should have no
> practical effect on guests.
>
> In fact, this brings the behaviour of multicalls more in line with the header
> description of how it behaves.
>
> With this fix, Xen is now fully clean to Rule 8.3, so mark it so.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
I am in favor of this approach. I have 2 suggestions which are
nice-to-have, not must-have.
We all know that "unsigned long" is register size. However, the C
standard doesn't define it that way. I tried to make it clear in
docs/misra/C-language-toolchain.rst. However, nowhere in the public
Xen headers we say that by "unsigned long" we mean register size. I
think we should say that somewhere in the headers, but I can see it
doesn't have to be part of this patch. It would be nice to add a comment
in xen/include/public/xen.h saying "unsigned long is register size" or
"refer to docs/misra/C-language-toolchain.rst for type sizes and
definitions", but it is not a hard request.
The second observation, if we are concerned about invalid nr_calls
values, we could add a check at the beginning of do_multicall:
if ( nr_calls >= UINT32_MAX )
I am not sure it is an improvement, but maybe it is.
Given that both the above suggestions are nice-to-have:
Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
> ---
> CC: George Dunlap <George.Dunlap@xxxxxxxxxx>
> CC: Jan Beulich <JBeulich@xxxxxxxx>
> CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
> CC: Julien Grall <julien@xxxxxxx>
> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
> CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
> CC: Roberto Bagnara <roberto.bagnara@xxxxxxxxxxx>
> CC: consulting@xxxxxxxxxxx <consulting@xxxxxxxxxxx>
> CC: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
>
> I know this isn't going to be universally liked, but we need to do something,
> and this is my very strong vote for the least bad way out of the current mess.
> ---
> automation/eclair_analysis/ECLAIR/tagging.ecl | 1 +
> xen/common/multicall.c | 4 ++--
> xen/include/hypercall-defs.c | 4 ++--
> xen/include/public/xen.h | 2 +-
> 4 files changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/automation/eclair_analysis/ECLAIR/tagging.ecl
> b/automation/eclair_analysis/ECLAIR/tagging.ecl
> index b829655ca0bc..3d06a1aad410 100644
> --- a/automation/eclair_analysis/ECLAIR/tagging.ecl
> +++ b/automation/eclair_analysis/ECLAIR/tagging.ecl
> @@ -45,6 +45,7 @@ MC3R1.R7.2||
> MC3R1.R7.4||
> MC3R1.R8.1||
> MC3R1.R8.2||
> +MC3R1.R8.3||
> MC3R1.R8.5||
> MC3R1.R8.6||
> MC3R1.R8.8||
> diff --git a/xen/common/multicall.c b/xen/common/multicall.c
> index 1f0cc4cb267c..ce394c5efcfe 100644
> --- a/xen/common/multicall.c
> +++ b/xen/common/multicall.c
> @@ -34,11 +34,11 @@ static void trace_multicall_call(multicall_entry_t *call)
> }
>
> ret_t do_multicall(
> - XEN_GUEST_HANDLE_PARAM(multicall_entry_t) call_list, uint32_t nr_calls)
> + XEN_GUEST_HANDLE_PARAM(multicall_entry_t) call_list, unsigned long
> nr_calls)
> {
> struct vcpu *curr = current;
> struct mc_state *mcs = &curr->mc_state;
> - uint32_t i;
> + unsigned long i;
> int rc = 0;
> enum mc_disposition disp = mc_continue;
>
> diff --git a/xen/include/hypercall-defs.c b/xen/include/hypercall-defs.c
> index 47c093acc84d..7720a29ade0b 100644
> --- a/xen/include/hypercall-defs.c
> +++ b/xen/include/hypercall-defs.c
> @@ -135,7 +135,7 @@ xenoprof_op(int op, void *arg)
> #ifdef CONFIG_COMPAT
> prefix: compat
> set_timer_op(uint32_t lo, uint32_t hi)
> -multicall(multicall_entry_compat_t *call_list, uint32_t nr_calls)
> +multicall(multicall_entry_compat_t *call_list, unsigned long nr_calls)
> memory_op(unsigned int cmd, void *arg)
> #ifdef CONFIG_IOREQ_SERVER
> dm_op(domid_t domid, unsigned int nr_bufs, void *bufs)
> @@ -172,7 +172,7 @@ console_io(unsigned int cmd, unsigned int count, char
> *buffer)
> vm_assist(unsigned int cmd, unsigned int type)
> event_channel_op(int cmd, void *arg)
> mmuext_op(mmuext_op_t *uops, unsigned int count, unsigned int *pdone,
> unsigned int foreigndom)
> -multicall(multicall_entry_t *call_list, unsigned int nr_calls)
> +multicall(multicall_entry_t *call_list, unsigned long nr_calls)
> #ifdef CONFIG_PV
> mmu_update(mmu_update_t *ureqs, unsigned int count, unsigned int *pdone,
> unsigned int foreigndom)
> stack_switch(unsigned long ss, unsigned long esp)
> diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
> index b47d48d0e2d6..e051f989a5ca 100644
> --- a/xen/include/public/xen.h
> +++ b/xen/include/public/xen.h
> @@ -623,7 +623,7 @@ DEFINE_XEN_GUEST_HANDLE(mmu_update_t);
> /*
> * ` enum neg_errnoval
> * ` HYPERVISOR_multicall(multicall_entry_t call_list[],
> - * ` uint32_t nr_calls);
> + * ` unsigned long nr_calls);
> *
> * NB. The fields are logically the natural register size for this
> * architecture. In cases where xen_ulong_t is larger than this then
> --
> 2.39.2
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |