Re: Issues with the first PowerPC updates for the kernel 6.1

2022-10-30 Thread Christian Zigotzky

On 29 October 2022 at 5:33 pm, Segher Boessenkool wrote:

On Mon, Oct 17, 2022 at 09:53:04AM +0200, Christian Zigotzky wrote:

On 17. Oct 2022, at 02:43, Michael Ellerman  wrote:
Previously BIG_ENDIAN && GENERIC_CPU would use -mcpu=power5, now it uses
-mcpu=power4.

Maybe this is the issue. We will wait and not release the RC1 for testing 
because it is a risk for our testers to test these new kernels because of this 
issue.

It is really important do not to rewrite code, that is well worked before.
Bugfixing and adding some new features is ok but rewriting of good code is 
expensive and doesn’t make any sense.

It was just a bugfix, and a (partial) revert.

471d7ff8b51b says it removed ISA 2.00 support (original power4, "GP").
Support for ISA 2.01 was retained it says.  That is power4+, "GQ", but
also 970 (Apple G5).  That patch actually switched to ISA 2.02 though,
unintendedly, and code generated for ISA 2.02 will not run on systems
like 970, in principle.  It is just one uncommon instruction that is
problematical, namely popcntb, because the kernel does not use floating
point at all, so that is why we got away with it for so long (most code
that does use fp will fall flat on its face in no time).  It still is a
bug fix though!

PA6T is ISA 2.04, it's not clear how this (bugfix, and revert!) change
made code not run on PA6T anymore.  Smells a lot like something indirect
(or triply indirect), a separate bug, something that was introduced in
the last two years maybe, but I'll even bet it is something *exposed* in
that time, a bug that has been here for longer!


Segher

Unfortunately my FSL P5040 system is also affected.

-- Christian


Re: Issues with the first PowerPC updates for the kernel 6.1

2022-10-30 Thread Christian Zigotzky

On 29 October 2022 at 01:44 pm, Christian Zigotzky wrote:

On 17 October 2022 at 09:53 am, Christian Zigotzky wrote:

On 17. Oct 2022, at 02:43, Michael Ellerman  wrote:
Previously BIG_ENDIAN && GENERIC_CPU would use -mcpu=power5, now it 
uses

-mcpu=power4.
Maybe this is the issue. We will wait and not release the RC1 for 
testing because it is a risk for our testers to test these new 
kernels because of this issue.




cheers



I compiled the RC2 of kernel 6.1 today.

After the first boot of the RC2, the file system was immediately to 
100% used.  This is the same issue we have seen with the git kernel 3 
weeks ago.


The Cyrus+ and Nemo boards are affected.

I wrote 3 weeks ago:

Hi All,

I successfully compiled the latest git kernel with the first PowerPC 
updates yesterday.


Unfortunately this kernel is really dangerous. Many things for example 
Network Manager and LightDM don't work anymore and produced several 
gigabyte of config files till the partition has been filled.


I deleted some files like the resolv.conf that had a size over 200 GB!

Unfortunately, MintPPC was still damaged. For example LightDM doesn't 
work anymore and the MATE desktop doesn't display any icons anymore 
because Caja wasn't able to reserve memory anymore.


In this case, bisecting isn't an option and I have to wait some weeks. 
It is really difficult to find the issue if the userland will damaged 
again and again.


Cheers,
Christian

---

Maybe there is an issue in my kernel configs. Could you please check 
the configs? Please find attached the configs. Could you please test 
the RC2 on your FSL and pasemi machines?


Thanks,
Christian


Hi All,

I bisected today because Void PPC is recovering after a reboot. Memory 
space is released again. [1]


Result: c2e7a19827eec443a7cbe85e8d959052412d6dc3 (powerpc: Use generic 
fallocate compatibility syscall) is the first bad commit. [2]


I was able to create a patch for reverting this bad commit. [3]

I compiled the kernel with this patch. After that the kernel works 
without any problems.


Please check the first bad commit. [2]

Thanks,
Christian


[1] https://forum.hyperion-entertainment.com/viewtopic.php?p=56099#p56099
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c2e7a19827eec443a7cbe85e8d959052412d6dc3

[3] syscall.patch:

diff -rupN a/arch/powerpc/include/asm/syscalls.h 
b/arch/powerpc/include/asm/syscalls.h
--- a/arch/powerpc/include/asm/syscalls.h   2022-10-30 
13:53:28.956001116 +0100
+++ b/arch/powerpc/include/asm/syscalls.h   2022-10-30 
13:55:39.166300756 +0100

@@ -15,6 +15,7 @@
 #include 
 #include 

+long compat_sys_fallocate(int fd, int mode, u32 offset1, u32 offset2, 
u32 len1, u32 len2);

 #ifndef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
 long sys_ni_syscall(void);
 #else
diff -rupN a/arch/powerpc/include/asm/unistd.h 
b/arch/powerpc/include/asm/unistd.h

--- a/arch/powerpc/include/asm/unistd.h 2022-10-30 13:53:28.957001103 +0100
+++ b/arch/powerpc/include/asm/unistd.h 2022-10-30 13:56:44.851441888 +0100
@@ -45,7 +45,6 @@
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_NEWFSTATAT
 #define __ARCH_WANT_COMPAT_STAT
-#define __ARCH_WANT_COMPAT_FALLOCATE
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
 #endif
 #define __ARCH_WANT_SYS_FORK
diff -rupN a/arch/powerpc/kernel/sys_ppc32.c 
b/arch/powerpc/kernel/sys_ppc32.c

--- a/arch/powerpc/kernel/sys_ppc32.c   2022-10-30 13:53:28.967000972 +0100
+++ b/arch/powerpc/kernel/sys_ppc32.c   2022-10-30 13:58:28.993078689 +0100
@@ -97,6 +97,13 @@ PPC32_SYSCALL_DEFINE4(ppc_truncate64,
    return ksys_truncate(path, merge_64(len1, len2));
 }

+long compat_sys_fallocate(int fd, int mode, u32 offset1, u32 offset2,
+    u32 len1, u32 len2)
+{
+   return ksys_fallocate(fd, mode, merge_64(offset1, offset2),
+    merge_64(len1, len2));
+}
+
 PPC32_SYSCALL_DEFINE4(ppc_ftruncate64,
   unsigned int, fd, u32, reg4,
   unsigned long, len1, unsigned long, len2)


Re: [PATCH v6 21/25] powerpc: Provide syscall wrapper

2022-10-30 Thread Andreas Schwab
This breaks powerpc32.  The fallocate syscall misinterprets its
arguments.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."


Re: [PATCH v6 21/25] powerpc: Provide syscall wrapper

2022-10-30 Thread Andreas Schwab
It probably breaks every syscall with a 64-bit argument.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."


Re: [PATCH 1/2] powerpc/32: fix syscall wrappers with 64-bit arguments of unaligned register-pairs

2022-10-30 Thread Andreas Schwab
On Okt 12 2022, Nicholas Piggin wrote:

> diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl 
> b/arch/powerpc/kernel/syscalls/syscall.tbl
> index 2bca64f96164..e9e0df4f9a61 100644
> --- a/arch/powerpc/kernel/syscalls/syscall.tbl
> +++ b/arch/powerpc/kernel/syscalls/syscall.tbl
> @@ -228,8 +228,10 @@
>  176  64  rt_sigtimedwait sys_rt_sigtimedwait
>  177  nospu   rt_sigqueueinfo sys_rt_sigqueueinfo 
> compat_sys_rt_sigqueueinfo
>  178  nospu   rt_sigsuspend   sys_rt_sigsuspend   
> compat_sys_rt_sigsuspend
> -179  common  pread64 sys_pread64 
> compat_sys_ppc_pread64
> -180  common  pwrite64sys_pwrite64
> compat_sys_ppc_pwrite64
> +179  32  pread64 sys_ppc_pread64 
> compat_sys_ppc_pread64
> +179  64  pread64 sys_pread64
> +180  32  pwrite64sys_ppc_pwrite64
> compat_sys_ppc_pwrite64
> +180  64  pwrite64sys_pwrite64

Doesn't that lack entries for SPU?  Likewise for all other former common
syscalls in this patch.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."


Re: Issues with the first PowerPC updates for the kernel 6.1 #forregzbot

2022-10-30 Thread Thorsten Leemhuis
[Note: this mail is primarily send for documentation purposes and/or for
regzbot, my Linux kernel regression tracking bot. That's why I removed
most or all folks from the list of recipients, but left any that looked
like a mailing lists. These mails usually contain '#forregzbot' in the
subject, to make them easy to spot and filter out.]

[TLDR: I'm adding this regression report to the list of tracked
regressions; all text from me you find below is based on a few templates
paragraphs you might have encountered already already in similar form.]

Hi, this is your Linux kernel regression tracker.

On 12.10.22 08:51, Christian Zigotzky wrote:
> Hi All,
> 
> I use the Nemo board with a PASemi PA6T CPU and have some issues since the 
> first PowerPC updates for the kernel 6.1.
> 
> I successfully compiled the git kernel with the first PowerPC updates two 
> days ago.
> 
> Unfortunately this kernel is really dangerous. Many things for example 
> Network Manager and LightDM don't work anymore and produced several gigabyte 
> of config files till the partition has been filled.
> 
> I deleted some files like the resolv.conf that had a size over 200 GB!
> 
> Unfortunately, MintPPC was still damaged. For example LightDM doesn't work 
> anymore and the MATE desktop doesn't display any icons anymore because Caja 
> wasn't able to reserve memory anymore.
> 
> In this case, bisecting isn't an option and I have to wait some weeks. It is 
> really difficult to find the issue if the userland will damaged again and 
> again.

Thanks for the report. To be sure below issue doesn't fall through the
cracks unnoticed, I'm adding it to regzbot, my Linux kernel regression
tracking bot:

#regzbot ^introduced c2e7a19827eec443a7cb
#regzbot title ppc: PASemi PA6T CPU: Network Manager and LightDM and
fill volume with data
#regzbot ignore-activity

This isn't a regression? This issue or a fix for it are already
discussed somewhere else? It was fixed already? You want to clarify when
the regression started to happen? Or point out I got the title or
something else totally wrong? Then just reply -- ideally with also
telling regzbot about it, as explained here:
https://linux-regtracking.leemhuis.info/tracked-regression/

Reminder for developers: When fixing the issue, add 'Link:' tags
pointing to the report (the mail this one replies to), as explained for
in the Linux kernel's documentation; above webpage explains why this is
important for tracked regressions.

Ciao, Thorsten (wearing his 'the Linux kernel's regression tracker' hat)

P.S.: As the Linux kernel's regression tracker I deal with a lot of
reports and sometimes miss something important when writing mails like
this. If that's the case here, don't hesitate to tell me in a public
reply, it's in everyone's interest to set the public record straight.


Re: [PATCH v6 21/25] powerpc: Provide syscall wrapper

2022-10-30 Thread Arnd Bergmann
On Sun, Oct 30, 2022, at 16:34, Andreas Schwab wrote:
> This breaks powerpc32.  The fallocate syscall misinterprets its
> arguments.

It was fixed in

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e237506238352f3bfa9cf3983cdab873e35651eb

 Arnd


Re: [PATCH v4] hugetlb: simplify hugetlb handling in follow_page_mask

2022-10-30 Thread Peter Xu
On Fri, Oct 28, 2022 at 11:11:08AM -0700, Mike Kravetz wrote:
> +struct page *hugetlb_follow_page_mask(struct vm_area_struct *vma,
> + unsigned long address, unsigned int flags)
> +{
> + struct hstate *h = hstate_vma(vma);
> + struct mm_struct *mm = vma->vm_mm;
> + unsigned long haddr = address & huge_page_mask(h);
> + struct page *page = NULL;
> + spinlock_t *ptl;
> + pte_t *pte, entry;
> +
> + /*
> +  * FOLL_PIN is not supported for follow_page(). Ordinary GUP goes via
> +  * follow_hugetlb_page().
> +  */
> + if (WARN_ON_ONCE(flags & FOLL_PIN))
> + return NULL;
> +
> +retry:
> + pte = huge_pte_offset(mm, haddr, huge_page_size(h));
> + if (!pte)
> + return NULL;
> +
> + ptl = huge_pte_lock(h, mm, pte);
> + entry = huge_ptep_get(pte);
> + if (pte_present(entry)) {
> + page = pte_page(entry) +
> + ((address & ~huge_page_mask(h)) >> PAGE_SHIFT);
> + /*
> +  * Note that page may be a sub-page, and with vmemmap
> +  * optimizations the page struct may be read only.
> +  * try_grab_page() will increase the ref count on the
> +  * head page, so this will be OK.
> +  *
> +  * try_grab_page() should always succeed here, because we hold
> +  * the ptl lock and have verified pte_present().
> +  */
> + if (WARN_ON_ONCE(!try_grab_page(page, flags))) {
> + page = NULL;
> + goto out;
> + }
> + } else {
> + if (is_hugetlb_entry_migration(entry)) {
> + spin_unlock(ptl);
> + hugetlb_vma_unlock_read(vma);

Just noticed it when pulled the last mm-unstable: this line seems to be a
left-over of v3, while not needed now?

> + __migration_entry_wait_huge(pte, ptl);
> + goto retry;
> + }
> + /*
> +  * hwpoisoned entry is treated as no_page_table in
> +  * follow_page_mask().
> +  */
> + }
> +out:
> + spin_unlock(ptl);
> + return page;
> +}

-- 
Peter Xu



Re: [PATCH v6 21/25] powerpc: Provide syscall wrapper

2022-10-30 Thread Andreas Schwab
On Okt 30 2022, Arnd Bergmann wrote:

> On Sun, Oct 30, 2022, at 16:34, Andreas Schwab wrote:
>> This breaks powerpc32.  The fallocate syscall misinterprets its
>> arguments.
>
> It was fixed in

Nope.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."


[PATCH v5] hugetlb: simplify hugetlb handling in follow_page_mask

2022-10-30 Thread Mike Kravetz
During discussions of this series [1], it was suggested that hugetlb
handling code in follow_page_mask could be simplified.  At the beginning
of follow_page_mask, there currently is a call to follow_huge_addr which
'may' handle hugetlb pages.  ia64 is the only architecture which provides
a follow_huge_addr routine that does not return error.  Instead, at each
level of the page table a check is made for a hugetlb entry.  If a hugetlb
entry is found, a call to a routine associated with that entry is made.

Currently, there are two checks for hugetlb entries at each page table
level.  The first check is of the form:
if (p?d_huge())
page = follow_huge_p?d();
the second check is of the form:
if (is_hugepd())
page = follow_huge_pd().

We can replace these checks, as well as the special handling routines
such as follow_huge_p?d() and follow_huge_pd() with a single routine to
handle hugetlb vmas.

A new routine hugetlb_follow_page_mask is called for hugetlb vmas at the
beginning of follow_page_mask.  hugetlb_follow_page_mask will use the
existing routine huge_pte_offset to walk page tables looking for hugetlb
entries.  huge_pte_offset can be overwritten by architectures, and already
handles special cases such as hugepd entries.

[1] 
https://lore.kernel.org/linux-mm/cover.1661240170.git.baolin.w...@linux.alibaba.com/

Suggested-by: David Hildenbrand 
Signed-off-by: Mike Kravetz 
---
v5 -Remove left over hugetlb_vma_unlock_read
v4 -Remove vma (pmd sharing) locking as this can be called with
FOLL_NOWAIT. Peter
v3 -Change WARN_ON_ONCE() to BUILD_BUG() as reminded by Christophe Leroy
v2 -Added WARN_ON_ONCE() and updated comment as suggested by David
Fixed build issue found by kernel test robot
Added vma (pmd sharing) locking to hugetlb_follow_page_mask
ReBased on Baolin's patch to fix issues with CONT_* entries

 arch/ia64/mm/hugetlbpage.c|  15 ---
 arch/powerpc/mm/hugetlbpage.c |  37 
 include/linux/hugetlb.h   |  50 ++
 mm/gup.c  |  80 +++-
 mm/hugetlb.c  | 172 +++---
 5 files changed, 76 insertions(+), 278 deletions(-)

diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index f993cb36c062..380d2f3966c9 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -91,21 +91,6 @@ int prepare_hugepage_range(struct file *file,
return 0;
 }
 
-struct page *follow_huge_addr(struct mm_struct *mm, unsigned long addr, int 
write)
-{
-   struct page *page;
-   pte_t *ptep;
-
-   if (REGION_NUMBER(addr) != RGN_HPAGE)
-   return ERR_PTR(-EINVAL);
-
-   ptep = huge_pte_offset(mm, addr, HPAGE_SIZE);
-   if (!ptep || pte_none(*ptep))
-   return NULL;
-   page = pte_page(*ptep);
-   page += ((addr & ~HPAGE_MASK) >> PAGE_SHIFT);
-   return page;
-}
 int pmd_huge(pmd_t pmd)
 {
return 0;
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 5852a86d990d..f1ba8d1e8c1a 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -506,43 +506,6 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
} while (addr = next, addr != end);
 }
 
-struct page *follow_huge_pd(struct vm_area_struct *vma,
-   unsigned long address, hugepd_t hpd,
-   int flags, int pdshift)
-{
-   pte_t *ptep;
-   spinlock_t *ptl;
-   struct page *page = NULL;
-   unsigned long mask;
-   int shift = hugepd_shift(hpd);
-   struct mm_struct *mm = vma->vm_mm;
-
-retry:
-   /*
-* hugepage directory entries are protected by mm->page_table_lock
-* Use this instead of huge_pte_lockptr
-*/
-   ptl = &mm->page_table_lock;
-   spin_lock(ptl);
-
-   ptep = hugepte_offset(hpd, address, pdshift);
-   if (pte_present(*ptep)) {
-   mask = (1UL << shift) - 1;
-   page = pte_page(*ptep);
-   page += ((address & mask) >> PAGE_SHIFT);
-   if (flags & FOLL_GET)
-   get_page(page);
-   } else {
-   if (is_hugetlb_entry_migration(*ptep)) {
-   spin_unlock(ptl);
-   __migration_entry_wait(mm, ptep, ptl);
-   goto retry;
-   }
-   }
-   spin_unlock(ptl);
-   return page;
-}
-
 bool __init arch_hugetlb_valid_size(unsigned long size)
 {
int shift = __ffs(size);
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 8b4f93e84868..4a76c0fc6bbf 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -149,6 +149,8 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma,
 unsigned long len);
 int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *,
struct vm_area

Re: [PATCH v4] hugetlb: simplify hugetlb handling in follow_page_mask

2022-10-30 Thread Mike Kravetz
On 10/30/22 15:45, Peter Xu wrote:
> On Fri, Oct 28, 2022 at 11:11:08AM -0700, Mike Kravetz wrote:
> > +   } else {
> > +   if (is_hugetlb_entry_migration(entry)) {
> > +   spin_unlock(ptl);
> > +   hugetlb_vma_unlock_read(vma);
> 
> Just noticed it when pulled the last mm-unstable: this line seems to be a
> left-over of v3, while not needed now?
> 
> > +   __migration_entry_wait_huge(pte, ptl);
> > +   goto retry;
> > +   }

Thanks Peter!

Sent v5 with the that line removed.

-- 
Mike Kravetz


Re: [PATCH v2 -next] powerpc/powermac: Fix symbol not declared warnings

2022-10-30 Thread chenlifu

在 2022/8/19 21:06, Chen Lifu 写道:

1. ppc_override_l2cr and ppc_override_l2cr_value are only used in
l2cr_init() function, remove them and used *l2cr directly.
2. has_l2cache is not used outside of the file, so mark it static and
do not initialise statics to 0.

Fixes the following warning:

arch/powerpc/platforms/powermac/setup.c:74:5: warning: symbol 
'ppc_override_l2cr' was not declared. Should it be static?
arch/powerpc/platforms/powermac/setup.c:75:5: warning: symbol 
'ppc_override_l2cr_value' was not declared. Should it be static?
arch/powerpc/platforms/powermac/setup.c:76:5: warning: symbol 'has_l2cache' was 
not declared. Should it be static?

Signed-off-by: Chen Lifu 
---
  arch/powerpc/platforms/powermac/setup.c | 19 ++-
  1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/platforms/powermac/setup.c 
b/arch/powerpc/platforms/powermac/setup.c
index 04daa7f0a03c..49faa066b372 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -68,13 +68,11 @@
  
  #include "pmac.h"
  
  #undef SHOW_GATWICK_IRQS
  
-int ppc_override_l2cr = 0;

-int ppc_override_l2cr_value;
-int has_l2cache = 0;
+static int has_l2cache;
  
  int pmac_newworld;
  
  static int current_root_goodness = -1;
  
@@ -234,26 +232,21 @@ static void __init l2cr_init(void)
  
  		for_each_of_cpu_node(np) {

const unsigned int *l2cr =
of_get_property(np, "l2cr-value", NULL);
if (l2cr) {
-   ppc_override_l2cr = 1;
-   ppc_override_l2cr_value = *l2cr;
_set_L2CR(0);
-   _set_L2CR(ppc_override_l2cr_value);
+   _set_L2CR(*l2cr);
+   printk(KERN_INFO "L2CR overridden (0x%x), "
+  "backside cache is %s\n",
+  *l2cr, ((*l2cr) & 0x8000) ?
+  "enabled" : "disabled");
}
of_node_put(np);
break;
}
}
-
-   if (ppc_override_l2cr)
-   printk(KERN_INFO "L2CR overridden (0x%x), "
-  "backside cache is %s\n",
-  ppc_override_l2cr_value,
-  (ppc_override_l2cr_value & 0x8000)
-   ? "enabled" : "disabled");
  }
  #endif
  
  static void __init pmac_setup_arch(void)

  {


Friendly ping ...



Re: [PATCH v6 21/25] powerpc: Provide syscall wrapper

2022-10-30 Thread Michael Ellerman
Andreas Schwab  writes:
> On Okt 30 2022, Arnd Bergmann wrote:
>
>> On Sun, Oct 30, 2022, at 16:34, Andreas Schwab wrote:
>>> This breaks powerpc32.  The fallocate syscall misinterprets its
>>> arguments.
>>
>> It was fixed in
>
> Nope.

Ack.


[RFC PATCH 01/19] powerpc/perf: callchain validate kernel stack pointer bounds

2022-10-30 Thread Nicholas Piggin
The interrupt frame detection and loads from the hypothetical pt_regs
are not bounds-checked. The next-frame validation only bounds-checks
STACK_FRAME_OVERHEAD, which does not include the pt_regs. Add another
test for this.

Signed-off-by: Nicholas Piggin 
---

Could the user set r1 to be equal to the address matching the first
interrupt frame - STACK_INT_FRAME_SIZE, which is in the previous page
due to the kernel redzone, and induce the kernel to load the marker from
there? Possibly it could cause a crash at least.

It also seems a bit rude to put a fancy next-frame-validation out in
perf/ rather than with the rest of the frame validation code.

Thanks,
Nick

 arch/powerpc/perf/callchain.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index 082f6d0308a4..8718289c051d 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -61,6 +61,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, 
struct pt_regs *re
next_sp = fp[0];
 
if (next_sp == sp + STACK_INT_FRAME_SIZE &&
+   validate_sp(sp, current, STACK_INT_FRAME_SIZE) &&
fp[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
/*
 * This looks like an interrupt frame for an
-- 
2.37.2



[RFC PATCH 00/19] Remove STACK_FRAME_OVERHEAD

2022-10-30 Thread Nicholas Piggin
This is some quick hacking, hardly tested but might have potential.

I think we're not validating the perf kernel stack walker bounds
quite correctly, and not setting up decent stack frames for the child
in copy_thread. So at least those two things we could do. Maybe
patch 1 should go upstream as a fix.

Thanks,
Nick

Nicholas Piggin (19):
  powerpc/perf: callchain validate kernel stack pointer bounds
  powerpc: Rearrange copy_thread child stack creation
  powerpc/64: Remove asm interrupt tracing call helpers
  powerpc/pseries: hvcall stack frame overhead
  powerpc/32: Use load and store multiple in GPR save/restore macros
  powerpc: simplify ppc_save_regs
  powerpc: add definition for pt_regs offset within an interrupt frame
  powerpc: add a definition for the marker offset within the interrupt
frame
  powerpc: Rename STACK_FRAME_MARKER and derive it from frame offset
  powerpc: add a define for the user interrupt frame size
  powerpc: add a define for the switch frame size and regs offset
  powerpc: copy_thread fill in interrupt frame marker and back chain
  powerpc: copy_thread add a back chain to the switch stack frame
  powerpc: split validate_sp into two functions
  powerpc: allow minimum sized kernel stack frames
  powerpc/64: ELFv2 use minimal stack frames in int and switch frame
sizes
  powerpc: remove STACK_FRAME_OVERHEAD
  powerpc: change stack marker memory operations to 32-bit
  powerpc/64: ELFv2 use reserved word in the stack frame for the regs
marker

 arch/powerpc/include/asm/irqflags.h   | 29 ---
 arch/powerpc/include/asm/ppc_asm.h| 18 +++-
 arch/powerpc/include/asm/processor.h  | 15 +++-
 arch/powerpc/include/asm/ptrace.h | 41 +++---
 arch/powerpc/kernel/asm-offsets.c |  9 +-
 arch/powerpc/kernel/entry_32.S| 14 ++--
 arch/powerpc/kernel/exceptions-64e.S  | 44 +-
 arch/powerpc/kernel/exceptions-64s.S  | 82 +--
 arch/powerpc/kernel/head_32.h |  4 +-
 arch/powerpc/kernel/head_40x.S|  2 +-
 arch/powerpc/kernel/head_44x.S|  6 +-
 arch/powerpc/kernel/head_64.S |  6 +-
 arch/powerpc/kernel/head_85xx.S   |  8 +-
 arch/powerpc/kernel/head_8xx.S|  2 +-
 arch/powerpc/kernel/head_book3s_32.S  |  4 +-
 arch/powerpc/kernel/head_booke.h  |  4 +-
 arch/powerpc/kernel/interrupt_64.S| 32 
 arch/powerpc/kernel/irq.c |  4 +-
 arch/powerpc/kernel/kgdb.c|  2 +-
 arch/powerpc/kernel/misc_32.S |  2 +-
 arch/powerpc/kernel/misc_64.S |  4 +-
 arch/powerpc/kernel/optprobes_head.S  |  4 +-
 arch/powerpc/kernel/ppc_save_regs.S   | 58 -
 arch/powerpc/kernel/process.c | 54 +++-
 arch/powerpc/kernel/smp.c |  2 +-
 arch/powerpc/kernel/stacktrace.c  | 10 +--
 arch/powerpc/kernel/tm.S  |  8 +-
 arch/powerpc/kernel/trace/ftrace_mprofile.S   |  2 +-
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   |  2 +-
 .../lib/test_emulate_step_exec_instr.S|  2 +-
 arch/powerpc/perf/callchain.c |  9 +-
 arch/powerpc/platforms/pseries/hvCall.S   | 38 +
 arch/powerpc/xmon/xmon.c  | 10 +--
 33 files changed, 263 insertions(+), 268 deletions(-)

-- 
2.37.2



[RFC PATCH 02/19] powerpc: Rearrange copy_thread child stack creation

2022-10-30 Thread Nicholas Piggin
This makes it a bit clearer where the stack frame is created, and will
allow easier use of some of the stack offset constants in a later
change.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/kernel/process.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 67da147fe34d..acfa197fb2df 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1726,13 +1726,16 @@ int copy_thread(struct task_struct *p, const struct 
kernel_clone_args *args)
 
klp_init_thread_info(p);
 
+   /* Create initial stack frame. */
+   sp -= (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD);
+   ((unsigned long *)sp)[0] = 0;
+
/* Copy registers */
-   sp -= sizeof(struct pt_regs);
-   childregs = (struct pt_regs *) sp;
+   childregs = (struct pt_regs *)(sp + STACK_FRAME_OVERHEAD);
if (unlikely(args->fn)) {
/* kernel thread */
memset(childregs, 0, sizeof(struct pt_regs));
-   childregs->gpr[1] = sp + sizeof(struct pt_regs);
+   childregs->gpr[1] = sp + (sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD);
/* function */
if (args->fn)
childregs->gpr[14] = ppc_function_entry((void 
*)args->fn);
@@ -1767,7 +1770,6 @@ int copy_thread(struct task_struct *p, const struct 
kernel_clone_args *args)
f = ret_from_fork;
}
childregs->msr &= ~(MSR_FP|MSR_VEC|MSR_VSX);
-   sp -= STACK_FRAME_OVERHEAD;
 
/*
 * The way this works is that at some point in the future
@@ -1777,7 +1779,6 @@ int copy_thread(struct task_struct *p, const struct 
kernel_clone_args *args)
 * do some house keeping and then return from the fork or clone
 * system call, using the stack frame created above.
 */
-   ((unsigned long *)sp)[0] = 0;
sp -= sizeof(struct pt_regs);
kregs = (struct pt_regs *) sp;
sp -= STACK_FRAME_OVERHEAD;
-- 
2.37.2



[RFC PATCH 03/19] powerpc/64: Remove asm interrupt tracing call helpers

2022-10-30 Thread Nicholas Piggin
These are unused. Remove.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/irqflags.h | 29 -
 1 file changed, 29 deletions(-)

diff --git a/arch/powerpc/include/asm/irqflags.h 
b/arch/powerpc/include/asm/irqflags.h
index 1a6c1ce17735..81e0a5025be8 100644
--- a/arch/powerpc/include/asm/irqflags.h
+++ b/arch/powerpc/include/asm/irqflags.h
@@ -13,32 +13,6 @@
 
 #else
 #ifdef CONFIG_TRACE_IRQFLAGS
-#ifdef CONFIG_IRQSOFF_TRACER
-/*
- * Since the ftrace irqsoff latency trace checks CALLER_ADDR1,
- * which is the stack frame here, we need to force a stack frame
- * in case we came from user space.
- */
-#define TRACE_WITH_FRAME_BUFFER(func)  \
-   mflrr0; \
-   stdur1, -STACK_FRAME_OVERHEAD(r1);  \
-   std r0, 16(r1); \
-   stdur1, -STACK_FRAME_OVERHEAD(r1);  \
-   bl func;\
-   ld  r1, 0(r1);  \
-   ld  r1, 0(r1);
-#else
-#define TRACE_WITH_FRAME_BUFFER(func)  \
-   bl func;
-#endif
-
-/*
- * These are calls to C code, so the caller must be prepared for volatiles to
- * be clobbered.
- */
-#define TRACE_ENABLE_INTS  TRACE_WITH_FRAME_BUFFER(trace_hardirqs_on)
-#define TRACE_DISABLE_INTS TRACE_WITH_FRAME_BUFFER(trace_hardirqs_off)
-
 /*
  * This is used by assembly code to soft-disable interrupts first and
  * reconcile irq state.
@@ -59,9 +33,6 @@
 44:
 
 #else
-#define TRACE_ENABLE_INTS
-#define TRACE_DISABLE_INTS
-
 #define RECONCILE_IRQ_STATE(__rA, __rB)\
lbz __rA,PACAIRQHAPPENED(r13);  \
li  __rB,IRQS_DISABLED; \
-- 
2.37.2



[RFC PATCH 04/19] powerpc/pseries: hvcall stack frame overhead

2022-10-30 Thread Nicholas Piggin
This call may use the min size stack frame. The scratch space used is
in the caller's parameter area frame, not this function's frame.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/platforms/pseries/hvCall.S | 38 +
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hvCall.S 
b/arch/powerpc/platforms/pseries/hvCall.S
index 762eb15d3bd4..783c16ad648b 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -27,7 +27,9 @@ hcall_tracepoint_refcount:
 
 /*
  * precall must preserve all registers.  use unused STK_PARAM()
- * areas to save snapshots and opcode.
+ * areas to save snapshots and opcode. STK_PARAM() in the caller's
+ * frame will be available even on ELFv2 because these are all
+ * variadic functions.
  */
 #define HCALL_INST_PRECALL(FIRST_REG)  \
mflrr0; \
@@ -41,29 +43,29 @@ hcall_tracepoint_refcount:
std r10,STK_PARAM(R10)(r1); \
std r0,16(r1);  \
addir4,r1,STK_PARAM(FIRST_REG); \
-   stdur1,-STACK_FRAME_OVERHEAD(r1);   \
+   stdur1,-STACK_FRAME_MIN_SIZE(r1);   \
bl  __trace_hcall_entry;\
-   ld  r3,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1);  \
-   ld  r4,STACK_FRAME_OVERHEAD+STK_PARAM(R4)(r1);  \
-   ld  r5,STACK_FRAME_OVERHEAD+STK_PARAM(R5)(r1);  \
-   ld  r6,STACK_FRAME_OVERHEAD+STK_PARAM(R6)(r1);  \
-   ld  r7,STACK_FRAME_OVERHEAD+STK_PARAM(R7)(r1);  \
-   ld  r8,STACK_FRAME_OVERHEAD+STK_PARAM(R8)(r1);  \
-   ld  r9,STACK_FRAME_OVERHEAD+STK_PARAM(R9)(r1);  \
-   ld  r10,STACK_FRAME_OVERHEAD+STK_PARAM(R10)(r1)
+   ld  r3,STACK_FRAME_MIN_SIZE+STK_PARAM(R3)(r1);  \
+   ld  r4,STACK_FRAME_MIN_SIZE+STK_PARAM(R4)(r1);  \
+   ld  r5,STACK_FRAME_MIN_SIZE+STK_PARAM(R5)(r1);  \
+   ld  r6,STACK_FRAME_MIN_SIZE+STK_PARAM(R6)(r1);  \
+   ld  r7,STACK_FRAME_MIN_SIZE+STK_PARAM(R7)(r1);  \
+   ld  r8,STACK_FRAME_MIN_SIZE+STK_PARAM(R8)(r1);  \
+   ld  r9,STACK_FRAME_MIN_SIZE+STK_PARAM(R9)(r1);  \
+   ld  r10,STACK_FRAME_MIN_SIZE+STK_PARAM(R10)(r1)
 
 /*
  * postcall is performed immediately before function return which
  * allows liberal use of volatile registers.
  */
 #define __HCALL_INST_POSTCALL  \
-   ld  r0,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1);  \
-   std r3,STACK_FRAME_OVERHEAD+STK_PARAM(R3)(r1);  \
+   ld  r0,STACK_FRAME_MIN_SIZE+STK_PARAM(R3)(r1);  \
+   std r3,STACK_FRAME_MIN_SIZE+STK_PARAM(R3)(r1);  \
mr  r4,r3;  \
mr  r3,r0;  \
bl  __trace_hcall_exit; \
-   ld  r0,STACK_FRAME_OVERHEAD+16(r1); \
-   addir1,r1,STACK_FRAME_OVERHEAD; \
+   ld  r0,STACK_FRAME_MIN_SIZE+16(r1); \
+   addir1,r1,STACK_FRAME_MIN_SIZE; \
ld  r3,STK_PARAM(R3)(r1);   \
mtlrr0
 
@@ -303,14 +305,14 @@ plpar_hcall9_trace:
mr  r7,r8
mr  r8,r9
mr  r9,r10
-   ld  r10,STACK_FRAME_OVERHEAD+STK_PARAM(R11)(r1)
-   ld  r11,STACK_FRAME_OVERHEAD+STK_PARAM(R12)(r1)
-   ld  r12,STACK_FRAME_OVERHEAD+STK_PARAM(R13)(r1)
+   ld  r10,STACK_FRAME_MIN_SIZE+STK_PARAM(R11)(r1)
+   ld  r11,STACK_FRAME_MIN_SIZE+STK_PARAM(R12)(r1)
+   ld  r12,STACK_FRAME_MIN_SIZE+STK_PARAM(R13)(r1)
 
HVSC
 
mr  r0,r12
-   ld  r12,STACK_FRAME_OVERHEAD+STK_PARAM(R4)(r1)
+   ld  r12,STACK_FRAME_MIN_SIZE+STK_PARAM(R4)(r1)
std r4,0(r12)
std r5,8(r12)
std r6,16(r12)
-- 
2.37.2



[RFC PATCH 05/19] powerpc/32: Use load and store multiple in GPR save/restore macros

2022-10-30 Thread Nicholas Piggin
---
 arch/powerpc/include/asm/ppc_asm.h | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/ppc_asm.h 
b/arch/powerpc/include/asm/ppc_asm.h
index 753a2757bcd4..ac44383d350a 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -57,8 +57,22 @@
 #define SAVE_NVGPRS(base)  SAVE_GPRS(14, 31, base)
 #define REST_NVGPRS(base)  REST_GPRS(14, 31, base)
 #else
-#define SAVE_GPRS(start, end, base)OP_REGS stw, 4, start, end, base, GPR0
-#define REST_GPRS(start, end, base)OP_REGS lwz, 4, start, end, base, GPR0
+.macro __SAVE_GPRS start, end, base, offset
+   .if \end == 31
+   stmw\start,\offset(\base)
+   .else
+   OP_REGS stw, 4, \start, \end, \base, \offset
+   .endif
+.endm
+.macro __REST_GPRS start, end, base, offset
+   .if \end == 31
+   lmw \start,\offset(\base)
+   .else
+   OP_REGS lwz, 4, \start, \end, \base, \offset
+   .endif
+.endm
+#define SAVE_GPRS(start, end, base)__SAVE_GPRS start, end, base, GPR0
+#define REST_GPRS(start, end, base)__REST_GPRS start, end, base, GPR0
 #define SAVE_NVGPRS(base)  SAVE_GPRS(13, 31, base)
 #define REST_NVGPRS(base)  REST_GPRS(13, 31, base)
 #endif
-- 
2.37.2



[RFC PATCH 06/19] powerpc: simplify ppc_save_regs

2022-10-30 Thread Nicholas Piggin
Adjust the pt_regs pointer so the interrupt frame offsets can be used
directly to save registers.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/kernel/ppc_save_regs.S | 58 +++--
 1 file changed, 14 insertions(+), 44 deletions(-)

diff --git a/arch/powerpc/kernel/ppc_save_regs.S 
b/arch/powerpc/kernel/ppc_save_regs.S
index 2d4d21bb46a9..2908a5c2cd2f 100644
--- a/arch/powerpc/kernel/ppc_save_regs.S
+++ b/arch/powerpc/kernel/ppc_save_regs.S
@@ -21,60 +21,30 @@
  * different ABIs, though).
  */
 _GLOBAL(ppc_save_regs)
-   PPC_STL r0,0*SZL(r3)
-#ifdef CONFIG_PPC32
-   stmwr2, 2*SZL(r3)
-#else
-   PPC_STL r2,2*SZL(r3)
-   PPC_STL r3,3*SZL(r3)
-   PPC_STL r4,4*SZL(r3)
-   PPC_STL r5,5*SZL(r3)
-   PPC_STL r6,6*SZL(r3)
-   PPC_STL r7,7*SZL(r3)
-   PPC_STL r8,8*SZL(r3)
-   PPC_STL r9,9*SZL(r3)
-   PPC_STL r10,10*SZL(r3)
-   PPC_STL r11,11*SZL(r3)
-   PPC_STL r12,12*SZL(r3)
-   PPC_STL r13,13*SZL(r3)
-   PPC_STL r14,14*SZL(r3)
-   PPC_STL r15,15*SZL(r3)
-   PPC_STL r16,16*SZL(r3)
-   PPC_STL r17,17*SZL(r3)
-   PPC_STL r18,18*SZL(r3)
-   PPC_STL r19,19*SZL(r3)
-   PPC_STL r20,20*SZL(r3)
-   PPC_STL r21,21*SZL(r3)
-   PPC_STL r22,22*SZL(r3)
-   PPC_STL r23,23*SZL(r3)
-   PPC_STL r24,24*SZL(r3)
-   PPC_STL r25,25*SZL(r3)
-   PPC_STL r26,26*SZL(r3)
-   PPC_STL r27,27*SZL(r3)
-   PPC_STL r28,28*SZL(r3)
-   PPC_STL r29,29*SZL(r3)
-   PPC_STL r30,30*SZL(r3)
-   PPC_STL r31,31*SZL(r3)
+   /* This allows stack frame accessor macros and offsets to be used */
+   subir3,r3,STACK_FRAME_OVERHEAD
+   SAVE_GPRS(0, 31, r3)
+#ifdef CONFIG_PPC64
lbz r0,PACAIRQSOFTMASK(r13)
-   PPC_STL r0,SOFTE-STACK_FRAME_OVERHEAD(r3)
+   PPC_STL r0,SOFTE(r3)
 #endif
/* go up one stack frame for SP */
PPC_LL  r4,0(r1)
-   PPC_STL r4,1*SZL(r3)
+   PPC_STL r4,GPR1(r3)
/* get caller's LR */
PPC_LL  r0,LRSAVE(r4)
-   PPC_STL r0,_LINK-STACK_FRAME_OVERHEAD(r3)
+   PPC_STL r0,_LINK(r3)
mflrr0
-   PPC_STL r0,_NIP-STACK_FRAME_OVERHEAD(r3)
+   PPC_STL r0,_NIP(r3)
mfmsr   r0
-   PPC_STL r0,_MSR-STACK_FRAME_OVERHEAD(r3)
+   PPC_STL r0,_MSR(r3)
mfctr   r0
-   PPC_STL r0,_CTR-STACK_FRAME_OVERHEAD(r3)
+   PPC_STL r0,_CTR(r3)
mfxer   r0
-   PPC_STL r0,_XER-STACK_FRAME_OVERHEAD(r3)
+   PPC_STL r0,_XER(r3)
mfcrr0
-   PPC_STL r0,_CCR-STACK_FRAME_OVERHEAD(r3)
+   PPC_STL r0,_CCR(r3)
li  r0,0
-   PPC_STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3)
-   PPC_STL r0,ORIG_GPR3-STACK_FRAME_OVERHEAD(r3)
+   PPC_STL r0,_TRAP(r3)
+   PPC_STL r0,ORIG_GPR3(r3)
blr
-- 
2.37.2



[RFC PATCH 07/19] powerpc: add definition for pt_regs offset within an interrupt frame

2022-10-30 Thread Nicholas Piggin
This is a common offset that currently uses the overloaded
STACK_FRAME_OVERHEAD constant. It's easier to read and more
flexible to use a specific regs offset for this.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/ptrace.h |  2 +
 arch/powerpc/kernel/asm-offsets.c |  7 +-
 arch/powerpc/kernel/entry_32.S|  6 +-
 arch/powerpc/kernel/exceptions-64e.S  | 42 +-
 arch/powerpc/kernel/exceptions-64s.S  | 80 +--
 arch/powerpc/kernel/head_32.h |  2 +-
 arch/powerpc/kernel/head_85xx.S   |  4 +-
 arch/powerpc/kernel/head_booke.h  |  2 +-
 arch/powerpc/kernel/interrupt_64.S| 22 ++---
 arch/powerpc/kernel/kgdb.c|  2 +-
 arch/powerpc/kernel/optprobes_head.S  |  4 +-
 arch/powerpc/kernel/ppc_save_regs.S   |  2 +-
 arch/powerpc/kernel/process.c |  4 +-
 arch/powerpc/kernel/tm.S  |  8 +-
 arch/powerpc/kernel/trace/ftrace_mprofile.S   |  2 +-
 .../lib/test_emulate_step_exec_instr.S|  2 +-
 arch/powerpc/perf/callchain.c |  2 +-
 arch/powerpc/xmon/xmon.c  |  7 +-
 18 files changed, 100 insertions(+), 100 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index 2efec6d87049..a4ae67aa9b76 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -124,6 +124,7 @@ struct pt_regs
 #define STACK_FRAME_LR_SAVE2   /* Location of LR in stack frame */
 #define STACK_INT_FRAME_SIZE   (sizeof(struct pt_regs) + \
 STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE)
+#define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
 #define STACK_FRAME_MARKER 12
 
 #ifdef CONFIG_PPC64_ELF_ABI_V2
@@ -143,6 +144,7 @@ struct pt_regs
 #define STACK_FRAME_OVERHEAD   16  /* size of minimum stack frame */
 #define STACK_FRAME_LR_SAVE1   /* Location of LR in stack frame */
 #define STACK_INT_FRAME_SIZE   (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
+#define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
 #define STACK_FRAME_MARKER 2
 #define STACK_FRAME_MIN_SIZE   STACK_FRAME_OVERHEAD
 
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 4ce2a4aa3985..db5e66c1d031 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -72,7 +72,7 @@
 #endif
 
 #define STACK_PT_REGS_OFFSET(sym, val) \
-   DEFINE(sym, STACK_FRAME_OVERHEAD + offsetof(struct pt_regs, val))
+   DEFINE(sym, STACK_INT_FRAME_REGS + offsetof(struct pt_regs, val))
 
 int main(void)
 {
@@ -167,9 +167,8 @@ int main(void)
OFFSET(THREAD_CKVRSTATE, thread_struct, ckvr_state.vr);
OFFSET(THREAD_CKVRSAVE, thread_struct, ckvrsave);
OFFSET(THREAD_CKFPSTATE, thread_struct, ckfp_state.fpr);
-   /* Local pt_regs on stack for Transactional Memory funcs. */
-   DEFINE(TM_FRAME_SIZE, STACK_FRAME_OVERHEAD +
-  sizeof(struct pt_regs) + 16);
+   /* Local pt_regs on stack in int frame form, plus 16 bytes for TM */
+   DEFINE(TM_FRAME_SIZE, STACK_INT_FRAME_SIZE + 16);
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 
OFFSET(TI_LOCAL_FLAGS, thread_info, local_flags);
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 3fc7c9886bb7..24c8d84a56c9 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -123,12 +123,12 @@ transfer_to_syscall:
kuep_lock
 
/* Calling convention has r3 = regs, r4 = orig r0 */
-   addir3,r1,STACK_FRAME_OVERHEAD
+   addir3,r1,STACK_INT_FRAME_REGS
mr  r4,r0
bl  system_call_exception
 
 ret_from_syscall:
-   addir4,r1,STACK_FRAME_OVERHEAD
+   addir4,r1,STACK_INT_FRAME_REGS
li  r5,0
bl  syscall_exit_prepare
 #ifdef CONFIG_PPC_47x
@@ -293,7 +293,7 @@ _ASM_NOKPROBE_SYMBOL(fast_exception_return)
.globl interrupt_return
 interrupt_return:
lwz r4,_MSR(r1)
-   addir3,r1,STACK_FRAME_OVERHEAD
+   addir3,r1,STACK_INT_FRAME_REGS
andi.   r0,r4,MSR_PR
beq .Lkernel_interrupt_return
bl  interrupt_exit_user_prepare
diff --git a/arch/powerpc/kernel/exceptions-64e.S 
b/arch/powerpc/kernel/exceptions-64e.S
index 930e36099015..f6b36083a8c2 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -455,7 +455,7 @@ exc_##n##_bad_stack:
\
EXCEPTION_COMMON(trapnum)   \
ack(r8);\
CHECK_NAPPING();\
-   addir3,r1,STACK_FRAME_OVERHEAD; \
+   addir3,r1,STACK_INT_FRAME_REGS;   

[RFC PATCH 08/19] powerpc: add a definition for the marker offset within the interrupt frame

2022-10-30 Thread Nicholas Piggin
Define a constant rather than open-code the offset for the
"regs" marker.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/ptrace.h   |  2 ++
 arch/powerpc/kernel/entry_32.S  |  2 +-
 arch/powerpc/kernel/exceptions-64e.S|  2 +-
 arch/powerpc/kernel/exceptions-64s.S|  2 +-
 arch/powerpc/kernel/head_32.h   |  2 +-
 arch/powerpc/kernel/head_booke.h|  2 +-
 arch/powerpc/kernel/interrupt_64.S  | 10 +-
 arch/powerpc/kvm/book3s_hv_rmhandlers.S |  2 +-
 8 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index a4ae67aa9b76..8a9f4cf8c4c5 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -125,6 +125,7 @@ struct pt_regs
 #define STACK_INT_FRAME_SIZE   (sizeof(struct pt_regs) + \
 STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE)
 #define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
+#define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 16)
 #define STACK_FRAME_MARKER 12
 
 #ifdef CONFIG_PPC64_ELF_ABI_V2
@@ -145,6 +146,7 @@ struct pt_regs
 #define STACK_FRAME_LR_SAVE1   /* Location of LR in stack frame */
 #define STACK_INT_FRAME_SIZE   (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
 #define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
+#define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 8)
 #define STACK_FRAME_MARKER 2
 #define STACK_FRAME_MIN_SIZE   STACK_FRAME_OVERHEAD
 
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 24c8d84a56c9..2f61b7d3677c 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -114,7 +114,7 @@ transfer_to_syscall:
addir12,r12,STACK_FRAME_REGS_MARKER@l
stw r9,_MSR(r1)
li  r2, INTERRUPT_SYSCALL
-   stw r12,8(r1)
+   stw r12,STACK_INT_FRAME_MARKER(r1)
stw r2,_TRAP(r1)
SAVE_GPR(0, r1)
SAVE_GPRS(3, 8, r1)
diff --git a/arch/powerpc/kernel/exceptions-64e.S 
b/arch/powerpc/kernel/exceptions-64e.S
index f6b36083a8c2..d74c2a53af13 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -391,7 +391,7 @@ exc_##n##_common:   
\
std r10,_CCR(r1);   /* store orig CR in stackframe */   \
std r9,GPR1(r1);/* store stack frame back link */   \
std r11,SOFTE(r1);  /* and save it to stackframe */ \
-   std r12,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */   \
+   std r12,STACK_INT_FRAME_MARKER(r1); /* mark the frame */\
std r3,_TRAP(r1);   /* set trap number  */  \
std r0,RESULT(r1);  /* clear regs->result */\
SAVE_NVGPRS(r1);
diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index 907054940a07..39f08ec56126 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -591,7 +591,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
li  r10,0
LOAD_REG_IMMEDIATE(r11, STACK_FRAME_REGS_MARKER)
std r10,RESULT(r1)  /* clear regs->result   */
-   std r11,STACK_FRAME_OVERHEAD-16(r1) /* mark the frame   */
+   std r11,STACK_INT_FRAME_MARKER(r1) /* mark the frame*/
 .endm
 
 /*
diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h
index 117d25330e13..f8e2911478a7 100644
--- a/arch/powerpc/kernel/head_32.h
+++ b/arch/powerpc/kernel/head_32.h
@@ -112,7 +112,7 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
stw r0,GPR0(r1)
lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
addir10,r10,STACK_FRAME_REGS_MARKER@l
-   stw r10,8(r1)
+   stw r10,STACK_INT_FRAME_MARKER(r1)
li  r10, \trapno
stw r10,_TRAP(r1)
SAVE_GPRS(3, 8, r1)
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 3149ac20b18e..37d43c172676 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -84,7 +84,7 @@ END_BTB_FLUSH_SECTION
stw r0,GPR0(r1)
lis r10, STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
addir10, r10, STACK_FRAME_REGS_MARKER@l
-   stw r10, 8(r1)
+   stw r10, STACK_INT_FRAME_MARKER(r1)
li  r10, \trapno
stw r10,_TRAP(r1)
SAVE_GPRS(3, 8, r1)
diff --git a/arch/powerpc/kernel/interrupt_64.S 
b/arch/powerpc/kernel/interrupt_64.S
index 12807d5298a3..2306b979e71f 100644
--- a/arch/powerpc/kernel/interrupt_64.S
+++ b/arch/powerpc/kernel/interrupt_64.S
@@ -77,11 +77,11 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
std r11,_TRAP(r1)
std r12,_CCR(r1)
std r3,ORIG_GPR3(r1)
+   LOAD_REG_IMMEDIATE(r

[RFC PATCH 09/19] powerpc: Rename STACK_FRAME_MARKER and derive it from frame offset

2022-10-30 Thread Nicholas Piggin
This is a count of longs from the stack pointer to the regs marker.
Rename it to make it more distinct from the other byte offsets. It
can be derived from the byte offset definitions just added.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/ptrace.h | 4 ++--
 arch/powerpc/kernel/process.c | 2 +-
 arch/powerpc/kernel/stacktrace.c  | 2 +-
 arch/powerpc/perf/callchain.c | 2 +-
 arch/powerpc/xmon/xmon.c  | 3 +--
 5 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index 8a9f4cf8c4c5..fdd50648df56 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -126,7 +126,6 @@ struct pt_regs
 STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE)
 #define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
 #define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 16)
-#define STACK_FRAME_MARKER 12
 
 #ifdef CONFIG_PPC64_ELF_ABI_V2
 #define STACK_FRAME_MIN_SIZE   32
@@ -147,7 +146,6 @@ struct pt_regs
 #define STACK_INT_FRAME_SIZE   (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
 #define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
 #define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 8)
-#define STACK_FRAME_MARKER 2
 #define STACK_FRAME_MIN_SIZE   STACK_FRAME_OVERHEAD
 
 /* Size of stack frame allocated when calling signal handler. */
@@ -155,6 +153,8 @@ struct pt_regs
 
 #endif /* __powerpc64__ */
 
+#define STACK_INT_FRAME_MARKER_LONGS   (STACK_INT_FRAME_MARKER/sizeof(long))
+
 #ifndef __ASSEMBLY__
 #include 
 
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index e7010f71de24..b0a9e5eeec4c 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -2234,7 +2234,7 @@ void __no_sanitize_address show_stack(struct task_struct 
*tsk,
 * We look for the "regs" marker in the current frame.
 */
if (validate_sp(sp, tsk, STACK_FRAME_WITH_PT_REGS)
-   && stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
+   && stack[STACK_INT_FRAME_MARKER_LONGS] == 
STACK_FRAME_REGS_MARKER) {
struct pt_regs *regs = (struct pt_regs *)
(sp + STACK_INT_FRAME_REGS);
 
diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
index a2443d61728e..7efa0ec9dd77 100644
--- a/arch/powerpc/kernel/stacktrace.c
+++ b/arch/powerpc/kernel/stacktrace.c
@@ -136,7 +136,7 @@ int __no_sanitize_address 
arch_stack_walk_reliable(stack_trace_consume_fn consum
 
/* Mark stacktraces with exception frames as unreliable. */
if (sp <= stack_end - STACK_INT_FRAME_SIZE &&
-   stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
+   stack[STACK_INT_FRAME_MARKER_LONGS] == 
STACK_FRAME_REGS_MARKER) {
return -EINVAL;
}
 
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index 9e254aed1f61..b01497ed5173 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -62,7 +62,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, 
struct pt_regs *re
 
if (next_sp == sp + STACK_INT_FRAME_SIZE &&
validate_sp(sp, current, STACK_INT_FRAME_SIZE) &&
-   fp[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
+   fp[STACK_INT_FRAME_MARKER_LONGS] == 
STACK_FRAME_REGS_MARKER) {
/*
 * This looks like an interrupt frame for an
 * interrupt that occurred in the kernel
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index e403f14eb6eb..bbdaa42ba4ba 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1720,7 +1720,6 @@ static void get_function_bounds(unsigned long pc, 
unsigned long *startp,
 }
 
 #define LRSAVE_OFFSET  (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
-#define MARKER_OFFSET  (STACK_FRAME_MARKER * sizeof(unsigned long))
 
 static void xmon_show_stack(unsigned long sp, unsigned long lr,
unsigned long pc)
@@ -1783,7 +1782,7 @@ static void xmon_show_stack(unsigned long sp, unsigned 
long lr,
 
/* Look for "regs" marker to see if this is
   an exception frame. */
-   if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
+   if (mread(sp + STACK_INT_FRAME_MARKER, &marker, sizeof(unsigned 
long))
&& marker == STACK_FRAME_REGS_MARKER) {
if (mread(sp + STACK_INT_FRAME_REGS, ®s, 
sizeof(regs)) != sizeof(regs)) {
printf("Couldn't read registers at %lx\n",
-- 
2.37.2



[RFC PATCH 10/19] powerpc: add a define for the user interrupt frame size

2022-10-30 Thread Nicholas Piggin
The user interrupt frame is a different size from the kernel frame, so
give it its own name.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/ptrace.h | 6 +++---
 arch/powerpc/kernel/process.c | 6 +++---
 arch/powerpc/kernel/stacktrace.c  | 4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index fdd50648df56..705ce26ae887 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -122,8 +122,7 @@ struct pt_regs
 
 #define STACK_FRAME_OVERHEAD   112 /* size of minimum stack frame */
 #define STACK_FRAME_LR_SAVE2   /* Location of LR in stack frame */
-#define STACK_INT_FRAME_SIZE   (sizeof(struct pt_regs) + \
-STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE)
+#define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
 #define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
 #define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 16)
 
@@ -143,7 +142,7 @@ struct pt_regs
 #define KERNEL_REDZONE_SIZE0
 #define STACK_FRAME_OVERHEAD   16  /* size of minimum stack frame */
 #define STACK_FRAME_LR_SAVE1   /* Location of LR in stack frame */
-#define STACK_INT_FRAME_SIZE   (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
+#define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
 #define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
 #define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 8)
 #define STACK_FRAME_MIN_SIZE   STACK_FRAME_OVERHEAD
@@ -153,6 +152,7 @@ struct pt_regs
 
 #endif /* __powerpc64__ */
 
+#define STACK_INT_FRAME_SIZE   (KERNEL_REDZONE_SIZE + 
STACK_USER_INT_FRAME_SIZE)
 #define STACK_INT_FRAME_MARKER_LONGS   (STACK_INT_FRAME_MARKER/sizeof(long))
 
 #ifndef __ASSEMBLY__
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index b0a9e5eeec4c..d6daf0d073b3 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1727,15 +1727,15 @@ int copy_thread(struct task_struct *p, const struct 
kernel_clone_args *args)
klp_init_thread_info(p);
 
/* Create initial stack frame. */
-   sp -= (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD);
+   sp -= STACK_USER_INT_FRAME_SIZE;
((unsigned long *)sp)[0] = 0;
 
/* Copy registers */
-   childregs = (struct pt_regs *)(sp + STACK_FRAME_OVERHEAD);
+   childregs = (struct pt_regs *)(sp + STACK_INT_FRAME_REGS);
if (unlikely(args->fn)) {
/* kernel thread */
memset(childregs, 0, sizeof(struct pt_regs));
-   childregs->gpr[1] = sp + (sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD);
+   childregs->gpr[1] = sp + STACK_USER_INT_FRAME_SIZE;
/* function */
if (args->fn)
childregs->gpr[14] = ppc_function_entry((void 
*)args->fn);
diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
index 7efa0ec9dd77..453ac317a6cf 100644
--- a/arch/powerpc/kernel/stacktrace.c
+++ b/arch/powerpc/kernel/stacktrace.c
@@ -77,7 +77,7 @@ int __no_sanitize_address 
arch_stack_walk_reliable(stack_trace_consume_fn consum
/*
 * For user tasks, this is the SP value loaded on
 * kernel entry, see "PACAKSAVE(r13)" in _switch() and
-* system_call_common()/EXCEPTION_PROLOG_COMMON().
+* system_call_common().
 *
 * Likewise for non-swapper kernel threads,
 * this also happens to be the top of the stack
@@ -88,7 +88,7 @@ int __no_sanitize_address 
arch_stack_walk_reliable(stack_trace_consume_fn consum
 * an unreliable stack trace until it's been
 * _switch()'ed to for the first time.
 */
-   stack_end -= STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
+   stack_end -= STACK_USER_INT_FRAME_SIZE;
} else {
/*
 * idle tasks have a custom stack layout,
-- 
2.37.2



[RFC PATCH 11/19] powerpc: add a define for the switch frame size and regs offset

2022-10-30 Thread Nicholas Piggin
This is open-coded in process.c, ppc32 uses a different define with the
same value, and the C definition is name differently which makes it an
extra indirection to grep for.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/ptrace.h |  6 --
 arch/powerpc/kernel/asm-offsets.c |  2 +-
 arch/powerpc/kernel/entry_32.S|  6 +++---
 arch/powerpc/kernel/process.c | 12 
 4 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index 705ce26ae887..412ef0749775 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -97,8 +97,6 @@ struct pt_regs
 #endif
 
 
-#define STACK_FRAME_WITH_PT_REGS (STACK_FRAME_OVERHEAD + sizeof(struct 
pt_regs))
-
 // Always displays as "REGS" in memory dumps
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define STACK_FRAME_REGS_MARKERASM_CONST(0x52454753)
@@ -125,6 +123,8 @@ struct pt_regs
 #define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
 #define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
 #define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 16)
+#define STACK_SWITCH_FRAME_SIZE(sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
+#define STACK_SWITCH_FRAME_REGSSTACK_FRAME_OVERHEAD
 
 #ifdef CONFIG_PPC64_ELF_ABI_V2
 #define STACK_FRAME_MIN_SIZE   32
@@ -146,6 +146,8 @@ struct pt_regs
 #define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
 #define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 8)
 #define STACK_FRAME_MIN_SIZE   STACK_FRAME_OVERHEAD
+#define STACK_SWITCH_FRAME_SIZE(sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
+#define STACK_SWITCH_FRAME_REGSSTACK_FRAME_OVERHEAD
 
 /* Size of stack frame allocated when calling signal handler. */
 #define __SIGNAL_FRAMESIZE 64
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index db5e66c1d031..f7dff906c24b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -260,7 +260,7 @@ int main(void)
 
/* Interrupt register frame */
DEFINE(INT_FRAME_SIZE, STACK_INT_FRAME_SIZE);
-   DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_WITH_PT_REGS);
+   DEFINE(SWITCH_FRAME_SIZE, STACK_SWITCH_FRAME_SIZE);
STACK_PT_REGS_OFFSET(GPR0, gpr[0]);
STACK_PT_REGS_OFFSET(GPR1, gpr[1]);
STACK_PT_REGS_OFFSET(GPR2, gpr[2]);
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 2f61b7d3677c..6e99ec10be89 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -215,9 +215,9 @@ ret_from_kernel_thread:
  * in arch/ppc/kernel/process.c
  */
 _GLOBAL(_switch)
-   stwur1,-INT_FRAME_SIZE(r1)
+   stwur1,-SWITCH_FRAME_SIZE(r1)
mflrr0
-   stw r0,INT_FRAME_SIZE+4(r1)
+   stw r0,SWITCH_FRAME_SIZE+4(r1)
/* r3-r12 are caller saved -- Cort */
SAVE_NVGPRS(r1)
stw r0,_NIP(r1) /* Return to switch caller */
@@ -248,7 +248,7 @@ _GLOBAL(_switch)
 
lwz r4,_NIP(r1) /* Return to _switch caller in new task */
mtlrr4
-   addir1,r1,INT_FRAME_SIZE
+   addir1,r1,SWITCH_FRAME_SIZE
blr
 
.globl  fast_exception_return
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index d6daf0d073b3..a097879b0474 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1779,10 +1779,10 @@ int copy_thread(struct task_struct *p, const struct 
kernel_clone_args *args)
 * do some house keeping and then return from the fork or clone
 * system call, using the stack frame created above.
 */
-   sp -= sizeof(struct pt_regs);
-   kregs = (struct pt_regs *) sp;
-   sp -= STACK_FRAME_OVERHEAD;
+   sp -= STACK_SWITCH_FRAME_SIZE;
+   kregs = (struct pt_regs *)(sp + STACK_SWITCH_FRAME_REGS);
p->thread.ksp = sp;
+
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
for (i = 0; i < nr_wp_slots(); i++)
p->thread.ptrace_bps[i] = NULL;
@@ -2232,8 +2232,12 @@ void __no_sanitize_address show_stack(struct task_struct 
*tsk,
/*
 * See if this is an exception frame.
 * We look for the "regs" marker in the current frame.
+*
+* STACK_SWITCH_FRAME_SIZE being the smallest frame that
+* could hold a pt_regs, if that does not fit then it can't
+* have regs.
 */
-   if (validate_sp(sp, tsk, STACK_FRAME_WITH_PT_REGS)
+   if (validate_sp(sp, tsk, STACK_SWITCH_FRAME_SIZE)
&& stack[STACK_INT_FRAME_MARKER_LONGS] == 
STACK_FRAME_REGS_MARKER) {
struct pt_regs *regs = (struct pt_regs *)
(sp + STACK_INT_FRAME_REGS);
-- 
2.37.2



[RFC PATCH 12/19] powerpc: copy_thread fill in interrupt frame marker and back chain

2022-10-30 Thread Nicholas Piggin
Backtraces will not recognise the fork system call interrupt without
the regs marker. And at least perf starts unwinding the user stack
from gpr[1] directly, but regular interrupt entry from userspace creates
the back chain to the user stack, so do this too, to be consistent.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/kernel/process.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index a097879b0474..27956831fa5d 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1728,12 +1728,13 @@ int copy_thread(struct task_struct *p, const struct 
kernel_clone_args *args)
 
/* Create initial stack frame. */
sp -= STACK_USER_INT_FRAME_SIZE;
-   ((unsigned long *)sp)[0] = 0;
+   *(unsigned long *)(sp + STACK_INT_FRAME_MARKER) = 
STACK_FRAME_REGS_MARKER;
 
/* Copy registers */
childregs = (struct pt_regs *)(sp + STACK_INT_FRAME_REGS);
if (unlikely(args->fn)) {
/* kernel thread */
+   ((unsigned long *)sp)[0] = 0;
memset(childregs, 0, sizeof(struct pt_regs));
childregs->gpr[1] = sp + STACK_USER_INT_FRAME_SIZE;
/* function */
@@ -1753,6 +1754,7 @@ int copy_thread(struct task_struct *p, const struct 
kernel_clone_args *args)
*childregs = *regs;
if (usp)
childregs->gpr[1] = usp;
+   ((unsigned long *)sp)[0] = childregs->gpr[1];
p->thread.regs = childregs;
/* 64s sets this in ret_from_fork */
if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64))
-- 
2.37.2



[RFC PATCH 13/19] powerpc: copy_thread add a back chain to the switch stack frame

2022-10-30 Thread Nicholas Piggin
Stack unwinders need LR and the back chain as a minimum. The switch
stack uses regs->nip for its return pointer rather than lrsave, so
that was not filled in, and neither was the back chain.

With this and the previous change, a stack trace in the switch or
interrupt stack goes from looking like this:

  Oops: Exception in kernel mode, sig: 5 [#1]
  LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries
  Modules linked in:
  CPU: 3 PID: 90 Comm: systemd Not tainted
  NIP:  c0011060 LR: c0010f68 CTR: 7fff
  [ ... regs ... ]
  NIP [c0011060] _switch+0x160/0x17c
  LR [c0010f68] _switch+0x68/0x17c
  Call Trace:

To this:

  Oops: Exception in kernel mode, sig: 5 [#1]
  LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries
  CPU: 0 PID: 93 Comm: systemd Not tainted
  NIP:  c0011060 LR: c0010f68 CTR: 7fff
  [ ... regs ... ]
  NIP [c0011060] _switch+0x160/0x17c
  LR [c0010f68] _switch+0x68/0x17c
  Call Trace:
  [c5a93e10] [c000cdbc] ret_from_fork_scv+0x0/0x54
  --- interrupt: 3000 at 0x7fffa72f56d8
  NIP:  7fffa72f56d8 LR:  CTR: 
  [ ... regs ... ]
  NIP [7fffa72f56d8] 0x7fffa72f56d8
  LR [] 0x0
  --- interrupt: 3000

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/kernel/process.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 27956831fa5d..6cb3982a11ef 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1781,7 +1781,9 @@ int copy_thread(struct task_struct *p, const struct 
kernel_clone_args *args)
 * do some house keeping and then return from the fork or clone
 * system call, using the stack frame created above.
 */
+   ((unsigned long *)sp)[STACK_FRAME_LR_SAVE] = (unsigned long)f;
sp -= STACK_SWITCH_FRAME_SIZE;
+   ((unsigned long *)sp)[0] = sp + STACK_SWITCH_FRAME_SIZE;
kregs = (struct pt_regs *)(sp + STACK_SWITCH_FRAME_REGS);
p->thread.ksp = sp;
 
-- 
2.37.2



[RFC PATCH 14/19] powerpc: split validate_sp into two functions

2022-10-30 Thread Nicholas Piggin
Most callers just want to validate an arbitrary kernel stack pointer,
some need a particular size. Make the size case the exceptional one
with an extra function.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/processor.h | 15 ---
 arch/powerpc/kernel/process.c| 23 ++-
 arch/powerpc/kernel/stacktrace.c |  2 +-
 arch/powerpc/perf/callchain.c|  6 +++---
 4 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index 631802999d59..e96c9b8c2a60 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -374,9 +374,18 @@ static inline unsigned long __pack_fe01(unsigned int 
fpmode)
 
 #endif
 
-/* Check that a certain kernel stack pointer is valid in task_struct p */
-int validate_sp(unsigned long sp, struct task_struct *p,
-   unsigned long nbytes);
+/*
+ * Check that a certain kernel stack pointer is a valid (minimum sized)
+ * stack frame in task_struct p.
+ */
+int validate_sp(unsigned long sp, struct task_struct *p);
+
+/*
+ * validate the stack frame of a particular minimum size, used for when we are
+ * looking at a certain object in the stack beyond the minimum.
+ */
+int validate_sp_size(unsigned long sp, struct task_struct *p,
+unsigned long nbytes);
 
 /*
  * Prefetch macros.
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 6cb3982a11ef..b5defea32e75 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -2128,9 +2128,12 @@ static inline int valid_emergency_stack(unsigned long 
sp, struct task_struct *p,
return 0;
 }
 
-
-int validate_sp(unsigned long sp, struct task_struct *p,
-  unsigned long nbytes)
+/*
+ * validate the stack frame of a particular minimum size, used for when we are
+ * looking at a certain object in the stack beyond the minimum.
+ */
+int validate_sp_size(unsigned long sp, struct task_struct *p,
+unsigned long nbytes)
 {
unsigned long stack_page = (unsigned long)task_stack_page(p);
 
@@ -2146,7 +2149,10 @@ int validate_sp(unsigned long sp, struct task_struct *p,
return valid_emergency_stack(sp, p, nbytes);
 }
 
-EXPORT_SYMBOL(validate_sp);
+int validate_sp(unsigned long sp, struct task_struct *p)
+{
+   return validate_sp(sp, p, STACK_FRAME_OVERHEAD);
+}
 
 static unsigned long ___get_wchan(struct task_struct *p)
 {
@@ -2154,13 +2160,12 @@ static unsigned long ___get_wchan(struct task_struct *p)
int count = 0;
 
sp = p->thread.ksp;
-   if (!validate_sp(sp, p, STACK_FRAME_OVERHEAD))
+   if (!validate_sp(sp, p))
return 0;
 
do {
sp = READ_ONCE_NOCHECK(*(unsigned long *)sp);
-   if (!validate_sp(sp, p, STACK_FRAME_OVERHEAD) ||
-   task_is_running(p))
+   if (!validate_sp(sp, p) || task_is_running(p))
return 0;
if (count > 0) {
ip = READ_ONCE_NOCHECK(((unsigned long 
*)sp)[STACK_FRAME_LR_SAVE]);
@@ -2214,7 +2219,7 @@ void __no_sanitize_address show_stack(struct task_struct 
*tsk,
lr = 0;
printk("%sCall Trace:\n", loglvl);
do {
-   if (!validate_sp(sp, tsk, STACK_FRAME_OVERHEAD))
+   if (!validate_sp(sp, tsk))
break;
 
stack = (unsigned long *) sp;
@@ -2241,7 +2246,7 @@ void __no_sanitize_address show_stack(struct task_struct 
*tsk,
 * could hold a pt_regs, if that does not fit then it can't
 * have regs.
 */
-   if (validate_sp(sp, tsk, STACK_SWITCH_FRAME_SIZE)
+   if (validate_sp_size(sp, tsk, STACK_SWITCH_FRAME_SIZE)
&& stack[STACK_INT_FRAME_MARKER_LONGS] == 
STACK_FRAME_REGS_MARKER) {
struct pt_regs *regs = (struct pt_regs *)
(sp + STACK_INT_FRAME_REGS);
diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
index 453ac317a6cf..1dbbf30f265e 100644
--- a/arch/powerpc/kernel/stacktrace.c
+++ b/arch/powerpc/kernel/stacktrace.c
@@ -43,7 +43,7 @@ void __no_sanitize_address 
arch_stack_walk(stack_trace_consume_fn consume_entry,
unsigned long *stack = (unsigned long *) sp;
unsigned long newsp, ip;
 
-   if (!validate_sp(sp, task, STACK_FRAME_OVERHEAD))
+   if (!validate_sp(sp, task))
return;
 
newsp = stack[0];
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index b01497ed5173..6b4434dd0ff3 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -27,7 +27,7 @@ static int valid_next_sp(unsigned long sp, unsigned long 
prev_sp)
 {
if (sp & 0xf)
retur

[RFC PATCH 15/19] powerpc: allow minimum sized kernel stack frames

2022-10-30 Thread Nicholas Piggin
This affects only 64-bit ELFv2 kernels, and reduces the minimum
asm-created stack frame size from 112 to 32 byte on those kernels.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/kernel/head_40x.S   | 2 +-
 arch/powerpc/kernel/head_44x.S   | 6 +++---
 arch/powerpc/kernel/head_64.S| 6 +++---
 arch/powerpc/kernel/head_85xx.S  | 4 ++--
 arch/powerpc/kernel/head_8xx.S   | 2 +-
 arch/powerpc/kernel/head_book3s_32.S | 4 ++--
 arch/powerpc/kernel/irq.c| 4 ++--
 arch/powerpc/kernel/misc_32.S| 2 +-
 arch/powerpc/kernel/misc_64.S| 4 ++--
 arch/powerpc/kernel/process.c| 2 +-
 arch/powerpc/kernel/smp.c| 2 +-
 arch/powerpc/kernel/stacktrace.c | 2 +-
 12 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index 088f500896c7..918547b93b5e 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -602,7 +602,7 @@ start_here:
lis r1,init_thread_union@ha
addir1,r1,init_thread_union@l
li  r0,0
-   stwur0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+   stwur0,THREAD_SIZE-STACK_FRAME_MIN_SIZE(r1)
 
bl  early_init  /* We have to do this with MMU on */
 
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index f15cb9fdb692..63a85c16fef4 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -109,7 +109,7 @@ _GLOBAL(_start);
lis r1,init_thread_union@h
ori r1,r1,init_thread_union@l
li  r0,0
-   stwur0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+   stwur0,THREAD_SIZE-STACK_FRAME_MIN_SIZE(r1)
 
bl  early_init
 
@@ -1012,7 +1012,7 @@ _GLOBAL(start_secondary_47x)
 */
lis r1,temp_boot_stack@h
ori r1,r1,temp_boot_stack@l
-   addir1,r1,1024-STACK_FRAME_OVERHEAD
+   addir1,r1,1024-STACK_FRAME_MIN_SIZE
li  r0,0
stw r0,0(r1)
bl  mmu_init_secondary
@@ -1025,7 +1025,7 @@ _GLOBAL(start_secondary_47x)
lwz r1,TASK_STACK(r2)
 
/* Current stack pointer */
-   addir1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+   addir1,r1,THREAD_SIZE-STACK_FRAME_MIN_SIZE
li  r0,0
stw r0,0(r1)
 
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index dedcc6fe2263..b513d13bf79e 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -424,7 +424,7 @@ generic_secondary_common_init:
 
/* Create a temp kernel stack for use before relocation is on.  */
ld  r1,PACAEMERGSP(r13)
-   subir1,r1,STACK_FRAME_OVERHEAD
+   subir1,r1,STACK_FRAME_MIN_SIZE
 
/* See if we need to call a cpu state restore handler */
LOAD_REG_ADDR(r23, cur_cpu_spec)
@@ -780,7 +780,7 @@ _GLOBAL(pmac_secondary_start)
 
/* Create a temp kernel stack for use before relocation is on.  */
ld  r1,PACAEMERGSP(r13)
-   subir1,r1,STACK_FRAME_OVERHEAD
+   subir1,r1,STACK_FRAME_MIN_SIZE
 
b   __secondary_start
 
@@ -958,7 +958,7 @@ start_here_multiplatform:
LOAD_REG_IMMEDIATE(r1,THREAD_SIZE)
add r1,r3,r1
li  r0,0
-   stdur0,-STACK_FRAME_OVERHEAD(r1)
+   stdur0,-STACK_FRAME_MIN_SIZE(r1)
 
/*
 * Do very early kernel initializations, including initial hash table
diff --git a/arch/powerpc/kernel/head_85xx.S b/arch/powerpc/kernel/head_85xx.S
index 24f39abf81df..d9bd377dec91 100644
--- a/arch/powerpc/kernel/head_85xx.S
+++ b/arch/powerpc/kernel/head_85xx.S
@@ -229,7 +229,7 @@ set_ivor:
lis r1,init_thread_union@h
ori r1,r1,init_thread_union@l
li  r0,0
-   stwur0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+   stwur0,THREAD_SIZE-STACK_FRAME_MIN_SIZE(r1)
 
 #ifdef CONFIG_SMP
stw r24, TASK_CPU(r2)
@@ -1044,7 +1044,7 @@ __secondary_start:
lwz r1,TASK_STACK(r2)
 
/* stack */
-   addir1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+   addir1,r1,THREAD_SIZE-STACK_FRAME_MIN_SIZE
li  r0,0
stw r0,0(r1)
 
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 0b05f2be66b9..cf546d0e5c40 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -537,7 +537,7 @@ start_here:
ori r0, r0, STACK_END_MAGIC@l
stw r0, 0(r1)
li  r0,0
-   stwur0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
+   stwur0,THREAD_SIZE-STACK_FRAME_MIN_SIZE(r1)
 
lis r6, swapper_pg_dir@ha
tophys(r6,r6)
diff --git a/arch/powerpc/kernel/head_book3s_32.S 
b/arch/powerpc/kernel/head_book3s_32.S
index 519b60695167..40854d092dd3 100644
--- a/arch/powerpc/kernel/head_book3s_32.S
+++ b/arch/powerpc/kernel/head_book3s_32.S
@@ -840,7 +840,7 @@ __secondary_start:
 

[RFC PATCH 16/19] powerpc/64: ELFv2 use minimal stack frames in int and switch frame sizes

2022-10-30 Thread Nicholas Piggin
This requires an extra 16 bytes beyond the minimum frame size for the
aligned regs marker for the int frame. The switch frame needs to match
that because they share some offset definitions.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/ptrace.h | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index 412ef0749775..a9dfce62a5eb 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -96,7 +96,6 @@ struct pt_regs
 };
 #endif
 
-
 // Always displays as "REGS" in memory dumps
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define STACK_FRAME_REGS_MARKERASM_CONST(0x52454753)
@@ -120,16 +119,26 @@ struct pt_regs
 
 #define STACK_FRAME_OVERHEAD   112 /* size of minimum stack frame */
 #define STACK_FRAME_LR_SAVE2   /* Location of LR in stack frame */
+
+#ifdef CONFIG_PPC64_ELF_ABI_V2
+#define STACK_FRAME_MIN_SIZE   32
+#define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_MIN_SIZE + 16)
+#define STACK_INT_FRAME_REGS   (STACK_FRAME_MIN_SIZE + 16)
+#define STACK_INT_FRAME_MARKER STACK_FRAME_MIN_SIZE
+#define STACK_SWITCH_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_MIN_SIZE 
+ 16)
+#define STACK_SWITCH_FRAME_REGS(STACK_FRAME_MIN_SIZE + 16)
+#else
+/*
+ * The ELFv1 ABI specifies 48 bytes plus a minimum 64 byte parameter save
+ * area. This parameter area is not used by calls to C from interrupt entry,
+ * so the second from last one of those is used for the frame marker.
+ */
+#define STACK_FRAME_MIN_SIZE   112
 #define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
 #define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
 #define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 16)
 #define STACK_SWITCH_FRAME_SIZE(sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
 #define STACK_SWITCH_FRAME_REGSSTACK_FRAME_OVERHEAD
-
-#ifdef CONFIG_PPC64_ELF_ABI_V2
-#define STACK_FRAME_MIN_SIZE   32
-#else
-#define STACK_FRAME_MIN_SIZE   STACK_FRAME_OVERHEAD
 #endif
 
 /* Size of dummy stack frame allocated when calling signal handler. */
-- 
2.37.2



[RFC PATCH 17/19] powerpc: remove STACK_FRAME_OVERHEAD

2022-10-30 Thread Nicholas Piggin
This is equal to STACK_FRAME_MIN_SIZE on 32-bit and 64-bit ELFv1, and no
longer used in 64-bit ELFv2, so replace it with that constant.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/ptrace.h | 24 +++-
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index a9dfce62a5eb..a53c580388e2 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -117,7 +117,6 @@ struct pt_regs
 #define USER_REDZONE_SIZE  512
 #define KERNEL_REDZONE_SIZE288
 
-#define STACK_FRAME_OVERHEAD   112 /* size of minimum stack frame */
 #define STACK_FRAME_LR_SAVE2   /* Location of LR in stack frame */
 
 #ifdef CONFIG_PPC64_ELF_ABI_V2
@@ -134,11 +133,11 @@ struct pt_regs
  * so the second from last one of those is used for the frame marker.
  */
 #define STACK_FRAME_MIN_SIZE   112
-#define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
-#define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
-#define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 16)
-#define STACK_SWITCH_FRAME_SIZE(sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
-#define STACK_SWITCH_FRAME_REGSSTACK_FRAME_OVERHEAD
+#define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_MIN_SIZE)
+#define STACK_INT_FRAME_REGS   STACK_FRAME_MIN_SIZE
+#define STACK_INT_FRAME_MARKER (STACK_FRAME_MIN_SIZE - 16)
+#define STACK_SWITCH_FRAME_SIZE(sizeof(struct pt_regs) + 
STACK_FRAME_MIN_SIZE)
+#define STACK_SWITCH_FRAME_REGSSTACK_FRAME_MIN_SIZE
 #endif
 
 /* Size of dummy stack frame allocated when calling signal handler. */
@@ -149,14 +148,13 @@ struct pt_regs
 
 #define USER_REDZONE_SIZE  0
 #define KERNEL_REDZONE_SIZE0
-#define STACK_FRAME_OVERHEAD   16  /* size of minimum stack frame */
+#define STACK_FRAME_MIN_SIZE   16
 #define STACK_FRAME_LR_SAVE1   /* Location of LR in stack frame */
-#define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
-#define STACK_INT_FRAME_REGS   STACK_FRAME_OVERHEAD
-#define STACK_INT_FRAME_MARKER (STACK_FRAME_OVERHEAD - 8)
-#define STACK_FRAME_MIN_SIZE   STACK_FRAME_OVERHEAD
-#define STACK_SWITCH_FRAME_SIZE(sizeof(struct pt_regs) + 
STACK_FRAME_OVERHEAD)
-#define STACK_SWITCH_FRAME_REGSSTACK_FRAME_OVERHEAD
+#define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_MIN_SIZE)
+#define STACK_INT_FRAME_REGS   STACK_FRAME_MIN_SIZE
+#define STACK_INT_FRAME_MARKER (STACK_FRAME_MIN_SIZE - 8)
+#define STACK_SWITCH_FRAME_SIZE(sizeof(struct pt_regs) + 
STACK_FRAME_MIN_SIZE)
+#define STACK_SWITCH_FRAME_REGSSTACK_FRAME_MIN_SIZE
 
 /* Size of stack frame allocated when calling signal handler. */
 #define __SIGNAL_FRAMESIZE 64
-- 
2.37.2



[RFC PATCH 18/19] powerpc: change stack marker memory operations to 32-bit

2022-10-30 Thread Nicholas Piggin
The marker is a 32-bit constant across all platforms now, so use 32-bit
memory accesses.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/ptrace.h| 1 -
 arch/powerpc/kernel/exceptions-64e.S | 2 +-
 arch/powerpc/kernel/exceptions-64s.S | 2 +-
 arch/powerpc/kernel/interrupt_64.S   | 6 +++---
 arch/powerpc/kernel/process.c| 6 +++---
 arch/powerpc/kernel/stacktrace.c | 2 +-
 arch/powerpc/perf/callchain.c| 2 +-
 7 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index a53c580388e2..ab41d47761c9 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -162,7 +162,6 @@ struct pt_regs
 #endif /* __powerpc64__ */
 
 #define STACK_INT_FRAME_SIZE   (KERNEL_REDZONE_SIZE + 
STACK_USER_INT_FRAME_SIZE)
-#define STACK_INT_FRAME_MARKER_LONGS   (STACK_INT_FRAME_MARKER/sizeof(long))
 
 #ifndef __ASSEMBLY__
 #include 
diff --git a/arch/powerpc/kernel/exceptions-64e.S 
b/arch/powerpc/kernel/exceptions-64e.S
index d74c2a53af13..86cf656c6777 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -391,7 +391,7 @@ exc_##n##_common:   
\
std r10,_CCR(r1);   /* store orig CR in stackframe */   \
std r9,GPR1(r1);/* store stack frame back link */   \
std r11,SOFTE(r1);  /* and save it to stackframe */ \
-   std r12,STACK_INT_FRAME_MARKER(r1); /* mark the frame */\
+   stw r12,STACK_INT_FRAME_MARKER(r1); /* mark the frame */\
std r3,_TRAP(r1);   /* set trap number  */  \
std r0,RESULT(r1);  /* clear regs->result */\
SAVE_NVGPRS(r1);
diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index 39f08ec56126..85bbdfa7e4d3 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -591,7 +591,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
li  r10,0
LOAD_REG_IMMEDIATE(r11, STACK_FRAME_REGS_MARKER)
std r10,RESULT(r1)  /* clear regs->result   */
-   std r11,STACK_INT_FRAME_MARKER(r1) /* mark the frame*/
+   stw r11,STACK_INT_FRAME_MARKER(r1) /* mark the frame*/
 .endm
 
 /*
diff --git a/arch/powerpc/kernel/interrupt_64.S 
b/arch/powerpc/kernel/interrupt_64.S
index 2306b979e71f..ee8cfe17ca37 100644
--- a/arch/powerpc/kernel/interrupt_64.S
+++ b/arch/powerpc/kernel/interrupt_64.S
@@ -78,7 +78,7 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
std r12,_CCR(r1)
std r3,ORIG_GPR3(r1)
LOAD_REG_IMMEDIATE(r11, STACK_FRAME_REGS_MARKER)
-   std r11,STACK_INT_FRAME_MARKER(r1)  /* "regs" marker */
+   stw r11,STACK_INT_FRAME_MARKER(r1)  /* "regs" marker */
/* Calling convention has r3 = regs, r4 = orig r0 */
addir3,r1,STACK_INT_FRAME_REGS
mr  r4,r0
@@ -251,7 +251,7 @@ END_BTB_FLUSH_SECTION
std r12,_CCR(r1)
std r3,ORIG_GPR3(r1)
LOAD_REG_IMMEDIATE(r11, STACK_FRAME_REGS_MARKER)
-   std r11,STACK_INT_FRAME_MARKER(r1)  /* "regs" marker */
+   stw r11,STACK_INT_FRAME_MARKER(r1)  /* "regs" marker */
/* Calling convention has r3 = regs, r4 = orig r0 */
addir3,r1,STACK_INT_FRAME_REGS
mr  r4,r0
@@ -628,7 +628,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
 * Leaving a stale STACK_FRAME_REGS_MARKER on the stack can confuse
 * the reliable stack unwinder later on. Clear it.
 */
-   std r0,STACK_INT_FRAME_MARKER(r1)
+   stw r0,STACK_INT_FRAME_MARKER(r1)
 
REST_GPRS(2, 5, r1)
 
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 20fdb84759f0..e447bf02f996 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1728,7 +1728,7 @@ int copy_thread(struct task_struct *p, const struct 
kernel_clone_args *args)
 
/* Create initial stack frame. */
sp -= STACK_USER_INT_FRAME_SIZE;
-   *(unsigned long *)(sp + STACK_INT_FRAME_MARKER) = 
STACK_FRAME_REGS_MARKER;
+   *(u32 *)(sp + STACK_INT_FRAME_MARKER) = STACK_FRAME_REGS_MARKER;
 
/* Copy registers */
childregs = (struct pt_regs *)(sp + STACK_INT_FRAME_REGS);
@@ -2246,8 +2246,8 @@ void __no_sanitize_address show_stack(struct task_struct 
*tsk,
 * could hold a pt_regs, if that does not fit then it can't
 * have regs.
 */
-   if (validate_sp_size(sp, tsk, STACK_SWITCH_FRAME_SIZE)
-   && stack[STACK_INT_FRAME_MARKER_LONGS] == 
STACK_FRAME_REGS_MARKER) {
+   if (validate_sp_size(sp, tsk, STACK_SWITCH_FRAME_SIZE) &&
+   *(u32 *)(sp

[RFC PATCH 19/19] powerpc/64: ELFv2 use reserved word in the stack frame for the regs marker

2022-10-30 Thread Nicholas Piggin
There are 4 unused bytes in the minimum frame in the ELFv2 ABI. At the
risk of causing a future ABI incompatibility, use this and save 16 bytes
from interrupt and switch frames.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/ptrace.h | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index ab41d47761c9..cc308dce7ace 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -121,11 +121,16 @@ struct pt_regs
 
 #ifdef CONFIG_PPC64_ELF_ABI_V2
 #define STACK_FRAME_MIN_SIZE   32
-#define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_MIN_SIZE + 16)
-#define STACK_INT_FRAME_REGS   (STACK_FRAME_MIN_SIZE + 16)
-#define STACK_INT_FRAME_MARKER STACK_FRAME_MIN_SIZE
-#define STACK_SWITCH_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_MIN_SIZE 
+ 16)
-#define STACK_SWITCH_FRAME_REGS(STACK_FRAME_MIN_SIZE + 16)
+#define STACK_USER_INT_FRAME_SIZE  (sizeof(struct pt_regs) + 
STACK_FRAME_MIN_SIZE)
+#define STACK_INT_FRAME_REGS   STACK_FRAME_MIN_SIZE
+#define STACK_INT_FRAME_MARKER 12  /* Reserved word next to CR save word */
+
+/*
+ * The switch frame has to match the format of the int frames up to pt_regs,
+ * because fields are accessed with the int frame pt_regs offsets.
+ */
+#define STACK_SWITCH_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_MIN_SIZE)
+#define STACK_SWITCH_FRAME_REGSSTACK_FRAME_MIN_SIZE
 #else
 /*
  * The ELFv1 ABI specifies 48 bytes plus a minimum 64 byte parameter save
-- 
2.37.2



[PATCH] powerpc/pseries/eeh: Fix some kernel-doc warnings

2022-10-30 Thread Bo Liu
Fixes the following W=1 kernel build warning(s):
  arch/powerpc/platforms/pseries/eeh_pseries.c:163: warning: Function parameter 
or member 'config_addr' not described in 'pseries_eeh_phb_reset'
  arch/powerpc/platforms/pseries/eeh_pseries.c:163: warning: Excess function 
parameter 'config_adddr' description in 'pseries_eeh_phb_reset'
  arch/powerpc/platforms/pseries/eeh_pseries.c:198: warning: Function parameter 
or member 'config_addr' not described in 'pseries_eeh_phb_configure_bridge'
  arch/powerpc/platforms/pseries/eeh_pseries.c:198: warning: Excess function 
parameter 'config_adddr' description in 'pseries_eeh_phb_configure_bridge'

Signed-off-by: Bo Liu 
---
 arch/powerpc/platforms/pseries/eeh_pseries.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c 
b/arch/powerpc/platforms/pseries/eeh_pseries.c
index 8e40ccac0f44..ea890037843c 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -154,7 +154,7 @@ static int pseries_eeh_get_pe_config_addr(struct pci_dn 
*pdn)
 /**
  * pseries_eeh_phb_reset - Reset the specified PHB
  * @phb: PCI controller
- * @config_adddr: the associated config address
+ * @config_addr: the associated config address
  * @option: reset option
  *
  * Reset the specified PHB/PE
@@ -188,7 +188,7 @@ static int pseries_eeh_phb_reset(struct pci_controller 
*phb, int config_addr, in
 /**
  * pseries_eeh_phb_configure_bridge - Configure PCI bridges in the indicated PE
  * @phb: PCI controller
- * @config_adddr: the associated config address
+ * @config_addr: the associated config address
  *
  * The function will be called to reconfigure the bridges included
  * in the specified PE so that the mulfunctional PE would be recovered
-- 
2.27.0