Please queue up the following fixes for 3.0, 3.2, 3.4, and
3.6 -stable branches, respectively.

Thanks!
>From 93532cc9548558200709c8e014240999535ff356 Mon Sep 17 00:00:00 2001
From: Al Viro <[email protected]>
Date: Wed, 10 Oct 2012 17:25:00 -0700
Subject: [PATCH 1/6] sparc64: fix ptrace interaction with
 force_successful_syscall_return()

[ Upstream commit 55c2770e413e96871147b9406a9c41fe9bc5209c ]

we want syscall_trace_leave() called on exit from any syscall;
skipping its call in case we'd done force_successful_syscall_return()
is broken...

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/syscalls.S | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index 1d7e274..7f5f65d 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -212,24 +212,20 @@ linux_sparc_syscall:
 3:     stx     %o0, [%sp + PTREGS_OFF + PT_V9_I0]
 ret_sys_call:
        ldx     [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
-       ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
        sra     %o0, 0, %o0
        mov     %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
        sllx    %g2, 32, %g2
 
-       /* Check if force_successful_syscall_return()
-        * was invoked.
-        */
-       ldub    [%g6 + TI_SYS_NOERROR], %l2
-       brnz,a,pn %l2, 80f
-        stb    %g0, [%g6 + TI_SYS_NOERROR]
-
        cmp     %o0, -ERESTART_RESTARTBLOCK
        bgeu,pn %xcc, 1f
-        andcc  %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%l6
-80:
+        andcc  %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%g0
+       ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
+
+2:
+       stb     %g0, [%g6 + TI_SYS_NOERROR]
        /* System call success, clear Carry condition code. */
        andn    %g3, %g2, %g3
+3:
        stx     %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]  
        bne,pn  %icc, linux_syscall_trace2
         add    %l1, 0x4, %l2                   ! npc = npc+4
@@ -238,20 +234,20 @@ ret_sys_call:
         stx    %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
 
 1:
+       /* Check if force_successful_syscall_return()
+        * was invoked.
+        */
+       ldub    [%g6 + TI_SYS_NOERROR], %l2
+       brnz,pn %l2, 2b
+        ldx    [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
        /* System call failure, set Carry condition code.
         * Also, get abs(errno) to return to the process.
         */
-       andcc   %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%l6  
        sub     %g0, %o0, %o0
-       or      %g3, %g2, %g3
        stx     %o0, [%sp + PTREGS_OFF + PT_V9_I0]
-       stx     %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
-       bne,pn  %icc, linux_syscall_trace2
-        add    %l1, 0x4, %l2                   ! npc = npc+4
-       stx     %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
+       ba,pt   %xcc, 3b
+        or     %g3, %g2, %g3
 
-       b,pt    %xcc, rtrap
-        stx    %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
 linux_syscall_trace2:
        call    syscall_trace_leave
         add    %sp, PTREGS_OFF, %o0
-- 
1.7.11.7


>From c988fe16b5dd4a50595dcfb8a7dfd4fc1ff871d9 Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Sun, 14 Oct 2012 17:59:40 -0700
Subject: [PATCH 2/6] sparc64: Like x86 we should check current->mm during
 perf backtrace generation.

[ Upstream commit 08280e6c4c2e8049ac61d9e8e3536ec1df629c0d ]

If the MM is not active, only report the top-level PC.  Do not try to
access the address space.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/perf_event.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 6860d40..bcc3eef 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1380,8 +1380,6 @@ static void perf_callchain_user_64(struct 
perf_callchain_entry *entry,
 {
        unsigned long ufp;
 
-       perf_callchain_store(entry, regs->tpc);
-
        ufp = regs->u_regs[UREG_I6] + STACK_BIAS;
        do {
                struct sparc_stackf *usf, sf;
@@ -1402,8 +1400,6 @@ static void perf_callchain_user_32(struct 
perf_callchain_entry *entry,
 {
        unsigned long ufp;
 
-       perf_callchain_store(entry, regs->tpc);
-
        ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
        do {
                struct sparc_stackf32 *usf, sf;
@@ -1422,6 +1418,11 @@ static void perf_callchain_user_32(struct 
perf_callchain_entry *entry,
 void
 perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
 {
+       perf_callchain_store(entry, regs->tpc);
+
+       if (!current->mm)
+               return;
+
        flushw_user();
        if (test_thread_flag(TIF_32BIT))
                perf_callchain_user_32(entry, regs);
-- 
1.7.11.7


>From e73ff5c0c0bba8cb9c7b51691bc290a7e4a9fc61 Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Tue, 16 Oct 2012 13:05:25 -0700
Subject: [PATCH 4/6] sparc64: Fix bit twiddling in sparc_pmu_enable_event().

[ Upstream commit e793d8c6740f8fe704fa216e95685f4d92c4c4b9 ]

There was a serious disconnect in the logic happening in
sparc_pmu_disable_event() vs. sparc_pmu_enable_event().

Event disable is implemented by programming a NOP event into the PCR.

However, event enable was not reversing this operation.  Instead, it
was setting the User/Priv/Hypervisor trace enable bits.

That's not sparc_pmu_enable_event()'s job, that's what
sparc_pmu_enable() and sparc_pmu_disable() do .

The intent of sparc_pmu_enable_event() is clear, since it first clear
out the event type encoding field.  So fix this by OR'ing in the event
encoding rather than the trace enable bits.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/perf_event.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index bcc3eef..904ed63 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -513,11 +513,13 @@ static u64 nop_for_index(int idx)
 
 static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct 
hw_perf_event *hwc, int idx)
 {
-       u64 val, mask = mask_for_index(idx);
+       u64 enc, val, mask = mask_for_index(idx);
+
+       enc = perf_event_get_enc(cpuc->events[idx]);
 
        val = cpuc->pcr;
        val &= ~mask;
-       val |= hwc->config;
+       val |= event_encoding(enc, idx);
        cpuc->pcr = val;
 
        pcr_ops->write(cpuc->pcr);
-- 
1.7.11.7


>From 63f5dbbff2508abbf19627b8679d39895af8dfa3 Mon Sep 17 00:00:00 2001
From: Jiri Kosina <[email protected]>
Date: Wed, 1 Aug 2012 21:10:51 +0200
Subject: [PATCH 5/6] sparc64: do not clobber personality flags in
 sys_sparc64_personality()

[ Upstream commit a27032eee8cb6e16516f13c8a9752e9d5d4cc430 ]

There are multiple errors in how sys_sparc64_personality() handles
personality flags stored in top three bytes.

- directly comparing current->personality against PER_LINUX32 doesn't work
  in cases when any of the personality flags stored in the top three bytes
  are used.
- directly forcefully setting personality to PER_LINUX32 or PER_LINUX
  discards any flags stored in the top three bytes

Fix the first one by properly using personality() macro to compare only
PER_MASK bytes.
Fix the second one by setting only the bits that should be set, instead of
overwriting the whole value.

Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/sys_sparc_64.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 908b47a..10c9b36 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -519,12 +519,12 @@ SYSCALL_DEFINE1(sparc64_personality, unsigned long, 
personality)
 {
        int ret;
 
-       if (current->personality == PER_LINUX32 &&
-           personality == PER_LINUX)
-               personality = PER_LINUX32;
+       if (personality(current->personality) == PER_LINUX32 &&
+           personality(personality) == PER_LINUX)
+               personality |= PER_LINUX32;
        ret = sys_personality(personality);
-       if (ret == PER_LINUX32)
-               ret = PER_LINUX;
+       if (personality(ret) == PER_LINUX32)
+               ret &= ~PER_LINUX32;
 
        return ret;
 }
-- 
1.7.11.7


>From d95bc56ac394a6cab136a87330680132a8068afd Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Wed, 15 Aug 2012 00:37:29 -0700
Subject: [PATCH 6/6] sparc64: Be less verbose during vmemmap population.

[ Upstream commit 2856cc2e4d0852c3ddaae9dcb19cb9396512eb08 ]

On a 2-node machine with 256GB of ram we get 512 lines of
console output, which is just too much.

This mimicks Yinghai Lu's x86 commit c2b91e2eec9678dbda274e906cc32ea8f711da3b
(x86_64/mm: check and print vmemmap allocation continuous) except that
we aren't ever going to get contiguous block pointers in between calls
so just print when the virtual address or node changes.

This decreases the output by an order of 16.

Also demote this to KERN_DEBUG.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/mm/init_64.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 8e073d8..6ff4d78 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -2118,6 +2118,9 @@ EXPORT_SYMBOL(_PAGE_CACHE);
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 unsigned long vmemmap_table[VMEMMAP_SIZE];
 
+static long __meminitdata addr_start, addr_end;
+static int __meminitdata node_start;
+
 int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
 {
        unsigned long vstart = (unsigned long) start;
@@ -2148,15 +2151,30 @@ int __meminit vmemmap_populate(struct page *start, 
unsigned long nr, int node)
 
                        *vmem_pp = pte_base | __pa(block);
 
-                       printk(KERN_INFO "[%p-%p] page_structs=%lu "
-                              "node=%d entry=%lu/%lu\n", start, block, nr,
-                              node,
-                              addr >> VMEMMAP_CHUNK_SHIFT,
-                              VMEMMAP_SIZE);
+                       /* check to see if we have contiguous blocks */
+                       if (addr_end != addr || node_start != node) {
+                               if (addr_start)
+                                       printk(KERN_DEBUG " [%lx-%lx] on node 
%d\n",
+                                              addr_start, addr_end-1, 
node_start);
+                               addr_start = addr;
+                               node_start = node;
+                       }
+                       addr_end = addr + VMEMMAP_CHUNK;
                }
        }
        return 0;
 }
+
+void __meminit vmemmap_populate_print_last(void)
+{
+       if (addr_start) {
+               printk(KERN_DEBUG " [%lx-%lx] on node %d\n",
+                      addr_start, addr_end-1, node_start);
+               addr_start = 0;
+               addr_end = 0;
+               node_start = 0;
+       }
+}
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
 static void prot_init_common(unsigned long page_none,
-- 
1.7.11.7

>From 03c789ca8b05d42d98acf64be7715cc6eb5820cf Mon Sep 17 00:00:00 2001
From: Al Viro <[email protected]>
Date: Wed, 10 Oct 2012 17:25:00 -0700
Subject: [PATCH 1/6] sparc64: fix ptrace interaction with
 force_successful_syscall_return()

[ Upstream commit 55c2770e413e96871147b9406a9c41fe9bc5209c ]

we want syscall_trace_leave() called on exit from any syscall;
skipping its call in case we'd done force_successful_syscall_return()
is broken...

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/syscalls.S | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index 1d7e274..7f5f65d 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -212,24 +212,20 @@ linux_sparc_syscall:
 3:     stx     %o0, [%sp + PTREGS_OFF + PT_V9_I0]
 ret_sys_call:
        ldx     [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
-       ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
        sra     %o0, 0, %o0
        mov     %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
        sllx    %g2, 32, %g2
 
-       /* Check if force_successful_syscall_return()
-        * was invoked.
-        */
-       ldub    [%g6 + TI_SYS_NOERROR], %l2
-       brnz,a,pn %l2, 80f
-        stb    %g0, [%g6 + TI_SYS_NOERROR]
-
        cmp     %o0, -ERESTART_RESTARTBLOCK
        bgeu,pn %xcc, 1f
-        andcc  %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%l6
-80:
+        andcc  %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%g0
+       ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
+
+2:
+       stb     %g0, [%g6 + TI_SYS_NOERROR]
        /* System call success, clear Carry condition code. */
        andn    %g3, %g2, %g3
+3:
        stx     %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]  
        bne,pn  %icc, linux_syscall_trace2
         add    %l1, 0x4, %l2                   ! npc = npc+4
@@ -238,20 +234,20 @@ ret_sys_call:
         stx    %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
 
 1:
+       /* Check if force_successful_syscall_return()
+        * was invoked.
+        */
+       ldub    [%g6 + TI_SYS_NOERROR], %l2
+       brnz,pn %l2, 2b
+        ldx    [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
        /* System call failure, set Carry condition code.
         * Also, get abs(errno) to return to the process.
         */
-       andcc   %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%l6  
        sub     %g0, %o0, %o0
-       or      %g3, %g2, %g3
        stx     %o0, [%sp + PTREGS_OFF + PT_V9_I0]
-       stx     %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
-       bne,pn  %icc, linux_syscall_trace2
-        add    %l1, 0x4, %l2                   ! npc = npc+4
-       stx     %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
+       ba,pt   %xcc, 3b
+        or     %g3, %g2, %g3
 
-       b,pt    %xcc, rtrap
-        stx    %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
 linux_syscall_trace2:
        call    syscall_trace_leave
         add    %sp, PTREGS_OFF, %o0
-- 
1.7.11.7


>From 62718dd5de78a9be115978b425de5225ce2d5556 Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Sun, 14 Oct 2012 17:59:40 -0700
Subject: [PATCH 2/6] sparc64: Like x86 we should check current->mm during
 perf backtrace generation.

[ Upstream commit 08280e6c4c2e8049ac61d9e8e3536ec1df629c0d ]

If the MM is not active, only report the top-level PC.  Do not try to
access the address space.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/perf_event.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 614da62..5331ae1 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1422,8 +1422,6 @@ static void perf_callchain_user_64(struct 
perf_callchain_entry *entry,
 {
        unsigned long ufp;
 
-       perf_callchain_store(entry, regs->tpc);
-
        ufp = regs->u_regs[UREG_I6] + STACK_BIAS;
        do {
                struct sparc_stackf *usf, sf;
@@ -1444,8 +1442,6 @@ static void perf_callchain_user_32(struct 
perf_callchain_entry *entry,
 {
        unsigned long ufp;
 
-       perf_callchain_store(entry, regs->tpc);
-
        ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
        do {
                struct sparc_stackf32 *usf, sf;
@@ -1464,6 +1460,11 @@ static void perf_callchain_user_32(struct 
perf_callchain_entry *entry,
 void
 perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
 {
+       perf_callchain_store(entry, regs->tpc);
+
+       if (!current->mm)
+               return;
+
        flushw_user();
        if (test_thread_flag(TIF_32BIT))
                perf_callchain_user_32(entry, regs);
-- 
1.7.11.7


>From d1c2d7c26d2dbe0535f593e82cd8525f24391611 Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Tue, 16 Oct 2012 13:05:25 -0700
Subject: [PATCH 4/6] sparc64: Fix bit twiddling in sparc_pmu_enable_event().

[ Upstream commit e793d8c6740f8fe704fa216e95685f4d92c4c4b9 ]

There was a serious disconnect in the logic happening in
sparc_pmu_disable_event() vs. sparc_pmu_enable_event().

Event disable is implemented by programming a NOP event into the PCR.

However, event enable was not reversing this operation.  Instead, it
was setting the User/Priv/Hypervisor trace enable bits.

That's not sparc_pmu_enable_event()'s job, that's what
sparc_pmu_enable() and sparc_pmu_disable() do .

The intent of sparc_pmu_enable_event() is clear, since it first clear
out the event type encoding field.  So fix this by OR'ing in the event
encoding rather than the trace enable bits.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/perf_event.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 5331ae1..3c8f220 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -555,11 +555,13 @@ static u64 nop_for_index(int idx)
 
 static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct 
hw_perf_event *hwc, int idx)
 {
-       u64 val, mask = mask_for_index(idx);
+       u64 enc, val, mask = mask_for_index(idx);
+
+       enc = perf_event_get_enc(cpuc->events[idx]);
 
        val = cpuc->pcr;
        val &= ~mask;
-       val |= hwc->config;
+       val |= event_encoding(enc, idx);
        cpuc->pcr = val;
 
        pcr_ops->write(cpuc->pcr);
-- 
1.7.11.7


>From 28077ac1ee44a96a63277847c89ec14012a46101 Mon Sep 17 00:00:00 2001
From: Jiri Kosina <[email protected]>
Date: Wed, 1 Aug 2012 21:10:51 +0200
Subject: [PATCH 5/6] sparc64: do not clobber personality flags in
 sys_sparc64_personality()

[ Upstream commit a27032eee8cb6e16516f13c8a9752e9d5d4cc430 ]

There are multiple errors in how sys_sparc64_personality() handles
personality flags stored in top three bytes.

- directly comparing current->personality against PER_LINUX32 doesn't work
  in cases when any of the personality flags stored in the top three bytes
  are used.
- directly forcefully setting personality to PER_LINUX32 or PER_LINUX
  discards any flags stored in the top three bytes

Fix the first one by properly using personality() macro to compare only
PER_MASK bytes.
Fix the second one by setting only the bits that should be set, instead of
overwriting the whole value.

Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/sys_sparc_64.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 441521a..5e4252b 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -519,12 +519,12 @@ SYSCALL_DEFINE1(sparc64_personality, unsigned long, 
personality)
 {
        int ret;
 
-       if (current->personality == PER_LINUX32 &&
-           personality == PER_LINUX)
-               personality = PER_LINUX32;
+       if (personality(current->personality) == PER_LINUX32 &&
+           personality(personality) == PER_LINUX)
+               personality |= PER_LINUX32;
        ret = sys_personality(personality);
-       if (ret == PER_LINUX32)
-               ret = PER_LINUX;
+       if (personality(ret) == PER_LINUX32)
+               ret &= ~PER_LINUX32;
 
        return ret;
 }
-- 
1.7.11.7


>From 11647face862b6542fc3b90d7a6b1f2c33504057 Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Wed, 15 Aug 2012 00:37:29 -0700
Subject: [PATCH 6/6] sparc64: Be less verbose during vmemmap population.

[ Upstream commit 2856cc2e4d0852c3ddaae9dcb19cb9396512eb08 ]

On a 2-node machine with 256GB of ram we get 512 lines of
console output, which is just too much.

This mimicks Yinghai Lu's x86 commit c2b91e2eec9678dbda274e906cc32ea8f711da3b
(x86_64/mm: check and print vmemmap allocation continuous) except that
we aren't ever going to get contiguous block pointers in between calls
so just print when the virtual address or node changes.

This decreases the output by an order of 16.

Also demote this to KERN_DEBUG.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/mm/init_64.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 8e073d8..6ff4d78 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -2118,6 +2118,9 @@ EXPORT_SYMBOL(_PAGE_CACHE);
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 unsigned long vmemmap_table[VMEMMAP_SIZE];
 
+static long __meminitdata addr_start, addr_end;
+static int __meminitdata node_start;
+
 int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
 {
        unsigned long vstart = (unsigned long) start;
@@ -2148,15 +2151,30 @@ int __meminit vmemmap_populate(struct page *start, 
unsigned long nr, int node)
 
                        *vmem_pp = pte_base | __pa(block);
 
-                       printk(KERN_INFO "[%p-%p] page_structs=%lu "
-                              "node=%d entry=%lu/%lu\n", start, block, nr,
-                              node,
-                              addr >> VMEMMAP_CHUNK_SHIFT,
-                              VMEMMAP_SIZE);
+                       /* check to see if we have contiguous blocks */
+                       if (addr_end != addr || node_start != node) {
+                               if (addr_start)
+                                       printk(KERN_DEBUG " [%lx-%lx] on node 
%d\n",
+                                              addr_start, addr_end-1, 
node_start);
+                               addr_start = addr;
+                               node_start = node;
+                       }
+                       addr_end = addr + VMEMMAP_CHUNK;
                }
        }
        return 0;
 }
+
+void __meminit vmemmap_populate_print_last(void)
+{
+       if (addr_start) {
+               printk(KERN_DEBUG " [%lx-%lx] on node %d\n",
+                      addr_start, addr_end-1, node_start);
+               addr_start = 0;
+               addr_end = 0;
+               node_start = 0;
+       }
+}
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
 static void prot_init_common(unsigned long page_none,
-- 
1.7.11.7

>From 54e7541c2eea7beecca0a7743406f8da1d041550 Mon Sep 17 00:00:00 2001
From: Al Viro <[email protected]>
Date: Wed, 10 Oct 2012 17:25:00 -0700
Subject: [PATCH 1/6] sparc64: fix ptrace interaction with
 force_successful_syscall_return()

[ Upstream commit 55c2770e413e96871147b9406a9c41fe9bc5209c ]

we want syscall_trace_leave() called on exit from any syscall;
skipping its call in case we'd done force_successful_syscall_return()
is broken...

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/syscalls.S | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index 1d7e274..7f5f65d 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -212,24 +212,20 @@ linux_sparc_syscall:
 3:     stx     %o0, [%sp + PTREGS_OFF + PT_V9_I0]
 ret_sys_call:
        ldx     [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
-       ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
        sra     %o0, 0, %o0
        mov     %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
        sllx    %g2, 32, %g2
 
-       /* Check if force_successful_syscall_return()
-        * was invoked.
-        */
-       ldub    [%g6 + TI_SYS_NOERROR], %l2
-       brnz,a,pn %l2, 80f
-        stb    %g0, [%g6 + TI_SYS_NOERROR]
-
        cmp     %o0, -ERESTART_RESTARTBLOCK
        bgeu,pn %xcc, 1f
-        andcc  %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%l6
-80:
+        andcc  %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%g0
+       ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
+
+2:
+       stb     %g0, [%g6 + TI_SYS_NOERROR]
        /* System call success, clear Carry condition code. */
        andn    %g3, %g2, %g3
+3:
        stx     %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]  
        bne,pn  %icc, linux_syscall_trace2
         add    %l1, 0x4, %l2                   ! npc = npc+4
@@ -238,20 +234,20 @@ ret_sys_call:
         stx    %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
 
 1:
+       /* Check if force_successful_syscall_return()
+        * was invoked.
+        */
+       ldub    [%g6 + TI_SYS_NOERROR], %l2
+       brnz,pn %l2, 2b
+        ldx    [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
        /* System call failure, set Carry condition code.
         * Also, get abs(errno) to return to the process.
         */
-       andcc   %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%l6  
        sub     %g0, %o0, %o0
-       or      %g3, %g2, %g3
        stx     %o0, [%sp + PTREGS_OFF + PT_V9_I0]
-       stx     %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
-       bne,pn  %icc, linux_syscall_trace2
-        add    %l1, 0x4, %l2                   ! npc = npc+4
-       stx     %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
+       ba,pt   %xcc, 3b
+        or     %g3, %g2, %g3
 
-       b,pt    %xcc, rtrap
-        stx    %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
 linux_syscall_trace2:
        call    syscall_trace_leave
         add    %sp, PTREGS_OFF, %o0
-- 
1.7.11.7


>From 15de396492e25989381e814ea61f699a8cce12db Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Sun, 14 Oct 2012 17:59:40 -0700
Subject: [PATCH 2/6] sparc64: Like x86 we should check current->mm during
 perf backtrace generation.

[ Upstream commit 08280e6c4c2e8049ac61d9e8e3536ec1df629c0d ]

If the MM is not active, only report the top-level PC.  Do not try to
access the address space.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/perf_event.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 28559ce..db344c4 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1428,8 +1428,6 @@ static void perf_callchain_user_64(struct 
perf_callchain_entry *entry,
 {
        unsigned long ufp;
 
-       perf_callchain_store(entry, regs->tpc);
-
        ufp = regs->u_regs[UREG_I6] + STACK_BIAS;
        do {
                struct sparc_stackf *usf, sf;
@@ -1450,8 +1448,6 @@ static void perf_callchain_user_32(struct 
perf_callchain_entry *entry,
 {
        unsigned long ufp;
 
-       perf_callchain_store(entry, regs->tpc);
-
        ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
        do {
                struct sparc_stackf32 *usf, sf;
@@ -1470,6 +1466,11 @@ static void perf_callchain_user_32(struct 
perf_callchain_entry *entry,
 void
 perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
 {
+       perf_callchain_store(entry, regs->tpc);
+
+       if (!current->mm)
+               return;
+
        flushw_user();
        if (test_thread_flag(TIF_32BIT))
                perf_callchain_user_32(entry, regs);
-- 
1.7.11.7


>From 60f463df0d39ddb5d875ed6052d458e4224055f2 Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Tue, 16 Oct 2012 13:05:25 -0700
Subject: [PATCH 4/6] sparc64: Fix bit twiddling in sparc_pmu_enable_event().

[ Upstream commit e793d8c6740f8fe704fa216e95685f4d92c4c4b9 ]

There was a serious disconnect in the logic happening in
sparc_pmu_disable_event() vs. sparc_pmu_enable_event().

Event disable is implemented by programming a NOP event into the PCR.

However, event enable was not reversing this operation.  Instead, it
was setting the User/Priv/Hypervisor trace enable bits.

That's not sparc_pmu_enable_event()'s job, that's what
sparc_pmu_enable() and sparc_pmu_disable() do .

The intent of sparc_pmu_enable_event() is clear, since it first clear
out the event type encoding field.  So fix this by OR'ing in the event
encoding rather than the trace enable bits.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/perf_event.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index db344c4..602eca8 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -557,11 +557,13 @@ static u64 nop_for_index(int idx)
 
 static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct 
hw_perf_event *hwc, int idx)
 {
-       u64 val, mask = mask_for_index(idx);
+       u64 enc, val, mask = mask_for_index(idx);
+
+       enc = perf_event_get_enc(cpuc->events[idx]);
 
        val = cpuc->pcr;
        val &= ~mask;
-       val |= hwc->config;
+       val |= event_encoding(enc, idx);
        cpuc->pcr = val;
 
        pcr_ops->write(cpuc->pcr);
-- 
1.7.11.7


>From 5b5ad809cd2d593cc34260a5ff064ff7e3a525c1 Mon Sep 17 00:00:00 2001
From: Jiri Kosina <[email protected]>
Date: Wed, 1 Aug 2012 21:10:51 +0200
Subject: [PATCH 5/6] sparc64: do not clobber personality flags in
 sys_sparc64_personality()

[ Upstream commit a27032eee8cb6e16516f13c8a9752e9d5d4cc430 ]

There are multiple errors in how sys_sparc64_personality() handles
personality flags stored in top three bytes.

- directly comparing current->personality against PER_LINUX32 doesn't work
  in cases when any of the personality flags stored in the top three bytes
  are used.
- directly forcefully setting personality to PER_LINUX32 or PER_LINUX
  discards any flags stored in the top three bytes

Fix the first one by properly using personality() macro to compare only
PER_MASK bytes.
Fix the second one by setting only the bits that should be set, instead of
overwriting the whole value.

Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/sys_sparc_64.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 3ee51f1..57b7cab 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -519,12 +519,12 @@ SYSCALL_DEFINE1(sparc64_personality, unsigned long, 
personality)
 {
        int ret;
 
-       if (current->personality == PER_LINUX32 &&
-           personality == PER_LINUX)
-               personality = PER_LINUX32;
+       if (personality(current->personality) == PER_LINUX32 &&
+           personality(personality) == PER_LINUX)
+               personality |= PER_LINUX32;
        ret = sys_personality(personality);
-       if (ret == PER_LINUX32)
-               ret = PER_LINUX;
+       if (personality(ret) == PER_LINUX32)
+               ret &= ~PER_LINUX32;
 
        return ret;
 }
-- 
1.7.11.7


>From 00950467b5e4b390ede1b8f796fab33d31064258 Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Wed, 15 Aug 2012 00:37:29 -0700
Subject: [PATCH 6/6] sparc64: Be less verbose during vmemmap population.

[ Upstream commit 2856cc2e4d0852c3ddaae9dcb19cb9396512eb08 ]

On a 2-node machine with 256GB of ram we get 512 lines of
console output, which is just too much.

This mimicks Yinghai Lu's x86 commit c2b91e2eec9678dbda274e906cc32ea8f711da3b
(x86_64/mm: check and print vmemmap allocation continuous) except that
we aren't ever going to get contiguous block pointers in between calls
so just print when the virtual address or node changes.

This decreases the output by an order of 16.

Also demote this to KERN_DEBUG.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/mm/init_64.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 21faaee..0791618 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -2099,6 +2099,9 @@ EXPORT_SYMBOL(_PAGE_CACHE);
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 unsigned long vmemmap_table[VMEMMAP_SIZE];
 
+static long __meminitdata addr_start, addr_end;
+static int __meminitdata node_start;
+
 int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
 {
        unsigned long vstart = (unsigned long) start;
@@ -2129,15 +2132,30 @@ int __meminit vmemmap_populate(struct page *start, 
unsigned long nr, int node)
 
                        *vmem_pp = pte_base | __pa(block);
 
-                       printk(KERN_INFO "[%p-%p] page_structs=%lu "
-                              "node=%d entry=%lu/%lu\n", start, block, nr,
-                              node,
-                              addr >> VMEMMAP_CHUNK_SHIFT,
-                              VMEMMAP_SIZE);
+                       /* check to see if we have contiguous blocks */
+                       if (addr_end != addr || node_start != node) {
+                               if (addr_start)
+                                       printk(KERN_DEBUG " [%lx-%lx] on node 
%d\n",
+                                              addr_start, addr_end-1, 
node_start);
+                               addr_start = addr;
+                               node_start = node;
+                       }
+                       addr_end = addr + VMEMMAP_CHUNK;
                }
        }
        return 0;
 }
+
+void __meminit vmemmap_populate_print_last(void)
+{
+       if (addr_start) {
+               printk(KERN_DEBUG " [%lx-%lx] on node %d\n",
+                      addr_start, addr_end-1, node_start);
+               addr_start = 0;
+               addr_end = 0;
+               node_start = 0;
+       }
+}
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
 static void prot_init_common(unsigned long page_none,
-- 
1.7.11.7

>From 434ac3f0b3aaf4f1b009233bca822a8a399514e7 Mon Sep 17 00:00:00 2001
From: Al Viro <[email protected]>
Date: Wed, 10 Oct 2012 17:25:00 -0700
Subject: [PATCH 1/4] sparc64: fix ptrace interaction with
 force_successful_syscall_return()

[ Upstream commit 55c2770e413e96871147b9406a9c41fe9bc5209c ]

we want syscall_trace_leave() called on exit from any syscall;
skipping its call in case we'd done force_successful_syscall_return()
is broken...

Signed-off-by: Al Viro <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/syscalls.S | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
index 1d7e274..7f5f65d 100644
--- a/arch/sparc/kernel/syscalls.S
+++ b/arch/sparc/kernel/syscalls.S
@@ -212,24 +212,20 @@ linux_sparc_syscall:
 3:     stx     %o0, [%sp + PTREGS_OFF + PT_V9_I0]
 ret_sys_call:
        ldx     [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
-       ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
        sra     %o0, 0, %o0
        mov     %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
        sllx    %g2, 32, %g2
 
-       /* Check if force_successful_syscall_return()
-        * was invoked.
-        */
-       ldub    [%g6 + TI_SYS_NOERROR], %l2
-       brnz,a,pn %l2, 80f
-        stb    %g0, [%g6 + TI_SYS_NOERROR]
-
        cmp     %o0, -ERESTART_RESTARTBLOCK
        bgeu,pn %xcc, 1f
-        andcc  %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%l6
-80:
+        andcc  %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%g0
+       ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
+
+2:
+       stb     %g0, [%g6 + TI_SYS_NOERROR]
        /* System call success, clear Carry condition code. */
        andn    %g3, %g2, %g3
+3:
        stx     %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]  
        bne,pn  %icc, linux_syscall_trace2
         add    %l1, 0x4, %l2                   ! npc = npc+4
@@ -238,20 +234,20 @@ ret_sys_call:
         stx    %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
 
 1:
+       /* Check if force_successful_syscall_return()
+        * was invoked.
+        */
+       ldub    [%g6 + TI_SYS_NOERROR], %l2
+       brnz,pn %l2, 2b
+        ldx    [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
        /* System call failure, set Carry condition code.
         * Also, get abs(errno) to return to the process.
         */
-       andcc   %l0, 
(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), 
%l6  
        sub     %g0, %o0, %o0
-       or      %g3, %g2, %g3
        stx     %o0, [%sp + PTREGS_OFF + PT_V9_I0]
-       stx     %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
-       bne,pn  %icc, linux_syscall_trace2
-        add    %l1, 0x4, %l2                   ! npc = npc+4
-       stx     %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
+       ba,pt   %xcc, 3b
+        or     %g3, %g2, %g3
 
-       b,pt    %xcc, rtrap
-        stx    %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
 linux_syscall_trace2:
        call    syscall_trace_leave
         add    %sp, PTREGS_OFF, %o0
-- 
1.7.11.7


>From 3149157b67ae8b5a96dce0a444137248cd1c9672 Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Sun, 14 Oct 2012 17:59:40 -0700
Subject: [PATCH 2/4] sparc64: Like x86 we should check current->mm during
 perf backtrace generation.

[ Upstream commit 08280e6c4c2e8049ac61d9e8e3536ec1df629c0d ]

If the MM is not active, only report the top-level PC.  Do not try to
access the address space.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/perf_event.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 5713957..b0cce26 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -1426,8 +1426,6 @@ static void perf_callchain_user_64(struct 
perf_callchain_entry *entry,
 {
        unsigned long ufp;
 
-       perf_callchain_store(entry, regs->tpc);
-
        ufp = regs->u_regs[UREG_I6] + STACK_BIAS;
        do {
                struct sparc_stackf *usf, sf;
@@ -1448,8 +1446,6 @@ static void perf_callchain_user_32(struct 
perf_callchain_entry *entry,
 {
        unsigned long ufp;
 
-       perf_callchain_store(entry, regs->tpc);
-
        ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
        do {
                struct sparc_stackf32 *usf, sf;
@@ -1468,6 +1464,11 @@ static void perf_callchain_user_32(struct 
perf_callchain_entry *entry,
 void
 perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
 {
+       perf_callchain_store(entry, regs->tpc);
+
+       if (!current->mm)
+               return;
+
        flushw_user();
        if (test_thread_flag(TIF_32BIT))
                perf_callchain_user_32(entry, regs);
-- 
1.7.11.7


>From 646af7e56d9541c68783519d0431c1515b7ce3e8 Mon Sep 17 00:00:00 2001
From: "David S. Miller" <[email protected]>
Date: Tue, 16 Oct 2012 13:05:25 -0700
Subject: [PATCH 4/4] sparc64: Fix bit twiddling in sparc_pmu_enable_event().

[ Upstream commit e793d8c6740f8fe704fa216e95685f4d92c4c4b9 ]

There was a serious disconnect in the logic happening in
sparc_pmu_disable_event() vs. sparc_pmu_enable_event().

Event disable is implemented by programming a NOP event into the PCR.

However, event enable was not reversing this operation.  Instead, it
was setting the User/Priv/Hypervisor trace enable bits.

That's not sparc_pmu_enable_event()'s job, that's what
sparc_pmu_enable() and sparc_pmu_disable() do .

The intent of sparc_pmu_enable_event() is clear, since it first clear
out the event type encoding field.  So fix this by OR'ing in the event
encoding rather than the trace enable bits.

Signed-off-by: David S. Miller <[email protected]>
---
 arch/sparc/kernel/perf_event.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index b0cce26..ac18037 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -557,11 +557,13 @@ static u64 nop_for_index(int idx)
 
 static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct 
hw_perf_event *hwc, int idx)
 {
-       u64 val, mask = mask_for_index(idx);
+       u64 enc, val, mask = mask_for_index(idx);
+
+       enc = perf_event_get_enc(cpuc->events[idx]);
 
        val = cpuc->pcr;
        val &= ~mask;
-       val |= hwc->config;
+       val |= event_encoding(enc, idx);
        cpuc->pcr = val;
 
        pcr_ops->write(cpuc->pcr);
-- 
1.7.11.7

Reply via email to