public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* 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