Re: [PATCH] powerpc/machdep: warn when machine_is() used too early

2023-02-10 Thread Christophe Leroy


Le 11/02/2023 à 00:56, Nathan Lynch via B4 Submission Endpoint a écrit :
> From: Nathan Lynch 
> 
> machine_is() can't provide correct results before probe_machine() has
> run. Warn when it's used too early in boot.
> 
> Signed-off-by: Nathan Lynch 
> ---
> Prompted by my attempts to do some pseries-specific setup during
> rtas_initialize() and being puzzled for a while that it wasn't
> working.
> ---
>   arch/powerpc/include/asm/machdep.h | 12 +++-
>   1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/machdep.h 
> b/arch/powerpc/include/asm/machdep.h
> index 378b8d5836a7..8c0a799d18cd 100644
> --- a/arch/powerpc/include/asm/machdep.h
> +++ b/arch/powerpc/include/asm/machdep.h
> @@ -220,11 +220,13 @@ extern struct machdep_calls *machine_id;
>   EXPORT_SYMBOL(mach_##name); \
>   struct machdep_calls mach_##name __machine_desc =
>   
> -#define machine_is(name) \
> - ({ \
> - extern struct machdep_calls mach_##name \
> - __attribute__((weak));   \
> - machine_id == _##name; \
> +#define machine_is(name)\
> + ({  \
> + extern struct machdep_calls mach_##name \
> + __attribute__((weak));  \
> + WARN(!machine_id,   \
> +  "machine_is() called before probe_machine()"); \

Is a WARN() really necessary ? WARN() is less optimised than WARN_ON(), 
especially on PPC64.

This should never ever happen so a WARN_ON(!machine_id) should be 
enough, the developper that hits it is able to go to the given file:line 
and understand what happened.

> + machine_id == _##name; \
>   })
>   
>   static inline void log_error(char *buf, unsigned int err_type, int fatal)
> 
> ---
> base-commit: 0bfb97203f5f300777624a2ad6f8f84aea3e8658
> change-id: 20230210-warn-on-machine-is-before-probe-machine-37515b1f43bb
> 
> Best regards,


Re: [PATCH 00/24 v2] Documentation: correct lots of spelling errors (series 1)

2023-02-10 Thread patchwork-bot+netdevbpf
Hello:

This series was applied to netdev/net-next.git (master)
by Jakub Kicinski :

On Wed,  8 Feb 2023 23:13:36 -0800 you wrote:
> Correct many spelling errors in Documentation/ as reported by codespell.
> 
> Maintainers of specific kernel subsystems are only Cc-ed on their
> respective patches, not the entire series.
> 
> These patches are based on linux-next-20230209.
> 
> [...]

Here is the summary with links:
  - [03/24] Documentation: core-api: correct spelling
(no matching commit)
  - [08/24] Documentation: isdn: correct spelling
https://git.kernel.org/netdev/net-next/c/d12f9ad02806

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




[PATCH 6.1 v2 6/7] s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36

2023-02-10 Thread Tom Saeger
From: Masahiro Yamada 

commit a494398bde273143c2352dd373cad8211f7d94b2 upstream.

Nathan Chancellor reports that the s390 vmlinux fails to link with
GNU ld < 2.36 since commit 99cb0d917ffa ("arch: fix broken BuildID
for arm64 and riscv").

It happens for defconfig, or more specifically for CONFIG_EXPOLINE=y.

  $ s390x-linux-gnu-ld --version | head -n1
  GNU ld (GNU Binutils for Debian) 2.35.2
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- allnoconfig
  $ ./scripts/config -e CONFIG_EXPOLINE
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- olddefconfig
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu-
  `.exit.text' referenced in section `.s390_return_reg' of drivers/base/dd.o: 
defined in discarded section `.exit.text' of drivers/base/dd.o
  make[1]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1
  make: *** [Makefile:1252: vmlinux] Error 2

arch/s390/kernel/vmlinux.lds.S wants to keep EXIT_TEXT:

.exit.text : {
EXIT_TEXT
}

But, at the same time, EXIT_TEXT is thrown away by DISCARD because
s390 does not define RUNTIME_DISCARD_EXIT.

I still do not understand why the latter wins after 99cb0d917ffa,
but defining RUNTIME_DISCARD_EXIT seems correct because the comment
line in arch/s390/kernel/vmlinux.lds.S says:

/*
 * .exit.text is discarded at runtime, not link time,
 * to deal with references from __bug_table
 */

Nathan also found that binutils commit 21401fc7bf67 ("Duplicate output
sections in scripts") cured this issue, so we cannot reproduce it with
binutils 2.36+, but it is better to not rely on it.

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Link: https://lore.kernel.org/all/Y7Jal56f6UBh1abE@dev-arch.thelio-3990X/
Reported-by: Nathan Chancellor 
Signed-off-by: Masahiro Yamada 
Link: https://lore.kernel.org/r/20230105031306.1455409-1-masahi...@kernel.org
Signed-off-by: Heiko Carstens 
Signed-off-by: Tom Saeger 
---
 arch/s390/kernel/vmlinux.lds.S | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index f81d96710595..cbf9c1b0beda 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -17,6 +17,8 @@
 /* Handle ro_after_init data on our own. */
 #define RO_AFTER_INIT_DATA
 
+#define RUNTIME_DISCARD_EXIT
+
 #define EMITS_PT_NOTE
 
 #include 

-- 
2.39.1



[PATCH 6.1 v2 2/7] arm64: remove special treatment for the link order of head.o

2023-02-10 Thread Tom Saeger
From: Masahiro Yamada 

commit 994b7ac1697b4581b7726d2ac64321e3c840229b upstream.

In the previous discussion (see the Link tag), Ard pointed out that
arm/arm64/kernel/head.o does not need any special treatment - the only
piece that must appear right at the start of the binary image is the
image header which is emitted into .head.text.

The linker script does the right thing to do. The build system does
not need to manipulate the link order of head.o.

Link: 
https://lore.kernel.org/lkml/CAMj1kXH77Ja8bSsq2Qj8Ck9iSZKw=1F8Uy-uAWGVDm4-CG=e...@mail.gmail.com/
Suggested-by: Ard Biesheuvel 
Signed-off-by: Masahiro Yamada 
Reviewed-by: Nicolas Schier 
Link: https://lore.kernel.org/r/20221012233500.156764-1-masahi...@kernel.org
Signed-off-by: Will Deacon 
Signed-off-by: Tom Saeger 
---
 scripts/head-object-list.txt | 1 -
 1 file changed, 1 deletion(-)

diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt
index 105ea7ac4751..b074134cfac2 100644
--- a/scripts/head-object-list.txt
+++ b/scripts/head-object-list.txt
@@ -15,7 +15,6 @@ arch/alpha/kernel/head.o
 arch/arc/kernel/head.o
 arch/arm/kernel/head-nommu.o
 arch/arm/kernel/head.o
-arch/arm64/kernel/head.o
 arch/csky/kernel/head.o
 arch/hexagon/kernel/head.o
 arch/ia64/kernel/head.o

-- 
2.39.1



[PATCH 5.4 v2 5/6] s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36

2023-02-10 Thread Tom Saeger
From: Masahiro Yamada 

commit a494398bde273143c2352dd373cad8211f7d94b2 upstream.

Nathan Chancellor reports that the s390 vmlinux fails to link with
GNU ld < 2.36 since commit 99cb0d917ffa ("arch: fix broken BuildID
for arm64 and riscv").

It happens for defconfig, or more specifically for CONFIG_EXPOLINE=y.

  $ s390x-linux-gnu-ld --version | head -n1
  GNU ld (GNU Binutils for Debian) 2.35.2
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- allnoconfig
  $ ./scripts/config -e CONFIG_EXPOLINE
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- olddefconfig
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu-
  `.exit.text' referenced in section `.s390_return_reg' of drivers/base/dd.o: 
defined in discarded section `.exit.text' of drivers/base/dd.o
  make[1]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1
  make: *** [Makefile:1252: vmlinux] Error 2

arch/s390/kernel/vmlinux.lds.S wants to keep EXIT_TEXT:

.exit.text : {
EXIT_TEXT
}

But, at the same time, EXIT_TEXT is thrown away by DISCARD because
s390 does not define RUNTIME_DISCARD_EXIT.

I still do not understand why the latter wins after 99cb0d917ffa,
but defining RUNTIME_DISCARD_EXIT seems correct because the comment
line in arch/s390/kernel/vmlinux.lds.S says:

/*
 * .exit.text is discarded at runtime, not link time,
 * to deal with references from __bug_table
 */

Nathan also found that binutils commit 21401fc7bf67 ("Duplicate output
sections in scripts") cured this issue, so we cannot reproduce it with
binutils 2.36+, but it is better to not rely on it.

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Link: https://lore.kernel.org/all/Y7Jal56f6UBh1abE@dev-arch.thelio-3990X/
Reported-by: Nathan Chancellor 
Signed-off-by: Masahiro Yamada 
Link: https://lore.kernel.org/r/20230105031306.1455409-1-masahi...@kernel.org
Signed-off-by: Heiko Carstens 
Signed-off-by: Tom Saeger 
---
 arch/s390/kernel/vmlinux.lds.S | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 4df41695caec..a471bd480397 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -15,6 +15,8 @@
 /* Handle ro_after_init data on our own. */
 #define RO_AFTER_INIT_DATA
 
+#define RUNTIME_DISCARD_EXIT
+
 #include 
 #include 
 

-- 
2.39.1



[PATCH 5.4 v2 6/6] sh: define RUNTIME_DISCARD_EXIT

2023-02-10 Thread Tom Saeger
commit c1c551bebf928889e7a8fef7415b44f9a64975f4 upstream.

sh vmlinux fails to link with GNU ld < 2.40 (likely < 2.36) since
commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv").

This is similar to fixes for powerpc and s390:
commit 4b9880dbf3bd ("powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT").
commit a494398bde27 ("s390: define RUNTIME_DISCARD_EXIT to fix link error
with GNU ld < 2.36").

  $ sh4-linux-gnu-ld --version | head -n1
  GNU ld (GNU Binutils for Debian) 2.35.2

  $ make ARCH=sh CROSS_COMPILE=sh4-linux-gnu- microdev_defconfig
  $ make ARCH=sh CROSS_COMPILE=sh4-linux-gnu-

  `.exit.text' referenced in section `__bug_table' of crypto/algboss.o:
  defined in discarded section `.exit.text' of crypto/algboss.o
  `.exit.text' referenced in section `__bug_table' of
  drivers/char/hw_random/core.o: defined in discarded section
  `.exit.text' of drivers/char/hw_random/core.o
  make[2]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1
  make[1]: *** [Makefile:1252: vmlinux] Error 2

arch/sh/kernel/vmlinux.lds.S keeps EXIT_TEXT:

/*
 * .exit.text is discarded at runtime, not link time, to deal with
 * references from __bug_table
 */
.exit.text : AT(ADDR(.exit.text)) { EXIT_TEXT }

However, EXIT_TEXT is thrown away by
DISCARD(include/asm-generic/vmlinux.lds.h) because
sh does not define RUNTIME_DISCARD_EXIT.

GNU ld 2.40 does not have this issue and builds fine.
This corresponds with Masahiro's comments in a494398bde27:
"Nathan [Chancellor] also found that binutils
commit 21401fc7bf67 ("Duplicate output sections in scripts") cured this
issue, so we cannot reproduce it with binutils 2.36+, but it is better
to not rely on it."

Link: 
https://lkml.kernel.org/r/9166a8abdc0f979e50377e61780a4bba1dfa2f52.1674518464.git.tom.sae...@oracle.com
Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Link: https://lore.kernel.org/all/Y7Jal56f6UBh1abE@dev-arch.thelio-3990X/
Link: https://lore.kernel.org/all/20230123194218.47ssfzhrpnv3x...@oracle.com/
Signed-off-by: Tom Saeger 
Tested-by: John Paul Adrian Glaubitz 
Cc: Ard Biesheuvel 
Cc: Arnd Bergmann 
Cc: Christoph Hellwig 
Cc: Dennis Gilmore 
Cc: Greg Kroah-Hartman 
Cc: Masahiro Yamada 
Cc: Naresh Kamboju 
Cc: Nathan Chancellor 
Cc: Palmer Dabbelt 
Cc: Rich Felker 
Cc: Yoshinori Sato 
Signed-off-by: Andrew Morton 
Signed-off-by: Tom Saeger 
---
 arch/sh/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 77a59d8c6b4d..ec3bae172b20 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -10,6 +10,7 @@ OUTPUT_ARCH(sh:sh5)
 #define LOAD_OFFSET0
 OUTPUT_ARCH(sh)
 #endif
+#define RUNTIME_DISCARD_EXIT
 
 #include 
 #include 

-- 
2.39.1



[PATCH 5.4 v2 4/6] powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds

2023-02-10 Thread Tom Saeger
From: Michael Ellerman 

commit 07b050f9290ee012a407a0f64151db902a1520f5 upstream.

Relocatable kernels must not discard relocations, they need to be
processed at runtime. As such they are included for CONFIG_RELOCATABLE
builds in the powerpc linker script (line 340).

However they are also unconditionally discarded later in the
script (line 414). Previously that worked because the earlier inclusion
superseded the discard.

However commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and
riscv") introduced an earlier use of DISCARD as part of the RO_DATA
macro (line 137). With binutils < 2.36 that causes the DISCARD
directives later in the script to be applied earlier, causing .rela* to
actually be discarded at link time, leading to build warnings and a
kernel that doesn't boot:

  ld: warning: discarding dynamic section .rela.init.rodata

Fix it by conditionally discarding .rela* only when CONFIG_RELOCATABLE
is disabled.

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Signed-off-by: Michael Ellerman 

Link: https://lore.kernel.org/r/20230105132349.384666-2-...@ellerman.id.au
Signed-off-by: Tom Saeger 
---
 arch/powerpc/kernel/vmlinux.lds.S | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 4d5e1662a0ba..46dfb3701c6e 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -395,9 +395,12 @@ SECTIONS
DISCARDS
/DISCARD/ : {
*(*.EMB.apuinfo)
-   *(.glink .iplt .plt .rela* .comment)
+   *(.glink .iplt .plt .comment)
*(.gnu.version*)
*(.gnu.attributes)
*(.eh_frame)
+#ifndef CONFIG_RELOCATABLE
+   *(.rela*)
+#endif
}
 }

-- 
2.39.1



[PATCH 5.4 v2 3/6] powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT

2023-02-10 Thread Tom Saeger
From: Michael Ellerman 

commit 4b9880dbf3bdba3a7c56445137c3d0e30aaa0a40 upstream.

The powerpc linker script explicitly includes .exit.text, because
otherwise the link fails due to references from __bug_table and
__ex_table. The code is freed (discarded) at runtime along with
.init.text and data.

That has worked in the past despite powerpc not defining
RUNTIME_DISCARD_EXIT because DISCARDS appears late in the powerpc linker
script (line 410), and the explicit inclusion of .exit.text
earlier (line 280) supersedes the discard.

However commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and
riscv") introduced an earlier use of DISCARD as part of the RO_DATA
macro (line 136). With binutils < 2.36 that causes the DISCARD
directives later in the script to be applied earlier [1], causing
.exit.text to actually be discarded at link time, leading to build
errors:

  '.exit.text' referenced in section '__bug_table' of crypto/algboss.o: defined 
in
  discarded section '.exit.text' of crypto/algboss.o
  '.exit.text' referenced in section '__ex_table' of drivers/nvdimm/core.o: 
defined in
  discarded section '.exit.text' of drivers/nvdimm/core.o

Fix it by defining RUNTIME_DISCARD_EXIT, which causes the generic
DISCARDS macro to not include .exit.text at all.

1: https://lore.kernel.org/lkml/87fscp2v7k@igel.home/

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Signed-off-by: Michael Ellerman 
Link: https://lore.kernel.org/r/20230105132349.384666-1-...@ellerman.id.au
Signed-off-by: Tom Saeger 
---
 arch/powerpc/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 3ea360cad337..4d5e1662a0ba 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -6,6 +6,7 @@
 #endif
 
 #define BSS_FIRST_SECTIONS *(.bss.prominit)
+#define RUNTIME_DISCARD_EXIT
 
 #include 
 #include 

-- 
2.39.1



[PATCH 5.4 v2 2/6] arch: fix broken BuildID for arm64 and riscv

2023-02-10 Thread Tom Saeger
From: Masahiro Yamada 

commit 99cb0d917ffa1ab628bb67364ca9b162c07699b1 upstream.

Dennis Gilmore reports that the BuildID is missing in the arm64 vmlinux
since commit 994b7ac1697b ("arm64: remove special treatment for the
link order of head.o").

The issue is that the type of .notes section, which contains the BuildID,
changed from NOTES to PROGBITS.

Ard Biesheuvel figured out that whichever object gets linked first gets
to decide the type of a section. The PROGBITS type is the result of the
compiler emitting .note.GNU-stack as PROGBITS rather than NOTE.

While Ard provided a fix for arm64, I want to fix this globally because
the same issue is happening on riscv since commit 2348e6bf4421 ("riscv:
remove special treatment for the link order of head.o"). This problem
will happen in general for other architectures if they start to drop
unneeded entries from scripts/head-object-list.txt.

Discard .note.GNU-stack in include/asm-generic/vmlinux.lds.h.

Link: 
https://lore.kernel.org/lkml/CAABkxwuQoz1CTbyb57n0ZX65eSYiTonFCU8-LCQc=74D=xE=r...@mail.gmail.com/
Fixes: 994b7ac1697b ("arm64: remove special treatment for the link order of 
head.o")
Fixes: 2348e6bf4421 ("riscv: remove special treatment for the link order of 
head.o")
Reported-by: Dennis Gilmore 
Suggested-by: Ard Biesheuvel 
Signed-off-by: Masahiro Yamada 
Acked-by: Palmer Dabbelt 
Signed-off-by: Tom Saeger 
---
 include/asm-generic/vmlinux.lds.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 2d45d98773e2..a68535f36d13 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -825,7 +825,12 @@
 #define TRACEDATA
 #endif
 
+/*
+ * Discard .note.GNU-stack, which is emitted as PROGBITS by the compiler.
+ * Otherwise, the type of .notes section would become PROGBITS instead of 
NOTES.
+ */
 #define NOTES  \
+   /DISCARD/ : { *(.note.GNU-stack) }  \
.notes : AT(ADDR(.notes) - LOAD_OFFSET) {   \
__start_notes = .;  \
KEEP(*(.note.*))\

-- 
2.39.1



[PATCH 5.4 v2 0/6] Fix Build ID on arm64 if CONFIG_MODVERSIONS=y

2023-02-10 Thread Tom Saeger
Build ID is missing for arm64 with CONFIG_MODVERSIONS=y using ld >= 2.36
on 5.4, 5.10, and 5.15

Backport BuildID fixes.

I've build tested this on {x86_64, arm64, riscv, powerpc, s390, sh}.

  # view Build ID
  $ readelf -n vmlinux | grep "Build ID"

Changes for v2:
- rebase 6/6 c1c551bebf92 ("sh: define RUNTIME_DISCARD_EXIT") from upstream

Previous threads:
[1] https://lore.kernel.org/all/cover.1674588616.git.tom.sae...@oracle.com/
[2] 
https://lore.kernel.org/all/3df32572ec7016e783d37e185f88495831671f5d.1671143628.git.tom.sae...@oracle.com/
[3] https://lore.kernel.org/all/cover.1670358255.git.tom.sae...@oracle.com/

Signed-off-by: Tom Saeger 
---
H.J. Lu (1):
  x86, vmlinux.lds: Add RUNTIME_DISCARD_EXIT to generic DISCARDS

Masahiro Yamada (2):
  arch: fix broken BuildID for arm64 and riscv
  s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36

Michael Ellerman (2):
  powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT
  powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds

Tom Saeger (1):
  sh: define RUNTIME_DISCARD_EXIT

 arch/powerpc/kernel/vmlinux.lds.S |  6 +-
 arch/s390/kernel/vmlinux.lds.S|  2 ++
 arch/sh/kernel/vmlinux.lds.S  |  1 +
 arch/x86/kernel/vmlinux.lds.S |  1 +
 include/asm-generic/vmlinux.lds.h | 16 ++--
 5 files changed, 23 insertions(+), 3 deletions(-)
---
base-commit: 59342376e8f0c704299dc7a2c14fed07ffb962e2
change-id: 20230210-tsaeger-upstream-linux-stable-5-4-07f93e88c218

Best regards,
-- 
Tom Saeger 



[PATCH 5.4 v2 1/6] x86, vmlinux.lds: Add RUNTIME_DISCARD_EXIT to generic DISCARDS

2023-02-10 Thread Tom Saeger
From: "H.J. Lu" 

commit 84d5f77fc2ee4e010c2c037750e32f06e55224b0 upstream.

In the x86 kernel, .exit.text and .exit.data sections are discarded at
runtime, not by the linker. Add RUNTIME_DISCARD_EXIT to generic DISCARDS
and define it in the x86 kernel linker script to keep them.

The sections are added before the DISCARD directive so document here
only the situation explicitly as this change doesn't have any effect on
the generated kernel. Also, other architectures like ARM64 will use it
too so generalize the approach with the RUNTIME_DISCARD_EXIT define.

 [ bp: Massage and extend commit message. ]

Signed-off-by: H.J. Lu 
Signed-off-by: Borislav Petkov 
Reviewed-by: Kees Cook 
Link: https://lkml.kernel.org/r/20200326193021.255002-1-hjl.to...@gmail.com
Signed-off-by: Tom Saeger 
---
 arch/x86/kernel/vmlinux.lds.S |  1 +
 include/asm-generic/vmlinux.lds.h | 11 +--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 1afe211d7a7c..0ae3cd9a25ea 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -21,6 +21,7 @@
 #define LOAD_OFFSET __START_KERNEL_map
 #endif
 
+#define RUNTIME_DISCARD_EXIT
 #include 
 #include 
 #include 
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index c3bcac22c389..2d45d98773e2 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -900,10 +900,17 @@
  * section definitions so that such archs put those in earlier section
  * definitions.
  */
+#ifdef RUNTIME_DISCARD_EXIT
+#define EXIT_DISCARDS
+#else
+#define EXIT_DISCARDS  \
+   EXIT_TEXT   \
+   EXIT_DATA
+#endif
+
 #define DISCARDS   \
/DISCARD/ : {   \
-   EXIT_TEXT   \
-   EXIT_DATA   \
+   EXIT_DISCARDS   \
EXIT_CALL   \
*(.discard) \
*(.discard.*)   \

-- 
2.39.1



[PATCH 5.10 v2 4/5] s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36

2023-02-10 Thread Tom Saeger
From: Masahiro Yamada 

commit a494398bde273143c2352dd373cad8211f7d94b2 upstream.

Nathan Chancellor reports that the s390 vmlinux fails to link with
GNU ld < 2.36 since commit 99cb0d917ffa ("arch: fix broken BuildID
for arm64 and riscv").

It happens for defconfig, or more specifically for CONFIG_EXPOLINE=y.

  $ s390x-linux-gnu-ld --version | head -n1
  GNU ld (GNU Binutils for Debian) 2.35.2
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- allnoconfig
  $ ./scripts/config -e CONFIG_EXPOLINE
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- olddefconfig
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu-
  `.exit.text' referenced in section `.s390_return_reg' of drivers/base/dd.o: 
defined in discarded section `.exit.text' of drivers/base/dd.o
  make[1]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1
  make: *** [Makefile:1252: vmlinux] Error 2

arch/s390/kernel/vmlinux.lds.S wants to keep EXIT_TEXT:

.exit.text : {
EXIT_TEXT
}

But, at the same time, EXIT_TEXT is thrown away by DISCARD because
s390 does not define RUNTIME_DISCARD_EXIT.

I still do not understand why the latter wins after 99cb0d917ffa,
but defining RUNTIME_DISCARD_EXIT seems correct because the comment
line in arch/s390/kernel/vmlinux.lds.S says:

/*
 * .exit.text is discarded at runtime, not link time,
 * to deal with references from __bug_table
 */

Nathan also found that binutils commit 21401fc7bf67 ("Duplicate output
sections in scripts") cured this issue, so we cannot reproduce it with
binutils 2.36+, but it is better to not rely on it.

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Link: https://lore.kernel.org/all/Y7Jal56f6UBh1abE@dev-arch.thelio-3990X/
Reported-by: Nathan Chancellor 
Signed-off-by: Masahiro Yamada 
Link: https://lore.kernel.org/r/20230105031306.1455409-1-masahi...@kernel.org
Signed-off-by: Heiko Carstens 
Signed-off-by: Tom Saeger 
---
 arch/s390/kernel/vmlinux.lds.S | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 9505bdb0aa54..137c805d6896 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -15,6 +15,8 @@
 /* Handle ro_after_init data on our own. */
 #define RO_AFTER_INIT_DATA
 
+#define RUNTIME_DISCARD_EXIT
+
 #define EMITS_PT_NOTE
 
 #include 

-- 
2.39.1



[PATCH 5.10 v2 5/5] sh: define RUNTIME_DISCARD_EXIT

2023-02-10 Thread Tom Saeger
commit c1c551bebf928889e7a8fef7415b44f9a64975f4 upstream.

sh vmlinux fails to link with GNU ld < 2.40 (likely < 2.36) since
commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv").

This is similar to fixes for powerpc and s390:
commit 4b9880dbf3bd ("powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT").
commit a494398bde27 ("s390: define RUNTIME_DISCARD_EXIT to fix link error
with GNU ld < 2.36").

  $ sh4-linux-gnu-ld --version | head -n1
  GNU ld (GNU Binutils for Debian) 2.35.2

  $ make ARCH=sh CROSS_COMPILE=sh4-linux-gnu- microdev_defconfig
  $ make ARCH=sh CROSS_COMPILE=sh4-linux-gnu-

  `.exit.text' referenced in section `__bug_table' of crypto/algboss.o:
  defined in discarded section `.exit.text' of crypto/algboss.o
  `.exit.text' referenced in section `__bug_table' of
  drivers/char/hw_random/core.o: defined in discarded section
  `.exit.text' of drivers/char/hw_random/core.o
  make[2]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1
  make[1]: *** [Makefile:1252: vmlinux] Error 2

arch/sh/kernel/vmlinux.lds.S keeps EXIT_TEXT:

/*
 * .exit.text is discarded at runtime, not link time, to deal with
 * references from __bug_table
 */
.exit.text : AT(ADDR(.exit.text)) { EXIT_TEXT }

However, EXIT_TEXT is thrown away by
DISCARD(include/asm-generic/vmlinux.lds.h) because
sh does not define RUNTIME_DISCARD_EXIT.

GNU ld 2.40 does not have this issue and builds fine.
This corresponds with Masahiro's comments in a494398bde27:
"Nathan [Chancellor] also found that binutils
commit 21401fc7bf67 ("Duplicate output sections in scripts") cured this
issue, so we cannot reproduce it with binutils 2.36+, but it is better
to not rely on it."

Link: 
https://lkml.kernel.org/r/9166a8abdc0f979e50377e61780a4bba1dfa2f52.1674518464.git.tom.sae...@oracle.com
Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Link: https://lore.kernel.org/all/Y7Jal56f6UBh1abE@dev-arch.thelio-3990X/
Link: https://lore.kernel.org/all/20230123194218.47ssfzhrpnv3x...@oracle.com/
Signed-off-by: Tom Saeger 
Tested-by: John Paul Adrian Glaubitz 
Cc: Ard Biesheuvel 
Cc: Arnd Bergmann 
Cc: Christoph Hellwig 
Cc: Dennis Gilmore 
Cc: Greg Kroah-Hartman 
Cc: Masahiro Yamada 
Cc: Naresh Kamboju 
Cc: Nathan Chancellor 
Cc: Palmer Dabbelt 
Cc: Rich Felker 
Cc: Yoshinori Sato 
Signed-off-by: Andrew Morton 
Signed-off-by: Tom Saeger 
---
 arch/sh/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 3161b9ccd2a5..b6276a3521d7 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -4,6 +4,7 @@
  * Written by Niibe Yutaka and Paul Mundt
  */
 OUTPUT_ARCH(sh)
+#define RUNTIME_DISCARD_EXIT
 #include 
 #include 
 #include 

-- 
2.39.1



[PATCH 5.10 v2 3/5] powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds

2023-02-10 Thread Tom Saeger
From: Michael Ellerman 

commit 07b050f9290ee012a407a0f64151db902a1520f5 upstream.

Relocatable kernels must not discard relocations, they need to be
processed at runtime. As such they are included for CONFIG_RELOCATABLE
builds in the powerpc linker script (line 340).

However they are also unconditionally discarded later in the
script (line 414). Previously that worked because the earlier inclusion
superseded the discard.

However commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and
riscv") introduced an earlier use of DISCARD as part of the RO_DATA
macro (line 137). With binutils < 2.36 that causes the DISCARD
directives later in the script to be applied earlier, causing .rela* to
actually be discarded at link time, leading to build warnings and a
kernel that doesn't boot:

  ld: warning: discarding dynamic section .rela.init.rodata

Fix it by conditionally discarding .rela* only when CONFIG_RELOCATABLE
is disabled.

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Signed-off-by: Michael Ellerman 

Link: https://lore.kernel.org/r/20230105132349.384666-2-...@ellerman.id.au
Signed-off-by: Tom Saeger 
---
 arch/powerpc/kernel/vmlinux.lds.S | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index e3984389f8ef..fabe6cf10bd2 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -379,9 +379,12 @@ SECTIONS
DISCARDS
/DISCARD/ : {
*(*.EMB.apuinfo)
-   *(.glink .iplt .plt .rela* .comment)
+   *(.glink .iplt .plt .comment)
*(.gnu.version*)
*(.gnu.attributes)
*(.eh_frame)
+#ifndef CONFIG_RELOCATABLE
+   *(.rela*)
+#endif
}
 }

-- 
2.39.1



[PATCH 5.10 v2 0/5] Fix Build ID on arm64 if CONFIG_MODVERSIONS=y

2023-02-10 Thread Tom Saeger
Build ID is missing for arm64 with CONFIG_MODVERSIONS=y using ld >= 2.36
on 5.4, 5.10, and 5.15

Backport BuildID fixes.

I've build tested this on {x86_64, arm64, riscv, powerpc, s390, sh}.

  # view Build ID
  $ readelf -n vmlinux | grep "Build ID"

Changes for v2:
- rebase 5/5 c1c551bebf92 ("sh: define RUNTIME_DISCARD_EXIT") from upstream

Previous threads:
[1] https://lore.kernel.org/all/cover.1674850666.git.tom.sae...@oracle.com
[2] 
https://lore.kernel.org/all/3df32572ec7016e783d37e185f88495831671f5d.1671143628.git.tom.sae...@oracle.com/
[3] https://lore.kernel.org/all/cover.1670358255.git.tom.sae...@oracle.com/

Signed-off-by: Tom Saeger 
---
Masahiro Yamada (2):
  arch: fix broken BuildID for arm64 and riscv
  s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36

Michael Ellerman (2):
  powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT
  powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds

Tom Saeger (1):
  sh: define RUNTIME_DISCARD_EXIT

 arch/powerpc/kernel/vmlinux.lds.S | 6 +-
 arch/s390/kernel/vmlinux.lds.S| 2 ++
 arch/sh/kernel/vmlinux.lds.S  | 1 +
 include/asm-generic/vmlinux.lds.h | 5 +
 4 files changed, 13 insertions(+), 1 deletion(-)
---
base-commit: a5acb54d4066f27e9707af9d93f047f542d5ad88
change-id: 20230210-tsaeger-upstream-linux-5-10-y-e443820440f6

Best regards,
-- 
Tom Saeger 



[PATCH 5.10 v2 2/5] powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT

2023-02-10 Thread Tom Saeger
From: Michael Ellerman 

commit 4b9880dbf3bdba3a7c56445137c3d0e30aaa0a40 upstream.

The powerpc linker script explicitly includes .exit.text, because
otherwise the link fails due to references from __bug_table and
__ex_table. The code is freed (discarded) at runtime along with
.init.text and data.

That has worked in the past despite powerpc not defining
RUNTIME_DISCARD_EXIT because DISCARDS appears late in the powerpc linker
script (line 410), and the explicit inclusion of .exit.text
earlier (line 280) supersedes the discard.

However commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and
riscv") introduced an earlier use of DISCARD as part of the RO_DATA
macro (line 136). With binutils < 2.36 that causes the DISCARD
directives later in the script to be applied earlier [1], causing
.exit.text to actually be discarded at link time, leading to build
errors:

  '.exit.text' referenced in section '__bug_table' of crypto/algboss.o: defined 
in
  discarded section '.exit.text' of crypto/algboss.o
  '.exit.text' referenced in section '__ex_table' of drivers/nvdimm/core.o: 
defined in
  discarded section '.exit.text' of drivers/nvdimm/core.o

Fix it by defining RUNTIME_DISCARD_EXIT, which causes the generic
DISCARDS macro to not include .exit.text at all.

1: https://lore.kernel.org/lkml/87fscp2v7k@igel.home/

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Signed-off-by: Michael Ellerman 
Link: https://lore.kernel.org/r/20230105132349.384666-1-...@ellerman.id.au
Signed-off-by: Tom Saeger 
---
 arch/powerpc/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 4a1f494ef03f..e3984389f8ef 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -8,6 +8,7 @@
 #define BSS_FIRST_SECTIONS *(.bss.prominit)
 #define EMITS_PT_NOTE
 #define RO_EXCEPTION_TABLE_ALIGN   0
+#define RUNTIME_DISCARD_EXIT
 
 #include 
 #include 

-- 
2.39.1



[PATCH 5.10 v2 1/5] arch: fix broken BuildID for arm64 and riscv

2023-02-10 Thread Tom Saeger
From: Masahiro Yamada 

commit 99cb0d917ffa1ab628bb67364ca9b162c07699b1 upstream.

Dennis Gilmore reports that the BuildID is missing in the arm64 vmlinux
since commit 994b7ac1697b ("arm64: remove special treatment for the
link order of head.o").

The issue is that the type of .notes section, which contains the BuildID,
changed from NOTES to PROGBITS.

Ard Biesheuvel figured out that whichever object gets linked first gets
to decide the type of a section. The PROGBITS type is the result of the
compiler emitting .note.GNU-stack as PROGBITS rather than NOTE.

While Ard provided a fix for arm64, I want to fix this globally because
the same issue is happening on riscv since commit 2348e6bf4421 ("riscv:
remove special treatment for the link order of head.o"). This problem
will happen in general for other architectures if they start to drop
unneeded entries from scripts/head-object-list.txt.

Discard .note.GNU-stack in include/asm-generic/vmlinux.lds.h.

Link: 
https://lore.kernel.org/lkml/CAABkxwuQoz1CTbyb57n0ZX65eSYiTonFCU8-LCQc=74D=xE=r...@mail.gmail.com/
Fixes: 994b7ac1697b ("arm64: remove special treatment for the link order of 
head.o")
Fixes: 2348e6bf4421 ("riscv: remove special treatment for the link order of 
head.o")
Reported-by: Dennis Gilmore 
Suggested-by: Ard Biesheuvel 
Signed-off-by: Masahiro Yamada 
Acked-by: Palmer Dabbelt 
Signed-off-by: Tom Saeger 
---
 include/asm-generic/vmlinux.lds.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index d233f9e4b9c6..44103f9487c9 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -906,7 +906,12 @@
 #define TRACEDATA
 #endif
 
+/*
+ * Discard .note.GNU-stack, which is emitted as PROGBITS by the compiler.
+ * Otherwise, the type of .notes section would become PROGBITS instead of 
NOTES.
+ */
 #define NOTES  \
+   /DISCARD/ : { *(.note.GNU-stack) }  \
.notes : AT(ADDR(.notes) - LOAD_OFFSET) {   \
__start_notes = .;  \
KEEP(*(.note.*))\

-- 
2.39.1



[PATCH 5.15 v2 5/5] sh: define RUNTIME_DISCARD_EXIT

2023-02-10 Thread Tom Saeger
commit c1c551bebf928889e7a8fef7415b44f9a64975f4 upstream.

sh vmlinux fails to link with GNU ld < 2.40 (likely < 2.36) since
commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv").

This is similar to fixes for powerpc and s390:
commit 4b9880dbf3bd ("powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT").
commit a494398bde27 ("s390: define RUNTIME_DISCARD_EXIT to fix link error
with GNU ld < 2.36").

  $ sh4-linux-gnu-ld --version | head -n1
  GNU ld (GNU Binutils for Debian) 2.35.2

  $ make ARCH=sh CROSS_COMPILE=sh4-linux-gnu- microdev_defconfig
  $ make ARCH=sh CROSS_COMPILE=sh4-linux-gnu-

  `.exit.text' referenced in section `__bug_table' of crypto/algboss.o:
  defined in discarded section `.exit.text' of crypto/algboss.o
  `.exit.text' referenced in section `__bug_table' of
  drivers/char/hw_random/core.o: defined in discarded section
  `.exit.text' of drivers/char/hw_random/core.o
  make[2]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1
  make[1]: *** [Makefile:1252: vmlinux] Error 2

arch/sh/kernel/vmlinux.lds.S keeps EXIT_TEXT:

/*
 * .exit.text is discarded at runtime, not link time, to deal with
 * references from __bug_table
 */
.exit.text : AT(ADDR(.exit.text)) { EXIT_TEXT }

However, EXIT_TEXT is thrown away by
DISCARD(include/asm-generic/vmlinux.lds.h) because
sh does not define RUNTIME_DISCARD_EXIT.

GNU ld 2.40 does not have this issue and builds fine.
This corresponds with Masahiro's comments in a494398bde27:
"Nathan [Chancellor] also found that binutils
commit 21401fc7bf67 ("Duplicate output sections in scripts") cured this
issue, so we cannot reproduce it with binutils 2.36+, but it is better
to not rely on it."

Link: 
https://lkml.kernel.org/r/9166a8abdc0f979e50377e61780a4bba1dfa2f52.1674518464.git.tom.sae...@oracle.com
Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Link: https://lore.kernel.org/all/Y7Jal56f6UBh1abE@dev-arch.thelio-3990X/
Link: https://lore.kernel.org/all/20230123194218.47ssfzhrpnv3x...@oracle.com/
Signed-off-by: Tom Saeger 
Tested-by: John Paul Adrian Glaubitz 
Cc: Ard Biesheuvel 
Cc: Arnd Bergmann 
Cc: Christoph Hellwig 
Cc: Dennis Gilmore 
Cc: Greg Kroah-Hartman 
Cc: Masahiro Yamada 
Cc: Naresh Kamboju 
Cc: Nathan Chancellor 
Cc: Palmer Dabbelt 
Cc: Rich Felker 
Cc: Yoshinori Sato 
Signed-off-by: Andrew Morton 
Signed-off-by: Tom Saeger 
---
 arch/sh/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 3161b9ccd2a5..b6276a3521d7 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -4,6 +4,7 @@
  * Written by Niibe Yutaka and Paul Mundt
  */
 OUTPUT_ARCH(sh)
+#define RUNTIME_DISCARD_EXIT
 #include 
 #include 
 #include 

-- 
2.39.1



[PATCH 5.15 v2 4/5] s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36

2023-02-10 Thread Tom Saeger
From: Masahiro Yamada 

commit a494398bde273143c2352dd373cad8211f7d94b2 upstream.

Nathan Chancellor reports that the s390 vmlinux fails to link with
GNU ld < 2.36 since commit 99cb0d917ffa ("arch: fix broken BuildID
for arm64 and riscv").

It happens for defconfig, or more specifically for CONFIG_EXPOLINE=y.

  $ s390x-linux-gnu-ld --version | head -n1
  GNU ld (GNU Binutils for Debian) 2.35.2
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- allnoconfig
  $ ./scripts/config -e CONFIG_EXPOLINE
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- olddefconfig
  $ make -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu-
  `.exit.text' referenced in section `.s390_return_reg' of drivers/base/dd.o: 
defined in discarded section `.exit.text' of drivers/base/dd.o
  make[1]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1
  make: *** [Makefile:1252: vmlinux] Error 2

arch/s390/kernel/vmlinux.lds.S wants to keep EXIT_TEXT:

.exit.text : {
EXIT_TEXT
}

But, at the same time, EXIT_TEXT is thrown away by DISCARD because
s390 does not define RUNTIME_DISCARD_EXIT.

I still do not understand why the latter wins after 99cb0d917ffa,
but defining RUNTIME_DISCARD_EXIT seems correct because the comment
line in arch/s390/kernel/vmlinux.lds.S says:

/*
 * .exit.text is discarded at runtime, not link time,
 * to deal with references from __bug_table
 */

Nathan also found that binutils commit 21401fc7bf67 ("Duplicate output
sections in scripts") cured this issue, so we cannot reproduce it with
binutils 2.36+, but it is better to not rely on it.

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Link: https://lore.kernel.org/all/Y7Jal56f6UBh1abE@dev-arch.thelio-3990X/
Reported-by: Nathan Chancellor 
Signed-off-by: Masahiro Yamada 
Link: https://lore.kernel.org/r/20230105031306.1455409-1-masahi...@kernel.org
Signed-off-by: Heiko Carstens 
Signed-off-by: Tom Saeger 
---
 arch/s390/kernel/vmlinux.lds.S | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 8ce1615c1046..cdc8b84b2db4 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -17,6 +17,8 @@
 /* Handle ro_after_init data on our own. */
 #define RO_AFTER_INIT_DATA
 
+#define RUNTIME_DISCARD_EXIT
+
 #define EMITS_PT_NOTE
 
 #include 

-- 
2.39.1



[PATCH 5.15 v2 3/5] powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds

2023-02-10 Thread Tom Saeger
From: Michael Ellerman 

commit 07b050f9290ee012a407a0f64151db902a1520f5 upstream.

Relocatable kernels must not discard relocations, they need to be
processed at runtime. As such they are included for CONFIG_RELOCATABLE
builds in the powerpc linker script (line 340).

However they are also unconditionally discarded later in the
script (line 414). Previously that worked because the earlier inclusion
superseded the discard.

However commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and
riscv") introduced an earlier use of DISCARD as part of the RO_DATA
macro (line 137). With binutils < 2.36 that causes the DISCARD
directives later in the script to be applied earlier, causing .rela* to
actually be discarded at link time, leading to build warnings and a
kernel that doesn't boot:

  ld: warning: discarding dynamic section .rela.init.rodata

Fix it by conditionally discarding .rela* only when CONFIG_RELOCATABLE
is disabled.

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Signed-off-by: Michael Ellerman 

Link: https://lore.kernel.org/r/20230105132349.384666-2-...@ellerman.id.au
Signed-off-by: Tom Saeger 
---
 arch/powerpc/kernel/vmlinux.lds.S | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 50a04347ab05..3a3ef558244a 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -400,9 +400,12 @@ SECTIONS
DISCARDS
/DISCARD/ : {
*(*.EMB.apuinfo)
-   *(.glink .iplt .plt .rela* .comment)
+   *(.glink .iplt .plt .comment)
*(.gnu.version*)
*(.gnu.attributes)
*(.eh_frame)
+#ifndef CONFIG_RELOCATABLE
+   *(.rela*)
+#endif
}
 }

-- 
2.39.1



[PATCH 5.15 v2 2/5] powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT

2023-02-10 Thread Tom Saeger
From: Michael Ellerman 

commit 4b9880dbf3bdba3a7c56445137c3d0e30aaa0a40 upstream.

The powerpc linker script explicitly includes .exit.text, because
otherwise the link fails due to references from __bug_table and
__ex_table. The code is freed (discarded) at runtime along with
.init.text and data.

That has worked in the past despite powerpc not defining
RUNTIME_DISCARD_EXIT because DISCARDS appears late in the powerpc linker
script (line 410), and the explicit inclusion of .exit.text
earlier (line 280) supersedes the discard.

However commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and
riscv") introduced an earlier use of DISCARD as part of the RO_DATA
macro (line 136). With binutils < 2.36 that causes the DISCARD
directives later in the script to be applied earlier [1], causing
.exit.text to actually be discarded at link time, leading to build
errors:

  '.exit.text' referenced in section '__bug_table' of crypto/algboss.o: defined 
in
  discarded section '.exit.text' of crypto/algboss.o
  '.exit.text' referenced in section '__ex_table' of drivers/nvdimm/core.o: 
defined in
  discarded section '.exit.text' of drivers/nvdimm/core.o

Fix it by defining RUNTIME_DISCARD_EXIT, which causes the generic
DISCARDS macro to not include .exit.text at all.

1: https://lore.kernel.org/lkml/87fscp2v7k@igel.home/

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Signed-off-by: Michael Ellerman 
Link: https://lore.kernel.org/r/20230105132349.384666-1-...@ellerman.id.au
Signed-off-by: Tom Saeger 
---
 arch/powerpc/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 1a63e37f336a..50a04347ab05 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -8,6 +8,7 @@
 #define BSS_FIRST_SECTIONS *(.bss.prominit)
 #define EMITS_PT_NOTE
 #define RO_EXCEPTION_TABLE_ALIGN   0
+#define RUNTIME_DISCARD_EXIT
 
 #define SOFT_MASK_TABLE(align) \
. = ALIGN(align);   \

-- 
2.39.1



[PATCH 5.15 v2 0/5] Fix Build ID on arm64 if CONFIG_MODVERSIONS=y

2023-02-10 Thread Tom Saeger
Build ID is missing for arm64 with CONFIG_MODVERSIONS=y using ld >= 2.36
on 5.4, 5.10, and 5.15

Backport BuildID fixes.

I've build tested this on {x86_64, arm64, riscv, powerpc, s390, sh}.

  # view Build ID
  $ readelf -n vmlinux | grep "Build ID"

Changes for v2:
- rebase 5/5 c1c551bebf92 ("sh: define RUNTIME_DISCARD_EXIT") from upstream

Previous threads:
[1] https://lore.kernel.org/all/cover.1674851705.git.tom.sae...@oracle.com/
[2] 
https://lore.kernel.org/all/3df32572ec7016e783d37e185f88495831671f5d.1671143628.git.tom.sae...@oracle.com/
[3] https://lore.kernel.org/all/cover.1670358255.git.tom.sae...@oracle.com/

Signed-off-by: Tom Saeger 
---
Masahiro Yamada (2):
  arch: fix broken BuildID for arm64 and riscv
  s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36

Michael Ellerman (2):
  powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT
  powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds

Tom Saeger (1):
  sh: define RUNTIME_DISCARD_EXIT

 arch/powerpc/kernel/vmlinux.lds.S | 6 +-
 arch/s390/kernel/vmlinux.lds.S| 2 ++
 arch/sh/kernel/vmlinux.lds.S  | 1 +
 include/asm-generic/vmlinux.lds.h | 5 +
 4 files changed, 13 insertions(+), 1 deletion(-)
---
base-commit: 85d7786c66b69d3f07cc149ac2f78d8f330c7c11
change-id: 20230210-tsaeger-upstream-linux-stable-5-15-f7bf45952c23

Best regards,
-- 
Tom Saeger 



[PATCH 5.15 v2 1/5] arch: fix broken BuildID for arm64 and riscv

2023-02-10 Thread Tom Saeger
From: Masahiro Yamada 

commit 99cb0d917ffa1ab628bb67364ca9b162c07699b1 upstream.

Dennis Gilmore reports that the BuildID is missing in the arm64 vmlinux
since commit 994b7ac1697b ("arm64: remove special treatment for the
link order of head.o").

The issue is that the type of .notes section, which contains the BuildID,
changed from NOTES to PROGBITS.

Ard Biesheuvel figured out that whichever object gets linked first gets
to decide the type of a section. The PROGBITS type is the result of the
compiler emitting .note.GNU-stack as PROGBITS rather than NOTE.

While Ard provided a fix for arm64, I want to fix this globally because
the same issue is happening on riscv since commit 2348e6bf4421 ("riscv:
remove special treatment for the link order of head.o"). This problem
will happen in general for other architectures if they start to drop
unneeded entries from scripts/head-object-list.txt.

Discard .note.GNU-stack in include/asm-generic/vmlinux.lds.h.

Link: 
https://lore.kernel.org/lkml/CAABkxwuQoz1CTbyb57n0ZX65eSYiTonFCU8-LCQc=74D=xE=r...@mail.gmail.com/
Fixes: 994b7ac1697b ("arm64: remove special treatment for the link order of 
head.o")
Fixes: 2348e6bf4421 ("riscv: remove special treatment for the link order of 
head.o")
Reported-by: Dennis Gilmore 
Suggested-by: Ard Biesheuvel 
Signed-off-by: Masahiro Yamada 
Acked-by: Palmer Dabbelt 
Signed-off-by: Tom Saeger 
---
 include/asm-generic/vmlinux.lds.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index e28792ca25a1..8471717c5085 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -903,7 +903,12 @@
 #define PRINTK_INDEX
 #endif
 
+/*
+ * Discard .note.GNU-stack, which is emitted as PROGBITS by the compiler.
+ * Otherwise, the type of .notes section would become PROGBITS instead of 
NOTES.
+ */
 #define NOTES  \
+   /DISCARD/ : { *(.note.GNU-stack) }  \
.notes : AT(ADDR(.notes) - LOAD_OFFSET) {   \
__start_notes = .;  \
KEEP(*(.note.*))\

-- 
2.39.1



[PATCH 6.1 v2 7/7] sh: define RUNTIME_DISCARD_EXIT

2023-02-10 Thread Tom Saeger
commit c1c551bebf928889e7a8fef7415b44f9a64975f4 upstream.

sh vmlinux fails to link with GNU ld < 2.40 (likely < 2.36) since
commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv").

This is similar to fixes for powerpc and s390:
commit 4b9880dbf3bd ("powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT").
commit a494398bde27 ("s390: define RUNTIME_DISCARD_EXIT to fix link error
with GNU ld < 2.36").

  $ sh4-linux-gnu-ld --version | head -n1
  GNU ld (GNU Binutils for Debian) 2.35.2

  $ make ARCH=sh CROSS_COMPILE=sh4-linux-gnu- microdev_defconfig
  $ make ARCH=sh CROSS_COMPILE=sh4-linux-gnu-

  `.exit.text' referenced in section `__bug_table' of crypto/algboss.o:
  defined in discarded section `.exit.text' of crypto/algboss.o
  `.exit.text' referenced in section `__bug_table' of
  drivers/char/hw_random/core.o: defined in discarded section
  `.exit.text' of drivers/char/hw_random/core.o
  make[2]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1
  make[1]: *** [Makefile:1252: vmlinux] Error 2

arch/sh/kernel/vmlinux.lds.S keeps EXIT_TEXT:

/*
 * .exit.text is discarded at runtime, not link time, to deal with
 * references from __bug_table
 */
.exit.text : AT(ADDR(.exit.text)) { EXIT_TEXT }

However, EXIT_TEXT is thrown away by
DISCARD(include/asm-generic/vmlinux.lds.h) because
sh does not define RUNTIME_DISCARD_EXIT.

GNU ld 2.40 does not have this issue and builds fine.
This corresponds with Masahiro's comments in a494398bde27:
"Nathan [Chancellor] also found that binutils
commit 21401fc7bf67 ("Duplicate output sections in scripts") cured this
issue, so we cannot reproduce it with binutils 2.36+, but it is better
to not rely on it."

Link: 
https://lkml.kernel.org/r/9166a8abdc0f979e50377e61780a4bba1dfa2f52.1674518464.git.tom.sae...@oracle.com
Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Link: https://lore.kernel.org/all/Y7Jal56f6UBh1abE@dev-arch.thelio-3990X/
Link: https://lore.kernel.org/all/20230123194218.47ssfzhrpnv3x...@oracle.com/
Signed-off-by: Tom Saeger 
Tested-by: John Paul Adrian Glaubitz 
Cc: Ard Biesheuvel 
Cc: Arnd Bergmann 
Cc: Christoph Hellwig 
Cc: Dennis Gilmore 
Cc: Greg Kroah-Hartman 
Cc: Masahiro Yamada 
Cc: Naresh Kamboju 
Cc: Nathan Chancellor 
Cc: Palmer Dabbelt 
Cc: Rich Felker 
Cc: Yoshinori Sato 
Signed-off-by: Andrew Morton 
Signed-off-by: Tom Saeger 
---
 arch/sh/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 3161b9ccd2a5..b6276a3521d7 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -4,6 +4,7 @@
  * Written by Niibe Yutaka and Paul Mundt
  */
 OUTPUT_ARCH(sh)
+#define RUNTIME_DISCARD_EXIT
 #include 
 #include 
 #include 

-- 
2.39.1



[PATCH 6.1 v2 5/7] powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds

2023-02-10 Thread Tom Saeger
From: Michael Ellerman 

commit 07b050f9290ee012a407a0f64151db902a1520f5 upstream.

Relocatable kernels must not discard relocations, they need to be
processed at runtime. As such they are included for CONFIG_RELOCATABLE
builds in the powerpc linker script (line 340).

However they are also unconditionally discarded later in the
script (line 414). Previously that worked because the earlier inclusion
superseded the discard.

However commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and
riscv") introduced an earlier use of DISCARD as part of the RO_DATA
macro (line 137). With binutils < 2.36 that causes the DISCARD
directives later in the script to be applied earlier, causing .rela* to
actually be discarded at link time, leading to build warnings and a
kernel that doesn't boot:

  ld: warning: discarding dynamic section .rela.init.rodata

Fix it by conditionally discarding .rela* only when CONFIG_RELOCATABLE
is disabled.

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Signed-off-by: Michael Ellerman 

Link: https://lore.kernel.org/r/20230105132349.384666-2-...@ellerman.id.au
Signed-off-by: Tom Saeger 
---
 arch/powerpc/kernel/vmlinux.lds.S | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index c5ea7d03d539..a4c6efadc90c 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -411,9 +411,12 @@ SECTIONS
DISCARDS
/DISCARD/ : {
*(*.EMB.apuinfo)
-   *(.glink .iplt .plt .rela* .comment)
+   *(.glink .iplt .plt .comment)
*(.gnu.version*)
*(.gnu.attributes)
*(.eh_frame)
+#ifndef CONFIG_RELOCATABLE
+   *(.rela*)
+#endif
}
 }

-- 
2.39.1



[PATCH 6.1 v2 4/7] powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT

2023-02-10 Thread Tom Saeger
From: Michael Ellerman 

commit 4b9880dbf3bdba3a7c56445137c3d0e30aaa0a40 upstream.

The powerpc linker script explicitly includes .exit.text, because
otherwise the link fails due to references from __bug_table and
__ex_table. The code is freed (discarded) at runtime along with
.init.text and data.

That has worked in the past despite powerpc not defining
RUNTIME_DISCARD_EXIT because DISCARDS appears late in the powerpc linker
script (line 410), and the explicit inclusion of .exit.text
earlier (line 280) supersedes the discard.

However commit 99cb0d917ffa ("arch: fix broken BuildID for arm64 and
riscv") introduced an earlier use of DISCARD as part of the RO_DATA
macro (line 136). With binutils < 2.36 that causes the DISCARD
directives later in the script to be applied earlier [1], causing
.exit.text to actually be discarded at link time, leading to build
errors:

  '.exit.text' referenced in section '__bug_table' of crypto/algboss.o: defined 
in
  discarded section '.exit.text' of crypto/algboss.o
  '.exit.text' referenced in section '__ex_table' of drivers/nvdimm/core.o: 
defined in
  discarded section '.exit.text' of drivers/nvdimm/core.o

Fix it by defining RUNTIME_DISCARD_EXIT, which causes the generic
DISCARDS macro to not include .exit.text at all.

1: https://lore.kernel.org/lkml/87fscp2v7k@igel.home/

Fixes: 99cb0d917ffa ("arch: fix broken BuildID for arm64 and riscv")
Signed-off-by: Michael Ellerman 
Link: https://lore.kernel.org/r/20230105132349.384666-1-...@ellerman.id.au
Signed-off-by: Tom Saeger 
---
 arch/powerpc/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 8c3862b4c259..c5ea7d03d539 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -8,6 +8,7 @@
 #define BSS_FIRST_SECTIONS *(.bss.prominit)
 #define EMITS_PT_NOTE
 #define RO_EXCEPTION_TABLE_ALIGN   0
+#define RUNTIME_DISCARD_EXIT
 
 #define SOFT_MASK_TABLE(align) \
. = ALIGN(align);   \

-- 
2.39.1



[PATCH 6.1 v2 0/7] Backport Build ID fixes

2023-02-10 Thread Tom Saeger
Keep 6.1 in-sync with Build ID fixes.

I've build tested this on {x86_64, arm64, riscv, powerpc, s390, sh}.

Changes for v2:
- include 1/7 2348e6bf4421 ("riscv: remove special treatment for the link order 
of head.o")
- include 2/7 994b7ac1697b ("arm64: remove special treatment for the link order 
of head.o")
- rebase  7/7 c1c551bebf92 ("sh: define RUNTIME_DISCARD_EXIT") from upstream

Previous threads:
[1] https://lore.kernel.org/all/cover.1674876902.git.tom.sae...@oracle.com/
[2] 
https://lore.kernel.org/all/3df32572ec7016e783d37e185f88495831671f5d.1671143628.git.tom.sae...@oracle.com/
[3] https://lore.kernel.org/all/cover.1670358255.git.tom.sae...@oracle.com/

Signed-off-by: Tom Saeger 
---
Jisheng Zhang (1):
  riscv: remove special treatment for the link order of head.o

Masahiro Yamada (3):
  arm64: remove special treatment for the link order of head.o
  arch: fix broken BuildID for arm64 and riscv
  s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36

Michael Ellerman (2):
  powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT
  powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds

Tom Saeger (1):
  sh: define RUNTIME_DISCARD_EXIT

 arch/powerpc/kernel/vmlinux.lds.S | 6 +-
 arch/s390/kernel/vmlinux.lds.S| 2 ++
 arch/sh/kernel/vmlinux.lds.S  | 1 +
 include/asm-generic/vmlinux.lds.h | 5 +
 scripts/head-object-list.txt  | 2 --
 5 files changed, 13 insertions(+), 3 deletions(-)
---
base-commit: d60c95efffe84428e3611431bf688f50bfc13f4e
change-id: 20230210-tsaeger-upstream-linux-6-1-y-06c93fbe5bc8

Best regards,
-- 
Tom Saeger 



[PATCH 6.1 v2 3/7] arch: fix broken BuildID for arm64 and riscv

2023-02-10 Thread Tom Saeger
From: Masahiro Yamada 

commit 99cb0d917ffa1ab628bb67364ca9b162c07699b1 upstream.

Dennis Gilmore reports that the BuildID is missing in the arm64 vmlinux
since commit 994b7ac1697b ("arm64: remove special treatment for the
link order of head.o").

The issue is that the type of .notes section, which contains the BuildID,
changed from NOTES to PROGBITS.

Ard Biesheuvel figured out that whichever object gets linked first gets
to decide the type of a section. The PROGBITS type is the result of the
compiler emitting .note.GNU-stack as PROGBITS rather than NOTE.

While Ard provided a fix for arm64, I want to fix this globally because
the same issue is happening on riscv since commit 2348e6bf4421 ("riscv:
remove special treatment for the link order of head.o"). This problem
will happen in general for other architectures if they start to drop
unneeded entries from scripts/head-object-list.txt.

Discard .note.GNU-stack in include/asm-generic/vmlinux.lds.h.

Link: 
https://lore.kernel.org/lkml/CAABkxwuQoz1CTbyb57n0ZX65eSYiTonFCU8-LCQc=74D=xE=r...@mail.gmail.com/
Fixes: 994b7ac1697b ("arm64: remove special treatment for the link order of 
head.o")
Fixes: 2348e6bf4421 ("riscv: remove special treatment for the link order of 
head.o")
Reported-by: Dennis Gilmore 
Suggested-by: Ard Biesheuvel 
Signed-off-by: Masahiro Yamada 
Acked-by: Palmer Dabbelt 
Signed-off-by: Tom Saeger 
---
 include/asm-generic/vmlinux.lds.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 3dc5824141cd..7ad6f51b3d91 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -929,7 +929,12 @@
 #define PRINTK_INDEX
 #endif
 
+/*
+ * Discard .note.GNU-stack, which is emitted as PROGBITS by the compiler.
+ * Otherwise, the type of .notes section would become PROGBITS instead of 
NOTES.
+ */
 #define NOTES  \
+   /DISCARD/ : { *(.note.GNU-stack) }  \
.notes : AT(ADDR(.notes) - LOAD_OFFSET) {   \
__start_notes = .;  \
KEEP(*(.note.*))\

-- 
2.39.1



[PATCH 6.1 v2 1/7] riscv: remove special treatment for the link order of head.o

2023-02-10 Thread Tom Saeger
From: Jisheng Zhang 

commit 2348e6bf44213c5f447ff698e43c089185241ed7 upstream.

arch/riscv/kernel/head.o does not need any special treatment - the only
requirement is the ".head.text" section must be placed before the
normal ".text" section.

The linker script does the right thing to do. The build system does
not need to manipulate the link order of head.o.

Signed-off-by: Jisheng Zhang 
Link: https://lore.kernel.org/r/20221018141200.1040-1-jszh...@kernel.org
Signed-off-by: Palmer Dabbelt 
Signed-off-by: Tom Saeger 
---
 scripts/head-object-list.txt | 1 -
 1 file changed, 1 deletion(-)

diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt
index b16326a92c45..105ea7ac4751 100644
--- a/scripts/head-object-list.txt
+++ b/scripts/head-object-list.txt
@@ -39,7 +39,6 @@ arch/powerpc/kernel/entry_64.o
 arch/powerpc/kernel/fpu.o
 arch/powerpc/kernel/vector.o
 arch/powerpc/kernel/prom_init.o
-arch/riscv/kernel/head.o
 arch/s390/kernel/head64.o
 arch/sh/kernel/head_32.o
 arch/sparc/kernel/head_32.o

-- 
2.39.1



Re: [External] : [PATCH v3 1/1] PCI: layerscape: Add EP mode support for ls1028a

2023-02-10 Thread ALOK TIWARI


Reviewed-by: Alok Tiwari 


On 2/9/2023 8:40 PM, Frank Li wrote:

From: Xiaowei Bao

Add PCIe EP mode support for ls1028a.

Signed-off-by: Xiaowei Bao
Signed-off-by: Hou Zhiqiang
Signed-off-by: Frank Li 
Acked-by:  Roy Zang
---

Change from v2 to v3
order by .compatible

Change from v2 to v2
Added
Signed-off-by: Frank Li 
Acked-by:  Roy Zang


Reviewed-by: Alok Tiwari 




All other patches were already accepte by maintainer in
https://urldefense.com/v3/__https://lore.kernel.org/lkml/2022223457.10599-1-leoyang...@nxp.com/__;!!ACWV5N9M2RV99hQ!NR9EU4fPDwxdyrb9tdBm9VNIMHSlw6dLgXCAPDSrm7ftWVNrh6JldLGzzrKyiE0xRlP5OdiGBN7PCf9gRaA$  


But missed this one.

Re-post

  drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c 
b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index ad99707b3b99..c640db60edc6 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -110,6 +110,7 @@ static const struct ls_pcie_ep_drvdata lx2_ep_drvdata = {
  };
  
  static const struct of_device_id ls_pcie_ep_of_match[] = {

+   { .compatible = "fsl,ls1028a-pcie-ep", .data = _ep_drvdata },
{ .compatible = "fsl,ls1046a-pcie-ep", .data = _ep_drvdata },
{ .compatible = "fsl,ls1088a-pcie-ep", .data = _ep_drvdata },
{ .compatible = "fsl,ls2088a-pcie-ep", .data = _ep_drvdata },

[PATCH v4 15/15] spi: spi-zynqmp-gqspi: Add parallel memories support in GQSPI driver

2023-02-10 Thread Amit Kumar Mahapatra
During GQSPI driver probe set ctlr->multi-cs-cap for enabling multi CS
capability of the controller. In parallel mode the controller can either
split the data between both the flash or can send the same data to both the
flashes, this is determined by the STRIPE bit. While sending commands to
the flashes the GQSPI driver send the same command to both the flashes by
resetting the STRIPE bit, but while writing/reading data to & from the
flash the GQSPI driver splits the data evenly between both the flashes by
setting the STRIPE bit.

Signed-off-by: Amit Kumar Mahapatra 
---
 drivers/spi/spi-zynqmp-gqspi.c | 39 +-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index 4759f704bf5c..9e44371bfda2 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Generic QSPI register offsets */
 #define GQSPI_CONFIG_OFST  0x0100
@@ -192,6 +193,7 @@ struct qspi_platform_data {
  * @op_lock:   Operational lock
  * @speed_hz:  Current SPI bus clock speed in hz
  * @has_tapdelay:  Used for tapdelay register available in qspi
+ * @is_parallel:   Used for multi CS support
  */
 struct zynqmp_qspi {
struct spi_controller *ctlr;
@@ -214,8 +216,33 @@ struct zynqmp_qspi {
struct mutex op_lock;
u32 speed_hz;
bool has_tapdelay;
+   bool is_parallel;
 };
 
+/**
+ * zynqmp_gqspi_update_stripe - For GQSPI controller data stripe capabilities
+ * @op:Pointer to mem ops
+ * Return:  Status of the data stripe
+ *
+ * Returns true if data stripe need to be enabled, else returns false
+ */
+bool zynqmp_gqspi_update_stripe(const struct spi_mem_op *op)
+{
+   if (op->cmd.opcode ==  SPINOR_OP_BE_4K ||
+   op->cmd.opcode ==  SPINOR_OP_BE_32K ||
+   op->cmd.opcode ==  SPINOR_OP_CHIP_ERASE ||
+   op->cmd.opcode ==  SPINOR_OP_SE ||
+   op->cmd.opcode ==  SPINOR_OP_BE_32K_4B ||
+   op->cmd.opcode ==  SPINOR_OP_SE_4B ||
+   op->cmd.opcode == SPINOR_OP_BE_4K_4B ||
+   op->cmd.opcode ==  SPINOR_OP_WRSR ||
+   op->cmd.opcode ==  SPINOR_OP_BRWR ||
+   (op->cmd.opcode ==  SPINOR_OP_WRSR2 && !op->addr.nbytes))
+   return false;
+
+   return true;
+}
+
 /**
  * zynqmp_gqspi_read - For GQSPI controller read operation
  * @xqspi: Pointer to the zynqmp_qspi structure
@@ -470,7 +497,14 @@ static void zynqmp_qspi_chipselect(struct spi_device 
*qspi, bool is_high)
 
genfifoentry |= GQSPI_GENFIFO_MODE_SPI;
 
-   if (qspi->cs_index_mask & GQSPI_SELECT_UPPER_CS) {
+   if ((qspi->cs_index_mask & GQSPI_SELECT_LOWER_CS) &&
+   (qspi->cs_index_mask & GQSPI_SELECT_UPPER_CS)) {
+   zynqmp_gqspi_selectslave(xqspi,
+GQSPI_SELECT_FLASH_CS_BOTH,
+GQSPI_SELECT_FLASH_BUS_BOTH);
+   if (!xqspi->is_parallel)
+   xqspi->is_parallel = true;
+   } else if (qspi->cs_index_mask & GQSPI_SELECT_UPPER_CS) {
zynqmp_gqspi_selectslave(xqspi,
 GQSPI_SELECT_FLASH_CS_UPPER,
 GQSPI_SELECT_FLASH_BUS_LOWER);
@@ -1139,6 +1173,8 @@ static int zynqmp_qspi_exec_op(struct spi_mem *mem,
}
 
if (op->data.nbytes) {
+   if (xqspi->is_parallel && zynqmp_gqspi_update_stripe(op))
+   genfifoentry |= GQSPI_GENFIFO_STRIPE;
reinit_completion(>data_completion);
if (op->data.dir == SPI_MEM_DATA_OUT) {
xqspi->txbuf = (u8 *)op->data.buf.out;
@@ -1334,6 +1370,7 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
ctlr->dev.of_node = np;
ctlr->auto_runtime_pm = true;
+   ctlr->multi_cs_cap = true;
 
ret = devm_spi_register_controller(>dev, ctlr);
if (ret) {
-- 
2.25.1



[PATCH v4 14/15] mtd: spi-nor: Add parallel memories support in spi-nor

2023-02-10 Thread Amit Kumar Mahapatra
The current implementation assumes that a maximum of two flashes are
connected in parallel mode. The QSPI controller splits the data evenly
between both the flashes so, both the flashes that are connected in
parallel mode should be identical.
During each operation SPI-NOR sets 0th bit for CS0 & 1st bit for CS1 in
nor->spimem->spi->cs_index_mask. The QSPI driver will then assert/de-assert
CS0 & CS1.
Write operation in parallel mode are performed in page size * 2 chunks as
each write operation results in writing both the flashes. For doubling the
address space each operation is performed at addr/2 flash offset, where
addr is the address specified by the user.

Signed-off-by: Amit Kumar Mahapatra 
---
 drivers/mtd/spi-nor/core.c  | 514 +++-
 drivers/mtd/spi-nor/core.h  |   4 +
 drivers/mtd/spi-nor/micron-st.c |   5 +
 3 files changed, 384 insertions(+), 139 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index bb7326dc8b70..367cbb36ef69 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -464,17 +464,29 @@ int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
op.data.nbytes = 2;
}
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   op.data.nbytes = 2;
+
spi_nor_spimem_setup_op(nor, , nor->reg_proto);
 
ret = spi_mem_exec_op(nor->spimem, );
} else {
-   ret = spi_nor_controller_ops_read_reg(nor, SPINOR_OP_RDSR, sr,
- 1);
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   ret = spi_nor_controller_ops_read_reg(nor,
+ SPINOR_OP_RDSR,
+ sr, 2);
+   else
+   ret = spi_nor_controller_ops_read_reg(nor,
+ SPINOR_OP_RDSR,
+ sr, 1);
}
 
if (ret)
dev_dbg(nor->dev, "error %d reading SR\n", ret);
 
+   if (nor->flags & SNOR_F_HAS_PARALLEL)
+   sr[0] |= sr[1];
+
return ret;
 }
 
@@ -1466,12 +1478,122 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
if (ret)
return ret;
 
-   /* whole-chip erase? */
-   if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
-   unsigned long timeout;
+   if (!(nor->flags & SNOR_F_HAS_PARALLEL)) {
+   /* whole-chip erase? */
+   if (len == mtd->size && !(nor->flags & 
SNOR_F_NO_OP_CHIP_ERASE)) {
+   unsigned long timeout;
+
+   while ((cur_cs_num < SNOR_FLASH_CNT_MAX) && params) {
+   nor->spimem->spi->cs_index_mask = 1 << 
cur_cs_num;
+   ret = spi_nor_write_enable(nor);
+   if (ret)
+   goto erase_err;
+
+   ret = spi_nor_erase_chip(nor);
+   if (ret)
+   goto erase_err;
+
+   /*
+* Scale the timeout linearly with the size of 
the flash, with
+* a minimum calibrated to an old 2MB flash. We 
could try to
+* pull these from CFI/SFDP, but these values 
should be good
+* enough for now.
+*/
+   timeout = max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES,
+ CHIP_ERASE_2MB_READY_WAIT_JIFFIES 
*
+ (unsigned long)(params->size /
+ SZ_2M));
+   ret = spi_nor_wait_till_ready_with_timeout(nor, 
timeout);
+   if (ret)
+   goto erase_err;
+
+   cur_cs_num++;
+   params = spi_nor_get_params(nor, cur_cs_num);
+   }
+
+   /* REVISIT in some cases we could speed up erasing large regions
+* by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K.  We may 
have set up
+* to use "small sector erase", but that's not always optimal.
+*/
+
+   /* "sector"-at-a-time erase */
+   } else if (spi_nor_has_uniform_erase(nor)) {
+   /* Determine the flash from which the operation need to 
start */
+   while ((cur_cs_num < SNOR_FLASH_CNT_MAX) &&
+  (addr > sz - 1) && params) {
+ 

[PATCH v4 13/15] spi: spi-zynqmp-gqspi: Add stacked memories support in GQSPI driver

2023-02-10 Thread Amit Kumar Mahapatra
GQSPI supports two chip select CS0 & CS1. Update the driver to
assert/de-assert the appropriate chip select as per the bits set in
qspi->cs_index_mask.

Signed-off-by: Amit Kumar Mahapatra 
---
 drivers/spi/spi-zynqmp-gqspi.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index 319cdd5a0bdc..4759f704bf5c 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -156,6 +156,9 @@
 #define GQSPI_FREQ_100MHZ  1
 #define GQSPI_FREQ_150MHZ  15000
 
+#define GQSPI_SELECT_LOWER_CS  BIT(0)
+#define GQSPI_SELECT_UPPER_CS  BIT(1)
+
 #define SPI_AUTOSUSPEND_TIMEOUT3000
 enum mode_type {GQSPI_MODE_IO, GQSPI_MODE_DMA};
 
@@ -467,15 +470,17 @@ static void zynqmp_qspi_chipselect(struct spi_device 
*qspi, bool is_high)
 
genfifoentry |= GQSPI_GENFIFO_MODE_SPI;
 
+   if (qspi->cs_index_mask & GQSPI_SELECT_UPPER_CS) {
+   zynqmp_gqspi_selectslave(xqspi,
+GQSPI_SELECT_FLASH_CS_UPPER,
+GQSPI_SELECT_FLASH_BUS_LOWER);
+   } else if (qspi->cs_index_mask & GQSPI_SELECT_LOWER_CS) {
+   zynqmp_gqspi_selectslave(xqspi,
+GQSPI_SELECT_FLASH_CS_LOWER,
+GQSPI_SELECT_FLASH_BUS_LOWER);
+   }
+   genfifoentry |= xqspi->genfifobus;
if (!is_high) {
-   if (!spi_get_chipselect(qspi, 0)) {
-   xqspi->genfifobus = GQSPI_GENFIFO_BUS_LOWER;
-   xqspi->genfifocs = GQSPI_GENFIFO_CS_LOWER;
-   } else {
-   xqspi->genfifobus = GQSPI_GENFIFO_BUS_UPPER;
-   xqspi->genfifocs = GQSPI_GENFIFO_CS_UPPER;
-   }
-   genfifoentry |= xqspi->genfifobus;
genfifoentry |= xqspi->genfifocs;
genfifoentry |= GQSPI_GENFIFO_CS_SETUP;
} else {
-- 
2.25.1



[PATCH v4 12/15] mtd: spi-nor: Add stacked memories support in spi-nor

2023-02-10 Thread Amit Kumar Mahapatra
Each flash that is connected in stacked mode should have a separate
parameter structure. So, the flash parameter member(*params) of the spi_nor
structure is changed to an array (*params[2]). The array is used to store
the parameters of each flash connected in stacked configuration.

The current implementation assumes that a maximum of two flashes are
connected in stacked mode and both the flashes are of same make but can
differ in sizes. So, except the sizes all other flash parameters of both
the flashes are identical.

SPI-NOR is not aware of the chip_select values, for any incoming request
SPI-NOR will decide the flash index with the help of individual flash size
and the configuration type (single/stacked). SPI-NOR will pass on the flash
index information to the SPI core & SPI driver by setting the appropriate
bit in nor->spimem->spi->cs_index_mask. For example, if nth bit of
nor->spimem->spi->cs_index_mask is set then the driver would
assert/de-assert spi->chip_slect[n].

Signed-off-by: Amit Kumar Mahapatra 
---
 drivers/mtd/spi-nor/core.c  | 282 +---
 drivers/mtd/spi-nor/core.h  |   4 +
 include/linux/mtd/spi-nor.h |  12 +-
 3 files changed, 244 insertions(+), 54 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 8a4a54bf2d0e..bb7326dc8b70 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1441,13 +1441,18 @@ static int spi_nor_erase_multi_sectors(struct spi_nor 
*nor, u64 addr, u32 len)
 static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
struct spi_nor *nor = mtd_to_spi_nor(mtd);
-   u32 addr, len;
+   struct spi_nor_flash_parameter *params;
+   u32 addr, len, offset, cur_cs_num = 0;
uint32_t rem;
int ret;
+   u64 sz;
 
dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
(long long)instr->len);
 
+   params = spi_nor_get_params(nor, 0);
+   sz = params->size;
+
if (spi_nor_has_uniform_erase(nor)) {
div_u64_rem(instr->len, mtd->erasesize, );
if (rem)
@@ -1465,26 +1470,30 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
unsigned long timeout;
 
-   ret = spi_nor_write_enable(nor);
-   if (ret)
-   goto erase_err;
+   while (cur_cs_num < SNOR_FLASH_CNT_MAX && params) {
+   nor->spimem->spi->cs_index_mask = 0x01 << cur_cs_num;
+   ret = spi_nor_write_enable(nor);
+   if (ret)
+   goto erase_err;
 
-   ret = spi_nor_erase_chip(nor);
-   if (ret)
-   goto erase_err;
+   ret = spi_nor_erase_chip(nor);
+   if (ret)
+   goto erase_err;
 
-   /*
-* Scale the timeout linearly with the size of the flash, with
-* a minimum calibrated to an old 2MB flash. We could try to
-* pull these from CFI/SFDP, but these values should be good
-* enough for now.
-*/
-   timeout = max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES,
- CHIP_ERASE_2MB_READY_WAIT_JIFFIES *
- (unsigned long)(mtd->size / SZ_2M));
-   ret = spi_nor_wait_till_ready_with_timeout(nor, timeout);
-   if (ret)
-   goto erase_err;
+   /*
+* Scale the timeout linearly with the size of the 
flash, with
+* a minimum calibrated to an old 2MB flash. We could 
try to
+* pull these from CFI/SFDP, but these values should be 
good
+* enough for now.
+*/
+   timeout = max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES,
+ CHIP_ERASE_2MB_READY_WAIT_JIFFIES *
+ (unsigned long)(params->size / SZ_2M));
+   ret = spi_nor_wait_till_ready_with_timeout(nor, 
timeout);
+   if (ret)
+   goto erase_err;
+   cur_cs_num++;
+   }
 
/* REVISIT in some cases we could speed up erasing large regions
 * by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K.  We may have set up
@@ -1493,12 +1502,26 @@ static int spi_nor_erase(struct mtd_info *mtd, struct 
erase_info *instr)
 
/* "sector"-at-a-time erase */
} else if (spi_nor_has_uniform_erase(nor)) {
+   /* Determine the flash from which the operation need to start */
+   while ((cur_cs_num < SNOR_FLASH_CNT_MAX) && (addr > sz - 1) && 
params) {
+   

[PATCH v4 11/15] mtd: spi-nor: Add APIs to set/get nor->params

2023-02-10 Thread Amit Kumar Mahapatra
Supporting multi-cs in spi-nor would require the *params member of
struct spi_nor to be an array. To make the transition smoother introduced
spi_nor_get_params() & spi_nor_set_params() APIs to get & set nor->params,
added a new local variable (struct spi_nor_flash_parameter *params) to hold
the return value of the spi_nor_get_params() function call and replaced all
nor->params references with the "params".
While adding multi-cs support in further patches the *params member of the
spi_nor structure would be converted to arrays & the "idx" parameter of
the APIs would be used as array index i.e., nor->params[idx].

Signed-off-by: Amit Kumar Mahapatra 
---
 drivers/mtd/spi-nor/atmel.c  |  17 ++--
 drivers/mtd/spi-nor/core.c   | 129 ---
 drivers/mtd/spi-nor/debugfs.c|   4 +-
 drivers/mtd/spi-nor/gigadevice.c |   4 +-
 drivers/mtd/spi-nor/issi.c   |  11 ++-
 drivers/mtd/spi-nor/macronix.c   |   6 +-
 drivers/mtd/spi-nor/micron-st.c  |  34 +---
 drivers/mtd/spi-nor/otp.c|  29 ---
 drivers/mtd/spi-nor/sfdp.c   |  29 ---
 drivers/mtd/spi-nor/spansion.c   |  50 +++-
 drivers/mtd/spi-nor/sst.c|   7 +-
 drivers/mtd/spi-nor/swp.c|  22 --
 drivers/mtd/spi-nor/winbond.c|  10 ++-
 drivers/mtd/spi-nor/xilinx.c |  18 +++--
 include/linux/mtd/spi-nor.h  |  10 +++
 15 files changed, 254 insertions(+), 126 deletions(-)

diff --git a/drivers/mtd/spi-nor/atmel.c b/drivers/mtd/spi-nor/atmel.c
index 656dd80a0be7..57ca9f5ee205 100644
--- a/drivers/mtd/spi-nor/atmel.c
+++ b/drivers/mtd/spi-nor/atmel.c
@@ -23,10 +23,11 @@ static int at25fs_nor_lock(struct spi_nor *nor, loff_t ofs, 
uint64_t len)
 
 static int at25fs_nor_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
+   struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
int ret;
 
/* We only support unlocking the whole flash array */
-   if (ofs || len != nor->params->size)
+   if (ofs || len != params->size)
return -EINVAL;
 
/* Write 0x00 to the status register to disable write protection */
@@ -50,7 +51,9 @@ static const struct spi_nor_locking_ops 
at25fs_nor_locking_ops = {
 
 static void at25fs_nor_late_init(struct spi_nor *nor)
 {
-   nor->params->locking_ops = _nor_locking_ops;
+   struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
+
+   params->locking_ops = _nor_locking_ops;
 }
 
 static const struct spi_nor_fixups at25fs_nor_fixups = {
@@ -69,11 +72,12 @@ static const struct spi_nor_fixups at25fs_nor_fixups = {
 static int atmel_nor_set_global_protection(struct spi_nor *nor, loff_t ofs,
   uint64_t len, bool is_protect)
 {
+   struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
int ret;
u8 sr;
 
/* We only support locking the whole flash array */
-   if (ofs || len != nor->params->size)
+   if (ofs || len != params->size)
return -EINVAL;
 
ret = spi_nor_read_sr(nor, nor->bouncebuf);
@@ -131,9 +135,10 @@ static int atmel_nor_global_unprotect(struct spi_nor *nor, 
loff_t ofs,
 static int atmel_nor_is_global_protected(struct spi_nor *nor, loff_t ofs,
 uint64_t len)
 {
+   struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
int ret;
 
-   if (ofs >= nor->params->size || (ofs + len) > nor->params->size)
+   if (ofs >= params->size || (ofs + len) > params->size)
return -EINVAL;
 
ret = spi_nor_read_sr(nor, nor->bouncebuf);
@@ -151,7 +156,9 @@ static const struct spi_nor_locking_ops 
atmel_nor_global_protection_ops = {
 
 static void atmel_nor_global_protection_late_init(struct spi_nor *nor)
 {
-   nor->params->locking_ops = _nor_global_protection_ops;
+   struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
+
+   params->locking_ops = _nor_global_protection_ops;
 }
 
 static const struct spi_nor_fixups atmel_nor_global_protection_fixups = {
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index d8703d7dfd0a..8a4a54bf2d0e 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -448,14 +448,15 @@ int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 
ndummy, u8 *id,
  */
 int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
 {
+   struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
int ret;
 
if (nor->spimem) {
struct spi_mem_op op = SPI_NOR_RDSR_OP(sr);
 
if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
-   op.addr.nbytes = nor->params->rdsr_addr_nbytes;
-   op.dummy.nbytes = nor->params->rdsr_dummy;
+   op.addr.nbytes = params->rdsr_addr_nbytes;
+   op.dummy.nbytes = params->rdsr_dummy;
/*
 * We 

[PATCH v4 10/15] mtd: spi-nor: Convert macros with inline functions

2023-02-10 Thread Amit Kumar Mahapatra
In further patches the nor->params references in
spi_nor_otp_region_len(nor) & spi_nor_otp_n_regions(nor) macros will be
replaced with spi_nor_get_params() API. To make the transition smoother,
first converting the macros into static inline functions.

Suggested-by: Michal Simek 
Signed-off-by: Amit Kumar Mahapatra 
---
 drivers/mtd/spi-nor/otp.c | 23 +--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/otp.c b/drivers/mtd/spi-nor/otp.c
index 00ab0d2d6d2f..3d75899de303 100644
--- a/drivers/mtd/spi-nor/otp.c
+++ b/drivers/mtd/spi-nor/otp.c
@@ -11,8 +11,27 @@
 
 #include "core.h"
 
-#define spi_nor_otp_region_len(nor) ((nor)->params->otp.org->len)
-#define spi_nor_otp_n_regions(nor) ((nor)->params->otp.org->n_regions)
+/**
+ * spi_nor_otp_region_len() - get size of one OTP region in bytes
+ * @nor:pointer to 'struct spi_nor'
+ *
+ * Return: size of one OTP region in bytes
+ */
+static inline unsigned int spi_nor_otp_region_len(struct spi_nor *nor)
+{
+   return nor->params->otp.org->len;
+}
+
+/**
+ * spi_nor_otp_n_regions() - get number of individual OTP regions
+ * @nor:pointer to 'struct spi_nor'
+ *
+ * Return: number of individual OTP regions
+ */
+static inline unsigned int spi_nor_otp_n_regions(struct spi_nor *nor)
+{
+   return nor->params->otp.org->n_regions;
+}
 
 /**
  * spi_nor_otp_read_secr() - read security register
-- 
2.25.1



[PATCH v4 09/15] spi: Add stacked and parallel memories support in SPI core

2023-02-10 Thread Amit Kumar Mahapatra
For supporting multiple CS the SPI device need to be aware of all the CS
values. So, the "chip_select" member in the spi_device structure is now an
array that holds all the CS values.

spi_device structure now has a "cs_index_mask" member. This acts as an
index to the chip_select array. If nth bit of spi->cs_index_mask is set
then the driver would assert spi->chip_select[n].

In parallel mode all the chip selects are asserted/de-asserted
simultaneously and each byte of data is stored in both devices, the even
bits in one, the odd bits in the other. The split is automatically handled
by the GQSPI controller. The GQSPI controller supports a maximum of two
flashes connected in parallel mode. A "multi-cs-cap" flag is added in the
spi controntroller data, through ctlr->multi-cs-cap the spi core will make
sure that the controller is capable of handling multiple chip selects at
once.

For supporting multiple CS via GPIO the cs_gpiod member of the spi_device
structure is now an array that holds the gpio descriptor for each
chipselect.

Multi CS support using GPIO is not tested due to unavailability of
necessary hardware setup.

Signed-off-by: Amit Kumar Mahapatra 
---
 drivers/spi/spi.c   | 213 +++-
 include/linux/spi/spi.h |  34 +--
 2 files changed, 173 insertions(+), 74 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 21a8c3a8eee4..7a9dbe1e0cab 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -613,7 +613,8 @@ static int spi_dev_check(struct device *dev, void *data)
struct spi_device *new_spi = data;
 
if (spi->controller == new_spi->controller &&
-   spi_get_chipselect(spi, 0) == spi_get_chipselect(new_spi, 0))
+   spi_get_chipselect(spi, 0) == spi_get_chipselect(new_spi, 0) &&
+   spi_get_chipselect(spi, 1) == spi_get_chipselect(new_spi, 1))
return -EBUSY;
return 0;
 }
@@ -628,7 +629,7 @@ static int __spi_add_device(struct spi_device *spi)
 {
struct spi_controller *ctlr = spi->controller;
struct device *dev = ctlr->dev.parent;
-   int status;
+   int status, idx;
 
/*
 * We need to make sure there's no other device with this
@@ -637,8 +638,7 @@ static int __spi_add_device(struct spi_device *spi)
 */
status = bus_for_each_dev(_bus_type, NULL, spi, spi_dev_check);
if (status) {
-   dev_err(dev, "chipselect %d already in use\n",
-   spi_get_chipselect(spi, 0));
+   dev_err(dev, "chipselect %d already in use\n", 
spi_get_chipselect(spi, 0));
return status;
}
 
@@ -648,8 +648,10 @@ static int __spi_add_device(struct spi_device *spi)
return -ENODEV;
}
 
-   if (ctlr->cs_gpiods)
-   spi_set_csgpiod(spi, 0, ctlr->cs_gpiods[spi_get_chipselect(spi, 
0)]);
+   if (ctlr->cs_gpiods) {
+   for (idx = 0; idx < SPI_CS_CNT_MAX; idx++)
+   spi_set_csgpiod(spi, idx, 
ctlr->cs_gpiods[spi_get_chipselect(spi, idx)]);
+   }
 
/*
 * Drivers may modify this initial i/o setup, but will
@@ -689,13 +691,15 @@ int spi_add_device(struct spi_device *spi)
 {
struct spi_controller *ctlr = spi->controller;
struct device *dev = ctlr->dev.parent;
-   int status;
+   int status, idx;
 
-   /* Chipselects are numbered 0..max; validate. */
-   if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) {
-   dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0),
-   ctlr->num_chipselect);
-   return -EINVAL;
+   for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
+   /* Chipselects are numbered 0..max; validate. */
+   if (spi_get_chipselect(spi, idx) >= ctlr->num_chipselect) {
+   dev_err(dev, "cs%d >= max %d\n", 
spi_get_chipselect(spi, idx),
+   ctlr->num_chipselect);
+   return -EINVAL;
+   }
}
 
/* Set the bus ID string */
@@ -712,12 +716,15 @@ static int spi_add_device_locked(struct spi_device *spi)
 {
struct spi_controller *ctlr = spi->controller;
struct device *dev = ctlr->dev.parent;
+   int idx;
 
-   /* Chipselects are numbered 0..max; validate. */
-   if (spi_get_chipselect(spi, 0) >= ctlr->num_chipselect) {
-   dev_err(dev, "cs%d >= max %d\n", spi_get_chipselect(spi, 0),
-   ctlr->num_chipselect);
-   return -EINVAL;
+   for (idx = 0; idx < SPI_CS_CNT_MAX; idx++) {
+   /* Chipselects are numbered 0..max; validate. */
+   if (spi_get_chipselect(spi, idx) >= ctlr->num_chipselect) {
+   dev_err(dev, "cs%d >= max %d\n", 
spi_get_chipselect(spi, idx),
+   ctlr->num_chipselect);
+   return -EINVAL;
+   }
 

[PATCH v4 08/15] ALSA: hda: cs35l41: Replace all spi->chip_select references with function call

2023-02-10 Thread Amit Kumar Mahapatra
Supporting multi-cs in spi drivers would require the chip_select & cs_gpiod
members of struct spi_device to be an array. But changing the type of these
members to array would break the spi driver functionality. To make the
transition smoother introduced four new APIs to get/set the
spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and
spi->cs_gpiod references with get or set API calls.
While adding multi-cs support in further patches the chip_select & cs_gpiod
members of the spi_device structure would be converted to arrays & the
"idx" parameter of the APIs would be used as array index i.e.,
spi->chip_select[idx] & spi->cs_gpiod[idx] respectively.

Signed-off-by: Amit Kumar Mahapatra 
---
 sound/pci/hda/cs35l41_hda_spi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c
index 71979cfb4d7e..eb287aa5f782 100644
--- a/sound/pci/hda/cs35l41_hda_spi.c
+++ b/sound/pci/hda/cs35l41_hda_spi.c
@@ -25,7 +25,7 @@ static int cs35l41_hda_spi_probe(struct spi_device *spi)
else
return -ENODEV;
 
-   return cs35l41_hda_probe(>dev, device_name, spi->chip_select, 
spi->irq,
+   return cs35l41_hda_probe(>dev, device_name, 
spi_get_chipselect(spi, 0), spi->irq,
 devm_regmap_init_spi(spi, 
_regmap_spi));
 }
 
-- 
2.25.1



[PATCH v4 07/15] powerpc/83xx/mpc832x_rdb: Replace all spi->chip_select references with function call

2023-02-10 Thread Amit Kumar Mahapatra
Supporting multi-cs in spi drivers would require the chip_select & cs_gpiod
members of struct spi_device to be an array. But changing the type of these
members to array would break the spi driver functionality. To make the
transition smoother introduced four new APIs to get/set the
spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and
spi->cs_gpiod references with get or set API calls.
While adding multi-cs support in further patches the chip_select & cs_gpiod
members of the spi_device structure would be converted to arrays & the
"idx" parameter of the APIs would be used as array index i.e.,
spi->chip_select[idx] & spi->cs_gpiod[idx] respectively.

Signed-off-by: Amit Kumar Mahapatra 
---
 arch/powerpc/platforms/83xx/mpc832x_rdb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c 
b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index caa96edf0e72..4ab1d48cd229 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -144,7 +144,7 @@ static int __init fsl_spi_init(struct spi_board_info 
*board_infos,
 
 static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
 {
-   pr_debug("%s %d %d\n", __func__, spi->chip_select, on);
+   pr_debug("%s %d %d\n", __func__, spi_get_chipselect(spi, 0), on);
par_io_data_set(3, 13, on);
 }
 
-- 
2.25.1



[PATCH v4 06/15] platform/x86: serial-multi-instantiate: Replace all spi->chip_select and spi->cs_gpiod references with function call

2023-02-10 Thread Amit Kumar Mahapatra
Supporting multi-cs in spi drivers would require the chip_select & cs_gpiod
members of struct spi_device to be an array. But changing the type of these
members to array would break the spi driver functionality. To make the
transition smoother introduced four new APIs to get/set the
spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and
spi->cs_gpiod references with get or set API calls.
While adding multi-cs support in further patches the chip_select & cs_gpiod
members of the spi_device structure would be converted to arrays & the
"idx" parameter of the APIs would be used as array index i.e.,
spi->chip_select[idx] & spi->cs_gpiod[idx] respectively.

Signed-off-by: Amit Kumar Mahapatra 
Reviewed-by: Michal Simek 
---
 drivers/platform/x86/serial-multi-instantiate.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/serial-multi-instantiate.c 
b/drivers/platform/x86/serial-multi-instantiate.c
index 5362f1a7b77c..270a4700d25d 100644
--- a/drivers/platform/x86/serial-multi-instantiate.c
+++ b/drivers/platform/x86/serial-multi-instantiate.c
@@ -139,7 +139,8 @@ static int smi_spi_probe(struct platform_device *pdev, 
struct smi *smi,
goto error;
}
 
-   dev_dbg(dev, "SPI device %s using chip select %u", name, 
spi_dev->chip_select);
+   dev_dbg(dev, "SPI device %s using chip select %u", name,
+   spi_get_chipselect(spi_dev, 0));
 
smi->spi_devs[i] = spi_dev;
smi->spi_num++;
-- 
2.25.1



[PATCH v4 05/15] staging: Replace all spi->chip_select and spi->cs_gpiod references with function call

2023-02-10 Thread Amit Kumar Mahapatra
Supporting multi-cs in spi drivers would require the chip_select & cs_gpiod
members of struct spi_device to be an array. But changing the type of these
members to array would break the spi driver functionality. To make the
transition smoother introduced four new APIs to get/set the
spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and
spi->cs_gpiod references with get or set API calls.
While adding multi-cs support in further patches the chip_select & cs_gpiod
members of the spi_device structure would be converted to arrays & the
"idx" parameter of the APIs would be used as array index i.e.,
spi->chip_select[idx] & spi->cs_gpiod[idx] respectively.

Signed-off-by: Amit Kumar Mahapatra 
Reviewed-by: Greg Kroah-Hartman 
Reviewed-by: Michal Simek 
---
 drivers/staging/fbtft/fbtft-core.c | 2 +-
 drivers/staging/greybus/spilib.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fbtft/fbtft-core.c 
b/drivers/staging/fbtft/fbtft-core.c
index afaba94d1d1c..3a4abf3bae40 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -840,7 +840,7 @@ int fbtft_register_framebuffer(struct fb_info *fb_info)
sprintf(text1, ", %zu KiB buffer memory", par->txbuf.len >> 10);
if (spi)
sprintf(text2, ", spi%d.%d at %d MHz", spi->master->bus_num,
-   spi->chip_select, spi->max_speed_hz / 100);
+   spi_get_chipselect(spi, 0), spi->max_speed_hz / 
100);
dev_info(fb_info->dev,
 "%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n",
 fb_info->fix.id, fb_info->var.xres, fb_info->var.yres,
diff --git a/drivers/staging/greybus/spilib.c b/drivers/staging/greybus/spilib.c
index ad0700a0bb81..efb3bec58e15 100644
--- a/drivers/staging/greybus/spilib.c
+++ b/drivers/staging/greybus/spilib.c
@@ -237,7 +237,7 @@ static struct gb_operation *gb_spi_operation_create(struct 
gb_spilib *spi,
request = operation->request->payload;
request->count = cpu_to_le16(count);
request->mode = dev->mode;
-   request->chip_select = dev->chip_select;
+   request->chip_select = spi_get_chipselect(dev, 0);
 
gb_xfer = >transfers[0];
tx_data = gb_xfer + count;  /* place tx data after last gb_xfer */
-- 
2.25.1



[PATCH v4 04/15] mtd: devices: Replace all spi->chip_select and spi->cs_gpiod references with function call

2023-02-10 Thread Amit Kumar Mahapatra
Supporting multi-cs in spi drivers would require the chip_select & cs_gpiod
members of struct spi_device to be an array. But changing the type of these
members to array would break the spi driver functionality. To make the
transition smoother introduced four new APIs to get/set the
spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and
spi->cs_gpiod references with get or set API calls.
While adding multi-cs support in further patches the chip_select & cs_gpiod
members of the spi_device structure would be converted to arrays & the
"idx" parameter of the APIs would be used as array index i.e.,
spi->chip_select[idx] & spi->cs_gpiod[idx] respectively.

Signed-off-by: Amit Kumar Mahapatra 
Reviewed-by: Michal Simek 
---
 drivers/mtd/devices/mtd_dataflash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/devices/mtd_dataflash.c 
b/drivers/mtd/devices/mtd_dataflash.c
index 25bad4318305..34d7a0c4807b 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -646,7 +646,7 @@ static int add_dataflash_otp(struct spi_device *spi, char 
*name, int nr_pages,
 
/* name must be usable with cmdlinepart */
sprintf(priv->name, "spi%d.%d-%s",
-   spi->master->bus_num, spi->chip_select,
+   spi->master->bus_num, spi_get_chipselect(spi, 0),
name);
 
device = >mtd;
-- 
2.25.1



[PATCH v4 03/15] iio: imu: Replace all spi->chip_select and spi->cs_gpiod references with function call

2023-02-10 Thread Amit Kumar Mahapatra
Supporting multi-cs in spi drivers would require the chip_select & cs_gpiod
members of struct spi_device to be an array. But changing the type of these
members to array would break the spi driver functionality. To make the
transition smoother introduced four new APIs to get/set the
spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and
spi->cs_gpiod references with get or set API calls.
While adding multi-cs support in further patches the chip_select & cs_gpiod
members of the spi_device structure would be converted to arrays & the
"idx" parameter of the APIs would be used as array index i.e.,
spi->chip_select[idx] & spi->cs_gpiod[idx] respectively.

Signed-off-by: Amit Kumar Mahapatra 
Acked-by: Jonathan Cameron 
Reviewed-by: Michal Simek 
---
 drivers/iio/imu/adis16400.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c
index c02fc35dceb4..3eda32e12a53 100644
--- a/drivers/iio/imu/adis16400.c
+++ b/drivers/iio/imu/adis16400.c
@@ -466,7 +466,7 @@ static int adis16400_initial_setup(struct iio_dev 
*indio_dev)
 
dev_info(_dev->dev, "%s: prod_id 0x%04x at CS%d (irq 
%d)\n",
indio_dev->name, prod_id,
-   st->adis.spi->chip_select, st->adis.spi->irq);
+   spi_get_chipselect(st->adis.spi, 0), st->adis.spi->irq);
}
/* use high spi speed if possible */
if (st->variant->flags & ADIS16400_HAS_SLOW_MODE) {
-- 
2.25.1



[PATCH v4 02/15] net: Replace all spi->chip_select and spi->cs_gpiod references with function call

2023-02-10 Thread Amit Kumar Mahapatra
Supporting multi-cs in spi drivers would require the chip_select & cs_gpiod
members of struct spi_device to be an array. But changing the type of these
members to array would break the spi driver functionality. To make the
transition smoother introduced four new APIs to get/set the
spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and
spi->cs_gpiod references with get or set API calls.
While adding multi-cs support in further patches the chip_select & cs_gpiod
members of the spi_device structure would be converted to arrays & the
"idx" parameter of the APIs would be used as array index i.e.,
spi->chip_select[idx] & spi->cs_gpiod[idx] respectively.

Signed-off-by: Amit Kumar Mahapatra 
Reviewed-by: Michal Simek 
---
 drivers/net/ethernet/adi/adin1110.c| 2 +-
 drivers/net/ethernet/asix/ax88796c_main.c  | 2 +-
 drivers/net/ethernet/davicom/dm9051.c  | 2 +-
 drivers/net/ethernet/qualcomm/qca_debug.c  | 2 +-
 drivers/net/ieee802154/ca8210.c| 2 +-
 drivers/net/wan/slic_ds26522.c | 2 +-
 drivers/net/wireless/marvell/libertas/if_spi.c | 2 +-
 drivers/net/wireless/silabs/wfx/bus_spi.c  | 2 +-
 drivers/net/wireless/st/cw1200/cw1200_spi.c| 2 +-
 9 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/adi/adin1110.c 
b/drivers/net/ethernet/adi/adin1110.c
index 0805f249fff2..aee7a98725ba 100644
--- a/drivers/net/ethernet/adi/adin1110.c
+++ b/drivers/net/ethernet/adi/adin1110.c
@@ -515,7 +515,7 @@ static int adin1110_register_mdiobus(struct adin1110_priv 
*priv,
return -ENOMEM;
 
snprintf(priv->mii_bus_name, MII_BUS_ID_SIZE, "%s-%u",
-priv->cfg->name, priv->spidev->chip_select);
+priv->cfg->name, spi_get_chipselect(priv->spidev, 0));
 
mii_bus->name = priv->mii_bus_name;
mii_bus->read = adin1110_mdio_read;
diff --git a/drivers/net/ethernet/asix/ax88796c_main.c 
b/drivers/net/ethernet/asix/ax88796c_main.c
index 21376c79f671..e551ffaed20d 100644
--- a/drivers/net/ethernet/asix/ax88796c_main.c
+++ b/drivers/net/ethernet/asix/ax88796c_main.c
@@ -1006,7 +1006,7 @@ static int ax88796c_probe(struct spi_device *spi)
ax_local->mdiobus->parent = >dev;
 
snprintf(ax_local->mdiobus->id, MII_BUS_ID_SIZE,
-"ax88796c-%s.%u", dev_name(>dev), spi->chip_select);
+"ax88796c-%s.%u", dev_name(>dev), spi_get_chipselect(spi, 
0));
 
ret = devm_mdiobus_register(>dev, ax_local->mdiobus);
if (ret < 0) {
diff --git a/drivers/net/ethernet/davicom/dm9051.c 
b/drivers/net/ethernet/davicom/dm9051.c
index de7105a84747..70728b2e5f18 100644
--- a/drivers/net/ethernet/davicom/dm9051.c
+++ b/drivers/net/ethernet/davicom/dm9051.c
@@ -1123,7 +1123,7 @@ static int dm9051_mdio_register(struct board_info *db)
db->mdiobus->phy_mask = (u32)~BIT(1);
db->mdiobus->parent = >dev;
snprintf(db->mdiobus->id, MII_BUS_ID_SIZE,
-"dm9051-%s.%u", dev_name(>dev), spi->chip_select);
+"dm9051-%s.%u", dev_name(>dev), spi_get_chipselect(spi, 
0));
 
ret = devm_mdiobus_register(>dev, db->mdiobus);
if (ret)
diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c 
b/drivers/net/ethernet/qualcomm/qca_debug.c
index f62c39544e08..6f2fa2a42770 100644
--- a/drivers/net/ethernet/qualcomm/qca_debug.c
+++ b/drivers/net/ethernet/qualcomm/qca_debug.c
@@ -119,7 +119,7 @@ qcaspi_info_show(struct seq_file *s, void *what)
seq_printf(s, "SPI mode : %x\n",
   qca->spi_dev->mode);
seq_printf(s, "SPI chip select  : %u\n",
-  (unsigned int)qca->spi_dev->chip_select);
+  (unsigned int)spi_get_chipselect(qca->spi_dev, 0));
seq_printf(s, "SPI legacy mode  : %u\n",
   (unsigned int)qca->legacy_mode);
seq_printf(s, "SPI burst length : %u\n",
diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c
index e1a569b99e4a..7093a07141bb 100644
--- a/drivers/net/ieee802154/ca8210.c
+++ b/drivers/net/ieee802154/ca8210.c
@@ -2967,7 +2967,7 @@ static int ca8210_test_interface_init(struct ca8210_priv 
*priv)
sizeof(node_name),
"ca8210@%d_%d",
priv->spi->master->bus_num,
-   priv->spi->chip_select
+   spi_get_chipselect(priv->spi, 0)
);
 
test->ca8210_dfs_spi_int = debugfs_create_file(
diff --git a/drivers/net/wan/slic_ds26522.c b/drivers/net/wan/slic_ds26522.c
index 6063552cea9b..8a51cfcff99e 100644
--- a/drivers/net/wan/slic_ds26522.c
+++ b/drivers/net/wan/slic_ds26522.c
@@ -211,7 +211,7 @@ static int slic_ds26522_probe(struct spi_device *spi)
 
ret = slic_ds26522_init_configure(spi);
if (ret == 0)
-   pr_info("DS26522 cs%d configured\n", spi->chip_select);
+   pr_info("DS26522 cs%d configured\n", spi_get_chipselect(spi, 
0));
 
return ret;
 }

[PATCH v4 01/15] spi: Replace all spi->chip_select and spi->cs_gpiod references with function call

2023-02-10 Thread Amit Kumar Mahapatra
Supporting multi-cs in spi drivers would require the chip_select & cs_gpiod
members of struct spi_device to be an array. But changing the type of these
members to array would break the spi driver functionality. To make the
transition smoother introduced four new APIs to get/set the
spi->chip_select & spi->cs_gpiod and replaced all spi->chip_select and
spi->cs_gpiod references with get or set API calls.
While adding multi-cs support in further patches the chip_select & cs_gpiod
members of the spi_device structure would be converted to arrays & the
"idx" parameter of the APIs would be used as array index i.e.,
spi->chip_select[idx] & spi->cs_gpiod[idx] respectively.

Signed-off-by: Amit Kumar Mahapatra 
Acked-by: Heiko Stuebner  # Rockchip drivers
Reviewed-by: Michal Simek 
Reviewed-by: Cédric Le Goater  # Aspeed driver
Reviewed-by: Dhruva Gole  # SPI Cadence QSPI
Reviewed-by: Patrice Chotard  # spi-stm32-qspi
Acked-by: William Zhang  # bcm63xx-hsspi driver
Reviewed-by: Serge Semin  # DW SSI part
---
 drivers/spi/spi-altera-core.c |  2 +-
 drivers/spi/spi-amd.c |  4 ++--
 drivers/spi/spi-ar934x.c  |  2 +-
 drivers/spi/spi-armada-3700.c |  4 ++--
 drivers/spi/spi-aspeed-smc.c  | 13 +++--
 drivers/spi/spi-at91-usart.c  |  2 +-
 drivers/spi/spi-ath79.c   |  4 ++--
 drivers/spi/spi-atmel.c   | 26 +-
 drivers/spi/spi-au1550.c  |  4 ++--
 drivers/spi/spi-axi-spi-engine.c  |  2 +-
 drivers/spi/spi-bcm-qspi.c| 10 +-
 drivers/spi/spi-bcm2835.c | 19 ++-
 drivers/spi/spi-bcm2835aux.c  |  4 ++--
 drivers/spi/spi-bcm63xx-hsspi.c   | 22 +++---
 drivers/spi/spi-bcm63xx.c |  2 +-
 drivers/spi/spi-cadence-quadspi.c |  5 +++--
 drivers/spi/spi-cadence-xspi.c|  4 ++--
 drivers/spi/spi-cadence.c |  4 ++--
 drivers/spi/spi-cavium.c  |  8 
 drivers/spi/spi-coldfire-qspi.c   |  8 
 drivers/spi/spi-davinci.c | 18 +-
 drivers/spi/spi-dln2.c|  6 +++---
 drivers/spi/spi-dw-core.c |  2 +-
 drivers/spi/spi-dw-mmio.c |  4 ++--
 drivers/spi/spi-falcon.c  |  2 +-
 drivers/spi/spi-fsi.c |  2 +-
 drivers/spi/spi-fsl-dspi.c| 16 
 drivers/spi/spi-fsl-espi.c|  6 +++---
 drivers/spi/spi-fsl-lpspi.c   |  2 +-
 drivers/spi/spi-fsl-qspi.c|  6 +++---
 drivers/spi/spi-fsl-spi.c |  2 +-
 drivers/spi/spi-geni-qcom.c   |  6 +++---
 drivers/spi/spi-gpio.c|  4 ++--
 drivers/spi/spi-gxp.c |  4 ++--
 drivers/spi/spi-hisi-sfc-v3xx.c   |  2 +-
 drivers/spi/spi-img-spfi.c| 14 +++---
 drivers/spi/spi-imx.c | 30 +++---
 drivers/spi/spi-ingenic.c |  4 ++--
 drivers/spi/spi-intel.c   |  2 +-
 drivers/spi/spi-jcore.c   |  4 ++--
 drivers/spi/spi-lantiq-ssc.c  |  6 +++---
 drivers/spi/spi-mem.c |  4 ++--
 drivers/spi/spi-meson-spicc.c |  2 +-
 drivers/spi/spi-microchip-core.c  |  6 +++---
 drivers/spi/spi-mpc512x-psc.c |  8 
 drivers/spi/spi-mpc52xx.c |  2 +-
 drivers/spi/spi-mt65xx.c  |  6 +++---
 drivers/spi/spi-mt7621.c  |  2 +-
 drivers/spi/spi-mux.c |  8 
 drivers/spi/spi-mxic.c| 10 +-
 drivers/spi/spi-mxs.c |  2 +-
 drivers/spi/spi-npcm-fiu.c| 20 ++--
 drivers/spi/spi-nxp-fspi.c| 10 +-
 drivers/spi/spi-omap-100k.c   |  2 +-
 drivers/spi/spi-omap-uwire.c  |  8 
 drivers/spi/spi-omap2-mcspi.c | 24 
 drivers/spi/spi-orion.c   |  4 ++--
 drivers/spi/spi-pci1.c|  4 ++--
 drivers/spi/spi-pic32-sqi.c   |  2 +-
 drivers/spi/spi-pic32.c   |  4 ++--
 drivers/spi/spi-pl022.c   |  4 ++--
 drivers/spi/spi-pxa2xx.c  |  6 +++---
 drivers/spi/spi-qcom-qspi.c   |  2 +-
 drivers/spi/spi-rb4xx.c   |  2 +-
 drivers/spi/spi-rockchip-sfc.c|  2 +-
 drivers/spi/spi-rockchip.c| 26 ++
 drivers/spi/spi-rspi.c| 10 +-
 drivers/spi/spi-s3c64xx.c |  2 +-
 drivers/spi/spi-sc18is602.c   |  4 ++--
 drivers/spi/spi-sh-msiof.c|  6 +++---
 drivers/spi/spi-sh-sci.c  |  2 +-
 drivers/spi/spi-sifive.c  |  6 +++---
 drivers/spi/spi-sn-f-ospi.c   |  2 +-
 drivers/spi/spi-st-ssc4.c |  2 +-
 drivers/spi/spi-stm32-qspi.c  | 12 ++--
 drivers/spi/spi-sun4i.c   |  2 +-
 drivers/spi/spi-sun6i.c   |  2 +-
 drivers/spi/spi-synquacer.c   |  6 +++---
 drivers/spi/spi-tegra114.c| 28 ++--
 drivers/spi/spi-tegra20-sflash.c  |  2 +-
 drivers/spi/spi-tegra20-slink.c   |  6 +++---
 drivers/spi/spi-tegra210-quad.c   |  8 
 drivers/spi/spi-ti-qspi.c | 16 
 

[PATCH v4 00/15] spi: Add support for stacked/parallel memories

2023-02-10 Thread Amit Kumar Mahapatra
This patch is in the continuation to the discussions which happened on
'commit f89504300e94 ("spi: Stacked/parallel memories bindings")' for
adding dt-binding support for stacked/parallel memories.

This patch series updated the spi-nor, spi core and the spi drivers
to add stacked and parallel memories support.

The first patch
https://lore.kernel.org/all/20230119185342.2093323-1-amit.kumar-mahapa...@amd.com/
of the previous series got applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
But the rest of the patches in the series did not get applied due to merge
conflict, so send the remaining patches in the series after rebasing it
on top of for-next branch.
---
BRANCH: for-next

Changes in v4:
- Fixed build error in spi-pl022.c file - reported by Mark.
- Fixed build error in spi-sn-f-ospi.c file.
- Added Reviewed-by: Serge Semin  tag.
- Added two more patches to replace spi->chip_select with API calls in 
  mpc832x_rdb.c & cs35l41_hda_spi.c files.

Changes in v3:
- Rebased the patches on top of
  https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
- Added a patch to convert spi_nor_otp_region_len(nor) &
  spi_nor_otp_n_regions(nor) macros into inline functions
- Added Reviewed-by & Acked-by tags

Changes in v2:
- Rebased the patches on top of v6.2-rc1
- Created separate patch to add get & set APIs for spi->chip_select &
  spi->cs_gpiod, and replaced all spi->chip_select and spi->cs_gpiod
  references with the API calls.
- Created separate patch to add get & set APIs for nor->params.
---
Amit Kumar Mahapatra (15):
  spi: Replace all spi->chip_select and spi->cs_gpiod references with
function call
  net: Replace all spi->chip_select and spi->cs_gpiod references with
function call
  iio: imu: Replace all spi->chip_select and spi->cs_gpiod references
with function call
  mtd: devices: Replace all spi->chip_select and spi->cs_gpiod
references with function call
  staging: Replace all spi->chip_select and spi->cs_gpiod references
with function call
  platform/x86: serial-multi-instantiate: Replace all spi->chip_select
and spi->cs_gpiod references with function call
  powerpc/83xx/mpc832x_rdb: Replace all spi->chip_select references with
function call
  ALSA: hda: cs35l41: Replace all spi->chip_select references with
function call
  spi: Add stacked and parallel memories support in SPI core
  mtd: spi-nor: Convert macros with inline functions
  mtd: spi-nor: Add APIs to set/get nor->params
  mtd: spi-nor: Add stacked memories support in spi-nor
  spi: spi-zynqmp-gqspi: Add stacked memories support in GQSPI driver
  mtd: spi-nor: Add parallel memories support in spi-nor
  spi: spi-zynqmp-gqspi: Add parallel memories support in GQSPI driver

 arch/powerpc/platforms/83xx/mpc832x_rdb.c |   2 +-
 drivers/iio/imu/adis16400.c   |   2 +-
 drivers/mtd/devices/mtd_dataflash.c   |   2 +-
 drivers/mtd/spi-nor/atmel.c   |  17 +-
 drivers/mtd/spi-nor/core.c| 665 +++---
 drivers/mtd/spi-nor/core.h|   8 +
 drivers/mtd/spi-nor/debugfs.c |   4 +-
 drivers/mtd/spi-nor/gigadevice.c  |   4 +-
 drivers/mtd/spi-nor/issi.c|  11 +-
 drivers/mtd/spi-nor/macronix.c|   6 +-
 drivers/mtd/spi-nor/micron-st.c   |  39 +-
 drivers/mtd/spi-nor/otp.c |  48 +-
 drivers/mtd/spi-nor/sfdp.c|  29 +-
 drivers/mtd/spi-nor/spansion.c|  50 +-
 drivers/mtd/spi-nor/sst.c |   7 +-
 drivers/mtd/spi-nor/swp.c |  22 +-
 drivers/mtd/spi-nor/winbond.c |  10 +-
 drivers/mtd/spi-nor/xilinx.c  |  18 +-
 drivers/net/ethernet/adi/adin1110.c   |   2 +-
 drivers/net/ethernet/asix/ax88796c_main.c |   2 +-
 drivers/net/ethernet/davicom/dm9051.c |   2 +-
 drivers/net/ethernet/qualcomm/qca_debug.c |   2 +-
 drivers/net/ieee802154/ca8210.c   |   2 +-
 drivers/net/wan/slic_ds26522.c|   2 +-
 .../net/wireless/marvell/libertas/if_spi.c|   2 +-
 drivers/net/wireless/silabs/wfx/bus_spi.c |   2 +-
 drivers/net/wireless/st/cw1200/cw1200_spi.c   |   2 +-
 .../platform/x86/serial-multi-instantiate.c   |   3 +-
 drivers/spi/spi-altera-core.c |   2 +-
 drivers/spi/spi-amd.c |   4 +-
 drivers/spi/spi-ar934x.c  |   2 +-
 drivers/spi/spi-armada-3700.c |   4 +-
 drivers/spi/spi-aspeed-smc.c  |  13 +-
 drivers/spi/spi-at91-usart.c  |   2 +-
 drivers/spi/spi-ath79.c   |   4 +-
 drivers/spi/spi-atmel.c   |  26 +-
 drivers/spi/spi-au1550.c  |   4 +-
 drivers/spi/spi-axi-spi-engine.c  |   2 +-
 drivers/spi/spi-bcm-qspi.c|  10 +-
 drivers/spi/spi-bcm2835.c

[powerpc:next-test] BUILD SUCCESS e4d432f204d77e853b9d55810ebc877fa6d69a3d

2023-02-10 Thread kernel test robot
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git 
next-test
branch HEAD: e4d432f204d77e853b9d55810ebc877fa6d69a3d  integrity/powerpc: 
Support loading keys from PLPKS

elapsed time: 743m

configs tested: 73
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
alphaallyesconfig
alpha   defconfig
arc  allyesconfig
arc defconfig
arc  randconfig-r043-20230210
arm  allmodconfig
arm  allyesconfig
arm defconfig
arm  randconfig-r046-20230210
arm64allyesconfig
arm64   defconfig
cskydefconfig
i386 allyesconfig
i386  debian-10.3
i386defconfig
i386  randconfig-a001
i386  randconfig-a003
i386  randconfig-a005
i386  randconfig-a012
i386  randconfig-a014
i386  randconfig-a016
ia64 allmodconfig
ia64defconfig
loongarchallmodconfig
loongarch allnoconfig
loongarch   defconfig
m68k allmodconfig
m68kdefconfig
mips allmodconfig
mips allyesconfig
nios2   defconfig
parisc  defconfig
parisc64defconfig
powerpc  allmodconfig
powerpc   allnoconfig
riscvallmodconfig
riscv allnoconfig
riscv   defconfig
riscv  rv32_defconfig
s390 allmodconfig
s390 allyesconfig
s390defconfig
sh   allmodconfig
sparc   defconfig
um i386_defconfig
um   x86_64_defconfig
x86_64allnoconfig
x86_64   allyesconfig
x86_64  defconfig
x86_64  kexec
x86_64randconfig-a002
x86_64randconfig-a004
x86_64randconfig-a006
x86_64randconfig-a011
x86_64randconfig-a013
x86_64randconfig-a015
x86_64   rhel-8.3

clang tested configs:
hexagon  randconfig-r041-20230210
hexagon  randconfig-r045-20230210
i386  randconfig-a002
i386  randconfig-a004
i386  randconfig-a006
i386  randconfig-a011
i386  randconfig-a013
i386  randconfig-a015
riscvrandconfig-r042-20230210
s390 randconfig-r044-20230210
x86_64randconfig-a001
x86_64randconfig-a003
x86_64randconfig-a005
x86_64randconfig-a012
x86_64randconfig-a014
x86_64randconfig-a016

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests


[powerpc:next] BUILD SUCCESS 231635a26513955fea98638e79e0a43734976c3b

2023-02-10 Thread kernel test robot
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git 
next
branch HEAD: 231635a26513955fea98638e79e0a43734976c3b  powerpc/kcsan: Add KCSAN 
Support

elapsed time: 733m

configs tested: 73
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
alphaallyesconfig
alpha   defconfig
arc  allyesconfig
arc defconfig
arc  randconfig-r043-20230210
arm  allmodconfig
arm  allyesconfig
arm defconfig
arm  randconfig-r046-20230210
arm64allyesconfig
arm64   defconfig
cskydefconfig
i386 allyesconfig
i386  debian-10.3
i386defconfig
i386  randconfig-a001
i386  randconfig-a003
i386  randconfig-a005
i386  randconfig-a012
i386  randconfig-a014
i386  randconfig-a016
ia64 allmodconfig
ia64defconfig
loongarchallmodconfig
loongarch allnoconfig
loongarch   defconfig
m68k allmodconfig
m68kdefconfig
mips allmodconfig
mips allyesconfig
nios2   defconfig
parisc  defconfig
parisc64defconfig
powerpc  allmodconfig
powerpc   allnoconfig
riscvallmodconfig
riscv allnoconfig
riscv   defconfig
riscv  rv32_defconfig
s390 allmodconfig
s390 allyesconfig
s390defconfig
sh   allmodconfig
sparc   defconfig
um i386_defconfig
um   x86_64_defconfig
x86_64allnoconfig
x86_64   allyesconfig
x86_64  defconfig
x86_64  kexec
x86_64randconfig-a002
x86_64randconfig-a004
x86_64randconfig-a006
x86_64randconfig-a011
x86_64randconfig-a013
x86_64randconfig-a015
x86_64   rhel-8.3

clang tested configs:
hexagon  randconfig-r041-20230210
hexagon  randconfig-r045-20230210
i386  randconfig-a002
i386  randconfig-a004
i386  randconfig-a006
i386  randconfig-a011
i386  randconfig-a013
i386  randconfig-a015
riscvrandconfig-r042-20230210
s390 randconfig-r044-20230210
x86_64randconfig-a001
x86_64randconfig-a003
x86_64randconfig-a005
x86_64randconfig-a012
x86_64randconfig-a014
x86_64randconfig-a016

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests


Re: [PATCH 00/34] selftests: Fix incorrect kernel headers search path

2023-02-10 Thread Shuah Khan

On 2/3/23 18:06, Shuah Khan wrote:

On 2/1/23 19:07, Shuah Khan wrote:

Hi Mathieu,

On 1/30/23 15:29, Shuah Khan wrote:

On 1/27/23 06:57, Mathieu Desnoyers wrote:

Hi,

This series fixes incorrect kernel header search path in kernel
selftests.

Near the end of the series, a few changes are not tagged as "Fixes"
because the current behavior is to rely on the kernel sources uapi files
rather than on the installed kernel header files. Nevertheless, those
are updated for consistency.

There are situations where "../../../../include/" was added to -I search
path, which is bogus for userspace tests and caused issues with types.h.
Those are removed.



Thanks again for taking care of this. I did out of tree build testing on
x86 on linux-kselftest next with these patches below. I haven't seen
any problems introduced by the patch set.


   selftests: dma: Fix incorrect kernel headers search path

This one needs a change and I will send a patch on top of yours.
Even with that this test depends on unexported header from the
repo and won't build out of tree. This is not related to your
change.


   selftests: mount_setattr: Fix incorrect kernel headers search path

This one fails to build with our without patch - an existing error.

I have to do cross-build tests on arm64 and other arch patches still.
This will happen later this week.


arm64, s390 patches look good.



I am seeing problem with selftests/dma and selfttests/user_events.

1. selftests: dma: Fix incorrect kernel headers search path

dma test no longer builds. This test depends on linux/map_benchmark.h
which is not included in uapi

The order of include directorries -isystem followed by installed kernel
headers, breaks the test build with the change to use KHDR_INCLUDES


I am going to revert this patch for now and figure a longer term fix.
The problem is the dependency on a non-uapi file: linux/map_benchmark.h

Fixes: 8ddde07a3d28 ("dma-mapping: benchmark: extract a common
header file for map_benchmark definition") change added this
dependency on including linux/map_benchmark.h

Christoph, Do you see this map_benchmark.h as part of uapi?


2. selftests: user_events: Fix incorrect kernel headers search path
This one depends on linux/user_events.h which has bee removed from
uapi in this commit:

commit 5cfff569cab8bf544bab62c911c5d6efd5af5e05
Author: Steven Rostedt (Google) 
Date:   Fri Apr 1 14:39:03 2022 -0400

tracing: Move user_events.h temporarily out of include/uapi

This isn't a regression from 6.2 - this test stopped building once
user_events.h has been removed from uapi. I will add a note that
this test depends on a non-uapi header and can't be built at the
moment.

thanks,
-- Shuah







[PATCH] powerpc/machdep: warn when machine_is() used too early

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

machine_is() can't provide correct results before probe_machine() has
run. Warn when it's used too early in boot.

Signed-off-by: Nathan Lynch 
---
Prompted by my attempts to do some pseries-specific setup during
rtas_initialize() and being puzzled for a while that it wasn't
working.
---
 arch/powerpc/include/asm/machdep.h | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/machdep.h 
b/arch/powerpc/include/asm/machdep.h
index 378b8d5836a7..8c0a799d18cd 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -220,11 +220,13 @@ extern struct machdep_calls *machine_id;
EXPORT_SYMBOL(mach_##name); \
struct machdep_calls mach_##name __machine_desc =
 
-#define machine_is(name) \
-   ({ \
-   extern struct machdep_calls mach_##name \
-   __attribute__((weak));   \
-   machine_id == _##name; \
+#define machine_is(name)\
+   ({  \
+   extern struct machdep_calls mach_##name \
+   __attribute__((weak));  \
+   WARN(!machine_id,   \
+"machine_is() called before probe_machine()"); \
+   machine_id == _##name; \
})
 
 static inline void log_error(char *buf, unsigned int err_type, int fatal)

---
base-commit: 0bfb97203f5f300777624a2ad6f8f84aea3e8658
change-id: 20230210-warn-on-machine-is-before-probe-machine-37515b1f43bb

Best regards,
-- 
Nathan Lynch 



[PATCH RFC] PCI/AER: Enable internal AER errors by default

2023-02-10 Thread Ira Weiny
The CXL driver expects internal error reporting to be enabled via
pci_enable_pcie_error_reporting().  It is likely other drivers expect the same.
Dave submitted a patch to enable the CXL side[1] but the PCI AER registers
still mask errors.

PCIe v6.0 Uncorrectable Mask Register (7.8.4.3) and Correctable Mask
Register (7.8.4.6) default to masking internal errors.  The
Uncorrectable Error Severity Register (7.8.4.4) defaults internal errors
as fatal.

Enable internal errors to be reported via the standard
pci_enable_pcie_error_reporting() call.  Ensure uncorrectable errors are set
non-fatal to limit any impact to other drivers.

[1] 
https://lore.kernel.org/all/167604864163.2392965.5102660329807283871.stgit@djiang5-mobl3.local/

Cc: Bjorn Helgaas 
Cc: Jonathan Cameron 
Cc: Dan Williams 
Cc: Dave Jiang 
Cc: Stefan Roese 
Cc: "Kuppuswamy Sathyanarayanan" 
Cc: Mahesh J Salgaonkar 
Cc: Oliver O'Halloran 
Cc: linux-...@vger.kernel.org
Cc: linux-ker...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Ira Weiny 
---
This is RFC to see if it is acceptable to be part of the standard
pci_enable_pcie_error_reporting() call or perhaps a separate pci core
call should be introduced.  It is anticipated that enabling this error
reporting is what existing drivers are expecting.  The errors are marked
non-fatal therefore it should not adversely affect existing devices.
---
 drivers/pci/pcie/aer.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index 625f7b2cafe4..9d3ed3a5fc23 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -229,11 +229,28 @@ int pcie_aer_is_native(struct pci_dev *dev)
 
 int pci_enable_pcie_error_reporting(struct pci_dev *dev)
 {
+   int pos_cap_err;
+   u32 reg;
int rc;
 
if (!pcie_aer_is_native(dev))
return -EIO;
 
+   pos_cap_err = dev->aer_cap;
+
+   /* Unmask correctable and uncorrectable (non-fatal) internal errors */
+   pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, );
+   reg &= ~PCI_ERR_COR_INTERNAL;
+   pci_write_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, reg);
+
+   pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, );
+   reg &= ~PCI_ERR_UNC_INTN;
+   pci_write_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, reg);
+
+   pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, );
+   reg &= ~PCI_ERR_UNC_INTN;
+   pci_write_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, reg);
+
rc = pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS);
return pcibios_err_to_errno(rc);
 }

---
base-commit: e5ab7f206ffc873160bd0f1a52cae17ab692a9d1
change-id: 20230209-cxl-pci-aer-18dda61c8239

Best regards,
-- 
Ira Weiny 



Re: [PATCH v6 24/26] powerpc/pseries: Implement secvars for dynamic secure boot

2023-02-10 Thread Stefan Berger




On 2/10/23 16:23, Stefan Berger wrote:






+
+// PLPKS dynamic secure boot doesn't give us a format string in the same way 
OPAL does.
+// Instead, report the format using the SB_VERSION variable in the keystore.
+// The string is made up by us, and takes the form "ibm,plpks-sb-v" (or 
"ibm,plpks-sb-unknown"
+// if the SB_VERSION variable doesn't exist). Hypervisor defines the 
SB_VERSION variable as a
+// "1 byte unsigned integer value".
+static ssize_t plpks_secvar_format(char *buf, size_t bufsize)
+{
+    struct plpks_var var = {0};
+    ssize_t ret;
+    u8 version;
+
+    var.component = NULL;


Since it's initialized with {0} this is not necessary.


+    // Only the signed variables have null bytes in their names, this one 
doesn't
+    var.name = "SB_VERSION";
+    var.namelen = strlen(var.name);
+    var.datalen = 1;
+    var.data = 
+
+    // Unlike the other vars, SB_VERSION is owned by firmware instead of the OS
+    ret = plpks_read_fw_var();
+    if (ret) {
+    if (ret == -ENOENT) {
+    ret = snprintf(buf, bufsize, "ibm,plpks-sb-unknown");
+    } else {
+    pr_err("Error %ld reading SB_VERSION from firmware\n", ret);
+    ret = -EIO;
+    }
+    goto err;
+    }
+
+    ret = snprintf(buf, bufsize, "ibm,plpks-sb-v%hhu", version);
+
+err:
+    kfree(var.data);


remove the kfree()


Actually don't remove it but it should probably be

if (var.data != )
kfree(var.data);



+    return ret;
+}
+


Re: [PATCH v6 24/26] powerpc/pseries: Implement secvars for dynamic secure boot

2023-02-10 Thread Stefan Berger




On 2/10/23 03:03, Andrew Donnellan wrote:

From: Russell Currey 

The pseries platform can support dynamic secure boot (i.e. secure boot
using user-defined keys) using variables contained with the PowerVM LPAR
Platform KeyStore (PLPKS).  Using the powerpc secvar API, expose the
relevant variables for pseries dynamic secure boot through the existing
secvar filesystem layout.

The relevant variables for dynamic secure boot are signed in the
keystore, and can only be modified using the H_PKS_SIGNED_UPDATE hcall.
Object labels in the keystore are encoded using ucs2 format.  With our
fixed variable names we don't have to care about encoding outside of the
necessary byte padding.

When a user writes to a variable, the first 8 bytes of data must contain
the signed update flags as defined by the hypervisor.

When a user reads a variable, the first 4 bytes of data contain the
policies defined for the object.

Limitations exist due to the underlying implementation of sysfs binary
attributes, as is the case for the OPAL secvar implementation -
partial writes are unsupported and writes cannot be larger than PAGE_SIZE.
(Even when using bin_attributes, which can be larger than a single page,
sysfs only gives us one page's worth of write buffer at a time, and the
hypervisor does not expose an interface for partial writes.)

Co-developed-by: Nayna Jain 
Signed-off-by: Nayna Jain 
Co-developed-by: Andrew Donnellan 
Signed-off-by: Andrew Donnellan 
Signed-off-by: Russell Currey 

---

v2: Remove unnecessary config vars from sysfs and document the others,
 thanks to review from Greg.  If we end up needing to expose more, we
 can add them later and update the docs.

 Use sysfs_emit() instead of sprintf(), thanks to Greg.

 Change the size of the sysfs binary attributes to include the 8-byte
 flags header, preventing truncation of large writes.

v3: plpks_set_variable(): pass var to plpks_signed_update_var() as a
 pointer (mpe)

 Update copyright date (ajd)

 Consistent comment style (ajd)

 Change device_initcall() to machine_arch_initcall(pseries...) so we
 don't try to load on powernv and kill the machine (mpe)

 Add config attributes into plpks_secvar_ops (mpe)

 Get rid of PLPKS_SECVAR_COUNT macro (mpe)

 Reworded descriptions in ABI documentation (mpe)

 Switch to using secvar_ops->var_names rather than
 secvar_ops->get_next() (ajd/mpe)

 Optimise allocation/copying of buffers (mpe)

 Elaborate the comment documenting the "format" string (mpe)

 Return -EIO on errors in the read case (mpe)

 Add "grubdbx" variable (Sudhakar Kuppusamy)

 Use utf8s_to_utf16s() rather than our own "UCS-2" conversion code (mpe)

 Change uint64_t to u64 (mpe)

 Fix SB_VERSION data length (ruscur)

 Stop prepending policy data on read (ruscur)

 Enforce max format length on format string (not strictly needed, but
 makes the length limit clear) (ajd)

 Update include of plpks.h to reflect new path (ruscur)

 Consistent constant naming scheme (ruscur)

v4: Return set_secvar_ops() return code

 Pass buffer size to plpks_secvar_format() (stefanb, npiggin)

 Add missing null check (stefanb)

 Add comment to commit message explaining PAGE_SIZE write limit (joel)

v5: Add comment explaining why we use "key_len - 1" (npiggin)

 Use strlen(var.name) instead of hardcoding 10 as length of
 "SB_VERSION" (npiggin)

 Improve comments about use of SB_VERSION and format string (npiggin)

 Change "+ 8" to "+ sizeof(u64)" when accounting for flags size in
 working out file's max size (npiggin)

 Compile plpks-secvar.c based on CONFIG_PPC_SECURE_BOOT, not
 CONFIG_PPC_SECVAR_SYSFS, as the secvar backend is needed for loading
 keys into keyrings even if the sysfs interface is disabled (ajd)

v6: Update date in ABI docs (stefanb)

 Get rid of 1 byte kzalloc (npiggin)
---
  Documentation/ABI/testing/sysfs-secvar|  75 +-
  arch/powerpc/platforms/pseries/Makefile   |   4 +-
  arch/powerpc/platforms/pseries/plpks-secvar.c | 218 ++
  3 files changed, 294 insertions(+), 3 deletions(-)
  create mode 100644 arch/powerpc/platforms/pseries/plpks-secvar.c

diff --git a/Documentation/ABI/testing/sysfs-secvar 
b/Documentation/ABI/testing/sysfs-secvar
index feebb8c57294..857cf12b0904 100644
--- a/Documentation/ABI/testing/sysfs-secvar
+++ b/Documentation/ABI/testing/sysfs-secvar
@@ -18,6 +18,14 @@ Description: A string indicating which backend is in use by 
the firmware.
This determines the format of the variable and the accepted
format of variable updates.
  
+		On powernv/OPAL, this value is provided by the OPAL firmware

+   and is expected to be "ibm,edk2-compat-v1".
+
+   On pseries/PLPKS, this is generated by the kernel based on the
+   version number in the SB_VERSION variable in the keystore, and
+   

Re: [PATCH v6 23/26] powerpc/pseries: Pass PLPKS password on kexec

2023-02-10 Thread Stefan Berger




On 2/10/23 03:03, Andrew Donnellan wrote:

From: Russell Currey 

Before interacting with the PLPKS, we ask the hypervisor to generate a
password for the current boot, which is then required for most further
PLPKS operations.

If we kexec into a new kernel, the new kernel will try and fail to
generate a new password, as the password has already been set.

Pass the password through to the new kernel via the device tree, in
/chosen/ibm,plpks-pw. Check for the presence of this property before
trying to generate a new password - if it exists, use the existing
password and remove it from the device tree.

This only works with the kexec_file_load() syscall, not the older
kexec_load() syscall, however if you're using Secure Boot then you want
to be using kexec_file_load() anyway.

Signed-off-by: Russell Currey 
Signed-off-by: Andrew Donnellan 

---

v3: New patch

v4: Fix compile when CONFIG_PSERIES_PLPKS=n (snowpatch)

 Fix error handling on fdt_path_offset() call (ruscur)

v5: Fix DT property name in commit message (npiggin)

 Clear prop in FDT during init to prevent password exposure (mpe)

 Rework to remove ifdefs from C code (npiggin)

v6: Rebase on top of 7294194b47e994753a86eee8cf1c61f3f36458a3 and
 fc546faa559538fb312c77e055243ece18ab3288

 Whitespace (stefanb)

 Use more const (stefanb)

 Get rid of FDT extra space allocation for node overhead, as it
 shouldn't be necessary (ruscur)

 Note kexec_file_load() restriction in commit message
---
  arch/powerpc/include/asm/plpks.h   | 14 ++
  arch/powerpc/kernel/prom.c |  4 ++
  arch/powerpc/kexec/file_load_64.c  | 18 +---
  arch/powerpc/platforms/pseries/plpks.c | 61 ++
  4 files changed, 92 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
index 757313e00521..23b77027c916 100644
--- a/arch/powerpc/include/asm/plpks.h
+++ b/arch/powerpc/include/asm/plpks.h
@@ -176,6 +176,20 @@ u64 plpks_get_signedupdatealgorithms(void);
   */
  u16 plpks_get_passwordlen(void);
  
+/**

+ * Called in early init to retrieve and clear the PLPKS password from the DT.
+ */
+void plpks_early_init_devtree(void);
+
+/**
+ * Populates the FDT with the PLPKS password to prepare for kexec.
+ */
+int plpks_populate_fdt(void *fdt);
+#else // CONFIG_PSERIES_PLPKS
+static inline bool plpks_is_available(void) { return false; }
+static inline u16 plpks_get_passwordlen(void) { BUILD_BUG(); }
+static inline void plpks_early_init_devtree(void) { }
+static inline int plpks_populate_fdt(void *fdt) { BUILD_BUG(); }
  #endif // CONFIG_PSERIES_PLPKS
  
  #endif // _ASM_POWERPC_PLPKS_H

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 4f1c920aa13e..8a13b378770f 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -56,6 +56,7 @@
  #include 
  #include 
  #include 
+#include 
  
  #include 
  
@@ -893,6 +894,9 @@ void __init early_init_devtree(void *params)

powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE;
  #endif
  
+	/* If kexec left a PLPKS password in the DT, get it and clear it */

+   plpks_early_init_devtree();
+
tm_init();
  
  	DBG(" <- early_init_devtree()\n");

diff --git a/arch/powerpc/kexec/file_load_64.c 
b/arch/powerpc/kexec/file_load_64.c
index 52085751f5f4..8a9469e1ce71 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -27,6 +27,7 @@
  #include 
  #include 
  #include 
+#include 
  
  struct umem_info {

u64 *buf;   /* data buffer for usable-memory property */
@@ -977,12 +978,17 @@ static unsigned int cpu_node_size(void)
   */
  unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image)
  {
-   unsigned int cpu_nodes, extra_size;
+   unsigned int cpu_nodes, extra_size = 0;
struct device_node *dn;
u64 usm_entries;
  
+	// Budget some space for the password blob. There's already extra space

+   // for the key name
+   if (plpks_is_available())
+   extra_size += (unsigned int)plpks_get_passwordlen();
+
if (image->type != KEXEC_TYPE_CRASH)
-   return 0;
+   return extra_size;
  
  	/*

 * For kdump kernel, account for linux,usable-memory and
@@ -992,9 +998,7 @@ unsigned int kexec_extra_fdt_size_ppc64(struct kimage 
*image)
if (drmem_lmb_size()) {
usm_entries = ((memory_hotplug_max() / drmem_lmb_size()) +
   (2 * (resource_size(_res) / 
drmem_lmb_size(;
-   extra_size = (unsigned int)(usm_entries * sizeof(u64));
-   } else {
-   extra_size = 0;
+   extra_size += (unsigned int)(usm_entries * sizeof(u64));
}
  
  	/*

@@ -1233,6 +1237,10 @@ int setup_new_fdt_ppc64(const struct kimage *image, void 
*fdt,
}
}
  
+	// If we have PLPKS active, we need to provide the password to the new kernel


Re: [PATCH v6 05/26] powerpc/secvar: Warn and error if multiple secvar ops are set

2023-02-10 Thread Stefan Berger




On 2/10/23 03:03, Andrew Donnellan wrote:

From: Russell Currey 

The secvar code only supports one consumer at a time.

Multiple consumers aren't possible at this point in time, but we'd want
it to be obvious if it ever could happen.

Signed-off-by: Russell Currey 
Co-developed-by: Andrew Donnellan 
Signed-off-by: Andrew Donnellan 

---

v4: Return an error and don't actually try to set secvar_operations if the
 warning is triggered (npiggin)

v5: Drop "extern" to fix a checkpatch check (snowpatch)

v6: Return -EBUSY rather than -1 (stefanb)
---
  arch/powerpc/include/asm/secvar.h|  4 ++--
  arch/powerpc/kernel/secvar-ops.c | 10 --
  arch/powerpc/platforms/powernv/opal-secvar.c |  4 +---
  3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/secvar.h 
b/arch/powerpc/include/asm/secvar.h
index 07ba36f868a7..a2b5f2203dc5 100644
--- a/arch/powerpc/include/asm/secvar.h
+++ b/arch/powerpc/include/asm/secvar.h
@@ -21,11 +21,11 @@ struct secvar_operations {
  
  #ifdef CONFIG_PPC_SECURE_BOOT
  
-extern void set_secvar_ops(const struct secvar_operations *ops);

+int set_secvar_ops(const struct secvar_operations *ops);
  
  #else
  
-static inline void set_secvar_ops(const struct secvar_operations *ops) { }

+static inline int set_secvar_ops(const struct secvar_operations *ops) { return 
0; }
  
  #endif
  
diff --git a/arch/powerpc/kernel/secvar-ops.c b/arch/powerpc/kernel/secvar-ops.c

index 6a29777d6a2d..19172a2804f0 100644
--- a/arch/powerpc/kernel/secvar-ops.c
+++ b/arch/powerpc/kernel/secvar-ops.c
@@ -8,10 +8,16 @@
  
  #include 

  #include 
+#include 
  
-const struct secvar_operations *secvar_ops __ro_after_init;

+const struct secvar_operations *secvar_ops __ro_after_init = NULL;
  
-void set_secvar_ops(const struct secvar_operations *ops)

+int set_secvar_ops(const struct secvar_operations *ops)
  {
+   if (WARN_ON_ONCE(secvar_ops))
+   return -EBUSY;
+
secvar_ops = ops;
+
+   return 0;
  }
diff --git a/arch/powerpc/platforms/powernv/opal-secvar.c 
b/arch/powerpc/platforms/powernv/opal-secvar.c
index ef89861569e0..4c0a3b030fe0 100644
--- a/arch/powerpc/platforms/powernv/opal-secvar.c
+++ b/arch/powerpc/platforms/powernv/opal-secvar.c
@@ -113,9 +113,7 @@ static int opal_secvar_probe(struct platform_device *pdev)
return -ENODEV;
}
  
-	set_secvar_ops(_secvar_ops);

-
-   return 0;
+   return set_secvar_ops(_secvar_ops);
  }
  
  static const struct of_device_id opal_secvar_match[] = {


Reviewed-by: Stefan Berger 


Re: [PATCH v6 21/26] powerpc/pseries: Clarify warning when PLPKS password already set

2023-02-10 Thread Stefan Berger




On 2/10/23 03:03, Andrew Donnellan wrote:

When the H_PKS_GEN_PASSWORD hcall returns H_IN_USE, operations that require
authentication (i.e. anything other than reading a world-readable variable)
will not work.

The current error message doesn't explain this clearly enough. Reword it
to emphasise that authenticated operations will fail.


typo: -> emphasize



Signed-off-by: Andrew Donnellan 

---

v6: New patch
---
  arch/powerpc/platforms/pseries/plpks.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index 926b6a927326..01ae919b4497 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -146,7 +146,7 @@ static int plpks_gen_password(void)
memcpy(ospassword, password, ospasswordlength);
} else {
if (rc == H_IN_USE) {
-   pr_warn("Password is already set for POWER LPAR Platform 
KeyStore\n");
+   pr_warn("Password already set - authenticated operations 
will fail\n");
rc = 0;
} else {
goto out;


Reviewed-by: Stefan Berger 


Re: [External] : [PATCH v3 1/1] PCI: layerscape: Add EP mode support for ls1028a

2023-02-10 Thread ALOK TIWARI

Reviewed-by: Alok Tiwari 

On 2/9/2023 8:40 PM, Frank Li wrote:

From: Xiaowei Bao 

Add PCIe EP mode support for ls1028a.

Signed-off-by: Xiaowei Bao 
Signed-off-by: Hou Zhiqiang 
Signed-off-by: Frank Li 
Acked-by:  Roy Zang 
---

Change from v2 to v3
order by .compatible

Change from v2 to v2
Added
Signed-off-by: Frank Li 
Acked-by:  Roy Zang 


All other patches were already accepte by maintainer in
https://urldefense.com/v3/__https://lore.kernel.org/lkml/2022223457.10599-1-leoyang...@nxp.com/__;!!ACWV5N9M2RV99hQ!NR9EU4fPDwxdyrb9tdBm9VNIMHSlw6dLgXCAPDSrm7ftWVNrh6JldLGzzrKyiE0xRlP5OdiGBN7PCf9gRaA$

But missed this one.

Re-post

  drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c 
b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index ad99707b3b99..c640db60edc6 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -110,6 +110,7 @@ static const struct ls_pcie_ep_drvdata lx2_ep_drvdata = {
  };
  
  static const struct of_device_id ls_pcie_ep_of_match[] = {

+   { .compatible = "fsl,ls1028a-pcie-ep", .data = _ep_drvdata },
{ .compatible = "fsl,ls1046a-pcie-ep", .data = _ep_drvdata },
{ .compatible = "fsl,ls1088a-pcie-ep", .data = _ep_drvdata },
{ .compatible = "fsl,ls2088a-pcie-ep", .data = _ep_drvdata },


Re: [External] : [PATCH v3 1/1] PCI: layerscape: Add EP mode support for ls1028a

2023-02-10 Thread Bjorn Helgaas
On Fri, Feb 10, 2023 at 11:51:46PM +0530, ALOK TIWARI wrote:
> LGTM,

Thanks a lot for looking at this!

In the Linux world, "LGTM" is not something a maintainer can really
act on.  If you respond with a "Reviewed-by" tag as described here:

  
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?id=v6.1#n495

maintainers (or tooling like b4) can add it to the patch when merging
it.  Here are some examples of how it can be used:

  
https://lore.kernel.org/linux-pci/bn9pr11mb527699243353309a1ddfefbe8c...@bn9pr11mb5276.namprd11.prod.outlook.com/
  https://lore.kernel.org/linux-pci/y9aezvrtb4sob...@memverge.com/
  
https://lore.kernel.org/linux-pci/a20028e6-3318-26ca-117a-26c87c292...@linaro.org/

Bjorn

> On 2/9/2023 8:40 PM, Frank Li wrote:
> > From: Xiaowei Bao 
> > 
> > Add PCIe EP mode support for ls1028a.
> > 
> > Signed-off-by: Xiaowei Bao 
> > Signed-off-by: Hou Zhiqiang 
> > Signed-off-by: Frank Li 
> > Acked-by:  Roy Zang 


[PATCH v3 12/20] powerpc/pseries: add RTAS work area allocator

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Various pseries-specific RTAS functions take a temporary "work area"
parameter - a buffer in memory accessible to RTAS. Typically such
functions are passed the statically allocated rtas_data_buf buffer as
the argument. This buffer is protected by a global spinlock. So users
of rtas_data_buf cannot perform sleeping operations while accessing
the buffer.

Most RTAS functions that have a work area parameter can return a
status (-2/990x) that indicates that the caller should retry. Before
retrying, the caller may need to reschedule or sleep (see
rtas_busy_delay() for details). This combination of factors
leads to uncomfortable constructions like this:

do {
spin_lock(_data_buf_lock);
rc = rtas_call(token, __pa(rtas_data_buf, ...);
if (rc == 0) {
/* parse or copy out rtas_data_buf contents */
}
spin_unlock(_data_buf_lock);
} while (rtas_busy_delay(rc));

Another unfortunately common way of handling this is for callers to
blithely ignore the possibility of a -2/990x status and hope for the
best.

If users were allowed to perform blocking operations while owning a
work area, the programming model would become less tedious and
error-prone. Users could schedule away, sleep, or perform other
blocking operations without having to release and re-acquire
resources.

We could continue to use a single work area buffer, and convert
rtas_data_buf_lock to a mutex. But that would impose an unnecessarily
coarse serialization on all users. As awkward as the current design
is, it prevents longer running operations that need to repeatedly use
rtas_data_buf from blocking the progress of others.

There are more considerations. One is that while 4KB is fine for all
current in-kernel uses, some RTAS calls can take much smaller buffers,
and some (VPD, platform dumps) would likely benefit from larger
ones. Another is that at least one RTAS function (ibm,get-vpd)
has *two* work area parameters. And finally, we should expect the
number of work area users in the kernel to increase over time as we
introduce lockdown-compatible ABIs to replace less safe use cases
based on sys_rtas/librtas.

So a special-purpose allocator for RTAS work area buffers seems worth
trying.

Properties:

* The backing memory for the allocator is reserved early in boot in
  order to satisfy RTAS addressing requirements, and then managed with
  genalloc.
* Allocations can block, but they never fail (mempool-like).
* Prioritizes first-come, first-serve fairness over throughput.
* Early boot allocations before the allocator has been initialized are
  served via an internal static buffer.

Intended to replace rtas_data_buf. New code that needs RTAS work area
buffers should prefer this API.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/include/asm/rtas-work-area.h   |  96 +++
 arch/powerpc/kernel/rtas.c  |   3 +
 arch/powerpc/platforms/pseries/Makefile |   2 +-
 arch/powerpc/platforms/pseries/rtas-work-area.c | 209 
 4 files changed, 309 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/rtas-work-area.h 
b/arch/powerpc/include/asm/rtas-work-area.h
new file mode 100644
index ..251a395dbd2e
--- /dev/null
+++ b/arch/powerpc/include/asm/rtas-work-area.h
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASM_POWERPC_RTAS_WORK_AREA_H
+#define _ASM_POWERPC_RTAS_WORK_AREA_H
+
+#include 
+#include 
+#include 
+
+#include 
+
+/**
+ * struct rtas_work_area - RTAS work area descriptor.
+ *
+ * Descriptor for a "work area" in PAPR terminology that satisfies
+ * RTAS addressing requirements.
+ */
+struct rtas_work_area {
+   /* private: Use the APIs provided below. */
+   char *buf;
+   size_t size;
+};
+
+enum {
+   /* Maximum allocation size, enforced at build time. */
+   RTAS_WORK_AREA_MAX_ALLOC_SZ = SZ_128K,
+};
+
+/**
+ * rtas_work_area_alloc() - Acquire a work area of the requested size.
+ * @size_: Allocation size. Must be compile-time constant and not more
+ * than %RTAS_WORK_AREA_MAX_ALLOC_SZ.
+ *
+ * Allocate a buffer suitable for passing to RTAS functions that have
+ * a memory address parameter, often (but not always) referred to as a
+ * "work area" in PAPR. Although callers are allowed to block while
+ * holding a work area, the amount of memory reserved for this purpose
+ * is limited, and allocations should be short-lived. A good guideline
+ * is to release any allocated work area before returning from a
+ * system call.
+ *
+ * This function does not fail. It blocks until the allocation
+ * succeeds. To prevent deadlocks, callers are discouraged from
+ * allocating more than one work area simultaneously in a single task
+ * context.
+ *
+ * Context: This function may sleep.
+ * Return: A  rtas_work_area descriptor for the allocated work area.
+ */
+#define rtas_work_area_alloc(size_) 

[PATCH v3 18/20] powerpc/pseries/lpar: convert to papr_sysparm API

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Convert the TLB block invalidate characteristics discovery to the new
papr_sysparm API. This occurs too early in boot to use
papr_sysparm_buf_alloc(), so use a static buffer.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/platforms/pseries/lpar.c | 37 +--
 1 file changed, 9 insertions(+), 28 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/lpar.c 
b/arch/powerpc/platforms/pseries/lpar.c
index 6597b2126ebb..2eab323f6970 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1469,8 +1470,6 @@ static inline void __init check_lp_set_hblkrm(unsigned 
int lp,
}
 }
 
-#define SPLPAR_TLB_BIC_TOKEN   50
-
 /*
  * The size of the TLB Block Invalidate Characteristics is variable. But at the
  * maximum it will be the number of possible page sizes *2 + 10 bytes.
@@ -1481,42 +1480,24 @@ static inline void __init check_lp_set_hblkrm(unsigned 
int lp,
 
 void __init pseries_lpar_read_hblkrm_characteristics(void)
 {
-   const s32 token = rtas_token("ibm,get-system-parameter");
-   unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH];
-   int call_status, len, idx, bpsize;
+   static struct papr_sysparm_buf buf __initdata;
+   int len, idx, bpsize;
 
if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE))
return;
 
-   do {
-   spin_lock(_data_buf_lock);
-   memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
-   call_status = rtas_call(token, 3, 1, NULL, SPLPAR_TLB_BIC_TOKEN,
-   __pa(rtas_data_buf), 
RTAS_DATA_BUF_SIZE);
-   memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH);
-   local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0';
-   spin_unlock(_data_buf_lock);
-   } while (rtas_busy_delay(call_status));
-
-   if (call_status != 0) {
-   pr_warn("%s %s Error calling get-system-parameter (0x%x)\n",
-   __FILE__, __func__, call_status);
+   if (papr_sysparm_get(PAPR_SYSPARM_TLB_BLOCK_INVALIDATE_ATTRS, ))
return;
-   }
 
-   /*
-* The first two (2) bytes of the data in the buffer are the length of
-* the returned data, not counting these first two (2) bytes.
-*/
-   len = be16_to_cpu(*((u16 *)local_buffer)) + 2;
+   len = be16_to_cpu(buf.len);
if (len > SPLPAR_TLB_BIC_MAXLENGTH) {
pr_warn("%s too large returned buffer %d", __func__, len);
return;
}
 
-   idx = 2;
+   idx = 0;
while (idx < len) {
-   u8 block_shift = local_buffer[idx++];
+   u8 block_shift = buf.val[idx++];
u32 block_size;
unsigned int npsize;
 
@@ -1525,9 +1506,9 @@ void __init pseries_lpar_read_hblkrm_characteristics(void)
 
block_size = 1 << block_shift;
 
-   for (npsize = local_buffer[idx++];
+   for (npsize = buf.val[idx++];
 npsize > 0 && idx < len; npsize--)
-   check_lp_set_hblkrm((unsigned int) local_buffer[idx++],
+   check_lp_set_hblkrm((unsigned int)buf.val[idx++],
block_size);
}
 

-- 
2.39.1



[PATCH v3 15/20] powerpc/pseries: convert CMO probe to papr_sysparm API

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Convert the direct invocation of the ibm,get-system-parameter RTAS
function to papr_sysparm_get().

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/platforms/pseries/setup.c | 23 ++-
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/setup.c 
b/arch/powerpc/platforms/pseries/setup.c
index 74e50b6b28d4..420a2fa48292 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -57,6 +57,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -941,32 +942,21 @@ void pSeries_coalesce_init(void)
  */
 static void __init pSeries_cmo_feature_init(void)
 {
-   const s32 token = rtas_token("ibm,get-system-parameter");
+   static struct papr_sysparm_buf buf __initdata;
+   static_assert(sizeof(buf.val) >= CMO_MAXLENGTH);
char *ptr, *key, *value, *end;
-   int call_status;
int page_order = IOMMU_PAGE_SHIFT_4K;
 
pr_debug(" -> fw_cmo_feature_init()\n");
 
-   do {
-   spin_lock(_data_buf_lock);
-   call_status = rtas_call(token, 3, 1, NULL,
-   CMO_CHARACTERISTICS_TOKEN,
-   __pa(rtas_data_buf),
-   RTAS_DATA_BUF_SIZE);
-   if (call_status == 0)
-   break;
-   spin_unlock(_data_buf_lock);
-   } while (rtas_busy_delay(call_status));
-
-   if (call_status != 0) {
+   if (papr_sysparm_get(PAPR_SYSPARM_COOP_MEM_OVERCOMMIT_ATTRS, )) {
pr_debug("CMO not available\n");
pr_debug(" <- fw_cmo_feature_init()\n");
return;
}
 
-   end = rtas_data_buf + CMO_MAXLENGTH - 2;
-   ptr = rtas_data_buf + 2;/* step over strlen value */
+   end = [CMO_MAXLENGTH];
+   ptr = [0];
key = value = ptr;
 
while (*ptr && (ptr <= end)) {
@@ -1012,7 +1002,6 @@ static void __init pSeries_cmo_feature_init(void)
} else
pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP,
 CMO_SecPSP);
-   spin_unlock(_data_buf_lock);
pr_debug(" <- fw_cmo_feature_init()\n");
 }
 

-- 
2.39.1



[PATCH v3 10/20] powerpc/tracing: tracepoints for RTAS entry and exit

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Add two sets of tracepoints to be used around RTAS entry:

* rtas_input/rtas_output, which emit the function name, its inputs,
  the returned status, and any other outputs. These produce an API-level
  record of OS<->RTAS activity.

* rtas_ll_entry/rtas_ll_exit, which are lower-level and emit the
  entire contents of the parameter block (aka rtas_args) on entry and
  exit. Likely useful only for debugging.

With uses of these tracepoints in do_enter_rtas() to be added in the
following patch, examples of get-time-of-day and event-scan functions
as rendered by trace-cmd (with some multi-line formatting manually
imposed on the rtas_ll_* entries to avoid extremely long lines in the
commit message):

cat-36800 [059]  4978.518303: rtas_input:   get-time-of-day arguments:
cat-36800 [059]  4978.518306: rtas_ll_entry:token=3 nargs=0 nret=8
params: [0]=0x 
[1]=0x [2]=0x [3]=0x
[4]=0x 
[5]=0x [6]=0x [7]=0x
[8]=0x 
[9]=0x [10]=0x [11]=0x
[12]=0x 
[13]=0x [14]=0x [15]=0x
cat-36800 [059]  4978.518366: rtas_ll_exit: token=3 nargs=0 nret=8
params: [0]=0x 
[1]=0x07e6 [2]=0x000b [3]=0x0001
[4]=0x 
[5]=0x000e [6]=0x0008 [7]=0x2e0dac40
[8]=0x 
[9]=0x [10]=0x [11]=0x
[12]=0x 
[13]=0x [14]=0x [15]=0x
cat-36800 [059]  4978.518366: rtas_output:  get-time-of-day status: 0, 
other outputs: 2022 11 1 0 14 8 772648000

kworker/39:1-336   [039]  4982.731623: rtas_input:   event-scan 
arguments: 4294967295 0 80484920 2048
kworker/39:1-336   [039]  4982.731626: rtas_ll_entry:token=6 nargs=4 
nret=1
 params: 
[0]=0x [1]=0x [2]=0x04cc1a38 [3]=0x0800
 
[4]=0x [5]=0x000e [6]=0x0008 [7]=0x2e0dac40
 
[8]=0x [9]=0x [10]=0x [11]=0x
 
[12]=0x [13]=0x [14]=0x [15]=0x
kworker/39:1-336   [039]  4982.731676: rtas_ll_exit: token=6 nargs=4 
nret=1
 params: 
[0]=0x [1]=0x [2]=0x04cc1a38 [3]=0x0800
 
[4]=0x0001 [5]=0x000e [6]=0x0008 [7]=0x2e0dac40
 
[8]=0x [9]=0x [10]=0x [11]=0x
 
[12]=0x [13]=0x [14]=0x [15]=0x
kworker/39:1-336   [039]  4982.731677: rtas_output:  event-scan status: 
1, other outputs:

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/include/asm/trace.h | 103 +++
 1 file changed, 103 insertions(+)

diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h
index 08cd60cd70b7..82cc2c6704e6 100644
--- a/arch/powerpc/include/asm/trace.h
+++ b/arch/powerpc/include/asm/trace.h
@@ -119,6 +119,109 @@ TRACE_EVENT_FN_COND(hcall_exit,
 );
 #endif
 
+#ifdef CONFIG_PPC_RTAS
+
+#include 
+
+TRACE_EVENT(rtas_input,
+
+   TP_PROTO(struct rtas_args *rtas_args, const char *name),
+
+   TP_ARGS(rtas_args, name),
+
+   TP_STRUCT__entry(
+   __field(__u32, nargs)
+   __string(name, name)
+   __dynamic_array(__u32, inputs, be32_to_cpu(rtas_args->nargs))
+   ),
+
+   TP_fast_assign(
+   __entry->nargs = be32_to_cpu(rtas_args->nargs);
+   __assign_str(name, name);
+   be32_to_cpu_array(__get_dynamic_array(inputs), rtas_args->args, 
__entry->nargs);
+   ),
+
+   TP_printk("%s arguments: %s", __get_str(name),
+ __print_array(__get_dynamic_array(inputs), __entry->nargs, 4)
+   )
+);
+
+TRACE_EVENT(rtas_output,
+
+   TP_PROTO(struct rtas_args *rtas_args, const char *name),
+
+   TP_ARGS(rtas_args, name),
+
+   TP_STRUCT__entry(
+   __field(__u32, nr_other)
+   __field(__s32, status)
+   __string(name, name)
+   __dynamic_array(__u32, other_outputs, 

[PATCH v3 09/20] powerpc/rtas: strengthen do_enter_rtas() type safety, drop inline

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Make do_enter_rtas() take a pointer to struct rtas_args and do the
__pa() conversion in one place instead of leaving it to callers. This
also makes it possible to introduce enter/exit tracepoints that access
the rtas_args struct fields.

There's no apparent reason to force inlining of do_enter_rtas()
either, and it seems to bloat the code a bit. Let the compiler decide.

Signed-off-by: Nathan Lynch 
Reviewed-by: Andrew Donnellan 
Reviewed-by: Nicholas Piggin 
---
 arch/powerpc/kernel/rtas.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 3c7151f4f2ba..d2622b997b68 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -523,7 +523,7 @@ static const struct rtas_function 
*rtas_token_to_function(s32 token)
 /* This is here deliberately so it's only used in this file */
 void enter_rtas(unsigned long);
 
-static inline void do_enter_rtas(unsigned long args)
+static void do_enter_rtas(struct rtas_args *args)
 {
unsigned long msr;
 
@@ -538,7 +538,7 @@ static inline void do_enter_rtas(unsigned long args)
 
hard_irq_disable(); /* Ensure MSR[EE] is disabled on PPC64 */
 
-   enter_rtas(args);
+   enter_rtas(__pa(args));
 
srr_regs_clobbered(); /* rtas uses SRRs, invalidate */
 }
@@ -892,7 +892,7 @@ static char *__fetch_rtas_last_error(char *altbuf)
save_args = rtas_args;
rtas_args = err_args;
 
-   do_enter_rtas(__pa(_args));
+   do_enter_rtas(_args);
 
err_args = rtas_args;
rtas_args = save_args;
@@ -939,7 +939,7 @@ va_rtas_call_unlocked(struct rtas_args *args, int token, 
int nargs, int nret,
for (i = 0; i < nret; ++i)
args->rets[i] = 0;
 
-   do_enter_rtas(__pa(args));
+   do_enter_rtas(args);
 }
 
 void rtas_call_unlocked(struct rtas_args *args, int token, int nargs, int 
nret, ...)
@@ -1757,7 +1757,7 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
raw_spin_lock_irqsave(_lock, flags);
 
rtas_args = args;
-   do_enter_rtas(__pa(_args));
+   do_enter_rtas(_args);
args = rtas_args;
 
/* A -1 return code indicates that the last command couldn't

-- 
2.39.1



[PATCH v3 14/20] powerpc/pseries: PAPR system parameter API

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Introduce a set of APIs for retrieving and updating PAPR system
parameters. This encapsulates the toil of temporary RTAS work area
management, RTAS function call retries, and translation of RTAS call
statuses to conventional error values.

There are several places in the kernel that already retrieve system
parameters by calling the RTAS ibm,get-system-parameter function
directly. These will be converted to papr_sysparm_get() in changes to
follow.

As for updating system parameters, current practice is to use
sys_rtas() from user space; there are no in-kernel users of the RTAS
ibm,set-system-parameter function. However this will become deprecated
in time because it is not compatible with lockdown.

The papr_sysparm_* APIs will form the common basis for in-kernel
and user space access to system parameters. The code to expose the
set/get capabilities to user space will follow.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/include/asm/papr-sysparm.h   |  38 +++
 arch/powerpc/platforms/pseries/Makefile   |   2 +-
 arch/powerpc/platforms/pseries/papr-sysparm.c | 151 ++
 3 files changed, 190 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/papr-sysparm.h 
b/arch/powerpc/include/asm/papr-sysparm.h
new file mode 100644
index ..f5fdbd8ae9db
--- /dev/null
+++ b/arch/powerpc/include/asm/papr-sysparm.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASM_POWERPC_PAPR_SYSPARM_H
+#define _ASM_POWERPC_PAPR_SYSPARM_H
+
+typedef struct {
+   const u32 token;
+} papr_sysparm_t;
+
+#define mk_papr_sysparm(x_) ((papr_sysparm_t){ .token = x_, })
+
+/*
+ * Derived from the "Defined Parameters" table in PAPR 7.3.16 System
+ * Parameters Option. Where the spec says "characteristics", we use
+ * "attrs" in the symbolic names to keep them from getting too
+ * unwieldy.
+ */
+#define PAPR_SYSPARM_SHARED_PROC_LPAR_ATTRSmk_papr_sysparm(20)
+#define PAPR_SYSPARM_PROC_MODULE_INFO  mk_papr_sysparm(43)
+#define PAPR_SYSPARM_COOP_MEM_OVERCOMMIT_ATTRS mk_papr_sysparm(44)
+#define PAPR_SYSPARM_TLB_BLOCK_INVALIDATE_ATTRSmk_papr_sysparm(50)
+#define PAPR_SYSPARM_LPAR_NAME mk_papr_sysparm(55)
+
+enum {
+   PAPR_SYSPARM_MAX_INPUT  = 1024,
+   PAPR_SYSPARM_MAX_OUTPUT = 4000,
+};
+
+struct papr_sysparm_buf {
+   __be16 len;
+   char val[PAPR_SYSPARM_MAX_OUTPUT];
+};
+
+struct papr_sysparm_buf *papr_sysparm_buf_alloc(void);
+void papr_sysparm_buf_free(struct papr_sysparm_buf *buf);
+int papr_sysparm_set(papr_sysparm_t param, const struct papr_sysparm_buf *buf);
+int papr_sysparm_get(papr_sysparm_t param, struct papr_sysparm_buf *buf);
+
+#endif /* _ASM_POWERPC_PAPR_SYSPARM_H */
diff --git a/arch/powerpc/platforms/pseries/Makefile 
b/arch/powerpc/platforms/pseries/Makefile
index b63d7b4ba8fe..1133bee7980a 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -3,7 +3,7 @@ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
 ccflags-$(CONFIG_PPC_PSERIES_DEBUG)+= -DDEBUG
 
 obj-y  := lpar.o hvCall.o nvram.o reconfig.o \
-  of_helpers.o rtas-work-area.o \
+  of_helpers.o rtas-work-area.o papr-sysparm.o \
   setup.o iommu.o event_sources.o ras.o \
   firmware.o power.o dlpar.o mobility.o rng.o \
   pci.o pci_dlpar.o eeh_pseries.o msi.o \
diff --git a/arch/powerpc/platforms/pseries/papr-sysparm.c 
b/arch/powerpc/platforms/pseries/papr-sysparm.c
new file mode 100644
index ..2bb5c816399b
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/papr-sysparm.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt)"papr-sysparm: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct papr_sysparm_buf *papr_sysparm_buf_alloc(void)
+{
+   struct papr_sysparm_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+
+   return buf;
+}
+
+void papr_sysparm_buf_free(struct papr_sysparm_buf *buf)
+{
+   kfree(buf);
+}
+
+/**
+ * papr_sysparm_get() - Retrieve the value of a PAPR system parameter.
+ * @param: PAPR system parameter token as described in
+ * 7.3.16 "System Parameters Option".
+ * @buf: A  papr_sysparm_buf as returned from papr_sysparm_buf_alloc().
+ *
+ * Place the result of querying the specified parameter, if available,
+ * in @buf. The result includes a be16 length header followed by the
+ * value, which may be a string or binary data. See  papr_sysparm_buf.
+ *
+ * Since there is at least one parameter (60, OS Service Entitlement
+ * Status) where the results depend on the incoming contents of the
+ * work area, the caller-supplied buffer is copied unmodified into the
+ * work area before calling ibm,get-system-parameter.
+ *
+ * A defined parameter may not be implemented on a given 

[PATCH v3 13/20] powerpc/pseries/dlpar: use RTAS work area API

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Hold a work area object for the duration of the RTAS
ibm,configure-connector sequence, eliminating locking and copying
around each RTAS call.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/platforms/pseries/dlpar.c | 27 +--
 1 file changed, 9 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/dlpar.c 
b/arch/powerpc/platforms/pseries/dlpar.c
index 498d6efcb5ae..9b65b50a5456 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static struct workqueue_struct *pseries_hp_wq;
 
@@ -137,6 +138,7 @@ struct device_node *dlpar_configure_connector(__be32 
drc_index,
struct property *property;
struct property *last_property = NULL;
struct cc_workarea *ccwa;
+   struct rtas_work_area *work_area;
char *data_buf;
int cc_token;
int rc = -1;
@@ -145,29 +147,18 @@ struct device_node *dlpar_configure_connector(__be32 
drc_index,
if (cc_token == RTAS_UNKNOWN_SERVICE)
return NULL;
 
-   data_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
-   if (!data_buf)
-   return NULL;
+   work_area = rtas_work_area_alloc(SZ_4K);
+   data_buf = rtas_work_area_raw_buf(work_area);
 
ccwa = (struct cc_workarea *)_buf[0];
ccwa->drc_index = drc_index;
ccwa->zero = 0;
 
do {
-   /* Since we release the rtas_data_buf lock between configure
-* connector calls we want to re-populate the rtas_data_buffer
-* with the contents of the previous call.
-*/
-   spin_lock(_data_buf_lock);
-
-   memcpy(rtas_data_buf, data_buf, RTAS_DATA_BUF_SIZE);
-   rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL);
-   memcpy(data_buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
-
-   spin_unlock(_data_buf_lock);
-
-   if (rtas_busy_delay(rc))
-   continue;
+   do {
+   rc = rtas_call(cc_token, 2, 1, NULL,
+  rtas_work_area_phys(work_area), NULL);
+   } while (rtas_busy_delay(rc));
 
switch (rc) {
case COMPLETE:
@@ -227,7 +218,7 @@ struct device_node *dlpar_configure_connector(__be32 
drc_index,
} while (rc);
 
 cc_error:
-   kfree(data_buf);
+   rtas_work_area_free(work_area);
 
if (rc) {
if (first_dn)

-- 
2.39.1



[PATCH v3 19/20] powerpc/rtas: introduce rtas_function_token() API

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Users of rtas_token() supply a string argument that can't be validated
at build time. A typo or misspelling has to be caught by inspection or
by observing wrong behavior at runtime.

Since the core RTAS code now has consolidated the names of all
possible RTAS functions and mapped them to their tokens, token lookup
can be implemented using symbolic constants to index a static array.

So introduce rtas_function_token(), a replacement API which does that,
along with a rtas_service_present()-equivalent helper,
rtas_function_implemented(). Callers supply an opaque predefined
function handle which is used internally to index the function
table. Typos or other inappropriate arguments yield build errors, and
the function handle is a type that can't be easily confused with RTAS
tokens or other integer types.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/include/asm/rtas.h | 99 +
 arch/powerpc/kernel/rtas.c  | 28 +++-
 2 files changed, 126 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index f03891891a2d..3abe15ac79db 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -101,6 +101,100 @@ enum rtas_function_index {
RTAS_FNIDX__WRITE_PCI_CONFIG,
 };
 
+/*
+ * Opaque handle for client code to refer to RTAS functions. All valid
+ * function handles are build-time constants prefixed with RTAS_FN_.
+ */
+typedef struct {
+   const enum rtas_function_index index;
+} rtas_fn_handle_t;
+
+
+#define rtas_fn_handle(x_) ((const rtas_fn_handle_t) { .index = x_, })
+
+#define RTAS_FN_CHECK_EXCEPTION   
rtas_fn_handle(RTAS_FNIDX__CHECK_EXCEPTION)
+#define RTAS_FN_DISPLAY_CHARACTER 
rtas_fn_handle(RTAS_FNIDX__DISPLAY_CHARACTER)
+#define RTAS_FN_EVENT_SCAN
rtas_fn_handle(RTAS_FNIDX__EVENT_SCAN)
+#define RTAS_FN_FREEZE_TIME_BASE  
rtas_fn_handle(RTAS_FNIDX__FREEZE_TIME_BASE)
+#define RTAS_FN_GET_POWER_LEVEL   
rtas_fn_handle(RTAS_FNIDX__GET_POWER_LEVEL)
+#define RTAS_FN_GET_SENSOR_STATE  
rtas_fn_handle(RTAS_FNIDX__GET_SENSOR_STATE)
+#define RTAS_FN_GET_TERM_CHAR 
rtas_fn_handle(RTAS_FNIDX__GET_TERM_CHAR)
+#define RTAS_FN_GET_TIME_OF_DAY   
rtas_fn_handle(RTAS_FNIDX__GET_TIME_OF_DAY)
+#define RTAS_FN_IBM_ACTIVATE_FIRMWARE 
rtas_fn_handle(RTAS_FNIDX__IBM_ACTIVATE_FIRMWARE)
+#define RTAS_FN_IBM_CBE_START_PTCAL   
rtas_fn_handle(RTAS_FNIDX__IBM_CBE_START_PTCAL)
+#define RTAS_FN_IBM_CBE_STOP_PTCAL
rtas_fn_handle(RTAS_FNIDX__IBM_CBE_STOP_PTCAL)
+#define RTAS_FN_IBM_CHANGE_MSI
rtas_fn_handle(RTAS_FNIDX__IBM_CHANGE_MSI)
+#define RTAS_FN_IBM_CLOSE_ERRINJCT
rtas_fn_handle(RTAS_FNIDX__IBM_CLOSE_ERRINJCT)
+#define RTAS_FN_IBM_CONFIGURE_BRIDGE  
rtas_fn_handle(RTAS_FNIDX__IBM_CONFIGURE_BRIDGE)
+#define RTAS_FN_IBM_CONFIGURE_CONNECTOR   
rtas_fn_handle(RTAS_FNIDX__IBM_CONFIGURE_CONNECTOR)
+#define RTAS_FN_IBM_CONFIGURE_KERNEL_DUMP 
rtas_fn_handle(RTAS_FNIDX__IBM_CONFIGURE_KERNEL_DUMP)
+#define RTAS_FN_IBM_CONFIGURE_PE  
rtas_fn_handle(RTAS_FNIDX__IBM_CONFIGURE_PE)
+#define RTAS_FN_IBM_CREATE_PE_DMA_WINDOW  
rtas_fn_handle(RTAS_FNIDX__IBM_CREATE_PE_DMA_WINDOW)
+#define RTAS_FN_IBM_DISPLAY_MESSAGE   
rtas_fn_handle(RTAS_FNIDX__IBM_DISPLAY_MESSAGE)
+#define RTAS_FN_IBM_ERRINJCT  
rtas_fn_handle(RTAS_FNIDX__IBM_ERRINJCT)
+#define RTAS_FN_IBM_EXTI2C
rtas_fn_handle(RTAS_FNIDX__IBM_EXTI2C)
+#define RTAS_FN_IBM_GET_CONFIG_ADDR_INFO  
rtas_fn_handle(RTAS_FNIDX__IBM_GET_CONFIG_ADDR_INFO)
+#define RTAS_FN_IBM_GET_CONFIG_ADDR_INFO2 
rtas_fn_handle(RTAS_FNIDX__IBM_GET_CONFIG_ADDR_INFO2)
+#define RTAS_FN_IBM_GET_DYNAMIC_SENSOR_STATE  
rtas_fn_handle(RTAS_FNIDX__IBM_GET_DYNAMIC_SENSOR_STATE)
+#define RTAS_FN_IBM_GET_INDICES   
rtas_fn_handle(RTAS_FNIDX__IBM_GET_INDICES)
+#define RTAS_FN_IBM_GET_RIO_TOPOLOGY  
rtas_fn_handle(RTAS_FNIDX__IBM_GET_RIO_TOPOLOGY)
+#define RTAS_FN_IBM_GET_SYSTEM_PARAMETER  
rtas_fn_handle(RTAS_FNIDX__IBM_GET_SYSTEM_PARAMETER)
+#define RTAS_FN_IBM_GET_VPD   
rtas_fn_handle(RTAS_FNIDX__IBM_GET_VPD)
+#define RTAS_FN_IBM_GET_XIVE  
rtas_fn_handle(RTAS_FNIDX__IBM_GET_XIVE)
+#define RTAS_FN_IBM_INT_OFF   
rtas_fn_handle(RTAS_FNIDX__IBM_INT_OFF)
+#define RTAS_FN_IBM_INT_ON
rtas_fn_handle(RTAS_FNIDX__IBM_INT_ON)
+#define RTAS_FN_IBM_IO_QUIESCE_ACK
rtas_fn_handle(RTAS_FNIDX__IBM_IO_QUIESCE_ACK)
+#define RTAS_FN_IBM_LPAR_PERFTOOLS
rtas_fn_handle(RTAS_FNIDX__IBM_LPAR_PERFTOOLS)
+#define RTAS_FN_IBM_MANAGE_FLASH_IMAGE
rtas_fn_handle(RTAS_FNIDX__IBM_MANAGE_FLASH_IMAGE)

[PATCH v3 11/20] powerpc/rtas: add tracepoints around RTAS entry

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Decompose the RTAS entry C code into tracing and non-tracing variants,
calling the just-added tracepoints in the tracing-enabled path. Skip
tracing in contexts known to be unsafe (real mode, CPU offline).

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/kernel/rtas.c | 59 +-
 1 file changed, 53 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index d2622b997b68..a6d0c46b4512 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 struct rtas_filter {
@@ -523,24 +524,70 @@ static const struct rtas_function 
*rtas_token_to_function(s32 token)
 /* This is here deliberately so it's only used in this file */
 void enter_rtas(unsigned long);
 
+static void __do_enter_rtas(struct rtas_args *args)
+{
+   enter_rtas(__pa(args));
+   srr_regs_clobbered(); /* rtas uses SRRs, invalidate */
+}
+
+static void __do_enter_rtas_trace(struct rtas_args *args)
+{
+   const char *name = NULL;
+   /*
+* If the tracepoints that consume the function name aren't
+* active, avoid the lookup.
+*/
+   if ((trace_rtas_input_enabled() || trace_rtas_output_enabled())) {
+   const s32 token = be32_to_cpu(args->token);
+   const struct rtas_function *func = 
rtas_token_to_function(token);
+
+   name = func->name;
+   }
+
+   trace_rtas_input(args, name);
+   trace_rtas_ll_entry(args);
+
+   __do_enter_rtas(args);
+
+   trace_rtas_ll_exit(args);
+   trace_rtas_output(args, name);
+}
+
 static void do_enter_rtas(struct rtas_args *args)
 {
-   unsigned long msr;
-
+   const unsigned long msr = mfmsr();
+   /*
+* Situations where we want to skip any active tracepoints for
+* safety reasons:
+*
+* 1. The last code executed on an offline CPU as it stops,
+*i.e. we're about to call stop-self. The tracepoints'
+*function name lookup uses xarray, which uses RCU, which
+*isn't valid to call on an offline CPU.  Any events
+*emitted on an offline CPU will be discarded anyway.
+*
+* 2. In real mode, as when invoking ibm,nmi-interlock from
+*the pseries MCE handler. We cannot count on trace
+*buffers or the entries in rtas_token_to_function_xarray
+*to be contained in the RMO.
+*/
+   const unsigned long mask = MSR_IR | MSR_DR;
+   const bool can_trace = likely(cpu_online(raw_smp_processor_id()) &&
+ (msr & mask) == mask);
/*
 * Make sure MSR[RI] is currently enabled as it will be forced later
 * in enter_rtas.
 */
-   msr = mfmsr();
BUG_ON(!(msr & MSR_RI));
 
BUG_ON(!irqs_disabled());
 
hard_irq_disable(); /* Ensure MSR[EE] is disabled on PPC64 */
 
-   enter_rtas(__pa(args));
-
-   srr_regs_clobbered(); /* rtas uses SRRs, invalidate */
+   if (can_trace)
+   __do_enter_rtas_trace(args);
+   else
+   __do_enter_rtas(args);
 }
 
 struct rtas_t rtas;

-- 
2.39.1



[PATCH v3 20/20] powerpc/rtas: arch-wide function token lookup conversions

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

With the tokens for all implemented RTAS functions now available via
rtas_function_token(), which is optimal and safe for arbitrary
contexts, there is no need to use rtas_token() or cache its result.

Most conversions are trivial, but a few are worth describing in more
detail:

* Error injection token comparisons for lockdown purposes are
  consolidated into a simple predicate: token_is_restricted_errinjct().

* A couple of special cases in block_rtas_call() do not use
  rtas_token() but perform string comparisons against names in the
  function table. These are converted to compare against token values
  instead, which is logically equivalent but less expensive.

* The lookup for the ibm,os-term token can be deferred until needed,
  instead of caching it at boot to avoid device tree traversal during
  panic.

* Since rtas_function_token() accesses a read-only data structure
  without taking any locks, xmon's lookup of set-indicator can be
  performed as needed instead of cached at startup.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/kernel/rtas-proc.c | 24 
 arch/powerpc/kernel/rtas-rtc.c  |  6 +-
 arch/powerpc/kernel/rtas.c  | 79 -
 arch/powerpc/kernel/rtas_flash.c| 21 ---
 arch/powerpc/kernel/rtas_pci.c  |  8 +--
 arch/powerpc/kernel/rtasd.c |  2 +-
 arch/powerpc/platforms/52xx/efika.c |  4 +-
 arch/powerpc/platforms/cell/ras.c   |  4 +-
 arch/powerpc/platforms/cell/smp.c   |  4 +-
 arch/powerpc/platforms/chrp/nvram.c |  4 +-
 arch/powerpc/platforms/chrp/pci.c   |  4 +-
 arch/powerpc/platforms/chrp/setup.c |  4 +-
 arch/powerpc/platforms/maple/setup.c|  4 +-
 arch/powerpc/platforms/pseries/dlpar.c  |  2 +-
 arch/powerpc/platforms/pseries/eeh_pseries.c| 22 +++
 arch/powerpc/platforms/pseries/hotplug-cpu.c|  4 +-
 arch/powerpc/platforms/pseries/io_event_irq.c   |  2 +-
 arch/powerpc/platforms/pseries/mobility.c   |  4 +-
 arch/powerpc/platforms/pseries/msi.c|  4 +-
 arch/powerpc/platforms/pseries/nvram.c  |  4 +-
 arch/powerpc/platforms/pseries/papr-sysparm.c   |  4 +-
 arch/powerpc/platforms/pseries/pci.c|  2 +-
 arch/powerpc/platforms/pseries/ras.c|  2 +-
 arch/powerpc/platforms/pseries/rtas-work-area.c |  4 +-
 arch/powerpc/platforms/pseries/setup.c  |  8 +--
 arch/powerpc/platforms/pseries/smp.c|  6 +-
 arch/powerpc/sysdev/xics/ics-rtas.c |  8 +--
 arch/powerpc/xmon/xmon.c| 16 +
 28 files changed, 123 insertions(+), 137 deletions(-)

diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 081b2b741a8c..9454b8395b6a 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -287,9 +287,9 @@ static ssize_t ppc_rtas_poweron_write(struct file *file,
 
rtc_time64_to_tm(nowtime, );
 
-   error = rtas_call(rtas_token("set-time-for-power-on"), 7, 1, NULL, 
-   tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
-   tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */);
+   error = rtas_call(rtas_function_token(RTAS_FN_SET_TIME_FOR_POWER_ON), 
7, 1, NULL,
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */);
if (error)
printk(KERN_WARNING "error: setting poweron time returned: 
%s\n", 
ppc_rtas_process_error(error));
@@ -350,9 +350,9 @@ static ssize_t ppc_rtas_clock_write(struct file *file,
return error;
 
rtc_time64_to_tm(nowtime, );
-   error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL, 
-   tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
-   tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
+   error = rtas_call(rtas_function_token(RTAS_FN_SET_TIME_OF_DAY), 7, 1, 
NULL,
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
if (error)
printk(KERN_WARNING "error: setting the clock returned: %s\n", 
ppc_rtas_process_error(error));
@@ -362,7 +362,7 @@ static ssize_t ppc_rtas_clock_write(struct file *file,
 static int ppc_rtas_clock_show(struct seq_file *m, void *v)
 {
int ret[8];
-   int error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
+   int error = rtas_call(rtas_function_token(RTAS_FN_GET_TIME_OF_DAY), 0, 
8, ret);
 
if (error) {
printk(KERN_WARNING "error: reading the clock returned: %s\n", 
@@ -385,7 +385,7 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void 
*v)
 {
int i,j;
int state, error;
-   int 

[PATCH v3 17/20] powerpc/pseries/hv-24x7: convert to papr_sysparm API

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

The new papr_sysparm API handles the details of system parameter
retrieval. Use that instead of open-coding the RTAS call, work area
management, and retries.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/perf/hv-24x7.c | 37 +++--
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index fcfebf5bd378..f388b984a336 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -66,8 +67,6 @@ static bool is_physical_domain(unsigned int domain)
  * Refer PAPR+ document to get parameter token value as '43'.
  */
 
-#define PROCESSOR_MODULE_INFO   43
-
 static u32 phys_sockets;   /* Physical sockets */
 static u32 phys_chipspersocket;/* Physical chips per socket*/
 static u32 phys_coresperchip; /* Physical cores per chip */
@@ -79,8 +78,7 @@ static u32 phys_coresperchip; /* Physical cores per chip */
  */
 void read_24x7_sys_info(void)
 {
-   const s32 token = rtas_token("ibm,get-system-parameter");
-   int call_status;
+   struct papr_sysparm_buf *buf;
 
/*
 * Making system parameter: chips and sockets and cores per chip
@@ -90,27 +88,22 @@ void read_24x7_sys_info(void)
phys_chipspersocket = 1;
phys_coresperchip = 1;
 
-   do {
-   spin_lock(_data_buf_lock);
-   call_status = rtas_call(token, 3, 1, NULL, 
PROCESSOR_MODULE_INFO,
-   __pa(rtas_data_buf), 
RTAS_DATA_BUF_SIZE);
-   if (call_status == 0) {
-   int ntypes = be16_to_cpup((__be16 *)_data_buf[2]);
-   int len = be16_to_cpup((__be16 *)_data_buf[0]);
+   buf = papr_sysparm_buf_alloc();
+   if (!buf)
+   return;
 
-   if (len >= 8 && ntypes != 0) {
-   phys_sockets = be16_to_cpup((__be16 
*)_data_buf[4]);
-   phys_chipspersocket = be16_to_cpup((__be16 
*)_data_buf[6]);
-   phys_coresperchip = be16_to_cpup((__be16 
*)_data_buf[8]);
-   }
+   if (!papr_sysparm_get(PAPR_SYSPARM_PROC_MODULE_INFO, buf)) {
+   int ntypes = be16_to_cpup((__be16 *)>val[0]);
+   int len = be16_to_cpu(buf->len);
+
+   if (len >= 8 && ntypes != 0) {
+   phys_sockets = be16_to_cpup((__be16 *)>val[2]);
+   phys_chipspersocket = be16_to_cpup((__be16 
*)>val[4]);
+   phys_coresperchip = be16_to_cpup((__be16 
*)>val[6]);
}
-   spin_unlock(_data_buf_lock);
-   } while (rtas_busy_delay(call_status));
-
-   if (call_status != 0) {
-   pr_err("Error calling get-system-parameter %d\n",
-  call_status);
}
+
+   papr_sysparm_buf_free(buf);
 }
 
 /* Domains for which more than one result element are returned for each event. 
*/

-- 
2.39.1



[PATCH v3 08/20] powerpc/rtas: improve function information lookups

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

The core RTAS support code and its clients perform two types of lookup
for RTAS firmware function information.

First, mapping a known function name to a token. The typical use case
invokes rtas_token() to retrieve the token value to pass to
rtas_call(). rtas_token() relies on of_get_property(), which performs
a linear search of the /rtas node's property list under a lock with
IRQs disabled.

Second, and less common: given a token value, looking up some
information about the function. The primary example is the sys_rtas
filter path, which linearly scans a small table to match the token to
a rtas_filter struct. Another use case to come is RTAS entry/exit
tracepoints, which will require efficient lookup of function names
from token values. Currently there is no general API for this.

We need something much like the existing rtas_filters table, but more
general and organized to facilitate efficient lookups.

Introduce:

* A new rtas_function type, aggregating function name, token,
  and filter. Other function characteristics could be added in the
  future.

* An array of rtas_function, where each element corresponds to a known
  RTAS function. All information in the table is static save the token
  values, which are derived from the device tree at boot. The array is
  sorted by function name to allow binary search.

* A named constant for each known RTAS function, used to index the
  function array. These also will be used in a client-facing API to be
  added later.

* An xarray that maps valid tokens to rtas_function objects.

Fold the existing rtas_filter table into the new rtas_function array,
with the appropriate adjustments to block_rtas_call(). Remove
now-redundant fields from struct rtas_filter. Preserve the function of
the CONFIG_CPU_BIG_ENDIAN guard in the current filter table by
introducing a per-function flag that is set for the function entries
related to pseries LPAR migration. These have never had working users
via sys_rtas on ppc64le; see commit de0f7349a0dd ("powerpc/rtas:
prevent suspend-related sys_rtas use on LE").

Convert rtas_token() to use a lockless binary search on the function
table. Fall back to the old behavior for lookups against names that
are not known to be RTAS functions, but issue a warning. rtas_token()
is for function names; it is not a general facility for accessing
arbitrary properties of the /rtas node. All known misuses of
rtas_token() have been converted to more appropriate of_ APIs in
preceding changes.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/include/asm/rtas.h |  85 +
 arch/powerpc/kernel/rtas.c  | 735 ++--
 2 files changed, 707 insertions(+), 113 deletions(-)

diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 479a95cb2770..f03891891a2d 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -16,6 +16,91 @@
  * Copyright (C) 2001 PPC 64 Team, IBM Corp
  */
 
+enum rtas_function_index {
+   RTAS_FNIDX__CHECK_EXCEPTION,
+   RTAS_FNIDX__DISPLAY_CHARACTER,
+   RTAS_FNIDX__EVENT_SCAN,
+   RTAS_FNIDX__FREEZE_TIME_BASE,
+   RTAS_FNIDX__GET_POWER_LEVEL,
+   RTAS_FNIDX__GET_SENSOR_STATE,
+   RTAS_FNIDX__GET_TERM_CHAR,
+   RTAS_FNIDX__GET_TIME_OF_DAY,
+   RTAS_FNIDX__IBM_ACTIVATE_FIRMWARE,
+   RTAS_FNIDX__IBM_CBE_START_PTCAL,
+   RTAS_FNIDX__IBM_CBE_STOP_PTCAL,
+   RTAS_FNIDX__IBM_CHANGE_MSI,
+   RTAS_FNIDX__IBM_CLOSE_ERRINJCT,
+   RTAS_FNIDX__IBM_CONFIGURE_BRIDGE,
+   RTAS_FNIDX__IBM_CONFIGURE_CONNECTOR,
+   RTAS_FNIDX__IBM_CONFIGURE_KERNEL_DUMP,
+   RTAS_FNIDX__IBM_CONFIGURE_PE,
+   RTAS_FNIDX__IBM_CREATE_PE_DMA_WINDOW,
+   RTAS_FNIDX__IBM_DISPLAY_MESSAGE,
+   RTAS_FNIDX__IBM_ERRINJCT,
+   RTAS_FNIDX__IBM_EXTI2C,
+   RTAS_FNIDX__IBM_GET_CONFIG_ADDR_INFO,
+   RTAS_FNIDX__IBM_GET_CONFIG_ADDR_INFO2,
+   RTAS_FNIDX__IBM_GET_DYNAMIC_SENSOR_STATE,
+   RTAS_FNIDX__IBM_GET_INDICES,
+   RTAS_FNIDX__IBM_GET_RIO_TOPOLOGY,
+   RTAS_FNIDX__IBM_GET_SYSTEM_PARAMETER,
+   RTAS_FNIDX__IBM_GET_VPD,
+   RTAS_FNIDX__IBM_GET_XIVE,
+   RTAS_FNIDX__IBM_INT_OFF,
+   RTAS_FNIDX__IBM_INT_ON,
+   RTAS_FNIDX__IBM_IO_QUIESCE_ACK,
+   RTAS_FNIDX__IBM_LPAR_PERFTOOLS,
+   RTAS_FNIDX__IBM_MANAGE_FLASH_IMAGE,
+   RTAS_FNIDX__IBM_MANAGE_STORAGE_PRESERVATION,
+   RTAS_FNIDX__IBM_NMI_INTERLOCK,
+   RTAS_FNIDX__IBM_NMI_REGISTER,
+   RTAS_FNIDX__IBM_OPEN_ERRINJCT,
+   RTAS_FNIDX__IBM_OPEN_SRIOV_ALLOW_UNFREEZE,
+   RTAS_FNIDX__IBM_OPEN_SRIOV_MAP_PE_NUMBER,
+   RTAS_FNIDX__IBM_OS_TERM,
+   RTAS_FNIDX__IBM_PARTNER_CONTROL,
+   RTAS_FNIDX__IBM_PHYSICAL_ATTESTATION,
+   RTAS_FNIDX__IBM_PLATFORM_DUMP,
+   RTAS_FNIDX__IBM_POWER_OFF_UPS,
+   RTAS_FNIDX__IBM_QUERY_INTERRUPT_SOURCE_NUMBER,
+   RTAS_FNIDX__IBM_QUERY_PE_DMA_WINDOW,
+   RTAS_FNIDX__IBM_READ_PCI_CONFIG,
+   

[PATCH v3 16/20] powerpc/pseries/lparcfg: convert to papr_sysparm API

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

/proc/powerpc/lparcfg derives the LPAR name and SPLPAR characteristics
it reports using bare calls to the RTAS ibm,get-system-parameter
function. Convert these to the higher-level papr_sysparm API, which
handles the tedious details.

While the SPLPAR string parsing code could stand to be updated, that
should be done in a separate change. It is minimally modified here to
reduce the risk of changing behavior.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/platforms/pseries/lparcfg.c | 104 +++
 1 file changed, 24 insertions(+), 80 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/lparcfg.c 
b/arch/powerpc/platforms/pseries/lparcfg.c
index cd33d5800763..8acc70509520 100644
--- a/arch/powerpc/platforms/pseries/lparcfg.c
+++ b/arch/powerpc/platforms/pseries/lparcfg.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -311,16 +312,6 @@ static void parse_mpp_x_data(struct seq_file *m)
seq_printf(m, "coalesce_pool_spurr=%ld\n", 
mpp_x_data.pool_spurr_cycles);
 }
 
-/*
- * PAPR defines, in section "7.3.16 System Parameters Option", the token 55 to
- * read the LPAR name, and the largest output data to 4000 + 2 bytes length.
- */
-#define SPLPAR_LPAR_NAME_TOKEN 55
-#define GET_SYS_PARM_BUF_SIZE  4002
-#if GET_SYS_PARM_BUF_SIZE > RTAS_DATA_BUF_SIZE
-#error "GET_SYS_PARM_BUF_SIZE is larger than RTAS_DATA_BUF_SIZE"
-#endif
-
 /*
  * Read the lpar name using the RTAS ibm,get-system-parameter call.
  *
@@ -332,46 +323,19 @@ static void parse_mpp_x_data(struct seq_file *m)
  */
 static int read_rtas_lpar_name(struct seq_file *m)
 {
-   int rc, len, token;
-   union {
-   char raw_buffer[GET_SYS_PARM_BUF_SIZE];
-   struct {
-   __be16 len;
-   char name[GET_SYS_PARM_BUF_SIZE-2];
-   };
-   } *local_buffer;
+   struct papr_sysparm_buf *buf;
+   int err;
 
-   token = rtas_token("ibm,get-system-parameter");
-   if (token == RTAS_UNKNOWN_SERVICE)
-   return -EINVAL;
-
-   local_buffer = kmalloc(sizeof(*local_buffer), GFP_KERNEL);
-   if (!local_buffer)
+   buf = papr_sysparm_buf_alloc();
+   if (!buf)
return -ENOMEM;
 
-   do {
-   spin_lock(_data_buf_lock);
-   memset(rtas_data_buf, 0, sizeof(*local_buffer));
-   rc = rtas_call(token, 3, 1, NULL, SPLPAR_LPAR_NAME_TOKEN,
-  __pa(rtas_data_buf), sizeof(*local_buffer));
-   if (!rc)
-   memcpy(local_buffer->raw_buffer, rtas_data_buf,
-  sizeof(local_buffer->raw_buffer));
-   spin_unlock(_data_buf_lock);
-   } while (rtas_busy_delay(rc));
+   err = papr_sysparm_get(PAPR_SYSPARM_LPAR_NAME, buf);
+   if (!err)
+   seq_printf(m, "partition_name=%s\n", buf->val);
 
-   if (!rc) {
-   /* Force end of string */
-   len = min((int) be16_to_cpu(local_buffer->len),
- (int) sizeof(local_buffer->name)-1);
-   local_buffer->name[len] = '\0';
-
-   seq_printf(m, "partition_name=%s\n", local_buffer->name);
-   } else
-   rc = -ENODATA;
-
-   kfree(local_buffer);
-   return rc;
+   papr_sysparm_buf_free(buf);
+   return err;
 }
 
 /*
@@ -397,7 +361,6 @@ static void read_lpar_name(struct seq_file *m)
pr_err_once("Error can't get the LPAR name");
 }
 
-#define SPLPAR_CHARACTERISTICS_TOKEN 20
 #define SPLPAR_MAXLENGTH 1026*(sizeof(char))
 
 /*
@@ -408,45 +371,25 @@ static void read_lpar_name(struct seq_file *m)
  */
 static void parse_system_parameter_string(struct seq_file *m)
 {
-   const s32 token = rtas_token("ibm,get-system-parameter");
-   int call_status;
+   struct papr_sysparm_buf *buf;
 
-   unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
-   if (!local_buffer) {
-   printk(KERN_ERR "%s %s kmalloc failure at line %d\n",
-  __FILE__, __func__, __LINE__);
+   buf = papr_sysparm_buf_alloc();
+   if (!buf)
return;
-   }
 
-   do {
-   spin_lock(_data_buf_lock);
-   memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
-   call_status = rtas_call(token, 3, 1, NULL, 
SPLPAR_CHARACTERISTICS_TOKEN,
-   __pa(rtas_data_buf), 
RTAS_DATA_BUF_SIZE);
-   memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
-   local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
-   spin_unlock(_data_buf_lock);
-   } while (rtas_busy_delay(call_status));
-
-   if (call_status != 0) {
-   printk(KERN_INFO
-  "%s %s Error calling get-system-parameter (0x%x)\n",
-  __FILE__, __func__, call_status);
+   if 

[PATCH v3 06/20] powerpc/rtas: ensure 4KB alignment for rtas_data_buf

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Some RTAS functions that have work area parameters impose alignment
requirements on the work area passed to them by the OS. Examples
include:

- ibm,configure-connector
- ibm,update-nodes
- ibm,update-properties

4KB is the greatest alignment required by PAPR for such
buffers. rtas_data_buf used to have a __page_aligned attribute in the
arch/ppc64 days, but that was changed to __cacheline_aligned for
unknown reasons by commit 033ef338b6e0 ("powerpc: Merge rtas.c into
arch/powerpc/kernel"). That works out to 128-byte alignment
on ppc64, which isn't right.

This was found by inspection and I'm not aware of any real problems
caused by this. Either current RTAS implementations don't enforce the
alignment constraints, or rtas_data_buf is always being placed at a
4KB boundary by accident (or both, perhaps).

Use __aligned(SZ_4K) to ensure the rtas_data_buf has alignment
appropriate for all users.

Signed-off-by: Nathan Lynch 
Fixes: 033ef338b6e0 ("powerpc: Merge rtas.c into arch/powerpc/kernel")
---
 arch/powerpc/kernel/rtas.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 86aff1cb8a0d..cce7f69b4ba1 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -75,7 +75,7 @@ static struct rtas_args rtas_args;
 DEFINE_SPINLOCK(rtas_data_buf_lock);
 EXPORT_SYMBOL_GPL(rtas_data_buf_lock);
 
-char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
+char rtas_data_buf[RTAS_DATA_BUF_SIZE] __aligned(SZ_4K);
 EXPORT_SYMBOL_GPL(rtas_data_buf);
 
 unsigned long rtas_rmo_buf;

-- 
2.39.1



[PATCH v3 05/20] powerpc/pseries/setup: add missing RTAS retry status handling

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

The ibm,get-system-parameter RTAS function may return -2 or 990x,
which indicate that the caller should try again.

pSeries_cmo_feature_init() ignores this, making it possible to fail to
detect cooperative memory overcommit capabilities during boot.

Move the RTAS call into a conventional rtas_busy_delay()-based
loop, dropping unnecessary clearing of rtas_data_buf.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/platforms/pseries/setup.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/setup.c 
b/arch/powerpc/platforms/pseries/setup.c
index 8ef3270515a9..74e50b6b28d4 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -941,21 +941,25 @@ void pSeries_coalesce_init(void)
  */
 static void __init pSeries_cmo_feature_init(void)
 {
+   const s32 token = rtas_token("ibm,get-system-parameter");
char *ptr, *key, *value, *end;
int call_status;
int page_order = IOMMU_PAGE_SHIFT_4K;
 
pr_debug(" -> fw_cmo_feature_init()\n");
-   spin_lock(_data_buf_lock);
-   memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
-   call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
-   NULL,
-   CMO_CHARACTERISTICS_TOKEN,
-   __pa(rtas_data_buf),
-   RTAS_DATA_BUF_SIZE);
 
-   if (call_status != 0) {
+   do {
+   spin_lock(_data_buf_lock);
+   call_status = rtas_call(token, 3, 1, NULL,
+   CMO_CHARACTERISTICS_TOKEN,
+   __pa(rtas_data_buf),
+   RTAS_DATA_BUF_SIZE);
+   if (call_status == 0)
+   break;
spin_unlock(_data_buf_lock);
+   } while (rtas_busy_delay(call_status));
+
+   if (call_status != 0) {
pr_debug("CMO not available\n");
pr_debug(" <- fw_cmo_feature_init()\n");
return;

-- 
2.39.1



[PATCH v3 07/20] powerpc/pseries: drop RTAS-based timebase synchronization

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

The pseries platform has been LPAR-only for several generations, and
the PAPR spec:

* Guarantees that timebase synchronization is performed by
  the platform ("The timebase registers are synchronized by the
  platform before CPUs are given to the OS" - 7.3.8 SMP Support).

* Completely omits the RTAS freeze-time-base and thaw-time-base RTAS
  functions, which are CHRP artifacts.

This code is effectively unused on currently supported models, so drop
it.

Signed-off-by: Nathan Lynch 
---
 arch/powerpc/platforms/pseries/smp.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/smp.c 
b/arch/powerpc/platforms/pseries/smp.c
index fd2174edfa1d..2bcfee86ff87 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -278,11 +278,5 @@ void __init smp_init_pseries(void)
cpumask_clear_cpu(boot_cpuid, of_spin_mask);
}
 
-   /* Non-lpar has additional take/give timebase */
-   if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
-   smp_ops->give_timebase = rtas_give_timebase;
-   smp_ops->take_timebase = rtas_take_timebase;
-   }
-
pr_debug(" <- smp_init_pSeries()\n");
 }

-- 
2.39.1



[PATCH v3 02/20] powerpc/perf/hv-24x7: add missing RTAS retry status handling

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

The ibm,get-system-parameter RTAS function may return -2 or 990x,
which indicate that the caller should try again. read_24x7_sys_info()
ignores this, allowing transient failures in reporting processor
module information.

Move the RTAS call into a coventional rtas_busy_delay()-based loop,
along with the parsing of results on success.

Signed-off-by: Nathan Lynch 
Fixes: 8ba214267382 ("powerpc/hv-24x7: Add rtas call in hv-24x7 driver to get 
processor details")
---
 arch/powerpc/perf/hv-24x7.c | 42 ++
 1 file changed, 18 insertions(+), 24 deletions(-)

diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
index 33c23225fd54..fcfebf5bd378 100644
--- a/arch/powerpc/perf/hv-24x7.c
+++ b/arch/powerpc/perf/hv-24x7.c
@@ -79,9 +79,8 @@ static u32 phys_coresperchip; /* Physical cores per chip */
  */
 void read_24x7_sys_info(void)
 {
-   int call_status, len, ntypes;
-
-   spin_lock(_data_buf_lock);
+   const s32 token = rtas_token("ibm,get-system-parameter");
+   int call_status;
 
/*
 * Making system parameter: chips and sockets and cores per chip
@@ -91,32 +90,27 @@ void read_24x7_sys_info(void)
phys_chipspersocket = 1;
phys_coresperchip = 1;
 
-   call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
-   NULL,
-   PROCESSOR_MODULE_INFO,
-   __pa(rtas_data_buf),
-   RTAS_DATA_BUF_SIZE);
+   do {
+   spin_lock(_data_buf_lock);
+   call_status = rtas_call(token, 3, 1, NULL, 
PROCESSOR_MODULE_INFO,
+   __pa(rtas_data_buf), 
RTAS_DATA_BUF_SIZE);
+   if (call_status == 0) {
+   int ntypes = be16_to_cpup((__be16 *)_data_buf[2]);
+   int len = be16_to_cpup((__be16 *)_data_buf[0]);
+
+   if (len >= 8 && ntypes != 0) {
+   phys_sockets = be16_to_cpup((__be16 
*)_data_buf[4]);
+   phys_chipspersocket = be16_to_cpup((__be16 
*)_data_buf[6]);
+   phys_coresperchip = be16_to_cpup((__be16 
*)_data_buf[8]);
+   }
+   }
+   spin_unlock(_data_buf_lock);
+   } while (rtas_busy_delay(call_status));
 
if (call_status != 0) {
pr_err("Error calling get-system-parameter %d\n",
   call_status);
-   } else {
-   len = be16_to_cpup((__be16 *)_data_buf[0]);
-   if (len < 8)
-   goto out;
-
-   ntypes = be16_to_cpup((__be16 *)_data_buf[2]);
-
-   if (!ntypes)
-   goto out;
-
-   phys_sockets = be16_to_cpup((__be16 *)_data_buf[4]);
-   phys_chipspersocket = be16_to_cpup((__be16 *)_data_buf[6]);
-   phys_coresperchip = be16_to_cpup((__be16 *)_data_buf[8]);
}
-
-out:
-   spin_unlock(_data_buf_lock);
 }
 
 /* Domains for which more than one result element are returned for each event. 
*/

-- 
2.39.1



[PATCH v3 01/20] powerpc/rtas: handle extended delays safely in early boot

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

Some code that runs early in boot calls RTAS functions that can return
-2 or 990x statuses, which mean the caller should retry. An example is
pSeries_cmo_feature_init(), which invokes ibm,get-system-parameter but
treats these benign statuses as errors instead of retrying.

pSeries_cmo_feature_init() and similar code should be made to retry
until they succeed or receive a real error, using the usual pattern:

do {
rc = rtas_call(token, etc...);
} while (rtas_busy_delay(rc));

But rtas_busy_delay() will perform a timed sleep on any 990x
status. This isn't safe so early in boot, before the CPU scheduler and
timer subsystem have initialized.

The -2 RTAS status is much more likely to occur during single-threaded
boot than 990x in practice, at least on PowerVM. This is because -2
usually means that RTAS made progress but exhausted its self-imposed
timeslice, while 990x is associated with concurrent requests from the
OS causing internal contention. Regardless, according to the language
in PAPR, the OS should be prepared to handle either type of status at
any time.

Add a fallback path to rtas_busy_delay() to handle this as safely as
possible, performing a small delay on 990x. Include a counter to
detect retry loops that aren't making progress and bail out. Add __ref
to rtas_busy_delay() since it now conditionally calls an __init
function.

This was found by inspection and I'm not aware of any real
failures. However, the implementation of rtas_busy_delay() before
commit 38f7b7067dae ("powerpc/rtas: rtas_busy_delay() improvements")
was not susceptible to this problem, so let's treat this as a
regression.

Signed-off-by: Nathan Lynch 
Fixes: 38f7b7067dae ("powerpc/rtas: rtas_busy_delay() improvements")
---
 arch/powerpc/kernel/rtas.c | 49 +-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 795225d7f138..86aff1cb8a0d 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -606,6 +606,47 @@ unsigned int rtas_busy_delay_time(int status)
return ms;
 }
 
+/*
+ * Early boot fallback for rtas_busy_delay().
+ */
+static bool __init rtas_busy_delay_early(int status)
+{
+   static size_t successive_ext_delays __initdata;
+   bool retry;
+
+   switch (status) {
+   case RTAS_EXTENDED_DELAY_MIN...RTAS_EXTENDED_DELAY_MAX:
+   /*
+* In the unlikely case that we receive an extended
+* delay status in early boot, the OS is probably not
+* the cause, and there's nothing we can do to clear
+* the condition. Best we can do is delay for a bit
+* and hope it's transient. Lie to the caller if it
+* seems like we're stuck in a retry loop.
+*/
+   mdelay(1);
+   retry = true;
+   successive_ext_delays += 1;
+   if (successive_ext_delays > 1000) {
+   pr_err("too many extended delays, giving up\n");
+   dump_stack();
+   retry = false;
+   successive_ext_delays = 0;
+   }
+   break;
+   case RTAS_BUSY:
+   retry = true;
+   successive_ext_delays = 0;
+   break;
+   default:
+   retry = false;
+   successive_ext_delays = 0;
+   break;
+   }
+
+   return retry;
+}
+
 /**
  * rtas_busy_delay() - helper for RTAS busy and extended delay statuses
  *
@@ -624,11 +665,17 @@ unsigned int rtas_busy_delay_time(int status)
  * * false - @status is not @RTAS_BUSY nor an extended delay hint. The
  *   caller is responsible for handling @status.
  */
-bool rtas_busy_delay(int status)
+bool __ref rtas_busy_delay(int status)
 {
unsigned int ms;
bool ret;
 
+   /*
+* Can't do timed sleeps before timekeeping is up.
+*/
+   if (system_state < SYSTEM_SCHEDULING)
+   return rtas_busy_delay_early(status);
+
switch (status) {
case RTAS_EXTENDED_DELAY_MIN...RTAS_EXTENDED_DELAY_MAX:
ret = true;

-- 
2.39.1



[PATCH v3 03/20] powerpc/pseries/lpar: add missing RTAS retry status handling

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

The ibm,get-system-parameter RTAS function may return -2 or 990x,
which indicate that the caller should try again.

pseries_lpar_read_hblkrm_characteristics() ignores this, making it
possible to incorrectly detect TLB block invalidation characteristics
at boot.

Move the RTAS call into a coventional rtas_busy_delay()-based loop.

Signed-off-by: Nathan Lynch 
Fixes: 1211ee61b4a8 ("powerpc/pseries: Read TLB Block Invalidate 
Characteristics")
---
 arch/powerpc/platforms/pseries/lpar.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/lpar.c 
b/arch/powerpc/platforms/pseries/lpar.c
index 97ef6499e501..6597b2126ebb 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -1481,22 +1481,22 @@ static inline void __init check_lp_set_hblkrm(unsigned 
int lp,
 
 void __init pseries_lpar_read_hblkrm_characteristics(void)
 {
+   const s32 token = rtas_token("ibm,get-system-parameter");
unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH];
int call_status, len, idx, bpsize;
 
if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE))
return;
 
-   spin_lock(_data_buf_lock);
-   memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
-   call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
-   NULL,
-   SPLPAR_TLB_BIC_TOKEN,
-   __pa(rtas_data_buf),
-   RTAS_DATA_BUF_SIZE);
-   memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH);
-   local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0';
-   spin_unlock(_data_buf_lock);
+   do {
+   spin_lock(_data_buf_lock);
+   memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
+   call_status = rtas_call(token, 3, 1, NULL, SPLPAR_TLB_BIC_TOKEN,
+   __pa(rtas_data_buf), 
RTAS_DATA_BUF_SIZE);
+   memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH);
+   local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0';
+   spin_unlock(_data_buf_lock);
+   } while (rtas_busy_delay(call_status));
 
if (call_status != 0) {
pr_warn("%s %s Error calling get-system-parameter (0x%x)\n",

-- 
2.39.1



[PATCH v3 04/20] powerpc/pseries/lparcfg: add missing RTAS retry status handling

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
From: Nathan Lynch 

The ibm,get-system-parameter RTAS function may return -2 or 990x,
which indicate that the caller should try again.

lparcfg's parse_system_parameter_string() ignores this, making it
possible to intermittently report incorrect SPLPAR characteristics.

Move the RTAS call into a coventional rtas_busy_delay()-based loop.

Signed-off-by: Nathan Lynch 
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 arch/powerpc/platforms/pseries/lparcfg.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/lparcfg.c 
b/arch/powerpc/platforms/pseries/lparcfg.c
index 63fd925ccbb8..cd33d5800763 100644
--- a/arch/powerpc/platforms/pseries/lparcfg.c
+++ b/arch/powerpc/platforms/pseries/lparcfg.c
@@ -408,6 +408,7 @@ static void read_lpar_name(struct seq_file *m)
  */
 static void parse_system_parameter_string(struct seq_file *m)
 {
+   const s32 token = rtas_token("ibm,get-system-parameter");
int call_status;
 
unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
@@ -417,16 +418,15 @@ static void parse_system_parameter_string(struct seq_file 
*m)
return;
}
 
-   spin_lock(_data_buf_lock);
-   memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
-   call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
-   NULL,
-   SPLPAR_CHARACTERISTICS_TOKEN,
-   __pa(rtas_data_buf),
-   RTAS_DATA_BUF_SIZE);
-   memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
-   local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
-   spin_unlock(_data_buf_lock);
+   do {
+   spin_lock(_data_buf_lock);
+   memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
+   call_status = rtas_call(token, 3, 1, NULL, 
SPLPAR_CHARACTERISTICS_TOKEN,
+   __pa(rtas_data_buf), 
RTAS_DATA_BUF_SIZE);
+   memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
+   local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
+   spin_unlock(_data_buf_lock);
+   } while (rtas_busy_delay(call_status));
 
if (call_status != 0) {
printk(KERN_INFO

-- 
2.39.1



[PATCH v3 00/20] RTAS maintenance

2023-02-10 Thread Nathan Lynch via B4 Submission Endpoint
Proposed changes for the RTAS subsystem and client code.

Fixes that are subject to backporting are at the front of the queue.
The rest of the queue is roughly ordered with respect to maturity:
i.e. patches that have already garnered some review and discussion
precede newer, more experimental changes.

Major features:

* Static tracepoints around RTAS entry/exit.
* An allocator for work area buffers.
* A new client of the work area allocator in the form of a
  higher-level API for PAPR system parameter retrieval.
* Constant-time symbolic RTAS function token lookups.

Tested with ppc64le in PowerVM LPARs and QEMU's pseries
model. Obsolescent RTAS platforms (chrp, cell, maple) get build
coverage.

---
Changes in v3:

* Additions:
  - Ensure 4KB alignment for rtas_data_buf.

* Modifications to existing patches (all per Michael Ellerman)
  - Rename "ret" to "retry" in rtas_busy_delay_early().
  - Reset the stuck counter when rtas_busy_delay_early() warns.
  - Explain addition of __ref to rtas_busy_delay().
  - Spell out function index constants instead of cpp-pasting.
  - Use more conventional header inclusion guards in new heaaders.
  - Align early_work_area_buf.
  - Prevent bad arguments to rtas_work_area_alloc() with a
compile-time assertion.
  - Discard pr_devel() from rtas-work-area.c.
  - Access work area allocator state through a single struct instead
of a pointer indirection.
  - Initialize work area descriptors more conventionally.
  - Ensure rtas_function_token() returns RTAS_UNKNOWN_SERVICE on
non-RTAS platforms.
  - Move rtas-work-area.c to platforms/pseries/ and initialize it on
pseries only.
* Link to v2: 
https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v2-0-9aa6bd058...@linux.ibm.com

Changes in v2:

* Drop applied patches:
  - powerpc/rtas: document rtas_call()
  - powerpc/rtasd: use correct OF API for event scan rate
  - powerpc/rtas: avoid device tree lookups in rtas_os_term()
  - powerpc/rtas: avoid scheduling in rtas_os_term()
  - powerpc/pseries/eeh: use correct API for error log size
  - powerpc/rtas: clean up rtas_error_log_max initialization
  - powerpc/rtas: clean up includes
  - powerpc/rtas: define pr_fmt and convert printk call sites
  - powerpc/rtas: mandate RTAS syscall filtering

* Additions:
  - Safe early-boot fallback in rtas_busy_delay().
  - Fixes for missed RTAS function call retries in various places.
  - Remove RTAS timebase sync from pseries, previously posted
separately as "powerpc/pseries: drop RTAS-based timebase
synchronization":

https://lore.kernel.org/linuxppc-dev/20230110042845.121792-1-nath...@linux.ibm.com/T/#u
  - RTAS work area buffer allocator.
  - Conversion of pseries DLPAR code to work area allocator.
  - A pseries-specific PAPR system parameter API built on top of the
RTAS work area allocator.
  - Conversion of ibm,get-system-parameter users to papr_sysparm API.
  - New rtas_function_token() API and associated conversions.

* Modifications to existing patches:
  - Convert RTAS tracepoint definitions to unconditional
variants (TRACE_EVENT_CONDITION() -> TRACE_EVENT()), dropping a
cpu_online() check that duplicates work already done at the call
site.
  - Skip tracepoints in unsafe contexts (real mode, CPU
offline). (Nicholas Piggin)
  - Use bool bitfield for "banned on LE" function flag.
  - Better documentation for "banned on LE" function flag. (Andrew Donnellan)
  - Drop unnecessary cast for xa_load() key argument. (Nick Child)

* Link to v1: 
https://lore.kernel.org/r/20221118150751.469393-1-nath...@linux.ibm.com

---
Nathan Lynch (20):
  powerpc/rtas: handle extended delays safely in early boot
  powerpc/perf/hv-24x7: add missing RTAS retry status handling
  powerpc/pseries/lpar: add missing RTAS retry status handling
  powerpc/pseries/lparcfg: add missing RTAS retry status handling
  powerpc/pseries/setup: add missing RTAS retry status handling
  powerpc/rtas: ensure 4KB alignment for rtas_data_buf
  powerpc/pseries: drop RTAS-based timebase synchronization
  powerpc/rtas: improve function information lookups
  powerpc/rtas: strengthen do_enter_rtas() type safety, drop inline
  powerpc/tracing: tracepoints for RTAS entry and exit
  powerpc/rtas: add tracepoints around RTAS entry
  powerpc/pseries: add RTAS work area allocator
  powerpc/pseries/dlpar: use RTAS work area API
  powerpc/pseries: PAPR system parameter API
  powerpc/pseries: convert CMO probe to papr_sysparm API
  powerpc/pseries/lparcfg: convert to papr_sysparm API
  powerpc/pseries/hv-24x7: convert to papr_sysparm API
  powerpc/pseries/lpar: convert to papr_sysparm API
  powerpc/rtas: introduce rtas_function_token() API
  powerpc/rtas: arch-wide function token lookup conversions

 arch/powerpc/include/asm/papr-sysparm.h |  38 +
 arch/powerpc/include/asm/rtas-work-area.h   |  96 +++
 arch/powerpc/include/asm/rtas.h | 184 +

Re: [External] : [PATCH v3 1/1] PCI: layerscape: Add EP mode support for ls1028a

2023-02-10 Thread ALOK TIWARI

LGTM,


Thanks,

Alok

On 2/9/2023 8:40 PM, Frank Li wrote:

From: Xiaowei Bao 

Add PCIe EP mode support for ls1028a.

Signed-off-by: Xiaowei Bao 
Signed-off-by: Hou Zhiqiang 
Signed-off-by: Frank Li 
Acked-by:  Roy Zang 
---

Change from v2 to v3
order by .compatible

Change from v2 to v2
Added
Signed-off-by: Frank Li 
Acked-by:  Roy Zang 


All other patches were already accepte by maintainer in
https://urldefense.com/v3/__https://lore.kernel.org/lkml/2022223457.10599-1-leoyang...@nxp.com/__;!!ACWV5N9M2RV99hQ!NR9EU4fPDwxdyrb9tdBm9VNIMHSlw6dLgXCAPDSrm7ftWVNrh6JldLGzzrKyiE0xRlP5OdiGBN7PCf9gRaA$

But missed this one.

Re-post

  drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c 
b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index ad99707b3b99..c640db60edc6 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -110,6 +110,7 @@ static const struct ls_pcie_ep_drvdata lx2_ep_drvdata = {
  };
  
  static const struct of_device_id ls_pcie_ep_of_match[] = {

+   { .compatible = "fsl,ls1028a-pcie-ep", .data = _ep_drvdata },
{ .compatible = "fsl,ls1046a-pcie-ep", .data = _ep_drvdata },
{ .compatible = "fsl,ls1088a-pcie-ep", .data = _ep_drvdata },
{ .compatible = "fsl,ls2088a-pcie-ep", .data = _ep_drvdata },


Re: [PATCH AUTOSEL 6.1 18/38] powerpc/kvm: Fix unannotated intra-function call warning

2023-02-10 Thread Sathvika Vasireddy

Hi Sasha,

On 09/02/23 16:44, Sasha Levin wrote:

From: Sathvika Vasireddy 

[ Upstream commit fe6de81b610e5d0b9d2231acff2de74a35482e7d ]

objtool throws the following warning:
   arch/powerpc/kvm/booke.o: warning: objtool: kvmppc_fill_pt_regs+0x30:
   unannotated intra-function call

Fix the warning by setting the value of 'nip' using the _THIS_IP_ macro,
without using an assembly bl/mflr sequence to save the instruction
pointer.

Reported-by: kernel test robot 
Suggested-by: Michael Ellerman 
Signed-off-by: Sathvika Vasireddy 
Signed-off-by: Michael Ellerman 
Link: https://lore.kernel.org/r/20230128124158.1066251-1...@linux.ibm.com
Signed-off-by: Sasha Levin 
---
  arch/powerpc/kvm/booke.c | 5 ++---
  1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 7b4920e9fd263..3852209989f04 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -912,16 +912,15 @@ static int kvmppc_handle_debug(struct kvm_vcpu *vcpu)
  
  static void kvmppc_fill_pt_regs(struct pt_regs *regs)

  {
-   ulong r1, ip, msr, lr;
+   ulong r1, msr, lr;
  
  	asm("mr %0, 1" : "=r"(r1));

asm("mflr %0" : "=r"(lr));
asm("mfmsr %0" : "=r"(msr));
-   asm("bl 1f; 1: mflr %0" : "=r"(ip));
  
  	memset(regs, 0, sizeof(*regs));

regs->gpr[1] = r1;
-   regs->nip = ip;
+   regs->nip = _THIS_IP_;
regs->msr = msr;
regs->link = lr;
  }


Please drop this patch because objtool enablement patches for powerpc 
are not a part of kernel v6.1



Thanks,
Sathvika



Re: [PATCH AUTOSEL 6.1 17/38] powerpc/85xx: Fix unannotated intra-function call warning

2023-02-10 Thread Sathvika Vasireddy

Hi Sasha,

On 09/02/23 16:44, Sasha Levin wrote:

From: Sathvika Vasireddy 

[ Upstream commit 8afffce6aa3bddc940ac1909627ff1e772b6cbf1 ]

objtool throws the following warning:
   arch/powerpc/kernel/head_85xx.o: warning: objtool: .head.text+0x1a6c:
   unannotated intra-function call

Fix the warning by annotating KernelSPE symbol with SYM_FUNC_START_LOCAL
and SYM_FUNC_END macros.

Reported-by: kernel test robot 
Signed-off-by: Sathvika Vasireddy 
Signed-off-by: Michael Ellerman 
Link: https://lore.kernel.org/r/20230128124138.1066176-1...@linux.ibm.com
Signed-off-by: Sasha Levin 
---
  arch/powerpc/kernel/head_85xx.S | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/head_85xx.S b/arch/powerpc/kernel/head_85xx.S
index 52c0ab416326a..d3939849f4550 100644
--- a/arch/powerpc/kernel/head_85xx.S
+++ b/arch/powerpc/kernel/head_85xx.S
@@ -862,7 +862,7 @@ _GLOBAL(load_up_spe)
   * SPE unavailable trap from kernel - print a message, but let
   * the task use SPE in the kernel until it returns to user mode.
   */
-KernelSPE:
+SYM_FUNC_START_LOCAL(KernelSPE)
lwz r3,_MSR(r1)
orisr3,r3,MSR_SPE@h
stw r3,_MSR(r1) /* enable use of SPE after return */
@@ -879,6 +879,7 @@ KernelSPE:
  #endif
.align  4,0
  
+SYM_FUNC_END(KernelSPE)

  #endif /* CONFIG_SPE */
  
  /*


Please drop this patch because objtool enablement patches for powerpc 
are not a part of kernel v6.1.


Thanks,
Sathvika


[PATCH v6 20/26] powerpc/pseries: Turn PSERIES_PLPKS into a hidden option

2023-02-10 Thread Andrew Donnellan
It seems a bit unnecessary for the PLPKS code to have a user-visible
config option when it doesn't do anything on its own, and there's existing
options for enabling Secure Boot-related features.

It should be enabled by PPC_SECURE_BOOT, which will eventually be what
uses PLPKS to populate keyrings.

However, we can't get of the separate option completely, because it will
also be used for SED Opal purposes.

Change PSERIES_PLPKS into a hidden option, which is selected by
PPC_SECURE_BOOT.

Signed-off-by: Andrew Donnellan 
Signed-off-by: Russell Currey 
Reviewed-by: Stefan Berger 

---

v3: New patch

v5: Change the previous description into a comment (npiggin)
---
 arch/powerpc/Kconfig   |  1 +
 arch/powerpc/platforms/pseries/Kconfig | 19 +--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b8c4ac56bddc..d4ed46101bec 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -1029,6 +1029,7 @@ config PPC_SECURE_BOOT
depends on PPC_POWERNV || PPC_PSERIES
depends on IMA_ARCH_POLICY
imply IMA_SECURE_AND_OR_TRUSTED_BOOT
+   select PSERIES_PLPKS if PPC_PSERIES
help
  Systems with firmware secure boot enabled need to define security
  policies to extend secure boot to the OS. This config allows a user
diff --git a/arch/powerpc/platforms/pseries/Kconfig 
b/arch/powerpc/platforms/pseries/Kconfig
index a3b4d99567cb..e51d65969318 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -151,16 +151,15 @@ config IBMEBUS
 
 config PSERIES_PLPKS
depends on PPC_PSERIES
-   bool "Support for the Platform Key Storage"
-   help
- PowerVM provides an isolated Platform Keystore(PKS) storage
- allocation for each LPAR with individually managed access
- controls to store sensitive information securely. It can be
- used to store asymmetric public keys or secrets as required
- by different usecases. Select this config to enable
- operating system interface to hypervisor to access this space.
-
- If unsure, select N.
+   bool
+   # PowerVM provides an isolated Platform Keystore (PKS) storage
+   # allocation for each LPAR with individually managed access
+   # controls to store sensitive information securely. It can be
+   # used to store asymmetric public keys or secrets as required
+   # by different usecases.
+   #
+   # This option is selected by in-kernel consumers that require
+   # access to the PKS.
 
 config PAPR_SCM
depends on PPC_PSERIES && MEMORY_HOTPLUG && LIBNVDIMM
-- 
2.39.1



[PATCH v6 01/26] powerpc/pseries: Fix handling of PLPKS object flushing timeout

2023-02-10 Thread Andrew Donnellan
plpks_confirm_object_flushed() uses the H_PKS_CONFIRM_OBJECT_FLUSHED hcall
to check whether changes to an object in the Platform KeyStore have been
flushed to non-volatile storage.

The hcall returns two output values, the return code and the flush status.
plpks_confirm_object_flushed() polls the hcall until either the flush
status has updated, the return code is an error, or a timeout has been
exceeded.

While we're still polling, the hcall is returning H_SUCCESS (0) as the
return code. In the timeout case, this means that upon exiting the polling
loop, rc is 0, and therefore 0 is returned to the user.

Handle the timeout case separately and return ETIMEDOUT if triggered.

Fixes: 2454a7af0f2a ("powerpc/pseries: define driver for Platform KeyStore")
Reported-by: Benjamin Gray 
Signed-off-by: Andrew Donnellan 
Tested-by: Russell Currey 
Reviewed-by: Russell Currey 
Signed-off-by: Russell Currey 

---

v3: Merge plpks fixes and signed update series with secvar series

Neaten how we return at the end of the function (ruscur)

v4: Move up in series (npiggin)
---
 arch/powerpc/platforms/pseries/plpks.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index 4edd1585e245..9e85b6d85b0b 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -248,6 +248,7 @@ static int plpks_confirm_object_flushed(struct label *label,
struct plpks_auth *auth)
 {
unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
+   bool timed_out = true;
u64 timeout = 0;
u8 status;
int rc;
@@ -259,22 +260,26 @@ static int plpks_confirm_object_flushed(struct label 
*label,
 
status = retbuf[0];
if (rc) {
+   timed_out = false;
if (rc == H_NOT_FOUND && status == 1)
rc = 0;
break;
}
 
-   if (!rc && status == 1)
+   if (!rc && status == 1) {
+   timed_out = false;
break;
+   }
 
usleep_range(PKS_FLUSH_SLEEP,
 PKS_FLUSH_SLEEP + PKS_FLUSH_SLEEP_RANGE);
timeout = timeout + PKS_FLUSH_SLEEP;
} while (timeout < PKS_FLUSH_MAX_TIMEOUT);
 
-   rc = pseries_status_to_err(rc);
+   if (timed_out)
+   return -ETIMEDOUT;
 
-   return rc;
+   return pseries_status_to_err(rc);
 }
 
 int plpks_write_var(struct plpks_var var)
-- 
2.39.1



[PATCH v6 14/26] powerpc/pseries: Move plpks.h to include directory

2023-02-10 Thread Andrew Donnellan
From: Russell Currey 

Move plpks.h from platforms/pseries/ to include/asm/. This is necessary
for later patches to make use of the PLPKS from code in other subsystems.

Signed-off-by: Russell Currey 
Signed-off-by: Andrew Donnellan 
Reviewed-by: Stefan Berger 

---

v3: New patch
---
 .../powerpc/{platforms/pseries => include/asm}/plpks.h | 10 +++---
 arch/powerpc/platforms/pseries/plpks.c |  3 +--
 2 files changed, 8 insertions(+), 5 deletions(-)
 rename arch/powerpc/{platforms/pseries => include/asm}/plpks.h (89%)

diff --git a/arch/powerpc/platforms/pseries/plpks.h 
b/arch/powerpc/include/asm/plpks.h
similarity index 89%
rename from arch/powerpc/platforms/pseries/plpks.h
rename to arch/powerpc/include/asm/plpks.h
index 275ccd86bfb5..8295502ee93b 100644
--- a/arch/powerpc/platforms/pseries/plpks.h
+++ b/arch/powerpc/include/asm/plpks.h
@@ -6,8 +6,10 @@
  * Platform keystore for pseries LPAR(PLPKS).
  */
 
-#ifndef _PSERIES_PLPKS_H
-#define _PSERIES_PLPKS_H
+#ifndef _ASM_POWERPC_PLPKS_H
+#define _ASM_POWERPC_PLPKS_H
+
+#ifdef CONFIG_PSERIES_PLPKS
 
 #include 
 #include 
@@ -68,4 +70,6 @@ int plpks_read_fw_var(struct plpks_var *var);
  */
 int plpks_read_bootloader_var(struct plpks_var *var);
 
-#endif
+#endif // CONFIG_PSERIES_PLPKS
+
+#endif // _ASM_POWERPC_PLPKS_H
diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index a01cf2ff140a..13e6daadb179 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -18,8 +18,7 @@
 #include 
 #include 
 #include 
-
-#include "plpks.h"
+#include 
 
 #define PKS_FW_OWNER0x1
 #define PKS_BOOTLOADER_OWNER 0x2
-- 
2.39.1



[PATCH v6 24/26] powerpc/pseries: Implement secvars for dynamic secure boot

2023-02-10 Thread Andrew Donnellan
From: Russell Currey 

The pseries platform can support dynamic secure boot (i.e. secure boot
using user-defined keys) using variables contained with the PowerVM LPAR
Platform KeyStore (PLPKS).  Using the powerpc secvar API, expose the
relevant variables for pseries dynamic secure boot through the existing
secvar filesystem layout.

The relevant variables for dynamic secure boot are signed in the
keystore, and can only be modified using the H_PKS_SIGNED_UPDATE hcall.
Object labels in the keystore are encoded using ucs2 format.  With our
fixed variable names we don't have to care about encoding outside of the
necessary byte padding.

When a user writes to a variable, the first 8 bytes of data must contain
the signed update flags as defined by the hypervisor.

When a user reads a variable, the first 4 bytes of data contain the
policies defined for the object.

Limitations exist due to the underlying implementation of sysfs binary
attributes, as is the case for the OPAL secvar implementation -
partial writes are unsupported and writes cannot be larger than PAGE_SIZE.
(Even when using bin_attributes, which can be larger than a single page,
sysfs only gives us one page's worth of write buffer at a time, and the
hypervisor does not expose an interface for partial writes.)

Co-developed-by: Nayna Jain 
Signed-off-by: Nayna Jain 
Co-developed-by: Andrew Donnellan 
Signed-off-by: Andrew Donnellan 
Signed-off-by: Russell Currey 

---

v2: Remove unnecessary config vars from sysfs and document the others,
thanks to review from Greg.  If we end up needing to expose more, we
can add them later and update the docs.

Use sysfs_emit() instead of sprintf(), thanks to Greg.

Change the size of the sysfs binary attributes to include the 8-byte
flags header, preventing truncation of large writes.

v3: plpks_set_variable(): pass var to plpks_signed_update_var() as a
pointer (mpe)

Update copyright date (ajd)

Consistent comment style (ajd)

Change device_initcall() to machine_arch_initcall(pseries...) so we
don't try to load on powernv and kill the machine (mpe)

Add config attributes into plpks_secvar_ops (mpe)

Get rid of PLPKS_SECVAR_COUNT macro (mpe)

Reworded descriptions in ABI documentation (mpe)

Switch to using secvar_ops->var_names rather than
secvar_ops->get_next() (ajd/mpe)

Optimise allocation/copying of buffers (mpe)

Elaborate the comment documenting the "format" string (mpe)

Return -EIO on errors in the read case (mpe)

Add "grubdbx" variable (Sudhakar Kuppusamy)

Use utf8s_to_utf16s() rather than our own "UCS-2" conversion code (mpe)

Change uint64_t to u64 (mpe)

Fix SB_VERSION data length (ruscur)

Stop prepending policy data on read (ruscur)

Enforce max format length on format string (not strictly needed, but
makes the length limit clear) (ajd)

Update include of plpks.h to reflect new path (ruscur)

Consistent constant naming scheme (ruscur)

v4: Return set_secvar_ops() return code

Pass buffer size to plpks_secvar_format() (stefanb, npiggin)

Add missing null check (stefanb)

Add comment to commit message explaining PAGE_SIZE write limit (joel)

v5: Add comment explaining why we use "key_len - 1" (npiggin)

Use strlen(var.name) instead of hardcoding 10 as length of
"SB_VERSION" (npiggin)

Improve comments about use of SB_VERSION and format string (npiggin)

Change "+ 8" to "+ sizeof(u64)" when accounting for flags size in
working out file's max size (npiggin)

Compile plpks-secvar.c based on CONFIG_PPC_SECURE_BOOT, not
CONFIG_PPC_SECVAR_SYSFS, as the secvar backend is needed for loading
keys into keyrings even if the sysfs interface is disabled (ajd)

v6: Update date in ABI docs (stefanb)

Get rid of 1 byte kzalloc (npiggin)
---
 Documentation/ABI/testing/sysfs-secvar|  75 +-
 arch/powerpc/platforms/pseries/Makefile   |   4 +-
 arch/powerpc/platforms/pseries/plpks-secvar.c | 218 ++
 3 files changed, 294 insertions(+), 3 deletions(-)
 create mode 100644 arch/powerpc/platforms/pseries/plpks-secvar.c

diff --git a/Documentation/ABI/testing/sysfs-secvar 
b/Documentation/ABI/testing/sysfs-secvar
index feebb8c57294..857cf12b0904 100644
--- a/Documentation/ABI/testing/sysfs-secvar
+++ b/Documentation/ABI/testing/sysfs-secvar
@@ -18,6 +18,14 @@ Description: A string indicating which backend is in use by 
the firmware.
This determines the format of the variable and the accepted
format of variable updates.
 
+   On powernv/OPAL, this value is provided by the OPAL firmware
+   and is expected to be "ibm,edk2-compat-v1".
+
+   On pseries/PLPKS, this is generated by the kernel based on the
+   version number in the SB_VERSION variable in the keystore, and
+   has the form "ibm,plpks-sb-v", or
+   "ibm,plpks-sb-unknown" if there 

[PATCH v6 17/26] powerpc/pseries: Implement signed update for PLPKS objects

2023-02-10 Thread Andrew Donnellan
From: Nayna Jain 

The Platform Keystore provides a signed update interface which can be used
to create, replace or append to certain variables in the PKS in a secure
fashion, with the hypervisor requiring that the update be signed using the
Platform Key.

Implement an interface to the H_PKS_SIGNED_UPDATE hcall in the plpks
driver to allow signed updates to PKS objects.

(The plpks driver doesn't need to do any cryptography or otherwise handle
the actual signed variable contents - that will be handled by userspace
tooling.)

Signed-off-by: Nayna Jain 
[ajd: split patch, add timeout handling and misc cleanups]
Co-developed-by: Andrew Donnellan 
Signed-off-by: Andrew Donnellan 
Signed-off-by: Russell Currey 
Reviewed-by: Stefan Berger 

---

v3: Merge plpks fixes and signed update series with secvar series

Fix error code handling in plpks_confirm_object_flushed() (ruscur)

Pass plpks_var struct to plpks_signed_update_var() by reference (mpe)

Consistent constant naming scheme (ruscur)

v4: Fix MAX_HCALL_OPCODE rebasing issue (npiggin)

v5: Drop the EXPORT_SYMBOL since we don't need it (npiggin)

Return an error if plpks_signed_update_var() is called with non-NULL
component (npiggin)
---
 arch/powerpc/include/asm/hvcall.h  |  1 +
 arch/powerpc/include/asm/plpks.h   |  5 ++
 arch/powerpc/platforms/pseries/plpks.c | 74 --
 3 files changed, 75 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/hvcall.h 
b/arch/powerpc/include/asm/hvcall.h
index 95fd7f9485d5..c099780385dd 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -335,6 +335,7 @@
 #define H_RPT_INVALIDATE   0x448
 #define H_SCM_FLUSH0x44C
 #define H_GET_ENERGY_SCALE_INFO0x450
+#define H_PKS_SIGNED_UPDATE0x454
 #define H_WATCHDOG 0x45C
 #define MAX_HCALL_OPCODE   H_WATCHDOG
 
diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
index 7c5f51a9af7c..e7204e6c0ca4 100644
--- a/arch/powerpc/include/asm/plpks.h
+++ b/arch/powerpc/include/asm/plpks.h
@@ -68,6 +68,11 @@ struct plpks_var_name_list {
struct plpks_var_name varlist[];
 };
 
+/**
+ * Updates the authenticated variable. It expects NULL as the component.
+ */
+int plpks_signed_update_var(struct plpks_var *var, u64 flags);
+
 /**
  * Writes the specified var and its data to PKS.
  * Any caller of PKS driver should present a valid component type for
diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index 1189246b03dc..cee06fb9a370 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -81,6 +81,12 @@ static int pseries_status_to_err(int rc)
err = -ENOENT;
break;
case H_BUSY:
+   case H_LONG_BUSY_ORDER_1_MSEC:
+   case H_LONG_BUSY_ORDER_10_MSEC:
+   case H_LONG_BUSY_ORDER_100_MSEC:
+   case H_LONG_BUSY_ORDER_1_SEC:
+   case H_LONG_BUSY_ORDER_10_SEC:
+   case H_LONG_BUSY_ORDER_100_SEC:
err = -EBUSY;
break;
case H_AUTHORITY:
@@ -184,14 +190,17 @@ static struct label *construct_label(char *component, u8 
varos, u8 *name,
 u16 namelen)
 {
struct label *label;
-   size_t slen;
+   size_t slen = 0;
 
if (!name || namelen > PLPKS_MAX_NAME_SIZE)
return ERR_PTR(-EINVAL);
 
-   slen = strlen(component);
-   if (component && slen > sizeof(label->attr.prefix))
-   return ERR_PTR(-EINVAL);
+   // Support NULL component for signed updates
+   if (component) {
+   slen = strlen(component);
+   if (slen > sizeof(label->attr.prefix))
+   return ERR_PTR(-EINVAL);
+   }
 
// The label structure must not cross a page boundary, so we align to 
the next power of 2
label = kzalloc(roundup_pow_of_two(sizeof(*label)), GFP_KERNEL);
@@ -397,6 +406,61 @@ static int plpks_confirm_object_flushed(struct label 
*label,
return pseries_status_to_err(rc);
 }
 
+int plpks_signed_update_var(struct plpks_var *var, u64 flags)
+{
+   unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
+   int rc;
+   struct label *label;
+   struct plpks_auth *auth;
+   u64 continuetoken = 0;
+   u64 timeout = 0;
+
+   if (!var->data || var->datalen <= 0 || var->namelen > 
PLPKS_MAX_NAME_SIZE)
+   return -EINVAL;
+
+   if (!(var->policy & PLPKS_SIGNEDUPDATE))
+   return -EINVAL;
+
+   // Signed updates need the component to be NULL.
+   if (var->component)
+   return -EINVAL;
+
+   auth = construct_auth(PLPKS_OS_OWNER);
+   if (IS_ERR(auth))
+   return PTR_ERR(auth);
+
+   label = construct_label(var->component, var->os, var->name, 
var->namelen);
+   if (IS_ERR(label)) {
+   rc = PTR_ERR(label);
+

[PATCH v6 26/26] integrity/powerpc: Support loading keys from PLPKS

2023-02-10 Thread Andrew Donnellan
From: Russell Currey 

Add support for loading keys from the PLPKS on pseries machines, with the
"ibm,plpks-sb-v1" format.

The object format is expected to be the same, so there shouldn't be any
functional differences between objects retrieved on powernv or pseries.

Unlike on powernv, on pseries the format string isn't contained in the
device tree. Use secvar_ops->format() to fetch the format string in a
generic manner, rather than searching the device tree ourselves.

(The current code searches the device tree for a node compatible with
"ibm,edk2-compat-v1". This patch switches to calling secvar_ops->format(),
which in the case of OPAL/powernv means opal_secvar_format(), which
searches the device tree for a node compatible with "ibm,secvar-backend"
and checks its "format" property. These are equivalent, as skiboot creates
a node with both "ibm,edk2-compat-v1" and "ibm,secvar-backend" as
compatible strings.)

Signed-off-by: Russell Currey 
Signed-off-by: Andrew Donnellan 
Reviewed-by: Stefan Berger 

---

v3: New patch

v4: Pass format buffer size (stefanb, npiggin)

v5: Use sizeof(buf) rather than stating the size twice (npiggin)

Clarify change to DT compatible strings in commit message (zohar)

Reword commit message a bit (ajd)
---
 .../integrity/platform_certs/load_powerpc.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/security/integrity/platform_certs/load_powerpc.c 
b/security/integrity/platform_certs/load_powerpc.c
index dee51606d5f4..b9de70b90826 100644
--- a/security/integrity/platform_certs/load_powerpc.c
+++ b/security/integrity/platform_certs/load_powerpc.c
@@ -10,7 +10,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include "keyring_handler.h"
@@ -59,16 +58,22 @@ static int __init load_powerpc_certs(void)
void *db = NULL, *dbx = NULL;
u64 dbsize = 0, dbxsize = 0;
int rc = 0;
-   struct device_node *node;
+   ssize_t len;
+   char buf[32];
 
if (!secvar_ops)
return -ENODEV;
 
-   /* The following only applies for the edk2-compat backend. */
-   node = of_find_compatible_node(NULL, NULL, "ibm,edk2-compat-v1");
-   if (!node)
+   len = secvar_ops->format(buf, sizeof(buf));
+   if (len <= 0)
return -ENODEV;
 
+   // Check for known secure boot implementations from OPAL or PLPKS
+   if (strcmp("ibm,edk2-compat-v1", buf) && strcmp("ibm,plpks-sb-v1", 
buf)) {
+   pr_err("Unsupported secvar implementation \"%s\", not loading 
certs\n", buf);
+   return -ENODEV;
+   }
+
/*
 * Get db, and dbx. They might not exist, so it isn't an error if we
 * can't get them.
@@ -103,8 +108,6 @@ static int __init load_powerpc_certs(void)
kfree(dbx);
}
 
-   of_node_put(node);
-
return rc;
 }
 late_initcall(load_powerpc_certs);
-- 
2.39.1



[PATCH v6 10/26] powerpc/secvar: Extend sysfs to include config vars

2023-02-10 Thread Andrew Donnellan
From: Russell Currey 

The forthcoming pseries consumer of the secvar API wants to expose a
number of config variables.  Allowing secvar implementations to provide
their own sysfs attributes makes it easy for consumers to expose what
they need to.

This is not being used by the OPAL secvar implementation at present, and
the config directory will not be created if no attributes are set.

Signed-off-by: Russell Currey 
Co-developed-by: Andrew Donnellan 
Signed-off-by: Andrew Donnellan 
Reviewed-by: Stefan Berger 

---

v3: Remove unnecessary "secvar:" prefix from error messages (ajd)

Merge config attributes into secvar_operations (mpe)
---
 arch/powerpc/include/asm/secvar.h  |  2 ++
 arch/powerpc/kernel/secvar-sysfs.c | 33 +-
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/secvar.h 
b/arch/powerpc/include/asm/secvar.h
index bf396215903d..011a53a8076c 100644
--- a/arch/powerpc/include/asm/secvar.h
+++ b/arch/powerpc/include/asm/secvar.h
@@ -10,6 +10,7 @@
 
 #include 
 #include 
+#include 
 
 extern const struct secvar_operations *secvar_ops;
 
@@ -19,6 +20,7 @@ struct secvar_operations {
int (*set)(const char *key, u64 key_len, u8 *data, u64 data_size);
ssize_t (*format)(char *buf, size_t bufsize);
int (*max_size)(u64 *max_size);
+   const struct attribute **config_attrs;
 };
 
 #ifdef CONFIG_PPC_SECURE_BOOT
diff --git a/arch/powerpc/kernel/secvar-sysfs.c 
b/arch/powerpc/kernel/secvar-sysfs.c
index 8f3deff94009..7df32be86507 100644
--- a/arch/powerpc/kernel/secvar-sysfs.c
+++ b/arch/powerpc/kernel/secvar-sysfs.c
@@ -144,6 +144,19 @@ static int update_kobj_size(void)
return 0;
 }
 
+static int secvar_sysfs_config(struct kobject *kobj)
+{
+   struct attribute_group config_group = {
+   .name = "config",
+   .attrs = (struct attribute **)secvar_ops->config_attrs,
+   };
+
+   if (secvar_ops->config_attrs)
+   return sysfs_create_group(kobj, _group);
+
+   return 0;
+}
+
 static int secvar_sysfs_load(void)
 {
struct kobject *kobj;
@@ -208,26 +221,36 @@ static int secvar_sysfs_init(void)
 
rc = sysfs_create_file(secvar_kobj, _attr.attr);
if (rc) {
-   kobject_put(secvar_kobj);
-   return -ENOMEM;
+   pr_err("Failed to create format object\n");
+   rc = -ENOMEM;
+   goto err;
}
 
secvar_kset = kset_create_and_add("vars", NULL, secvar_kobj);
if (!secvar_kset) {
pr_err("sysfs kobject registration failed\n");
-   kobject_put(secvar_kobj);
-   return -ENOMEM;
+   rc = -ENOMEM;
+   goto err;
}
 
rc = update_kobj_size();
if (rc) {
pr_err("Cannot read the size of the attribute\n");
-   return rc;
+   goto err;
+   }
+
+   rc = secvar_sysfs_config(secvar_kobj);
+   if (rc) {
+   pr_err("Failed to create config directory\n");
+   goto err;
}
 
secvar_sysfs_load();
 
return 0;
+err:
+   kobject_put(secvar_kobj);
+   return rc;
 }
 
 late_initcall(secvar_sysfs_init);
-- 
2.39.1



[PATCH v6 22/26] powerpc/pseries: Add helper to get PLPKS password length

2023-02-10 Thread Andrew Donnellan
From: Russell Currey 

Add helper function to get the PLPKS password length. This will be used
in a later patch to support passing the password between kernels over
kexec.

Signed-off-by: Russell Currey 
Signed-off-by: Andrew Donnellan 
Reviewed-by: Stefan Berger 

---

v3: New patch

v5: Drop plpks_get_password() since we no longer need to expose it.
---
 arch/powerpc/include/asm/plpks.h   | 5 +
 arch/powerpc/platforms/pseries/plpks.c | 5 +
 2 files changed, 10 insertions(+)

diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
index 0c49969b0864..757313e00521 100644
--- a/arch/powerpc/include/asm/plpks.h
+++ b/arch/powerpc/include/asm/plpks.h
@@ -171,6 +171,11 @@ u32 plpks_get_maxlargeobjectsize(void);
  */
 u64 plpks_get_signedupdatealgorithms(void);
 
+/**
+ * Returns the length of the PLPKS password in bytes.
+ */
+u16 plpks_get_passwordlen(void);
+
 #endif // CONFIG_PSERIES_PLPKS
 
 #endif // _ASM_POWERPC_PLPKS_H
diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index 01ae919b4497..671a10acaebf 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -359,6 +359,11 @@ u64 plpks_get_signedupdatealgorithms(void)
return signedupdatealgorithms;
 }
 
+u16 plpks_get_passwordlen(void)
+{
+   return ospasswordlength;
+}
+
 bool plpks_is_available(void)
 {
int rc;
-- 
2.39.1



[PATCH v6 19/26] powerpc/pseries: Make caller pass buffer to plpks_read_var()

2023-02-10 Thread Andrew Donnellan
Currently, plpks_read_var() allocates a buffer to pass to the
H_PKS_READ_OBJECT hcall, then allocates another buffer into which the data
is copied, and returns that buffer to the caller.

This is a bit over the top - while we probably still want to allocate a
separate buffer to pass to the hypervisor in the hcall, we can let the
caller allocate the final buffer and specify the size.

Don't allocate var->data in plpks_read_var(), instead expect the caller to
allocate it. If the caller needs to discover the size, it can set
var->data to NULL and var->datalen will be populated. Update header file
to document this.

Suggested-by: Michael Ellerman 
Signed-off-by: Andrew Donnellan 
Signed-off-by: Russell Currey 
Reviewed-by: Stefan Berger 

---

v3: New patch (mpe)

v6: Reword commit message (stefanb)
---
 arch/powerpc/include/asm/plpks.h   | 12 
 arch/powerpc/platforms/pseries/plpks.c | 11 ---
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
index e7204e6c0ca4..0c49969b0864 100644
--- a/arch/powerpc/include/asm/plpks.h
+++ b/arch/powerpc/include/asm/plpks.h
@@ -88,16 +88,28 @@ int plpks_remove_var(char *component, u8 varos,
 
 /**
  * Returns the data for the specified os variable.
+ *
+ * Caller must allocate a buffer in var->data with length in var->datalen.
+ * If no buffer is provided, var->datalen will be populated with the object's
+ * size.
  */
 int plpks_read_os_var(struct plpks_var *var);
 
 /**
  * Returns the data for the specified firmware variable.
+ *
+ * Caller must allocate a buffer in var->data with length in var->datalen.
+ * If no buffer is provided, var->datalen will be populated with the object's
+ * size.
  */
 int plpks_read_fw_var(struct plpks_var *var);
 
 /**
  * Returns the data for the specified bootloader variable.
+ *
+ * Caller must allocate a buffer in var->data with length in var->datalen.
+ * If no buffer is provided, var->datalen will be populated with the object's
+ * size.
  */
 int plpks_read_bootloader_var(struct plpks_var *var);
 
diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index e5755443d4a4..926b6a927326 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -581,17 +581,14 @@ static int plpks_read_var(u8 consumer, struct plpks_var 
*var)
goto out_free_output;
}
 
-   if (var->datalen == 0 || var->datalen > retbuf[0])
+   if (!var->data || var->datalen > retbuf[0])
var->datalen = retbuf[0];
 
-   var->data = kzalloc(var->datalen, GFP_KERNEL);
-   if (!var->data) {
-   rc = -ENOMEM;
-   goto out_free_output;
-   }
var->policy = retbuf[1];
 
-   memcpy(var->data, output, var->datalen);
+   if (var->data)
+   memcpy(var->data, output, var->datalen);
+
rc = 0;
 
 out_free_output:
-- 
2.39.1



[PATCH v6 15/26] powerpc/pseries: Move PLPKS constants to header file

2023-02-10 Thread Andrew Donnellan
From: Russell Currey 

Move the constants defined in plpks.c to plpks.h, and standardise their
naming, so that PLPKS consumers can make use of them later on.

Signed-off-by: Russell Currey 
Co-developed-by: Andrew Donnellan 
Signed-off-by: Andrew Donnellan 
Reviewed-by: Stefan Berger 

---

v3: New patch
---
 arch/powerpc/include/asm/plpks.h   | 36 +---
 arch/powerpc/platforms/pseries/plpks.c | 57 ++
 2 files changed, 53 insertions(+), 40 deletions(-)

diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
index 8295502ee93b..6466aadd7145 100644
--- a/arch/powerpc/include/asm/plpks.h
+++ b/arch/powerpc/include/asm/plpks.h
@@ -14,14 +14,40 @@
 #include 
 #include 
 
-#define OSSECBOOTAUDIT 0x4000
-#define OSSECBOOTENFORCE 0x2000
-#define WORLDREADABLE 0x0800
-#define SIGNEDUPDATE 0x0100
+// Object policy flags from supported_policies
+#define PLPKS_OSSECBOOTAUDIT   PPC_BIT32(1) // OS secure boot must be 
audit/enforce
+#define PLPKS_OSSECBOOTENFORCE PPC_BIT32(2) // OS secure boot must be enforce
+#define PLPKS_PWSETPPC_BIT32(3) // No access without password set
+#define PLPKS_WORLDREADABLEPPC_BIT32(4) // Readable without authentication
+#define PLPKS_IMMUTABLEPPC_BIT32(5) // Once written, object 
cannot be removed
+#define PLPKS_TRANSIENTPPC_BIT32(6) // Object does not persist 
through reboot
+#define PLPKS_SIGNEDUPDATE PPC_BIT32(7) // Object can only be modified by 
signed updates
+#define PLPKS_HVPROVISIONEDPPC_BIT32(28) // Hypervisor has provisioned 
this object
 
-#define PLPKS_VAR_LINUX0x02
+// Signature algorithm flags from signed_update_algorithms
+#define PLPKS_ALG_RSA2048  PPC_BIT(0)
+#define PLPKS_ALG_RSA4096  PPC_BIT(1)
+
+// Object label OS metadata flags
+#define PLPKS_VAR_LINUX0x02
 #define PLPKS_VAR_COMMON   0x04
 
+// Flags for which consumer owns an object is owned by
+#define PLPKS_FW_OWNER 0x1
+#define PLPKS_BOOTLOADER_OWNER 0x2
+#define PLPKS_OS_OWNER 0x3
+
+// Flags for label metadata fields
+#define PLPKS_LABEL_VERSION0
+#define PLPKS_MAX_LABEL_ATTR_SIZE  16
+#define PLPKS_MAX_NAME_SIZE239
+#define PLPKS_MAX_DATA_SIZE4000
+
+// Timeouts for PLPKS operations
+#define PLPKS_MAX_TIMEOUT  5000 // msec
+#define PLPKS_FLUSH_SLEEP  10 // msec
+#define PLPKS_FLUSH_SLEEP_RANGE400
+
 struct plpks_var {
char *component;
u8 *name;
diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index 13e6daadb179..91f3f623a2c7 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -20,19 +20,6 @@
 #include 
 #include 
 
-#define PKS_FW_OWNER0x1
-#define PKS_BOOTLOADER_OWNER 0x2
-#define PKS_OS_OWNER0x3
-
-#define LABEL_VERSION  0
-#define MAX_LABEL_ATTR_SIZE 16
-#define MAX_NAME_SIZE  239
-#define MAX_DATA_SIZE  4000
-
-#define PKS_FLUSH_MAX_TIMEOUT 5000 //msec
-#define PKS_FLUSH_SLEEP  10 //msec
-#define PKS_FLUSH_SLEEP_RANGE 400
-
 static u8 *ospassword;
 static u16 ospasswordlength;
 
@@ -59,7 +46,7 @@ struct label_attr {
 
 struct label {
struct label_attr attr;
-   u8 name[MAX_NAME_SIZE];
+   u8 name[PLPKS_MAX_NAME_SIZE];
size_t size;
 };
 
@@ -122,7 +109,7 @@ static int pseries_status_to_err(int rc)
 static int plpks_gen_password(void)
 {
unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
-   u8 *password, consumer = PKS_OS_OWNER;
+   u8 *password, consumer = PLPKS_OS_OWNER;
int rc;
 
// The password must not cross a page boundary, so we align to the next 
power of 2
@@ -159,7 +146,7 @@ static struct plpks_auth *construct_auth(u8 consumer)
 {
struct plpks_auth *auth;
 
-   if (consumer > PKS_OS_OWNER)
+   if (consumer > PLPKS_OS_OWNER)
return ERR_PTR(-EINVAL);
 
// The auth structure must not cross a page boundary and must be
@@ -171,7 +158,7 @@ static struct plpks_auth *construct_auth(u8 consumer)
auth->version = 1;
auth->consumer = consumer;
 
-   if (consumer == PKS_FW_OWNER || consumer == PKS_BOOTLOADER_OWNER)
+   if (consumer == PLPKS_FW_OWNER || consumer == PLPKS_BOOTLOADER_OWNER)
return auth;
 
memcpy(auth->password, ospassword, ospasswordlength);
@@ -191,7 +178,7 @@ static struct label *construct_label(char *component, u8 
varos, u8 *name,
struct label *label;
size_t slen;
 
-   if (!name || namelen > MAX_NAME_SIZE)
+   if (!name || namelen > PLPKS_MAX_NAME_SIZE)
return ERR_PTR(-EINVAL);
 
slen = strlen(component);
@@ -206,9 +193,9 @@ static struct label *construct_label(char *component, u8 
varos, u8 *name,
if (component)
memcpy(>attr.prefix, component, 

[PATCH v6 23/26] powerpc/pseries: Pass PLPKS password on kexec

2023-02-10 Thread Andrew Donnellan
From: Russell Currey 

Before interacting with the PLPKS, we ask the hypervisor to generate a
password for the current boot, which is then required for most further
PLPKS operations.

If we kexec into a new kernel, the new kernel will try and fail to
generate a new password, as the password has already been set.

Pass the password through to the new kernel via the device tree, in
/chosen/ibm,plpks-pw. Check for the presence of this property before
trying to generate a new password - if it exists, use the existing
password and remove it from the device tree.

This only works with the kexec_file_load() syscall, not the older
kexec_load() syscall, however if you're using Secure Boot then you want
to be using kexec_file_load() anyway.

Signed-off-by: Russell Currey 
Signed-off-by: Andrew Donnellan 

---

v3: New patch

v4: Fix compile when CONFIG_PSERIES_PLPKS=n (snowpatch)

Fix error handling on fdt_path_offset() call (ruscur)

v5: Fix DT property name in commit message (npiggin)

Clear prop in FDT during init to prevent password exposure (mpe)

Rework to remove ifdefs from C code (npiggin)

v6: Rebase on top of 7294194b47e994753a86eee8cf1c61f3f36458a3 and
fc546faa559538fb312c77e055243ece18ab3288

Whitespace (stefanb)

Use more const (stefanb)

Get rid of FDT extra space allocation for node overhead, as it
shouldn't be necessary (ruscur)

Note kexec_file_load() restriction in commit message
---
 arch/powerpc/include/asm/plpks.h   | 14 ++
 arch/powerpc/kernel/prom.c |  4 ++
 arch/powerpc/kexec/file_load_64.c  | 18 +---
 arch/powerpc/platforms/pseries/plpks.c | 61 ++
 4 files changed, 92 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
index 757313e00521..23b77027c916 100644
--- a/arch/powerpc/include/asm/plpks.h
+++ b/arch/powerpc/include/asm/plpks.h
@@ -176,6 +176,20 @@ u64 plpks_get_signedupdatealgorithms(void);
  */
 u16 plpks_get_passwordlen(void);
 
+/**
+ * Called in early init to retrieve and clear the PLPKS password from the DT.
+ */
+void plpks_early_init_devtree(void);
+
+/**
+ * Populates the FDT with the PLPKS password to prepare for kexec.
+ */
+int plpks_populate_fdt(void *fdt);
+#else // CONFIG_PSERIES_PLPKS
+static inline bool plpks_is_available(void) { return false; }
+static inline u16 plpks_get_passwordlen(void) { BUILD_BUG(); }
+static inline void plpks_early_init_devtree(void) { }
+static inline int plpks_populate_fdt(void *fdt) { BUILD_BUG(); }
 #endif // CONFIG_PSERIES_PLPKS
 
 #endif // _ASM_POWERPC_PLPKS_H
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 4f1c920aa13e..8a13b378770f 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -56,6 +56,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -893,6 +894,9 @@ void __init early_init_devtree(void *params)
powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE;
 #endif
 
+   /* If kexec left a PLPKS password in the DT, get it and clear it */
+   plpks_early_init_devtree();
+
tm_init();
 
DBG(" <- early_init_devtree()\n");
diff --git a/arch/powerpc/kexec/file_load_64.c 
b/arch/powerpc/kexec/file_load_64.c
index 52085751f5f4..8a9469e1ce71 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct umem_info {
u64 *buf;   /* data buffer for usable-memory property */
@@ -977,12 +978,17 @@ static unsigned int cpu_node_size(void)
  */
 unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image)
 {
-   unsigned int cpu_nodes, extra_size;
+   unsigned int cpu_nodes, extra_size = 0;
struct device_node *dn;
u64 usm_entries;
 
+   // Budget some space for the password blob. There's already extra space
+   // for the key name
+   if (plpks_is_available())
+   extra_size += (unsigned int)plpks_get_passwordlen();
+
if (image->type != KEXEC_TYPE_CRASH)
-   return 0;
+   return extra_size;
 
/*
 * For kdump kernel, account for linux,usable-memory and
@@ -992,9 +998,7 @@ unsigned int kexec_extra_fdt_size_ppc64(struct kimage 
*image)
if (drmem_lmb_size()) {
usm_entries = ((memory_hotplug_max() / drmem_lmb_size()) +
   (2 * (resource_size(_res) / 
drmem_lmb_size(;
-   extra_size = (unsigned int)(usm_entries * sizeof(u64));
-   } else {
-   extra_size = 0;
+   extra_size += (unsigned int)(usm_entries * sizeof(u64));
}
 
/*
@@ -1233,6 +1237,10 @@ int setup_new_fdt_ppc64(const struct kimage *image, void 
*fdt,
}
}
 
+   // If we have PLPKS active, we need to provide the password to the new 
kernel
+   if (plpks_is_available())
+   ret = 

[PATCH v6 25/26] integrity/powerpc: Improve error handling & reporting when loading certs

2023-02-10 Thread Andrew Donnellan
From: Russell Currey 

A few improvements to load_powerpc.c:

 - include integrity.h for the pr_fmt()
 - move all error reporting out of get_cert_list()
 - use ERR_PTR() to better preserve error detail
 - don't use pr_err() for missing keys

Reviewed-by: Mimi Zohar 
Signed-off-by: Russell Currey 
Signed-off-by: Andrew Donnellan 

---

v3: New patch
---
 .../integrity/platform_certs/load_powerpc.c   | 26 ++-
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/security/integrity/platform_certs/load_powerpc.c 
b/security/integrity/platform_certs/load_powerpc.c
index 1e4f80a4e71c..dee51606d5f4 100644
--- a/security/integrity/platform_certs/load_powerpc.c
+++ b/security/integrity/platform_certs/load_powerpc.c
@@ -14,9 +14,15 @@
 #include 
 #include 
 #include "keyring_handler.h"
+#include "../integrity.h"
 
 /*
  * Get a certificate list blob from the named secure variable.
+ *
+ * Returns:
+ *  - a pointer to a kmalloc'd buffer containing the cert list on success
+ *  - NULL if the key does not exist
+ *  - an ERR_PTR on error
  */
 static __init void *get_cert_list(u8 *key, unsigned long keylen, u64 *size)
 {
@@ -25,19 +31,19 @@ static __init void *get_cert_list(u8 *key, unsigned long 
keylen, u64 *size)
 
rc = secvar_ops->get(key, keylen, NULL, size);
if (rc) {
-   pr_err("Couldn't get size: %d\n", rc);
-   return NULL;
+   if (rc == -ENOENT)
+   return NULL;
+   return ERR_PTR(rc);
}
 
db = kmalloc(*size, GFP_KERNEL);
if (!db)
-   return NULL;
+   return ERR_PTR(-ENOMEM);
 
rc = secvar_ops->get(key, keylen, db, size);
if (rc) {
kfree(db);
-   pr_err("Error reading %s var: %d\n", key, rc);
-   return NULL;
+   return ERR_PTR(rc);
}
 
return db;
@@ -69,7 +75,11 @@ static int __init load_powerpc_certs(void)
 */
db = get_cert_list("db", 3, );
if (!db) {
-   pr_err("Couldn't get db list from firmware\n");
+   pr_info("Couldn't get db list from firmware\n");
+   } else if (IS_ERR(db)) {
+   rc = PTR_ERR(db);
+   pr_err("Error reading db from firmware: %d\n", rc);
+   return rc;
} else {
rc = parse_efi_signature_list("powerpc:db", db, dbsize,
  get_handler_for_db);
@@ -81,6 +91,10 @@ static int __init load_powerpc_certs(void)
dbx = get_cert_list("dbx", 4,  );
if (!dbx) {
pr_info("Couldn't get dbx list from firmware\n");
+   } else if (IS_ERR(dbx)) {
+   rc = PTR_ERR(dbx);
+   pr_err("Error reading dbx from firmware: %d\n", rc);
+   return rc;
} else {
rc = parse_efi_signature_list("powerpc:dbx", dbx, dbxsize,
  get_handler_for_dbx);
-- 
2.39.1



[PATCH v6 21/26] powerpc/pseries: Clarify warning when PLPKS password already set

2023-02-10 Thread Andrew Donnellan
When the H_PKS_GEN_PASSWORD hcall returns H_IN_USE, operations that require
authentication (i.e. anything other than reading a world-readable variable)
will not work.

The current error message doesn't explain this clearly enough. Reword it
to emphasise that authenticated operations will fail.

Signed-off-by: Andrew Donnellan 

---

v6: New patch
---
 arch/powerpc/platforms/pseries/plpks.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index 926b6a927326..01ae919b4497 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -146,7 +146,7 @@ static int plpks_gen_password(void)
memcpy(ospassword, password, ospasswordlength);
} else {
if (rc == H_IN_USE) {
-   pr_warn("Password is already set for POWER LPAR 
Platform KeyStore\n");
+   pr_warn("Password already set - authenticated 
operations will fail\n");
rc = 0;
} else {
goto out;
-- 
2.39.1



[PATCH v6 16/26] powerpc/pseries: Expose PLPKS config values, support additional fields

2023-02-10 Thread Andrew Donnellan
From: Nayna Jain 

The plpks driver uses the H_PKS_GET_CONFIG hcall to retrieve configuration
and status information about the PKS from the hypervisor.

Update _plpks_get_config() to handle some additional fields. Add getter
functions to allow the PKS configuration information to be accessed from
other files. Validate that the values we're getting comply with the spec.

While we're here, move the config struct in _plpks_get_config() off the
stack - it's getting large and we also need to make sure it doesn't cross
a page boundary.

Signed-off-by: Nayna Jain 
[ajd: split patch, extend to support additional v3 API fields, minor fixes]
Co-developed-by: Andrew Donnellan 
Signed-off-by: Andrew Donnellan 
Signed-off-by: Russell Currey 
Reviewed-by: Stefan Berger 

---

v3: Merge plpks fixes and signed update series with secvar series

Refresh config values in plpks_get_usedspace() (ajd)

Validate the config values being returned comply with spec (ruscur)

Return maxobjlabelsize as is (ruscur)

Move plpks.h to include/asm (ruscur)

Fix checkpatch checks (ruscur)
---
 arch/powerpc/include/asm/plpks.h   |  58 ++
 arch/powerpc/platforms/pseries/plpks.c | 149 +++--
 2 files changed, 195 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
index 6466aadd7145..7c5f51a9af7c 100644
--- a/arch/powerpc/include/asm/plpks.h
+++ b/arch/powerpc/include/asm/plpks.h
@@ -96,6 +96,64 @@ int plpks_read_fw_var(struct plpks_var *var);
  */
 int plpks_read_bootloader_var(struct plpks_var *var);
 
+/**
+ * Returns if PKS is available on this LPAR.
+ */
+bool plpks_is_available(void);
+
+/**
+ * Returns version of the Platform KeyStore.
+ */
+u8 plpks_get_version(void);
+
+/**
+ * Returns hypervisor storage overhead per object, not including the size of
+ * the object or label. Only valid for config version >= 2
+ */
+u16 plpks_get_objoverhead(void);
+
+/**
+ * Returns maximum password size. Must be >= 32 bytes
+ */
+u16 plpks_get_maxpwsize(void);
+
+/**
+ * Returns maximum object size supported by Platform KeyStore.
+ */
+u16 plpks_get_maxobjectsize(void);
+
+/**
+ * Returns maximum object label size supported by Platform KeyStore.
+ */
+u16 plpks_get_maxobjectlabelsize(void);
+
+/**
+ * Returns total size of the configured Platform KeyStore.
+ */
+u32 plpks_get_totalsize(void);
+
+/**
+ * Returns used space from the total size of the Platform KeyStore.
+ */
+u32 plpks_get_usedspace(void);
+
+/**
+ * Returns bitmask of policies supported by the hypervisor.
+ */
+u32 plpks_get_supportedpolicies(void);
+
+/**
+ * Returns maximum byte size of a single object supported by the hypervisor.
+ * Only valid for config version >= 3
+ */
+u32 plpks_get_maxlargeobjectsize(void);
+
+/**
+ * Returns bitmask of signature algorithms supported for signed updates.
+ * Only valid for config version >= 3
+ */
+u64 plpks_get_signedupdatealgorithms(void);
+
 #endif // CONFIG_PSERIES_PLPKS
 
 #endif // _ASM_POWERPC_PLPKS_H
diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index 91f3f623a2c7..1189246b03dc 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -24,8 +24,16 @@ static u8 *ospassword;
 static u16 ospasswordlength;
 
 // Retrieved with H_PKS_GET_CONFIG
+static u8 version;
+static u16 objoverhead;
 static u16 maxpwsize;
 static u16 maxobjsize;
+static s16 maxobjlabelsize;
+static u32 totalsize;
+static u32 usedspace;
+static u32 supportedpolicies;
+static u32 maxlargeobjectsize;
+static u64 signedupdatealgorithms;
 
 struct plpks_auth {
u8 version;
@@ -206,32 +214,149 @@ static struct label *construct_label(char *component, u8 
varos, u8 *name,
 static int _plpks_get_config(void)
 {
unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
-   struct {
+   struct config {
u8 version;
u8 flags;
-   __be32 rsvd0;
+   __be16 rsvd0;
+   __be16 objoverhead;
__be16 maxpwsize;
__be16 maxobjlabelsize;
__be16 maxobjsize;
__be32 totalsize;
__be32 usedspace;
__be32 supportedpolicies;
-   __be64 rsvd1;
-   } __packed config;
+   __be32 maxlargeobjectsize;
+   __be64 signedupdatealgorithms;
+   u8 rsvd1[476];
+   } __packed * config;
size_t size;
-   int rc;
+   int rc = 0;
+
+   size = sizeof(*config);
+
+   // Config struct must not cross a page boundary. So long as the struct
+   // size is a power of 2, this should be fine as alignment is guaranteed
+   config = kzalloc(size, GFP_KERNEL);
+   if (!config) {
+   rc = -ENOMEM;
+   goto err;
+   }
+
+   rc = plpar_hcall(H_PKS_GET_CONFIG, retbuf, virt_to_phys(config), size);
+
+   if (rc != H_SUCCESS) {
+   

[PATCH v6 18/26] powerpc/pseries: Log hcall return codes for PLPKS debug

2023-02-10 Thread Andrew Donnellan
From: Russell Currey 

The plpks code converts hypervisor return codes into their Linux
equivalents so that users can understand them.  Having access to the
original return codes is really useful for debugging, so add a
pr_debug() so we don't lose information from the conversion.

Signed-off-by: Russell Currey 
Signed-off-by: Andrew Donnellan 
Reviewed-by: Stefan Berger 
---
 arch/powerpc/platforms/pseries/plpks.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/plpks.c 
b/arch/powerpc/platforms/pseries/plpks.c
index cee06fb9a370..e5755443d4a4 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -117,6 +117,8 @@ static int pseries_status_to_err(int rc)
err = -EINVAL;
}
 
+   pr_debug("Converted hypervisor code %d to Linux %d\n", rc, err);
+
return err;
 }
 
-- 
2.39.1



[PATCH v6 13/26] powerpc/secvar: Don't print error on ENOENT when reading variables

2023-02-10 Thread Andrew Donnellan
If attempting to read the size or data attributes of a  non-existent
variable (which will be possible after a later patch to expose the PLPKS
via the secvar interface), don't spam the kernel log with error messages.
Only print errors for return codes that aren't ENOENT.

Reported-by: Sudhakar Kuppusamy 
Signed-off-by: Andrew Donnellan 
Reviewed-by: Stefan Berger 

---

v3: New patch
---
 arch/powerpc/kernel/secvar-sysfs.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/secvar-sysfs.c 
b/arch/powerpc/kernel/secvar-sysfs.c
index 6ba23b2bb9da..eb3c053f323f 100644
--- a/arch/powerpc/kernel/secvar-sysfs.c
+++ b/arch/powerpc/kernel/secvar-sysfs.c
@@ -43,8 +43,8 @@ static ssize_t size_show(struct kobject *kobj, struct 
kobj_attribute *attr,
 
rc = secvar_ops->get(kobj->name, strlen(kobj->name) + 1, NULL, );
if (rc) {
-   pr_err("Error retrieving %s variable size %d\n", kobj->name,
-  rc);
+   if (rc != -ENOENT)
+   pr_err("Error retrieving %s variable size %d\n", 
kobj->name, rc);
return rc;
}
 
@@ -61,7 +61,8 @@ static ssize_t data_read(struct file *filep, struct kobject 
*kobj,
 
rc = secvar_ops->get(kobj->name, strlen(kobj->name) + 1, NULL, );
if (rc) {
-   pr_err("Error getting %s variable size %d\n", kobj->name, rc);
+   if (rc != -ENOENT)
+   pr_err("Error getting %s variable size %d\n", 
kobj->name, rc);
return rc;
}
pr_debug("dsize is %llu\n", dsize);
-- 
2.39.1



[PATCH v6 11/26] powerpc/secvar: Allow backend to populate static list of variable names

2023-02-10 Thread Andrew Donnellan
Currently, the list of variables is populated by calling
secvar_ops->get_next() repeatedly, which is explicitly modelled on the
OPAL API (including the keylen parameter).

For the upcoming PLPKS backend, we have a static list of variable names.
It is messy to fit that into get_next(), so instead, let the backend put
a NULL-terminated array of variable names into secvar_ops->var_names,
which will be used if get_next() is undefined.

Signed-off-by: Andrew Donnellan 
Signed-off-by: Russell Currey 
Reviewed-by: Stefan Berger 

---

v3: New patch (ajd/mpe)

v6: Add newlines for better aesthetics (stefanb)
---
 arch/powerpc/include/asm/secvar.h  |  4 ++
 arch/powerpc/kernel/secvar-sysfs.c | 69 +-
 2 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/include/asm/secvar.h 
b/arch/powerpc/include/asm/secvar.h
index 011a53a8076c..4828e0ab7e3c 100644
--- a/arch/powerpc/include/asm/secvar.h
+++ b/arch/powerpc/include/asm/secvar.h
@@ -21,6 +21,10 @@ struct secvar_operations {
ssize_t (*format)(char *buf, size_t bufsize);
int (*max_size)(u64 *max_size);
const struct attribute **config_attrs;
+
+   // NULL-terminated array of fixed variable names
+   // Only used if get_next() isn't provided
+   const char * const *var_names;
 };
 
 #ifdef CONFIG_PPC_SECURE_BOOT
diff --git a/arch/powerpc/kernel/secvar-sysfs.c 
b/arch/powerpc/kernel/secvar-sysfs.c
index 7df32be86507..bfb19f22c6ba 100644
--- a/arch/powerpc/kernel/secvar-sysfs.c
+++ b/arch/powerpc/kernel/secvar-sysfs.c
@@ -157,9 +157,31 @@ static int secvar_sysfs_config(struct kobject *kobj)
return 0;
 }
 
-static int secvar_sysfs_load(void)
+static int add_var(const char *name)
 {
struct kobject *kobj;
+   int rc;
+
+   kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
+   if (!kobj)
+   return -ENOMEM;
+
+   kobject_init(kobj, _ktype);
+
+   rc = kobject_add(kobj, _kset->kobj, "%s", name);
+   if (rc) {
+   pr_warn("kobject_add error %d for attribute: %s\n", rc,
+   name);
+   kobject_put(kobj);
+   return rc;
+   }
+
+   kobject_uevent(kobj, KOBJ_ADD);
+   return 0;
+}
+
+static int secvar_sysfs_load(void)
+{
u64 namesize = 0;
char *name;
int rc;
@@ -179,31 +201,28 @@ static int secvar_sysfs_load(void)
break;
}
 
-   kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
-   if (!kobj) {
-   rc = -ENOMEM;
-   break;
-   }
-
-   kobject_init(kobj, _ktype);
-
-   rc = kobject_add(kobj, _kset->kobj, "%s", name);
-   if (rc) {
-   pr_warn("kobject_add error %d for attribute: %s\n", rc,
-   name);
-   kobject_put(kobj);
-   kobj = NULL;
-   }
-
-   if (kobj)
-   kobject_uevent(kobj, KOBJ_ADD);
-
+   rc = add_var(name);
} while (!rc);
 
kfree(name);
return rc;
 }
 
+static int secvar_sysfs_load_static(void)
+{
+   const char * const *name_ptr = secvar_ops->var_names;
+   int rc;
+
+   while (*name_ptr) {
+   rc = add_var(*name_ptr);
+   if (rc)
+   return rc;
+   name_ptr++;
+   }
+
+   return 0;
+}
+
 static int secvar_sysfs_init(void)
 {
int rc;
@@ -245,7 +264,15 @@ static int secvar_sysfs_init(void)
goto err;
}
 
-   secvar_sysfs_load();
+   if (secvar_ops->get_next)
+   rc = secvar_sysfs_load();
+   else
+   rc = secvar_sysfs_load_static();
+
+   if (rc) {
+   pr_err("Failed to create variable attributes\n");
+   goto err;
+   }
 
return 0;
 err:
-- 
2.39.1



[PATCH v6 12/26] powerpc/secvar: Warn when PAGE_SIZE is smaller than max object size

2023-02-10 Thread Andrew Donnellan
Due to sysfs constraints, when writing to a variable, we can only handle
writes of up to PAGE_SIZE.

It's possible that the maximum object size is larger than PAGE_SIZE, in
which case, print a warning on boot so that the user is aware.

Signed-off-by: Andrew Donnellan 
Signed-off-by: Russell Currey 
Reviewed-by: Stefan Berger 

---

v3: New patch (ajd)
---
 arch/powerpc/kernel/secvar-sysfs.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/powerpc/kernel/secvar-sysfs.c 
b/arch/powerpc/kernel/secvar-sysfs.c
index bfb19f22c6ba..6ba23b2bb9da 100644
--- a/arch/powerpc/kernel/secvar-sysfs.c
+++ b/arch/powerpc/kernel/secvar-sysfs.c
@@ -225,6 +225,7 @@ static int secvar_sysfs_load_static(void)
 
 static int secvar_sysfs_init(void)
 {
+   u64 max_size;
int rc;
 
if (!secvar_ops) {
@@ -274,6 +275,14 @@ static int secvar_sysfs_init(void)
goto err;
}
 
+   // Due to sysfs limitations, we will only ever get a write buffer of
+   // up to 1 page in size. Print a warning if this is potentially going
+   // to cause problems, so that the user is aware.
+   secvar_ops->max_size(_size);
+   if (max_size > PAGE_SIZE)
+   pr_warn_ratelimited("PAGE_SIZE (%lu) is smaller than maximum 
object size (%llu), writes are limited to PAGE_SIZE\n",
+   PAGE_SIZE, max_size);
+
return 0;
 err:
kobject_put(secvar_kobj);
-- 
2.39.1



  1   2   >