All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PULL] drm-intel-next
From: Martin @ 2011-10-23 11:10 UTC (permalink / raw)
  To: linux-kernel

Keith Packard wrote:

> 
> Here's a pile of new code for the 3.2 series.
[...]
>       drm/i915: close PM interrupt masking races in the irq handler
>       drm/i915: close PM interrupt masking races in the rps work func

I always get my hopes high when I read something like this. Maybe my Clarkdale 
based workstation will eventually get fully stable and I can close my ancient 
bugzilla entries.

Martin

^ permalink raw reply

* Re: [GIT PULL 0/4] perf/core improvements and fixes
From: Ingo Molnar @ 2011-10-23 10:59 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: linux-kernel, David Ahern, Frederic Weisbecker, Mike Galbraith,
	Paul Mackerras, Peter Zijlstra, Stephane Eranian, arnaldo.melo
In-Reply-To: <1319115948-12060-1-git-send-email-acme@infradead.org>


* Arnaldo Carvalho de Melo <acme@infradead.org> wrote:

> Hi Ingo,
> 
>         Please consider pulling from:
> 
> git://github.com/acmel/linux.git perf/core
> 
> Regards,
> 
> - Arnaldo
> 
> Arnaldo Carvalho de Melo (4):
>   perf hists browser: Honour symbol_conf.show_{nr_samples,total_period}
>   perf hists: Don't decay total_period for filtered entries
>   perf hists: Don't consider filtered entries when calculating column widths
>   perf hists browser: Elide DSO column when it is set to just one DSO, ditto for threads
> 
>  tools/perf/util/hist.c              |   14 ++++++++++----
>  tools/perf/util/sort.c              |    4 +++-
>  tools/perf/util/ui/browsers/hists.c |   14 ++++++++++++++
>  3 files changed, 27 insertions(+), 5 deletions(-)

Pulled, thanks Arnaldo!

	Ingo

^ permalink raw reply

* RE: [PATCH] regulator: Add S5M8767 regulator driver
From: Sangbeom Kim @ 2011-10-23 10:59 UTC (permalink / raw)
  To: 'Mark Brown'; +Cc: 'Liam Girdwood', linux-kernel
In-Reply-To: <20111023093020.GC3135@opensource.wolfsonmicro.com>

On Sun, Oct 23, 2011 at 06:30 PM , Mark Brown wrote:
 
> I guess you need an implementation for enable_suspend() (otherwise you
> can't do disable->enable)
Ok, I will add it in the next version.

> 
> > +	{
> > +		.name	= "AP 32KHz",
> > +		.id	= S5M8767_32KHZAP_EN,
> > +		.ops	= &s5m8767_others_ops,
> > +		.type	= REGULATOR_VOLTAGE,
> > +		.owner	= THIS_MODULE,
> > +	}, {
> > +		.name	= "CP 32KHz",
> > +		.id	= S5M8767_32KHZAP_EN,
> > +		.ops	= &s5m8767_others_ops,
> > +		.type	= REGULATOR_VOLTAGE,
> > +		.owner	= THIS_MODULE,
> > +	},
> 
> Do these actually share anything with the other regulators?  If not then
> I guess it's better to do with the struct clk framework.

OK, I will consider clk framework

 
> > +				dev_warn(&pdev->dev, "Duplicated gpio
> > request"
> > +						" for SET3\n");
> 
> Please keep the strings on one line (it makes grepping for errors
> easier).

Thanks,
Sangbeom.


^ permalink raw reply

* Re: cifs and win2k8
From: Jeff Layton @ 2011-10-23 10:55 UTC (permalink / raw)
  To: sean finney
  Cc: Terrence Shipclark, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	Pavel Shilovsky
In-Reply-To: <20111023103003.GA6132-Znhnm/lQSyjxW5zecs3cv0EOCMrvLtNR@public.gmane.org>

On Sun, 23 Oct 2011 12:30:03 +0200
sean finney <seanius-ADwgVSpYHhHR7s880joybQ@public.gmane.org> wrote:

> Hello Terrence,
> 
> On Fri, Oct 21, 2011 at 07:18:20AM -0400, Terrence Shipclark wrote:
> > I have been attempting to get the cifs kernel modules to mount the
> > win2k8 dfs at my workplace.   I did finally manage to get
> > the dfs to mount after modifying the kernel module with this small patch
> 
> I believe this should already be fixed (in a more correct fashion) in >= 3.0.
> 
> > Within the dfs tree there is a referral to //server/share$/folder.
> > My user has access to //server/share$/folder, however do not have
> > access to
> > //server/$share.  While following the referral the cifs module does a
> > QUERY_PATH_INFO on \\server\share$\folder, and then is followed up
> > by a QUERY_PATH_INFO on \\server\share$\ which rightfully returns a
> > STATUS_ACCESS_DENIED from the server.
> 
> I've also noticed that the mounting process seems to query more than
> it should, but I've taken the easy way out and asked the local windows
> admin to add "traverse filesystem" and "read attributes" permissions on
> the parent folders, which should be enough.  I suspect that there is a
> "real fix" to avoid this, but haven't looked too hard myself.
> 
> 

I believe this is a known bug...

3.0 got a patchset to allow superblocks to be shared, but that
regressed the above use case (mounting a directory that you have access
to but not the stuff below it).

Pavel had some patches that he was going to propose to fix it, but
discussion of them sort of fell off. Pavel, did you ever come up with
something that worked here?

-- 
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>

^ permalink raw reply

* Re: BUG: All network processes hang (brcmsmac/wpa_supplicant)
From: Nico Schottelius @ 2011-10-23 10:53 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Nico Schottelius, Eric Dumazet, linux-wireless@vger.kernel.org
In-Reply-To: <4EA3E6AD.4030701@broadcom.com>

[-- Attachment #1: Type: text/plain, Size: 1564 bytes --]

Hey Arend,

Arend van Spriel [Sun, Oct 23, 2011 at 12:04:29PM +0200]:
> I see three different AP's in this log. Could you indicate what AP you
> have issues with.

Sure, it's this one:

> [19010.367351] wlan0: RX AssocResp from 00:14:6c:67:9c:32 (capab=0x611
> status=0 aid=2)
> [19010.367355] wlan0: associated

It's a WPNT384 (Netgear), an early pre-draft-n ap.

> With the suspend/resume cycles early in the dmesg log it seems brcmsmac
> gets disassoc/deauth before going to sleep. When things start to get
> flaky this does not seem to happen and I see a lot of deauth reason=2 in
> the log. If I am correct that would mean previousAuthNotValid. Not sure
> why we see that. Will try to reproduce this tomorrow.

Thanks for digging in there. I've to update my report: After another two
suspend/resume cycles, the connection works fine again:

64 bytes from 192.168.42.1: icmp_req=38950 ttl=64 time=103 ms
64 bytes from 192.168.42.1: icmp_req=38951 ttl=64 time=47.4 ms
64 bytes from 192.168.42.1: icmp_req=38952 ttl=64 time=34.1 ms
64 bytes from 192.168.42.1: icmp_req=38953 ttl=64 time=3.57 ms
64 bytes from 192.168.42.1: icmp_req=38954 ttl=64 time=10.6 ms
64 bytes from 192.168.42.1: icmp_req=38955 ttl=64 time=1.24 ms
64 bytes from 192.168.42.1: icmp_req=38956 ttl=64 time=64.8 ms
[...]

I'm watching this problem for the next time and as soon it happens
again, I'll test with other wifi devices to verify that the problem
is not within the AP.

I've attached the updated dmesg.

Cheers,

Nico

-- 
PGP key: 7ED9 F7D3 6B10 81D7 0EC5  5C09 D7DC C8E4 3187 7DF0

[-- Attachment #2: dmesg.gz --]
[-- Type: application/octet-stream, Size: 69222 bytes --]

^ permalink raw reply

* RE: [PATCH 2/3] mfd: Add s5m series irq support
From: Sangbeom Kim @ 2011-10-23 10:51 UTC (permalink / raw)
  To: 'Mark Brown'; +Cc: 'Samuel Ortiz', linux-kernel
In-Reply-To: <20111023084233.GB3135@opensource.wolfsonmicro.com>

On Sun, Oct 23, 2011 at 05:43 PM , Mark Brown wrote:
 
> Actually, one of the things I want to do in the 3.3 timeframe is to
> factor out this code from my drivers into a regmap based irq_chip since
> it seems a lot of people are "drawing inspiration" from it.  This
> shouldn't be any form of blocker for merging this driver though.

I hope that this driver will be base code for regmap based irq driver
I want discuss more detail in Prague.
Thanks,

Sangbeom.


^ permalink raw reply

* Re: [patch net-next V2] net: introduce ethernet teaming device
From: Eric Dumazet @ 2011-10-23 10:45 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, bhutchings, shemminger, fubar, andy, tgraf,
	ebiederm, mirqus, kaber, greearb, jesse, fbl, benjamin.poirier,
	jzupka
In-Reply-To: <20111023082545.GA15908@minipsycho.orion>

Le dimanche 23 octobre 2011 à 10:25 +0200, Jiri Pirko a écrit :

> Please forgive me, it's possible I'm missing something. But I see no way how
> team->mode_ops.receive can change during team_handle_frame (holding
> rcu_read_lock) for the reason I stated earlier.
> 
> team_port_del() calls netdev_rx_handler_unregister() and after that it
> calls synchronize_rcu(). That ensures that by the finish of team_port_del()
> run, team_handle_frame() is not called for this port anymore.
> 
> And this combined with "if (!list_empty(&team->port_list))" check in
> team_change_mode() ensures safety.
> 
> Of course team_port_del() and team_change_mode() are both protected by
> team->lock so they are mutually excluded.

Oh well.

Jirka, I believe I do understand how RCU is working ;)

There is an obvious problem I pointed to you, but you persist leaving
this potential bug.

After netdev_rx_handler_unregister(), you can still have other cpus
calling your handler and reading/using previous memory content. Only
after synchronize_rcu() you can be safe. But in your patch the bug
window is _exactly_ _before_ synchronize_rcu() returns.

Your spinlock wont help you at all, since readers dont take it.
Spinlock only protects writers.


So a reader, even holding rcu lock, can really see two different
mode_ops.receive values for the :

if (team->mode_ops.receive)
	res = team->mode_ops.receive(team, port, skb);


rcu_lock() doesnt mean the reader can see an unique .receive value,

I am afraid you misunderstood the point.

Real point of RCU here is that the _writer_ wont returns from
synchronize_rcu() if at least one reader is still running the handler.

No problem with me, I'll just post a patch later, I just cant Ack your
work as is.

^ permalink raw reply

* Re: [PATCH 00/22] Refactor to accept NUL in commit messages
From: Robin Rosenberg @ 2011-10-23 10:44 UTC (permalink / raw)
  To: Jeff King
  Cc: Nguyễn Thái Ngọc Duy, git, Junio C Hamano,
	Ævar Arnfjörð
In-Reply-To: <20111022190914.GA1785@sigill.intra.peff.net>

Jeff King skrev 2011-10-22 21.09:
> On Sat, Oct 22, 2011 at 09:04:19PM +1100, Nguyen Thai Ngoc Duy wrote:
>
>> This series helps pass commit message size up to output functions,
>> though it does not change any output functions to print ^@.
> Can we take a step back for a second and discuss what git _should_ do
> with commits that contain NUL?
Yes please. I don't think allowing NUL makes sense, but it makes sense
to state how NUL should be handled when anyone attempt it, so there
might be things to fix even if NUL is banned.

Are there any such commits in the wild?

-- robin

^ permalink raw reply

* RE: [PATCH 1/3] mfd: Add S5M core driver
From: Sangbeom Kim @ 2011-10-23 10:39 UTC (permalink / raw)
  To: 'Mark Brown'; +Cc: 'Samuel Ortiz', linux-kernel
In-Reply-To: <20111023083704.GA3135@opensource.wolfsonmicro.com>

Hi!

On Sun, Oct 23, 2011 at 05:37 PM +0900, Mark Brown wrote:

> >  drivers/mfd/s5m-core.c               |  235 +++++++++++++++++++++++++
> >  include/linux/mfd/s5m87xx/s5m-core.h |  313
> > ++++++++++++++++++++++++++++++++++
> 
> Naughty Outlook!

Sorry, I hope that I can send next version by git send-email.

> Actually, looking at this what I'm thinking is that we should put some
> inline functions in the regmap header which let you write this as
> something like
> 
> 	int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, u8 *dest)
> 	{
> 		return regmap_read_u8(s5m87xx->dev, reg, dest);
> 	}
> (which might be inline itself) as most of what you're doing here is the
> type conversion for the arguments.

OK, I will modify it.
> 
> > +EXPORT_SYMBOL(s5m_bulk_read);
> 
> All this stuff should be _GPL as the regmap core is _GPL - you shouldn't
> wrap a _GPL function with a non-GPL one.

You mean that EXPORT_SYMBOL should be replace with EXPORT_SYMBOL_GPL?

> > +static struct mfd_cell s5m87xx_devs[] = {
> > +	{
> > +		.name = "s5m8763-pmic",
> > +	}, {
> > +		.name = "s5m8767-pmic",
> > +	}, {
> 
> It looks a bit odd to have both simultaneously but I guess this will
> become more obvious later on?  I guess what I'd expect is one of these
> arrays per device variant.

My intention of this mfd driver is supporting all samsung mfd.
It is desirable that a core driver handle various driver to prevent produce
similar code.
So, If I want to implement like above concept, What kind of approach can be
advised?
 
> > +	s5m87xx->dev = &i2c->dev;
> > +	s5m87xx->i2c = i2c;
> > +	s5m87xx->irq = i2c->irq;
> 
> Is SPI supported?

SPI isn't supported by Samsung mfd

> 
> > +	dev_info(s5m87xx->dev ,"SAMSUNG S5M MFD\n");
> 
> Probably best to remove this for mainline, it's not really adding
> anything.

OK, I will remove it.

> > +static const struct i2c_device_id s5m87xx_i2c_id[] = {
> > +	{ "s5m87xx", 0 },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(i2c, s5m87xx_i2c_id);
> 
> It'd be better to have one entry per chip explicitly naming the device,
> that way boards are describing which they have and the kernel can apply
> any device specific configuration.
> 
As I write above, I want to use a core driver for various mfd.
What kind of approach can be advised?

I'm very thank for your kindly review.
Sangbeom.


^ permalink raw reply

* Re: Use of _hint() functions and older machines
From: Clemens Ladisch @ 2011-10-23 10:36 UTC (permalink / raw)
  To: Randell Jesup; +Cc: alsa-devel
In-Reply-To: <4EA0E6E5.1050600@jesup.org>

On 10/21/2011 05:28 AM, Randell Jesup wrote:
> On older machines, _hint() aren't available, so even if I make them
> optional to dlsym-loading, I would need some other method to get the
> information I assume using older, now-deprecated-or-gone interfaces.

On older machines, that information wasn't available at all.

The recommendation was to use "default" or to let the user enter
a device name.

The best way to get a list of devices would have been to enumerate sound
cards with snd_card_next(), then use device names "default:CARD=x".
However, this gets only the primary device of each card, there might be
sound cards without a PCM device, devices not based on an ALSA kernel
driver aren't listed, and the "default:CARD=x" mechanism doesn't work if
the user has redefined the "default" device.


Regards,
Clemens

^ permalink raw reply

* Re: git mergetool ignores configured command line
From: David Aguilar @ 2011-10-23 10:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Andreas Schwab, Alexander Vladimirov, git
In-Reply-To: <7vaa8s592k.fsf@alter.siamese.dyndns.org>

On Sun, Oct 23, 2011 at 02:52:19AM -0700, Junio C Hamano wrote:
> Andreas Schwab <schwab@linux-m68k.org> writes:
> 
> > diffuse is already a predefined merge tool, so mergetool.diffuse.cmd is
> > ignored.  Try using a different name.
> 
> I wonder if we can improve this, though.
> 
> It is nice that we give canned definition of argument order to so many
> obscure tools, but instead of ignoring mergetool.<tool>.cmd when the user
> told us to use <tool>, couldn't we simply ignore what we have internally
> as canned definition?
> 
> Even if such a change were too intrusive (I didn't check), could we have
> a decency to at least warn that we are ignoring the configuration?

I agree.  Ideally, we should honor their configuration.
I'll see if doing so is not too intrusive.
-- 
					David

^ permalink raw reply

* Re: cifs and win2k8
From: sean finney @ 2011-10-23 10:30 UTC (permalink / raw)
  To: Terrence Shipclark; +Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4EA154FC.3090601-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Hello Terrence,

On Fri, Oct 21, 2011 at 07:18:20AM -0400, Terrence Shipclark wrote:
> I have been attempting to get the cifs kernel modules to mount the
> win2k8 dfs at my workplace.   I did finally manage to get
> the dfs to mount after modifying the kernel module with this small patch

I believe this should already be fixed (in a more correct fashion) in >= 3.0.

> Within the dfs tree there is a referral to //server/share$/folder.
> My user has access to //server/share$/folder, however do not have
> access to
> //server/$share.  While following the referral the cifs module does a
> QUERY_PATH_INFO on \\server\share$\folder, and then is followed up
> by a QUERY_PATH_INFO on \\server\share$\ which rightfully returns a
> STATUS_ACCESS_DENIED from the server.

I've also noticed that the mounting process seems to query more than
it should, but I've taken the easy way out and asked the local windows
admin to add "traverse filesystem" and "read attributes" permissions on
the parent folders, which should be enough.  I suspect that there is a
"real fix" to avoid this, but haven't looked too hard myself.


	sean

^ permalink raw reply

* [RFC] ipv6 over wireless classification issue?
From: David Täht @ 2011-10-23 10:23 UTC (permalink / raw)
  To: bloat-devel, linux-wireless@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 1932 bytes --]

After slowly working my way down from verifying the apps to ECN handling 
and up from the drivers... I've been (also) slowly working on getting 
wireless qos/aqms to work better, on ipv6. (I need to get to having a 
spectrum analyzer or better instrumentation...) I was puzzled about dscp 
marked ipv6 packets responding differently.

Perhaps this is it. I'm not making this a commit yet (untested code!)

d@cruithne:~/git/linux-2.6/include$ git diff
diff --git a/net/wireless/util.c b/net/wireless/util.c
index be75a3a..a11c5f2 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -658,6 +658,12 @@ unsigned int cfg80211_classify8021d(struct sk_buff 
*skb)
         case htons(ETH_P_IP):
                 dscp = ip_hdr(skb)->tos & 0xfc;
                 break;
+       case htons(ETH_P_IPV6):
+               dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & 0xfc;
+               break;
+       case htons(ETH_P_ARP):
+               dscp = 4<<5;
+               break;
         default:
                 return 0;
         }


A) Elsewhere in the stack ipv4_get_dsfield is the equivalent of the 
ip_hdr(skb)->tos & 0xfc line
B) It appears ipv6_get_dsfield is safe to call from non-ipv6 enabled 
systems

So my thought would be to also harmonize this with ipv4_get_dsfield...

C) And I doubt that slamming arp packets into the VI queue would be 
acceptable yet (as per the ANTs discussion of a few months back, ARP, 
ND, RA, RS, DHCP, and possibly DNS, ssh (marked interactive), etc might 
do better in the VI queue)
(however this part of the patch is not relevant to the IPv6 issue, it's 
just the patch I wanted to try)

D) Lastly, Later on in this function only dscp's first 3 bits (CS0 - 
CS7) are used to classify packets into the queues, where a mildly saner 
version would use a lookup table to also do sane things with the 
'immediate' bit, perhaps settable via userspace from via sysfs, sysctl, 
or proc.

-- 
Dave Täht


[-- Attachment #2: dave_taht.vcf --]
[-- Type: text/x-vcard, Size: 204 bytes --]

begin:vcard
fn;quoted-printable:Dave T=C3=A4ht
n;quoted-printable:T=C3=A4ht;Dave
email;internet:dave.taht@gmail.com
tel;home:1-239-829-5608
tel;cell:0638645374
x-mozilla-html:FALSE
version:2.1
end:vcard


^ permalink raw reply related

* [PATCH RFC 6/8] m68k: implement syscall restart generically
From: Jonas Bonn @ 2011-10-23 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn, linux-m68k
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating task state to effect re-execution of an interrupted syscall
used to be purely architecture specific code.  However, as most arch's
were essentially just making minor adjustments to almost identical logic,
this code could be moved to a common implementation.

The generic variant introduces the function handle_syscall_restart() to be
called after get_signal_to_deliver().  The architecture specific register
manipulations required to effect the actual restart are now implemented
in the generic syscall interface found in asm/syscall.h

This patch transitions this architecture's signal handling code over to
using the generic syscall restart code by:

i)  Implementing the register manipulations in asm/syscall.h
ii) Replacing the restart logic with a call to handle_syscall_restart

Cc: linux-m68k@lists.linux-m68k.org
Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 arch/m68k/include/asm/syscall.h |   87 +++++++++++++++++++++++++++++++++++++++
 arch/m68k/kernel/signal_mm.c    |   45 +-------------------
 arch/m68k/kernel/signal_no.c    |   46 +-------------------
 3 files changed, 93 insertions(+), 85 deletions(-)
 create mode 100644 arch/m68k/include/asm/syscall.h

diff --git a/arch/m68k/include/asm/syscall.h b/arch/m68k/include/asm/syscall.h
new file mode 100644
index 0000000..a482b7b
--- /dev/null
+++ b/arch/m68k/include/asm/syscall.h
@@ -0,0 +1,87 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Copyright (C) 2011 Jonas Bonn <jonas@southpole.se>
+ */
+
+#ifndef _M68K_SYSCALL_H
+#define _M68K_SYSCALL_H
+
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <asm/unistd.h>
+
+static inline int
+syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+	if (regs->orig_d0 >= 0)
+		return regs->orig_d0;
+	else
+		return -1;
+}
+
+static inline void
+syscall_rollback(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->d0 = regs->orig_d0;
+}
+
+static inline void
+syscall_clear(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->orig_d0 = -1;
+}
+
+static inline void
+syscall_restart(struct task_struct *task, struct pt_regs *regs)
+{
+	syscall_rollback(task, regs);
+	regs->pc -= 2;
+}
+
+static inline void
+syscall_do_restartblock(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->d0 = __NR_restart_syscall;
+	regs->pc -= 2;
+}
+
+static inline long
+syscall_get_error(struct task_struct *task, struct pt_regs *regs)
+{
+	return IS_ERR_VALUE(regs->d0) ? regs->d0 : 0;
+}
+
+static inline long
+syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+	return regs->d0;
+}
+
+static inline void
+syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
+			 int error, long val)
+{
+	regs->d0 = (long) error ?: val;
+}
+
+#if 0
+static inline void
+syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
+		      unsigned int i, unsigned int n, unsigned long *args)
+{
+	/* TODO */
+}
+
+static inline void
+syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
+		      unsigned int i, unsigned int n, const unsigned long *args)
+{
+	/* TODO */
+}
+#endif
+
+#endif
diff --git a/arch/m68k/kernel/signal_mm.c b/arch/m68k/kernel/signal_mm.c
index a0afc23..a8fa041 100644
--- a/arch/m68k/kernel/signal_mm.c
+++ b/arch/m68k/kernel/signal_mm.c
@@ -895,39 +895,6 @@ give_sigsegv:
 	return err;
 }
 
-static inline void
-handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
-{
-	switch (regs->d0) {
-	case -ERESTARTNOHAND:
-		if (!has_handler)
-			goto do_restart;
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTART_RESTARTBLOCK:
-		if (!has_handler) {
-			regs->d0 = __NR_restart_syscall;
-			regs->pc -= 2;
-			break;
-		}
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTARTSYS:
-		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
-			regs->d0 = -EINTR;
-			break;
-		}
-	/* fallthrough */
-	case -ERESTARTNOINTR:
-	do_restart:
-		regs->d0 = regs->orig_d0;
-		regs->pc -= 2;
-		break;
-	}
-}
-
 void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
 {
 	if (regs->orig_d0 < 0)
@@ -951,10 +918,6 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	      sigset_t *oldset, struct pt_regs *regs)
 {
 	int err;
-	/* are we from a system call? */
-	if (regs->orig_d0 >= 0)
-		/* If so, check system call restarting.. */
-		handle_restart(regs, ka, 1);
 
 	/* set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
@@ -998,17 +961,15 @@ asmlinkage void do_signal(struct pt_regs *regs)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	handle_syscall_restart(regs, &ka, (signr > 0));
+
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &ka, &info, oldset, regs);
 		return;
 	}
 
-	/* Did we come from a system call? */
-	if (regs->orig_d0 >= 0)
-		/* Restart the system call - no handlers present */
-		handle_restart(regs, NULL, 0);
-
 	/* If there's no signal to deliver, we just restore the saved mask.  */
 	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
 		clear_thread_flag(TIF_RESTORE_SIGMASK);
diff --git a/arch/m68k/kernel/signal_no.c b/arch/m68k/kernel/signal_no.c
index 36a81bb..2fad7c7 100644
--- a/arch/m68k/kernel/signal_no.c
+++ b/arch/m68k/kernel/signal_no.c
@@ -653,39 +653,6 @@ give_sigsegv:
 	goto adjust_stack;
 }
 
-static inline void
-handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
-{
-	switch (regs->d0) {
-	case -ERESTARTNOHAND:
-		if (!has_handler)
-			goto do_restart;
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTART_RESTARTBLOCK:
-		if (!has_handler) {
-			regs->d0 = __NR_restart_syscall;
-			regs->pc -= 2;
-			break;
-		}
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTARTSYS:
-		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
-			regs->d0 = -EINTR;
-			break;
-		}
-	/* fallthrough */
-	case -ERESTARTNOINTR:
-	do_restart:
-		regs->d0 = regs->orig_d0;
-		regs->pc -= 2;
-		break;
-	}
-}
-
 /*
  * OK, we're invoking a handler
  */
@@ -694,10 +661,6 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	      sigset_t *oldset, struct pt_regs *regs)
 {
 	int err;
-	/* are we from a system call? */
-	if (regs->orig_d0 >= 0)
-		/* If so, check system call restarting.. */
-		handle_restart(regs, ka, 1);
 
 	/* set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
@@ -745,18 +708,15 @@ asmlinkage void do_signal(struct pt_regs *regs)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	handle_syscall_restart(regs, &ka, (signr > 0));
+
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &ka, &info, oldset, regs);
 		return;
 	}
 
-	/* Did we come from a system call? */
-	if (regs->orig_d0 >= 0) {
-		/* Restart the system call - no handlers present */
-		handle_restart(regs, NULL, 0);
-	}
-
 	/* If there's no signal to deliver, we just restore the saved mask.  */
 	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
 		clear_thread_flag(TIF_RESTORE_SIGMASK);
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH RFC 7/8] ia64: implement syscall restart generically
From: Jonas Bonn @ 2011-10-23 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn, linux-ia64
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating task state to effect re-execution of an interrupted syscall
used to be purely architecture specific code.  However, as most arch's
were essentially just making minor adjustments to almost identical logic,
this code could be moved to a common implementation.

The generic variant introduces the function handle_syscall_restart() to be
called after get_signal_to_deliver().  The architecture specific register
manipulations required to effect the actual restart are now implemented
in the generic syscall interface found in asm/syscall.h

This patch transitions this architecture's signal handling code over to
using the generic syscall restart code by:

i)  Implementing the register manipulations in asm/syscall.h
ii) Replacing the restart logic with a call to handle_syscall_restart

Cc: linux-ia64@vger.kernel.org
Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 arch/ia64/include/asm/syscall.h |   21 +++++++++++++++
 arch/ia64/kernel/signal.c       |   54 +--------------------------------------
 2 files changed, 22 insertions(+), 53 deletions(-)

diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h
index a7ff1c6..ee18042 100644
--- a/arch/ia64/include/asm/syscall.h
+++ b/arch/ia64/include/asm/syscall.h
@@ -15,6 +15,7 @@
 
 #include <linux/sched.h>
 #include <linux/err.h>
+#include <asm/unistd.h>
 
 static inline long syscall_get_nr(struct task_struct *task,
 				  struct pt_regs *regs)
@@ -31,6 +32,26 @@ static inline void syscall_rollback(struct task_struct *task,
 	/* do nothing */
 }
 
+static inline void
+syscall_clear(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->cr_ifs |= (1UL << 63);
+}
+
+static inline void
+syscall_restart(struct task_struct *task, struct pt_regs *regs)
+{
+	syscall_rollback(task, regs);
+	ia64_decrement_ip(regs);
+}
+
+static inline void
+syscall_do_restartblock(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->r15 = __NR_restart_syscall;
+	ia64_decrement_ip(regs);
+}
+
 static inline long syscall_get_error(struct task_struct *task,
 				     struct pt_regs *regs)
 {
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 7bdafc8..0b8abbc 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -453,8 +453,6 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
 	struct k_sigaction ka;
 	sigset_t *oldset;
 	siginfo_t info;
-	long restart = in_syscall;
-	long errno = scr->pt.r8;
 
 	/*
 	 * In the ia64_leave_kernel code path, we want the common case to go fast, which
@@ -476,44 +474,11 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
 	while (1) {
 		int signr = get_signal_to_deliver(&info, &ka, &scr->pt, NULL);
 
-		/*
-		 * get_signal_to_deliver() may have run a debugger (via notify_parent())
-		 * and the debugger may have modified the state (e.g., to arrange for an
-		 * inferior call), thus it's important to check for restarting _after_
-		 * get_signal_to_deliver().
-		 */
-		if ((long) scr->pt.r10 != -1)
-			/*
-			 * A system calls has to be restarted only if one of the error codes
-			 * ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned.  If r10
-			 * isn't -1 then r8 doesn't hold an error code and we don't need to
-			 * restart the syscall, so we can clear the "restart" flag here.
-			 */
-			restart = 0;
+		handle_syscall_restart(&scr->pt, &ka, (signr > 0));
 
 		if (signr <= 0)
 			break;
 
-		if (unlikely(restart)) {
-			switch (errno) {
-			      case ERESTART_RESTARTBLOCK:
-			      case ERESTARTNOHAND:
-				scr->pt.r8 = EINTR;
-				/* note: scr->pt.r10 is already -1 */
-				break;
-
-			      case ERESTARTSYS:
-				if ((ka.sa.sa_flags & SA_RESTART) == 0) {
-					scr->pt.r8 = EINTR;
-					/* note: scr->pt.r10 is already -1 */
-					break;
-				}
-			      case ERESTARTNOINTR:
-				ia64_decrement_ip(&scr->pt);
-				restart = 0; /* don't restart twice if handle_signal() fails... */
-			}
-		}
-
 		/*
 		 * Whee!  Actually deliver the signal.  If the delivery failed, we need to
 		 * continue to iterate in this loop so we can deliver the SIGSEGV...
@@ -530,23 +495,6 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
 		}
 	}
 
-	/* Did we come from a system call? */
-	if (restart) {
-		/* Restart the system call - no handlers present */
-		if (errno == ERESTARTNOHAND || errno == ERESTARTSYS || errno == ERESTARTNOINTR
-		    || errno == ERESTART_RESTARTBLOCK)
-		{
-			/*
-			 * Note: the syscall number is in r15 which is saved in
-			 * pt_regs so all we need to do here is adjust ip so that
-			 * the "break" instruction gets re-executed.
-			 */
-			ia64_decrement_ip(&scr->pt);
-			if (errno == ERESTART_RESTARTBLOCK)
-				scr->pt.r15 = __NR_restart_syscall;
-		}
-	}
-
 	/* if there's no signal to deliver, we just put the saved sigmask
 	 * back */
 	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH RFC 5/8] x86: implement syscall restart generically
From: Jonas Bonn @ 2011-10-23 10:19 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn, x86
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating task state to effect re-execution of an interrupted syscall
used to be purely architecture specific code.  However, as most arch's
were essentially just making minor adjustments to almost identical logic,
this code could be moved to a common implementation.

The generic variant introduces the function handle_syscall_restart() to be
called after get_signal_to_deliver().  The architecture specific register
manipulations required to effect the actual restart are now implemented
in the generic syscall interface found in asm/syscall.h

This patch transitions this architecture's signal handling code over to
using the generic syscall restart code by:

i)  Implementing the register manipulations in asm/syscall.h
ii) Replacing the restart logic with a call to handle_syscall_restart

Cc: x86@kernel.org
Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 arch/x86/include/asm/syscall.h |   21 +++++++++++++++++++
 arch/x86/kernel/signal.c       |   43 ++-------------------------------------
 2 files changed, 24 insertions(+), 40 deletions(-)

diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h
index c4a348f..bd7e0f6 100644
--- a/arch/x86/include/asm/syscall.h
+++ b/arch/x86/include/asm/syscall.h
@@ -15,6 +15,7 @@
 
 #include <linux/sched.h>
 #include <linux/err.h>
+#include <asm/unistd.h>
 
 extern const unsigned long sys_call_table[];
 
@@ -34,6 +35,26 @@ static inline void syscall_rollback(struct task_struct *task,
 	regs->ax = regs->orig_ax;
 }
 
+static inline void
+syscall_clear(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->orig_ax = -1;
+}
+
+static inline void
+syscall_restart(struct task_struct *task, struct pt_regs *regs)
+{
+	syscall_rollback(task, regs);
+	regs->ip -= 2;
+}
+
+static inline void
+syscall_do_restartblock(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->ax = __NR_restart_syscall;
+	regs->ip -= 2;
+}
+
 static inline long syscall_get_error(struct task_struct *task,
 				     struct pt_regs *regs)
 {
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 54ddaeb2..366d5f7 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -685,28 +685,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 	sigset_t blocked;
 	int ret;
 
-	/* Are we from a system call? */
-	if (syscall_get_nr(current, regs) >= 0) {
-		/* If so, check system call restarting.. */
-		switch (syscall_get_error(current, regs)) {
-		case -ERESTART_RESTARTBLOCK:
-		case -ERESTARTNOHAND:
-			regs->ax = -EINTR;
-			break;
-
-		case -ERESTARTSYS:
-			if (!(ka->sa.sa_flags & SA_RESTART)) {
-				regs->ax = -EINTR;
-				break;
-			}
-		/* fallthrough */
-		case -ERESTARTNOINTR:
-			regs->ax = regs->orig_ax;
-			regs->ip -= 2;
-			break;
-		}
-	}
-
 	/*
 	 * If TF is set due to a debugger (TIF_FORCED_TF), clear the TF
 	 * flag so that register information in the sigcontext is correct.
@@ -773,30 +751,15 @@ static void do_signal(struct pt_regs *regs)
 		return;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	handle_syscall_restart(regs, &ka, (signr > 0));
+
 	if (signr > 0) {
 		/* Whee! Actually deliver the signal.  */
 		handle_signal(signr, &info, &ka, regs);
 		return;
 	}
 
-	/* Did we come from a system call? */
-	if (syscall_get_nr(current, regs) >= 0) {
-		/* Restart the system call - no handlers present */
-		switch (syscall_get_error(current, regs)) {
-		case -ERESTARTNOHAND:
-		case -ERESTARTSYS:
-		case -ERESTARTNOINTR:
-			regs->ax = regs->orig_ax;
-			regs->ip -= 2;
-			break;
-
-		case -ERESTART_RESTARTBLOCK:
-			regs->ax = NR_restart_syscall;
-			regs->ip -= 2;
-			break;
-		}
-	}
-
 	/*
 	 * If there's no signal to deliver, we just put the saved sigmask
 	 * back.
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH RFC 3/8] frv: implement syscall restart generically
From: Jonas Bonn @ 2011-10-23 10:19 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn, David Howells
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating task state to effect re-execution of an interrupted syscall
used to be purely architecture specific code.  However, as most arch's
were essentially just making minor adjustments to almost identical logic,
this code could be moved to a common implementation.

The generic variant introduces the function handle_syscall_restart() to be
called after get_signal_to_deliver().  The architecture specific register
manipulations required to effect the actual restart are now implemented
in the generic syscall interface found in asm/syscall.h

This patch transitions this architecture's signal handling code over to
using the generic syscall restart code by:

i)  Implementing the register manipulations in asm/syscall.h
ii) Replacing the restart logic with a call to handle_syscall_restart

Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 arch/frv/include/asm/syscall.h |   23 ++++++++++++++++++-
 arch/frv/kernel/signal.c       |   48 ++-------------------------------------
 2 files changed, 25 insertions(+), 46 deletions(-)

diff --git a/arch/frv/include/asm/syscall.h b/arch/frv/include/asm/syscall.h
index 70689eb..a0493da 100644
--- a/arch/frv/include/asm/syscall.h
+++ b/arch/frv/include/asm/syscall.h
@@ -14,6 +14,7 @@
 
 #include <linux/err.h>
 #include <asm/ptrace.h>
+#include <asm/unistd.h>
 
 /*
  * Get the system call number or -1
@@ -34,6 +35,26 @@ static inline void syscall_rollback(struct task_struct *task,
 	regs->gr8 = regs->orig_gr8;
 }
 
+static inline void
+syscall_clear(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->syscallno = -1;
+}
+
+static inline void
+syscall_restart(struct task_struct *task, struct pt_regs *regs)
+{
+	syscall_rollback(task, regs);
+	regs->pc -= 4;
+}
+
+static inline void
+syscall_do_restartblock(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->gr7 = __NR_restart_syscall;
+	regs->pc -= 4;
+}
+
 /*
  * See if the syscall return value is an error, returning it if it is and 0 if
  * not
@@ -61,7 +82,7 @@ static inline void syscall_set_return_value(struct task_struct *task,
 					    int error, long val)
 {
 	if (error)
-		regs->gr8 = -error;
+		regs->gr8 = error;
 	else
 		regs->gr8 = val;
 }
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index bab0129..a8bacdd 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -445,29 +445,6 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
 {
 	int ret;
 
-	/* Are we from a system call? */
-	if (__frame->syscallno != -1) {
-		/* If so, check system call restarting.. */
-		switch (__frame->gr8) {
-		case -ERESTART_RESTARTBLOCK:
-		case -ERESTARTNOHAND:
-			__frame->gr8 = -EINTR;
-			break;
-
-		case -ERESTARTSYS:
-			if (!(ka->sa.sa_flags & SA_RESTART)) {
-				__frame->gr8 = -EINTR;
-				break;
-			}
-
-			/* fallthrough */
-		case -ERESTARTNOINTR:
-			__frame->gr8 = __frame->orig_gr8;
-			__frame->pc -= 4;
-		}
-		__frame->syscallno = -1;
-	}
-
 	/* Set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
 		ret = setup_rt_frame(sig, ka, info, oldset);
@@ -510,15 +487,15 @@ static void do_signal(void)
 	if (!user_mode(__frame))
 		return;
 
-	if (try_to_freeze())
-		goto no_signal;
-
 	if (test_thread_flag(TIF_RESTORE_SIGMASK))
 		oldset = &current->saved_sigmask;
 	else
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
+
+	handle_syscall_restart(__frame, &ka, (signr > 0));
+
 	if (signr > 0) {
 		if (handle_signal(signr, &info, &ka, oldset) == 0) {
 			/* a signal was successfully delivered; the saved
@@ -536,25 +513,6 @@ static void do_signal(void)
 	}
 
 no_signal:
-	/* Did we come from a system call? */
-	if (__frame->syscallno != -1) {
-		/* Restart the system call - no handlers present */
-		switch (__frame->gr8) {
-		case -ERESTARTNOHAND:
-		case -ERESTARTSYS:
-		case -ERESTARTNOINTR:
-			__frame->gr8 = __frame->orig_gr8;
-			__frame->pc -= 4;
-			break;
-
-		case -ERESTART_RESTARTBLOCK:
-			__frame->gr7 = __NR_restart_syscall;
-			__frame->pc -= 4;
-			break;
-		}
-		__frame->syscallno = -1;
-	}
-
 	/* if there's no signal to deliver, we just put the saved sigmask
 	 * back */
 	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH RFC 2/8] blackfin: implement syscall restart generically
From: Jonas Bonn @ 2011-10-23 10:19 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn, uclinux-dist-devel
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating task state to effect re-execution of an interrupted syscall
used to be purely architecture specific code.  However, as most arch's
were essentially just making minor adjustments to almost identical logic,
this code could be moved to a common implementation.

The generic variant introduces the function handle_syscall_restart() to be
called after get_signal_to_deliver().  The architecture specific register
manipulations required to effect the actual restart are now implemented
in the generic syscall interface found in asm/syscall.h

This patch transitions this architecture's signal handling code over to
using the generic syscall restart code by:

i)  Implementing the register manipulations in asm/syscall.h
ii) Replacing the restart logic with a call to handle_syscall_restart

Cc: uclinux-dist-devel@blackfin.uclinux.org
Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 arch/blackfin/include/asm/syscall.h |   26 ++++++++++++++++++-
 arch/blackfin/kernel/signal.c       |   47 ++--------------------------------
 2 files changed, 27 insertions(+), 46 deletions(-)

diff --git a/arch/blackfin/include/asm/syscall.h b/arch/blackfin/include/asm/syscall.h
index 4921a48..87005c4 100644
--- a/arch/blackfin/include/asm/syscall.h
+++ b/arch/blackfin/include/asm/syscall.h
@@ -21,17 +21,39 @@
 #include <linux/err.h>
 #include <linux/sched.h>
 #include <asm/ptrace.h>
+#include <asm/unistd.h>
 
 static inline long
 syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
 {
-	return regs->p0;
+	return regs->orig_p0;
 }
 
 static inline void
 syscall_rollback(struct task_struct *task, struct pt_regs *regs)
 {
 	regs->p0 = regs->orig_p0;
+	regs->r0 = regs->orig_r0;
+}
+
+static inline void
+syscall_clear(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->orig_p0 = -1;
+}
+
+static inline void
+syscall_restart(struct task_struct *task, struct pt_regs *regs)
+{
+	syscall_rollback(task, regs);
+	regs->pc -= 2;
+}
+
+static inline void
+syscall_do_restartblock(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->p0 = __NR_restart_syscall;
+	regs->pc -= 2;
 }
 
 static inline long
@@ -50,7 +72,7 @@ static inline void
 syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
                          int error, long val)
 {
-	regs->r0 = error ? -error : val;
+	regs->r0 = error ? error : val;
 }
 
 /**
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index d536f35..7fc176a 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -219,36 +219,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
 	return -EFAULT;
 }
 
-static inline void
-handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
-{
-	switch (regs->r0) {
-	case -ERESTARTNOHAND:
-		if (!has_handler)
-			goto do_restart;
-		regs->r0 = -EINTR;
-		break;
-
-	case -ERESTARTSYS:
-		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
-			regs->r0 = -EINTR;
-			break;
-		}
-		/* fallthrough */
-	case -ERESTARTNOINTR:
- do_restart:
-		regs->p0 = regs->orig_p0;
-		regs->r0 = regs->orig_r0;
-		regs->pc -= 2;
-		break;
-
-	case -ERESTART_RESTARTBLOCK:
-		regs->p0 = __NR_restart_syscall;
-		regs->pc -= 2;
-		break;
-	}
-}
-
 /*
  * OK, we're invoking a handler
  */
@@ -258,11 +228,6 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
 {
 	int ret;
 
-	/* are we from a system call? to see pt_regs->orig_p0 */
-	if (regs->orig_p0 >= 0)
-		/* If so, check system call restarting.. */
-		handle_restart(regs, ka, 1);
-
 	/* set up the stack frame */
 	ret = setup_rt_frame(sig, ka, info, oldset, regs);
 
@@ -296,15 +261,15 @@ asmlinkage void do_signal(struct pt_regs *regs)
 
 	current->thread.esp0 = (unsigned long)regs;
 
-	if (try_to_freeze())
-		goto no_signal;
-
 	if (test_thread_flag(TIF_RESTORE_SIGMASK))
 		oldset = &current->saved_sigmask;
 	else
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	handle_syscall_restart(regs, &ka, (signr > 0));
+
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
@@ -322,12 +287,6 @@ asmlinkage void do_signal(struct pt_regs *regs)
 		return;
 	}
 
- no_signal:
-	/* Did we come from a system call? */
-	if (regs->orig_p0 >= 0)
-		/* Restart the system call - no handlers present */
-		handle_restart(regs, NULL, 0);
-
 	/* if there's no signal to deliver, we just put the saved sigmask
 	 * back */
 	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH RFC 8/8] tile: implement syscall restart generically
From: Jonas Bonn @ 2011-10-23 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn, Chris Metcalf
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating task state to effect re-execution of an interrupted syscall
used to be purely architecture specific code.  However, as most arch's
were essentially just making minor adjustments to almost identical logic,
this code could be moved to a common implementation.

The generic variant introduces the function handle_syscall_restart() to be
called after get_signal_to_deliver().  The architecture specific register
manipulations required to effect the actual restart are now implemented
in the generic syscall interface found in asm/syscall.h

This patch transitions this architecture's signal handling code over to
using the generic syscall restart code by:

i)  Implementing the register manipulations in asm/syscall.h
ii) Replacing the restart logic with a call to handle_syscall_restart

Cc: Chris Metcalf <cmetcalf@tilera.com>
Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 arch/tile/include/asm/syscall.h |   28 ++++++++++++++++++++-
 arch/tile/kernel/signal.c       |   52 +++------------------------------------
 2 files changed, 31 insertions(+), 49 deletions(-)

diff --git a/arch/tile/include/asm/syscall.h b/arch/tile/include/asm/syscall.h
index d35e0dc..428e28c 100644
--- a/arch/tile/include/asm/syscall.h
+++ b/arch/tile/include/asm/syscall.h
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/err.h>
 #include <arch/abi.h>
+#include <asm/unistd.h>
 
 /*
  * Only the low 32 bits of orig_r0 are meaningful, so we return int.
@@ -29,15 +30,40 @@
  */
 static inline int syscall_get_nr(struct task_struct *t, struct pt_regs *regs)
 {
-	return regs->regs[TREG_SYSCALL_NR];
+	if (regs->faultnum == INT_SWINT_1)
+		return regs->regs[TREG_SYSCALL_NR];
+	else
+		return -1;
 }
 
 static inline void syscall_rollback(struct task_struct *task,
 				    struct pt_regs *regs)
 {
+	regs->flags |= PT_FLAGS_CALLER_SAVES;
 	regs->regs[0] = regs->orig_r0;
 }
 
+static inline void
+syscall_clear(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->faultnum = INT_SWINT_1_SIGRETURN;
+}
+
+static inline void
+syscall_restart(struct task_struct *task, struct pt_regs *regs)
+{
+	syscall_rollback(task, regs);
+	regs->pc -= 8;
+}
+
+static inline void
+syscall_do_restartblock(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->flags |= PT_FLAGS_CALLER_SAVES;
+	regs->gpr[TREG_SYSCALL_NR] = __NR_restart_syscall;
+	regs->pc -= 8;
+}
+
 static inline long syscall_get_error(struct task_struct *task,
 				     struct pt_regs *regs)
 {
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index bedaf4e..ab1f4e7 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -251,29 +251,6 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
 {
 	int ret;
 
-	/* Are we from a system call? */
-	if (regs->faultnum == INT_SWINT_1) {
-		/* If so, check system call restarting.. */
-		switch (regs->regs[0]) {
-		case -ERESTART_RESTARTBLOCK:
-		case -ERESTARTNOHAND:
-			regs->regs[0] = -EINTR;
-			break;
-
-		case -ERESTARTSYS:
-			if (!(ka->sa.sa_flags & SA_RESTART)) {
-				regs->regs[0] = -EINTR;
-				break;
-			}
-			/* fallthrough */
-		case -ERESTARTNOINTR:
-			/* Reload caller-saves to restore r0..r5 and r10. */
-			regs->flags |= PT_FLAGS_CALLER_SAVES;
-			regs->regs[0] = regs->orig_r0;
-			regs->pc -= 8;
-		}
-	}
-
 	/* Set up the stack frame */
 #ifdef CONFIG_COMPAT
 	if (is_compat_task())
@@ -323,6 +300,9 @@ void do_signal(struct pt_regs *regs)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	handle_syscall_restart(regs, &ka, (signr > 0));
+
 	if (signr > 0) {
 		/* Whee! Actually deliver the signal.  */
 		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
@@ -335,27 +315,7 @@ void do_signal(struct pt_regs *regs)
 			current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 		}
 
-		goto done;
-	}
-
-	/* Did we come from a system call? */
-	if (regs->faultnum == INT_SWINT_1) {
-		/* Restart the system call - no handlers present */
-		switch (regs->regs[0]) {
-		case -ERESTARTNOHAND:
-		case -ERESTARTSYS:
-		case -ERESTARTNOINTR:
-			regs->flags |= PT_FLAGS_CALLER_SAVES;
-			regs->regs[0] = regs->orig_r0;
-			regs->pc -= 8;
-			break;
-
-		case -ERESTART_RESTARTBLOCK:
-			regs->flags |= PT_FLAGS_CALLER_SAVES;
-			regs->regs[TREG_SYSCALL_NR] = __NR_restart_syscall;
-			regs->pc -= 8;
-			break;
-		}
+		return;
 	}
 
 	/* If there's no signal to deliver, just put the saved sigmask back. */
@@ -363,10 +323,6 @@ void do_signal(struct pt_regs *regs)
 		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 	}
-
-done:
-	/* Avoid double syscall restart if there are nested signals. */
-	regs->faultnum = INT_SWINT_1_SIGRETURN;
 }
 
 int show_unhandled_signals = 1;
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH RFC 7/8] ia64: implement syscall restart generically
From: Jonas Bonn @ 2011-10-23 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn, linux-ia64
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating task state to effect re-execution of an interrupted syscall
used to be purely architecture specific code.  However, as most arch's
were essentially just making minor adjustments to almost identical logic,
this code could be moved to a common implementation.

The generic variant introduces the function handle_syscall_restart() to be
called after get_signal_to_deliver().  The architecture specific register
manipulations required to effect the actual restart are now implemented
in the generic syscall interface found in asm/syscall.h

This patch transitions this architecture's signal handling code over to
using the generic syscall restart code by:

i)  Implementing the register manipulations in asm/syscall.h
ii) Replacing the restart logic with a call to handle_syscall_restart

Cc: linux-ia64@vger.kernel.org
Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 arch/ia64/include/asm/syscall.h |   21 +++++++++++++++
 arch/ia64/kernel/signal.c       |   54 +--------------------------------------
 2 files changed, 22 insertions(+), 53 deletions(-)

diff --git a/arch/ia64/include/asm/syscall.h b/arch/ia64/include/asm/syscall.h
index a7ff1c6..ee18042 100644
--- a/arch/ia64/include/asm/syscall.h
+++ b/arch/ia64/include/asm/syscall.h
@@ -15,6 +15,7 @@
 
 #include <linux/sched.h>
 #include <linux/err.h>
+#include <asm/unistd.h>
 
 static inline long syscall_get_nr(struct task_struct *task,
 				  struct pt_regs *regs)
@@ -31,6 +32,26 @@ static inline void syscall_rollback(struct task_struct *task,
 	/* do nothing */
 }
 
+static inline void
+syscall_clear(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->cr_ifs |= (1UL << 63);
+}
+
+static inline void
+syscall_restart(struct task_struct *task, struct pt_regs *regs)
+{
+	syscall_rollback(task, regs);
+	ia64_decrement_ip(regs);
+}
+
+static inline void
+syscall_do_restartblock(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->r15 = __NR_restart_syscall;
+	ia64_decrement_ip(regs);
+}
+
 static inline long syscall_get_error(struct task_struct *task,
 				     struct pt_regs *regs)
 {
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 7bdafc8..0b8abbc 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -453,8 +453,6 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
 	struct k_sigaction ka;
 	sigset_t *oldset;
 	siginfo_t info;
-	long restart = in_syscall;
-	long errno = scr->pt.r8;
 
 	/*
 	 * In the ia64_leave_kernel code path, we want the common case to go fast, which
@@ -476,44 +474,11 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
 	while (1) {
 		int signr = get_signal_to_deliver(&info, &ka, &scr->pt, NULL);
 
-		/*
-		 * get_signal_to_deliver() may have run a debugger (via notify_parent())
-		 * and the debugger may have modified the state (e.g., to arrange for an
-		 * inferior call), thus it's important to check for restarting _after_
-		 * get_signal_to_deliver().
-		 */
-		if ((long) scr->pt.r10 != -1)
-			/*
-			 * A system calls has to be restarted only if one of the error codes
-			 * ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned.  If r10
-			 * isn't -1 then r8 doesn't hold an error code and we don't need to
-			 * restart the syscall, so we can clear the "restart" flag here.
-			 */
-			restart = 0;
+		handle_syscall_restart(&scr->pt, &ka, (signr > 0));
 
 		if (signr <= 0)
 			break;
 
-		if (unlikely(restart)) {
-			switch (errno) {
-			      case ERESTART_RESTARTBLOCK:
-			      case ERESTARTNOHAND:
-				scr->pt.r8 = EINTR;
-				/* note: scr->pt.r10 is already -1 */
-				break;
-
-			      case ERESTARTSYS:
-				if ((ka.sa.sa_flags & SA_RESTART) = 0) {
-					scr->pt.r8 = EINTR;
-					/* note: scr->pt.r10 is already -1 */
-					break;
-				}
-			      case ERESTARTNOINTR:
-				ia64_decrement_ip(&scr->pt);
-				restart = 0; /* don't restart twice if handle_signal() fails... */
-			}
-		}
-
 		/*
 		 * Whee!  Actually deliver the signal.  If the delivery failed, we need to
 		 * continue to iterate in this loop so we can deliver the SIGSEGV...
@@ -530,23 +495,6 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
 		}
 	}
 
-	/* Did we come from a system call? */
-	if (restart) {
-		/* Restart the system call - no handlers present */
-		if (errno = ERESTARTNOHAND || errno = ERESTARTSYS || errno = ERESTARTNOINTR
-		    || errno = ERESTART_RESTARTBLOCK)
-		{
-			/*
-			 * Note: the syscall number is in r15 which is saved in
-			 * pt_regs so all we need to do here is adjust ip so that
-			 * the "break" instruction gets re-executed.
-			 */
-			ia64_decrement_ip(&scr->pt);
-			if (errno = ERESTART_RESTARTBLOCK)
-				scr->pt.r15 = __NR_restart_syscall;
-		}
-	}
-
 	/* if there's no signal to deliver, we just put the saved sigmask
 	 * back */
 	if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH RFC 6/8] m68k: implement syscall restart generically
From: Jonas Bonn @ 2011-10-23 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn, linux-m68k
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating task state to effect re-execution of an interrupted syscall
used to be purely architecture specific code.  However, as most arch's
were essentially just making minor adjustments to almost identical logic,
this code could be moved to a common implementation.

The generic variant introduces the function handle_syscall_restart() to be
called after get_signal_to_deliver().  The architecture specific register
manipulations required to effect the actual restart are now implemented
in the generic syscall interface found in asm/syscall.h

This patch transitions this architecture's signal handling code over to
using the generic syscall restart code by:

i)  Implementing the register manipulations in asm/syscall.h
ii) Replacing the restart logic with a call to handle_syscall_restart

Cc: linux-m68k@lists.linux-m68k.org
Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 arch/m68k/include/asm/syscall.h |   87 +++++++++++++++++++++++++++++++++++++++
 arch/m68k/kernel/signal_mm.c    |   45 +-------------------
 arch/m68k/kernel/signal_no.c    |   46 +-------------------
 3 files changed, 93 insertions(+), 85 deletions(-)
 create mode 100644 arch/m68k/include/asm/syscall.h

diff --git a/arch/m68k/include/asm/syscall.h b/arch/m68k/include/asm/syscall.h
new file mode 100644
index 0000000..a482b7b
--- /dev/null
+++ b/arch/m68k/include/asm/syscall.h
@@ -0,0 +1,87 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Copyright (C) 2011 Jonas Bonn <jonas@southpole.se>
+ */
+
+#ifndef _M68K_SYSCALL_H
+#define _M68K_SYSCALL_H
+
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <asm/unistd.h>
+
+static inline int
+syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+	if (regs->orig_d0 >= 0)
+		return regs->orig_d0;
+	else
+		return -1;
+}
+
+static inline void
+syscall_rollback(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->d0 = regs->orig_d0;
+}
+
+static inline void
+syscall_clear(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->orig_d0 = -1;
+}
+
+static inline void
+syscall_restart(struct task_struct *task, struct pt_regs *regs)
+{
+	syscall_rollback(task, regs);
+	regs->pc -= 2;
+}
+
+static inline void
+syscall_do_restartblock(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->d0 = __NR_restart_syscall;
+	regs->pc -= 2;
+}
+
+static inline long
+syscall_get_error(struct task_struct *task, struct pt_regs *regs)
+{
+	return IS_ERR_VALUE(regs->d0) ? regs->d0 : 0;
+}
+
+static inline long
+syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+	return regs->d0;
+}
+
+static inline void
+syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
+			 int error, long val)
+{
+	regs->d0 = (long) error ?: val;
+}
+
+#if 0
+static inline void
+syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
+		      unsigned int i, unsigned int n, unsigned long *args)
+{
+	/* TODO */
+}
+
+static inline void
+syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
+		      unsigned int i, unsigned int n, const unsigned long *args)
+{
+	/* TODO */
+}
+#endif
+
+#endif
diff --git a/arch/m68k/kernel/signal_mm.c b/arch/m68k/kernel/signal_mm.c
index a0afc23..a8fa041 100644
--- a/arch/m68k/kernel/signal_mm.c
+++ b/arch/m68k/kernel/signal_mm.c
@@ -895,39 +895,6 @@ give_sigsegv:
 	return err;
 }
 
-static inline void
-handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
-{
-	switch (regs->d0) {
-	case -ERESTARTNOHAND:
-		if (!has_handler)
-			goto do_restart;
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTART_RESTARTBLOCK:
-		if (!has_handler) {
-			regs->d0 = __NR_restart_syscall;
-			regs->pc -= 2;
-			break;
-		}
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTARTSYS:
-		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
-			regs->d0 = -EINTR;
-			break;
-		}
-	/* fallthrough */
-	case -ERESTARTNOINTR:
-	do_restart:
-		regs->d0 = regs->orig_d0;
-		regs->pc -= 2;
-		break;
-	}
-}
-
 void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
 {
 	if (regs->orig_d0 < 0)
@@ -951,10 +918,6 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	      sigset_t *oldset, struct pt_regs *regs)
 {
 	int err;
-	/* are we from a system call? */
-	if (regs->orig_d0 >= 0)
-		/* If so, check system call restarting.. */
-		handle_restart(regs, ka, 1);
 
 	/* set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
@@ -998,17 +961,15 @@ asmlinkage void do_signal(struct pt_regs *regs)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	handle_syscall_restart(regs, &ka, (signr > 0));
+
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &ka, &info, oldset, regs);
 		return;
 	}
 
-	/* Did we come from a system call? */
-	if (regs->orig_d0 >= 0)
-		/* Restart the system call - no handlers present */
-		handle_restart(regs, NULL, 0);
-
 	/* If there's no signal to deliver, we just restore the saved mask.  */
 	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
 		clear_thread_flag(TIF_RESTORE_SIGMASK);
diff --git a/arch/m68k/kernel/signal_no.c b/arch/m68k/kernel/signal_no.c
index 36a81bb..2fad7c7 100644
--- a/arch/m68k/kernel/signal_no.c
+++ b/arch/m68k/kernel/signal_no.c
@@ -653,39 +653,6 @@ give_sigsegv:
 	goto adjust_stack;
 }
 
-static inline void
-handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
-{
-	switch (regs->d0) {
-	case -ERESTARTNOHAND:
-		if (!has_handler)
-			goto do_restart;
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTART_RESTARTBLOCK:
-		if (!has_handler) {
-			regs->d0 = __NR_restart_syscall;
-			regs->pc -= 2;
-			break;
-		}
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTARTSYS:
-		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
-			regs->d0 = -EINTR;
-			break;
-		}
-	/* fallthrough */
-	case -ERESTARTNOINTR:
-	do_restart:
-		regs->d0 = regs->orig_d0;
-		regs->pc -= 2;
-		break;
-	}
-}
-
 /*
  * OK, we're invoking a handler
  */
@@ -694,10 +661,6 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	      sigset_t *oldset, struct pt_regs *regs)
 {
 	int err;
-	/* are we from a system call? */
-	if (regs->orig_d0 >= 0)
-		/* If so, check system call restarting.. */
-		handle_restart(regs, ka, 1);
 
 	/* set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
@@ -745,18 +708,15 @@ asmlinkage void do_signal(struct pt_regs *regs)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	handle_syscall_restart(regs, &ka, (signr > 0));
+
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &ka, &info, oldset, regs);
 		return;
 	}
 
-	/* Did we come from a system call? */
-	if (regs->orig_d0 >= 0) {
-		/* Restart the system call - no handlers present */
-		handle_restart(regs, NULL, 0);
-	}
-
 	/* If there's no signal to deliver, we just restore the saved mask.  */
 	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
 		clear_thread_flag(TIF_RESTORE_SIGMASK);
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH RFC 6/8] m68k: implement syscall restart generically
From: Jonas Bonn @ 2011-10-23 10:20 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn, linux-m68k
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating task state to effect re-execution of an interrupted syscall
used to be purely architecture specific code.  However, as most arch's
were essentially just making minor adjustments to almost identical logic,
this code could be moved to a common implementation.

The generic variant introduces the function handle_syscall_restart() to be
called after get_signal_to_deliver().  The architecture specific register
manipulations required to effect the actual restart are now implemented
in the generic syscall interface found in asm/syscall.h

This patch transitions this architecture's signal handling code over to
using the generic syscall restart code by:

i)  Implementing the register manipulations in asm/syscall.h
ii) Replacing the restart logic with a call to handle_syscall_restart

Cc: linux-m68k@lists.linux-m68k.org
Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 arch/m68k/include/asm/syscall.h |   87 +++++++++++++++++++++++++++++++++++++++
 arch/m68k/kernel/signal_mm.c    |   45 +-------------------
 arch/m68k/kernel/signal_no.c    |   46 +-------------------
 3 files changed, 93 insertions(+), 85 deletions(-)
 create mode 100644 arch/m68k/include/asm/syscall.h

diff --git a/arch/m68k/include/asm/syscall.h b/arch/m68k/include/asm/syscall.h
new file mode 100644
index 0000000..a482b7b
--- /dev/null
+++ b/arch/m68k/include/asm/syscall.h
@@ -0,0 +1,87 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Copyright (C) 2011 Jonas Bonn <jonas@southpole.se>
+ */
+
+#ifndef _M68K_SYSCALL_H
+#define _M68K_SYSCALL_H
+
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <asm/unistd.h>
+
+static inline int
+syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+	if (regs->orig_d0 >= 0)
+		return regs->orig_d0;
+	else
+		return -1;
+}
+
+static inline void
+syscall_rollback(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->d0 = regs->orig_d0;
+}
+
+static inline void
+syscall_clear(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->orig_d0 = -1;
+}
+
+static inline void
+syscall_restart(struct task_struct *task, struct pt_regs *regs)
+{
+	syscall_rollback(task, regs);
+	regs->pc -= 2;
+}
+
+static inline void
+syscall_do_restartblock(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->d0 = __NR_restart_syscall;
+	regs->pc -= 2;
+}
+
+static inline long
+syscall_get_error(struct task_struct *task, struct pt_regs *regs)
+{
+	return IS_ERR_VALUE(regs->d0) ? regs->d0 : 0;
+}
+
+static inline long
+syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+	return regs->d0;
+}
+
+static inline void
+syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
+			 int error, long val)
+{
+	regs->d0 = (long) error ?: val;
+}
+
+#if 0
+static inline void
+syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
+		      unsigned int i, unsigned int n, unsigned long *args)
+{
+	/* TODO */
+}
+
+static inline void
+syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
+		      unsigned int i, unsigned int n, const unsigned long *args)
+{
+	/* TODO */
+}
+#endif
+
+#endif
diff --git a/arch/m68k/kernel/signal_mm.c b/arch/m68k/kernel/signal_mm.c
index a0afc23..a8fa041 100644
--- a/arch/m68k/kernel/signal_mm.c
+++ b/arch/m68k/kernel/signal_mm.c
@@ -895,39 +895,6 @@ give_sigsegv:
 	return err;
 }
 
-static inline void
-handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
-{
-	switch (regs->d0) {
-	case -ERESTARTNOHAND:
-		if (!has_handler)
-			goto do_restart;
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTART_RESTARTBLOCK:
-		if (!has_handler) {
-			regs->d0 = __NR_restart_syscall;
-			regs->pc -= 2;
-			break;
-		}
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTARTSYS:
-		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
-			regs->d0 = -EINTR;
-			break;
-		}
-	/* fallthrough */
-	case -ERESTARTNOINTR:
-	do_restart:
-		regs->d0 = regs->orig_d0;
-		regs->pc -= 2;
-		break;
-	}
-}
-
 void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
 {
 	if (regs->orig_d0 < 0)
@@ -951,10 +918,6 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	      sigset_t *oldset, struct pt_regs *regs)
 {
 	int err;
-	/* are we from a system call? */
-	if (regs->orig_d0 >= 0)
-		/* If so, check system call restarting.. */
-		handle_restart(regs, ka, 1);
 
 	/* set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
@@ -998,17 +961,15 @@ asmlinkage void do_signal(struct pt_regs *regs)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	handle_syscall_restart(regs, &ka, (signr > 0));
+
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &ka, &info, oldset, regs);
 		return;
 	}
 
-	/* Did we come from a system call? */
-	if (regs->orig_d0 >= 0)
-		/* Restart the system call - no handlers present */
-		handle_restart(regs, NULL, 0);
-
 	/* If there's no signal to deliver, we just restore the saved mask.  */
 	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
 		clear_thread_flag(TIF_RESTORE_SIGMASK);
diff --git a/arch/m68k/kernel/signal_no.c b/arch/m68k/kernel/signal_no.c
index 36a81bb..2fad7c7 100644
--- a/arch/m68k/kernel/signal_no.c
+++ b/arch/m68k/kernel/signal_no.c
@@ -653,39 +653,6 @@ give_sigsegv:
 	goto adjust_stack;
 }
 
-static inline void
-handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
-{
-	switch (regs->d0) {
-	case -ERESTARTNOHAND:
-		if (!has_handler)
-			goto do_restart;
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTART_RESTARTBLOCK:
-		if (!has_handler) {
-			regs->d0 = __NR_restart_syscall;
-			regs->pc -= 2;
-			break;
-		}
-		regs->d0 = -EINTR;
-		break;
-
-	case -ERESTARTSYS:
-		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
-			regs->d0 = -EINTR;
-			break;
-		}
-	/* fallthrough */
-	case -ERESTARTNOINTR:
-	do_restart:
-		regs->d0 = regs->orig_d0;
-		regs->pc -= 2;
-		break;
-	}
-}
-
 /*
  * OK, we're invoking a handler
  */
@@ -694,10 +661,6 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	      sigset_t *oldset, struct pt_regs *regs)
 {
 	int err;
-	/* are we from a system call? */
-	if (regs->orig_d0 >= 0)
-		/* If so, check system call restarting.. */
-		handle_restart(regs, ka, 1);
 
 	/* set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
@@ -745,18 +708,15 @@ asmlinkage void do_signal(struct pt_regs *regs)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	handle_syscall_restart(regs, &ka, (signr > 0));
+
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &ka, &info, oldset, regs);
 		return;
 	}
 
-	/* Did we come from a system call? */
-	if (regs->orig_d0 >= 0) {
-		/* Restart the system call - no handlers present */
-		handle_restart(regs, NULL, 0);
-	}
-
 	/* If there's no signal to deliver, we just restore the saved mask.  */
 	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
 		clear_thread_flag(TIF_RESTORE_SIGMASK);
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH RFC 4/8] mips: implement syscall restart generically
From: Jonas Bonn @ 2011-10-23 10:19 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn, linux-mips
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating task state to effect re-execution of an interrupted syscall
used to be purely architecture specific code.  However, as most arch's
were essentially just making minor adjustments to almost identical logic,
this code could be moved to a common implementation.

The generic variant introduces the function handle_syscall_restart() to be
called after get_signal_to_deliver().  The architecture specific register
manipulations required to effect the actual restart are now implemented
in the generic syscall interface found in asm/syscall.h

This patch transitions this architecture's signal handling code over to
using the generic syscall restart code by:

i)  Implementing the register manipulations in asm/syscall.h
ii) Replacing the restart logic with a call to handle_syscall_restart

Cc: linux-mips@linux-mips.org
Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 arch/mips/include/asm/syscall.h |   91 +++++++++++++++++++++++++++++++++++++++
 arch/mips/kernel/signal.c       |   40 +----------------
 2 files changed, 94 insertions(+), 37 deletions(-)
 create mode 100644 arch/mips/include/asm/syscall.h

diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h
new file mode 100644
index 0000000..7280d95
--- /dev/null
+++ b/arch/mips/include/asm/syscall.h
@@ -0,0 +1,91 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Copyright (C) 2011 Jonas Bonn <jonas@southpole.se>
+ */
+
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H
+
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <asm/unistd.h>
+
+static inline int
+syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+	return regs->regs[0] ?: -1;
+}
+
+static inline void
+syscall_rollback(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->regs[2] = regs->regs[0];
+	regs->regs[7] = regs->regs[26];
+}
+
+static inline void
+syscall_clear(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->regs[0] = 0;
+}
+
+static inline void
+syscall_restart(struct task_struct *task, struct pt_regs *regs)
+{
+	syscall_rollback(task, regs);
+	regs->cp0_epc -= 4;
+}
+
+static inline void
+syscall_do_restartblock(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->regs[2] = current->thread.abi->restart;
+	regs->regs[7] = regs->regs[26];
+	regs->cp0_epc -= 4;
+}
+
+static inline long
+syscall_get_error(struct task_struct *task, struct pt_regs *regs)
+{
+	/*
+	 * r7 == 1 if syscall returns error
+	 * r2 contains _positive_ result
+	 */
+	if (regs->regs[7])
+		return -regs->regs[2];
+	else
+		return 0;
+}
+
+static inline long
+syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+	return regs->gpr[2];
+}
+
+static inline void
+syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
+			 int error, long val)
+{
+	regs->gpr[2] = (long) error ? -error : val;
+}
+
+static inline void
+syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
+		      unsigned int i, unsigned int n, unsigned long *args)
+{
+	/* TODO */
+}
+
+static inline void
+syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
+		      unsigned int i, unsigned int n, const unsigned long *args)
+{
+	/* TODO */
+}
+
+#endif
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index dbbe0ce..13f2864 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -547,27 +547,6 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
 	struct mips_abi *abi = current->thread.abi;
 	void *vdso = current->mm->context.vdso;
 
-	if (regs->regs[0]) {
-		switch(regs->regs[2]) {
-		case ERESTART_RESTARTBLOCK:
-		case ERESTARTNOHAND:
-			regs->regs[2] = EINTR;
-			break;
-		case ERESTARTSYS:
-			if (!(ka->sa.sa_flags & SA_RESTART)) {
-				regs->regs[2] = EINTR;
-				break;
-			}
-		/* fallthrough */
-		case ERESTARTNOINTR:
-			regs->regs[7] = regs->regs[26];
-			regs->regs[2] = regs->regs[0];
-			regs->cp0_epc -= 4;
-		}
-
-		regs->regs[0] = 0;		/* Don't deal with this again.  */
-	}
-
 	if (sig_uses_siginfo(ka))
 		ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
 					  ka, regs, sig, oldset, info);
@@ -609,6 +588,9 @@ static void do_signal(struct pt_regs *regs)
 		oldset = &current->blocked;
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	handle_syscall_restart(regs, &ka, (signr > 0));
+
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
@@ -625,22 +607,6 @@ static void do_signal(struct pt_regs *regs)
 		return;
 	}
 
-	if (regs->regs[0]) {
-		if (regs->regs[2] == ERESTARTNOHAND ||
-		    regs->regs[2] == ERESTARTSYS ||
-		    regs->regs[2] == ERESTARTNOINTR) {
-			regs->regs[2] = regs->regs[0];
-			regs->regs[7] = regs->regs[26];
-			regs->cp0_epc -= 4;
-		}
-		if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
-			regs->regs[2] = current->thread.abi->restart;
-			regs->regs[7] = regs->regs[26];
-			regs->cp0_epc -= 4;
-		}
-		regs->regs[0] = 0;	/* Don't deal with this again.  */
-	}
-
 	/*
 	 * If there's no signal to deliver, we just put the saved sigmask
 	 * back
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH RFC 1/8] signal: introduce generic syscall restart logic
From: Jonas Bonn @ 2011-10-23 10:19 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn
In-Reply-To: <cover.1319364492.git.jonas@southpole.se>


Manipulating the task state so that an interrupted syscall will be
re-executed after signal handling has historically been purely architecture
specific logic.  Most architectures, however, are implementing essentially
the same thing (some incorrectly) with the actual details of the registers
to be manipulated being the only relevant difference.

This patch introduces generic code for handling the syscall restart logic
by:

i)  introducing methods for doing the actual register manipulations to
the generic syscall interface in asm/syscall.h

ii) introducing the function handle_syscall_restart to determine the
actual restart requirements and invoke the required register manipulations;
this function is designed to be called immediately after invoking the
function get_signal_to_deliver

This generic variant is applicable for any architecture that maintains the
information necessary to effect a syscall restart in its pt_regs struct.

Signed-off-by: Jonas Bonn <jonas@southpole.se>
---
 include/asm-generic/syscall.h |   46 +++++++++++++++++++++++++-
 include/linux/signal.h        |    3 ++
 kernel/signal.c               |   72 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 119 insertions(+), 2 deletions(-)

diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h
index 5c122ae..b7b489f 100644
--- a/include/asm-generic/syscall.h
+++ b/include/asm-generic/syscall.h
@@ -36,11 +36,55 @@ struct pt_regs;
  * system call number can be meaningful.  If the actual arch value
  * is 64 bits, this truncates to 32 bits so 0xffffffff means -1.
  *
- * It's only valid to call this when @task is known to be blocked.
+ * It's only valid to call this for the current task or when @task
+ * is known to be blocked.
  */
 int syscall_get_nr(struct task_struct *task, struct pt_regs *regs);
 
 /**
+ * syscall_clear - clear the syscall execution state
+ *
+ * Clear the syscall execution state of @task so that future invocations
+ * of syscall_get_nr for @task return -1.
+ *
+ * It's only valid to call this for the current task.  This function
+ * is primarily intended for use in the signal handling path; when
+ * signal handling takes over after a syscall then the syscall handling
+ * is effectively finished and the syscall state can be cleared.
+ */
+void syscall_clear(struct task_struct *task, struct pt_regs *regs);
+
+/**
+ * syscall_do_restart - roll back PC and argument regs for syscall restart
+ * @task:	must be current task
+ * @regs:	task_pt_regs() of @task
+ * 
+ * Rolls back the syscall number, arguments, and the instruction pointer
+ * so that the current syscall will be reexecuted upon return to userspace.
+ *
+ * This function is primarily intended for use in the signal handling
+ * code and shouldn't really be used elsewhere.
+ */
+void syscall_restart(struct task_struct *task, struct pt_regs *regs);
+
+/**
+ * syscall_do_restartblock - roll back PC and execute restart_syscall
+ * @task:	must be current task
+ * @regs:	task_pt_regs() of @task
+ * 
+ * Configure @task so that upon return to userspace the restart_syscall
+ * (or equivalent) function is executed to perform syscall restart via a
+ * restart_block.  Since restart_syscall normally doesn't take any arguments,
+ * restoring the syscall arguments can be skipped.  This normally boils
+ * down to rewinding the PC and setting the syscall register to 
+ * __NR_restart_syscall; however, some arch's may do this differently.
+ *
+ * This function is primarily intended for use in the signal handling
+ * code.
+ */
+void syscall_do_restartblock(struct task_struct * taks, struct pt_regs* regs);
+
+/**
  * syscall_rollback - roll back registers after an aborted system call
  * @task:	task of interest, must be in system call exit tracing
  * @regs:	task_pt_regs() of @task
diff --git a/include/linux/signal.h b/include/linux/signal.h
index a822300..7ede592 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -256,6 +256,9 @@ extern int show_unhandled_signals;
 extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
 extern void exit_signals(struct task_struct *tsk);
 
+void handle_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
+			    int has_handler);
+
 extern struct kmem_cache *sighand_cachep;
 
 int unhandled_signal(struct task_struct *tsk, int sig);
diff --git a/kernel/signal.c b/kernel/signal.c
index 291c970..7b3d9a4 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -33,8 +33,8 @@
 
 #include <asm/param.h>
 #include <asm/uaccess.h>
-#include <asm/unistd.h>
 #include <asm/siginfo.h>
+#include <asm/syscall.h>
 #include "audit.h"	/* audit_signal_info() */
 
 /*
@@ -2396,6 +2396,76 @@ EXPORT_SYMBOL(sigprocmask);
 EXPORT_SYMBOL(block_all_signals);
 EXPORT_SYMBOL(unblock_all_signals);
 
+/**
+ * handle_syscall_restart();
+ * @regs: pt_regs for current process
+ * @ka:   k_sigaction struct for current signal handler 
+ * @has_handler: boolean indicating whether there is a handler waiting
+ *               to be invoked for a pending signal
+ *
+ * Prepare the currently executing task to restart an interrupted
+ * syscall.  After completion of this function, the task is effectively
+ * switched from syscall-execution mode to signal-processing mode and
+ * further attempts to manipulate the syscall state will fail.
+ *
+ * If has_handler != 0, then ka must point to a valid sigaction struct.
+ */
+
+void handle_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
+			    int has_handler)
+{
+	/* Are we from a system call? */
+	if (syscall_get_nr(current, regs) >= 0) {
+		int restart = 1;
+		long error;
+
+		error = syscall_get_error(current, regs);
+
+		/* Check if syscall was interrupted. */
+		switch (error) {
+		case -ERESTART_RESTARTBLOCK:
+		case -ERESTARTNOHAND:
+			/* Restart if there is no handler */
+			restart = !has_handler;
+			break;
+
+		case -ERESTARTSYS:
+			/*
+			 * Restart if there is no handler or if the handler
+			 * was registered with SA_RESTART
+			 */
+			restart = !has_handler
+				  || (ka->sa.sa_flags & SA_RESTART);
+			break;
+
+		case -ERESTARTNOINTR:
+			/* Restart after signal handler returns */ 
+			restart = 1;
+			break;
+
+		default:
+			/* Syscall wasn't interrupted so we're done with it */
+			syscall_clear(current, regs);
+			return;
+		}
+
+		if (restart) {
+			if (error == -ERESTART_RESTARTBLOCK)
+				syscall_do_restartblock(current, regs);
+			else
+				syscall_restart(current, regs);
+		} else {
+			syscall_set_return_value(current, regs, -EINTR, 0);
+		}
+
+		/*
+		 * The syscall processing is effectively complete here so
+		 * the syscall state can be cleared to prevent this function
+		 * from triggering again for nested signals.
+		 */
+		syscall_clear(current, regs);
+	}
+}
 
 /*
  * System call entry points.
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH RFC 0/8] Signal: harmonize syscall restart logic
From: Jonas Bonn @ 2011-10-23 10:19 UTC (permalink / raw)
  To: linux-kernel, linux-arch; +Cc: Jonas Bonn


I've been looking into trying to harmonize the architecture specific
signal handling code.  With a couple of helper functions to mask some
of the architecture specific bits, the code for do_signal and handle_signal
(implemented by essentially everybody) start to look identical across
all arch's and could likely be made generic.

The big helper is the one in this series.  This one moves the syscall
restart logic out to a common helper.  The arch specific bit here is
the register manipulations required to actually effect the restart;
this patch series moves those manipulations to the asm/syscall.h header
which already attempts to define a generic syscall interface for several
arch's today.

Where this series remains an RFC is due to a couple of open questions:

i)  ARM (and a few arch's copied from it) does its restart logic in two
    steps so that a debugger can intervene; is there still value in
    this approach or would the single step approach in this patch series
    be sufficient for ARM (and others)?

ii) The syscall.h interface requires that the information needed to do
    the register manipulations be in the pt_regs struct.  This isn't
    the case for all arch's today.  Are there any issues with putting that
    info into pt_regs for those arch's?

With the rest of the cleanups in this series it currently comes to 64
patches, so I'm just posting a couple of the syscall restart patches
now for comment in order not to flood the lists.  I'll post the remainder
of the series later based on the feedback from this series.

/Jonas

Jonas Bonn (8):
  signal: introduce generic syscall restart logic
  blackfin: implement syscall restart generically
  frv: implement syscall restart generically
  mips: implement syscall restart generically
  x86: implement syscall restart generically
  m68k: implement syscall restart generically
  ia64: implement syscall restart generically
  tile: implement syscall restart generically

 arch/blackfin/include/asm/syscall.h |   26 +++++++++-
 arch/blackfin/kernel/signal.c       |   47 +-----------------
 arch/frv/include/asm/syscall.h      |   23 ++++++++-
 arch/frv/kernel/signal.c            |   48 +-----------------
 arch/ia64/include/asm/syscall.h     |   21 ++++++++
 arch/ia64/kernel/signal.c           |   54 +--------------------
 arch/m68k/include/asm/syscall.h     |   87 +++++++++++++++++++++++++++++++++
 arch/m68k/kernel/signal_mm.c        |   45 +----------------
 arch/m68k/kernel/signal_no.c        |   46 +----------------
 arch/mips/include/asm/syscall.h     |   91 +++++++++++++++++++++++++++++++++++
 arch/mips/kernel/signal.c           |   40 +--------------
 arch/tile/include/asm/syscall.h     |   28 ++++++++++-
 arch/tile/kernel/signal.c           |   52 ++------------------
 arch/x86/include/asm/syscall.h      |   21 ++++++++
 arch/x86/kernel/signal.c            |   43 +---------------
 include/asm-generic/syscall.h       |   46 +++++++++++++++++-
 include/linux/signal.h              |    3 +
 kernel/signal.c                     |   72 +++++++++++++++++++++++++++-
 18 files changed, 435 insertions(+), 358 deletions(-)
 create mode 100644 arch/m68k/include/asm/syscall.h
 create mode 100644 arch/mips/include/asm/syscall.h

-- 
1.7.5.4

^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.