On Wed, Feb 10, 2021 at 06:13:22PM +0000, Michael Kelley wrote:
From: Wei Liu <wei.liu(a)kernel.org>
> > >
> > > "sparse warnings: (new ones prefixed by >>)"
> > > arch/x86/hyperv/hv_init.c:90:30: sparse: sparse: incorrect type in
initializer (different
> address spaces) @@ expected void const [noderef] __percpu *__vpp_verify @@
got
> void [noderef] __percpu ** @@
> > > arch/x86/hyperv/hv_init.c:90:30: sparse: expected void const
[noderef] __percpu
> *__vpp_verify
> > > arch/x86/hyperv/hv_init.c:90:30: sparse: got void [noderef]
__percpu **
> > > arch/x86/hyperv/hv_init.c:95:39: sparse: sparse: incorrect type in
initializer (different
> address spaces) @@ expected void const [noderef] __percpu *__vpp_verify @@
got
> void [noderef] __percpu ** @@
> > > arch/x86/hyperv/hv_init.c:95:39: sparse: expected void const
[noderef] __percpu
> *__vpp_verify
> > > arch/x86/hyperv/hv_init.c:95:39: sparse: got void [noderef]
__percpu **
> >
> > I don't think this class of issue is newly introduced specifically by
> > the Linux root partition changes.
> >
> > Sparse is complaining the pointer types don't match. GCC doesn't
> > actually care.
> >
> > Off the top of my head, this should be fixable by using the __force
> > annotation. But that means littering that everywhere. That does not look
> > nice.
> >
> > Thoughts?
>
> One way of doing it would be to provide helpers like
> hv_get_hypercall_input_arg and hv_get_hypercall_output_arg. The __force
> annotation is going to be enclosed with these two functions. We still
> need to replace all the this_cpu_ptr(XXX) with the helpers, so code
> churn is inevitable.
>
> If people deem these issues important enough to fix and we agree on an
> approach I don't mind writing a patch myself.
>
Without your helpers proposal, where would you put the __force
annotation?
Basically in every location we switch to
X = (__force *)this_cpu_ptr(Y);
With helpers it will look like
X = hv_get_hypercall_input_arg();
__force is then encapsulated in the helpers. That would be much easier
to reason about.
I haven't written any code yet because I want to reproduce these issues
first. I tried doing that a few days ago. Unfortunately the stock
Sparse that comes with Debian segfaulted long before it got to Hyper-V
code.
It's not clear to me that the assignment to the local variable
"input_arg" is the problem. To me, the error looks more like it is coming
from
the __verify_pcpu_ptr() macro, which is where __vpp_verify is defined and
initialized.
I can't find my reference anymore, but to me this class of issues look to stem
from the type mismatch derived from the annotation of __percpu in
include/linux/compiler_types.h.
# define __percpu __attribute__((noderef, address_space(__percpu)))
Notice the "different address space" in the logs. The pointers in code are
not annotated, so they are in a different address space to Sparse.
Wei.
> Michael