* Re: [PATCH v6 4/4] powerpc/64s: Initialize and use a temporary mm for patching on Radix
From: Jordan Niethe @ 2021-09-11 9:14 UTC (permalink / raw)
To: Christopher M. Riedl; +Cc: linuxppc-dev, linux-hardening
In-Reply-To: <20210911022904.30962-5-cmr@bluescreens.de>
On Sat, Sep 11, 2021 at 12:39 PM Christopher M. Riedl
<cmr@bluescreens.de> wrote:
>
> When code patching a STRICT_KERNEL_RWX kernel the page containing the
> address to be patched is temporarily mapped as writeable. Currently, a
> per-cpu vmalloc patch area is used for this purpose. While the patch
> area is per-cpu, the temporary page mapping is inserted into the kernel
> page tables for the duration of patching. The mapping is exposed to CPUs
> other than the patching CPU - this is undesirable from a hardening
> perspective. Use a temporary mm instead which keeps the mapping local to
> the CPU doing the patching.
>
> Use the `poking_init` init hook to prepare a temporary mm and patching
> address. Initialize the temporary mm by copying the init mm. Choose a
> randomized patching address inside the temporary mm userspace address
> space. The patching address is randomized between PAGE_SIZE and
> DEFAULT_MAP_WINDOW-PAGE_SIZE.
>
> Bits of entropy with 64K page size on BOOK3S_64:
>
> bits of entropy = log2(DEFAULT_MAP_WINDOW_USER64 / PAGE_SIZE)
>
> PAGE_SIZE=64K, DEFAULT_MAP_WINDOW_USER64=128TB
> bits of entropy = log2(128TB / 64K)
> bits of entropy = 31
>
> The upper limit is DEFAULT_MAP_WINDOW due to how the Book3s64 Hash MMU
> operates - by default the space above DEFAULT_MAP_WINDOW is not
> available. Currently the Hash MMU does not use a temporary mm so
> technically this upper limit isn't necessary; however, a larger
> randomization range does not further "harden" this overall approach and
> future work may introduce patching with a temporary mm on Hash as well.
>
> Randomization occurs only once during initialization at boot for each
> possible CPU in the system.
>
> Introduce two new functions, map_patch_mm() and unmap_patch_mm(), to
> respectively create and remove the temporary mapping with write
> permissions at patching_addr. Map the page with PAGE_KERNEL to set
> EAA[0] for the PTE which ignores the AMR (so no need to unlock/lock
> KUAP) according to PowerISA v3.0b Figure 35 on Radix.
>
> Based on x86 implementation:
>
> commit 4fc19708b165
> ("x86/alternatives: Initialize temporary mm for patching")
>
> and:
>
> commit b3fd8e83ada0
> ("x86/alternatives: Use temporary mm for text poking")
>
> Signed-off-by: Christopher M. Riedl <cmr@bluescreens.de>
>
> ---
>
> v6: * Small clean-ups (naming, formatting, style, etc).
> * Call stop_using_temporary_mm() before pte_unmap_unlock() after
> patching.
> * Replace BUG_ON()s in poking_init() w/ WARN_ON()s.
>
> v5: * Only support Book3s64 Radix MMU for now.
> * Use a per-cpu datastructure to hold the patching_addr and
> patching_mm to avoid the need for a synchronization lock/mutex.
>
> v4: * In the previous series this was two separate patches: one to init
> the temporary mm in poking_init() (unused in powerpc at the time)
> and the other to use it for patching (which removed all the
> per-cpu vmalloc code). Now that we use poking_init() in the
> existing per-cpu vmalloc approach, that separation doesn't work
> as nicely anymore so I just merged the two patches into one.
> * Preload the SLB entry and hash the page for the patching_addr
> when using Hash on book3s64 to avoid taking an SLB and Hash fault
> during patching. The previous implementation was a hack which
> changed current->mm to allow the SLB and Hash fault handlers to
> work with the temporary mm since both of those code-paths always
> assume mm == current->mm.
> * Also (hmm - seeing a trend here) with the book3s64 Hash MMU we
> have to manage the mm->context.active_cpus counter and mm cpumask
> since they determine (via mm_is_thread_local()) if the TLB flush
> in pte_clear() is local or not - it should always be local when
> we're using the temporary mm. On book3s64's Radix MMU we can
> just call local_flush_tlb_mm().
> * Use HPTE_USE_KERNEL_KEY on Hash to avoid costly lock/unlock of
> KUAP.
> ---
> arch/powerpc/lib/code-patching.c | 119 +++++++++++++++++++++++++++++--
> 1 file changed, 112 insertions(+), 7 deletions(-)
>
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
> index e802e42c2789..af8e2a02a9dd 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -11,6 +11,7 @@
> #include <linux/cpuhotplug.h>
> #include <linux/slab.h>
> #include <linux/uaccess.h>
> +#include <linux/random.h>
>
> #include <asm/tlbflush.h>
> #include <asm/page.h>
> @@ -103,6 +104,7 @@ static inline void stop_using_temporary_mm(struct temp_mm *temp_mm)
>
> static DEFINE_PER_CPU(struct vm_struct *, text_poke_area);
> static DEFINE_PER_CPU(unsigned long, cpu_patching_addr);
> +static DEFINE_PER_CPU(struct mm_struct *, cpu_patching_mm);
>
> static int text_area_cpu_up(unsigned int cpu)
> {
> @@ -126,8 +128,48 @@ static int text_area_cpu_down(unsigned int cpu)
> return 0;
> }
>
> +static __always_inline void __poking_init_temp_mm(void)
> +{
> + int cpu;
> + spinlock_t *ptl; /* for protecting pte table */
ptl is just used so we don't have to open code allocating a pte in
patching_mm isn't it?
> + pte_t *ptep;
> + struct mm_struct *patching_mm;
> + unsigned long patching_addr;
> +
> + for_each_possible_cpu(cpu) {
> + patching_mm = copy_init_mm();
> + WARN_ON(!patching_mm);
Would it be okay to just let the mmu handle null pointer dereferences?
> + per_cpu(cpu_patching_mm, cpu) = patching_mm;
> +
> + /*
> + * Choose a randomized, page-aligned address from the range:
> + * [PAGE_SIZE, DEFAULT_MAP_WINDOW - PAGE_SIZE] The lower
> + * address bound is PAGE_SIZE to avoid the zero-page. The
> + * upper address bound is DEFAULT_MAP_WINDOW - PAGE_SIZE to
> + * stay under DEFAULT_MAP_WINDOW with the Book3s64 Hash MMU.
> + */
> + patching_addr = PAGE_SIZE + ((get_random_long() & PAGE_MASK)
> + % (DEFAULT_MAP_WINDOW - 2 * PAGE_SIZE));
> + per_cpu(cpu_patching_addr, cpu) = patching_addr;
On x86 the randomization depends on CONFIG_RANDOMIZE_BASE. Should it
be controllable here too?
> +
> + /*
> + * PTE allocation uses GFP_KERNEL which means we need to
> + * pre-allocate the PTE here because we cannot do the
> + * allocation during patching when IRQs are disabled.
> + */
> + ptep = get_locked_pte(patching_mm, patching_addr, &ptl);
> + WARN_ON(!ptep);
> + pte_unmap_unlock(ptep, ptl);
> + }
> +}
> +
> void __init poking_init(void)
> {
> + if (radix_enabled()) {
> + __poking_init_temp_mm();
Should this also be done with cpuhp_setup_state()?
> + return;
> + }
> +
> WARN_ON(cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
> "powerpc/text_poke:online", text_area_cpu_up,
> text_area_cpu_down) < 0);
> @@ -197,30 +239,93 @@ static inline int unmap_patch_area(void)
> return 0;
> }
>
> +struct patch_mapping {
> + spinlock_t *ptl; /* for protecting pte table */
> + pte_t *ptep;
> + struct temp_mm temp_mm;
> +};
> +
> +/*
> + * This can be called for kernel text or a module.
> + */
> +static int map_patch_mm(const void *addr, struct patch_mapping *patch_mapping)
> +{
> + struct page *page;
> + struct mm_struct *patching_mm = __this_cpu_read(cpu_patching_mm);
> + unsigned long patching_addr = __this_cpu_read(cpu_patching_addr);
> +
> + if (is_vmalloc_or_module_addr(addr))
> + page = vmalloc_to_page(addr);
> + else
> + page = virt_to_page(addr);
> +
> + patch_mapping->ptep = get_locked_pte(patching_mm, patching_addr,
> + &patch_mapping->ptl);
> + if (unlikely(!patch_mapping->ptep)) {
> + pr_warn("map patch: failed to allocate pte for patching\n");
> + return -1;
> + }
> +
> + set_pte_at(patching_mm, patching_addr, patch_mapping->ptep,
> + pte_mkdirty(mk_pte(page, PAGE_KERNEL)));
> +
> + init_temp_mm(&patch_mapping->temp_mm, patching_mm);
> + start_using_temporary_mm(&patch_mapping->temp_mm);
> +
> + return 0;
> +}
> +
> +static int unmap_patch_mm(struct patch_mapping *patch_mapping)
> +{
> + struct mm_struct *patching_mm = __this_cpu_read(cpu_patching_mm);
> + unsigned long patching_addr = __this_cpu_read(cpu_patching_addr);
> +
> + pte_clear(patching_mm, patching_addr, patch_mapping->ptep);
> +
> + local_flush_tlb_mm(patching_mm);
> + stop_using_temporary_mm(&patch_mapping->temp_mm);
> +
> + pte_unmap_unlock(patch_mapping->ptep, patch_mapping->ptl);
> +
> + return 0;
> +}
> +
> static int do_patch_instruction(u32 *addr, struct ppc_inst instr)
> {
> int err, rc = 0;
> u32 *patch_addr = NULL;
> unsigned long flags;
> + struct patch_mapping patch_mapping;
>
> /*
> - * During early early boot patch_instruction is called
> - * when text_poke_area is not ready, but we still need
> - * to allow patching. We just do the plain old patching
> + * During early early boot patch_instruction is called when the
> + * patching_mm/text_poke_area is not ready, but we still need to allow
> + * patching. We just do the plain old patching.
> */
> - if (!this_cpu_read(text_poke_area))
> - return raw_patch_instruction(addr, instr);
> + if (radix_enabled()) {
> + if (!this_cpu_read(cpu_patching_mm))
> + return raw_patch_instruction(addr, instr);
> + } else {
> + if (!this_cpu_read(text_poke_area))
> + return raw_patch_instruction(addr, instr);
> + }
Would testing cpu_patching_addr handler both of these cases?
Then I think it might be clearer to do something like this:
if (radix_enabled()) {
return patch_instruction_mm(addr, instr);
}
patch_instruction_mm() would combine map_patch_mm(), then patching and
unmap_patch_mm() into one function.
IMO, a bit of code duplication would be cleaner than checking multiple
times for radix_enabled() and having struct patch_mapping especially
for maintaining state.
>
> local_irq_save(flags);
>
> - err = map_patch_area(addr);
> + if (radix_enabled())
> + err = map_patch_mm(addr, &patch_mapping);
> + else
> + err = map_patch_area(addr);
> if (err)
> goto out;
>
> patch_addr = (u32 *)(__this_cpu_read(cpu_patching_addr) | offset_in_page(addr));
> rc = __patch_instruction(addr, instr, patch_addr);
>
> - err = unmap_patch_area();
> + if (radix_enabled())
> + err = unmap_patch_mm(&patch_mapping);
> + else
> + err = unmap_patch_area();
>
> out:
> local_irq_restore(flags);
> --
> 2.32.0
>
Thanks,
Jordan
^ permalink raw reply
* Re: [PATCH v3 3/8] x86/sev: Add an x86 version of cc_platform_has()
From: Borislav Petkov @ 2021-09-11 10:10 UTC (permalink / raw)
To: Tom Lendacky
Cc: Sathyanarayanan Kuppuswamy, linux-efi, Brijesh Singh, kvm,
Peter Zijlstra, Dave Hansen, dri-devel, platform-driver-x86,
linux-s390, Andi Kleen, Joerg Roedel, x86, amd-gfx,
Christoph Hellwig, Ingo Molnar, linux-graphics-maintainer,
Tianyu Lan, Andy Lutomirski, Thomas Gleixner, kexec, linux-kernel,
iommu, linux-fsdevel, linuxppc-dev
In-Reply-To: <f9951644147e27772bf4512325e8ba6472e363b7.1631141919.git.thomas.lendacky@amd.com>
On Wed, Sep 08, 2021 at 05:58:34PM -0500, Tom Lendacky wrote:
> diff --git a/arch/x86/kernel/cc_platform.c b/arch/x86/kernel/cc_platform.c
> new file mode 100644
> index 000000000000..3c9bacd3c3f3
> --- /dev/null
> +++ b/arch/x86/kernel/cc_platform.c
> @@ -0,0 +1,21 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Confidential Computing Platform Capability checks
> + *
> + * Copyright (C) 2021 Advanced Micro Devices, Inc.
> + *
> + * Author: Tom Lendacky <thomas.lendacky@amd.com>
> + */
> +
> +#include <linux/export.h>
> +#include <linux/cc_platform.h>
> +#include <linux/mem_encrypt.h>
> +
> +bool cc_platform_has(enum cc_attr attr)
> +{
> + if (sme_me_mask)
Why are you still checking the sme_me_mask here? AFAIR, we said that
we'll do that only when the KVM folks come with a valid use case...
> + return amd_cc_platform_has(attr);
> +
> + return false;
> +}
> +EXPORT_SYMBOL_GPL(cc_platform_has);
> diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
> index ff08dc463634..18fe19916bc3 100644
> --- a/arch/x86/mm/mem_encrypt.c
> +++ b/arch/x86/mm/mem_encrypt.c
> @@ -20,6 +20,7 @@
> #include <linux/bitops.h>
> #include <linux/dma-mapping.h>
> #include <linux/virtio_config.h>
> +#include <linux/cc_platform.h>
>
> #include <asm/tlbflush.h>
> #include <asm/fixmap.h>
> @@ -389,6 +390,26 @@ bool noinstr sev_es_active(void)
> return sev_status & MSR_AMD64_SEV_ES_ENABLED;
> }
>
> +bool amd_cc_platform_has(enum cc_attr attr)
> +{
> + switch (attr) {
> + case CC_ATTR_MEM_ENCRYPT:
> + return sme_me_mask != 0;
No need for the "!= 0"
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply
* Re: [PATCH 06/10] powerpc: remove GCC version check for UPD_CONSTR
From: Michael Ellerman @ 2021-09-11 10:43 UTC (permalink / raw)
To: Nathan Chancellor, Nick Desaulniers, Andrew Morton
Cc: Stephen Rothwell, linuxppc-dev, Arnd Bergmann, Masahiro Yamada,
llvm, Rasmus Villemoes, linux-kernel, Paul Mackerras, Joe Perches,
Linus Torvalds
In-Reply-To: <b940bd2c-21d2-dfe9-e171-e265085a2b11@kernel.org>
Nathan Chancellor <nathan@kernel.org> writes:
> On 9/10/2021 4:40 PM, Nick Desaulniers wrote:
>> Now that GCC 5.1 is the minimum supported version, we can drop this
>> workaround for older versions of GCC. This adversely affected clang,
>> too.
>>
>> Cc: Michael Ellerman <mpe@ellerman.id.au>
>> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> Cc: Paul Mackerras <paulus@samba.org>
>> Cc: Segher Boessenkool <segher@kernel.crashing.org>
>> Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
>> Cc: linuxppc-dev@lists.ozlabs.org
>> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
>> ---
>> arch/powerpc/include/asm/asm-const.h | 10 ----------
>> 1 file changed, 10 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/asm-const.h b/arch/powerpc/include/asm/asm-const.h
>> index 0ce2368bd20f..dbfa5e1e3198 100644
>> --- a/arch/powerpc/include/asm/asm-const.h
>> +++ b/arch/powerpc/include/asm/asm-const.h
>> @@ -12,16 +12,6 @@
>> # define ASM_CONST(x) __ASM_CONST(x)
>> #endif
>>
>> -/*
>> - * Inline assembly memory constraint
>> - *
>> - * GCC 4.9 doesn't properly handle pre update memory constraint "m<>"
>> - *
>> - */
>> -#if defined(GCC_VERSION) && GCC_VERSION < 50000
>> -#define UPD_CONSTR ""
>> -#else
>> #define UPD_CONSTR "<>"
>> -#endif
>
> The only reason this exists is because of commit 592bbe9c505d
> ("powerpc/uaccess: Don't use "m<>" constraint with GCC 4.9"). It is
> probably just worth sinking "<>" into all of the callsites and removing
> UPD_CONSTR.
Yeah that would be great if you're doing a v2. Or we can do it as a
follow-up.
cheers
^ permalink raw reply
* Re: [PATCH 1/1] powerpc: Drop superfluous pci_dev_is_added() calls
From: Michael Ellerman @ 2021-09-11 11:09 UTC (permalink / raw)
To: Niklas Schnelle, Bjorn Helgaas
Cc: linux-arch, linux-s390, linux-kernel, Oliver O'Halloran,
linux-pci, linuxppc-dev
In-Reply-To: <20210910141940.2598035-2-schnelle@linux.ibm.com>
Niklas Schnelle <schnelle@linux.ibm.com> writes:
> On powerpc, pci_dev_is_added() is called as part of SR-IOV fixups
> that are done under pcibios_add_device() which in turn is only called in
> pci_device_add() whih is called when a PCI device is scanned.
Thanks for cleaning this up for us.
> Now pci_dev_assign_added() is called in pci_bus_add_device() which is
> only called after scanning the device. Thus pci_dev_is_added() is always
> false and can be dropped.
My only query is whether we can pin down when that changed.
Oliver said:
The use of pci_dev_is_added() in arch/powerpc was because in the past
pci_bus_add_device() could be called before pci_device_add(). That was
fixed a while ago so It should be safe to remove those calls now.
I trawled back through the history a bit but I can't remember/find which
commit changed that, Oliver can you remember?
cheers
> diff --git a/arch/powerpc/platforms/powernv/pci-sriov.c b/arch/powerpc/platforms/powernv/pci-sriov.c
> index 28aac933a439..deddbb233fde 100644
> --- a/arch/powerpc/platforms/powernv/pci-sriov.c
> +++ b/arch/powerpc/platforms/powernv/pci-sriov.c
> @@ -9,9 +9,6 @@
>
> #include "pci.h"
>
> -/* for pci_dev_is_added() */
> -#include "../../../../drivers/pci/pci.h"
> -
> /*
> * The majority of the complexity in supporting SR-IOV on PowerNV comes from
> * the need to put the MMIO space for each VF into a separate PE. Internally
> @@ -228,9 +225,6 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
>
> void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev)
> {
> - if (WARN_ON(pci_dev_is_added(pdev)))
> - return;
> -
> if (pdev->is_virtfn) {
> struct pnv_ioda_pe *pe = pnv_ioda_get_pe(pdev);
>
> diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
> index f79126f16258..2188054470c1 100644
> --- a/arch/powerpc/platforms/pseries/setup.c
> +++ b/arch/powerpc/platforms/pseries/setup.c
> @@ -74,7 +74,6 @@
> #include <asm/hvconsole.h>
>
> #include "pseries.h"
> -#include "../../../../drivers/pci/pci.h"
>
> DEFINE_STATIC_KEY_FALSE(shared_processor);
> EXPORT_SYMBOL(shared_processor);
> @@ -750,7 +749,7 @@ static void pseries_pci_fixup_iov_resources(struct pci_dev *pdev)
> const int *indexes;
> struct device_node *dn = pci_device_to_OF_node(pdev);
>
> - if (!pdev->is_physfn || pci_dev_is_added(pdev))
> + if (!pdev->is_physfn)
> return;
> /*Firmware must support open sriov otherwise dont configure*/
> indexes = of_get_property(dn, "ibm,open-sriov-vf-bar-info", NULL);
> --
> 2.25.1
^ permalink raw reply
* Re: [PATCH 1/1] selftests/powerpc: Add memmove_64 test
From: Michael Ellerman @ 2021-09-11 11:26 UTC (permalink / raw)
To: Ritesh Harjani, linuxppc-dev
Cc: Aneesh Kumar K . V, Ritesh Harjani, Vaibhav Jain
In-Reply-To: <c152ad80dc3a80cd362f6cbbccd626798ab0d5db.1629300331.git.riteshh@linux.ibm.com>
Ritesh Harjani <riteshh@linux.ibm.com> writes:
> While debugging an issue, we wanted to check whether the arch specific
> kernel memmove implementation is correct. This selftest could help test that.
>
> Suggested-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> Suggested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
> Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
> ---
> tools/testing/selftests/powerpc/Makefile | 1 +
> .../selftests/powerpc/memmoveloop/.gitignore | 2 +
> .../selftests/powerpc/memmoveloop/Makefile | 19 +++++++
> .../powerpc/memmoveloop/asm/asm-compat.h | 0
> .../powerpc/memmoveloop/asm/export.h | 4 ++
> .../powerpc/memmoveloop/asm/feature-fixups.h | 0
> .../selftests/powerpc/memmoveloop/asm/kasan.h | 0
> .../powerpc/memmoveloop/asm/ppc_asm.h | 39 +++++++++++++
> .../powerpc/memmoveloop/asm/processor.h | 0
> .../selftests/powerpc/memmoveloop/mem_64.S | 1 +
> .../selftests/powerpc/memmoveloop/memcpy_64.S | 1 +
> .../selftests/powerpc/memmoveloop/stubs.S | 8 +++
> .../selftests/powerpc/memmoveloop/validate.c | 56 +++++++++++++++++++
> 13 files changed, 131 insertions(+)
> create mode 100644 tools/testing/selftests/powerpc/memmoveloop/.gitignore
> create mode 100644 tools/testing/selftests/powerpc/memmoveloop/Makefile
> create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/asm-compat.h
> create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/export.h
> create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/feature-fixups.h
> create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/kasan.h
> create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/ppc_asm.h
> create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/processor.h
> create mode 120000 tools/testing/selftests/powerpc/memmoveloop/mem_64.S
> create mode 120000 tools/testing/selftests/powerpc/memmoveloop/memcpy_64.S
> create mode 100644 tools/testing/selftests/powerpc/memmoveloop/stubs.S
> create mode 100644 tools/testing/selftests/powerpc/memmoveloop/validate.c
You've copied a lot of tools/testing/selftests/powerpc/copyloops
I'd be happier if you integrated the memmove test into that existing
code. I realise memmove is not technically a copy loop, but it's close
enough.
Did you try that and hit some roadblock?
cheers
> diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
> index 0830e63818c1..d110b3e5cbcd 100644
> --- a/tools/testing/selftests/powerpc/Makefile
> +++ b/tools/testing/selftests/powerpc/Makefile
> @@ -16,6 +16,7 @@ export CFLAGS
> SUB_DIRS = alignment \
> benchmarks \
> cache_shape \
> + memmoveloop \
> copyloops \
> dscr \
> mm \
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/.gitignore b/tools/testing/selftests/powerpc/memmoveloop/.gitignore
> new file mode 100644
> index 000000000000..56c1426013d5
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/memmoveloop/.gitignore
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +memmove_64
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/Makefile b/tools/testing/selftests/powerpc/memmoveloop/Makefile
> new file mode 100644
> index 000000000000..d58d8c100099
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/memmoveloop/Makefile
> @@ -0,0 +1,19 @@
> +# SPDX-License-Identifier: GPL-2.0
> +CFLAGS += -m64
> +CFLAGS += -I$(CURDIR)
> +CFLAGS += -D SELFTEST
> +CFLAGS += -maltivec
> +
> +ASFLAGS = $(CFLAGS) -Wa,-mpower4
> +
> +TEST_GEN_PROGS := memmove_64
> +EXTRA_SOURCES := validate.c ../harness.c stubs.S
> +CPPFLAGS += -D TEST_MEMMOVE=test_memmove
> +
> +top_srcdir = ../../../../..
> +include ../../lib.mk
> +
> +$(OUTPUT)/memmove_64: mem_64.S memcpy_64.S $(EXTRA_SOURCES)
> + $(CC) $(CPPFLAGS) $(CFLAGS) \
> + -D TEST_MEMMOVE=test_memmove \
> + -o $@ $^
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/asm-compat.h b/tools/testing/selftests/powerpc/memmoveloop/asm/asm-compat.h
> new file mode 100644
> index 000000000000..e69de29bb2d1
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/export.h b/tools/testing/selftests/powerpc/memmoveloop/asm/export.h
> new file mode 100644
> index 000000000000..e6b80d5fbd14
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/memmoveloop/asm/export.h
> @@ -0,0 +1,4 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#define EXPORT_SYMBOL(x)
> +#define EXPORT_SYMBOL_GPL(x)
> +#define EXPORT_SYMBOL_KASAN(x)
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/feature-fixups.h b/tools/testing/selftests/powerpc/memmoveloop/asm/feature-fixups.h
> new file mode 100644
> index 000000000000..e69de29bb2d1
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/kasan.h b/tools/testing/selftests/powerpc/memmoveloop/asm/kasan.h
> new file mode 100644
> index 000000000000..e69de29bb2d1
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/ppc_asm.h b/tools/testing/selftests/powerpc/memmoveloop/asm/ppc_asm.h
> new file mode 100644
> index 000000000000..117005c56e19
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/memmoveloop/asm/ppc_asm.h
> @@ -0,0 +1,39 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __SELFTESTS_POWERPC_PPC_ASM_H
> +#define __SELFTESTS_POWERPC_PPC_ASM_H
> +#include <ppc-asm.h>
> +
> +#define CONFIG_ALTIVEC
> +
> +#define r1 1
> +
> +#define R14 r14
> +#define R15 r15
> +#define R16 r16
> +#define R17 r17
> +#define R18 r18
> +#define R19 r19
> +#define R20 r20
> +#define R21 r21
> +#define R22 r22
> +#define R29 r29
> +#define R30 r30
> +#define R31 r31
> +
> +#define STACKFRAMESIZE 256
> +#define STK_REG(i) (112 + ((i)-14)*8)
> +
> +#define _GLOBAL(A) FUNC_START(test_ ## A)
> +#define _GLOBAL_TOC(A) _GLOBAL(A)
> +#define _GLOBAL_TOC_KASAN(A) _GLOBAL(A)
> +#define _GLOBAL_KASAN(A) _GLOBAL(A)
> +
> +#define PPC_MTOCRF(A, B) mtocrf A, B
> +
> +#define BEGIN_FTR_SECTION
> +#define FTR_SECTION_ELSE
> +#define ALT_FTR_SECTION_END_IFCLR(x)
> +#define ALT_FTR_SECTION_END(x, y)
> +#define END_FTR_SECTION_IFCLR(x)
> +
> +#endif /* __SELFTESTS_POWERPC_PPC_ASM_H */
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/processor.h b/tools/testing/selftests/powerpc/memmoveloop/asm/processor.h
> new file mode 100644
> index 000000000000..e69de29bb2d1
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/mem_64.S b/tools/testing/selftests/powerpc/memmoveloop/mem_64.S
> new file mode 120000
> index 000000000000..db254c9a5f5c
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/memmoveloop/mem_64.S
> @@ -0,0 +1 @@
> +../../../../../arch/powerpc/lib/mem_64.S
> \ No newline at end of file
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/memcpy_64.S b/tools/testing/selftests/powerpc/memmoveloop/memcpy_64.S
> new file mode 120000
> index 000000000000..cce33fb6f9d8
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/memmoveloop/memcpy_64.S
> @@ -0,0 +1 @@
> +../../../../../arch/powerpc/lib/memcpy_64.S
> \ No newline at end of file
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/stubs.S b/tools/testing/selftests/powerpc/memmoveloop/stubs.S
> new file mode 100644
> index 000000000000..d9baa832fa49
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/memmoveloop/stubs.S
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <asm/ppc_asm.h>
> +
> +FUNC_START(memcpy)
> + b test_memcpy
> +
> +FUNC_START(backwards_memcpy)
> + b test_backwards_memcpy
> diff --git a/tools/testing/selftests/powerpc/memmoveloop/validate.c b/tools/testing/selftests/powerpc/memmoveloop/validate.c
> new file mode 100644
> index 000000000000..52f7d32bb3fe
> --- /dev/null
> +++ b/tools/testing/selftests/powerpc/memmoveloop/validate.c
> @@ -0,0 +1,56 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <malloc.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <assert.h>
> +#include "utils.h"
> +
> +void *TEST_MEMMOVE(const void *s1, const void *s2, size_t n);
> +
> +#define BUF_LEN 65536
> +#define MAX_OFFSET 512
> +
> +size_t max(size_t a, size_t b)
> +{
> + if (a >= b) return a;
> + return b;
> +}
> +
> +static int testcase_run(void)
> +{
> + size_t i, src_off, dst_off, len;
> +
> + char *usermap = memalign(BUF_LEN, BUF_LEN);
> + char *kernelmap = memalign(BUF_LEN, BUF_LEN);
> +
> + assert(usermap != NULL);
> + assert(kernelmap != NULL);
> +
> + memset(usermap, 0, BUF_LEN);
> + memset(kernelmap, 0, BUF_LEN);
> +
> + for (i = 0; i < BUF_LEN; i++) {
> + usermap[i] = i & 0xff;
> + kernelmap[i] = i & 0xff;
> + }
> +
> + for (src_off = 0; src_off < MAX_OFFSET; src_off++) {
> + for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) {
> + for (len = 1; len < MAX_OFFSET - max(src_off, dst_off); len++) {
> +
> + memmove(usermap + dst_off, usermap + src_off, len);
> + TEST_MEMMOVE(kernelmap + dst_off, kernelmap + src_off, len);
> + if (memcmp(usermap, kernelmap, MAX_OFFSET) != 0) {
> + printf("memmove failed at %ld %ld %ld\n", src_off, dst_off, len);
> + abort();
> + }
> + }
> + }
> + }
> + return 0;
> +}
> +
> +int main(void)
> +{
> + return test_harness(testcase_run, "memmove");
> +}
> --
> 2.31.1
^ permalink raw reply
* Re: [PATCH AUTOSEL 5.14 38/99] KVM: PPC: Book3S HV: XICS: Fix mapping of passthrough interrupts
From: Sasha Levin @ 2021-09-11 14:35 UTC (permalink / raw)
To: Cédric Le Goater; +Cc: kvm-ppc, linuxppc-dev, linux-kernel, stable
In-Reply-To: <27739836-bad2-6b3f-7f40-e84663fbbf24@kaod.org>
On Fri, Sep 10, 2021 at 07:48:18AM +0200, Cédric Le Goater wrote:
>On 9/10/21 2:14 AM, Sasha Levin wrote:
>> From: Cédric Le Goater <clg@kaod.org>
>>
>> [ Upstream commit 1753081f2d445f9157550692fcc4221cd3ff0958 ]
>>
>> PCI MSIs now live in an MSI domain but the underlying calls, which
>> will EOI the interrupt in real mode, need an HW IRQ number mapped in
>> the XICS IRQ domain. Grab it there.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
>> Link: https://lore.kernel.org/r/20210701132750.1475580-31-clg@kaod.org
>> Signed-off-by: Sasha Levin <sashal@kernel.org>
>
>
>Why are we backporting this patch in stable trees ?
>
>It should be fine but to compile, we need a partial backport of commit
>51be9e51a800 ("KVM: PPC: Book3S HV: XIVE: Fix mapping of passthrough
>interrupts") which exports irq_get_default_host().
Or, I can drop it if it makes no sense?
--
Thanks,
Sasha
^ permalink raw reply
* Re: [PATCH 06/10] powerpc: remove GCC version check for UPD_CONSTR
From: Christophe Leroy @ 2021-09-11 15:34 UTC (permalink / raw)
To: Nick Desaulniers, Andrew Morton
Cc: Arnd Bergmann, linuxppc-dev, Stephen Rothwell, Masahiro Yamada,
llvm, Rasmus Villemoes, linux-kernel, Nathan Chancellor,
Paul Mackerras, Joe Perches, Linus Torvalds
In-Reply-To: <20210910234047.1019925-7-ndesaulniers@google.com>
Le 11/09/2021 à 01:40, Nick Desaulniers a écrit :
> Now that GCC 5.1 is the minimum supported version, we can drop this
> workaround for older versions of GCC. This adversely affected clang,
> too.
Why do you say that GCC 5.1 is the minimum supported ?
As far as I can see, the minimum supported is still 4.9, see
https://github.com/torvalds/linux/blob/master/Documentation/process/changes.rst
>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Segher Boessenkool <segher@kernel.crashing.org>
> Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
> Cc: linuxppc-dev@lists.ozlabs.org
> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
> ---
> arch/powerpc/include/asm/asm-const.h | 10 ----------
> 1 file changed, 10 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/asm-const.h b/arch/powerpc/include/asm/asm-const.h
> index 0ce2368bd20f..dbfa5e1e3198 100644
> --- a/arch/powerpc/include/asm/asm-const.h
> +++ b/arch/powerpc/include/asm/asm-const.h
> @@ -12,16 +12,6 @@
> # define ASM_CONST(x) __ASM_CONST(x)
> #endif
>
> -/*
> - * Inline assembly memory constraint
> - *
> - * GCC 4.9 doesn't properly handle pre update memory constraint "m<>"
> - *
> - */
> -#if defined(GCC_VERSION) && GCC_VERSION < 50000
> -#define UPD_CONSTR ""
> -#else
> #define UPD_CONSTR "<>"
> -#endif
There is no point in keeping UPD_CONSTR if it becomes invariant. You
should just replace all instances of UPD_CONSTR with <> and drop
UPD_CONSTR completely.
Christophe
^ permalink raw reply
* Re: [PATCH v2 3/5] signal: Add unsafe_copy_siginfo_to_user()
From: Eric W. Biederman @ 2021-09-11 15:58 UTC (permalink / raw)
To: Christophe Leroy; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <7caf5127-36fc-7c77-00f1-7be82d6f26e0@csgroup.eu>
Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> On 9/8/21 6:17 PM, Eric W. Biederman wrote:
>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>
>>> Le 02/09/2021 à 20:43, Eric W. Biederman a écrit :
>>>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>>>
>>>>> In the same spirit as commit fb05121fd6a2 ("signal: Add
>>>>> unsafe_get_compat_sigset()"), implement an 'unsafe' version of
>>>>> copy_siginfo_to_user() in order to use it within user access blocks.
>>>>>
>>>>> For that, also add an 'unsafe' version of clear_user().
>>>>
>>>> Looking at your use cases you need the 32bit compat version of this
>>>> as well.
>>>>
>>>> The 32bit compat version is too complicated to become a macro, so I
>>>> don't think you can make this work correctly for the 32bit compat case.
>>>
>>> When looking into patch 5/5 that you nacked, I think you missed the fact that we
>>> keep using copy_siginfo_to_user32() as it for the 32 bit compat case.
>>
>> I did. My mistake.
>>
>> However that mistake was so easy I think it mirrors the comments others
>> have made that this looks like a maintenance hazard.
>>
>> Is improving the performance of 32bit kernels interesting?
>
> Yes it is, and that's what this series do.
>
>> Is improving the performance of 32bit compat support interesting?
>
> For me this is a corner case, so I left it aside for now.
>
>>
>> If performance one or either of those cases is interesting it looks like
>> we already have copy_siginfo_to_external32 the factor you would need
>> to build unsafe_copy_siginfo_to_user32.
>
> I'm not sure I understand your saying here. What do you expect me to
> do with copy_siginfo_to_external32() ?
Implement unsafe_copy_siginfo_to_user32.
> copy_siginfo_to_user32() is for compat only.
>
> Native 32 bits powerpc use copy_siginfo_to_user()
What you implemented doubles the number of test cases necessary to
compile test the 32bit ppc signal code, and makes the code noticeably
harder to follow.
Having a unsafe_copy_to_siginfo_to_user32 at least would allow the
number of test cases to remain the same as the current code.
>> So I am not going to say impossible but please make something
>> maintainable. I unified all of the compat 32bit siginfo logic because
>> it simply did not get enough love and attention when it was implemented
>> per architecture.
>
> Yes, and ? I didn't do any modification to the compat case, so what
> you did remains.
You undid the unification between the 32bit code and the 32bit compat
code.
>> In general I think that concern applies to this case as well. We really
>> need an implementation that shares as much burden as possible with other
>> architectures.
>
> I think yes, that's the reason why I made a generic
> unsafe_copy_siginfo_to_user() and didn't make a powerpc dedicated
> change.
>
> Once this is merged any other architecture can use
> unsafe_copy_siginfo_to_user().
>
> Did I miss something ?
Not dealing with the compat case and making the code signal stack frame
code noticeably more complicated.
If this optimization profitably applies to other architectures we need
to figure out how to implement unsafe_copy_siginfo_to_user32 or risk
making them all much worse to maintain.
Eric
^ permalink raw reply
* Re: [PATCH 0/2] powerpc/perf: Add instruction and data address registers to extended regs
From: Arnaldo Carvalho de Melo @ 2021-09-11 19:09 UTC (permalink / raw)
To: Athira Rajeev
Cc: Madhavan Srinivasan, rnsastry, kajoljain, Jiri Olsa, linuxppc-dev
In-Reply-To: <BAA2B1EE-36BA-495A-B507-EC3C996199D8@linux.vnet.ibm.com>
Em Mon, Sep 06, 2021 at 08:13:13AM +0530, Athira Rajeev escreveu:
>
>
> > On 02-Sep-2021, at 1:04 PM, kajoljain <kjain@linux.ibm.com> wrote:
> >
> >
> >
> > On 6/20/21 8:15 PM, Athira Rajeev wrote:
> >> Patch set adds PMU registers namely Sampled Instruction Address Register
> >> (SIAR) and Sampled Data Address Register (SDAR) as part of extended regs
> >> in PowerPC. These registers provides the instruction/data address and
> >> adding these to extended regs helps in debug purposes.
> >>
> >> Patch 1/2 adds SIAR and SDAR as part of the extended regs mask.
> >> Patch 2/2 includes perf tools side changes to add the SPRs to
> >> sample_reg_mask to use with -I? option.
> >>
> >> Athira Rajeev (2):
> >> powerpc/perf: Expose instruction and data address registers as part of
> >> extended regs
> >> tools/perf: Add perf tools support to expose instruction and data
> >> address registers as part of extended regs
> >>
> >
> > Patchset looks good to me.
> >
> > Reviewed-By: kajol Jain<kjain@linux.ibm.com>
>
> Hi Arnaldo,
>
> Requesting for your review on this patchset.
So, this touches the kernel, usually I get a patchkit when the kernel
bits landed, is that the case by now?
- Arnaldo
>
> Thanks
> Athira
> >
> > Thanks,
> > Kajol Jain
> >
> >> arch/powerpc/include/uapi/asm/perf_regs.h | 12 +++++++-----
> >> arch/powerpc/perf/perf_regs.c | 4 ++++
> >> tools/arch/powerpc/include/uapi/asm/perf_regs.h | 12 +++++++-----
> >> tools/perf/arch/powerpc/include/perf_regs.h | 2 ++
> >> tools/perf/arch/powerpc/util/perf_regs.c | 2 ++
> >> 5 files changed, 22 insertions(+), 10 deletions(-)
--
- Arnaldo
^ permalink raw reply
* Re: [PATCH 1/1] selftests/powerpc: Add memmove_64 test
From: Ritesh Harjani @ 2021-09-13 2:57 UTC (permalink / raw)
To: Michael Ellerman; +Cc: Aneesh Kumar K . V, linuxppc-dev, Vaibhav Jain
In-Reply-To: <87sfybl5f9.fsf@mpe.ellerman.id.au>
On 21/09/11 09:26PM, Michael Ellerman wrote:
> Ritesh Harjani <riteshh@linux.ibm.com> writes:
> > While debugging an issue, we wanted to check whether the arch specific
> > kernel memmove implementation is correct. This selftest could help test that.
> >
> > Suggested-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> > Suggested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
> > Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
> > ---
> > tools/testing/selftests/powerpc/Makefile | 1 +
> > .../selftests/powerpc/memmoveloop/.gitignore | 2 +
> > .../selftests/powerpc/memmoveloop/Makefile | 19 +++++++
> > .../powerpc/memmoveloop/asm/asm-compat.h | 0
> > .../powerpc/memmoveloop/asm/export.h | 4 ++
> > .../powerpc/memmoveloop/asm/feature-fixups.h | 0
> > .../selftests/powerpc/memmoveloop/asm/kasan.h | 0
> > .../powerpc/memmoveloop/asm/ppc_asm.h | 39 +++++++++++++
> > .../powerpc/memmoveloop/asm/processor.h | 0
> > .../selftests/powerpc/memmoveloop/mem_64.S | 1 +
> > .../selftests/powerpc/memmoveloop/memcpy_64.S | 1 +
> > .../selftests/powerpc/memmoveloop/stubs.S | 8 +++
> > .../selftests/powerpc/memmoveloop/validate.c | 56 +++++++++++++++++++
> > 13 files changed, 131 insertions(+)
> > create mode 100644 tools/testing/selftests/powerpc/memmoveloop/.gitignore
> > create mode 100644 tools/testing/selftests/powerpc/memmoveloop/Makefile
> > create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/asm-compat.h
> > create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/export.h
> > create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/feature-fixups.h
> > create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/kasan.h
> > create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/ppc_asm.h
> > create mode 100644 tools/testing/selftests/powerpc/memmoveloop/asm/processor.h
> > create mode 120000 tools/testing/selftests/powerpc/memmoveloop/mem_64.S
> > create mode 120000 tools/testing/selftests/powerpc/memmoveloop/memcpy_64.S
> > create mode 100644 tools/testing/selftests/powerpc/memmoveloop/stubs.S
> > create mode 100644 tools/testing/selftests/powerpc/memmoveloop/validate.c
>
> You've copied a lot of tools/testing/selftests/powerpc/copyloops
>
> I'd be happier if you integrated the memmove test into that existing
> code. I realise memmove is not technically a copy loop, but it's close
> enough.
Sure.
>
> Did you try that and hit some roadblock?
Nope, let me try that and send it in v2.
-ritesh
>
> cheers
>
>
> > diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
> > index 0830e63818c1..d110b3e5cbcd 100644
> > --- a/tools/testing/selftests/powerpc/Makefile
> > +++ b/tools/testing/selftests/powerpc/Makefile
> > @@ -16,6 +16,7 @@ export CFLAGS
> > SUB_DIRS = alignment \
> > benchmarks \
> > cache_shape \
> > + memmoveloop \
> > copyloops \
> > dscr \
> > mm \
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/.gitignore b/tools/testing/selftests/powerpc/memmoveloop/.gitignore
> > new file mode 100644
> > index 000000000000..56c1426013d5
> > --- /dev/null
> > +++ b/tools/testing/selftests/powerpc/memmoveloop/.gitignore
> > @@ -0,0 +1,2 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +memmove_64
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/Makefile b/tools/testing/selftests/powerpc/memmoveloop/Makefile
> > new file mode 100644
> > index 000000000000..d58d8c100099
> > --- /dev/null
> > +++ b/tools/testing/selftests/powerpc/memmoveloop/Makefile
> > @@ -0,0 +1,19 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +CFLAGS += -m64
> > +CFLAGS += -I$(CURDIR)
> > +CFLAGS += -D SELFTEST
> > +CFLAGS += -maltivec
> > +
> > +ASFLAGS = $(CFLAGS) -Wa,-mpower4
> > +
> > +TEST_GEN_PROGS := memmove_64
> > +EXTRA_SOURCES := validate.c ../harness.c stubs.S
> > +CPPFLAGS += -D TEST_MEMMOVE=test_memmove
> > +
> > +top_srcdir = ../../../../..
> > +include ../../lib.mk
> > +
> > +$(OUTPUT)/memmove_64: mem_64.S memcpy_64.S $(EXTRA_SOURCES)
> > + $(CC) $(CPPFLAGS) $(CFLAGS) \
> > + -D TEST_MEMMOVE=test_memmove \
> > + -o $@ $^
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/asm-compat.h b/tools/testing/selftests/powerpc/memmoveloop/asm/asm-compat.h
> > new file mode 100644
> > index 000000000000..e69de29bb2d1
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/export.h b/tools/testing/selftests/powerpc/memmoveloop/asm/export.h
> > new file mode 100644
> > index 000000000000..e6b80d5fbd14
> > --- /dev/null
> > +++ b/tools/testing/selftests/powerpc/memmoveloop/asm/export.h
> > @@ -0,0 +1,4 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#define EXPORT_SYMBOL(x)
> > +#define EXPORT_SYMBOL_GPL(x)
> > +#define EXPORT_SYMBOL_KASAN(x)
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/feature-fixups.h b/tools/testing/selftests/powerpc/memmoveloop/asm/feature-fixups.h
> > new file mode 100644
> > index 000000000000..e69de29bb2d1
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/kasan.h b/tools/testing/selftests/powerpc/memmoveloop/asm/kasan.h
> > new file mode 100644
> > index 000000000000..e69de29bb2d1
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/ppc_asm.h b/tools/testing/selftests/powerpc/memmoveloop/asm/ppc_asm.h
> > new file mode 100644
> > index 000000000000..117005c56e19
> > --- /dev/null
> > +++ b/tools/testing/selftests/powerpc/memmoveloop/asm/ppc_asm.h
> > @@ -0,0 +1,39 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef __SELFTESTS_POWERPC_PPC_ASM_H
> > +#define __SELFTESTS_POWERPC_PPC_ASM_H
> > +#include <ppc-asm.h>
> > +
> > +#define CONFIG_ALTIVEC
> > +
> > +#define r1 1
> > +
> > +#define R14 r14
> > +#define R15 r15
> > +#define R16 r16
> > +#define R17 r17
> > +#define R18 r18
> > +#define R19 r19
> > +#define R20 r20
> > +#define R21 r21
> > +#define R22 r22
> > +#define R29 r29
> > +#define R30 r30
> > +#define R31 r31
> > +
> > +#define STACKFRAMESIZE 256
> > +#define STK_REG(i) (112 + ((i)-14)*8)
> > +
> > +#define _GLOBAL(A) FUNC_START(test_ ## A)
> > +#define _GLOBAL_TOC(A) _GLOBAL(A)
> > +#define _GLOBAL_TOC_KASAN(A) _GLOBAL(A)
> > +#define _GLOBAL_KASAN(A) _GLOBAL(A)
> > +
> > +#define PPC_MTOCRF(A, B) mtocrf A, B
> > +
> > +#define BEGIN_FTR_SECTION
> > +#define FTR_SECTION_ELSE
> > +#define ALT_FTR_SECTION_END_IFCLR(x)
> > +#define ALT_FTR_SECTION_END(x, y)
> > +#define END_FTR_SECTION_IFCLR(x)
> > +
> > +#endif /* __SELFTESTS_POWERPC_PPC_ASM_H */
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/asm/processor.h b/tools/testing/selftests/powerpc/memmoveloop/asm/processor.h
> > new file mode 100644
> > index 000000000000..e69de29bb2d1
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/mem_64.S b/tools/testing/selftests/powerpc/memmoveloop/mem_64.S
> > new file mode 120000
> > index 000000000000..db254c9a5f5c
> > --- /dev/null
> > +++ b/tools/testing/selftests/powerpc/memmoveloop/mem_64.S
> > @@ -0,0 +1 @@
> > +../../../../../arch/powerpc/lib/mem_64.S
> > \ No newline at end of file
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/memcpy_64.S b/tools/testing/selftests/powerpc/memmoveloop/memcpy_64.S
> > new file mode 120000
> > index 000000000000..cce33fb6f9d8
> > --- /dev/null
> > +++ b/tools/testing/selftests/powerpc/memmoveloop/memcpy_64.S
> > @@ -0,0 +1 @@
> > +../../../../../arch/powerpc/lib/memcpy_64.S
> > \ No newline at end of file
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/stubs.S b/tools/testing/selftests/powerpc/memmoveloop/stubs.S
> > new file mode 100644
> > index 000000000000..d9baa832fa49
> > --- /dev/null
> > +++ b/tools/testing/selftests/powerpc/memmoveloop/stubs.S
> > @@ -0,0 +1,8 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#include <asm/ppc_asm.h>
> > +
> > +FUNC_START(memcpy)
> > + b test_memcpy
> > +
> > +FUNC_START(backwards_memcpy)
> > + b test_backwards_memcpy
> > diff --git a/tools/testing/selftests/powerpc/memmoveloop/validate.c b/tools/testing/selftests/powerpc/memmoveloop/validate.c
> > new file mode 100644
> > index 000000000000..52f7d32bb3fe
> > --- /dev/null
> > +++ b/tools/testing/selftests/powerpc/memmoveloop/validate.c
> > @@ -0,0 +1,56 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +#include <malloc.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <assert.h>
> > +#include "utils.h"
> > +
> > +void *TEST_MEMMOVE(const void *s1, const void *s2, size_t n);
> > +
> > +#define BUF_LEN 65536
> > +#define MAX_OFFSET 512
> > +
> > +size_t max(size_t a, size_t b)
> > +{
> > + if (a >= b) return a;
> > + return b;
> > +}
> > +
> > +static int testcase_run(void)
> > +{
> > + size_t i, src_off, dst_off, len;
> > +
> > + char *usermap = memalign(BUF_LEN, BUF_LEN);
> > + char *kernelmap = memalign(BUF_LEN, BUF_LEN);
> > +
> > + assert(usermap != NULL);
> > + assert(kernelmap != NULL);
> > +
> > + memset(usermap, 0, BUF_LEN);
> > + memset(kernelmap, 0, BUF_LEN);
> > +
> > + for (i = 0; i < BUF_LEN; i++) {
> > + usermap[i] = i & 0xff;
> > + kernelmap[i] = i & 0xff;
> > + }
> > +
> > + for (src_off = 0; src_off < MAX_OFFSET; src_off++) {
> > + for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) {
> > + for (len = 1; len < MAX_OFFSET - max(src_off, dst_off); len++) {
> > +
> > + memmove(usermap + dst_off, usermap + src_off, len);
> > + TEST_MEMMOVE(kernelmap + dst_off, kernelmap + src_off, len);
> > + if (memcmp(usermap, kernelmap, MAX_OFFSET) != 0) {
> > + printf("memmove failed at %ld %ld %ld\n", src_off, dst_off, len);
> > + abort();
> > + }
> > + }
> > + }
> > + }
> > + return 0;
> > +}
> > +
> > +int main(void)
> > +{
> > + return test_harness(testcase_run, "memmove");
> > +}
> > --
> > 2.31.1
^ permalink raw reply
* [PATCHv2] selftests/powerpc/copyloops: Add memmove_64 test
From: Ritesh Harjani @ 2021-09-13 6:17 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Vaibhav Jain, Ritesh Harjani, Aneesh Kumar K . V
While debugging an issue, we wanted to check whether the arch specific
kernel memmove implementation is correct.
This selftest could help test that.
Suggested-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Suggested-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
---
v1 -> v2: Integrated memmove_64 test within copyloops tests
[v1]: https://patchwork.ozlabs.org/patch/1518082
.../selftests/powerpc/copyloops/.gitignore | 1 +
.../selftests/powerpc/copyloops/Makefile | 9 ++-
.../selftests/powerpc/copyloops/asm/ppc_asm.h | 1 +
.../selftests/powerpc/copyloops/mem_64.S | 1 +
.../powerpc/copyloops/memcpy_stubs.S | 8 +++
.../powerpc/copyloops/memmove_validate.c | 58 +++++++++++++++++++
6 files changed, 77 insertions(+), 1 deletion(-)
create mode 120000 tools/testing/selftests/powerpc/copyloops/mem_64.S
create mode 100644 tools/testing/selftests/powerpc/copyloops/memcpy_stubs.S
create mode 100644 tools/testing/selftests/powerpc/copyloops/memmove_validate.c
diff --git a/tools/testing/selftests/powerpc/copyloops/.gitignore b/tools/testing/selftests/powerpc/copyloops/.gitignore
index 994b11af765c..7283e8b07b75 100644
--- a/tools/testing/selftests/powerpc/copyloops/.gitignore
+++ b/tools/testing/selftests/powerpc/copyloops/.gitignore
@@ -13,3 +13,4 @@ copyuser_64_exc_t0
copyuser_64_exc_t1
copyuser_64_exc_t2
copy_mc_64
+memmove_64
diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile
index 3095b1f1c02b..77594e697f2f 100644
--- a/tools/testing/selftests/powerpc/copyloops/Makefile
+++ b/tools/testing/selftests/powerpc/copyloops/Makefile
@@ -13,7 +13,8 @@ TEST_GEN_PROGS := copyuser_64_t0 copyuser_64_t1 copyuser_64_t2 \
copyuser_p7_t0 copyuser_p7_t1 \
memcpy_64_t0 memcpy_64_t1 memcpy_64_t2 \
memcpy_p7_t0 memcpy_p7_t1 copy_mc_64 \
- copyuser_64_exc_t0 copyuser_64_exc_t1 copyuser_64_exc_t2
+ copyuser_64_exc_t0 copyuser_64_exc_t1 copyuser_64_exc_t2 \
+ memmove_64
EXTRA_SOURCES := validate.c ../harness.c stubs.S
@@ -56,3 +57,9 @@ $(OUTPUT)/copyuser_64_exc_t%: copyuser_64.S exc_validate.c ../harness.c \
-D COPY_LOOP=test___copy_tofrom_user_base \
-D SELFTEST_CASE=$(subst copyuser_64_exc_t,,$(notdir $@)) \
-o $@ $^
+
+$(OUTPUT)/memmove_64: mem_64.S memcpy_64.S memmove_validate.c ../harness.c \
+ memcpy_stubs.S
+ $(CC) $(CPPFLAGS) $(CFLAGS) \
+ -D TEST_MEMMOVE=test_memmove \
+ -o $@ $^
diff --git a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
index 58c1cef3e399..003e1b3d9300 100644
--- a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
+++ b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
@@ -26,6 +26,7 @@
#define _GLOBAL(A) FUNC_START(test_ ## A)
#define _GLOBAL_TOC(A) _GLOBAL(A)
#define _GLOBAL_TOC_KASAN(A) _GLOBAL(A)
+#define _GLOBAL_KASAN(A) _GLOBAL(A)
#define PPC_MTOCRF(A, B) mtocrf A, B
diff --git a/tools/testing/selftests/powerpc/copyloops/mem_64.S b/tools/testing/selftests/powerpc/copyloops/mem_64.S
new file mode 120000
index 000000000000..db254c9a5f5c
--- /dev/null
+++ b/tools/testing/selftests/powerpc/copyloops/mem_64.S
@@ -0,0 +1 @@
+../../../../../arch/powerpc/lib/mem_64.S
\ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/copyloops/memcpy_stubs.S b/tools/testing/selftests/powerpc/copyloops/memcpy_stubs.S
new file mode 100644
index 000000000000..d9baa832fa49
--- /dev/null
+++ b/tools/testing/selftests/powerpc/copyloops/memcpy_stubs.S
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/ppc_asm.h>
+
+FUNC_START(memcpy)
+ b test_memcpy
+
+FUNC_START(backwards_memcpy)
+ b test_backwards_memcpy
diff --git a/tools/testing/selftests/powerpc/copyloops/memmove_validate.c b/tools/testing/selftests/powerpc/copyloops/memmove_validate.c
new file mode 100644
index 000000000000..1a23218b5757
--- /dev/null
+++ b/tools/testing/selftests/powerpc/copyloops/memmove_validate.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "utils.h"
+
+void *TEST_MEMMOVE(const void *s1, const void *s2, size_t n);
+
+#define BUF_LEN 65536
+#define MAX_OFFSET 512
+
+size_t max(size_t a, size_t b)
+{
+ if (a >= b)
+ return a;
+ return b;
+}
+
+static int testcase_run(void)
+{
+ size_t i, src_off, dst_off, len;
+
+ char *usermap = memalign(BUF_LEN, BUF_LEN);
+ char *kernelmap = memalign(BUF_LEN, BUF_LEN);
+
+ assert(usermap != NULL);
+ assert(kernelmap != NULL);
+
+ memset(usermap, 0, BUF_LEN);
+ memset(kernelmap, 0, BUF_LEN);
+
+ for (i = 0; i < BUF_LEN; i++) {
+ usermap[i] = i & 0xff;
+ kernelmap[i] = i & 0xff;
+ }
+
+ for (src_off = 0; src_off < MAX_OFFSET; src_off++) {
+ for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) {
+ for (len = 1; len < MAX_OFFSET - max(src_off, dst_off); len++) {
+
+ memmove(usermap + dst_off, usermap + src_off, len);
+ TEST_MEMMOVE(kernelmap + dst_off, kernelmap + src_off, len);
+ if (memcmp(usermap, kernelmap, MAX_OFFSET) != 0) {
+ printf("memmove failed at %ld %ld %ld\n",
+ src_off, dst_off, len);
+ abort();
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+int main(void)
+{
+ return test_harness(testcase_run, "memmove");
+}
--
2.31.1
^ permalink raw reply related
* [Bug 213837] "Kernel panic - not syncing: corrupted stack end detected inside scheduler" at building via distcc on a G5
From: bugzilla-daemon @ 2021-09-13 7:16 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-213837-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=213837
Michael Ellerman (michael@ellerman.id.au) changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |michael@ellerman.id.au
Component|Other |PPC-64
Hardware|All |PPC-64
Assignee|akpm@linux-foundation.org |platform_ppc-64@kernel-bugs
| |.osdl.org
Product|Memory Management |Platform Specific/Hardware
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are watching the assignee of the bug.
You are watching someone on the CC list of the bug.
^ permalink raw reply
* [Bug 213837] "Kernel panic - not syncing: corrupted stack end detected inside scheduler" at building via distcc on a G5
From: bugzilla-daemon @ 2021-09-13 7:16 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-213837-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=213837
Michael Ellerman (michael@ellerman.id.au) changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |NEEDINFO
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are watching the assignee of the bug.
You are watching someone on the CC list of the bug.
^ permalink raw reply
* Re: [PATCH v3 1/2] powerpc/64s: system call scv tabort fix for corrupt irq soft-mask state
From: kernel test robot @ 2021-09-13 7:51 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev; +Cc: Eirik Fuller, kbuild-all, Nicholas Piggin
In-Reply-To: <202109040154.k1W0uBhG-lkp@intel.com>
[-- Attachment #1: Type: text/plain, Size: 4421 bytes --]
Please kindly note that this is a powerpc32 build.
Hi Nicholas,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v5.14 next-20210903]
[cannot apply to powerpc/next scottwood/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-64s-system-call-scv-tabort-fix-for-corrupt-irq-soft-mask-state/20210903-205907
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a9c9a6f741cdaa2fa9ba24a790db8d07295761e3
:::::: branch date: 5 hours ago
:::::: commit date: 5 hours ago
config: powerpc-randconfig-s032-20210903 (attached as .config)
compiler: powerpc-linux-gcc (GCC) 11.2.0
reproduce:
cd linux
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O make.cross
chmod +x make.cross
# https://github.com/0day-ci/linux/commit/3510c8c0951ec7ac98da8d6931df7499ca6c881e
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Nicholas-Piggin/powerpc-64s-system-call-scv-tabort-fix-for-corrupt-irq-soft-mask-state/20210903-205907
git checkout 3510c8c0951ec7ac98da8d6931df7499ca6c881e
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 ./make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
In file included from arch/powerpc/include/asm/processor.h:11,
from arch/powerpc/include/asm/thread_info.h:40,
from include/linux/thread_info.h:60,
from arch/powerpc/include/asm/ptrace.h:298,
from arch/powerpc/include/asm/hw_irq.h:12,
from arch/powerpc/include/asm/irqflags.h:12,
from include/linux/irqflags.h:16,
from include/asm-generic/cmpxchg-local.h:6,
from arch/powerpc/include/asm/cmpxchg.h:526,
from arch/powerpc/include/asm/atomic.h:11,
from include/linux/atomic.h:7,
from include/linux/rcupdate.h:25,
from include/linux/rculist.h:11,
from include/linux/pid.h:5,
from include/linux/sched.h:14,
from include/linux/context_tracking.h:5,
from arch/powerpc/kernel/interrupt.c:3:
arch/powerpc/kernel/interrupt.c: In function 'system_call_exception':
>> arch/powerpc/include/asm/reg.h:66:29: error: left shift count >= width of type [-Werror=shift-count-overflow]
66 | #define __MASK(X) (1UL<<(X))
| ^~
arch/powerpc/include/asm/reg.h:1378:61: note: in definition of macro 'mtmsr'
1378 | : "r" ((unsigned long)(v)) \
| ^
arch/powerpc/include/asm/reg.h:115:25: note: in expansion of macro '__MASK'
115 | #define MSR_TM __MASK(MSR_TM_LG) /* Transactional Mem Available */
| ^~~~~~
arch/powerpc/kernel/interrupt.c:153:33: note: in expansion of macro 'MSR_TM'
153 | mtmsr(mfmsr() | MSR_TM);
| ^~~~~~
cc1: all warnings being treated as errors
vim +66 arch/powerpc/include/asm/reg.h
14cf11af6cf608 include/asm-powerpc/reg.h Paul Mackerras 2005-09-26 62
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 63 #ifdef __ASSEMBLY__
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 64 #define __MASK(X) (1<<(X))
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 65 #else
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 @66 #define __MASK(X) (1UL<<(X))
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 67 #endif
9f04b9e327c495 include/asm-powerpc/reg.h Paul Mackerras 2005-10-10 68
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 26576 bytes --]
^ permalink raw reply
* [Bug 206669] Little-endian kernel crashing on POWER8 on heavy big-endian PowerKVM load
From: bugzilla-daemon @ 2021-09-13 8:52 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-206669-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=206669
Michael Ellerman (michael@ellerman.id.au) changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |NEEDINFO
CC| |michael@ellerman.id.au
--- Comment #15 from Michael Ellerman (michael@ellerman.id.au) ---
After a day and a half I have managed to get BE debian installed in a VM :}
You said "running the glibc testsuite" was enough to trigger it. Do you mean
from the glibc git tree? I can't get upstream, or the debian packaged glibc
sources to build.
Both fail building with:
../include/setjmp.h:42:3: error: static assertion failed: "size of jmp_buf !=
656"
42 | _Static_assert (sizeof (type) == size, \
| ^~~~~~~~~~~~~~
I guess I'm doing something wrong.
Any pointers on what your setup is?
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* [Bug 206669] Little-endian kernel crashing on POWER8 on heavy big-endian PowerKVM load
From: bugzilla-daemon @ 2021-09-13 9:24 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-206669-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=206669
--- Comment #16 from John Paul Adrian Glaubitz (glaubitz@physik.fu-berlin.de) ---
Hi Michael!
Thanks a lot for looking into this!
If you have installed a Debian unstable big-endian system, the easiest way to
get such a setup by creating an sbuild chroot. You should set up an sbuild
chroot for both powerpc and ppc64:
$ sbuild-createchroot --arch=powerpc
$ sbuild-createchroot --arch=ppc64
and then build the glibc package using sbuild for both powerpc and ppc64 in
parallel which is what makes the VM and the host crash during the testsuite:
$ dget -u https://deb.debian.org/debian/pool/main/g/glibc/glibc_2.32-2.dsc
In one shell:
$ sbuild -d sid --arch=ppc64 --no-arch-all glibc_2.32-2.dsc
and in a second one:
$ sbuild -d sid --arch=powerpc --no-arch-all glibc_2.32-2.dsc
If glibc doesn't trigger the crash, try gcc-10 or llvm-toolchain-13:
$ dget -u
https://deb.debian.org/debian/pool/main/l/llvm-toolchain-13/llvm-toolchain-13_13.0.0~+rc2-3.dsc
$ dget -u https://deb.debian.org/debian/pool/main/g/gcc-11/gcc-11_11.2.0-5.dsc
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* LLVM/clang ias build fails with unsupported arguments '-mpower4' and '-many' to option 'Wa,'
From: Paul Menzel @ 2021-09-13 9:48 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras
Cc: Derek Parker, llvm, Nick Desaulniers, Nathan Chancellor,
Dmitrii Okunev, linuxppc-dev
Dear Linux folks,
Building Linux with LLVM’s integrated assembler fails with the error
below [1].
```
$ ARCH=powerpc CROSS_COMPILE=powerpc64le-linux-gnu- make LLVM=1
LLVM_IAS=1 -j72 pseries_defconfig arch/powerpc/kernel/vdso32/gettimeofday.o
...
arch/powerpc/kernel/vdso32/gettimeofday.S:72:8: error: unsupported
directive '.stabs'
.stabs "_restgpr_31_x:F-1",36,0,0,_restgpr_31_x; .globl _restgpr_31_x;
_restgpr_31_x:
^
arch/powerpc/kernel/vdso32/gettimeofday.S:73:8: error: unsupported
directive '.stabs'
.stabs "_rest32gpr_31_x:F-1",36,0,0,_rest32gpr_31_x; .globl
_rest32gpr_31_x; _rest32gpr_31_x:
^
```
The LLVM developers are not planning on implementing this, as Stab has
been succeeded by DWARF [2].
Kind regards,
Paul
[1]: https://github.com/ClangBuiltLinux/linux/issues/1418
[2]: https://bugs.llvm.org/show_bug.cgi?id=31134
^ permalink raw reply
* Re: [PATCH v2] ASoC: fsl_rpmsg: add soc specific data structure
From: Mark Brown @ 2021-09-13 10:53 UTC (permalink / raw)
To: perex, nicoleotsuka, festevam, alsa-devel, Xiubo.Lee,
Shengjiu Wang, tiwai, timur
Cc: Mark Brown, linuxppc-dev, linux-kernel
In-Reply-To: <1630044038-19036-1-git-send-email-shengjiu.wang@nxp.com>
On Fri, 27 Aug 2021 14:00:38 +0800, Shengjiu Wang wrote:
> Each platform has different supported rates and
> formats, so add soc specific data for each platform.
> This soc specific data is attached with compatible string.
>
>
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/1] ASoC: fsl_rpmsg: add soc specific data structure
commit: b7bbbf01362720a8066e3f6d880cae6d63fc92f6
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply
* [PATCH v3 1/6] powerpc/signal64: Access function descriptor with user access block
From: Christophe Leroy @ 2001-09-16 22:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
ebiederm, hch
Cc: linuxppc-dev, linux-kernel
Access the function descriptor of the handler within a
user access block.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
v3: Flatten the change to avoid nested gotos.
---
arch/powerpc/kernel/signal_64.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 1831bba0582e..7b1cd50bc4fb 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -936,8 +936,13 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
func_descr_t __user *funct_desc_ptr =
(func_descr_t __user *) ksig->ka.sa.sa_handler;
- err |= get_user(regs->ctr, &funct_desc_ptr->entry);
- err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
+ if (!user_read_access_begin(funct_desc_ptr, sizeof(func_descr_t)))
+ goto badfunc;
+
+ unsafe_get_user(regs->ctr, &funct_desc_ptr->entry, badfunc_block);
+ unsafe_get_user(regs->gpr[2], &funct_desc_ptr->toc, badfunc_block);
+
+ user_read_access_end();
}
/* enter the signal handler in native-endian mode */
@@ -962,5 +967,12 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
badframe:
signal_fault(current, regs, "handle_rt_signal64", frame);
+ return 1;
+
+badfunc_block:
+ user_read_access_end();
+badfunc:
+ signal_fault(current, regs, __func__, (void __user *)ksig->ka.sa.sa_handler);
+
return 1;
}
--
2.31.1
^ permalink raw reply related
* [PATCH v3 2/6] powerpc/signal: Include the new stack frame inside the user access block
From: Christophe Leroy @ 2001-09-16 22:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
ebiederm, hch
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1718f38859d5366f82d5bef531f255cedf537b5d.1631532888.git.christophe.leroy@csgroup.eu>
Include the new stack frame inside the user access block and set it up
using unsafe_put_user().
On an mpc 8321 (book3s/32) the improvment is about 4% on a process
sending a signal to itself.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 29 +++++++++++++----------------
arch/powerpc/kernel/signal_64.c | 14 +++++++-------
2 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 0608581967f0..ff101e2b3bab 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -726,7 +726,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
struct rt_sigframe __user *frame;
struct mcontext __user *mctx;
struct mcontext __user *tm_mctx = NULL;
- unsigned long newsp = 0;
+ unsigned long __user *newsp;
unsigned long tramp;
struct pt_regs *regs = tsk->thread.regs;
/* Save the thread's msr before get_tm_stackpointer() changes it */
@@ -734,6 +734,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
frame = get_sigframe(ksig, tsk, sizeof(*frame), 1);
+ newsp = (unsigned long __user *)((unsigned long)frame - (__SIGNAL_FRAMESIZE + 16));
mctx = &frame->uc.uc_mcontext;
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
tm_mctx = &frame->uc_transact.uc_mcontext;
@@ -743,7 +744,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
else
prepare_save_user_regs(1);
- if (!user_access_begin(frame, sizeof(*frame)))
+ if (!user_access_begin(newsp, __SIGNAL_FRAMESIZE + 16 + sizeof(*frame)))
goto badframe;
/* Put the siginfo & fill in most of the ucontext */
@@ -779,6 +780,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
}
unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, failed);
+ /* create a stack frame for the caller of the handler */
+ unsafe_put_user(regs->gpr[1], newsp, failed);
+
user_access_end();
if (copy_siginfo_to_user(&frame->info, &ksig->info))
@@ -790,13 +794,8 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
#endif
- /* create a stack frame for the caller of the handler */
- newsp = ((unsigned long)frame) - (__SIGNAL_FRAMESIZE + 16);
- if (put_user(regs->gpr[1], (u32 __user *)newsp))
- goto badframe;
-
/* Fill registers for signal handler */
- regs->gpr[1] = newsp;
+ regs->gpr[1] = (unsigned long)newsp;
regs->gpr[3] = ksig->sig;
regs->gpr[4] = (unsigned long)&frame->info;
regs->gpr[5] = (unsigned long)&frame->uc;
@@ -826,7 +825,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
struct sigframe __user *frame;
struct mcontext __user *mctx;
struct mcontext __user *tm_mctx = NULL;
- unsigned long newsp = 0;
+ unsigned long __user *newsp;
unsigned long tramp;
struct pt_regs *regs = tsk->thread.regs;
/* Save the thread's msr before get_tm_stackpointer() changes it */
@@ -834,6 +833,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
frame = get_sigframe(ksig, tsk, sizeof(*frame), 1);
+ newsp = (unsigned long __user *)((unsigned long)frame - __SIGNAL_FRAMESIZE);
mctx = &frame->mctx;
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
tm_mctx = &frame->mctx_transact;
@@ -843,7 +843,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
else
prepare_save_user_regs(1);
- if (!user_access_begin(frame, sizeof(*frame)))
+ if (!user_access_begin(newsp, __SIGNAL_FRAMESIZE + sizeof(*frame)))
goto badframe;
sc = (struct sigcontext __user *) &frame->sctx;
@@ -873,6 +873,8 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
unsafe_put_user(PPC_RAW_SC(), &mctx->mc_pad[1], failed);
asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0]));
}
+ /* create a stack frame for the caller of the handler */
+ unsafe_put_user(regs->gpr[1], newsp, failed);
user_access_end();
regs->link = tramp;
@@ -881,12 +883,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
#endif
- /* create a stack frame for the caller of the handler */
- newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
- if (put_user(regs->gpr[1], (u32 __user *)newsp))
- goto badframe;
-
- regs->gpr[1] = newsp;
+ regs->gpr[1] = (unsigned long)newsp;
regs->gpr[3] = ksig->sig;
regs->gpr[4] = (unsigned long) sc;
regs_set_return_ip(regs, (unsigned long) ksig->ka.sa.sa_handler);
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 7b1cd50bc4fb..d80ff83cacb9 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -847,13 +847,14 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
struct task_struct *tsk)
{
struct rt_sigframe __user *frame;
- unsigned long newsp = 0;
+ unsigned long __user *newsp;
long err = 0;
struct pt_regs *regs = tsk->thread.regs;
/* Save the thread's msr before get_tm_stackpointer() changes it */
unsigned long msr = regs->msr;
frame = get_sigframe(ksig, tsk, sizeof(*frame), 0);
+ newsp = (unsigned long __user *)((unsigned long)frame - __SIGNAL_FRAMESIZE);
/*
* This only applies when calling unsafe_setup_sigcontext() and must be
@@ -862,7 +863,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
if (!MSR_TM_ACTIVE(msr))
prepare_setup_sigcontext(tsk);
- if (!user_write_access_begin(frame, sizeof(*frame)))
+ if (!user_write_access_begin(newsp, __SIGNAL_FRAMESIZE + sizeof(*frame)))
goto badframe;
unsafe_put_user(&frame->info, &frame->pinfo, badframe_block);
@@ -900,6 +901,9 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
}
unsafe_copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set), badframe_block);
+ /* Allocate a dummy caller frame for the signal handler. */
+ unsafe_put_user(regs->gpr[1], newsp, badframe_block);
+
user_write_access_end();
/* Save the siginfo outside of the unsafe block. */
@@ -919,10 +923,6 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
regs_set_return_ip(regs, (unsigned long) &frame->tramp[0]);
}
- /* Allocate a dummy caller frame for the signal handler. */
- newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
- err |= put_user(regs->gpr[1], (unsigned long __user *)newsp);
-
/* Set up "regs" so we "return" to the signal handler. */
if (is_elf2_task()) {
regs->ctr = (unsigned long) ksig->ka.sa.sa_handler;
@@ -947,7 +947,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
/* enter the signal handler in native-endian mode */
regs_set_return_msr(regs, (regs->msr & ~MSR_LE) | (MSR_KERNEL & MSR_LE));
- regs->gpr[1] = newsp;
+ regs->gpr[1] = (unsigned long)newsp;
regs->gpr[3] = ksig->sig;
regs->result = 0;
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
--
2.31.1
^ permalink raw reply related
* [PATCH v3 3/6] signal: Add unsafe_copy_siginfo_to_user()
From: Christophe Leroy @ 2001-09-16 22:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
ebiederm, hch
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1718f38859d5366f82d5bef531f255cedf537b5d.1631532888.git.christophe.leroy@csgroup.eu>
In the same spirit as commit fb05121fd6a2 ("signal: Add
unsafe_get_compat_sigset()"), implement an 'unsafe' version of
copy_siginfo_to_user() in order to use it within user access blocks.
For that, also add an 'unsafe' version of clear_user().
This commit adds the generic fallback for unsafe_clear_user().
Architectures wanting to use unsafe_copy_siginfo_to_user() within a
user_access_begin() section have to make sure they have their
own unsafe_clear_user().
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
v3: Added precision about unsafe_clear_user() in commit message.
---
include/linux/signal.h | 15 +++++++++++++++
include/linux/uaccess.h | 1 +
kernel/signal.c | 5 -----
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 3f96a6374e4f..70ea7e741427 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -35,6 +35,21 @@ static inline void copy_siginfo_to_external(siginfo_t *to,
int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *from);
int copy_siginfo_from_user(kernel_siginfo_t *to, const siginfo_t __user *from);
+static __always_inline char __user *si_expansion(const siginfo_t __user *info)
+{
+ return ((char __user *)info) + sizeof(struct kernel_siginfo);
+}
+
+#define unsafe_copy_siginfo_to_user(to, from, label) do { \
+ siginfo_t __user *__ucs_to = to; \
+ const kernel_siginfo_t *__ucs_from = from; \
+ char __user *__ucs_expansion = si_expansion(__ucs_to); \
+ \
+ unsafe_copy_to_user(__ucs_to, __ucs_from, \
+ sizeof(struct kernel_siginfo), label); \
+ unsafe_clear_user(__ucs_expansion, SI_EXPANSION_SIZE, label); \
+} while (0)
+
enum siginfo_layout {
SIL_KILL,
SIL_TIMER,
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index c05e903cef02..37073caac474 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -398,6 +398,7 @@ long strnlen_user_nofault(const void __user *unsafe_addr, long count);
#define unsafe_put_user(x,p,e) unsafe_op_wrap(__put_user(x,p),e)
#define unsafe_copy_to_user(d,s,l,e) unsafe_op_wrap(__copy_to_user(d,s,l),e)
#define unsafe_copy_from_user(d,s,l,e) unsafe_op_wrap(__copy_from_user(d,s,l),e)
+#define unsafe_clear_user(d, l, e) unsafe_op_wrap(__clear_user(d, l), e)
static inline unsigned long user_access_save(void) { return 0UL; }
static inline void user_access_restore(unsigned long flags) { }
#endif
diff --git a/kernel/signal.c b/kernel/signal.c
index 952741f6d0f9..23f168730b7e 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3324,11 +3324,6 @@ enum siginfo_layout siginfo_layout(unsigned sig, int si_code)
return layout;
}
-static inline char __user *si_expansion(const siginfo_t __user *info)
-{
- return ((char __user *)info) + sizeof(struct kernel_siginfo);
-}
-
int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *from)
{
char __user *expansion = si_expansion(to);
--
2.31.1
^ permalink raw reply related
* [PATCH v3 4/6] signal: Add unsafe_copy_siginfo_to_user32()
From: Christophe Leroy @ 2001-09-16 22:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
ebiederm, hch
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1718f38859d5366f82d5bef531f255cedf537b5d.1631532888.git.christophe.leroy@csgroup.eu>
In the same spirit as commit fb05121fd6a2 ("signal: Add
unsafe_get_compat_sigset()"), implement an 'unsafe' version of
copy_siginfo_to_user32() in order to use it within user access blocks.
To do so, we need inline version of copy_siginfo_to_external32() as we
don't want any function call inside user access blocks.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
include/linux/compat.h | 83 +++++++++++++++++++++++++++++-
include/linux/signal.h | 58 +++++++++++++++++++++
kernel/signal.c | 114 +----------------------------------------
3 files changed, 141 insertions(+), 114 deletions(-)
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 8e0598c7d1d1..68823f4b86ee 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -412,6 +412,19 @@ int __copy_siginfo_to_user32(struct compat_siginfo __user *to,
#ifndef copy_siginfo_to_user32
#define copy_siginfo_to_user32 __copy_siginfo_to_user32
#endif
+
+#ifdef CONFIG_COMPAT
+#define unsafe_copy_siginfo_to_user32(to, from, label) do { \
+ struct compat_siginfo __user *__ucs_to = to; \
+ const struct kernel_siginfo *__ucs_from = from; \
+ struct compat_siginfo __ucs_new = {0}; \
+ \
+ __copy_siginfo_to_external32(&__ucs_new, __ucs_from); \
+ unsafe_copy_to_user(__ucs_to, &__ucs_new, \
+ sizeof(struct compat_siginfo), label); \
+} while (0)
+#endif
+
int get_compat_sigevent(struct sigevent *event,
const struct compat_sigevent __user *u_event);
@@ -992,15 +1005,81 @@ static inline bool in_compat_syscall(void) { return false; }
* appropriately converted them already.
*/
#ifndef compat_ptr
-static inline void __user *compat_ptr(compat_uptr_t uptr)
+static __always_inline void __user *compat_ptr(compat_uptr_t uptr)
{
return (void __user *)(unsigned long)uptr;
}
#endif
-static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+static __always_inline compat_uptr_t ptr_to_compat(void __user *uptr)
{
return (u32)(unsigned long)uptr;
}
+static __always_inline void
+__copy_siginfo_to_external32(struct compat_siginfo *to,
+ const struct kernel_siginfo *from)
+{
+ to->si_signo = from->si_signo;
+ to->si_errno = from->si_errno;
+ to->si_code = from->si_code;
+ switch(__siginfo_layout(from->si_signo, from->si_code)) {
+ case SIL_KILL:
+ to->si_pid = from->si_pid;
+ to->si_uid = from->si_uid;
+ break;
+ case SIL_TIMER:
+ to->si_tid = from->si_tid;
+ to->si_overrun = from->si_overrun;
+ to->si_int = from->si_int;
+ break;
+ case SIL_POLL:
+ to->si_band = from->si_band;
+ to->si_fd = from->si_fd;
+ break;
+ case SIL_FAULT:
+ to->si_addr = ptr_to_compat(from->si_addr);
+ break;
+ case SIL_FAULT_TRAPNO:
+ to->si_addr = ptr_to_compat(from->si_addr);
+ to->si_trapno = from->si_trapno;
+ break;
+ case SIL_FAULT_MCEERR:
+ to->si_addr = ptr_to_compat(from->si_addr);
+ to->si_addr_lsb = from->si_addr_lsb;
+ break;
+ case SIL_FAULT_BNDERR:
+ to->si_addr = ptr_to_compat(from->si_addr);
+ to->si_lower = ptr_to_compat(from->si_lower);
+ to->si_upper = ptr_to_compat(from->si_upper);
+ break;
+ case SIL_FAULT_PKUERR:
+ to->si_addr = ptr_to_compat(from->si_addr);
+ to->si_pkey = from->si_pkey;
+ break;
+ case SIL_FAULT_PERF_EVENT:
+ to->si_addr = ptr_to_compat(from->si_addr);
+ to->si_perf_data = from->si_perf_data;
+ to->si_perf_type = from->si_perf_type;
+ break;
+ case SIL_CHLD:
+ to->si_pid = from->si_pid;
+ to->si_uid = from->si_uid;
+ to->si_status = from->si_status;
+ to->si_utime = from->si_utime;
+ to->si_stime = from->si_stime;
+ break;
+ case SIL_RT:
+ to->si_pid = from->si_pid;
+ to->si_uid = from->si_uid;
+ to->si_int = from->si_int;
+ break;
+ case SIL_SYS:
+ to->si_call_addr = ptr_to_compat(from->si_call_addr);
+ to->si_syscall = from->si_syscall;
+ to->si_arch = from->si_arch;
+ break;
+ }
+}
+
#endif /* _LINUX_COMPAT_H */
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 70ea7e741427..637260bc193d 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -65,6 +65,64 @@ enum siginfo_layout {
SIL_SYS,
};
+static const struct {
+ unsigned char limit, layout;
+} sig_sicodes[] = {
+ [SIGILL] = { NSIGILL, SIL_FAULT },
+ [SIGFPE] = { NSIGFPE, SIL_FAULT },
+ [SIGSEGV] = { NSIGSEGV, SIL_FAULT },
+ [SIGBUS] = { NSIGBUS, SIL_FAULT },
+ [SIGTRAP] = { NSIGTRAP, SIL_FAULT },
+#if defined(SIGEMT)
+ [SIGEMT] = { NSIGEMT, SIL_FAULT },
+#endif
+ [SIGCHLD] = { NSIGCHLD, SIL_CHLD },
+ [SIGPOLL] = { NSIGPOLL, SIL_POLL },
+ [SIGSYS] = { NSIGSYS, SIL_SYS },
+};
+
+static __always_inline enum
+siginfo_layout __siginfo_layout(unsigned sig, int si_code)
+{
+ enum siginfo_layout layout = SIL_KILL;
+
+ if ((si_code > SI_USER) && (si_code < SI_KERNEL)) {
+ if ((sig < ARRAY_SIZE(sig_sicodes)) &&
+ (si_code <= sig_sicodes[sig].limit)) {
+ layout = sig_sicodes[sig].layout;
+ /* Handle the exceptions */
+ if ((sig == SIGBUS) &&
+ (si_code >= BUS_MCEERR_AR) && (si_code <= BUS_MCEERR_AO))
+ layout = SIL_FAULT_MCEERR;
+ else if ((sig == SIGSEGV) && (si_code == SEGV_BNDERR))
+ layout = SIL_FAULT_BNDERR;
+#ifdef SEGV_PKUERR
+ else if ((sig == SIGSEGV) && (si_code == SEGV_PKUERR))
+ layout = SIL_FAULT_PKUERR;
+#endif
+ else if ((sig == SIGTRAP) && (si_code == TRAP_PERF))
+ layout = SIL_FAULT_PERF_EVENT;
+ else if (IS_ENABLED(CONFIG_SPARC) &&
+ (sig == SIGILL) && (si_code == ILL_ILLTRP))
+ layout = SIL_FAULT_TRAPNO;
+ else if (IS_ENABLED(CONFIG_ALPHA) &&
+ ((sig == SIGFPE) ||
+ ((sig == SIGTRAP) && (si_code == TRAP_UNK))))
+ layout = SIL_FAULT_TRAPNO;
+ }
+ else if (si_code <= NSIGPOLL)
+ layout = SIL_POLL;
+ } else {
+ if (si_code == SI_TIMER)
+ layout = SIL_TIMER;
+ else if (si_code == SI_SIGIO)
+ layout = SIL_POLL;
+ else if (si_code < 0)
+ layout = SIL_RT;
+ }
+ return layout;
+}
+
enum siginfo_layout siginfo_layout(unsigned sig, int si_code);
/*
diff --git a/kernel/signal.c b/kernel/signal.c
index 23f168730b7e..0d402bdb174e 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3249,22 +3249,6 @@ COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset,
}
#endif
-static const struct {
- unsigned char limit, layout;
-} sig_sicodes[] = {
- [SIGILL] = { NSIGILL, SIL_FAULT },
- [SIGFPE] = { NSIGFPE, SIL_FAULT },
- [SIGSEGV] = { NSIGSEGV, SIL_FAULT },
- [SIGBUS] = { NSIGBUS, SIL_FAULT },
- [SIGTRAP] = { NSIGTRAP, SIL_FAULT },
-#if defined(SIGEMT)
- [SIGEMT] = { NSIGEMT, SIL_FAULT },
-#endif
- [SIGCHLD] = { NSIGCHLD, SIL_CHLD },
- [SIGPOLL] = { NSIGPOLL, SIL_POLL },
- [SIGSYS] = { NSIGSYS, SIL_SYS },
-};
-
static bool known_siginfo_layout(unsigned sig, int si_code)
{
if (si_code == SI_KERNEL)
@@ -3286,42 +3270,7 @@ static bool known_siginfo_layout(unsigned sig, int si_code)
enum siginfo_layout siginfo_layout(unsigned sig, int si_code)
{
- enum siginfo_layout layout = SIL_KILL;
- if ((si_code > SI_USER) && (si_code < SI_KERNEL)) {
- if ((sig < ARRAY_SIZE(sig_sicodes)) &&
- (si_code <= sig_sicodes[sig].limit)) {
- layout = sig_sicodes[sig].layout;
- /* Handle the exceptions */
- if ((sig == SIGBUS) &&
- (si_code >= BUS_MCEERR_AR) && (si_code <= BUS_MCEERR_AO))
- layout = SIL_FAULT_MCEERR;
- else if ((sig == SIGSEGV) && (si_code == SEGV_BNDERR))
- layout = SIL_FAULT_BNDERR;
-#ifdef SEGV_PKUERR
- else if ((sig == SIGSEGV) && (si_code == SEGV_PKUERR))
- layout = SIL_FAULT_PKUERR;
-#endif
- else if ((sig == SIGTRAP) && (si_code == TRAP_PERF))
- layout = SIL_FAULT_PERF_EVENT;
- else if (IS_ENABLED(CONFIG_SPARC) &&
- (sig == SIGILL) && (si_code == ILL_ILLTRP))
- layout = SIL_FAULT_TRAPNO;
- else if (IS_ENABLED(CONFIG_ALPHA) &&
- ((sig == SIGFPE) ||
- ((sig == SIGTRAP) && (si_code == TRAP_UNK))))
- layout = SIL_FAULT_TRAPNO;
- }
- else if (si_code <= NSIGPOLL)
- layout = SIL_POLL;
- } else {
- if (si_code == SI_TIMER)
- layout = SIL_TIMER;
- else if (si_code == SI_SIGIO)
- layout = SIL_POLL;
- else if (si_code < 0)
- layout = SIL_RT;
- }
- return layout;
+ return __siginfo_layout(sig, si_code);
}
int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *from)
@@ -3389,66 +3338,7 @@ void copy_siginfo_to_external32(struct compat_siginfo *to,
{
memset(to, 0, sizeof(*to));
- to->si_signo = from->si_signo;
- to->si_errno = from->si_errno;
- to->si_code = from->si_code;
- switch(siginfo_layout(from->si_signo, from->si_code)) {
- case SIL_KILL:
- to->si_pid = from->si_pid;
- to->si_uid = from->si_uid;
- break;
- case SIL_TIMER:
- to->si_tid = from->si_tid;
- to->si_overrun = from->si_overrun;
- to->si_int = from->si_int;
- break;
- case SIL_POLL:
- to->si_band = from->si_band;
- to->si_fd = from->si_fd;
- break;
- case SIL_FAULT:
- to->si_addr = ptr_to_compat(from->si_addr);
- break;
- case SIL_FAULT_TRAPNO:
- to->si_addr = ptr_to_compat(from->si_addr);
- to->si_trapno = from->si_trapno;
- break;
- case SIL_FAULT_MCEERR:
- to->si_addr = ptr_to_compat(from->si_addr);
- to->si_addr_lsb = from->si_addr_lsb;
- break;
- case SIL_FAULT_BNDERR:
- to->si_addr = ptr_to_compat(from->si_addr);
- to->si_lower = ptr_to_compat(from->si_lower);
- to->si_upper = ptr_to_compat(from->si_upper);
- break;
- case SIL_FAULT_PKUERR:
- to->si_addr = ptr_to_compat(from->si_addr);
- to->si_pkey = from->si_pkey;
- break;
- case SIL_FAULT_PERF_EVENT:
- to->si_addr = ptr_to_compat(from->si_addr);
- to->si_perf_data = from->si_perf_data;
- to->si_perf_type = from->si_perf_type;
- break;
- case SIL_CHLD:
- to->si_pid = from->si_pid;
- to->si_uid = from->si_uid;
- to->si_status = from->si_status;
- to->si_utime = from->si_utime;
- to->si_stime = from->si_stime;
- break;
- case SIL_RT:
- to->si_pid = from->si_pid;
- to->si_uid = from->si_uid;
- to->si_int = from->si_int;
- break;
- case SIL_SYS:
- to->si_call_addr = ptr_to_compat(from->si_call_addr);
- to->si_syscall = from->si_syscall;
- to->si_arch = from->si_arch;
- break;
- }
+ __copy_siginfo_to_external32(to, from);
}
int __copy_siginfo_to_user32(struct compat_siginfo __user *to,
--
2.31.1
^ permalink raw reply related
* [PATCH v3 5/6] powerpc/uaccess: Add unsafe_clear_user()
From: Christophe Leroy @ 2001-09-16 22:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
ebiederm, hch
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1718f38859d5366f82d5bef531f255cedf537b5d.1631532888.git.christophe.leroy@csgroup.eu>
Implement unsafe_clear_user() for powerpc.
It's a copy/paste of unsafe_copy_to_user() with value 0 as source.
It may be improved in a later patch by using 'dcbz' instruction
to zeroize full cache lines at once.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/uaccess.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 22c79ab40006..962b675485ff 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -467,6 +467,26 @@ do { \
unsafe_put_user(*(u8*)(_src + _i), (u8 __user *)(_dst + _i), e); \
} while (0)
+#define unsafe_clear_user(d, l, e) \
+do { \
+ u8 __user *_dst = (u8 __user *)(d); \
+ size_t _len = (l); \
+ int _i; \
+ \
+ for (_i = 0; _i < (_len & ~(sizeof(u64) - 1)); _i += sizeof(u64)) \
+ unsafe_put_user(0, (u64 __user *)(_dst + _i), e); \
+ if (_len & 4) { \
+ unsafe_put_user(0, (u32 __user *)(_dst + _i), e); \
+ _i += 4; \
+ } \
+ if (_len & 2) { \
+ unsafe_put_user(0, (u16 __user *)(_dst + _i), e); \
+ _i += 2; \
+ } \
+ if (_len & 1) \
+ unsafe_put_user(0, (u8 __user *)(_dst + _i), e); \
+} while (0)
+
#define HAVE_GET_KERNEL_NOFAULT
#define __get_kernel_nofault(dst, src, type, err_label) \
--
2.31.1
^ permalink raw reply related
* [PATCH v3 6/6] powerpc/signal: Use unsafe_copy_siginfo_to_user()
From: Christophe Leroy @ 2001-09-16 22:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
ebiederm, hch
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1718f38859d5366f82d5bef531f255cedf537b5d.1631532888.git.christophe.leroy@csgroup.eu>
Use unsafe_copy_siginfo_to_user() in order to do the copy
within the user access block.
On an mpc 8321 (book3s/32) the improvment is about 5% on a process
sending a signal to itself.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
v3: Don't leave compat aside, use the new unsafe_copy_siginfo_to_user32()
---
arch/powerpc/kernel/signal_32.c | 8 +++-----
arch/powerpc/kernel/signal_64.c | 5 +----
2 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index ff101e2b3bab..3a2db8af2d65 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -710,9 +710,9 @@ static long restore_tm_user_regs(struct pt_regs *regs, struct mcontext __user *s
}
#endif
-#ifdef CONFIG_PPC64
+#ifndef CONFIG_PPC64
-#define copy_siginfo_to_user copy_siginfo_to_user32
+#define unsafe_copy_siginfo_to_user32 unsafe_copy_siginfo_to_user
#endif /* CONFIG_PPC64 */
@@ -779,15 +779,13 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0]));
}
unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, failed);
+ unsafe_copy_siginfo_to_user32(&frame->info, &ksig->info, failed);
/* create a stack frame for the caller of the handler */
unsafe_put_user(regs->gpr[1], newsp, failed);
user_access_end();
- if (copy_siginfo_to_user(&frame->info, &ksig->info))
- goto badframe;
-
regs->link = tramp;
#ifdef CONFIG_PPC_FPU_REGS
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index d80ff83cacb9..56c0c74aa28c 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -901,15 +901,12 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
}
unsafe_copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set), badframe_block);
+ unsafe_copy_siginfo_to_user(&frame->info, &ksig->info, badframe_block);
/* Allocate a dummy caller frame for the signal handler. */
unsafe_put_user(regs->gpr[1], newsp, badframe_block);
user_write_access_end();
- /* Save the siginfo outside of the unsafe block. */
- if (copy_siginfo_to_user(&frame->info, &ksig->info))
- goto badframe;
-
/* Make sure signal handler doesn't get spurious FP exceptions */
tsk->thread.fp_state.fpscr = 0;
--
2.31.1
^ permalink raw reply related
* Re: [PATCH v2 3/5] signal: Add unsafe_copy_siginfo_to_user()
From: Christophe Leroy @ 2021-09-13 12:56 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <87o88zqf3k.fsf@disp2133>
Le 11/09/2021 à 17:58, Eric W. Biederman a écrit :
> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>
>> On 9/8/21 6:17 PM, Eric W. Biederman wrote:
>>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>>
>>>> Le 02/09/2021 à 20:43, Eric W. Biederman a écrit :
>>>>> Christophe Leroy <christophe.leroy@csgroup.eu> writes:
>>>>>
>>>>>> In the same spirit as commit fb05121fd6a2 ("signal: Add
>>>>>> unsafe_get_compat_sigset()"), implement an 'unsafe' version of
>>>>>> copy_siginfo_to_user() in order to use it within user access blocks.
>>>>>>
>>>>>> For that, also add an 'unsafe' version of clear_user().
>>>>>
>>>>> Looking at your use cases you need the 32bit compat version of this
>>>>> as well.
>>>>>
>>>>> The 32bit compat version is too complicated to become a macro, so I
>>>>> don't think you can make this work correctly for the 32bit compat case.
>>>>
>>>> When looking into patch 5/5 that you nacked, I think you missed the fact that we
>>>> keep using copy_siginfo_to_user32() as it for the 32 bit compat case.
>>>
>>> I did. My mistake.
>>>
>>> However that mistake was so easy I think it mirrors the comments others
>>> have made that this looks like a maintenance hazard.
>>>
>>> Is improving the performance of 32bit kernels interesting?
>>
>> Yes it is, and that's what this series do.
>>
>>> Is improving the performance of 32bit compat support interesting?
>>
>> For me this is a corner case, so I left it aside for now.
>>
>>>
>>> If performance one or either of those cases is interesting it looks like
>>> we already have copy_siginfo_to_external32 the factor you would need
>>> to build unsafe_copy_siginfo_to_user32.
>>
>> I'm not sure I understand your saying here. What do you expect me to
>> do with copy_siginfo_to_external32() ?
>
> Implement unsafe_copy_siginfo_to_user32.
Ok, initialy I thought it would be a too big job but finaly that's not
so big.
>
>> copy_siginfo_to_user32() is for compat only.
>>
>> Native 32 bits powerpc use copy_siginfo_to_user()
>
> What you implemented doubles the number of test cases necessary to
> compile test the 32bit ppc signal code, and makes the code noticeably
> harder to follow.
Yes and no.
We already have a different copy_siginfo_to_user() for compat and for
native, why would anything be doubled ?
I agree it makes the code harder to follow though
>
> Having a unsafe_copy_to_siginfo_to_user32 at least would allow the
> number of test cases to remain the same as the current code.
Not sure I follow you here, but regardless I have sent a v3 which
tentatively implements copy_siginfo_to_user32() for the compat case.
>
>>> So I am not going to say impossible but please make something
>>> maintainable. I unified all of the compat 32bit siginfo logic because
>>> it simply did not get enough love and attention when it was implemented
>>> per architecture.
>>
>> Yes, and ? I didn't do any modification to the compat case, so what
>> you did remains.
>
> You undid the unification between the 32bit code and the 32bit compat
> code.
>
>>> In general I think that concern applies to this case as well. We really
>>> need an implementation that shares as much burden as possible with other
>>> architectures.
>>
>> I think yes, that's the reason why I made a generic
>> unsafe_copy_siginfo_to_user() and didn't make a powerpc dedicated
>> change.
>>
>> Once this is merged any other architecture can use
>> unsafe_copy_siginfo_to_user().
>>
>> Did I miss something ?
>
> Not dealing with the compat case and making the code signal stack frame
> code noticeably more complicated.
>
> If this optimization profitably applies to other architectures we need
> to figure out how to implement unsafe_copy_siginfo_to_user32 or risk
> making them all much worse to maintain.
>
Ok, let's see what you think about v3.
Thanks for you feedback
Christophe
^ permalink raw reply
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