* sparse annotation question
@ 2006-07-12 5:47 Keith Owens
2006-07-12 6:14 ` David Miller
0 siblings, 1 reply; 4+ messages in thread
From: Keith Owens @ 2006-07-12 5:47 UTC (permalink / raw)
To: linux-kernel
This fragment of ia64 code calculates the address of a user space
location, starting from a kernel derived (i.e. not user supplied)
pointer. put_user() has to be used because the code is running in
interrupt context and the calculated target address may be invalid or
paged out.
func (long regno, unsigned long *contents)
{
unsigned long i, *bsp;
mm_segment_t old_fs;
bsp = <expression involving only kernel variables>;
old_fs = set_fs(KERNEL_DS);
for (i = 0; i < (regno - 32); ++i)
bsp = ia64_rse_skip_regs(bsp, 1);
put_user(*contents, bsp);
set_fs(old_fs);
}
sparse is complaining that the second parameter to put_user() is not
marked as __user. How do I tell sparse to ignore this case? Marking
bsp as __user does not work, sparse then complains about incorrect type
in assignment (different address spaces).
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: sparse annotation question
2006-07-12 5:47 sparse annotation question Keith Owens
@ 2006-07-12 6:14 ` David Miller
2006-07-12 6:42 ` Keith Owens
0 siblings, 1 reply; 4+ messages in thread
From: David Miller @ 2006-07-12 6:14 UTC (permalink / raw)
To: kaos; +Cc: linux-kernel
From: Keith Owens <kaos@ocs.com.au>
Date: Wed, 12 Jul 2006 15:47:03 +1000
> func (long regno, unsigned long *contents)
> {
> unsigned long i, *bsp;
> mm_segment_t old_fs;
> bsp = <expression involving only kernel variables>;
> old_fs = set_fs(KERNEL_DS);
> for (i = 0; i < (regno - 32); ++i)
> bsp = ia64_rse_skip_regs(bsp, 1);
> put_user(*contents, bsp);
> set_fs(old_fs);
> }
>
> sparse is complaining that the second parameter to put_user() is not
> marked as __user. How do I tell sparse to ignore this case? Marking
> bsp as __user does not work, sparse then complains about incorrect type
> in assignment (different address spaces).
Since, in this case, you "know what you are doing" you can force the
matter by using the __force keyword as well as __user.
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: sparse annotation question
2006-07-12 6:14 ` David Miller
@ 2006-07-12 6:42 ` Keith Owens
2006-07-12 7:22 ` David Miller
0 siblings, 1 reply; 4+ messages in thread
From: Keith Owens @ 2006-07-12 6:42 UTC (permalink / raw)
To: David Miller; +Cc: linux-kernel
David Miller (on Tue, 11 Jul 2006 23:14:09 -0700 (PDT)) wrote:
>From: Keith Owens <kaos@ocs.com.au>
>Date: Wed, 12 Jul 2006 15:47:03 +1000
>
>> func (long regno, unsigned long *contents)
>> {
>> unsigned long i, *bsp;
>> mm_segment_t old_fs;
>> bsp = <expression involving only kernel variables>;
>> old_fs = set_fs(KERNEL_DS);
>> for (i = 0; i < (regno - 32); ++i)
>> bsp = ia64_rse_skip_regs(bsp, 1);
>> put_user(*contents, bsp);
>> set_fs(old_fs);
>> }
>>
>> sparse is complaining that the second parameter to put_user() is not
>> marked as __user. How do I tell sparse to ignore this case? Marking
>> bsp as __user does not work, sparse then complains about incorrect type
>> in assignment (different address spaces).
>
>Since, in this case, you "know what you are doing" you can force the
>matter by using the __force keyword as well as __user.
I tried various combinations of __force, but kept getting this:
warning: incorrect type in argument 1 (different address spaces)
expected unsigned long *addr
got unsigned long [noderef] [force] *[addressable] bsp<asn:1>
What finally worked was
unsigned long i, *bsp, __user *ubsp;
...
ubsp = (unsigned long __user *) bsp;
put_user(*contents, ubsp);
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: sparse annotation question
2006-07-12 6:42 ` Keith Owens
@ 2006-07-12 7:22 ` David Miller
0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2006-07-12 7:22 UTC (permalink / raw)
To: kaos; +Cc: linux-kernel
From: Keith Owens <kaos@ocs.com.au>
Date: Wed, 12 Jul 2006 16:42:44 +1000
> I tried various combinations of __force, but kept getting this:
>
> warning: incorrect type in argument 1 (different address spaces)
> expected unsigned long *addr
> got unsigned long [noderef] [force] *[addressable] bsp<asn:1>
>
> What finally worked was
>
> unsigned long i, *bsp, __user *ubsp;
> ...
> ubsp = (unsigned long __user *) bsp;
> put_user(*contents, ubsp);
>
Right, I guess if you try to do the cast in the put_user() macro
argument, you'll run into troubles because the __chk_user_ptr(ptr)
call wants an absolutely pure __user pointer, not one that is part of
a __force cast.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2006-07-12 7:22 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-12 5:47 sparse annotation question Keith Owens
2006-07-12 6:14 ` David Miller
2006-07-12 6:42 ` Keith Owens
2006-07-12 7:22 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox