--- /dev/null
+From stable-bounces@linux.kernel.org Tue May 13 01:24:07 2008
+From: Tejun Heo <htejun@gmail.com>
+Date: Tue, 13 May 2008 17:23:38 +0900
+Subject: ata_piix: verify SIDPR access before enabling it
+To: stable@kernel.org, Jeff Garzik l <jeff@garzik.org>, IDE/ATA development list <linux-ide@vger.kernel.org>
+Message-ID: <4829500A.7060506@gmail.com>
+
+From: Tejun Heo <htejun@gmail.com>
+
+commit cb6716c879ecf49e2af344926c6a476821812061 upstream
+
+On certain configurations (certain macbooks), even though all the
+conditions for SIDPR access described in the datasheet are met,
+actually reading those registers just returns 0 and have no effect on
+write. Verify SIDPR is actually working before enabling it.
+
+This is reported by Ryan Roth in bz#10512.
+
+Signed-off-by: Tejun Heo <htejun@gmail.com>
+Cc: Ryan Roth <ryan.roth@ch2m.com>
+Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ata/ata_piix.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/drivers/ata/ata_piix.c
++++ b/drivers/ata/ata_piix.c
+@@ -1531,6 +1531,8 @@ static void __devinit piix_init_sidpr(st
+ {
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ struct piix_host_priv *hpriv = host->private_data;
++ struct ata_device *dev0 = &host->ports[0]->link.device[0];
++ u32 scontrol;
+ int i;
+
+ /* check for availability */
+@@ -1549,6 +1551,29 @@ static void __devinit piix_init_sidpr(st
+ return;
+
+ hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
++
++ /* SCR access via SIDPR doesn't work on some configurations.
++ * Give it a test drive by inhibiting power save modes which
++ * we'll do anyway.
++ */
++ scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
++
++ /* if IPM is already 3, SCR access is probably working. Don't
++ * un-inhibit power save modes as BIOS might have inhibited
++ * them for a reason.
++ */
++ if ((scontrol & 0xf00) != 0x300) {
++ scontrol |= 0x300;
++ piix_sidpr_write(dev0, SCR_CONTROL, scontrol);
++ scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
++
++ if ((scontrol & 0xf00) != 0x300) {
++ dev_printk(KERN_INFO, host->dev, "SCR access via "
++ "SIDPR is available but doesn't work\n");
++ return;
++ }
++ }
++
+ host->ports[0]->ops = &piix_sidpr_sata_ops;
+ host->ports[1]->ops = &piix_sidpr_sata_ops;
+ }
--- /dev/null
+From stable-bounces@linux.kernel.org Mon May 12 08:34:37 2008
+From: Jean Delvare <khali@linux-fr.org>
+Date: Mon, 12 May 2008 16:21:24 +0200
+Subject: i2c-piix4: Blacklist two mainboards
+To: stable@kernel.org
+Message-ID: <20080512162124.21baa05f@hyperion.delvare>
+
+From: Jean Delvare <khali@linux-fr.org>
+
+commit c2fc54fcd340cbee47510aa84c346aab3440ba09 upstream
+
+We had a report that running sensors-detect on a Sapphire AM2RD790
+motherbord killed the CPU. While the exact cause is still unknown,
+I'd rather play it safe and prevent any access to the SMBus on that
+machine by not letting the i2c-piix4 driver attach to the SMBus host
+device on that machine. Also blacklist a similar board made by DFI.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/busses/i2c-piix4.c | 32 ++++++++++++++++++++++++++++++--
+ 1 file changed, 30 insertions(+), 2 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-piix4.c
++++ b/drivers/i2c/busses/i2c-piix4.c
+@@ -108,7 +108,27 @@ static unsigned short piix4_smba;
+ static struct pci_driver piix4_driver;
+ static struct i2c_adapter piix4_adapter;
+
+-static struct dmi_system_id __devinitdata piix4_dmi_table[] = {
++static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = {
++ {
++ .ident = "Sapphire AM2RD790",
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."),
++ DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"),
++ },
++ },
++ {
++ .ident = "DFI Lanparty UT 790FX",
++ .matches = {
++ DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."),
++ DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"),
++ },
++ },
++ { }
++};
++
++/* The IBM entry is in a separate table because we only check it
++ on Intel-based systems */
++static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = {
+ {
+ .ident = "IBM",
+ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
+@@ -123,8 +143,16 @@ static int __devinit piix4_setup(struct
+
+ dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
+
++ /* On some motherboards, it was reported that accessing the SMBus
++ caused severe hardware problems */
++ if (dmi_check_system(piix4_dmi_blacklist)) {
++ dev_err(&PIIX4_dev->dev,
++ "Accessing the SMBus on this system is unsafe!\n");
++ return -EPERM;
++ }
++
+ /* Don't access SMBus on IBM systems which get corrupted eeproms */
+- if (dmi_check_system(piix4_dmi_table) &&
++ if (dmi_check_system(piix4_dmi_ibm) &&
+ PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
+ dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
+ "may corrupt your serial eeprom! Refusing to load "
--- /dev/null
+From stable-bounces@linux.kernel.org Tue May 13 05:11:11 2008
+From: Philip Craig <philipc@snapgear.com>
+Date: Tue, 13 May 2008 13:39:13 +0200
+Subject: nf_conntrack: padding breaks conntrack hash on ARM
+To: stable@kernel.org
+Cc: Netfilter Development Mailinglist <netfilter-devel@vger.kernel.org>, "David S. Miller" <davem@davemloft.net>
+Message-ID: <48297DE1.901@trash.net>
+
+From: Philip Craig <philipc@snapgear.com>
+
+[NETFILTER]: nf_conntrack: padding breaks conntrack hash on ARM
+
+Upstream commit 443a70d50:
+
+commit 0794935e "[NETFILTER]: nf_conntrack: optimize hash_conntrack()"
+results in ARM platforms hashing uninitialised padding. This padding
+doesn't exist on other architectures.
+
+Fix this by replacing NF_CT_TUPLE_U_BLANK() with memset() to ensure
+everything is initialised. There were only 4 bytes that
+NF_CT_TUPLE_U_BLANK() wasn't clearing anyway (or 12 bytes on ARM).
+
+Signed-off-by: Philip Craig <philipc@snapgear.com>
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/net/netfilter/nf_conntrack_tuple.h | 10 ----------
+ net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 2 +-
+ net/netfilter/nf_conntrack_core.c | 4 ++--
+ 3 files changed, 3 insertions(+), 13 deletions(-)
+
+--- a/include/net/netfilter/nf_conntrack_tuple.h
++++ b/include/net/netfilter/nf_conntrack_tuple.h
+@@ -101,16 +101,6 @@ struct nf_conntrack_tuple_mask
+ } src;
+ };
+
+-/* This is optimized opposed to a memset of the whole structure. Everything we
+- * really care about is the source/destination unions */
+-#define NF_CT_TUPLE_U_BLANK(tuple) \
+- do { \
+- (tuple)->src.u.all = 0; \
+- (tuple)->dst.u.all = 0; \
+- memset(&(tuple)->src.u3, 0, sizeof((tuple)->src.u3)); \
+- memset(&(tuple)->dst.u3, 0, sizeof((tuple)->dst.u3)); \
+- } while (0)
+-
+ #ifdef __KERNEL__
+
+ #define NF_CT_DUMP_TUPLE(tp) \
+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+@@ -305,7 +305,7 @@ getorigdst(struct sock *sk, int optval,
+ const struct nf_conntrack_tuple_hash *h;
+ struct nf_conntrack_tuple tuple;
+
+- NF_CT_TUPLE_U_BLANK(&tuple);
++ memset(&tuple, 0, sizeof(tuple));
+ tuple.src.u3.ip = inet->rcv_saddr;
+ tuple.src.u.tcp.port = inet->sport;
+ tuple.dst.u3.ip = inet->daddr;
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -104,7 +104,7 @@ nf_ct_get_tuple(const struct sk_buff *sk
+ const struct nf_conntrack_l3proto *l3proto,
+ const struct nf_conntrack_l4proto *l4proto)
+ {
+- NF_CT_TUPLE_U_BLANK(tuple);
++ memset(tuple, 0, sizeof(*tuple));
+
+ tuple->src.l3num = l3num;
+ if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0)
+@@ -153,7 +153,7 @@ nf_ct_invert_tuple(struct nf_conntrack_t
+ const struct nf_conntrack_l3proto *l3proto,
+ const struct nf_conntrack_l4proto *l4proto)
+ {
+- NF_CT_TUPLE_U_BLANK(inverse);
++ memset(inverse, 0, sizeof(*inverse));
+
+ inverse->src.l3num = orig->src.l3num;
+ if (l3proto->invert_tuple(inverse, orig) == 0)
--- /dev/null
+From stable-bounces@linux.kernel.org Tue May 13 05:11:11 2008
+From: Arnaud Ebalard <arno@natisbad.org>
+Date: Tue, 13 May 2008 13:39:16 +0200
+Subject: {nfnetlink, ip, ip6}_queue: fix skb_over_panic when enlarging packets
+To: stable@kernel.org
+Cc: Netfilter Development Mailinglist <netfilter-devel@vger.kernel.org>, "David S. Miller" <davem@davemloft.net>
+Message-ID: <48297DE4.6070001@trash.net>
+
+From: Arnaud Ebalard <arno@natisbad.org>
+
+[NETFILTER]: {nfnetlink,ip,ip6}_queue: fix skb_over_panic when enlarging packets
+
+From: Arnaud Ebalard <arno@natisbad.org>
+
+Upstream commit 9a732ed6d:
+
+While reinjecting *bigger* modified versions of IPv6 packets using
+libnetfilter_queue, things work fine on a 2.6.24 kernel (2.6.22 too)
+but I get the following on recents kernels (2.6.25, trace below is
+against today's net-2.6 git tree):
+
+skb_over_panic: text:c04fddb0 len:696 put:632 head:f7592c00 data:f7592c00 tail:0xf7592eb8 end:0xf7592e80 dev:eth0
+------------[ cut here ]------------
+invalid opcode: 0000 [#1] PREEMPT
+Process sendd (pid: 3657, ti=f6014000 task=f77c31d0 task.ti=f6014000)
+Stack: c071e638 c04fddb0 000002b8 00000278 f7592c00 f7592c00 f7592eb8 f7592e80
+ f763c000 f6bc5200 f7592c40 f6015c34 c04cdbfc f6bc5200 00000278 f6015c60
+ c04fddb0 00000020 f72a10c0 f751b420 00000001 0000000a 000002b8 c065582c
+Call Trace:
+ [<c04fddb0>] ? nfqnl_recv_verdict+0x1c0/0x2e0
+ [<c04cdbfc>] ? skb_put+0x3c/0x40
+ [<c04fddb0>] ? nfqnl_recv_verdict+0x1c0/0x2e0
+ [<c04fd115>] ? nfnetlink_rcv_msg+0xf5/0x160
+ [<c04fd03e>] ? nfnetlink_rcv_msg+0x1e/0x160
+ [<c04fd020>] ? nfnetlink_rcv_msg+0x0/0x160
+ [<c04f8ed7>] ? netlink_rcv_skb+0x77/0xa0
+ [<c04fcefc>] ? nfnetlink_rcv+0x1c/0x30
+ [<c04f8c73>] ? netlink_unicast+0x243/0x2b0
+ [<c04cfaba>] ? memcpy_fromiovec+0x4a/0x70
+ [<c04f9406>] ? netlink_sendmsg+0x1c6/0x270
+ [<c04c8244>] ? sock_sendmsg+0xc4/0xf0
+ [<c011970d>] ? set_next_entity+0x1d/0x50
+ [<c0133a80>] ? autoremove_wake_function+0x0/0x40
+ [<c0118f9e>] ? __wake_up_common+0x3e/0x70
+ [<c0342fbf>] ? n_tty_receive_buf+0x34f/0x1280
+ [<c011d308>] ? __wake_up+0x68/0x70
+ [<c02cea47>] ? copy_from_user+0x37/0x70
+ [<c04cfd7c>] ? verify_iovec+0x2c/0x90
+ [<c04c837a>] ? sys_sendmsg+0x10a/0x230
+ [<c011967a>] ? __dequeue_entity+0x2a/0xa0
+ [<c011970d>] ? set_next_entity+0x1d/0x50
+ [<c0345397>] ? pty_write+0x47/0x60
+ [<c033d59b>] ? tty_default_put_char+0x1b/0x20
+ [<c011d2e9>] ? __wake_up+0x49/0x70
+ [<c033df99>] ? tty_ldisc_deref+0x39/0x90
+ [<c033ff20>] ? tty_write+0x1a0/0x1b0
+ [<c04c93af>] ? sys_socketcall+0x7f/0x260
+ [<c0102ff9>] ? sysenter_past_esp+0x6a/0x91
+ [<c05f0000>] ? snd_intel8x0m_probe+0x270/0x6e0
+ =======================
+Code: 00 00 89 5c 24 14 8b 98 9c 00 00 00 89 54 24 0c 89 5c 24 10 8b 40 50 89 4c 24 04 c7 04 24 38 e6 71 c0 89 44 24 08 e8 c4 46 c5 ff <0f> 0b eb fe 55 89 e5 56 89 d6 53 89 c3 83 ec 0c 8b 40 50 39 d0
+EIP: [<c04ccdfc>] skb_over_panic+0x5c/0x60 SS:ESP 0068:f6015bf8
+
+Looking at the code, I ended up in nfq_mangle() function (called by
+nfqnl_recv_verdict()) which performs a call to skb_copy_expand() due to
+the increased size of data passed to the function. AFAICT, it should ask
+for 'diff' instead of 'diff - skb_tailroom(e->skb)'. Because the
+resulting sk_buff has not enough space to support the skb_put(skb, diff)
+call a few lines later, this results in the call to skb_over_panic().
+
+The patch below asks for allocation of a copy with enough space for
+mangled packet and the same amount of headroom as old sk_buff. While
+looking at how the regression appeared (e2b58a67), I noticed the same
+pattern in ipq_mangle_ipv6() and ipq_mangle_ipv4(). The patch corrects
+those locations too.
+
+Tested with bigger reinjected IPv6 packets (nfqnl_mangle() path), things
+are ok (2.6.25 and today's net-2.6 git tree).
+
+Signed-off-by: Arnaud Ebalard <arno@natisbad.org>
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ net/ipv4/netfilter/ip_queue.c | 5 ++---
+ net/ipv6/netfilter/ip6_queue.c | 5 ++---
+ net/netfilter/nfnetlink_queue.c | 5 ++---
+ 3 files changed, 6 insertions(+), 9 deletions(-)
+
+--- a/net/ipv4/netfilter/ip_queue.c
++++ b/net/ipv4/netfilter/ip_queue.c
+@@ -296,9 +296,8 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, st
+ if (v->data_len > 0xFFFF)
+ return -EINVAL;
+ if (diff > skb_tailroom(e->skb)) {
+- nskb = skb_copy_expand(e->skb, 0,
+- diff - skb_tailroom(e->skb),
+- GFP_ATOMIC);
++ nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
++ diff, GFP_ATOMIC);
+ if (!nskb) {
+ printk(KERN_WARNING "ip_queue: error "
+ "in mangle, dropping packet\n");
+--- a/net/ipv6/netfilter/ip6_queue.c
++++ b/net/ipv6/netfilter/ip6_queue.c
+@@ -298,9 +298,8 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, st
+ if (v->data_len > 0xFFFF)
+ return -EINVAL;
+ if (diff > skb_tailroom(e->skb)) {
+- nskb = skb_copy_expand(e->skb, 0,
+- diff - skb_tailroom(e->skb),
+- GFP_ATOMIC);
++ nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
++ diff, GFP_ATOMIC);
+ if (!nskb) {
+ printk(KERN_WARNING "ip6_queue: OOM "
+ "in mangle, dropping packet\n");
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -454,9 +454,8 @@ nfqnl_mangle(void *data, int data_len, s
+ if (data_len > 0xFFFF)
+ return -EINVAL;
+ if (diff > skb_tailroom(e->skb)) {
+- nskb = skb_copy_expand(e->skb, 0,
+- diff - skb_tailroom(e->skb),
+- GFP_ATOMIC);
++ nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
++ diff, GFP_ATOMIC);
+ if (!nskb) {
+ printk(KERN_WARNING "nf_queue: OOM "
+ "in mangle, dropping packet\n");
dccp-return-einval-on-invalid-feature-length.patch
can-fix-can_send-handling-on-dev_queue_xmit-failures.patch
x86-use-defconfigs-from-x86-configs.patch
+nf_conntrack-padding-breaks-conntrack-hash-on-arm.patch
+nfnetlink-ip-ip6-_queue-fix-skb_over_panic-when-enlarging-packets.patch
+ata_piix-verify-sidpr-access-before-enabling-it.patch
+x86-sysfs-cpu-topology-is-empty-in-2.6.25.patch
+i2c-piix4-blacklist-two-mainboards.patch
+sparc-fix-ptrace-detach.patch
+sparc-fix-mremap-address-range-validation.patch
+sparc-fix-debugger-syscall-restart-interactions.patch
+sparc32-don-t-twiddle-pt_dtrace-in-exec.patch
+usb-airprime-unlock-mutex-instead-of-trying-to-lock-it-again.patch
--- /dev/null
+From da98a7f13a001b4f7c7617107a5a044092770d55 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Sun, 11 May 2008 19:35:21 -0700
+Subject: [PATCH] sparc: Fix debugger syscall restart interactions.
+
+From: David S. Miller <davem@davemloft.net>
+
+[ This is a 2.6.25 backport of upstream changeset
+ 28e6103665301ce60634e8a77f0b657c6cc099de with sparc32 build
+ fixes from Robert Reif ]
+
+So, forever, we've had this ptrace_signal_deliver implementation
+which tries to handle all of the nasties that can occur when the
+debugger looks at a process about to take a signal. It's meant
+to address all of these issues inside of the kernel so that the
+debugger need not be mindful of such things.
+
+Problem is, this doesn't work.
+
+The idea was that we should do the syscall restart business first, so
+that the debugger captures that state. Otherwise, if the debugger for
+example saves the child's state, makes the child execute something
+else, then restores the saved state, we won't handle the syscall
+restart properly because we lose the "we're in a syscall" state.
+
+The code here worked for most cases, but if the debugger actually
+passes the signal through to the child unaltered, it's possible that
+we would do a syscall restart when we shouldn't have.
+
+In particular this breaks the case of debugging a process under a gdb
+which is being debugged by yet another gdb. gdb uses sigsuspend
+to wait for SIGCHLD of the inferior, but if gdb itself is being
+debugged by a top-level gdb we get a ptrace_stop(). The top-level gdb
+does a PTRACE_CONT with SIGCHLD to let the inferior gdb see the
+signal. But ptrace_signal_deliver() assumed the debugger would cancel
+out the signal and therefore did a syscall restart, because the return
+error was ERESTARTNOHAND.
+
+Fix this by simply making ptrace_signal_deliver() a nop, and providing
+a way for the debugger to control system call restarting properly:
+
+1) Report a "in syscall" software bit in regs->{tstate,psr}.
+ It is set early on in trap entry to a system call and is fully
+ visible to the debugger via ptrace() and regsets.
+
+2) Test this bit right before doing a syscall restart. We have
+ to do a final recheck right after get_signal_to_deliver() in
+ case the debugger cleared the bit during ptrace_stop().
+
+3) Clear the bit in trap return so we don't accidently try to set
+ that bit in the real register.
+
+As a result we also get a ptrace_{is,clear}_syscall() for sparc32 just
+like sparc64 has.
+
+M68K has this same exact bug, and is now the only other user of the
+ptrace_signal_deliver hook. It needs to be fixed in the same exact
+way as sparc.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/sparc/kernel/entry.S | 2 +
+ arch/sparc/kernel/ptrace.c | 4 +-
+ arch/sparc/kernel/rtrap.S | 11 ++++--
+ arch/sparc/kernel/signal.c | 64 ++++++++++++++++---------------------
+ arch/sparc64/kernel/etrap.S | 7 ++--
+ arch/sparc64/kernel/ptrace.c | 12 ++++--
+ arch/sparc64/kernel/rtrap.S | 1
+ arch/sparc64/kernel/signal.c | 69 +++++++++++++++++-----------------------
+ arch/sparc64/kernel/signal32.c | 30 +++++++++++------
+ include/asm-sparc/psr.h | 1
+ include/asm-sparc/ptrace.h | 12 ++++++
+ include/asm-sparc/signal.h | 8 ----
+ include/asm-sparc64/psrcompat.h | 2 +
+ include/asm-sparc64/pstate.h | 1
+ include/asm-sparc64/ptrace.h | 12 ++++++
+ include/asm-sparc64/signal.h | 8 ----
+ include/asm-sparc64/ttable.h | 7 ++--
+ 17 files changed, 136 insertions(+), 115 deletions(-)
+
+--- a/arch/sparc64/kernel/etrap.S
++++ b/arch/sparc64/kernel/etrap.S
+@@ -27,11 +27,12 @@
+
+ .text
+ .align 64
+- .globl etrap, etrap_irq, etraptl1
++ .globl etrap_syscall, etrap, etrap_irq, etraptl1
+ etrap: rdpr %pil, %g2
+-etrap_irq:
+- TRAP_LOAD_THREAD_REG(%g6, %g1)
++etrap_irq: clr %g3
++etrap_syscall: TRAP_LOAD_THREAD_REG(%g6, %g1)
+ rdpr %tstate, %g1
++ or %g1, %g3, %g1
+ sllx %g2, 20, %g3
+ andcc %g1, TSTATE_PRIV, %g0
+ or %g1, %g3, %g1
+--- a/arch/sparc64/kernel/ptrace.c
++++ b/arch/sparc64/kernel/ptrace.c
+@@ -287,11 +287,11 @@ static int genregs64_set(struct task_str
+ 32 * sizeof(u64),
+ 33 * sizeof(u64));
+ if (!ret) {
+- /* Only the condition codes can be modified
+- * in the %tstate register.
++ /* Only the condition codes and the "in syscall"
++ * state can be modified in the %tstate register.
+ */
+- tstate &= (TSTATE_ICC | TSTATE_XCC);
+- regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
++ tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
++ regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
+ regs->tstate |= tstate;
+ }
+ }
+@@ -657,8 +657,10 @@ static int genregs32_set(struct task_str
+ switch (pos) {
+ case 32: /* PSR */
+ tstate = regs->tstate;
+- tstate &= ~(TSTATE_ICC | TSTATE_XCC);
++ tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
+ tstate |= psr_to_tstate_icc(reg);
++ if (reg & PSR_SYSCALL)
++ tstate |= TSTATE_SYSCALL;
+ regs->tstate = tstate;
+ break;
+ case 33: /* PC */
+--- a/arch/sparc64/kernel/rtrap.S
++++ b/arch/sparc64/kernel/rtrap.S
+@@ -270,6 +270,7 @@ rt_continue: ldx [%sp + PTREGS_OFF + P
+ wr %o3, %g0, %y
+ wrpr %l4, 0x0, %pil
+ wrpr %g0, 0x1, %tl
++ andn %l1, TSTATE_SYSCALL, %l1
+ wrpr %l1, %g0, %tstate
+ wrpr %l2, %g0, %tpc
+ wrpr %o2, %g0, %tnpc
+--- a/arch/sparc64/kernel/signal32.c
++++ b/arch/sparc64/kernel/signal32.c
+@@ -295,6 +295,9 @@ void do_new_sigreturn32(struct pt_regs *
+ regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
+ regs->tstate |= psr_to_tstate_icc(psr);
+
++ /* Prevent syscall restart. */
++ pt_regs_clear_syscall(regs);
++
+ err |= __get_user(fpu_save, &sf->fpu_save);
+ if (fpu_save)
+ err |= restore_fpu_state32(regs, &sf->fpu_state);
+@@ -448,6 +451,9 @@ asmlinkage void do_rt_sigreturn32(struct
+ regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
+ regs->tstate |= psr_to_tstate_icc(psr);
+
++ /* Prevent syscall restart. */
++ pt_regs_clear_syscall(regs);
++
+ err |= __get_user(fpu_save, &sf->fpu_save);
+ if (fpu_save)
+ err |= restore_fpu_state32(regs, &sf->fpu_state);
+@@ -1280,20 +1286,24 @@ static inline void syscall_restart32(uns
+ * mistake.
+ */
+ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
+- unsigned long orig_i0, int restart_syscall)
++ int restart_syscall, unsigned long orig_i0)
+ {
+- siginfo_t info;
+- struct signal_deliver_cookie cookie;
+ struct k_sigaction ka;
++ siginfo_t info;
+ int signr;
+ int svr4_signal = current->personality == PER_SVR4;
+
+- cookie.restart_syscall = restart_syscall;
+- cookie.orig_i0 = orig_i0;
++ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
++
++ /* If the debugger messes with the program counter, it clears
++ * the "in syscall" bit, directing us to not perform a syscall
++ * restart.
++ */
++ if (restart_syscall && !pt_regs_is_syscall(regs))
++ restart_syscall = 0;
+
+- signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
+ if (signr > 0) {
+- if (cookie.restart_syscall)
++ if (restart_syscall)
+ syscall_restart32(orig_i0, regs, &ka.sa);
+ handle_signal32(signr, &ka, &info, oldset,
+ regs, svr4_signal);
+@@ -1307,16 +1317,16 @@ void do_signal32(sigset_t *oldset, struc
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ return;
+ }
+- if (cookie.restart_syscall &&
++ if (restart_syscall &&
+ (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+ regs->u_regs[UREG_I0] == ERESTARTSYS ||
+ regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+ /* replay the system call when we are done */
+- regs->u_regs[UREG_I0] = cookie.orig_i0;
++ regs->u_regs[UREG_I0] = orig_i0;
+ regs->tpc -= 4;
+ regs->tnpc -= 4;
+ }
+- if (cookie.restart_syscall &&
++ if (restart_syscall &&
+ regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+ regs->u_regs[UREG_G1] = __NR_restart_syscall;
+ regs->tpc -= 4;
+--- a/arch/sparc64/kernel/signal.c
++++ b/arch/sparc64/kernel/signal.c
+@@ -336,6 +336,9 @@ void do_rt_sigreturn(struct pt_regs *reg
+ regs->tpc = tpc;
+ regs->tnpc = tnpc;
+
++ /* Prevent syscall restart. */
++ pt_regs_clear_syscall(regs);
++
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(¤t->sighand->siglock);
+ current->blocked = set;
+@@ -500,7 +503,7 @@ static inline void handle_signal(unsigne
+ }
+
+ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
+- struct sigaction *sa)
++ struct sigaction *sa)
+ {
+ switch (regs->u_regs[UREG_I0]) {
+ case ERESTART_RESTARTBLOCK:
+@@ -524,17 +527,20 @@ static inline void syscall_restart(unsig
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+-static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall)
++static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int __ignored)
+ {
+- siginfo_t info;
+- struct signal_deliver_cookie cookie;
+ struct k_sigaction ka;
+- int signr;
++ int restart_syscall;
+ sigset_t *oldset;
++ siginfo_t info;
++ int signr;
+
+- cookie.restart_syscall = restart_syscall;
+- cookie.orig_i0 = orig_i0;
+-
++ if (pt_regs_is_syscall(regs) &&
++ (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
++ restart_syscall = 1;
++ } else
++ restart_syscall = 0;
++
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = ¤t->saved_sigmask;
+ else
+@@ -543,16 +549,24 @@ static void do_signal(struct pt_regs *re
+ #ifdef CONFIG_SPARC32_COMPAT
+ if (test_thread_flag(TIF_32BIT)) {
+ extern void do_signal32(sigset_t *, struct pt_regs *,
+- unsigned long, int);
+- do_signal32(oldset, regs, orig_i0,
+- cookie.restart_syscall);
++ int restart_syscall,
++ unsigned long orig_i0);
++ do_signal32(oldset, regs, restart_syscall, orig_i0);
+ return;
+ }
+ #endif
+
+- signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
++ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
++
++ /* If the debugger messes with the program counter, it clears
++ * the software "in syscall" bit, directing us to not perform
++ * a syscall restart.
++ */
++ if (restart_syscall && !pt_regs_is_syscall(regs))
++ restart_syscall = 0;
++
+ if (signr > 0) {
+- if (cookie.restart_syscall)
++ if (restart_syscall)
+ syscall_restart(orig_i0, regs, &ka.sa);
+ handle_signal(signr, &ka, &info, oldset, regs);
+
+@@ -565,16 +579,16 @@ static void do_signal(struct pt_regs *re
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ return;
+ }
+- if (cookie.restart_syscall &&
++ if (restart_syscall &&
+ (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+ regs->u_regs[UREG_I0] == ERESTARTSYS ||
+ regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+ /* replay the system call when we are done */
+- regs->u_regs[UREG_I0] = cookie.orig_i0;
++ regs->u_regs[UREG_I0] = orig_i0;
+ regs->tpc -= 4;
+ regs->tnpc -= 4;
+ }
+- if (cookie.restart_syscall &&
++ if (restart_syscall &&
+ regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+ regs->u_regs[UREG_G1] = __NR_restart_syscall;
+ regs->tpc -= 4;
+@@ -596,26 +610,3 @@ void do_notify_resume(struct pt_regs *re
+ if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+ do_signal(regs, orig_i0, restart_syscall);
+ }
+-
+-void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
+-{
+- struct signal_deliver_cookie *cp = cookie;
+-
+- if (cp->restart_syscall &&
+- (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+- regs->u_regs[UREG_I0] == ERESTARTSYS ||
+- regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+- /* replay the system call when we are done */
+- regs->u_regs[UREG_I0] = cp->orig_i0;
+- regs->tpc -= 4;
+- regs->tnpc -= 4;
+- cp->restart_syscall = 0;
+- }
+- if (cp->restart_syscall &&
+- regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+- regs->u_regs[UREG_G1] = __NR_restart_syscall;
+- regs->tpc -= 4;
+- regs->tnpc -= 4;
+- cp->restart_syscall = 0;
+- }
+-}
+--- a/arch/sparc/kernel/entry.S
++++ b/arch/sparc/kernel/entry.S
+@@ -1398,6 +1398,8 @@ ret_from_fork:
+ .align 4
+ .globl linux_sparc_syscall
+ linux_sparc_syscall:
++ sethi %hi(PSR_SYSCALL), %l4
++ or %l0, %l4, %l0
+ /* Direct access to user regs, must faster. */
+ cmp %g1, NR_SYSCALLS
+ bgeu linux_sparc_ni_syscall
+--- a/arch/sparc/kernel/ptrace.c
++++ b/arch/sparc/kernel/ptrace.c
+@@ -170,8 +170,8 @@ static int genregs32_set(struct task_str
+ switch (pos) {
+ case 32: /* PSR */
+ psr = regs->psr;
+- psr &= ~PSR_ICC;
+- psr |= (reg & PSR_ICC);
++ psr &= ~(PSR_ICC | PSR_SYSCALL);
++ psr |= (reg & (PSR_ICC | PSR_SYSCALL));
+ regs->psr = psr;
+ break;
+ case 33: /* PC */
+--- a/arch/sparc/kernel/rtrap.S
++++ b/arch/sparc/kernel/rtrap.S
+@@ -50,8 +50,9 @@ rtrap_7win_patch5: and %g1, 0x7f, %g1
+ ret_trap_entry:
+ ret_trap_lockless_ipi:
+ andcc %t_psr, PSR_PS, %g0
++ sethi %hi(PSR_SYSCALL), %g1
+ be 1f
+- nop
++ andn %t_psr, %g1, %t_psr
+
+ wr %t_psr, 0x0, %psr
+ b ret_trap_kernel
+@@ -73,7 +74,6 @@ signal_p:
+ ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
+
+ mov %l5, %o1
+- mov %l6, %o2
+ call do_signal
+ add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr
+
+@@ -81,6 +81,8 @@ signal_p:
+ ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
+ clr %l6
+ ret_trap_continue:
++ sethi %hi(PSR_SYSCALL), %g1
++ andn %t_psr, %g1, %t_psr
+ wr %t_psr, 0x0, %psr
+ WRITE_PAUSE
+
+@@ -137,8 +139,9 @@ ret_trap_userwins_ok:
+ LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
+ or %t_pc, %t_npc, %g2
+ andcc %g2, 0x3, %g0
++ sethi %hi(PSR_SYSCALL), %g2
+ be 1f
+- nop
++ andn %t_psr, %g2, %t_psr
+
+ b ret_trap_unaligned_pc
+ add %sp, STACKFRAME_SZ, %o0
+@@ -201,6 +204,8 @@ rtrap_patch5: and %g1, 0xff, %g1
+ 1:
+ LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
+ 2:
++ sethi %hi(PSR_SYSCALL), %twin_tmp1
++ andn %t_psr, %twin_tmp1, %t_psr
+ wr %t_psr, 0x0, %psr
+ WRITE_PAUSE
+
+--- a/arch/sparc/kernel/signal.c
++++ b/arch/sparc/kernel/signal.c
+@@ -178,6 +178,9 @@ static inline void do_new_sigreturn (str
+ regs->psr = (up_psr & ~(PSR_ICC | PSR_EF))
+ | (regs->psr & (PSR_ICC | PSR_EF));
+
++ /* Prevent syscall restart. */
++ pt_regs_clear_syscall(regs);
++
+ err |= __get_user(fpu_save, &sf->fpu_save);
+
+ if (fpu_save)
+@@ -299,6 +302,9 @@ asmlinkage void do_rt_sigreturn(struct p
+
+ regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC);
+
++ /* Prevent syscall restart. */
++ pt_regs_clear_syscall(regs);
++
+ err |= __get_user(fpu_save, &sf->fpu_save);
+
+ if (fpu_save)
+@@ -1008,13 +1014,13 @@ static inline void syscall_restart(unsig
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+-asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall)
++asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0)
+ {
+- siginfo_t info;
+- struct sparc_deliver_cookie cookie;
+ struct k_sigaction ka;
+- int signr;
++ int restart_syscall;
+ sigset_t *oldset;
++ siginfo_t info;
++ int signr;
+
+ /*
+ * XXX Disable svr4 signal handling until solaris emulation works.
+@@ -1027,18 +1033,28 @@ asmlinkage void do_signal(struct pt_regs
+ int svr4_signal = current->personality == PER_SVR4;
+ #endif
+
+- cookie.restart_syscall = restart_syscall;
+- cookie.orig_i0 = orig_i0;
++ if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
++ restart_syscall = 1;
++ else
++ restart_syscall = 0;
+
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = ¤t->saved_sigmask;
+ else
+ oldset = ¤t->blocked;
+
+- signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
++ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
++
++ /* If the debugger messes with the program counter, it clears
++ * the software "in syscall" bit, directing us to not perform
++ * a syscall restart.
++ */
++ if (restart_syscall && !pt_regs_is_syscall(regs))
++ restart_syscall = 0;
++
+ if (signr > 0) {
+- if (cookie.restart_syscall)
+- syscall_restart(cookie.orig_i0, regs, &ka.sa);
++ if (restart_syscall)
++ syscall_restart(orig_i0, regs, &ka.sa);
+ handle_signal(signr, &ka, &info, oldset,
+ regs, svr4_signal);
+ /* a signal was successfully delivered; the saved
+@@ -1050,16 +1066,16 @@ asmlinkage void do_signal(struct pt_regs
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ return;
+ }
+- if (cookie.restart_syscall &&
++ if (restart_syscall &&
+ (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+ regs->u_regs[UREG_I0] == ERESTARTSYS ||
+ regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+ /* replay the system call when we are done */
+- regs->u_regs[UREG_I0] = cookie.orig_i0;
++ regs->u_regs[UREG_I0] = orig_i0;
+ regs->pc -= 4;
+ regs->npc -= 4;
+ }
+- if (cookie.restart_syscall &&
++ if (restart_syscall &&
+ regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+ regs->u_regs[UREG_G1] = __NR_restart_syscall;
+ regs->pc -= 4;
+@@ -1111,27 +1127,3 @@ do_sys_sigstack(struct sigstack __user *
+ out:
+ return ret;
+ }
+-
+-void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
+-{
+- struct sparc_deliver_cookie *cp = cookie;
+-
+- if (cp->restart_syscall &&
+- (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+- regs->u_regs[UREG_I0] == ERESTARTSYS ||
+- regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+- /* replay the system call when we are done */
+- regs->u_regs[UREG_I0] = cp->orig_i0;
+- regs->pc -= 4;
+- regs->npc -= 4;
+- cp->restart_syscall = 0;
+- }
+-
+- if (cp->restart_syscall &&
+- regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+- regs->u_regs[UREG_G1] = __NR_restart_syscall;
+- regs->pc -= 4;
+- regs->npc -= 4;
+- cp->restart_syscall = 0;
+- }
+-}
+--- a/include/asm-sparc64/psrcompat.h
++++ b/include/asm-sparc64/psrcompat.h
+@@ -12,6 +12,7 @@
+ #define PSR_PIL 0x00000f00 /* processor interrupt level */
+ #define PSR_EF 0x00001000 /* enable floating point */
+ #define PSR_EC 0x00002000 /* enable co-processor */
++#define PSR_SYSCALL 0x00004000 /* inside of a syscall */
+ #define PSR_LE 0x00008000 /* SuperSparcII little-endian */
+ #define PSR_ICC 0x00f00000 /* integer condition codes */
+ #define PSR_C 0x00100000 /* carry bit */
+@@ -30,6 +31,7 @@ static inline unsigned int tstate_to_psr
+ PSR_S |
+ ((tstate & TSTATE_ICC) >> 12) |
+ ((tstate & TSTATE_XCC) >> 20) |
++ ((tstate & TSTATE_SYSCALL) ? PSR_SYSCALL : 0) |
+ PSR_V8PLUS);
+ }
+
+--- a/include/asm-sparc64/pstate.h
++++ b/include/asm-sparc64/pstate.h
+@@ -62,6 +62,7 @@
+ #define TSTATE_PRIV _AC(0x0000000000000400,UL) /* Privilege. */
+ #define TSTATE_IE _AC(0x0000000000000200,UL) /* Interrupt Enable. */
+ #define TSTATE_AG _AC(0x0000000000000100,UL) /* Alternate Globals.*/
++#define TSTATE_SYSCALL _AC(0x0000000000000020,UL) /* in syscall trap */
+ #define TSTATE_CWP _AC(0x000000000000001f,UL) /* Curr Win-Pointer. */
+
+ /* Floating-Point Registers State Register.
+--- a/include/asm-sparc64/ptrace.h
++++ b/include/asm-sparc64/ptrace.h
+@@ -10,6 +10,8 @@
+
+ #ifndef __ASSEMBLY__
+
++#include <linux/types.h>
++
+ struct pt_regs {
+ unsigned long u_regs[16]; /* globals and ins */
+ unsigned long tstate;
+@@ -27,6 +29,16 @@ struct pt_regs32 {
+ unsigned int u_regs[16]; /* globals and ins */
+ };
+
++static inline bool pt_regs_is_syscall(struct pt_regs *regs)
++{
++ return (regs->tstate & TSTATE_SYSCALL);
++}
++
++static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
++{
++ return (regs->tstate &= ~TSTATE_SYSCALL);
++}
++
+ #define UREG_G0 0
+ #define UREG_G1 1
+ #define UREG_G2 2
+--- a/include/asm-sparc64/signal.h
++++ b/include/asm-sparc64/signal.h
+@@ -186,13 +186,7 @@ struct k_sigaction {
+ void __user *ka_restorer;
+ };
+
+-struct signal_deliver_cookie {
+- int restart_syscall;
+- unsigned long orig_i0;
+-};
+-
+-struct pt_regs;
+-extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
++#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+ #endif /* !(__KERNEL__) */
+
+--- a/include/asm-sparc64/ttable.h
++++ b/include/asm-sparc64/ttable.h
+@@ -91,13 +91,14 @@
+ clr %l6;
+
+ #define SYSCALL_TRAP(routine, systbl) \
++ rdpr %pil, %g2; \
++ mov TSTATE_SYSCALL, %g3; \
+ sethi %hi(109f), %g7; \
+- ba,pt %xcc, etrap; \
++ ba,pt %xcc, etrap_syscall; \
+ 109: or %g7, %lo(109b), %g7; \
+ sethi %hi(systbl), %l7; \
+ ba,pt %xcc, routine; \
+- or %l7, %lo(systbl), %l7; \
+- nop; nop;
++ or %l7, %lo(systbl), %l7;
+
+ #define INDIRECT_SOLARIS_SYSCALL(num) \
+ sethi %hi(109f), %g7; \
+--- a/include/asm-sparc/psr.h
++++ b/include/asm-sparc/psr.h
+@@ -25,6 +25,7 @@
+ #define PSR_PIL 0x00000f00 /* processor interrupt level */
+ #define PSR_EF 0x00001000 /* enable floating point */
+ #define PSR_EC 0x00002000 /* enable co-processor */
++#define PSR_SYSCALL 0x00004000 /* inside of a syscall */
+ #define PSR_LE 0x00008000 /* SuperSparcII little-endian */
+ #define PSR_ICC 0x00f00000 /* integer condition codes */
+ #define PSR_C 0x00100000 /* carry bit */
+--- a/include/asm-sparc/ptrace.h
++++ b/include/asm-sparc/ptrace.h
+@@ -10,6 +10,8 @@
+
+ #ifndef __ASSEMBLY__
+
++#include <linux/types.h>
++
+ struct pt_regs {
+ unsigned long psr;
+ unsigned long pc;
+@@ -39,6 +41,16 @@ struct pt_regs {
+ #define UREG_FP UREG_I6
+ #define UREG_RETPC UREG_I7
+
++static inline bool pt_regs_is_syscall(struct pt_regs *regs)
++{
++ return (regs->psr & PSR_SYSCALL);
++}
++
++static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
++{
++ return (regs->psr &= ~PSR_SYSCALL);
++}
++
+ /* A register window */
+ struct reg_window {
+ unsigned long locals[8];
+--- a/include/asm-sparc/signal.h
++++ b/include/asm-sparc/signal.h
+@@ -199,13 +199,7 @@ typedef struct sigaltstack {
+ size_t ss_size;
+ } stack_t;
+
+-struct sparc_deliver_cookie {
+- int restart_syscall;
+- unsigned long orig_i0;
+-};
+-
+-struct pt_regs;
+-extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
++#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+ #endif /* !(__KERNEL__) */
+
--- /dev/null
+From 9cd1cdff49a03876b453a8b2fa4d9886208acc03 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Mon, 12 May 2008 16:33:33 -0700
+Subject: sparc: Fix mremap address range validation.
+
+From: David S. Miller <davem@davemloft.net>
+
+Just like mmap, we need to validate address ranges regardless
+of MAP_FIXED.
+
+sparc{,64}_mmap_check()'s flag argument is unused, remove.
+
+Based upon a report and preliminary patch by
+Jan Lieskovsky <jlieskov@redhat.com>
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/sparc/kernel/sys_sparc.c | 48 +++-----------------------------------
+ arch/sparc64/kernel/sys_sparc.c | 36 +++-------------------------
+ arch/sparc64/kernel/sys_sparc32.c | 33 +-------------------------
+ include/asm-sparc/mman.h | 5 +--
+ include/asm-sparc64/mman.h | 5 +--
+ 5 files changed, 15 insertions(+), 112 deletions(-)
+
+--- a/arch/sparc64/kernel/sys_sparc32.c
++++ b/arch/sparc64/kernel/sys_sparc32.c
+@@ -906,44 +906,15 @@ asmlinkage unsigned long sys32_mremap(un
+ unsigned long old_len, unsigned long new_len,
+ unsigned long flags, u32 __new_addr)
+ {
+- struct vm_area_struct *vma;
+ unsigned long ret = -EINVAL;
+ unsigned long new_addr = __new_addr;
+
+- if (old_len > STACK_TOP32 || new_len > STACK_TOP32)
++ if (unlikely(sparc64_mmap_check(addr, old_len)))
+ goto out;
+- if (addr > STACK_TOP32 - old_len)
++ if (unlikely(sparc64_mmap_check(new_addr, new_len)))
+ goto out;
+ down_write(¤t->mm->mmap_sem);
+- if (flags & MREMAP_FIXED) {
+- if (new_addr > STACK_TOP32 - new_len)
+- goto out_sem;
+- } else if (addr > STACK_TOP32 - new_len) {
+- unsigned long map_flags = 0;
+- struct file *file = NULL;
+-
+- ret = -ENOMEM;
+- if (!(flags & MREMAP_MAYMOVE))
+- goto out_sem;
+-
+- vma = find_vma(current->mm, addr);
+- if (vma) {
+- if (vma->vm_flags & VM_SHARED)
+- map_flags |= MAP_SHARED;
+- file = vma->vm_file;
+- }
+-
+- /* MREMAP_FIXED checked above. */
+- new_addr = get_unmapped_area(file, addr, new_len,
+- vma ? vma->vm_pgoff : 0,
+- map_flags);
+- ret = new_addr;
+- if (new_addr & ~PAGE_MASK)
+- goto out_sem;
+- flags |= MREMAP_FIXED;
+- }
+ ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ up_write(¤t->mm->mmap_sem);
+ out:
+ return ret;
+--- a/arch/sparc64/kernel/sys_sparc.c
++++ b/arch/sparc64/kernel/sys_sparc.c
+@@ -542,8 +542,7 @@ asmlinkage long sparc64_personality(unsi
+ return ret;
+ }
+
+-int sparc64_mmap_check(unsigned long addr, unsigned long len,
+- unsigned long flags)
++int sparc64_mmap_check(unsigned long addr, unsigned long len)
+ {
+ if (test_thread_flag(TIF_32BIT)) {
+ if (len >= STACK_TOP32)
+@@ -609,46 +608,19 @@ asmlinkage unsigned long sys64_mremap(un
+ unsigned long old_len, unsigned long new_len,
+ unsigned long flags, unsigned long new_addr)
+ {
+- struct vm_area_struct *vma;
+ unsigned long ret = -EINVAL;
+
+ if (test_thread_flag(TIF_32BIT))
+ goto out;
+ if (unlikely(new_len >= VA_EXCLUDE_START))
+ goto out;
+- if (unlikely(invalid_64bit_range(addr, old_len)))
++ if (unlikely(sparc64_mmap_check(addr, old_len)))
++ goto out;
++ if (unlikely(sparc64_mmap_check(new_addr, new_len)))
+ goto out;
+
+ down_write(¤t->mm->mmap_sem);
+- if (flags & MREMAP_FIXED) {
+- if (invalid_64bit_range(new_addr, new_len))
+- goto out_sem;
+- } else if (invalid_64bit_range(addr, new_len)) {
+- unsigned long map_flags = 0;
+- struct file *file = NULL;
+-
+- ret = -ENOMEM;
+- if (!(flags & MREMAP_MAYMOVE))
+- goto out_sem;
+-
+- vma = find_vma(current->mm, addr);
+- if (vma) {
+- if (vma->vm_flags & VM_SHARED)
+- map_flags |= MAP_SHARED;
+- file = vma->vm_file;
+- }
+-
+- /* MREMAP_FIXED checked above. */
+- new_addr = get_unmapped_area(file, addr, new_len,
+- vma ? vma->vm_pgoff : 0,
+- map_flags);
+- ret = new_addr;
+- if (new_addr & ~PAGE_MASK)
+- goto out_sem;
+- flags |= MREMAP_FIXED;
+- }
+ ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ up_write(¤t->mm->mmap_sem);
+ out:
+ return ret;
+--- a/arch/sparc/kernel/sys_sparc.c
++++ b/arch/sparc/kernel/sys_sparc.c
+@@ -220,7 +220,7 @@ out:
+ return err;
+ }
+
+-int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
++int sparc_mmap_check(unsigned long addr, unsigned long len)
+ {
+ if (ARCH_SUN4C_SUN4 &&
+ (len > 0x20000000 ||
+@@ -296,52 +296,14 @@ asmlinkage unsigned long sparc_mremap(un
+ unsigned long old_len, unsigned long new_len,
+ unsigned long flags, unsigned long new_addr)
+ {
+- struct vm_area_struct *vma;
+ unsigned long ret = -EINVAL;
+- if (ARCH_SUN4C_SUN4) {
+- if (old_len > 0x20000000 || new_len > 0x20000000)
+- goto out;
+- if (addr < 0xe0000000 && addr + old_len > 0x20000000)
+- goto out;
+- }
+- if (old_len > TASK_SIZE - PAGE_SIZE ||
+- new_len > TASK_SIZE - PAGE_SIZE)
++
++ if (unlikely(sparc_mmap_check(addr, old_len)))
++ goto out;
++ if (unlikely(sparc_mmap_check(new_addr, new_len)))
+ goto out;
+ down_write(¤t->mm->mmap_sem);
+- if (flags & MREMAP_FIXED) {
+- if (ARCH_SUN4C_SUN4 &&
+- new_addr < 0xe0000000 &&
+- new_addr + new_len > 0x20000000)
+- goto out_sem;
+- if (new_addr + new_len > TASK_SIZE - PAGE_SIZE)
+- goto out_sem;
+- } else if ((ARCH_SUN4C_SUN4 && addr < 0xe0000000 &&
+- addr + new_len > 0x20000000) ||
+- addr + new_len > TASK_SIZE - PAGE_SIZE) {
+- unsigned long map_flags = 0;
+- struct file *file = NULL;
+-
+- ret = -ENOMEM;
+- if (!(flags & MREMAP_MAYMOVE))
+- goto out_sem;
+-
+- vma = find_vma(current->mm, addr);
+- if (vma) {
+- if (vma->vm_flags & VM_SHARED)
+- map_flags |= MAP_SHARED;
+- file = vma->vm_file;
+- }
+-
+- new_addr = get_unmapped_area(file, addr, new_len,
+- vma ? vma->vm_pgoff : 0,
+- map_flags);
+- ret = new_addr;
+- if (new_addr & ~PAGE_MASK)
+- goto out_sem;
+- flags |= MREMAP_FIXED;
+- }
+ ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ up_write(¤t->mm->mmap_sem);
+ out:
+ return ret;
+--- a/include/asm-sparc64/mman.h
++++ b/include/asm-sparc64/mman.h
+@@ -37,9 +37,8 @@
+
+ #ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+-#define arch_mmap_check sparc64_mmap_check
+-int sparc64_mmap_check(unsigned long addr, unsigned long len,
+- unsigned long flags);
++#define arch_mmap_check(addr,len,flags) sparc64_mmap_check(addr,len)
++int sparc64_mmap_check(unsigned long addr, unsigned long len);
+ #endif
+ #endif
+
+--- a/include/asm-sparc/mman.h
++++ b/include/asm-sparc/mman.h
+@@ -37,9 +37,8 @@
+
+ #ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+-#define arch_mmap_check sparc_mmap_check
+-int sparc_mmap_check(unsigned long addr, unsigned long len,
+- unsigned long flags);
++#define arch_mmap_check(addr,len,flags) sparc_mmap_check(addr,len)
++int sparc_mmap_check(unsigned long addr, unsigned long len);
+ #endif
+ #endif
+
--- /dev/null
+From d765628765956808985bfa1cbb1d3a38cd6b48f0 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Sat, 10 May 2008 21:11:23 -0700
+Subject: [PATCH] sparc: Fix ptrace() detach.
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit: 986bef854fab44012df678a5b51817d5274d3ca1 ]
+
+Forever we had a PTRACE_SUNOS_DETACH which was unconditionally
+recognized, regardless of the personality of the process.
+
+Unfortunately, this value is what ended up in the GLIBC sys/ptrace.h
+header file on sparc as PTRACE_DETACH and PT_DETACH.
+
+So continue to recognize this old value. Luckily, it doesn't conflict
+with anything we actually care about.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/sparc/kernel/ptrace.c | 2 ++
+ arch/sparc64/kernel/ptrace.c | 4 ++++
+ include/asm-sparc/ptrace.h | 1 +
+ include/asm-sparc64/ptrace.h | 1 +
+ 4 files changed, 8 insertions(+)
+
+--- a/arch/sparc64/kernel/ptrace.c
++++ b/arch/sparc64/kernel/ptrace.c
+@@ -944,6 +944,8 @@ long compat_arch_ptrace(struct task_stru
+ break;
+
+ default:
++ if (request == PTRACE_SPARC_DETACH)
++ request = PTRACE_DETACH;
+ ret = compat_ptrace_request(child, request, addr, data);
+ break;
+ }
+@@ -1036,6 +1038,8 @@ long arch_ptrace(struct task_struct *chi
+ break;
+
+ default:
++ if (request == PTRACE_SPARC_DETACH)
++ request = PTRACE_DETACH;
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+--- a/arch/sparc/kernel/ptrace.c
++++ b/arch/sparc/kernel/ptrace.c
+@@ -441,6 +441,8 @@ long arch_ptrace(struct task_struct *chi
+ break;
+
+ default:
++ if (request == PTRACE_SPARC_DETACH)
++ request = PTRACE_DETACH;
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+--- a/include/asm-sparc64/ptrace.h
++++ b/include/asm-sparc64/ptrace.h
+@@ -263,6 +263,7 @@ extern void __show_regs(struct pt_regs *
+ #define SF_XXARG 0x5c
+
+ /* Stuff for the ptrace system call */
++#define PTRACE_SPARC_DETACH 11
+ #define PTRACE_GETREGS 12
+ #define PTRACE_SETREGS 13
+ #define PTRACE_GETFPREGS 14
+--- a/include/asm-sparc/ptrace.h
++++ b/include/asm-sparc/ptrace.h
+@@ -149,6 +149,7 @@ extern void show_regs(struct pt_regs *);
+ #define SF_XXARG 0x5c
+
+ /* Stuff for the ptrace system call */
++#define PTRACE_SPARC_DETACH 11
+ #define PTRACE_GETREGS 12
+ #define PTRACE_SETREGS 13
+ #define PTRACE_GETFPREGS 14
--- /dev/null
+From 9a27867f393cb602b803f7a1dcd37dd762fd621e Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Sat, 10 May 2008 00:31:28 -0700
+Subject: sparc32: Don't twiddle PT_DTRACE in exec.
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit: c07c6053c41f736711ed856aa377007078c7c396 ]
+
+That bit isn't used on this platform.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/sparc/kernel/process.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/arch/sparc/kernel/process.c
++++ b/arch/sparc/kernel/process.c
+@@ -640,11 +640,6 @@ asmlinkage int sparc_execve(struct pt_re
+ (char __user * __user *)regs->u_regs[base + UREG_I2],
+ regs);
+ putname(filename);
+- if (error == 0) {
+- task_lock(current);
+- current->ptrace &= ~PT_DTRACE;
+- task_unlock(current);
+- }
+ out:
+ return error;
+ }
--- /dev/null
+From 21ae1dd1d4948968ad2d923c5e104d38fb35b4e4 Mon Sep 17 00:00:00 2001
+From: Leonardo Chiquitto <leonardo@iken.com.br>
+Date: Tue, 22 Apr 2008 16:02:03 -0300
+Subject: USB: airprime: unlock mutex instead of trying to lock it again
+
+From: Leonardo Chiquitto <leonardo@iken.com.br>
+
+commit 21ae1dd1d4948968ad2d923c5e104d38fb35b4e4 upstream
+
+The following patch fixes a [probable] copy & paste mistake in
+airprime.c. Instead of unlocking an acquired mutex, the actual
+code tries to lock it again.
+
+Signed-off-by: Leonardo Chiquitto <lchiquitto@novell.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/airprime.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/airprime.c
++++ b/drivers/usb/serial/airprime.c
+@@ -220,7 +220,7 @@ static void airprime_close(struct usb_se
+ mutex_lock(&port->serial->disc_mutex);
+ if (!port->serial->disconnected)
+ airprime_send_setup(port);
+- mutex_lock(&port->serial->disc_mutex);
++ mutex_unlock(&port->serial->disc_mutex);
+
+ for (i = 0; i < NUM_READ_URBS; ++i) {
+ usb_kill_urb (priv->read_urbp[i]);
--- /dev/null
+From stable-bounces@linux.kernel.org Sat May 10 21:20:28 2008
+From: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+Date: Sun, 11 May 2008 04:20:09 GMT
+Subject: x86: sysfs cpu?/topology is empty in 2.6.25 (32-bit Intel system)
+To: jejb@kernel.org, stable@kernel.org
+Message-ID: <200805110420.m4B4K9cE012132@hera.kernel.org>
+
+From: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+
+commit 5c3a121d52b30a1e53cdaa802fa1965fcd243164 upstream
+
+System topology on intel based system needs to be exported
+for non-numa case as well.
+
+All parts of asm-i386/topology.h has come under
+#ifdef CONFIG_NUMA after the merge to asm-x86/topology.h
+
+/sys/devices/system/cpu/cpu?/topology/* is populated based on
+ENABLE_TOPO_DEFINES
+
+The sysfs cpu topology is not being populated on my dual socket
+dual core xeon 5160 processor based (x86 32 bit) system.
+
+CONFIG_NUMA is not set in my case yet the topology is relevant
+and useful.
+
+irqbalance daemon application depends on topology to build the
+cpus and package list and it fails on Fedora9 beta since the
+sysfs topology was not being populated in the 2.6.25 kernel.
+
+I am not sure if it was intentional to not define ENABLE_TOPO_DEFINES
+for non-numa systems.
+
+This fix has been tested on the above mentioned dual core, dual socket
+system.
+
+Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-x86/topology.h | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+--- a/include/asm-x86/topology.h
++++ b/include/asm-x86/topology.h
+@@ -25,6 +25,16 @@
+ #ifndef _ASM_X86_TOPOLOGY_H
+ #define _ASM_X86_TOPOLOGY_H
+
++#ifdef CONFIG_X86_32
++# ifdef CONFIG_X86_HT
++# define ENABLE_TOPO_DEFINES
++# endif
++#else
++# ifdef CONFIG_SMP
++# define ENABLE_TOPO_DEFINES
++# endif
++#endif
++
+ #ifdef CONFIG_NUMA
+ #include <linux/cpumask.h>
+ #include <asm/mpspec.h>
+@@ -112,10 +122,6 @@ extern unsigned long node_end_pfn[];
+ extern unsigned long node_remap_size[];
+ #define node_has_online_mem(nid) (node_start_pfn[nid] != node_end_pfn[nid])
+
+-# ifdef CONFIG_X86_HT
+-# define ENABLE_TOPO_DEFINES
+-# endif
+-
+ # define SD_CACHE_NICE_TRIES 1
+ # define SD_IDLE_IDX 1
+ # define SD_NEWIDLE_IDX 2
+@@ -123,10 +129,6 @@ extern unsigned long node_remap_size[];
+
+ #else
+
+-# ifdef CONFIG_SMP
+-# define ENABLE_TOPO_DEFINES
+-# endif
+-
+ # define SD_CACHE_NICE_TRIES 2
+ # define SD_IDLE_IDX 2
+ # define SD_NEWIDLE_IDX 0