2006-01-27 19:06:44

by Jeffrey V. Merkey

[permalink] [raw]
Subject: 2.6.14 kernels and above copy_to_user stupidity with IRQ disabled check


Is there a good reason someone set a disabled_irq() check on 2.6.14 and
above for copy_to_user to barf out
tons of bogus stack dump messages if the function is called from within
a spinlock:

i.e.

spin_lock_irqsave(&regen_lock, regen_flags);
v = regen_head;
while (v)
{
if (i >= count)
return -EFAULT;


err = copy_to_user(&s[i++], v, sizeof(VIRTUAL_SETUP));
if (err)
return err;


v = v->next;
}
spin_unlock_irqrestore(&regen_lock, regen_flags);

is now busted and worked in kernels up to this point. The error message
is annoying but non-fatal.

Jeff



2006-01-27 19:31:18

by Phillip Susi

[permalink] [raw]
Subject: Re: 2.6.14 kernels and above copy_to_user stupidity with IRQ disabled check

Probably because you aren't allowed to call copy_to_user while holding a
spin lock? The user pages might be non resident and you can't have a
page fault with interrupts disabled. Also you don't want to spend a lot
of time with interrupts disabled, and copy_to_user can take a fair
amount of time for large copies.

Jeff V. Merkey wrote:
>
> Is there a good reason someone set a disabled_irq() check on 2.6.14
> and above for copy_to_user to barf out
> tons of bogus stack dump messages if the function is called from
> within a spinlock:
>
> i.e.
>
> spin_lock_irqsave(&regen_lock, regen_flags);
> v = regen_head;
> while (v)
> {
> if (i >= count)
> return -EFAULT;
>
>
> err = copy_to_user(&s[i++], v, sizeof(VIRTUAL_SETUP));
> if (err)
> return err;
>
>
> v = v->next;
> }
> spin_unlock_irqrestore(&regen_lock, regen_flags);
>
> is now busted and worked in kernels up to this point. The error
> message is annoying but non-fatal.
>
> Jeff
>

2006-01-27 20:18:11

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: 2.6.14 kernels and above copy_to_user stupidity with IRQ disabled check


On Fri, 27 Jan 2006, Jeff V. Merkey wrote:

>
> Is there a good reason someone set a disabled_irq() check on 2.6.14 and
> above for copy_to_user to barf out
> tons of bogus stack dump messages if the function is called from within
> a spinlock:
>

This is a joke, right????

> i.e.
>
> spin_lock_irqsave(&regen_lock, regen_flags);
> v = regen_head;
> while (v)
> {
> if (i >= count)
> return -EFAULT;

** BUG ** return with spin-lock held!

>
>
> err = copy_to_user(&s[i++], v, sizeof(VIRTUAL_SETUP));

** BUG ** copy to user with spinlock held!

> if (err)
> return err;
>

** BUG ** Return with spin-lock held!
>
> v = v->next;
> }
> spin_unlock_irqrestore(&regen_lock, regen_flags);
>
> is now busted and worked in kernels up to this point. The error message
> is annoying but non-fatal.
>
> Jeff

It was NEVER supposed to work! The only reason it worked is because
your page(s) copied to, were not swapped out. If they were swapped
out, you are stuck, the page-fault won't occur.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.13.4 on an i686 machine (5589.66 BogoMips).
Warning : 98.36% of all statistics are fiction.
.

****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

2006-01-27 20:24:50

by jmerkey

[permalink] [raw]
Subject: Re: 2.6.14 kernels and above copy_to_user stupidity with IRQ disabled check



OK. Got it. I guess I need to restructure. And BTW, This was a code fragment
only, the spinlock gets released when -EFAULT is called -- was just an example.

Jeff

On Fri, Jan 27, 2006 at 03:18:06PM -0500, linux-os (Dick Johnson) wrote:
>
> On Fri, 27 Jan 2006, Jeff V. Merkey wrote:
>
> >
> > Is there a good reason someone set a disabled_irq() check on 2.6.14 and
> > above for copy_to_user to barf out
> > tons of bogus stack dump messages if the function is called from within
> > a spinlock:
> >
>
> This is a joke, right????
>
> > i.e.
> >
> > spin_lock_irqsave(&regen_lock, regen_flags);
> > v = regen_head;
> > while (v)
> > {
> > if (i >= count)
> > return -EFAULT;
>
> ** BUG ** return with spin-lock held!
>
> >
> >
> > err = copy_to_user(&s[i++], v, sizeof(VIRTUAL_SETUP));
>
> ** BUG ** copy to user with spinlock held!
>
> > if (err)
> > return err;
> >
>
> ** BUG ** Return with spin-lock held!
> >
> > v = v->next;
> > }
> > spin_unlock_irqrestore(&regen_lock, regen_flags);
> >
> > is now busted and worked in kernels up to this point. The error message
> > is annoying but non-fatal.
> >
> > Jeff
>
> It was NEVER supposed to work! The only reason it worked is because
> your page(s) copied to, were not swapped out. If they were swapped
> out, you are stuck, the page-fault won't occur.
>
> Cheers,
> Dick Johnson
> Penguin : Linux version 2.6.13.4 on an i686 machine (5589.66 BogoMips).
> Warning : 98.36% of all statistics are fiction.
> .
>
> ****************************************************************
> The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.
>
> Thank you.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

2006-01-27 20:36:41

by jmerkey

[permalink] [raw]
Subject: Re: 2.6.14 kernels and above copy_to_user stupidity with IRQ disabled check

On Fri, Jan 27, 2006 at 01:10:58PM -0700, [email protected] wrote:


Also, allowing page faults in kernel to swap in user space memory
seems dangerous. Now I understand why I see the page fault handler
recurse in some cases with other code.

W2K does the same thing for performance reasons, so I guess it doesn't really
matter. I would assume there would be a safer place to fault in the memory, but
given people rolling their own ioctl requests, I can see where determining
this would be difficult.

Jeff

>
>
> OK. Got it. I guess I need to restructure. And BTW, This was a code fragment
> only, the spinlock gets released when -EFAULT is called -- was just an example.
>
> Jeff
>
> On Fri, Jan 27, 2006 at 03:18:06PM -0500, linux-os (Dick Johnson) wrote:
> >
> > On Fri, 27 Jan 2006, Jeff V. Merkey wrote:
> >
> > >
> > > Is there a good reason someone set a disabled_irq() check on 2.6.14 and
> > > above for copy_to_user to barf out
> > > tons of bogus stack dump messages if the function is called from within
> > > a spinlock:
> > >
> >
> > This is a joke, right????
> >
> > > i.e.
> > >
> > > spin_lock_irqsave(&regen_lock, regen_flags);
> > > v = regen_head;
> > > while (v)
> > > {
> > > if (i >= count)
> > > return -EFAULT;
> >
> > ** BUG ** return with spin-lock held!
> >
> > >
> > >
> > > err = copy_to_user(&s[i++], v, sizeof(VIRTUAL_SETUP));
> >
> > ** BUG ** copy to user with spinlock held!
> >
> > > if (err)
> > > return err;
> > >
> >
> > ** BUG ** Return with spin-lock held!
> > >
> > > v = v->next;
> > > }
> > > spin_unlock_irqrestore(&regen_lock, regen_flags);
> > >
> > > is now busted and worked in kernels up to this point. The error message
> > > is annoying but non-fatal.
> > >
> > > Jeff
> >
> > It was NEVER supposed to work! The only reason it worked is because
> > your page(s) copied to, were not swapped out. If they were swapped
> > out, you are stuck, the page-fault won't occur.
> >
> > Cheers,
> > Dick Johnson
> > Penguin : Linux version 2.6.13.4 on an i686 machine (5589.66 BogoMips).
> > Warning : 98.36% of all statistics are fiction.
> > .
> >
> > ****************************************************************
> > The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.
> >
> > Thank you.
> > -
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to [email protected]
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at http://www.tux.org/lkml/
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

2006-01-27 20:40:33

by Phillip Susi

[permalink] [raw]
Subject: Re: 2.6.14 kernels and above copy_to_user stupidity with IRQ disabled check

[email protected] wrote:
> OK. Got it. I guess I need to restructure. And BTW, This was a code fragment
> only, the spinlock gets released when -EFAULT is called -- was just an example.
>
> Jeff

Unless you have redefined EFAULT in some strange and hideous way, it is
not "called" and doesn't free the spinlock. EFAULT is defined as a
literal integer, so you're just returning a number without freeing the
spinlock.


If you have redefined EFAULT to a macro function call or whatever, then
don't do that, it's REALLY horrible coding practice.


2006-01-27 21:18:50

by Jeffrey V. Merkey

[permalink] [raw]
Subject: Re: 2.6.14 kernels and above copy_to_user stupidity with IRQ disabled check

Phillip Susi wrote:

> [email protected] wrote:
>
>> OK. Got it. I guess I need to restructure. And BTW, This was a
>> code fragment
>> only, the spinlock gets released when -EFAULT is called -- was just
>> an example.
>>
>> Jeff
>
>
> Unless you have redefined EFAULT in some strange and hideous way, it
> is not "called" and doesn't free the spinlock. EFAULT is defined as a
> literal integer, so you're just returning a number without freeing the
> spinlock.
>
> If you have redefined EFAULT to a macro function call or whatever,
> then don't do that, it's REALLY horrible coding practice.
>
>
No. I posted a code fragment as an example. Here's the actual code:

int dump_regen(VIRTUAL_SETUP *s, ULONG count)
{
register int i = 0;
VIRTUAL_SETUP *v;


spin_lock_irqsave(&regen_lock, regen_flags);
v = regen_head;
while (v)
{
if (i >= count)
{
spin_unlock_irqrestore(&regen_lock, regen_flags);
return -EFAULT;
}


err = copy_to_user(&s[i++], v, sizeof(VIRTUAL_SETUP));
if (err)
{
spin_unlock_irqrestore(&regen_lock, regen_flags);
return err;
}

v = v->next;
}
spin_unlock_irqrestore(&regen_lock, regen_flags);
return 0;
}

Needless to say, this has been restructured to this:

int dump_regen(VIRTUAL_SETUP *s, ULONG count)
{
register int i = 0;
VIRTUAL_SETUP *v;


spin_lock_irqsave(&regen_lock, regen_flags);
v = regen_head;
while (v)
{
if (i >= count)
{
spin_unlock_irqrestore(&regen_lock, regen_flags);
return 0;
}


P_Copy(&s[i++], v, sizeof(VIRTUAL_SETUP));
v = v->next;
}
spin_unlock_irqrestore(&regen_lock, regen_flags);
return 0;
}


Jeff