* Re: [PATCH V3 10/15] arch/kmap: Define kmap_atomic_prot() for all arch's
From: Ira Weiny @ 2020-05-18 18:17 UTC (permalink / raw)
To: Guenter Roeck
Cc: Peter Zijlstra, Dave Hansen, dri-devel, linux-mips,
James E.J. Bottomley, Max Filippov, Paul Mackerras,
H. Peter Anvin, sparclinux, Dan Williams, Helge Deller, x86,
linux-csky, Christoph Hellwig, Ingo Molnar, linux-snps-arc,
linux-xtensa, Borislav Petkov, Al Viro, Andy Lutomirski,
Thomas Gleixner, linux-arm-kernel, Chris Zankel,
Thomas Bogendoerfer, linux-parisc, linux-kernel, Christian Koenig,
Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <20200517173722.GA33341@roeck-us.net>
On Sun, May 17, 2020 at 10:37:22AM -0700, Guenter Roeck wrote:
> Hi,
>
> On Thu, May 07, 2020 at 07:59:58AM -0700, ira.weiny@intel.com wrote:
> > From: Ira Weiny <ira.weiny@intel.com>
> >
> > To support kmap_atomic_prot(), all architectures need to support
> > protections passed to their kmap_atomic_high() function. Pass
> > protections into kmap_atomic_high() and change the name to
> > kmap_atomic_high_prot() to match.
> >
> > Then define kmap_atomic_prot() as a core function which calls
> > kmap_atomic_high_prot() when needed.
> >
> > Finally, redefine kmap_atomic() as a wrapper of kmap_atomic_prot() with
> > the default kmap_prot exported by the architectures.
> >
> > Reviewed-by: Christoph Hellwig <hch@lst.de>
> > Signed-off-by: Ira Weiny <ira.weiny@intel.com>
>
> This patch causes a variety of crashes whem booting powerpc images in qemu.
PowerPC has the same issue as microblaze and sparc.
I'm preping a patch with all three fixed which fixes the kunmap_atomic clean up
patch...
Sorry for not seeing this last night...
Hopefully this can explain all the problems. It is clearly a bug.
Ira
>
> There are lots of warnings such as:
>
> WARNING: CPU: 0 PID: 0 at lib/locking-selftest.c:743 irqsafe1_hard_spin_12+0x50/0xb0
> Modules linked in:
> CPU: 0 PID: 0 Comm: swapper Tainted: G W 5.7.0-rc5-next-20200515 #1
> NIP: c0660c7c LR: c0660c44 CTR: c0660c2c
> REGS: c1223e68 TRAP: 0700 Tainted: G W (5.7.0-rc5-next-20200515)
> MSR: 00021000 <CE,ME> CR: 28000224 XER: 20000000
>
> GPR00: c0669c78 c1223f20 c113d560 c0660c44 00000000 00000001 c1223ea8 00000001
> GPR08: 00000000 00000001 0000fffc ffffffff 88000222 00000000 00000000 00000000
> GPR16: 00000000 00000000 00000000 00000000 c0000000 00000000 00000000 c1125084
> GPR24: c1125084 c1230000 c1879538 fffffffc 00000001 00000000 c1011afc c1230000
> NIP [c0660c7c] irqsafe1_hard_spin_12+0x50/0xb0
> LR [c0660c44] irqsafe1_hard_spin_12+0x18/0xb0
> Call Trace:
> [c1223f20] [c1880000] megasas_mgmt_info+0xee4/0x1008 (unreliable)
> [c1223f40] [c0669c78] dotest+0x38/0x550
> [c1223f70] [c066aa4c] locking_selftest+0x8bc/0x1d54
> [c1223fa0] [c10e0bc8] start_kernel+0x3ec/0x510
> [c1223ff0] [c00003a0] set_ivor+0x118/0x154
> Instruction dump:
> 81420000 38e80001 3d4a0001 2c080000 91420000 90e20488 40820008 91020470
> 81290000 5529031e 7d290034 5529d97e <0f090000> 3fe0c11c 3bff3964 3bff00ac
> irq event stamp: 588
> hardirqs last enabled at (587): [<c00b9fe4>] vprintk_emit+0x1b4/0x33c
> hardirqs last disabled at (588): [<c0660c44>] irqsafe1_hard_spin_12+0x18/0xb0
> softirqs last enabled at (0): [<00000000>] 0x0
> softirqs last disabled at (0): [<00000000>] 0x0
> ---[ end trace b18fe9e172f99d03 ]---
>
> This is followed by:
>
> BUG: sleeping function called from invalid context at lib/mpi/mpi-pow.c:245
> in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 14, name: cryptomgr_test
> INFO: lockdep is turned off.
> CPU: 0 PID: 14 Comm: cryptomgr_test Tainted: G W 5.7.0-rc5-next-20200515 #1
> Call Trace:
> [ce221b58] [c008755c] ___might_sleep+0x280/0x2a8 (unreliable)
> [ce221b78] [c06bc524] mpi_powm+0x634/0xc50
> [ce221c38] [c05eafdc] rsa_dec+0x88/0x134
> [ce221c78] [c05f3b40] test_akcipher_one+0x678/0x804
> [ce221dc8] [c05f3d7c] alg_test_akcipher+0xb0/0x130
> [ce221df8] [c05ee674] alg_test.part.0+0xb4/0x458
> [ce221ed8] [c05ed2b0] cryptomgr_test+0x30/0x50
> [ce221ef8] [c007cd74] kthread+0x134/0x170
> [ce221f38] [c001433c] ret_from_kernel_thread+0x14/0x1c
> Kernel panic - not syncing: Aiee, killing interrupt handler!
> CPU: 0 PID: 14 Comm: cryptomgr_test Tainted: G W 5.7.0-rc5-next-20200515 #1
> Call Trace:
> [ce221e08] [c00530fc] panic+0x148/0x34c (unreliable)
> [ce221e68] [c0056460] do_exit+0xac0/0xb40
> [ce221eb8] [c00f5be8] find_kallsyms_symbol_value+0x0/0x128
> [ce221ed8] [c05ed2d0] crypto_alg_put+0x0/0x70
> [ce221ef8] [c007cd74] kthread+0x134/0x170
> [ce221f38] [c001433c] ret_from_kernel_thread+0x14/0x1c
>
> Bisect log is attached. The patch can not easily be reverted since
> it results in compile errors.
>
> Note that similar failures are seen with sparc32 images. Those bisect
> to a different patch, but reverting that patch doesn't fix the problem.
> The failure pattern (warnings followed by a crash in cryptomgr_test)
> is the same.
>
> Guenter
>
> ---
> # bad: [bdecf38f228bcca73b31ada98b5b7ba1215eb9c9] Add linux-next specific files for 20200515
> # good: [2ef96a5bb12be62ef75b5828c0aab838ebb29cb8] Linux 5.7-rc5
> git bisect start 'HEAD' 'v5.7-rc5'
> # good: [3674d7aa7a8e61d993886c2fb7c896c5ef85e988] Merge remote-tracking branch 'crypto/master'
> git bisect good 3674d7aa7a8e61d993886c2fb7c896c5ef85e988
> # good: [87f6f21783522e6d62127cf33ae5e95f50874beb] Merge remote-tracking branch 'spi/for-next'
> git bisect good 87f6f21783522e6d62127cf33ae5e95f50874beb
> # good: [5c428e8277d5d97c85126387d4e00aa5adde4400] Merge remote-tracking branch 'staging/staging-next'
> git bisect good 5c428e8277d5d97c85126387d4e00aa5adde4400
> # good: [f68de67ed934e7bdef4799fd7777c86f33f14982] Merge remote-tracking branch 'hyperv/hyperv-next'
> git bisect good f68de67ed934e7bdef4799fd7777c86f33f14982
> # bad: [54acd2dc52b069da59639eea0d0c92726f32fb01] mm/memblock: fix a typo in comment "implict"->"implicit"
> git bisect bad 54acd2dc52b069da59639eea0d0c92726f32fb01
> # good: [784a17aa58a529b84f7cc50f351ed4acf3bd11f3] mm: remove the pgprot argument to __vmalloc
> git bisect good 784a17aa58a529b84f7cc50f351ed4acf3bd11f3
> # good: [6cd8137ff37e9a37aee2d2a8889c8beb8eab192f] khugepaged: replace the usage of system(3) in the test
> git bisect good 6cd8137ff37e9a37aee2d2a8889c8beb8eab192f
> # bad: [6987da379826ed01b8a1cf046b67cc8cc10117cc] sparc: remove unnecessary includes
> git bisect bad 6987da379826ed01b8a1cf046b67cc8cc10117cc
> # good: [bc17b545388f64c09e83e367898e28f60277c584] mm/hugetlb: define a generic fallback for is_hugepage_only_range()
> git bisect good bc17b545388f64c09e83e367898e28f60277c584
> # good: [9b5aa5b43f957f03a1f4a9aff5f7924e2ebbc011] arch-kmap_atomic-consolidate-duplicate-code-checkpatch-fixes
> git bisect good 9b5aa5b43f957f03a1f4a9aff5f7924e2ebbc011
> # bad: [89194ba5ee31567eeee9c81101b334c8e3248198] arch/kmap: define kmap_atomic_prot() for all arch's
> git bisect bad 89194ba5ee31567eeee9c81101b334c8e3248198
> # good: [022785d2bea99f8bc2a37b7b6c525eea26f6ac59] arch-kunmap_atomic-consolidate-duplicate-code-checkpatch-fixes
> git bisect good 022785d2bea99f8bc2a37b7b6c525eea26f6ac59
> # good: [a13c2f39e3f0519ddee57d26cc66ec70e3546106] arch/kmap: don't hard code kmap_prot values
> git bisect good a13c2f39e3f0519ddee57d26cc66ec70e3546106
> # first bad commit: [89194ba5ee31567eeee9c81101b334c8e3248198] arch/kmap: define kmap_atomic_prot() for all arch's
>
>
^ permalink raw reply
* Re: [PATCH 10/29] c6x: use asm-generic/cacheflush.h
From: Mark Salter @ 2020-05-18 18:20 UTC (permalink / raw)
To: Christoph Hellwig, Andrew Morton, Arnd Bergmann, Roman Zippel
Cc: linux-arch, linux-xtensa, Michal Simek, linux-alpha, linux-ia64,
linux-c6x-dev, linux-sh, linux-hexagon, x86, linux-um,
linux-kernel, linux-mips, linux-mm, linux-m68k, openrisc,
Jessica Yu, sparclinux, linux-fsdevel, linux-riscv, linuxppc-dev,
linux-arm-kernel
In-Reply-To: <20200515143646.3857579-11-hch@lst.de>
On Fri, 2020-05-15 at 16:36 +0200, Christoph Hellwig wrote:
> C6x needs almost no cache flushing routines of its own. Rely on
> asm-generic/cacheflush.h for the defaults.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> arch/c6x/include/asm/cacheflush.h | 19 +------------------
> 1 file changed, 1 insertion(+), 18 deletions(-)
>
> diff --git a/arch/c6x/include/asm/cacheflush.h b/arch/c6x/include/asm/cacheflush.h
> index 4540b40475e6c..10922d528de6d 100644
> --- a/arch/c6x/include/asm/cacheflush.h
> +++ b/arch/c6x/include/asm/cacheflush.h
> @@ -16,21 +16,6 @@
> #include <asm/page.h>
> #include <asm/string.h>
>
> -/*
> - * virtually-indexed cache management (our cache is physically indexed)
> - */
> -#define flush_cache_all() do {} while (0)
> -#define flush_cache_mm(mm) do {} while (0)
> -#define flush_cache_dup_mm(mm) do {} while (0)
> -#define flush_cache_range(mm, start, end) do {} while (0)
> -#define flush_cache_page(vma, vmaddr, pfn) do {} while (0)
> -#define flush_cache_vmap(start, end) do {} while (0)
> -#define flush_cache_vunmap(start, end) do {} while (0)
> -#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
> -#define flush_dcache_page(page) do {} while (0)
> -#define flush_dcache_mmap_lock(mapping) do {} while (0)
> -#define flush_dcache_mmap_unlock(mapping) do {} while (0)
> -
> /*
> * physically-indexed cache management
> */
> @@ -49,14 +34,12 @@ do { \
> (unsigned long) page_address(page) + PAGE_SIZE)); \
> } while (0)
>
> -
> #define copy_to_user_page(vma, page, vaddr, dst, src, len) \
> do { \
> memcpy(dst, src, len); \
> flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \
> } while (0)
>
> -#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
> - memcpy(dst, src, len)
> +#include <asm-generic/cacheflush.h>
>
> #endif /* _ASM_C6X_CACHEFLUSH_H */
Acked-by: Mark Salter <msalter@redhat.com>
^ permalink raw reply
* [PATCH] arch/{mips, sparc, microblaze, powerpc}: Don't enable pagefault/preempt twice
From: ira.weiny @ 2020-05-18 18:48 UTC (permalink / raw)
To: linux-kernel, Andrew Morton, Guenter Roeck
Cc: Peter Zijlstra, Dave Hansen, dri-devel, James E.J. Bottomley,
Max Filippov, Paul Mackerras, H. Peter Anvin, sparclinux,
Ira Weiny, Thomas Gleixner, Helge Deller, x86, linux-csky,
Christoph Hellwig, Ingo Molnar, linux-snps-arc, linux-xtensa,
Borislav Petkov, Al Viro, Andy Lutomirski, Dan Williams,
linux-arm-kernel, Chris Zankel, Thomas Bogendoerfer, linux-parisc,
linux-mips, Christian Koenig, linuxppc-dev, David S. Miller
In-Reply-To: <20200507150004.1423069-8-ira.weiny@intel.com>
From: Ira Weiny <ira.weiny@intel.com>
The kunmap_atomic clean up failed to remove one set of pagefault/preempt
enables when vaddr is not in the fixmap.
Fixes: bee2128a09e6 ("arch/kunmap_atomic: consolidate duplicate code")
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
---
arch/microblaze/mm/highmem.c | 5 +----
arch/mips/mm/highmem.c | 5 +----
arch/powerpc/mm/highmem.c | 5 +----
arch/sparc/mm/highmem.c | 5 +----
4 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/arch/microblaze/mm/highmem.c b/arch/microblaze/mm/highmem.c
index ee8a422b2b76..92e0890416c9 100644
--- a/arch/microblaze/mm/highmem.c
+++ b/arch/microblaze/mm/highmem.c
@@ -57,11 +57,8 @@ void kunmap_atomic_high(void *kvaddr)
int type;
unsigned int idx;
- if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
- pagefault_enable();
- preempt_enable();
+ if (vaddr < __fix_to_virt(FIX_KMAP_END))
return;
- }
type = kmap_atomic_idx();
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 37e244cdb14e..8e8726992720 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -41,11 +41,8 @@ void kunmap_atomic_high(void *kvaddr)
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
int type __maybe_unused;
- if (vaddr < FIXADDR_START) { // FIXME
- pagefault_enable();
- preempt_enable();
+ if (vaddr < FIXADDR_START)
return;
- }
type = kmap_atomic_idx();
#ifdef CONFIG_DEBUG_HIGHMEM
diff --git a/arch/powerpc/mm/highmem.c b/arch/powerpc/mm/highmem.c
index 35071c2913f1..624b4438aff9 100644
--- a/arch/powerpc/mm/highmem.c
+++ b/arch/powerpc/mm/highmem.c
@@ -44,11 +44,8 @@ void kunmap_atomic_high(void *kvaddr)
{
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
- if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
- pagefault_enable();
- preempt_enable();
+ if (vaddr < __fix_to_virt(FIX_KMAP_END))
return;
- }
if (IS_ENABLED(CONFIG_DEBUG_HIGHMEM)) {
int type = kmap_atomic_idx();
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index d237d902f9c3..6ff6e2a9f9b3 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -86,11 +86,8 @@ void kunmap_atomic_high(void *kvaddr)
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
int type;
- if (vaddr < FIXADDR_START) { // FIXME
- pagefault_enable();
- preempt_enable();
+ if (vaddr < FIXADDR_START)
return;
- }
type = kmap_atomic_idx();
--
2.25.1
^ permalink raw reply related
* Re: [RFC][PATCH 0/2] Add support for using reserved memory for ima buffer pass
From: Prakhar Srivastava @ 2020-05-18 20:16 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, kstewart, gregkh, bhsharma, tao.li, zohar, paulus,
vincenzo.frascino, will, nramas, frowand.list, masahiroy, jmorris,
takahiro.akashi, linux-arm-kernel, catalin.marinas, serge,
devicetree, pasha.tatashin, hsinyi, tusharsu, tglx, allison,
christophe.leroy, mbrugger, balajib, dmitry.kasatkin,
linux-kernel, linux-security-module, james.morse, linux-integrity,
linuxppc-dev
In-Reply-To: <20200512230509.GA2654@bogus>
On 5/12/20 4:05 PM, Rob Herring wrote:
> On Wed, May 06, 2020 at 10:50:04PM -0700, Prakhar Srivastava wrote:
>> Hi Mark,
>
> Please don't top post.
>
>> This patch set currently only address the Pure DT implementation.
>> EFI and ACPI implementations will be posted in subsequent patchsets.
>>
>> The logs are intended to be carried over the kexec and once read the
>> logs are no longer needed and in prior conversation with James(
>> https://lore.kernel.org/linux-arm-kernel/0053eb68-0905-4679-c97a-00c5cb6f1abb@arm.com/)
>> the apporach of using a chosen node doesn't
>> support the case.
>>
>> The DT entries make the reservation permanent and thus doesnt need kernel
>> segments to be used for this, however using a chosen-node with
>> reserved memory only changes the node information but memory still is
>> reserved via reserved-memory section.
>
> I think Mark's point was whether it needs to be permanent. We don't
> hardcode the initrd address for example.
>
Thankyou for clarifying my misunderstanding, i am modelling this keeping
to the TPM log implementation that uses a reserved memory. I will rev up
the version with chosen-node support.
That will make the memory reservation free after use.
>> On 5/5/20 2:59 AM, Mark Rutland wrote:
>>> Hi Prakhar,
>>>
>>> On Mon, May 04, 2020 at 01:38:27PM -0700, Prakhar Srivastava wrote:
>>>> IMA during kexec(kexec file load) verifies the kernel signature and measures
>
> What's IMAIMA is a LSM attempting to detect if files have been accidentally or
maliciously altered, both remotely and locally, it can also be used
to appraise a file's measurement against a "good" value stored as an
extended attribute, and enforce local file integrity.
IMA also validates and measures the signers of the kernel and initrd
during kexec. The measurements are extended to PCR 10(configurable) and
the logs stored in memory, however once kexec'd the logs are lost. Kexec
is used as secondary boot loader in may use cases and loosing the signer
creates a security hole.
This patch is an implementation to carry over the logs and making it
possible to remotely validate the signers of the kernel and initrd. Such
a support exits only in powerpc.
This patch makes the carry over of logs architecture independent and
puts the complexity in a driver.
Thanks,
Prakhar
>
>>>> the signature of the kernel. The signature in the logs can be used to verfiy the
>>>> authenticity of the kernel. The logs don not get carried over kexec and thus
>>>> remote attesation cannot verify the signature of the running kernel.
>>>>
>>>> Introduce an ABI to carry forward the ima logs over kexec.
>>>> Memory reserved via device tree reservation can be used to store and read
>>>> via the of_* functions.
>>>
>>> This flow needs to work for:
>>>
>>> 1) Pure DT
>>> 2) DT + EFI memory map
>>> 3) ACPI + EFI memory map
>>>
>>> ... and if this is just for transiently passing the log, I don't think
>>> that a reserved memory region is the right thing to use, since they're
>>> supposed to be more permanent.
>>>
>>> This sounds analogous to passing the initrd, and should probably use
>>> properties under the chosen node (which can be used for all three boot
>>> flows above).
>>>
>>> For reference, how big is the IMA log likely to be? Does it need
>>> physically contiguous space?
>>
>> It purely depends on the policy used and the modules/files that are accessed
>> for my local testing over a kexec session the log in
>> about 30KB.
>>
>> Current implementation expects enough contiguous memory to allocated to
>> carry forward the logs. If the log size exceeds the reserved memory the
>> call will fail.
>>
>> Thanks,
>> Prakhar Srivastava
>>>
>>> Thanks,
>>> Mark.
>>>
>>>>
>>>> Reserved memory stores the size(sizeof(size_t)) of the buffer in the starting
>>>> address, followed by the IMA log contents.
>>>>
>>>> Tested on:
>>>> arm64 with Uboot
>>>>
>>>> Prakhar Srivastava (2):
>>>> Add a layer of abstraction to use the memory reserved by device tree
>>>> for ima buffer pass.
>>>> Add support for ima buffer pass using reserved memory for arm64 kexec.
>>>> Update the arch sepcific code path in kexec file load to store the
>>>> ima buffer in the reserved memory. The same reserved memory is read
>>>> on kexec or cold boot.
>>>>
>>>> arch/arm64/Kconfig | 1 +
>>>> arch/arm64/include/asm/ima.h | 22 ++++
>>>> arch/arm64/include/asm/kexec.h | 5 +
>>>> arch/arm64/kernel/Makefile | 1 +
>>>> arch/arm64/kernel/ima_kexec.c | 64 ++++++++++
>>>> arch/arm64/kernel/machine_kexec_file.c | 1 +
>>>> arch/powerpc/include/asm/ima.h | 3 +-
>>>> arch/powerpc/kexec/ima.c | 14 ++-
>>>> drivers/of/Kconfig | 6 +
>>>> drivers/of/Makefile | 1 +
>>>> drivers/of/of_ima.c | 165 +++++++++++++++++++++++++
>>>> include/linux/of.h | 34 +++++
>>>> security/integrity/ima/ima_kexec.c | 15 ++-
>>>> 13 files changed, 325 insertions(+), 7 deletions(-)
>>>> create mode 100644 arch/arm64/include/asm/ima.h
>>>> create mode 100644 arch/arm64/kernel/ima_kexec.c
>>>> create mode 100644 drivers/of/of_ima.c
>>>>
>>>> --
>>>> 2.25.1
>>>>
^ permalink raw reply
* Re: [RFC][PATCH 1/2] Add a layer of abstraction to use the memory reserved by device tree for ima buffer pass.
From: Prakhar Srivastava @ 2020-05-18 20:34 UTC (permalink / raw)
To: Rob Herring
Cc: kstewart, mark.rutland, gregkh, bhsharma, tao.li, zohar, paulus,
vincenzo.frascino, will, nramas, frowand.list, masahiroy, jmorris,
takahiro.akashi, linux-arm-kernel, catalin.marinas, serge,
devicetree, pasha.tatashin, hsinyi, tusharsu, tglx, allison,
christophe.leroy, mbrugger, balajib, dmitry.kasatkin,
linux-kernel, linux-security-module, james.morse, linux-integrity,
linuxppc-dev
In-Reply-To: <20200512230954.GB2654@bogus>
On 5/12/20 4:09 PM, Rob Herring wrote:
> On Mon, May 04, 2020 at 01:38:28PM -0700, Prakhar Srivastava wrote:
>> Introduce a device tree layer for to read and store ima buffer
>> from the reserved memory section of a device tree.
>
> But why do I need 'a layer of abstraction'? I don't like them.
>
This is a common path for the all architectures to carry over the
IMA measurement logs. A single layer will avoid any code duplication.
>> Signed-off-by: Prakhar Srivastava <prsriva@linux.microsoft.com>
>> ---
>> drivers/of/Kconfig | 6 ++
>> drivers/of/Makefile | 1 +
>> drivers/of/of_ima.c | 165 ++++++++++++++++++++++++++++++++++++++++++++
>
> Who are the users of this code and why does it need to be here? Most
> code for specific bindings are not in drivers/of/ but with the user. It
> doesn't sound like there's more than 1 user.
>
Currently the path is exercised by arm64 kexec_file_load path. A slight
restructuring is needed on the powerpc side to use the same code path
and other architectures can follow to add carrying over IMA logs over
kexec with just a few function calls.
I have attempted to bring the code path down to the highest common
layer, however please do suggest if i can move this some where else.
Thanks,
Prakhar
>> include/linux/of.h | 34 +++++++++
>> 4 files changed, 206 insertions(+)
>> create mode 100644 drivers/of/of_ima.c
^ permalink raw reply
* Re: [PATCH 16/21] mm: remove early_pfn_in_nid() and CONFIG_NODES_SPAN_OTHER_NODES
From: Hoan Tran @ 2020-05-18 21:38 UTC (permalink / raw)
To: Baoquan He, Mike Rapoport
Cc: Rich Felker, linux-ia64, linux-doc, Catalin Marinas,
Heiko Carstens, Michal Hocko, James E.J. Bottomley, Max Filippov,
Guo Ren, linux-csky, sparclinux, linux-hexagon, linux-riscv,
Greg Ungerer, linux-arch, linux-s390, linux-snps-arc,
linux-c6x-dev, Brian Cain, Jonathan Corbet, linux-sh,
Helge Deller, x86, Russell King, Ley Foon Tan, Mike Rapoport,
Geert Uytterhoeven, linux-parisc, Mark Salter, Matt Turner,
linux-mips, uclinux-h8-devel, linux-xtensa, linux-alpha, linux-um,
linux-m68k, Tony Luck, Greentime Hu, Paul Walmsley,
Stafford Horne, Guan Xuetao, linux-arm-kernel, Michal Simek,
Thomas Bogendoerfer, Yoshinori Sato, Nick Hu, linux-mm,
Vineet Gupta, linux-kernel, openrisc, Richard Weinberger,
Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <20200423011312.GY4247@MiWiFi-R3L-srv>
Hi Mike and Baoquan,
On 4/22/20 6:13 PM, Baoquan He wrote:
> On 04/12/20 at 10:48pm, Mike Rapoport wrote:
>> From: Mike Rapoport <rppt@linux.ibm.com>
>>
>> The commit f47ac088c406 ("mm: memmap_init: iterate over memblock regions
>
> This commit id should be a temporary one, will be changed when merged
> into maintainer's tree and linus's tree. Only saying last patch plus the
> patch subject is OK?
>
>> rather that check each PFN") made early_pfn_in_nid() obsolete and since
>> CONFIG_NODES_SPAN_OTHER_NODES is only used to pick a stub or a real
>> implementation of early_pfn_in_nid() it is also not needed anymore.
>>
>> Remove both early_pfn_in_nid() and the CONFIG_NODES_SPAN_OTHER_NODES.
>>
>> Co-developed-by: Hoan Tran <Hoan@os.amperecomputing.com>
>> Signed-off-by: Hoan Tran <Hoan@os.amperecomputing.com>
>> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
>> ---
>> arch/powerpc/Kconfig | 9 ---------
>> arch/sparc/Kconfig | 9 ---------
>> arch/x86/Kconfig | 9 ---------
>> mm/page_alloc.c | 20 --------------------
>> 4 files changed, 47 deletions(-)
>>
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index 5f86b22b7d2c..74f316deeae1 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -685,15 +685,6 @@ config ARCH_MEMORY_PROBE
>> def_bool y
>> depends on MEMORY_HOTPLUG
>>
>> -# Some NUMA nodes have memory ranges that span
>> -# other nodes. Even though a pfn is valid and
>> -# between a node's start and end pfns, it may not
>> -# reside on that node. See memmap_init_zone()
>> -# for details.
>> -config NODES_SPAN_OTHER_NODES
>> - def_bool y
>> - depends on NEED_MULTIPLE_NODES
>> -
>> config STDBINUTILS
>> bool "Using standard binutils settings"
>> depends on 44x
>> diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
>> index 795206b7b552..0e4f3891b904 100644
>> --- a/arch/sparc/Kconfig
>> +++ b/arch/sparc/Kconfig
>> @@ -286,15 +286,6 @@ config NODES_SHIFT
>> Specify the maximum number of NUMA Nodes available on the target
>> system. Increases memory reserved to accommodate various tables.
>>
>> -# Some NUMA nodes have memory ranges that span
>> -# other nodes. Even though a pfn is valid and
>> -# between a node's start and end pfns, it may not
>> -# reside on that node. See memmap_init_zone()
>> -# for details.
>> -config NODES_SPAN_OTHER_NODES
>> - def_bool y
>> - depends on NEED_MULTIPLE_NODES
>> -
>> config ARCH_SPARSEMEM_ENABLE
>> def_bool y if SPARC64
>> select SPARSEMEM_VMEMMAP_ENABLE
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index 9d3e95b4fb85..37dac095659e 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -1581,15 +1581,6 @@ config X86_64_ACPI_NUMA
>> ---help---
>> Enable ACPI SRAT based node topology detection.
>>
>> -# Some NUMA nodes have memory ranges that span
>> -# other nodes. Even though a pfn is valid and
>> -# between a node's start and end pfns, it may not
>> -# reside on that node. See memmap_init_zone()
>> -# for details.
>> -config NODES_SPAN_OTHER_NODES
>> - def_bool y
>> - depends on X86_64_ACPI_NUMA
>> -
>> config NUMA_EMU
>> bool "NUMA emulation"
>> depends on NUMA
>> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
>> index c43ce8709457..343d87b8697d 100644
>> --- a/mm/page_alloc.c
>> +++ b/mm/page_alloc.c
>> @@ -1541,26 +1541,6 @@ int __meminit early_pfn_to_nid(unsigned long pfn)
>> }
>> #endif /* CONFIG_NEED_MULTIPLE_NODES */
>>
>> -#ifdef CONFIG_NODES_SPAN_OTHER_NODES
>> -/* Only safe to use early in boot when initialisation is single-threaded */
>> -static inline bool __meminit early_pfn_in_nid(unsigned long pfn, int node)
>> -{
>> - int nid;
>> -
>> - nid = __early_pfn_to_nid(pfn, &early_pfnnid_cache);
>> - if (nid >= 0 && nid != node)
>> - return false;
>> - return true;
>> -}
>> -
>> -#else
>> -static inline bool __meminit early_pfn_in_nid(unsigned long pfn, int node)
>> -{
>> - return true;
>> -}
>> -#endif
>
> And macro early_pfn_valid() is not needed either, we may need remove it
> too.
>
> Otherwise, removing NODES_SPAN_OTHER_NODES in this patch looks good.
>
> Reviewed-by: Baoquan He <bhe@redhat.com>
I have tested this patch set on Arm64, and it worked as expected with
the case where the node memory spans to other nodes or the old
NODES_SPAN_OTHER_NODES config.
Hope to the whole patch set will be upstream soon.
Thanks and Regards
Hoan
>
>> -
>> -
>> void __init memblock_free_pages(struct page *page, unsigned long pfn,
>> unsigned int order)
>> {
>> --
>> 2.25.1
>>
>
^ permalink raw reply
* [PATCH] soc: fsl: qe: Replace one-element array and use struct_size() helper
From: Gustavo A. R. Silva @ 2020-05-18 22:19 UTC (permalink / raw)
To: Qiang Zhao, Li Yang
Cc: Kees Cook, linuxppc-dev, linux-kernel, linux-arm-kernel,
Gustavo A. R. Silva
The current codebase makes use of one-element arrays in the following
form:
struct something {
int length;
u8 data[1];
};
struct something *instance;
instance = kmalloc(sizeof(*instance) + size, GFP_KERNEL);
instance->length = size;
memcpy(instance->data, source, size);
but the preferred mechanism to declare variable-length types such as
these ones is a flexible array member[1][2], introduced in C99:
struct foo {
int stuff;
struct boo array[];
};
By making use of the mechanism above, we will get a compiler warning
in case the flexible array does not occur last in the structure, which
will help us prevent some kind of undefined behavior bugs from being
inadvertently introduced[3] to the codebase from now on. So, replace
the one-element array with a flexible-array member.
Also, make use of the new struct_size() helper to properly calculate the
size of struct qe_firmware.
This issue was found with the help of Coccinelle and, audited and fixed
_manually_.
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
---
drivers/soc/fsl/qe/qe.c | 4 ++--
include/soc/fsl/qe/qe.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
index 447146861c2c1..2df20d6f85fa4 100644
--- a/drivers/soc/fsl/qe/qe.c
+++ b/drivers/soc/fsl/qe/qe.c
@@ -448,7 +448,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware)
unsigned int i;
unsigned int j;
u32 crc;
- size_t calc_size = sizeof(struct qe_firmware);
+ size_t calc_size;
size_t length;
const struct qe_header *hdr;
@@ -480,7 +480,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware)
}
/* Validate the length and check if there's a CRC */
- calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
+ calc_size = struct_size(firmware, microcode, firmware->count);
for (i = 0; i < firmware->count; i++)
/*
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h
index e282ac01ec081..3feddfec9f87d 100644
--- a/include/soc/fsl/qe/qe.h
+++ b/include/soc/fsl/qe/qe.h
@@ -307,7 +307,7 @@ struct qe_firmware {
u8 revision; /* The microcode version revision */
u8 padding; /* Reserved, for alignment */
u8 reserved[4]; /* Reserved, for future expansion */
- } __attribute__ ((packed)) microcode[1];
+ } __packed microcode[];
/* All microcode binaries should be located here */
/* CRC32 should be located here, after the microcode binaries */
} __attribute__ ((packed));
--
2.26.2
^ permalink raw reply related
* Re: [PATCH v4 6/6] ramoops: Add max_reason optional field to ramoops DT node
From: Rob Herring @ 2020-05-18 22:45 UTC (permalink / raw)
To: Kees Cook
Cc: Petr Mladek, Tony Luck, Pavel Tatashin, Jonathan Corbet,
Anton Vorontsov, Linux Doc Mailing List,
linux-kernel@vger.kernel.org, Steven Rostedt, Sergey Senozhatsky,
devicetree, Paul Mackerras, Colin Cross, Enric Balletbo i Serra,
linuxppc-dev, Benson Leung
In-Reply-To: <20200515184434.8470-7-keescook@chromium.org>
On Fri, May 15, 2020 at 12:44 PM Kees Cook <keescook@chromium.org> wrote:
>
> From: Pavel Tatashin <pasha.tatashin@soleen.com>
Subject still has 'max_reason'.
>
> Currently, it is possible to dump kmsges for panic, or oops.
> With max_reason it is possible to dump messages for other
And here.
> kmesg_dump events, for example reboot, halt, shutdown, kexec.
>
> Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
> Link: https://lore.kernel.org/lkml/20200506211523.15077-6-keescook@chromium.org/
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
> .../devicetree/bindings/reserved-memory/ramoops.txt | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/reserved-memory/ramoops.txt b/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
> index 0eba562fe5c6..b7886fea368c 100644
> --- a/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
> +++ b/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
> @@ -30,7 +30,7 @@ Optional properties:
> - ecc-size: enables ECC support and specifies ECC buffer size in bytes
> (defaults to 0: no ECC)
>
> -- record-size: maximum size in bytes of each dump done on oops/panic
> +- record-size: maximum size in bytes of each kmsg dump.
> (defaults to 0: disabled)
>
> - console-size: size in bytes of log buffer reserved for kernel messages
> @@ -45,7 +45,16 @@ Optional properties:
> - unbuffered: if present, use unbuffered mappings to map the reserved region
> (defaults to buffered mappings)
>
> -- no-dump-oops: if present, only dump panics (defaults to panics and oops)
> +- max-reason: if present, sets maximum type of kmsg dump reasons to store
> + (defaults to 2: log Oopses and Panics). This can be set to INT_MAX to
> + store all kmsg dumps. See include/linux/kmsg_dump.h KMSG_DUMP_* for other
> + kmsg dump reason values. Setting this to 0 (KMSG_DUMP_UNDEF), means the
> + reason filtering will be controlled by the printk.always_kmsg_dump boot
> + param: if unset, it will be KMSG_DUMP_OOPS, otherwise KMSG_DUMP_MAX.
> +
> +- no-dump-oops: deprecated, use max_reason instead. If present, and
> + max_reason is not specified, it is equivalent to max_reason = 1
And here (3 times).
> + (KMSG_DUMP_PANIC).
>
> - flags: if present, pass ramoops behavioral flags (defaults to 0,
> see include/linux/pstore_ram.h RAMOOPS_FLAG_* for flag values).
> --
> 2.20.1
>
^ permalink raw reply
* Re: [PATCH] soc: fsl: qe: Replace one-element array and use struct_size() helper
From: Kees Cook @ 2020-05-18 22:56 UTC (permalink / raw)
To: Gustavo A. R. Silva
Cc: Gustavo A. R. Silva, linux-kernel, Li Yang, linuxppc-dev,
linux-arm-kernel, Qiang Zhao
In-Reply-To: <20200518221904.GA22274@embeddedor>
On Mon, May 18, 2020 at 05:19:04PM -0500, Gustavo A. R. Silva wrote:
> The current codebase makes use of one-element arrays in the following
> form:
>
> struct something {
> int length;
> u8 data[1];
> };
>
> struct something *instance;
>
> instance = kmalloc(sizeof(*instance) + size, GFP_KERNEL);
> instance->length = size;
> memcpy(instance->data, source, size);
>
> but the preferred mechanism to declare variable-length types such as
> these ones is a flexible array member[1][2], introduced in C99:
>
> struct foo {
> int stuff;
> struct boo array[];
> };
>
> By making use of the mechanism above, we will get a compiler warning
> in case the flexible array does not occur last in the structure, which
> will help us prevent some kind of undefined behavior bugs from being
> inadvertently introduced[3] to the codebase from now on. So, replace
> the one-element array with a flexible-array member.
>
> Also, make use of the new struct_size() helper to properly calculate the
> size of struct qe_firmware.
>
> This issue was found with the help of Coccinelle and, audited and fixed
> _manually_.
>
> [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
> [2] https://github.com/KSPP/linux/issues/21
> [3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")
>
> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> ---
> drivers/soc/fsl/qe/qe.c | 4 ++--
> include/soc/fsl/qe/qe.h | 2 +-
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
> index 447146861c2c1..2df20d6f85fa4 100644
> --- a/drivers/soc/fsl/qe/qe.c
> +++ b/drivers/soc/fsl/qe/qe.c
> @@ -448,7 +448,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware)
> unsigned int i;
> unsigned int j;
> u32 crc;
> - size_t calc_size = sizeof(struct qe_firmware);
> + size_t calc_size;
> size_t length;
> const struct qe_header *hdr;
>
> @@ -480,7 +480,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware)
> }
>
> /* Validate the length and check if there's a CRC */
> - calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
> + calc_size = struct_size(firmware, microcode, firmware->count);
>
> for (i = 0; i < firmware->count; i++)
> /*
> diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h
> index e282ac01ec081..3feddfec9f87d 100644
> --- a/include/soc/fsl/qe/qe.h
> +++ b/include/soc/fsl/qe/qe.h
> @@ -307,7 +307,7 @@ struct qe_firmware {
> u8 revision; /* The microcode version revision */
> u8 padding; /* Reserved, for alignment */
> u8 reserved[4]; /* Reserved, for future expansion */
> - } __attribute__ ((packed)) microcode[1];
> + } __packed microcode[];
> /* All microcode binaries should be located here */
> /* CRC32 should be located here, after the microcode binaries */
> } __attribute__ ((packed));
> --
> 2.26.2
>
Hm, looking at this code, I see a few other things that need to be
fixed:
1) drivers/tty/serial/ucc_uart.c does not do a be32_to_cpu() conversion
on the length test (understandably, a little-endian system has never run
this code since it's ppc specific), but it's still wrong:
if (firmware->header.length != fw->size) {
compare to the firmware loader:
length = be32_to_cpu(hdr->length);
2) drivers/soc/fsl/qe/qe.c does not perform bounds checking on the
per-microcode offsets, so the uploader might send data outside the
firmware buffer. Perhaps:
diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
index 447146861c2c..c4e0bc452f03 100644
--- a/drivers/soc/fsl/qe/qe.c
+++ b/drivers/soc/fsl/qe/qe.c
@@ -451,6 +451,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware)
size_t calc_size = sizeof(struct qe_firmware);
size_t length;
const struct qe_header *hdr;
+ void *firmware_end;
if (!firmware) {
printk(KERN_ERR "qe-firmware: invalid pointer\n");
@@ -491,19 +492,39 @@ int qe_upload_firmware(const struct qe_firmware *firmware)
calc_size += sizeof(__be32) *
be32_to_cpu(firmware->microcode[i].count);
- /* Validate the length */
+ /* Validate total length */
if (length != calc_size + sizeof(__be32)) {
printk(KERN_ERR "qe-firmware: invalid length\n");
return -EPERM;
}
/* Validate the CRC */
- crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
+ firmware_end = (void *)firmware + calc_size;
+ crc = be32_to_cpu(*(__be32 *)firmware_end);
if (crc != crc32(0, firmware, calc_size)) {
printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
return -EIO;
}
+ /* Validate ucode lengths and offsets */
+ for (i = 0; i < firmware->count; i++) {
+ const struct qe_microcode *ucode = &firmware->microcode[i];
+ __be32 *code;
+ size_t count;
+
+ if (!ucode->code_offset)
+ continue;
+
+ code = (void *)firmware + be32_to_cpu(ucode->code_offset);
+ count = be32_to_cpu(ucode->count) * sizeof(*code);
+
+ if (code < firmware || code >= firmware_end ||
+ code + count < firmware || code + count >= firmware_end) {
+ printk(KERN_ERR "qe-firmware: invalid ucode offset\n");
+ return -EIO;
+ }
+ }
+
/*
* If the microcode calls for it, split the I-RAM.
*/
I haven't tested this.
--
Kees Cook
^ permalink raw reply related
* Re: [PATCH v4 6/6] ramoops: Add max_reason optional field to ramoops DT node
From: Kees Cook @ 2020-05-18 23:04 UTC (permalink / raw)
To: Rob Herring
Cc: Petr Mladek, Tony Luck, Pavel Tatashin, Jonathan Corbet,
Anton Vorontsov, Linux Doc Mailing List,
linux-kernel@vger.kernel.org, Steven Rostedt, Sergey Senozhatsky,
devicetree, Paul Mackerras, Colin Cross, Enric Balletbo i Serra,
linuxppc-dev, Benson Leung
In-Reply-To: <CAL_JsqLVgdUEP74nJOHOBD2abK=3YfCqX9GmL2iXdPNctcRdjw@mail.gmail.com>
On Mon, May 18, 2020 at 04:45:32PM -0600, Rob Herring wrote:
> On Fri, May 15, 2020 at 12:44 PM Kees Cook <keescook@chromium.org> wrote:
> >
> > From: Pavel Tatashin <pasha.tatashin@soleen.com>
>
> Subject still has 'max_reason'.
>
> >
> > Currently, it is possible to dump kmsges for panic, or oops.
> > With max_reason it is possible to dump messages for other
>
> And here.
Ah yeah, this was, I think, describing the internal field name, but I
see it would be less confusing to refer to this by the DT name. I will
adjust it. Thanks!
-Kees
>
> > kmesg_dump events, for example reboot, halt, shutdown, kexec.
> >
> > Signed-off-by: Pavel Tatashin <pasha.tatashin@soleen.com>
> > Link: https://lore.kernel.org/lkml/20200506211523.15077-6-keescook@chromium.org/
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> > .../devicetree/bindings/reserved-memory/ramoops.txt | 13 +++++++++++--
> > 1 file changed, 11 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/reserved-memory/ramoops.txt b/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
> > index 0eba562fe5c6..b7886fea368c 100644
> > --- a/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
> > +++ b/Documentation/devicetree/bindings/reserved-memory/ramoops.txt
> > @@ -30,7 +30,7 @@ Optional properties:
> > - ecc-size: enables ECC support and specifies ECC buffer size in bytes
> > (defaults to 0: no ECC)
> >
> > -- record-size: maximum size in bytes of each dump done on oops/panic
> > +- record-size: maximum size in bytes of each kmsg dump.
> > (defaults to 0: disabled)
> >
> > - console-size: size in bytes of log buffer reserved for kernel messages
> > @@ -45,7 +45,16 @@ Optional properties:
> > - unbuffered: if present, use unbuffered mappings to map the reserved region
> > (defaults to buffered mappings)
> >
> > -- no-dump-oops: if present, only dump panics (defaults to panics and oops)
> > +- max-reason: if present, sets maximum type of kmsg dump reasons to store
> > + (defaults to 2: log Oopses and Panics). This can be set to INT_MAX to
> > + store all kmsg dumps. See include/linux/kmsg_dump.h KMSG_DUMP_* for other
> > + kmsg dump reason values. Setting this to 0 (KMSG_DUMP_UNDEF), means the
> > + reason filtering will be controlled by the printk.always_kmsg_dump boot
> > + param: if unset, it will be KMSG_DUMP_OOPS, otherwise KMSG_DUMP_MAX.
> > +
> > +- no-dump-oops: deprecated, use max_reason instead. If present, and
> > + max_reason is not specified, it is equivalent to max_reason = 1
>
> And here (3 times).
>
> > + (KMSG_DUMP_PANIC).
> >
> > - flags: if present, pass ramoops behavioral flags (defaults to 0,
> > see include/linux/pstore_ram.h RAMOOPS_FLAG_* for flag values).
> > --
> > 2.20.1
> >
--
Kees Cook
^ permalink raw reply
* Re: [PATCH v5 2/2] powerpc/rtas: Implement reentrant rtas call
From: Leonardo Bras @ 2020-05-18 23:40 UTC (permalink / raw)
To: Nicholas Piggin, Allison Randal, Thiago Jung Bauermann,
Benjamin Herrenschmidt, Daniel Axtens, Gautham R. Shenoy,
Greg Kroah-Hartman, Anshuman Khandual, Michael Ellerman,
Nadav Amit, Nathan Lynch, Paul Mackerras, Thomas Gleixner
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1589614523.yfijifo1n6.astroid@bobo.none>
On Sat, 2020-05-16 at 17:36 +1000, Nicholas Piggin wrote:
> Good, I think this should work as you want now. Can you allocate it like
> lppacas? Put it under PSERIES (and in the paca) and check for !HV?
Sure, I will do that.
> Oh and while there, could you prefix the name with rtas_?
Sure, replacing reentrant_args with rtas_args_reentrant.
>
> Thanks,
> Nick
Thank you for the feedback!
Leonardo Bras
^ permalink raw reply
* [powerpc:next] BUILD SUCCESS 30df74d67d48949da87e3a5b57c381763e8fd526
From: kbuild test robot @ 2020-05-18 23:41 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
branch HEAD: 30df74d67d48949da87e3a5b57c381763e8fd526 powerpc/watchpoint/xmon: Support 2nd DAWR
elapsed time: 482m
configs tested: 98
configs skipped: 1
The following configs have been built successfully.
More configs may be tested in the coming days.
arm defconfig
arm allyesconfig
arm allmodconfig
arm allnoconfig
arm64 allyesconfig
arm64 defconfig
arm64 allmodconfig
arm64 allnoconfig
m68k allyesconfig
sparc allyesconfig
mips allyesconfig
i386 allnoconfig
i386 allyesconfig
i386 defconfig
i386 debian-10.3
ia64 allmodconfig
ia64 defconfig
ia64 allnoconfig
ia64 allyesconfig
m68k allmodconfig
m68k allnoconfig
m68k sun3_defconfig
m68k defconfig
nios2 defconfig
nios2 allyesconfig
openrisc defconfig
c6x allyesconfig
c6x allnoconfig
openrisc allyesconfig
nds32 defconfig
nds32 allnoconfig
csky allyesconfig
csky defconfig
alpha defconfig
alpha allyesconfig
xtensa allyesconfig
h8300 allyesconfig
h8300 allmodconfig
xtensa defconfig
arc defconfig
arc allyesconfig
sh allmodconfig
sh allnoconfig
microblaze allnoconfig
mips allnoconfig
mips allmodconfig
parisc allnoconfig
parisc defconfig
parisc allyesconfig
parisc allmodconfig
powerpc defconfig
powerpc allyesconfig
powerpc rhel-kconfig
powerpc allmodconfig
powerpc allnoconfig
i386 randconfig-a006-20200518
i386 randconfig-a005-20200518
i386 randconfig-a001-20200518
i386 randconfig-a003-20200518
i386 randconfig-a004-20200518
i386 randconfig-a002-20200518
x86_64 randconfig-a016-20200518
x86_64 randconfig-a012-20200518
x86_64 randconfig-a015-20200518
x86_64 randconfig-a013-20200518
x86_64 randconfig-a011-20200518
x86_64 randconfig-a014-20200518
i386 randconfig-a012-20200518
i386 randconfig-a014-20200518
i386 randconfig-a016-20200518
i386 randconfig-a011-20200518
i386 randconfig-a015-20200518
i386 randconfig-a013-20200518
riscv allyesconfig
riscv allnoconfig
riscv defconfig
riscv allmodconfig
s390 allyesconfig
s390 allnoconfig
s390 allmodconfig
s390 defconfig
x86_64 defconfig
sparc defconfig
sparc64 defconfig
sparc64 allnoconfig
sparc64 allyesconfig
sparc64 allmodconfig
um allmodconfig
um allnoconfig
um allyesconfig
um defconfig
x86_64 rhel
x86_64 rhel-7.6
x86_64 rhel-7.6-kselftests
x86_64 rhel-7.2-clear
x86_64 lkp
x86_64 fedora-25
x86_64 kexec
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
^ permalink raw reply
* [PATCH v6 0/2] Implement reentrant rtas call
From: Leonardo Bras @ 2020-05-18 23:42 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Allison Randal, Greg Kroah-Hartman, Thomas Gleixner,
Nicholas Piggin, Leonardo Bras, Nathan Lynch, Gautham R. Shenoy,
Nadav Amit
Cc: linuxppc-dev, linux-kernel
Patch 2 implement rtas_call_reentrant() for reentrant rtas-calls:
"ibm,int-on", "ibm,int-off",ibm,get-xive" and "ibm,set-xive",
according to LoPAPR Version 1.1 (March 24, 2016).
For that, it's necessary that every call uses a different
rtas buffer (rtas_args). Paul Mackerras suggested using the PACA
structure for creating a per-cpu buffer for these calls.
Patch 1 was necessary to make PACA have a 'struct rtas_args' member.
Reentrant rtas calls can be useful to avoid deadlocks in crashing,
where rtas-calls are needed, but some other thread crashed holding
the rtas.lock.
This is a backtrace of a deadlock from a kdump testing environment:
#0 arch_spin_lock
#1 lock_rtas ()
#2 rtas_call (token=8204, nargs=1, nret=1, outputs=0x0)
#3 ics_rtas_mask_real_irq (hw_irq=4100)
#4 machine_kexec_mask_interrupts
#5 default_machine_crash_shutdown
#6 machine_crash_shutdown
#7 __crash_kexec
#8 crash_kexec
#9 oops_end
Signed-off-by: Leonardo Bras <leobras.c@gmail.com>
Special thanks to Nick Piggin, who have been helping me a lot with
this series!
---
Changes since v5:
- Renames new paca member from reentrant_args to rtas_args_reentrant
- Compile out rtas_args_reentrant if CONFIG_PPC_RTAS=n
- new_rtas_args() is skipped (returns NULL) if CPU_FTR_HVMODE
Changes since v4:
- Insted of having the full buffer on PACA, adds only a pointer and
allocate it during allocate_paca(), making sure it's in a memory
range available for RTAS (32-bit). (Thanks Nick Piggin!)
Changes since v3:
- Adds protection from preemption and interruption
Changes since v2:
- Fixed build failure from ppc64e, by including spinlock_types.h on
rtas-types.h
- Improved commit messages
Changes since v1:
- Moved buffer from stack to PACA (as suggested by Paul Mackerras)
- Added missing output bits
- Improve documentation following kernel-doc format (as suggested by
Nathan Lynch)
Leonardo Bras (2):
powerpc/rtas: Move type/struct definitions from rtas.h into
rtas-types.h
powerpc/rtas: Implement reentrant rtas call
arch/powerpc/include/asm/paca.h | 2 +
arch/powerpc/include/asm/rtas-types.h | 126 ++++++++++++++++++++++++++
arch/powerpc/include/asm/rtas.h | 119 +-----------------------
arch/powerpc/kernel/rtas.c | 42 +++++++++
arch/powerpc/sysdev/xics/ics-rtas.c | 22 ++---
5 files changed, 183 insertions(+), 128 deletions(-)
create mode 100644 arch/powerpc/include/asm/rtas-types.h
--
2.25.4
^ permalink raw reply
* [PATCH v6 1/2] powerpc/rtas: Move type/struct definitions from rtas.h into rtas-types.h
From: Leonardo Bras @ 2020-05-18 23:42 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Nicholas Piggin, Allison Randal, Thomas Gleixner,
Greg Kroah-Hartman, Leonardo Bras, Thiago Jung Bauermann,
Anshuman Khandual, Daniel Axtens, Nathan Lynch, Gautham R. Shenoy,
Nadav Amit
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20200518234245.200672-1-leobras.c@gmail.com>
In order to get any rtas* struct into other headers, including rtas.h
may cause a lot of errors, regarding include dependency needed for
inline functions.
Create rtas-types.h and move there all type/struct definitions
from rtas.h, then include rtas-types.h into rtas.h.
Also, as suggested by checkpath.pl, replace uint8_t for u8, and keep
the same type pattern for the whole file, as they are the same
according to powerpc/boot/types.h.
Signed-off-by: Leonardo Bras <leobras.c@gmail.com>
---
arch/powerpc/include/asm/rtas-types.h | 126 ++++++++++++++++++++++++++
arch/powerpc/include/asm/rtas.h | 118 +-----------------------
2 files changed, 127 insertions(+), 117 deletions(-)
create mode 100644 arch/powerpc/include/asm/rtas-types.h
diff --git a/arch/powerpc/include/asm/rtas-types.h b/arch/powerpc/include/asm/rtas-types.h
new file mode 100644
index 000000000000..87354e28f160
--- /dev/null
+++ b/arch/powerpc/include/asm/rtas-types.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _POWERPC_RTAS_TYPES_H
+#define _POWERPC_RTAS_TYPES_H
+#ifdef __KERNEL__
+
+#include <linux/spinlock_types.h>
+
+typedef __be32 rtas_arg_t;
+
+struct rtas_args {
+ __be32 token;
+ __be32 nargs;
+ __be32 nret;
+ rtas_arg_t args[16];
+ rtas_arg_t *rets; /* Pointer to return values in args[]. */
+};
+
+struct rtas_t {
+ unsigned long entry; /* physical address pointer */
+ unsigned long base; /* physical address pointer */
+ unsigned long size;
+ arch_spinlock_t lock;
+ struct rtas_args args;
+ struct device_node *dev; /* virtual address pointer */
+};
+
+struct rtas_suspend_me_data {
+ atomic_t working; /* number of cpus accessing this struct */
+ atomic_t done;
+ int token; /* ibm,suspend-me */
+ atomic_t error;
+ struct completion *complete; /* wait on this until working == 0 */
+};
+
+struct rtas_error_log {
+ /* Byte 0 */
+ u8 byte0; /* Architectural version */
+
+ /* Byte 1 */
+ u8 byte1;
+ /* XXXXXXXX
+ * XXX 3: Severity level of error
+ * XX 2: Degree of recovery
+ * X 1: Extended log present?
+ * XX 2: Reserved
+ */
+
+ /* Byte 2 */
+ u8 byte2;
+ /* XXXXXXXX
+ * XXXX 4: Initiator of event
+ * XXXX 4: Target of failed operation
+ */
+ u8 byte3; /* General event or error*/
+ __be32 extended_log_length; /* length in bytes */
+ unsigned char buffer[1]; /* Start of extended log */
+ /* Variable length. */
+};
+
+/* RTAS general extended event log, Version 6. The extended log starts
+ * from "buffer" field of struct rtas_error_log defined above.
+ */
+struct rtas_ext_event_log_v6 {
+ /* Byte 0 */
+ u8 byte0;
+ /* XXXXXXXX
+ * X 1: Log valid
+ * X 1: Unrecoverable error
+ * X 1: Recoverable (correctable or successfully retried)
+ * X 1: Bypassed unrecoverable error (degraded operation)
+ * X 1: Predictive error
+ * X 1: "New" log (always 1 for data returned from RTAS)
+ * X 1: Big Endian
+ * X 1: Reserved
+ */
+
+ /* Byte 1 */
+ u8 byte1; /* reserved */
+
+ /* Byte 2 */
+ u8 byte2;
+ /* XXXXXXXX
+ * X 1: Set to 1 (indicating log is in PowerPC format)
+ * XXX 3: Reserved
+ * XXXX 4: Log format used for bytes 12-2047
+ */
+
+ /* Byte 3 */
+ u8 byte3; /* reserved */
+ /* Byte 4-11 */
+ u8 reserved[8]; /* reserved */
+ /* Byte 12-15 */
+ __be32 company_id; /* Company ID of the company */
+ /* that defines the format for */
+ /* the vendor specific log type */
+ /* Byte 16-end of log */
+ u8 vendor_log[1]; /* Start of vendor specific log */
+ /* Variable length. */
+};
+
+/* Vendor specific Platform Event Log Format, Version 6, section header */
+struct pseries_errorlog {
+ __be16 id; /* 0x00 2-byte ASCII section ID */
+ __be16 length; /* 0x02 Section length in bytes */
+ u8 version; /* 0x04 Section version */
+ u8 subtype; /* 0x05 Section subtype */
+ __be16 creator_component; /* 0x06 Creator component ID */
+ u8 data[]; /* 0x08 Start of section data */
+};
+
+/* RTAS pseries hotplug errorlog section */
+struct pseries_hp_errorlog {
+ u8 resource;
+ u8 action;
+ u8 id_type;
+ u8 reserved;
+ union {
+ __be32 drc_index;
+ __be32 drc_count;
+ struct { __be32 count, index; } ic;
+ char drc_name[1];
+ } _drc_u;
+};
+
+#endif /* __KERNEL__ */
+#endif /* _POWERPC_RTAS_TYPES_H */
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 3c1887351c71..c35c5350b7e4 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -5,6 +5,7 @@
#include <linux/spinlock.h>
#include <asm/page.h>
+#include <asm/rtas-types.h>
#include <linux/time.h>
#include <linux/cpumask.h>
@@ -42,33 +43,6 @@
*
*/
-typedef __be32 rtas_arg_t;
-
-struct rtas_args {
- __be32 token;
- __be32 nargs;
- __be32 nret;
- rtas_arg_t args[16];
- rtas_arg_t *rets; /* Pointer to return values in args[]. */
-};
-
-struct rtas_t {
- unsigned long entry; /* physical address pointer */
- unsigned long base; /* physical address pointer */
- unsigned long size;
- arch_spinlock_t lock;
- struct rtas_args args;
- struct device_node *dev; /* virtual address pointer */
-};
-
-struct rtas_suspend_me_data {
- atomic_t working; /* number of cpus accessing this struct */
- atomic_t done;
- int token; /* ibm,suspend-me */
- atomic_t error;
- struct completion *complete; /* wait on this until working == 0 */
-};
-
/* RTAS event classes */
#define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */
#define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */
@@ -148,31 +122,6 @@ struct rtas_suspend_me_data {
/* RTAS check-exception vector offset */
#define RTAS_VECTOR_EXTERNAL_INTERRUPT 0x500
-struct rtas_error_log {
- /* Byte 0 */
- uint8_t byte0; /* Architectural version */
-
- /* Byte 1 */
- uint8_t byte1;
- /* XXXXXXXX
- * XXX 3: Severity level of error
- * XX 2: Degree of recovery
- * X 1: Extended log present?
- * XX 2: Reserved
- */
-
- /* Byte 2 */
- uint8_t byte2;
- /* XXXXXXXX
- * XXXX 4: Initiator of event
- * XXXX 4: Target of failed operation
- */
- uint8_t byte3; /* General event or error*/
- __be32 extended_log_length; /* length in bytes */
- unsigned char buffer[1]; /* Start of extended log */
- /* Variable length. */
-};
-
static inline uint8_t rtas_error_severity(const struct rtas_error_log *elog)
{
return (elog->byte1 & 0xE0) >> 5;
@@ -212,47 +161,6 @@ uint32_t rtas_error_extended_log_length(const struct rtas_error_log *elog)
#define RTAS_V6EXT_COMPANY_ID_IBM (('I' << 24) | ('B' << 16) | ('M' << 8))
-/* RTAS general extended event log, Version 6. The extended log starts
- * from "buffer" field of struct rtas_error_log defined above.
- */
-struct rtas_ext_event_log_v6 {
- /* Byte 0 */
- uint8_t byte0;
- /* XXXXXXXX
- * X 1: Log valid
- * X 1: Unrecoverable error
- * X 1: Recoverable (correctable or successfully retried)
- * X 1: Bypassed unrecoverable error (degraded operation)
- * X 1: Predictive error
- * X 1: "New" log (always 1 for data returned from RTAS)
- * X 1: Big Endian
- * X 1: Reserved
- */
-
- /* Byte 1 */
- uint8_t byte1; /* reserved */
-
- /* Byte 2 */
- uint8_t byte2;
- /* XXXXXXXX
- * X 1: Set to 1 (indicating log is in PowerPC format)
- * XXX 3: Reserved
- * XXXX 4: Log format used for bytes 12-2047
- */
-
- /* Byte 3 */
- uint8_t byte3; /* reserved */
- /* Byte 4-11 */
- uint8_t reserved[8]; /* reserved */
- /* Byte 12-15 */
- __be32 company_id; /* Company ID of the company */
- /* that defines the format for */
- /* the vendor specific log type */
- /* Byte 16-end of log */
- uint8_t vendor_log[1]; /* Start of vendor specific log */
- /* Variable length. */
-};
-
static
inline uint8_t rtas_ext_event_log_format(struct rtas_ext_event_log_v6 *ext_log)
{
@@ -287,16 +195,6 @@ inline uint32_t rtas_ext_event_company_id(struct rtas_ext_event_log_v6 *ext_log)
#define PSERIES_ELOG_SECT_ID_HOTPLUG (('H' << 8) | 'P')
#define PSERIES_ELOG_SECT_ID_MCE (('M' << 8) | 'C')
-/* Vendor specific Platform Event Log Format, Version 6, section header */
-struct pseries_errorlog {
- __be16 id; /* 0x00 2-byte ASCII section ID */
- __be16 length; /* 0x02 Section length in bytes */
- uint8_t version; /* 0x04 Section version */
- uint8_t subtype; /* 0x05 Section subtype */
- __be16 creator_component; /* 0x06 Creator component ID */
- uint8_t data[]; /* 0x08 Start of section data */
-};
-
static
inline uint16_t pseries_errorlog_id(struct pseries_errorlog *sect)
{
@@ -309,20 +207,6 @@ inline uint16_t pseries_errorlog_length(struct pseries_errorlog *sect)
return be16_to_cpu(sect->length);
}
-/* RTAS pseries hotplug errorlog section */
-struct pseries_hp_errorlog {
- u8 resource;
- u8 action;
- u8 id_type;
- u8 reserved;
- union {
- __be32 drc_index;
- __be32 drc_count;
- struct { __be32 count, index; } ic;
- char drc_name[1];
- } _drc_u;
-};
-
#define PSERIES_HP_ELOG_RESOURCE_CPU 1
#define PSERIES_HP_ELOG_RESOURCE_MEM 2
#define PSERIES_HP_ELOG_RESOURCE_SLOT 3
--
2.25.4
^ permalink raw reply related
* [PATCH v6 2/2] powerpc/rtas: Implement reentrant rtas call
From: Leonardo Bras @ 2020-05-18 23:42 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Nicholas Piggin, Allison Randal, Thomas Gleixner,
Greg Kroah-Hartman, Leonardo Bras, Thiago Jung Bauermann,
Anshuman Khandual, Daniel Axtens, Nathan Lynch, Gautham R. Shenoy,
Nadav Amit
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20200518234245.200672-1-leobras.c@gmail.com>
Implement rtas_call_reentrant() for reentrant rtas-calls:
"ibm,int-on", "ibm,int-off",ibm,get-xive" and "ibm,set-xive".
On LoPAPR Version 1.1 (March 24, 2016), from 7.3.10.1 to 7.3.10.4,
items 2 and 3 say:
2 - For the PowerPC External Interrupt option: The * call must be
reentrant to the number of processors on the platform.
3 - For the PowerPC External Interrupt option: The * argument call
buffer for each simultaneous call must be physically unique.
So, these rtas-calls can be called in a lockless way, if using
a different buffer for each cpu doing such rtas call.
For this, it was suggested to add the buffer (struct rtas_args)
in the PACA struct, so each cpu can have it's own buffer.
The PACA struct received a pointer to rtas buffer, which is
allocated in the memory range available to rtas 32-bit.
Reentrant rtas calls are useful to avoid deadlocks in crashing,
where rtas-calls are needed, but some other thread crashed holding
the rtas.lock.
This is a backtrace of a deadlock from a kdump testing environment:
#0 arch_spin_lock
#1 lock_rtas ()
#2 rtas_call (token=8204, nargs=1, nret=1, outputs=0x0)
#3 ics_rtas_mask_real_irq (hw_irq=4100)
#4 machine_kexec_mask_interrupts
#5 default_machine_crash_shutdown
#6 machine_crash_shutdown
#7 __crash_kexec
#8 crash_kexec
#9 oops_end
Signed-off-by: Leonardo Bras <leobras.c@gmail.com>
---
arch/powerpc/include/asm/paca.h | 4 +++
arch/powerpc/include/asm/rtas.h | 1 +
arch/powerpc/kernel/paca.c | 34 +++++++++++++++++++
arch/powerpc/kernel/rtas.c | 52 +++++++++++++++++++++++++++++
arch/powerpc/sysdev/xics/ics-rtas.c | 22 ++++++------
5 files changed, 102 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index e3cc9eb9204d..1e2d45f3f84c 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -29,6 +29,7 @@
#include <asm/hmi.h>
#include <asm/cpuidle.h>
#include <asm/atomic.h>
+#include <asm/rtas-types.h>
#include <asm-generic/mmiowb_types.h>
@@ -270,6 +271,9 @@ struct paca_struct {
#ifdef CONFIG_MMIOWB
struct mmiowb_state mmiowb_state;
#endif
+#ifdef CONFIG_PPC_RTAS
+ struct rtas_args *rtas_args_reentrant;
+#endif /* CONFIG_PPC_RTAS */
} ____cacheline_aligned;
extern void copy_mm_to_paca(struct mm_struct *mm);
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index c35c5350b7e4..fa7509c85881 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -236,6 +236,7 @@ extern struct rtas_t rtas;
extern int rtas_token(const char *service);
extern int rtas_service_present(const char *service);
extern int rtas_call(int token, int, int, int *, ...);
+int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...);
void rtas_call_unlocked(struct rtas_args *args, int token, int nargs,
int nret, ...);
extern void __noreturn rtas_restart(char *cmd);
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 3f91ccaa9c74..04855ad455c7 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -16,6 +16,7 @@
#include <asm/kexec.h>
#include <asm/svm.h>
#include <asm/ultravisor.h>
+#include <asm/rtas.h>
#include "setup.h"
@@ -164,6 +165,32 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit)
#endif /* CONFIG_PPC_BOOK3S_64 */
+#ifdef CONFIG_PPC_RTAS
+
+/**
+ * new_rtas_args() - Allocates rtas args
+ * @cpu: CPU number
+ * @limit: Memory limit for this allocation
+ *
+ * Allocates a struct rtas_args and return it's pointer,
+ * if not in Hypervisor mode
+ *
+ * Return: Pointer to allocated rtas_args
+ * NULL if CPU in Hypervisor Mode
+ */
+static struct rtas_args * __init new_rtas_args(int cpu, unsigned long limit)
+{
+ limit = min_t(unsigned long, limit, RTAS_INSTANTIATE_MAX);
+
+ if (early_cpu_has_feature(CPU_FTR_HVMODE))
+ return NULL;
+
+ return alloc_paca_data(sizeof(struct rtas_args), L1_CACHE_BYTES,
+ limit, cpu);
+}
+
+#endif /*CONFIG_PPC_RTAS*/
+
/* The Paca is an array with one entry per processor. Each contains an
* lppaca, which contains the information shared between the
* hypervisor and Linux.
@@ -202,6 +229,10 @@ void __init __nostackprotector initialise_paca(struct paca_struct *new_paca, int
/* For now -- if we have threads this will be adjusted later */
new_paca->tcd_ptr = &new_paca->tcd;
#endif
+
+#ifdef CONFIG_PPC_RTAS
+ new_paca->rtas_args_reentrant = NULL;
+#endif
}
/* Put the paca pointer into r13 and SPRG_PACA */
@@ -273,6 +304,9 @@ void __init allocate_paca(int cpu)
#endif
#ifdef CONFIG_PPC_BOOK3S_64
paca->slb_shadow_ptr = new_slb_shadow(cpu, limit);
+#endif
+#ifdef CONFIG_PPC_RTAS
+ paca->rtas_args_reentrant = new_rtas_args(cpu, limit);
#endif
paca_struct_size += sizeof(struct paca_struct);
}
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index c5fa251b8950..7b8864abd1ab 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -41,6 +41,7 @@
#include <asm/time.h>
#include <asm/mmu.h>
#include <asm/topology.h>
+#include <asm/paca.h>
/* This is here deliberately so it's only used in this file */
void enter_rtas(unsigned long);
@@ -483,6 +484,57 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
}
EXPORT_SYMBOL(rtas_call);
+/**
+ * rtas_call_reentrant() - Used for reentrant rtas calls
+ * @token: Token for desired reentrant RTAS call
+ * @nargs: Number of Input Parameters
+ * @nret: Number of Output Parameters
+ * @outputs: Array of outputs
+ * @...: Inputs for desired RTAS call
+ *
+ * According to LoPAR documentation, only "ibm,int-on", "ibm,int-off",
+ * "ibm,get-xive" and "ibm,set-xive" are currently reentrant.
+ * Reentrant calls need their own rtas_args buffer, so not using rtas.args, but
+ * PACA one instead.
+ *
+ * Return: -1 on error,
+ * First output value of RTAS call if (nret > 0),
+ * 0 otherwise,
+ */
+
+int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...)
+{
+ va_list list;
+ struct rtas_args *args;
+ unsigned long flags;
+ int i, ret = 0;
+
+ if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE)
+ return -1;
+
+ local_irq_save(flags);
+ preempt_disable();
+
+ /* We use the per-cpu (PACA) rtas args buffer */
+ args = local_paca->rtas_args_reentrant;
+
+ va_start(list, outputs);
+ va_rtas_call_unlocked(args, token, nargs, nret, list);
+ va_end(list);
+
+ if (nret > 1 && outputs)
+ for (i = 0; i < nret - 1; ++i)
+ outputs[i] = be32_to_cpu(args->rets[i + 1]);
+
+ if (nret > 0)
+ ret = be32_to_cpu(args->rets[0]);
+
+ local_irq_restore(flags);
+ preempt_enable();
+
+ return ret;
+}
+
/* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status
* code of 990n, perform the hinted delay of 10^n (last digit) milliseconds.
*/
diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
index 6aabc74688a6..4cf18000f07c 100644
--- a/arch/powerpc/sysdev/xics/ics-rtas.c
+++ b/arch/powerpc/sysdev/xics/ics-rtas.c
@@ -50,8 +50,8 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);
- call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq, server,
- DEFAULT_PRIORITY);
+ call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
+ server, DEFAULT_PRIORITY);
if (call_status != 0) {
printk(KERN_ERR
"%s: ibm_set_xive irq %u server %x returned %d\n",
@@ -60,7 +60,7 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
}
/* Now unmask the interrupt (often a no-op) */
- call_status = rtas_call(ibm_int_on, 1, 1, NULL, hw_irq);
+ call_status = rtas_call_reentrant(ibm_int_on, 1, 1, NULL, hw_irq);
if (call_status != 0) {
printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
__func__, hw_irq, call_status);
@@ -91,7 +91,7 @@ static void ics_rtas_mask_real_irq(unsigned int hw_irq)
if (hw_irq == XICS_IPI)
return;
- call_status = rtas_call(ibm_int_off, 1, 1, NULL, hw_irq);
+ call_status = rtas_call_reentrant(ibm_int_off, 1, 1, NULL, hw_irq);
if (call_status != 0) {
printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
__func__, hw_irq, call_status);
@@ -99,8 +99,8 @@ static void ics_rtas_mask_real_irq(unsigned int hw_irq)
}
/* Have to set XIVE to 0xff to be able to remove a slot */
- call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq,
- xics_default_server, 0xff);
+ call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
+ xics_default_server, 0xff);
if (call_status != 0) {
printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
__func__, hw_irq, call_status);
@@ -131,7 +131,7 @@ static int ics_rtas_set_affinity(struct irq_data *d,
if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
return -1;
- status = rtas_call(ibm_get_xive, 1, 3, xics_status, hw_irq);
+ status = rtas_call_reentrant(ibm_get_xive, 1, 3, xics_status, hw_irq);
if (status) {
printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
@@ -146,8 +146,8 @@ static int ics_rtas_set_affinity(struct irq_data *d,
return -1;
}
- status = rtas_call(ibm_set_xive, 3, 1, NULL,
- hw_irq, irq_server, xics_status[1]);
+ status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL,
+ hw_irq, irq_server, xics_status[1]);
if (status) {
printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
@@ -179,7 +179,7 @@ static int ics_rtas_map(struct ics *ics, unsigned int virq)
return -EINVAL;
/* Check if RTAS knows about this interrupt */
- rc = rtas_call(ibm_get_xive, 1, 3, status, hw_irq);
+ rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, hw_irq);
if (rc)
return -ENXIO;
@@ -198,7 +198,7 @@ static long ics_rtas_get_server(struct ics *ics, unsigned long vec)
{
int rc, status[2];
- rc = rtas_call(ibm_get_xive, 1, 3, status, vec);
+ rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, vec);
if (rc)
return -1;
return status[0];
--
2.25.4
^ permalink raw reply related
* Re: [PATCH V3 07/15] arch/kunmap_atomic: Consolidate duplicate code
From: Ira Weiny @ 2020-05-19 0:03 UTC (permalink / raw)
To: Guenter Roeck
Cc: Peter Zijlstra, Dave Hansen, dri-devel, linux-mips,
James E.J. Bottomley, Max Filippov, Paul Mackerras,
H. Peter Anvin, sparclinux, Dan Williams, Helge Deller, x86,
linux-csky, Christoph Hellwig, Ingo Molnar, linux-snps-arc,
linux-xtensa, Borislav Petkov, Al Viro, Andy Lutomirski,
Thomas Gleixner, linux-arm-kernel, Chris Zankel,
Thomas Bogendoerfer, linux-parisc, linux-kernel, Christian Koenig,
Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <20200518042932.GA59205@roeck-us.net>
On Sun, May 17, 2020 at 09:29:32PM -0700, Guenter Roeck wrote:
> On Sun, May 17, 2020 at 08:49:39PM -0700, Ira Weiny wrote:
> > On Sat, May 16, 2020 at 03:33:06PM -0700, Guenter Roeck wrote:
> > > On Thu, May 07, 2020 at 07:59:55AM -0700, ira.weiny@intel.com wrote:
> > > > From: Ira Weiny <ira.weiny@intel.com>
> > > >
> > > > Every single architecture (including !CONFIG_HIGHMEM) calls...
> > > >
> > > > pagefault_enable();
> > > > preempt_enable();
> > > >
> > > > ... before returning from __kunmap_atomic(). Lift this code into the
> > > > kunmap_atomic() macro.
> > > >
> > > > While we are at it rename __kunmap_atomic() to kunmap_atomic_high() to
> > > > be consistent.
> > > >
> > > > Reviewed-by: Christoph Hellwig <hch@lst.de>
> > > > Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> > >
> > > This patch results in:
> > >
> > > Starting init: /bin/sh exists but couldn't execute it (error -14)
> > >
> > > when trying to boot microblazeel:petalogix-ml605 in qemu.
> >
> > Thanks for the report. I'm not readily seeing the issue.
> >
> > Do you have a kernel config? Specifically is CONFIG_HIGHMEM set?
> >
> See below. Yes, CONFIG_HIGHMEM is set.
>
> The scripts used to build and boot the image are at:
>
> https://github.com/groeck/linux-build-test/tree/master/rootfs/microblazeel
Despite finding the obvious error earlier today I've still been trying to get
this to work.
I had to make some slight modifications to use the 0-day cross compile build
and my local qemu build. But those were pretty minor modifications. I'm
running on x86_64 host.
With those slight mods to the scripts I get the following error even without my
patch set on 5.7-rc4. I have 1 cpu pegged at 100% while it is running... Is
there anything I can do to get more debug output? Perhaps I just need to let
it run longer?
Thanks,
Ira
16:46:54 > ../linux-build-test/rootfs/microblazeel/run-qemu-microblazeel.sh
Build reference: v5.7-rc4-2-g7c2411d7fb6a
Building microblaze:petalogix-s3adsp1800:qemu_microblazeel_defconfig ...
running ................ failed (silent)
------------
qemu log:
qemu-system-microblazeel: terminating on signal 15 from pid 3277686 (/bin/bash)
------------
Building microblaze:petalogix-ml605:qemu_microblazeel_ml605_defconfig ...
running ................ failed (silent)
------------
qemu log:
qemu-system-microblazeel: terminating on signal 15 from pid 3277686 (/bin/bash)
------------
<env changes>
16:47:23 > git di
diff --git a/rootfs/microblazeel/run-qemu-microblazeel.sh b/rootfs/microblazeel/run-qemu-microblazeel.sh
index 68d4de39ab50..0d6a4f85308f 100755
--- a/rootfs/microblazeel/run-qemu-microblazeel.sh
+++ b/rootfs/microblazeel/run-qemu-microblazeel.sh
@@ -3,7 +3,8 @@
dir=$(cd $(dirname $0); pwd)
. ${dir}/../scripts/common.sh
-QEMU=${QEMU:-${QEMU_BIN}/qemu-system-microblazeel}
+#QEMU=${QEMU:-${QEMU_BIN}/qemu-system-microblazeel}
+QEMU=/home/iweiny/dev/qemu/microblazeel-softmmu/qemu-system-microblazeel
PREFIX=microblazeel-linux-
ARCH=microblaze
PATH_MICROBLAZE=/opt/kernel/microblazeel/gcc-4.9.1/usr/bin
diff --git a/rootfs/scripts/common.sh b/rootfs/scripts/common.sh
index 8fa6a9be2b2f..c4550a27beaa 100644
--- a/rootfs/scripts/common.sh
+++ b/rootfs/scripts/common.sh
@@ -1,5 +1,9 @@
#!/bin/bash
+# Set up make.cross
+export COMPILER_INSTALL_PATH=$HOME/0day
+export GCC_VERSION=6.5.0
+
# Set the following variable to true to skip DC395/AM53C97 build tests
__skip_dc395=0
@@ -569,7 +573,7 @@ doclean()
then
git clean -x -d -f -q
else
- make ARCH=${ARCH} mrproper >/dev/null 2>&1
+ make.cross ARCH=${ARCH} mrproper >/dev/null 2>&1
fi
}
@@ -669,7 +673,7 @@ __setup_config()
cp ${__progdir}/${defconfig} arch/${arch}/configs
fi
- if ! make ARCH=${ARCH} CROSS_COMPILE=${PREFIX} ${defconfig} >/dev/null 2>&1 </dev/null; then
+ if ! make.cross ARCH=${ARCH} ${defconfig} >/dev/null 2>&1 </dev/null; then
return 2
fi
@@ -687,7 +691,7 @@ __setup_config()
if [[ "${rel}" = "v3.16" ]]; then
target="oldconfig"
fi
- if ! make ARCH=${ARCH} CROSS_COMPILE=${PREFIX} ${target} >/dev/null 2>&1 </dev/null; then
+ if ! make.cross ARCH=${ARCH} ${target} >/dev/null 2>&1 </dev/null; then
return 1
fi
fi
@@ -1038,7 +1042,7 @@ dosetup()
rootfs="$(setup_rootfs ${dynamic} ${rootfs})"
__common_fixups "${fixups}" "${rootfs}"
- make -j${maxload} ARCH=${ARCH} CROSS_COMPILE=${PREFIX} ${EXTRAS} </dev/null >/dev/null 2>${logfile}
+ make.cross -j${maxload} ARCH=${ARCH} ${EXTRAS} </dev/null >/dev/null 2>${logfile}
rv=$?
if [ ${rv} -ne 0 ]
then
</env changes>
^ permalink raw reply related
* [powerpc:merge] BUILD SUCCESS 7b06fb8795ffea9d12be45a172197c3307955479
From: kbuild test robot @ 2020-05-19 0:25 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git merge
branch HEAD: 7b06fb8795ffea9d12be45a172197c3307955479 Automatic merge of 'master', 'next' and 'fixes' (2020-05-18 12:23)
elapsed time: 526m
configs tested: 92
configs skipped: 7
The following configs have been built successfully.
More configs may be tested in the coming days.
arm64 allyesconfig
arm64 defconfig
arm64 allmodconfig
arm64 allnoconfig
arm defconfig
arm allyesconfig
arm allmodconfig
arm allnoconfig
mips allyesconfig
m68k allyesconfig
i386 allnoconfig
i386 allyesconfig
i386 defconfig
i386 debian-10.3
ia64 allmodconfig
ia64 defconfig
ia64 allnoconfig
ia64 allyesconfig
m68k allmodconfig
m68k allnoconfig
m68k sun3_defconfig
m68k defconfig
nds32 defconfig
nds32 allnoconfig
csky allyesconfig
csky defconfig
alpha defconfig
alpha allyesconfig
xtensa allyesconfig
h8300 allyesconfig
h8300 allmodconfig
xtensa defconfig
arc defconfig
arc allyesconfig
sh allmodconfig
sh allnoconfig
microblaze allnoconfig
mips allnoconfig
mips allmodconfig
parisc defconfig
parisc allnoconfig
parisc allyesconfig
parisc allmodconfig
powerpc defconfig
powerpc allyesconfig
powerpc rhel-kconfig
powerpc allmodconfig
powerpc allnoconfig
i386 randconfig-a006-20200518
i386 randconfig-a005-20200518
i386 randconfig-a001-20200518
i386 randconfig-a003-20200518
i386 randconfig-a004-20200518
i386 randconfig-a002-20200518
x86_64 randconfig-a016-20200518
x86_64 randconfig-a012-20200518
x86_64 randconfig-a015-20200518
x86_64 randconfig-a013-20200518
x86_64 randconfig-a011-20200518
x86_64 randconfig-a014-20200518
i386 randconfig-a012-20200518
i386 randconfig-a014-20200518
i386 randconfig-a016-20200518
i386 randconfig-a011-20200518
i386 randconfig-a015-20200518
i386 randconfig-a013-20200518
riscv allyesconfig
riscv allnoconfig
riscv defconfig
riscv allmodconfig
s390 allyesconfig
s390 allnoconfig
s390 allmodconfig
s390 defconfig
x86_64 defconfig
sparc allyesconfig
sparc defconfig
sparc64 defconfig
sparc64 allnoconfig
sparc64 allyesconfig
sparc64 allmodconfig
um allmodconfig
um allnoconfig
um allyesconfig
um defconfig
x86_64 rhel
x86_64 rhel-7.6
x86_64 rhel-7.6-kselftests
x86_64 rhel-7.2-clear
x86_64 lkp
x86_64 fedora-25
x86_64 kexec
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
^ permalink raw reply
* [PATCH v3 1/1] powerpc/crash: Use NMI context for printk when starting to crash
From: Leonardo Bras @ 2020-05-19 0:25 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
Allison Randal, Leonardo Bras, Christophe Leroy, Alexios Zavras,
Thomas Gleixner, Nicholas Piggin
Cc: linuxppc-dev, linux-kernel
Currently, if printk lock (logbuf_lock) is held by other thread during
crash, there is a chance of deadlocking the crash on next printk, and
blocking a possibly desired kdump.
At the start of default_machine_crash_shutdown, make printk enter
NMI context, as it will use per-cpu buffers to store the message,
and avoid locking logbuf_lock.
Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Leonardo Bras <leobras.c@gmail.com>
---
Changes since v2:
- Changes usage of printk_nmi_enter() to nmi_enter()
(Suggested by Nick Piggin)
Changes since v1:
- Added in-code comment explaining the need of context change
- Function moved to the start of default_machine_crash_shutdown,
to avoid locking any printk on crashing routine.
- Title was 'Use NMI context for printk after crashing other CPUs'
---
arch/powerpc/kexec/crash.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c
index d488311efab1..53c5cf9b6d3c 100644
--- a/arch/powerpc/kexec/crash.c
+++ b/arch/powerpc/kexec/crash.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/types.h>
+#include <linux/hardirq.h>
#include <asm/processor.h>
#include <asm/machdep.h>
@@ -311,6 +312,13 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
unsigned int i;
int (*old_handler)(struct pt_regs *regs);
+ /*
+ * Avoid hardlocking with irresponsive CPU holding logbuf_lock,
+ * by using printk nmi_context
+ */
+ if (!in_nmi())
+ nmi_enter();
+
/*
* This function is only called after the system
* has panicked or is otherwise in a critical state.
--
2.25.4
^ permalink raw reply related
* [PATCH v2 0/7] Base support for POWER10
From: Alistair Popple @ 2020-05-19 0:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mikey, npiggin, aneesh.kumar, Alistair Popple
This series brings together several previously posted patches required for
POWER10 support and introduces a new patch enabling POWER10 architected
mode to enable booting as a POWER10 pseries guest.
It includes support for enabling facilities related to MMA and prefix
instructions.
Changes from v1:
- Two bug-fixes to enable prefix and MMA on pseries
- Minor updates to commit message wording
- Fixes a build error when CONFIG_KVM_BOOK3S_64_HV is enabled
Alistair Popple (7):
powerpc: Add new HWCAP bits
powerpc: Add support for ISA v3.1
powerpc/dt_cpu_ftrs: Advertise support for ISA v3.1 if selected
powerpc/dt_cpu_ftrs: Set current thread fscr bits
powerpc/dt_cpu_ftrs: Enable Prefixed Instructions
powerpc/dt_cpu_ftrs: Add MMA feature
powerpc: Add POWER10 architected mode
arch/powerpc/include/asm/cputable.h | 16 +++++++++++--
arch/powerpc/include/asm/mmu.h | 1 +
arch/powerpc/include/asm/prom.h | 1 +
arch/powerpc/include/asm/reg.h | 6 +++--
arch/powerpc/include/uapi/asm/cputable.h | 2 ++
arch/powerpc/kernel/cpu_setup_power.S | 20 ++++++++++++++--
arch/powerpc/kernel/cputable.c | 30 ++++++++++++++++++++++++
arch/powerpc/kernel/dt_cpu_ftrs.c | 26 +++++++++++++++++++-
arch/powerpc/kernel/prom_init.c | 12 ++++++++--
arch/powerpc/kvm/book3s_hv.c | 3 ---
10 files changed, 105 insertions(+), 12 deletions(-)
--
2.20.1
^ permalink raw reply
* [PATCH v2 1/7] powerpc: Add new HWCAP bits
From: Alistair Popple @ 2020-05-19 0:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mikey, npiggin, aneesh.kumar, Alistair Popple
In-Reply-To: <20200519003157.31946-1-alistair@popple.id.au>
POWER10 introduces two new architectural features - ISAv3.1 and matrix
multiply accumulate (MMA) instructions. Userspace detects the presence
of these features via two HWCAP bits introduced in this patch. These
bits have been agreed to by the compiler and binutils team.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
arch/powerpc/include/uapi/asm/cputable.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/include/uapi/asm/cputable.h b/arch/powerpc/include/uapi/asm/cputable.h
index 540592034740..2692a56bf20b 100644
--- a/arch/powerpc/include/uapi/asm/cputable.h
+++ b/arch/powerpc/include/uapi/asm/cputable.h
@@ -50,6 +50,8 @@
#define PPC_FEATURE2_DARN 0x00200000 /* darn random number insn */
#define PPC_FEATURE2_SCV 0x00100000 /* scv syscall */
#define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 /* TM w/out suspended state */
+#define PPC_FEATURE2_ARCH_3_1 0x00040000 /* ISA 3.1 */
+#define PPC_FEATURE2_MMA 0x00020000 /* Matrix Multiply Accumulate */
/*
* IMPORTANT!
--
2.20.1
^ permalink raw reply related
* [PATCH v2 2/7] powerpc: Add support for ISA v3.1
From: Alistair Popple @ 2020-05-19 0:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mikey, npiggin, aneesh.kumar, Alistair Popple
In-Reply-To: <20200519003157.31946-1-alistair@popple.id.au>
Newer ISA versions are enabled by clearing all bits in the PCR
associated with previous versions of the ISA. Enable ISA v3.1 support
by updating the PCR mask to include ISA v3.0. This ensures all PCR
bits corresponding to earlier architecture versions get cleared
thereby enabling ISA v3.1 if supported by the hardware.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
arch/powerpc/include/asm/cputable.h | 1 +
arch/powerpc/include/asm/reg.h | 3 ++-
arch/powerpc/kvm/book3s_hv.c | 3 ---
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 40a4d3c6fd99..36f894dea9e7 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -213,6 +213,7 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_P9_TIDR LONG_ASM_CONST(0x0000800000000000)
#define CPU_FTR_P9_TLBIE_ERAT_BUG LONG_ASM_CONST(0x0001000000000000)
#define CPU_FTR_P9_RADIX_PREFETCH_BUG LONG_ASM_CONST(0x0002000000000000)
+#define CPU_FTR_ARCH_31 LONG_ASM_CONST(0x0004000000000000)
#ifndef __ASSEMBLY__
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 773f76402392..1931b1142599 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -485,10 +485,11 @@
* determine both the compatibility level which we want to emulate and the
* compatibility level which the host is capable of emulating.
*/
+#define PCR_ARCH_300 0x10 /* Architecture 3.00 */
#define PCR_ARCH_207 0x8 /* Architecture 2.07 */
#define PCR_ARCH_206 0x4 /* Architecture 2.06 */
#define PCR_ARCH_205 0x2 /* Architecture 2.05 */
-#define PCR_LOW_BITS (PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205)
+#define PCR_LOW_BITS (PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205 | PCR_ARCH_300)
#define PCR_MASK ~(PCR_HIGH_BITS | PCR_LOW_BITS) /* PCR Reserved Bits */
#define SPRN_HEIR 0x153 /* Hypervisor Emulated Instruction Register */
#define SPRN_TLBINDEXR 0x154 /* P7 TLB control register */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 93493f0cbfe8..532215040f3e 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -344,9 +344,6 @@ static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr)
vcpu->arch.pvr = pvr;
}
-/* Dummy value used in computing PCR value below */
-#define PCR_ARCH_300 (PCR_ARCH_207 << 1)
-
static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
{
unsigned long host_pcr_bit = 0, guest_pcr_bit = 0;
--
2.20.1
^ permalink raw reply related
* [PATCH v2 3/7] powerpc/dt_cpu_ftrs: Advertise support for ISA v3.1 if selected
From: Alistair Popple @ 2020-05-19 0:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mikey, npiggin, aneesh.kumar, Alistair Popple
In-Reply-To: <20200519003157.31946-1-alistair@popple.id.au>
On powernv hardware support for ISAv3.1 is advertised via a cpu feature
bit in the device tree. This patch enables the associated HWCAP bit if
the device tree indicates ISAv3.1 is available.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
arch/powerpc/kernel/dt_cpu_ftrs.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index 36bc0d5c4f3a..b5e21264d168 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -26,6 +26,7 @@
/* Device-tree visible constants follow */
#define ISA_V2_07B 2070
#define ISA_V3_0B 3000
+#define ISA_V3_1 3100
#define USABLE_PR (1U << 0)
#define USABLE_OS (1U << 1)
@@ -654,6 +655,11 @@ static void __init cpufeatures_setup_start(u32 isa)
cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_300;
cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_00;
}
+
+ if (isa >= 3100) {
+ cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_31;
+ cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_1;
+ }
}
static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)
--
2.20.1
^ permalink raw reply related
* [PATCH v2 4/7] powerpc/dt_cpu_ftrs: Set current thread fscr bits
From: Alistair Popple @ 2020-05-19 0:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mikey, npiggin, aneesh.kumar, Alistair Popple
In-Reply-To: <20200519003157.31946-1-alistair@popple.id.au>
Setting the FSCR bit directly in the SPR only sets it during the initial
boot and early init of the kernel but not for the init process or any
subsequent kthreads. This is because the thread_struct for those is
copied from the current thread_struct setup at boot which doesn't
reflect any changes made to the FSCR during cpu feature detection. This
patch ensures the current thread state is updated to match once feature
detection is complete.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
arch/powerpc/kernel/dt_cpu_ftrs.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index b5e21264d168..677190f70cac 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -170,6 +170,7 @@ static int __init feat_try_enable_unknown(struct dt_cpu_feature *f)
u64 fscr = mfspr(SPRN_FSCR);
fscr |= 1UL << f->fscr_bit_nr;
mtspr(SPRN_FSCR, fscr);
+ current->thread.fscr |= 1UL << f->fscr_bit_nr;
} else {
/* Does not have a known recipe */
return 0;
@@ -205,6 +206,7 @@ static int __init feat_enable(struct dt_cpu_feature *f)
u64 fscr = mfspr(SPRN_FSCR);
fscr |= 1UL << f->fscr_bit_nr;
mtspr(SPRN_FSCR, fscr);
+ current->thread.fscr |= 1UL << f->fscr_bit_nr;
}
}
--
2.20.1
^ permalink raw reply related
* [PATCH v2 5/7] powerpc/dt_cpu_ftrs: Enable Prefixed Instructions
From: Alistair Popple @ 2020-05-19 0:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mikey, npiggin, aneesh.kumar, Alistair Popple
In-Reply-To: <20200519003157.31946-1-alistair@popple.id.au>
Prefix instructions have their own FSCR bit which needs to be enabled
via a CPU feature. The kernel will save the FSCR for problem state but
it needs to be enabled initially.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
arch/powerpc/kernel/dt_cpu_ftrs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index 677190f70cac..93c340906aad 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -628,6 +628,7 @@ static struct dt_cpu_feature_match __initdata
{"vector-binary128", feat_enable, 0},
{"vector-binary16", feat_enable, 0},
{"wait-v3", feat_enable, 0},
+ {"prefix-instructions", feat_enable, 0},
};
static bool __initdata using_dt_cpu_ftrs;
--
2.20.1
^ permalink raw reply related
* [PATCH v2 6/7] powerpc/dt_cpu_ftrs: Add MMA feature
From: Alistair Popple @ 2020-05-19 0:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mikey, npiggin, aneesh.kumar, Alistair Popple
In-Reply-To: <20200519003157.31946-1-alistair@popple.id.au>
Matrix multiple accumulate (MMA) is a new feature added to ISAv3.1 and
POWER10. Support on powernv can be selected via a firmware CPU device
tree feature which enables it via a PCR bit.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
arch/powerpc/include/asm/reg.h | 3 ++-
arch/powerpc/kernel/dt_cpu_ftrs.c | 17 ++++++++++++++++-
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 1931b1142599..c446863a40cf 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -479,7 +479,8 @@
#define PCR_VEC_DIS (__MASK(63-0)) /* Vec. disable (bit NA since POWER8) */
#define PCR_VSX_DIS (__MASK(63-1)) /* VSX disable (bit NA since POWER8) */
#define PCR_TM_DIS (__MASK(63-2)) /* Trans. memory disable (POWER8) */
-#define PCR_HIGH_BITS (PCR_VEC_DIS | PCR_VSX_DIS | PCR_TM_DIS)
+#define PCR_MMA_DIS (__MASK(63-3)) /* Matrix-Multiply Accelerator */
+#define PCR_HIGH_BITS (PCR_MMA_DIS | PCR_VEC_DIS | PCR_VSX_DIS | PCR_TM_DIS)
/*
* These bits are used in the function kvmppc_set_arch_compat() to specify and
* determine both the compatibility level which we want to emulate and the
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index 93c340906aad..e7540ee5cad8 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -75,6 +75,7 @@ static struct {
u64 lpcr_clear;
u64 hfscr;
u64 fscr;
+ u64 pcr;
} system_registers;
static void (*init_pmu_registers)(void);
@@ -102,7 +103,7 @@ static void __restore_cpu_cpufeatures(void)
if (hv_mode) {
mtspr(SPRN_LPID, 0);
mtspr(SPRN_HFSCR, system_registers.hfscr);
- mtspr(SPRN_PCR, PCR_MASK);
+ mtspr(SPRN_PCR, system_registers.pcr);
}
mtspr(SPRN_FSCR, system_registers.fscr);
@@ -555,6 +556,18 @@ static int __init feat_enable_large_ci(struct dt_cpu_feature *f)
return 1;
}
+static int __init feat_enable_mma(struct dt_cpu_feature *f)
+{
+ u64 pcr;
+
+ feat_enable(f);
+ pcr = mfspr(SPRN_PCR);
+ pcr &= ~PCR_MMA_DIS;
+ mtspr(SPRN_PCR, pcr);
+
+ return 1;
+}
+
struct dt_cpu_feature_match {
const char *name;
int (*enable)(struct dt_cpu_feature *f);
@@ -629,6 +642,7 @@ static struct dt_cpu_feature_match __initdata
{"vector-binary16", feat_enable, 0},
{"wait-v3", feat_enable, 0},
{"prefix-instructions", feat_enable, 0},
+ {"matrix-multiply-accumulate", feat_enable_mma, 0},
};
static bool __initdata using_dt_cpu_ftrs;
@@ -779,6 +793,7 @@ static void __init cpufeatures_setup_finished(void)
system_registers.lpcr = mfspr(SPRN_LPCR);
system_registers.hfscr = mfspr(SPRN_HFSCR);
system_registers.fscr = mfspr(SPRN_FSCR);
+ system_registers.pcr = mfspr(SPRN_PCR);
pr_info("final cpu/mmu features = 0x%016lx 0x%08x\n",
cur_cpu_spec->cpu_features, cur_cpu_spec->mmu_features);
--
2.20.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox