* Re: [PATCH v2 3/3] powerpc/spinlocks: Fix oops in shared-processor spinlocks
From: Michael Ellerman @ 2019-08-06 12:14 UTC (permalink / raw)
To: Christopher M Riedl, linuxppc-dev; +Cc: ajd, bauerman
In-Reply-To: <850780620.61430.1564758724962@privateemail.com>
Christopher M Riedl <cmr@informatik.wtf> writes:
>> On August 2, 2019 at 6:38 AM Michael Ellerman <mpe@ellerman.id.au> wrote:
>> "Christopher M. Riedl" <cmr@informatik.wtf> writes:
>> > diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h
>> > index 0a8270183770..6aed8a83b180 100644
>> > --- a/arch/powerpc/include/asm/spinlock.h
>> > +++ b/arch/powerpc/include/asm/spinlock.h
>> > @@ -124,6 +122,22 @@ static inline bool is_shared_processor(void)
>> > #endif
>> > }
>> >
>> > +static inline void spin_yield(arch_spinlock_t *lock)
>> > +{
>> > + if (is_shared_processor())
>> > + splpar_spin_yield(lock);
>> > + else
>> > + barrier();
>> > +}
>> ...
>> > static inline void arch_spin_lock(arch_spinlock_t *lock)
>> > {
>> > while (1) {
>> > @@ -132,7 +146,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
>> > do {
>> > HMT_low();
>> > if (is_shared_processor())
>> > - __spin_yield(lock);
>> > + spin_yield(lock);
>>
>> This leaves us with a double test of is_shared_processor() doesn't it?
>
> Yep, and that's no good. Hmm, executing the barrier() in the non-shared-processor
> case probably hurts performance here?
It's only a "compiler barrier", so it shouldn't generate any code.
But it does have the effect of telling the compiler it can't optimise
across that barrier, which can be important.
In those spin loops all we're doing is checking lock->slock which is
already marked volatile in the definition of arch_spinlock_t, so the
extra barrier shouldn't really make any difference.
But still the current code doesn't have a barrier() there, so we should
make sure we don't introduce one as part of this refactor.
So I think you just want to change the call to spin_yield() above to
splpar_spin_yield(), which avoids the double check, and also avoids the
barrier() in the SPLPAR=n case.
And then arch_spin_relax() calls spin_yield() etc.
cheers
^ permalink raw reply
* Re: [PATCH v2 3/3] powerpc/spinlocks: Fix oops in shared-processor spinlocks
From: Christopher M Riedl @ 2019-08-06 12:31 UTC (permalink / raw)
To: Michael Ellerman, linuxppc-dev; +Cc: ajd, bauerman
In-Reply-To: <87r25yv6cc.fsf@concordia.ellerman.id.au>
> On August 6, 2019 at 7:14 AM Michael Ellerman <mpe@ellerman.id.au> wrote:
>
>
> Christopher M Riedl <cmr@informatik.wtf> writes:
> >> On August 2, 2019 at 6:38 AM Michael Ellerman <mpe@ellerman.id.au> wrote:
> >> "Christopher M. Riedl" <cmr@informatik.wtf> writes:
> >>
> >> This leaves us with a double test of is_shared_processor() doesn't it?
> >
> > Yep, and that's no good. Hmm, executing the barrier() in the non-shared-processor
> > case probably hurts performance here?
>
> It's only a "compiler barrier", so it shouldn't generate any code.
>
> But it does have the effect of telling the compiler it can't optimise
> across that barrier, which can be important.
>
> In those spin loops all we're doing is checking lock->slock which is
> already marked volatile in the definition of arch_spinlock_t, so the
> extra barrier shouldn't really make any difference.
>
> But still the current code doesn't have a barrier() there, so we should
> make sure we don't introduce one as part of this refactor.
Thank you for taking the time to explain this. I have some more reading to
do about compiler-barriers it seems :)
>
> So I think you just want to change the call to spin_yield() above to
> splpar_spin_yield(), which avoids the double check, and also avoids the
> barrier() in the SPLPAR=n case.
>
> And then arch_spin_relax() calls spin_yield() etc.
I submitted a v3 before your reply with this change already - figured this
is the best way to avoid the double check and maintain legacy behavior.
>
> cheers
^ permalink raw reply
* Re: [PATCH net-next] ibmveth: Allow users to update reported speed and duplex
From: Thomas Falcon @ 2019-08-06 14:41 UTC (permalink / raw)
To: Michael Ellerman, netdev; +Cc: linuxppc-dev
In-Reply-To: <87zhkmvbec.fsf@concordia.ellerman.id.au>
On 8/6/19 5:25 AM, Michael Ellerman wrote:
> Thomas Falcon <tlfalcon@linux.ibm.com> writes:
>> Reported ethtool link settings for the ibmveth driver are currently
>> hardcoded and no longer reflect the actual capabilities of supported
>> hardware. There is no interface designed for retrieving this information
>> from device firmware nor is there any way to update current settings
>> to reflect observed or expected link speeds.
>>
>> To avoid confusion, initially define speed and duplex as unknown and
> Doesn't that risk break existing setups?
You're right, sorry for missing that.
>
>> allow the user to alter these settings to match the expected
>> capabilities of underlying hardware if needed. This update would allow
>> the use of configurations that rely on certain link speed settings,
>> such as LACP. This patch is based on the implementation in virtio_net.
> Wouldn't it be safer to keep the current values as the default, and then
> also allow them to be overridden by a motivated user.
That is a good compromise. I will resend an updated version soon with
that change.
Thanks!
>
> cheers
>
^ permalink raw reply
* [PATCH v2 0/3] arm/arm64: Add support for function error injection
From: Leo Yan @ 2019-08-06 10:00 UTC (permalink / raw)
To: Russell King, Oleg Nesterov, Catalin Marinas, Will Deacon,
Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
x86, Arnd Bergmann, Alexei Starovoitov, Daniel Borkmann,
Martin KaFai Lau, Song Liu, Yonghong Song, Naveen N. Rao,
linux-arm-kernel, linux-kernel, linuxppc-dev, linux-arch, netdev,
bpf, clang-built-linux, Masami Hiramatsu
Cc: Leo Yan
This small patch set is to add support for function error injection;
this can be used to eanble more advanced debugging feature, e.g.
CONFIG_BPF_KPROBE_OVERRIDE.
The patch 01/03 is to consolidate the function definition which can be
suared cross architectures, patches 02,03/03 are used for enabling
function error injection on arm64 and arm architecture respectively.
I tested on arm64 platform Juno-r2 and one of my laptop with x86
architecture with below steps; I don't test for Arm architecture so
only pass compilation.
- Enable kernel configuration:
CONFIG_BPF_KPROBE_OVERRIDE
CONFIG_BTRFS_FS
CONFIG_BPF_EVENTS=y
CONFIG_KPROBES=y
CONFIG_KPROBE_EVENTS=y
CONFIG_BPF_KPROBE_OVERRIDE=y
- Build samples/bpf on with Debian rootFS:
# cd $kernel
# make headers_install
# make samples/bpf/ LLC=llc-7 CLANG=clang-7
- Run the sample tracex7:
# dd if=/dev/zero of=testfile.img bs=1M seek=1000 count=1
# DEVICE=$(losetup --show -f testfile.img)
# mkfs.btrfs -f $DEVICE
# ./tracex7 testfile.img
[ 1975.211781] BTRFS error (device (efault)): open_ctree failed
mount: /mnt/linux-kernel/linux-cs-dev/samples/bpf/tmpmnt: mount(2) system call failed: Cannot allocate memory.
Changes from v1:
* Consolidated the function definition into asm-generic header (Will);
* Used APIs to access pt_regs elements (Will);
* Fixed typos in the comments (Will).
Leo Yan (3):
error-injection: Consolidate override function definition
arm64: Add support for function error injection
arm: Add support for function error injection
arch/arm/Kconfig | 1 +
arch/arm/include/asm/ptrace.h | 5 +++++
arch/arm/lib/Makefile | 2 ++
arch/arm/lib/error-inject.c | 19 +++++++++++++++++++
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/ptrace.h | 5 +++++
arch/arm64/lib/Makefile | 2 ++
arch/arm64/lib/error-inject.c | 18 ++++++++++++++++++
arch/powerpc/include/asm/error-injection.h | 13 -------------
arch/x86/include/asm/error-injection.h | 13 -------------
include/asm-generic/error-injection.h | 6 ++++++
include/linux/error-injection.h | 6 +++---
12 files changed, 62 insertions(+), 29 deletions(-)
create mode 100644 arch/arm/lib/error-inject.c
create mode 100644 arch/arm64/lib/error-inject.c
delete mode 100644 arch/powerpc/include/asm/error-injection.h
delete mode 100644 arch/x86/include/asm/error-injection.h
--
2.17.1
^ permalink raw reply
* [PATCH v2 1/3] error-injection: Consolidate override function definition
From: Leo Yan @ 2019-08-06 10:00 UTC (permalink / raw)
To: Russell King, Oleg Nesterov, Catalin Marinas, Will Deacon,
Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
x86, Arnd Bergmann, Alexei Starovoitov, Daniel Borkmann,
Martin KaFai Lau, Song Liu, Yonghong Song, Naveen N. Rao,
linux-arm-kernel, linux-kernel, linuxppc-dev, linux-arch, netdev,
bpf, clang-built-linux, Masami Hiramatsu
Cc: Leo Yan
In-Reply-To: <20190806100015.11256-1-leo.yan@linaro.org>
The function override_function_with_return() is defined separately for
each architecture and every architecture's definition is almost same
with each other. E.g. x86 and powerpc both define function in its own
asm/error-injection.h header and override_function_with_return() has
the same definition, the only difference is that x86 defines an extra
function just_return_func() but it is specific for x86 and is only used
by x86's override_function_with_return(), so don't need to export this
function.
This patch consolidates override_function_with_return() definition into
asm-generic/error-injection.h header, thus all architectures can use the
common definition. As result, the architecture specific headers are
removed; the include/linux/error-injection.h header also changes to
include asm-generic/error-injection.h header rather than architecture
header, furthermore, it includes linux/compiler.h for successful
compilation.
Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
arch/powerpc/include/asm/error-injection.h | 13 -------------
arch/x86/include/asm/error-injection.h | 13 -------------
include/asm-generic/error-injection.h | 6 ++++++
include/linux/error-injection.h | 6 +++---
4 files changed, 9 insertions(+), 29 deletions(-)
delete mode 100644 arch/powerpc/include/asm/error-injection.h
delete mode 100644 arch/x86/include/asm/error-injection.h
diff --git a/arch/powerpc/include/asm/error-injection.h b/arch/powerpc/include/asm/error-injection.h
deleted file mode 100644
index 62fd24739852..000000000000
--- a/arch/powerpc/include/asm/error-injection.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-
-#ifndef _ASM_ERROR_INJECTION_H
-#define _ASM_ERROR_INJECTION_H
-
-#include <linux/compiler.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-#include <asm-generic/error-injection.h>
-
-void override_function_with_return(struct pt_regs *regs);
-
-#endif /* _ASM_ERROR_INJECTION_H */
diff --git a/arch/x86/include/asm/error-injection.h b/arch/x86/include/asm/error-injection.h
deleted file mode 100644
index 47b7a1296245..000000000000
--- a/arch/x86/include/asm/error-injection.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_ERROR_INJECTION_H
-#define _ASM_ERROR_INJECTION_H
-
-#include <linux/compiler.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-#include <asm-generic/error-injection.h>
-
-asmlinkage void just_return_func(void);
-void override_function_with_return(struct pt_regs *regs);
-
-#endif /* _ASM_ERROR_INJECTION_H */
diff --git a/include/asm-generic/error-injection.h b/include/asm-generic/error-injection.h
index 95a159a4137f..80ca61058dd2 100644
--- a/include/asm-generic/error-injection.h
+++ b/include/asm-generic/error-injection.h
@@ -16,6 +16,8 @@ struct error_injection_entry {
int etype;
};
+struct pt_regs;
+
#ifdef CONFIG_FUNCTION_ERROR_INJECTION
/*
* Whitelist ganerating macro. Specify functions which can be
@@ -28,8 +30,12 @@ static struct error_injection_entry __used \
.addr = (unsigned long)fname, \
.etype = EI_ETYPE_##_etype, \
};
+
+void override_function_with_return(struct pt_regs *regs);
#else
#define ALLOW_ERROR_INJECTION(fname, _etype)
+
+static inline void override_function_with_return(struct pt_regs *regs) { }
#endif
#endif
diff --git a/include/linux/error-injection.h b/include/linux/error-injection.h
index 280c61ecbf20..635a95caf29f 100644
--- a/include/linux/error-injection.h
+++ b/include/linux/error-injection.h
@@ -2,16 +2,16 @@
#ifndef _LINUX_ERROR_INJECTION_H
#define _LINUX_ERROR_INJECTION_H
-#ifdef CONFIG_FUNCTION_ERROR_INJECTION
+#include <linux/compiler.h>
+#include <asm-generic/error-injection.h>
-#include <asm/error-injection.h>
+#ifdef CONFIG_FUNCTION_ERROR_INJECTION
extern bool within_error_injection_list(unsigned long addr);
extern int get_injectable_error_type(unsigned long addr);
#else /* !CONFIG_FUNCTION_ERROR_INJECTION */
-#include <asm-generic/error-injection.h>
static inline bool within_error_injection_list(unsigned long addr)
{
return false;
--
2.17.1
^ permalink raw reply related
* [PATCH v2 2/3] arm64: Add support for function error injection
From: Leo Yan @ 2019-08-06 10:00 UTC (permalink / raw)
To: Russell King, Oleg Nesterov, Catalin Marinas, Will Deacon,
Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
x86, Arnd Bergmann, Alexei Starovoitov, Daniel Borkmann,
Martin KaFai Lau, Song Liu, Yonghong Song, Naveen N. Rao,
linux-arm-kernel, linux-kernel, linuxppc-dev, linux-arch, netdev,
bpf, clang-built-linux, Masami Hiramatsu
Cc: Leo Yan
In-Reply-To: <20190806100015.11256-1-leo.yan@linaro.org>
Inspired by the commit 7cd01b08d35f ("powerpc: Add support for function
error injection"), this patch supports function error injection for
Arm64.
This patch mainly support two functions: one is regs_set_return_value()
which is used to overwrite the return value; the another function is
override_function_with_return() which is to override the probed
function returning and jump to its caller.
Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/ptrace.h | 5 +++++
arch/arm64/lib/Makefile | 2 ++
arch/arm64/lib/error-inject.c | 18 ++++++++++++++++++
4 files changed, 26 insertions(+)
create mode 100644 arch/arm64/lib/error-inject.c
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3adcec05b1f6..b15803afb2a0 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -148,6 +148,7 @@ config ARM64
select HAVE_FAST_GUP
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_TRACER
+ select HAVE_FUNCTION_ERROR_INJECTION
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_GCC_PLUGINS
select HAVE_HW_BREAKPOINT if PERF_EVENTS
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index b1dd039023ef..891b9995cb4b 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -301,6 +301,11 @@ static inline unsigned long regs_return_value(struct pt_regs *regs)
return regs->regs[0];
}
+static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
+{
+ regs->regs[0] = rc;
+}
+
/**
* regs_get_kernel_argument() - get Nth function argument in kernel
* @regs: pt_regs of that context
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 33c2a4abda04..f182ccb0438e 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -33,3 +33,5 @@ UBSAN_SANITIZE_atomic_ll_sc.o := n
lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
obj-$(CONFIG_CRC32) += crc32.o
+
+obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
diff --git a/arch/arm64/lib/error-inject.c b/arch/arm64/lib/error-inject.c
new file mode 100644
index 000000000000..ed15021da3ed
--- /dev/null
+++ b/arch/arm64/lib/error-inject.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/error-injection.h>
+#include <linux/kprobes.h>
+
+void override_function_with_return(struct pt_regs *regs)
+{
+ /*
+ * 'regs' represents the state on entry of a predefined function in
+ * the kernel/module and which is captured on a kprobe.
+ *
+ * When kprobe returns back from exception it will override the end
+ * of probed function and directly return to the predefined
+ * function's caller.
+ */
+ instruction_pointer_set(regs, procedure_link_pointer(regs));
+}
+NOKPROBE_SYMBOL(override_function_with_return);
--
2.17.1
^ permalink raw reply related
* [PATCH v2 3/3] arm: Add support for function error injection
From: Leo Yan @ 2019-08-06 10:00 UTC (permalink / raw)
To: Russell King, Oleg Nesterov, Catalin Marinas, Will Deacon,
Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
x86, Arnd Bergmann, Alexei Starovoitov, Daniel Borkmann,
Martin KaFai Lau, Song Liu, Yonghong Song, Naveen N. Rao,
linux-arm-kernel, linux-kernel, linuxppc-dev, linux-arch, netdev,
bpf, clang-built-linux, Masami Hiramatsu
Cc: Leo Yan
In-Reply-To: <20190806100015.11256-1-leo.yan@linaro.org>
This patch implements arm specific functions regs_set_return_value() and
override_function_with_return() to support function error injection.
In the exception flow, it updates pt_regs::ARM_pc with pt_regs::ARM_lr
so can override the probed function return.
Signed-off-by: Leo Yan <leo.yan@linaro.org>
---
arch/arm/Kconfig | 1 +
arch/arm/include/asm/ptrace.h | 5 +++++
arch/arm/lib/Makefile | 2 ++
arch/arm/lib/error-inject.c | 19 +++++++++++++++++++
4 files changed, 27 insertions(+)
create mode 100644 arch/arm/lib/error-inject.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 33b00579beff..2d3d44a037f6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -77,6 +77,7 @@ config ARM
select HAVE_EXIT_THREAD
select HAVE_FAST_GUP if ARM_LPAE
select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
+ select HAVE_FUNCTION_ERROR_INJECTION if !THUMB2_KERNEL
select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG
select HAVE_FUNCTION_TRACER if !XIP_KERNEL
select HAVE_GCC_PLUGINS
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 91d6b7856be4..3b41f37b361a 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -89,6 +89,11 @@ static inline long regs_return_value(struct pt_regs *regs)
return regs->ARM_r0;
}
+static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
+{
+ regs->ARM_r0 = rc;
+}
+
#define instruction_pointer(regs) (regs)->ARM_pc
#ifdef CONFIG_THUMB2_KERNEL
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index b25c54585048..8f56484a7156 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -42,3 +42,5 @@ ifeq ($(CONFIG_KERNEL_MODE_NEON),y)
CFLAGS_xor-neon.o += $(NEON_FLAGS)
obj-$(CONFIG_XOR_BLOCKS) += xor-neon.o
endif
+
+obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
diff --git a/arch/arm/lib/error-inject.c b/arch/arm/lib/error-inject.c
new file mode 100644
index 000000000000..2d696dc94893
--- /dev/null
+++ b/arch/arm/lib/error-inject.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/error-injection.h>
+#include <linux/kprobes.h>
+
+void override_function_with_return(struct pt_regs *regs)
+{
+ /*
+ * 'regs' represents the state on entry of a predefined function in
+ * the kernel/module and which is captured on a kprobe.
+ *
+ * 'regs->ARM_lr' contains the the link register for the probed
+ * function, when kprobe returns back from exception it will override
+ * the end of probed function and directly return to the predefined
+ * function's caller.
+ */
+ instruction_pointer_set(regs, regs->ARM_lr);
+}
+NOKPROBE_SYMBOL(override_function_with_return);
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v2 3/3] powerpc/spinlocks: Fix oops in shared-processor spinlocks
From: Segher Boessenkool @ 2019-08-06 15:57 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Christopher M Riedl, ajd, bauerman
In-Reply-To: <87r25yv6cc.fsf@concordia.ellerman.id.au>
On Tue, Aug 06, 2019 at 10:14:27PM +1000, Michael Ellerman wrote:
> Christopher M Riedl <cmr@informatik.wtf> writes:
> > Yep, and that's no good. Hmm, executing the barrier() in the non-shared-processor
> > case probably hurts performance here?
>
> It's only a "compiler barrier", so it shouldn't generate any code.
>
> But it does have the effect of telling the compiler it can't optimise
> across that barrier, which can be important.
This is
#define barrier() __asm__ __volatile__("": : :"memory")
It doesn't tell the compiler "not to optimise" across the barrier. It
tells the compiler that all memory accesses before the barrier should
stay before it, and all accesses after the barrier should stay after it,
because it says the "barrier" can access and/or change any memory.
This does not tell the hardware not to move those accesses around. It
also doesn't say anything about things that are not in memory. Not
everything you think is in memory, is. What is and isn't in memory can
change during compilation.
[ This message brought to you by the "Stamp Out Optimisation Barrier"
campaign. ]
Segher
^ permalink raw reply
* Re: [PATCH] dma-mapping: fix page attributes for dma_mmap_*
From: Will Deacon @ 2019-08-06 16:08 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Shawn Anastasio, linuxppc-dev, Russell King, linux-kernel, iommu,
Catalin Marinas, Robin Murphy, linux-arm-kernel
In-Reply-To: <20190803064812.GA29746@lst.de>
On Sat, Aug 03, 2019 at 08:48:12AM +0200, Christoph Hellwig wrote:
> On Fri, Aug 02, 2019 at 11:38:03AM +0100, Will Deacon wrote:
> >
> > So this boils down to a terminology mismatch. The Arm architecture doesn't have
> > anything called "write combine", so in Linux we instead provide what the Arm
> > architecture calls "Normal non-cacheable" memory for pgprot_writecombine().
> > Amongst other things, this memory type permits speculation, unaligned accesses
> > and merging of writes. I found something in the architecture spec about
> > non-cachable memory, but it's written in Armglish[1].
> >
> > pgprot_noncached(), on the other hand, provides what the architecture calls
> > Strongly Ordered or Device-nGnRnE memory. This is intended for mapping MMIO
> > (i.e. PCI config space) and therefore forbids speculation, preserves access
> > size, requires strict alignment and also forces write responses to come from
> > the endpoint.
> >
> > I think the naming mismatch is historical, but on arm64 we wanted to use the
> > same names as arm32 so that any drivers using these things directly would get
> > the same behaviour.
>
> That all makes sense, but it totally needs a comment. I'll try to draft
> one based on this. I've also looked at the arm32 code a bit more, and
> it seems arm always (?) supported Normal non-cacheable attribute, but
> Linux only optionally uses it for arm v6+ because of fears of drivers
> missing barriers.
I think it was also to do with aliasing, but I don't recall all of the
details.
> The other really weird things is that in arm32
> pgprot_dmacoherent incudes the L_PTE_XN bit, which from my understanding
> is the no-execture bit, but pgprot_writecombine does not. This seems to
> not very unintentional. So minus that the whole DMA_ATTR_WRITE_COMBІNE
> seems to be about flagging old arm specific drivers as having the proper
> barriers in places and otherwise is a no-op.
I think it only matters for Armv7 CPUs, but yes, we should probably be
setting L_PTE_XN for both of these memory types.
> Here is my tentative plan:
>
> - respin this patch with a small fix to handle the
> DMA_ATTR_NON_CONSISTENT (as in ignore it unless actually supported),
> but keep the name as-is to avoid churn. This should allow 5.3
> inclusion and backports
> - remove DMA_ATTR_WRITE_COMBINE support from mips, probably also 5.3
> material.
> - move all architectures but arm over to just define
> pgprot_dmacoherent, including a comment with the above explanation
> for arm64.
That would be great, thanks.
> - make DMA_ATTR_WRITE_COMBINE a no-op and schedule it for removal,
> thus removing the last instances of arch_dma_mmap_pgprot
All sounds good to me, although I suppose 32-bit Arm platforms without
CONFIG_ARM_DMA_MEM_BUFFERABLE may run into issues if DMA_ATTR_WRITE_COMBINE
disappears. Only one way to find out...
Will
^ permalink raw reply
* [PATCH net-next v2] ibmveth: Allow users to update reported speed and duplex
From: Thomas Falcon @ 2019-08-06 16:23 UTC (permalink / raw)
To: mpe; +Cc: netdev, Thomas Falcon, linuxppc-dev
Reported ethtool link settings for the ibmveth driver are currently
hardcoded and no longer reflect the actual capabilities of supported
hardware. There is no interface designed for retrieving this information
from device firmware nor is there any way to update current settings
to reflect observed or expected link speeds.
To avoid breaking existing configurations, retain current values as
default settings but let users update them to match the expected
capabilities of underlying hardware if needed. This update would
allow the use of configurations that rely on certain link speed
settings, such as LACP. This patch is based on the implementation
in virtio_net.
Signed-off-by: Thomas Falcon <tlfalcon@linux.ibm.com>
---
v2: Updated default driver speed/duplex settings to avoid
breaking existing setups
---
drivers/net/ethernet/ibm/ibmveth.c | 83 ++++++++++++++++++++++++++++----------
drivers/net/ethernet/ibm/ibmveth.h | 3 ++
2 files changed, 64 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index d654c23..5dc634f 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -712,31 +712,68 @@ static int ibmveth_close(struct net_device *netdev)
return 0;
}
-static int netdev_get_link_ksettings(struct net_device *dev,
- struct ethtool_link_ksettings *cmd)
+static bool
+ibmveth_validate_ethtool_cmd(const struct ethtool_link_ksettings *cmd)
{
- u32 supported, advertising;
-
- supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
- SUPPORTED_FIBRE);
- advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg |
- ADVERTISED_FIBRE);
- cmd->base.speed = SPEED_1000;
- cmd->base.duplex = DUPLEX_FULL;
- cmd->base.port = PORT_FIBRE;
- cmd->base.phy_address = 0;
- cmd->base.autoneg = AUTONEG_ENABLE;
-
- ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
- supported);
- ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
- advertising);
+ struct ethtool_link_ksettings diff1 = *cmd;
+ struct ethtool_link_ksettings diff2 = {};
+
+ diff2.base.port = PORT_OTHER;
+ diff1.base.speed = 0;
+ diff1.base.duplex = 0;
+ diff1.base.cmd = 0;
+ diff1.base.link_mode_masks_nwords = 0;
+ ethtool_link_ksettings_zero_link_mode(&diff1, advertising);
+
+ return !memcmp(&diff1.base, &diff2.base, sizeof(diff1.base)) &&
+ bitmap_empty(diff1.link_modes.supported,
+ __ETHTOOL_LINK_MODE_MASK_NBITS) &&
+ bitmap_empty(diff1.link_modes.advertising,
+ __ETHTOOL_LINK_MODE_MASK_NBITS) &&
+ bitmap_empty(diff1.link_modes.lp_advertising,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+static int ibmveth_set_link_ksettings(struct net_device *dev,
+ const struct ethtool_link_ksettings *cmd)
+{
+ struct ibmveth_adapter *adapter = netdev_priv(dev);
+ u32 speed;
+ u8 duplex;
+
+ speed = cmd->base.speed;
+ duplex = cmd->base.duplex;
+ /* don't allow custom speed and duplex */
+ if (!ethtool_validate_speed(speed) ||
+ !ethtool_validate_duplex(duplex) ||
+ !ibmveth_validate_ethtool_cmd(cmd))
+ return -EINVAL;
+ adapter->speed = speed;
+ adapter->duplex = duplex;
return 0;
}
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
+static int ibmveth_get_link_ksettings(struct net_device *dev,
+ struct ethtool_link_ksettings *cmd)
+{
+ struct ibmveth_adapter *adapter = netdev_priv(dev);
+
+ cmd->base.speed = adapter->speed;
+ cmd->base.duplex = adapter->duplex;
+ cmd->base.port = PORT_OTHER;
+
+ return 0;
+}
+
+static void ibmveth_init_link_settings(struct ibmveth_adapter *adapter)
+{
+ adapter->duplex = DUPLEX_FULL;
+ adapter->speed = SPEED_1000;
+}
+
+static void ibmveth_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
{
strlcpy(info->driver, ibmveth_driver_name, sizeof(info->driver));
strlcpy(info->version, ibmveth_driver_version, sizeof(info->version));
@@ -965,12 +1002,13 @@ static void ibmveth_get_ethtool_stats(struct net_device *dev,
}
static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
+ .get_drvinfo = ibmveth_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_strings = ibmveth_get_strings,
.get_sset_count = ibmveth_get_sset_count,
.get_ethtool_stats = ibmveth_get_ethtool_stats,
- .get_link_ksettings = netdev_get_link_ksettings,
+ .get_link_ksettings = ibmveth_get_link_ksettings,
+ .set_link_ksettings = ibmveth_set_link_ksettings
};
static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1647,6 +1685,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
adapter->netdev = netdev;
adapter->mcastFilterSize = *mcastFilterSize_p;
adapter->pool_config = 0;
+ ibmveth_init_link_settings(adapter);
netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16);
diff --git a/drivers/net/ethernet/ibm/ibmveth.h b/drivers/net/ethernet/ibm/ibmveth.h
index 4e9bf34..db96c88 100644
--- a/drivers/net/ethernet/ibm/ibmveth.h
+++ b/drivers/net/ethernet/ibm/ibmveth.h
@@ -162,6 +162,9 @@ struct ibmveth_adapter {
u64 tx_send_failed;
u64 tx_large_packets;
u64 rx_large_packets;
+ /* Ethtool settings */
+ u8 duplex;
+ u32 speed;
};
/*
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH v2 3/5] x86: Kconfig: Remove CONFIG_NODES_SPAN_OTHER_NODES
From: Hoan Tran OS @ 2019-08-06 16:47 UTC (permalink / raw)
To: Thomas Gleixner, Catalin Marinas, Will Deacon
Cc: Michal Hocko, Heiko Carstens, open list:MEMORY MANAGEMENT,
Paul Mackerras, H . Peter Anvin, sparclinux@vger.kernel.org,
Alexander Duyck, linux-s390@vger.kernel.org, x86@kernel.org,
Mike Rapoport, Christian Borntraeger, Ingo Molnar,
Vlastimil Babka, Open Source Submission, Pavel Tatashin,
Vasily Gorbik, Borislav Petkov,
linux-arm-kernel@lists.infradead.org, Oscar Salvador,
linux-kernel@vger.kernel.org, Andrew Morton,
linuxppc-dev@lists.ozlabs.org, David S . Miller
In-Reply-To: <alpine.DEB.2.21.1907152042110.1767@nanos.tec.linutronix.de>
Hi Thomas,
On 7/15/19 11:43 AM, Thomas Gleixner wrote:
> On Thu, 11 Jul 2019, Hoan Tran OS wrote:
>
>> Remove CONFIG_NODES_SPAN_OTHER_NODES as it's enabled
>> by default with NUMA.
>
> As I told you before this does not mention that the option is now enabled
> even for x86(32bit) configurations which did not enable it before and does
> not longer depend on X86_64_ACPI_NUMA.
Agreed, let me add it into this patch description.
>
> And there is still no rationale why this makes sense.
>
As we know about the memmap_init_zone() function, it is used to
initialize all pages. During initializing, early_pfn_in_nid() function
makes sure the page is in the same node id. Otherwise,
memmap_init_zone() only checks the page validity. It won't work with
node memory spans across the others.
The option CONFIG_NODES_SPAN_OTHER_NODES is only used to enable
early_pfn_in_nid() function.
It occurs during boot-time and won't affect the run-time performance.
And I saw the majority NUMA architectures enable this option by default
with NUMA.
Thanks and Regards
Hoan
> Thanks,
>
> tglx
>
^ permalink raw reply
* Re: [PATCH] dma-mapping: fix page attributes for dma_mmap_*
From: Russell King - ARM Linux admin @ 2019-08-06 16:48 UTC (permalink / raw)
To: Will Deacon
Cc: Shawn Anastasio, linux-kernel, iommu, Catalin Marinas,
linuxppc-dev, Christoph Hellwig, linux-arm-kernel, Robin Murphy
In-Reply-To: <20190806164503.GD1330@shell.armlinux.org.uk>
On Tue, Aug 06, 2019 at 05:45:03PM +0100, Russell King - ARM Linux admin wrote:
> On Tue, Aug 06, 2019 at 05:08:54PM +0100, Will Deacon wrote:
> > On Sat, Aug 03, 2019 at 08:48:12AM +0200, Christoph Hellwig wrote:
> > > On Fri, Aug 02, 2019 at 11:38:03AM +0100, Will Deacon wrote:
> > > >
> > > > So this boils down to a terminology mismatch. The Arm architecture doesn't have
> > > > anything called "write combine", so in Linux we instead provide what the Arm
> > > > architecture calls "Normal non-cacheable" memory for pgprot_writecombine().
> > > > Amongst other things, this memory type permits speculation, unaligned accesses
> > > > and merging of writes. I found something in the architecture spec about
> > > > non-cachable memory, but it's written in Armglish[1].
> > > >
> > > > pgprot_noncached(), on the other hand, provides what the architecture calls
> > > > Strongly Ordered or Device-nGnRnE memory. This is intended for mapping MMIO
> > > > (i.e. PCI config space) and therefore forbids speculation, preserves access
> > > > size, requires strict alignment and also forces write responses to come from
> > > > the endpoint.
> > > >
> > > > I think the naming mismatch is historical, but on arm64 we wanted to use the
> > > > same names as arm32 so that any drivers using these things directly would get
> > > > the same behaviour.
> > >
> > > That all makes sense, but it totally needs a comment. I'll try to draft
> > > one based on this. I've also looked at the arm32 code a bit more, and
> > > it seems arm always (?) supported Normal non-cacheable attribute, but
> > > Linux only optionally uses it for arm v6+ because of fears of drivers
> > > missing barriers.
> >
> > I think it was also to do with aliasing, but I don't recall all of the
> > details.
>
> ARMv6+ is where the architecture significantly changed to introduce
> the idea of [Normal, Device, Strongly Ordered] where Normal has the
> cache attributes.
>
> Before that, we had just "uncached/unbuffered, uncached/buffered,
> cached/unbuffered, cached/buffered" modes.
>
> The write buffer (enabled by buffered modes) has no architected
> guarantees about how long writes will sit in it, and there is only
> the "drain write buffer" instruction to push writes out.
>
> Up to and including ARMv5, we took the easy approach of just using
> the "uncached/unbuffered" mode since that is (a) the safest, and (b)
> avoids write buffers that alias when there are multiple different
> mappings.
>
> We could have used a different approach, making all IO writes contain
> a "drain write buffer" instruction, and map DMA memory as "buffered",
> but as there were no Linux barriers defined to order memory accesses
> to DMA memory (so, for example, ring buffers can be updated in the
> correct order) back in those days, using the uncached/unbuffered mode
> was the sanest and most reliable solution.
>
> >
> > > The other really weird things is that in arm32
> > > pgprot_dmacoherent incudes the L_PTE_XN bit, which from my understanding
> > > is the no-execture bit, but pgprot_writecombine does not. This seems to
> > > not very unintentional. So minus that the whole DMA_ATTR_WRITE_COMBІNE
> > > seems to be about flagging old arm specific drivers as having the proper
> > > barriers in places and otherwise is a no-op.
> >
> > I think it only matters for Armv7 CPUs, but yes, we should probably be
> > setting L_PTE_XN for both of these memory types.
>
> Conventionally, pgprot_writecombine() has only been used to change
> the memory type and not the permissions. Since writecombine memory
> is still capable of being executed, I don't see any reason to set XN
> for it.
>
> If the user wishes to mmap() using PROT_READ|PROT_EXEC, then is there
> really a reason for writecombine to set XN overriding the user?
>
> That said, pgprot_writecombine() is mostly used for framebuffers, which
> arguably shouldn't be executable anyway - but who'd want to mmap() the
> framebuffer with PROT_EXEC?
>
> >
> > > Here is my tentative plan:
> > >
> > > - respin this patch with a small fix to handle the
> > > DMA_ATTR_NON_CONSISTENT (as in ignore it unless actually supported),
> > > but keep the name as-is to avoid churn. This should allow 5.3
> > > inclusion and backports
> > > - remove DMA_ATTR_WRITE_COMBINE support from mips, probably also 5.3
> > > material.
> > > - move all architectures but arm over to just define
> > > pgprot_dmacoherent, including a comment with the above explanation
> > > for arm64.
> >
> > That would be great, thanks.
> >
> > > - make DMA_ATTR_WRITE_COMBINE a no-op and schedule it for removal,
> > > thus removing the last instances of arch_dma_mmap_pgprot
> >
> > All sounds good to me, although I suppose 32-bit Arm platforms without
> > CONFIG_ARM_DMA_MEM_BUFFERABLE may run into issues if DMA_ATTR_WRITE_COMBINE
> > disappears. Only one way to find out...
>
> Looking at the results of grep, I think only OMAP2+ and Exynos may be
> affected.
>
> However, removing writecombine support from the DMA API is going to
> have a huge impact for framebuffers on earlier ARMs - that's where we
> do expect framebuffers to be mapped "uncached/buffered" for performance
> reasons and not "uncached/unbuffered". It's quite literally the
> difference between console scrolling being usable and totally unusable.
>
> Given what I've said above, switching to using buffered mode for normal
> DMA mappings is data-corrupting risky - as in your filesystem could get
> fried. I don't think we should play fast and loose with people's data
> by randomly changing that "because we'd like to", and I don't see that
> screwing the console is really an option either.
Sorry, I forgot to explain - the reason is dma_alloc_writecombine()
internally uses DMA_ATTR_WRITE_COMBINE, which I'd forgotten about
when grepping - so there's potentially way more users than my greps
above found.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
^ permalink raw reply
* Re: [PATCH] dma-mapping: fix page attributes for dma_mmap_*
From: Russell King - ARM Linux admin @ 2019-08-06 16:45 UTC (permalink / raw)
To: Will Deacon
Cc: Shawn Anastasio, linuxppc-dev, linux-kernel, iommu,
Catalin Marinas, Robin Murphy, Christoph Hellwig,
linux-arm-kernel
In-Reply-To: <20190806160854.htk67msiyadlrl4m@willie-the-truck>
On Tue, Aug 06, 2019 at 05:08:54PM +0100, Will Deacon wrote:
> On Sat, Aug 03, 2019 at 08:48:12AM +0200, Christoph Hellwig wrote:
> > On Fri, Aug 02, 2019 at 11:38:03AM +0100, Will Deacon wrote:
> > >
> > > So this boils down to a terminology mismatch. The Arm architecture doesn't have
> > > anything called "write combine", so in Linux we instead provide what the Arm
> > > architecture calls "Normal non-cacheable" memory for pgprot_writecombine().
> > > Amongst other things, this memory type permits speculation, unaligned accesses
> > > and merging of writes. I found something in the architecture spec about
> > > non-cachable memory, but it's written in Armglish[1].
> > >
> > > pgprot_noncached(), on the other hand, provides what the architecture calls
> > > Strongly Ordered or Device-nGnRnE memory. This is intended for mapping MMIO
> > > (i.e. PCI config space) and therefore forbids speculation, preserves access
> > > size, requires strict alignment and also forces write responses to come from
> > > the endpoint.
> > >
> > > I think the naming mismatch is historical, but on arm64 we wanted to use the
> > > same names as arm32 so that any drivers using these things directly would get
> > > the same behaviour.
> >
> > That all makes sense, but it totally needs a comment. I'll try to draft
> > one based on this. I've also looked at the arm32 code a bit more, and
> > it seems arm always (?) supported Normal non-cacheable attribute, but
> > Linux only optionally uses it for arm v6+ because of fears of drivers
> > missing barriers.
>
> I think it was also to do with aliasing, but I don't recall all of the
> details.
ARMv6+ is where the architecture significantly changed to introduce
the idea of [Normal, Device, Strongly Ordered] where Normal has the
cache attributes.
Before that, we had just "uncached/unbuffered, uncached/buffered,
cached/unbuffered, cached/buffered" modes.
The write buffer (enabled by buffered modes) has no architected
guarantees about how long writes will sit in it, and there is only
the "drain write buffer" instruction to push writes out.
Up to and including ARMv5, we took the easy approach of just using
the "uncached/unbuffered" mode since that is (a) the safest, and (b)
avoids write buffers that alias when there are multiple different
mappings.
We could have used a different approach, making all IO writes contain
a "drain write buffer" instruction, and map DMA memory as "buffered",
but as there were no Linux barriers defined to order memory accesses
to DMA memory (so, for example, ring buffers can be updated in the
correct order) back in those days, using the uncached/unbuffered mode
was the sanest and most reliable solution.
>
> > The other really weird things is that in arm32
> > pgprot_dmacoherent incudes the L_PTE_XN bit, which from my understanding
> > is the no-execture bit, but pgprot_writecombine does not. This seems to
> > not very unintentional. So minus that the whole DMA_ATTR_WRITE_COMBІNE
> > seems to be about flagging old arm specific drivers as having the proper
> > barriers in places and otherwise is a no-op.
>
> I think it only matters for Armv7 CPUs, but yes, we should probably be
> setting L_PTE_XN for both of these memory types.
Conventionally, pgprot_writecombine() has only been used to change
the memory type and not the permissions. Since writecombine memory
is still capable of being executed, I don't see any reason to set XN
for it.
If the user wishes to mmap() using PROT_READ|PROT_EXEC, then is there
really a reason for writecombine to set XN overriding the user?
That said, pgprot_writecombine() is mostly used for framebuffers, which
arguably shouldn't be executable anyway - but who'd want to mmap() the
framebuffer with PROT_EXEC?
>
> > Here is my tentative plan:
> >
> > - respin this patch with a small fix to handle the
> > DMA_ATTR_NON_CONSISTENT (as in ignore it unless actually supported),
> > but keep the name as-is to avoid churn. This should allow 5.3
> > inclusion and backports
> > - remove DMA_ATTR_WRITE_COMBINE support from mips, probably also 5.3
> > material.
> > - move all architectures but arm over to just define
> > pgprot_dmacoherent, including a comment with the above explanation
> > for arm64.
>
> That would be great, thanks.
>
> > - make DMA_ATTR_WRITE_COMBINE a no-op and schedule it for removal,
> > thus removing the last instances of arch_dma_mmap_pgprot
>
> All sounds good to me, although I suppose 32-bit Arm platforms without
> CONFIG_ARM_DMA_MEM_BUFFERABLE may run into issues if DMA_ATTR_WRITE_COMBINE
> disappears. Only one way to find out...
Looking at the results of grep, I think only OMAP2+ and Exynos may be
affected.
However, removing writecombine support from the DMA API is going to
have a huge impact for framebuffers on earlier ARMs - that's where we
do expect framebuffers to be mapped "uncached/buffered" for performance
reasons and not "uncached/unbuffered". It's quite literally the
difference between console scrolling being usable and totally unusable.
Given what I've said above, switching to using buffered mode for normal
DMA mappings is data-corrupting risky - as in your filesystem could get
fried. I don't think we should play fast and loose with people's data
by randomly changing that "because we'd like to", and I don't see that
screwing the console is really an option either.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
^ permalink raw reply
* [PATCH] KVM: PPC: Book3S HV: XIVE: Free escalation interrupts before disabling the VP
From: Cédric Le Goater @ 2019-08-06 17:25 UTC (permalink / raw)
To: Paul Mackerras; +Cc: kvm, kvm-ppc, Cédric Le Goater, linuxppc-dev
When a vCPU is brought done, the XIVE VP is first disabled and then
the event notification queues are freed. When freeing the queues, we
check for possible escalation interrupts and free them also.
But when a XIVE VP is disabled, the underlying XIVE ENDs also are
disabled in OPAL. When an END is disabled, its ESB pages (ESn and ESe)
are disabled and loads return all 1s. Which means that any access on
the ESB page of the escalation interrupt will return invalid values.
When an interrupt is freed, the shutdown handler computes a 'saved_p'
field from the value returned by a load in xive_do_source_set_mask().
This value is incorrect for escalation interrupts for the reason
described above.
This has no impact on Linux/KVM today because we don't make use of it
but we will introduce in future changes a xive_get_irqchip_state()
handler. This handler will use the 'saved_p' field to return the state
of an interrupt and 'saved_p' being incorrect, softlockup will occur.
Fix the vCPU cleanup sequence by first freeing the escalation
interrupts if any, then disable the XIVE VP and last free the queues.
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
arch/powerpc/kvm/book3s_xive.c | 18 ++++++++++--------
arch/powerpc/kvm/book3s_xive_native.c | 12 +++++++-----
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index e3ba67095895..09f838aa3138 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -1134,20 +1134,22 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
/* Mask the VP IPI */
xive_vm_esb_load(&xc->vp_ipi_data, XIVE_ESB_SET_PQ_01);
- /* Disable the VP */
- xive_native_disable_vp(xc->vp_id);
-
- /* Free the queues & associated interrupts */
+ /* Free escalations */
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
- struct xive_q *q = &xc->queues[i];
-
- /* Free the escalation irq */
if (xc->esc_virq[i]) {
free_irq(xc->esc_virq[i], vcpu);
irq_dispose_mapping(xc->esc_virq[i]);
kfree(xc->esc_virq_names[i]);
}
- /* Free the queue */
+ }
+
+ /* Disable the VP */
+ xive_native_disable_vp(xc->vp_id);
+
+ /* Free the queues */
+ for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
+ struct xive_q *q = &xc->queues[i];
+
xive_native_disable_queue(xc->vp_id, q, i);
if (q->qpage) {
free_pages((unsigned long)q->qpage,
diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c
index a998823f68a3..368427fcad20 100644
--- a/arch/powerpc/kvm/book3s_xive_native.c
+++ b/arch/powerpc/kvm/book3s_xive_native.c
@@ -67,10 +67,7 @@ void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu)
xc->valid = false;
kvmppc_xive_disable_vcpu_interrupts(vcpu);
- /* Disable the VP */
- xive_native_disable_vp(xc->vp_id);
-
- /* Free the queues & associated interrupts */
+ /* Free escalations */
for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
/* Free the escalation irq */
if (xc->esc_virq[i]) {
@@ -79,8 +76,13 @@ void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu)
kfree(xc->esc_virq_names[i]);
xc->esc_virq[i] = 0;
}
+ }
- /* Free the queue */
+ /* Disable the VP */
+ xive_native_disable_vp(xc->vp_id);
+
+ /* Free the queues */
+ for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
kvmppc_xive_native_cleanup_queue(vcpu, i);
}
--
2.21.0
^ permalink raw reply related
* Re: [PATCH 1/2] dma-mapping: fix page attributes for dma_mmap_*
From: Shawn Anastasio @ 2019-08-06 19:39 UTC (permalink / raw)
To: Christoph Hellwig, iommu
Cc: Gavin Li, linux-kernel, Will Deacon, linuxppc-dev, Russell King,
linux-mips, Paul Burton, Catalin Marinas, James Hogan,
Robin Murphy, linux-arm-kernel
In-Reply-To: <20190805080145.5694-2-hch@lst.de>
On 8/5/19 10:01 AM, Christoph Hellwig wrote:
> diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
> index 3813211a9aad..9ae5cee543c4 100644
> --- a/include/linux/dma-noncoherent.h
> +++ b/include/linux/dma-noncoherent.h
> @@ -42,13 +42,8 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
> dma_addr_t dma_addr, unsigned long attrs);
> long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
> dma_addr_t dma_addr);
> -
> -#ifdef CONFIG_ARCH_HAS_DMA_MMAP_PGPROT
> pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
> unsigned long attrs);
> -#else
> -# define arch_dma_mmap_pgprot(dev, prot, attrs) pgprot_noncached(prot)
> -#endif
Nit, but maybe the prototype should still be ifdef'd here? It at least
could prevent a reader from incorrectly thinking that the function is
always present.
Also, like Will mentioned earlier, the function name isn't entirely
accurate anymore. I second the suggestion of using something like
arch_dma_noncoherent_pgprot(). As for your idea of defining
pgprot_dmacoherent for all architectures as
#ifndef pgprot_dmacoherent
#define pgprot_dmacoherent pgprot_noncached
#endif
I think that the name here is kind of misleading too, since this
definition will only be used when there is no support for proper
DMA coherency.
^ permalink raw reply
* [Bug 204371] BUG kmalloc-4k (Tainted: G W ): Object padding overwritten
From: bugzilla-daemon @ 2019-08-06 20:47 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-204371-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=204371
--- Comment #6 from Erhard F. (erhard_f@mailbox.org) ---
On Wed, 31 Jul 2019 12:09:54 +0000
bugzilla-daemon@bugzilla.kernel.org wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=204371
>
> --- Comment #4 from mpe@ellerman.id.au ---
> bugzilla-daemon@bugzilla.kernel.org writes:
>
> > https://bugzilla.kernel.org/show_bug.cgi?id=204371
> >
> > --- Comment #2 from Andrew Morton (akpm@linux-foundation.org) ---
> > (switched to email. Please respond via emailed reply-to-all, not via the
> > bugzilla web interface).
> >
> >
> > On Mon, 29 Jul 2019 22:35:48 +0000 bugzilla-daemon@bugzilla.kernel.org
> wrote:
> >
> >> https://bugzilla.kernel.org/show_bug.cgi?id=204371
> >>
> >> Bug ID: 204371
> >> Summary: BUG kmalloc-4k (Tainted: G W ): Object
> >> padding overwritten
> >> Product: Memory Management
> >> Version: 2.5
> >> Kernel Version: 5.3.0-rc2
> >> Hardware: PPC-32
> >> OS: Linux
> >> Tree: Mainline
> >> Status: NEW
> >> Severity: normal
> >> Priority: P1
> >> Component: Slab Allocator
> >> Assignee: akpm@linux-foundation.org
> >> Reporter: erhard_f@mailbox.org
> >> Regression: No
> >
> > cc'ing various people here.
> >
> > I suspect proc_cgroup_show() is innocent and that perhaps
> > bpf_prepare_filter() had a memory scribble. iirc there has been at
> > least one recent pretty serious bpf fix applied recently. Can others
> > please take a look?
>
> I haven't been able to reproduce this on a 64-bit or 32-bit powerpc
> machine here. But I don't run gentoo userspace, so I suspect I'm not
> tripping the same path at boot. I did run the seccomp selftest and that
> didn't trip it either.
Had the time to test this on my G5 11,2. It's kernel 5.3-rc3 now, also booting
from a zstd:1 compressed btrfs partition. Without SLUB_DEBUG_ON selected in the
kernel, the machine boots seemingly fine, with SLUB_DEBUG_ON I get this:
[...]
Aug 06 22:26:35 T800 kernel: BTRFS info (device sda7): use zstd compression,
level 1
Aug 06 22:26:35 T800 kernel: BTRFS info (device sda7): disk space caching is
enabled
Aug 06 22:26:38 T800 kernel:
=============================================================================
Aug 06 22:26:38 T800 kernel: BUG kmalloc-4k (Tainted: G W ):
Object padding overwritten
Aug 06 22:26:38 T800 kernel:
-----------------------------------------------------------------------------
Aug 06 22:26:38 T800 kernel: INFO: 0x0000000062cd4309-0x000000004edab9d1. First
byte 0x0 instead of 0x5a
Aug 06 22:26:38 T800 kernel: INFO: Slab 0x0000000070aa589a objects=7 used=7
fp=0x0000000016708aa5 flags=0x7fe00000010200
Aug 06 22:26:38 T800 kernel: INFO: Object 0x000000007ed48057 @offset=17736
fp=0x00000000b4be3601
Aug 06 22:26:38 T800 kernel: Redzone 00000000f5b164d9: bb bb bb bb bb bb bb bb
........
Aug 06 22:26:38 T800 kernel: Object 000000007ed48057: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
[...]
Aug 06 22:26:38 T800 kernel: Redzone 00000000bd6d4c8f: bb bb bb bb bb bb bb bb
........
Aug 06 22:26:38 T800 kernel: Padding 0000000062cd4309: 00 00 00 00 00 00 00 00
........
Aug 06 22:26:38 T800 kernel: CPU: 0 PID: 118 Comm: systemd-journal Tainted: G
B W 5.3.0-rc3 #5
Aug 06 22:26:38 T800 kernel: Call Trace:
Aug 06 22:26:38 T800 kernel: [c00000045baa72a0] [c0000000009e1a74]
.dump_stack+0xe0/0x15c (unreliable)
Aug 06 22:26:38 T800 kernel: [c00000045baa7340] [c0000000002d4640]
.print_trailer+0x228/0x250
Aug 06 22:26:38 T800 kernel: [c00000045baa73e0] [c0000000002c81f8]
.check_bytes_and_report+0x118/0x140
Aug 06 22:26:38 T800 kernel: [c00000045baa7490] [c0000000002ca9fc]
.check_object+0xcc/0x3a0
Aug 06 22:26:38 T800 kernel: [c00000045baa7540] [c0000000002cc6b8]
.alloc_debug_processing+0x158/0x210
Aug 06 22:26:38 T800 kernel: [c00000045baa75d0] [c0000000002cce28]
.___slab_alloc+0x6b8/0x860
Aug 06 22:26:38 T800 kernel: [c00000045baa7710] [c0000000002cd024]
.__slab_alloc+0x54/0xc0
Aug 06 22:26:38 T800 kernel: [c00000045baa7790] [c0000000002cd854]
.kmem_cache_alloc_trace+0x3b4/0x410
Aug 06 22:26:38 T800 kernel: [c00000045baa7840] [c0000000004b9928]
.alloc_log_tree+0x38/0x140
Aug 06 22:26:38 T800 kernel: [c00000045baa78d0] [c0000000004b9ad0]
.btrfs_add_log_tree+0x30/0x130
Aug 06 22:26:38 T800 kernel: [c00000045baa7960] [c000000000525624]
.btrfs_log_inode_parent+0x4a4/0xeb0
Aug 06 22:26:38 T800 kernel: [c00000045baa7ae0] [c00000000052737c]
.btrfs_log_dentry_safe+0x6c/0xb0
Aug 06 22:26:38 T800 kernel: [c00000045baa7b80] [c0000000004e1e3c]
.btrfs_sync_file+0x1ec/0x570
Aug 06 22:26:38 T800 kernel: [c00000045baa7c90] [c000000000355ac4]
.vfs_fsync_range+0x64/0xe0
Aug 06 22:26:38 T800 kernel: [c00000045baa7d20] [c000000000355ba8]
.do_fsync+0x48/0xc0
Aug 06 22:26:38 T800 kernel: [c00000045baa7db0] [c000000000356028]
.__se_sys_fsync+0x18/0x30
Aug 06 22:26:38 T800 kernel: [c00000045baa7e20] [c00000000000a324]
system_call+0x5c/0x70
Aug 06 22:26:38 T800 kernel: FIX kmalloc-4k: Restoring
0x0000000062cd4309-0x000000004edab9d1=0x5a
[...]
Also I get:
[...]
Aug 06 22:27:53 T800 kernel:
=============================================================================
Aug 06 22:27:53 T800 kernel: BUG bfq_queue (Tainted: G B W ):
Poison overwritten
Aug 06 22:27:53 T800 kernel:
-----------------------------------------------------------------------------
Aug 06 22:27:53 T800 kernel: INFO: 0x00000000c2bbc60e-0x00000000710e6222. First
byte 0x0 instead of 0x6b
Aug 06 22:27:53 T800 kernel: INFO: Allocated in .bfq_get_queue+0x27c/0x600
age=22029 cpu=1 pid=155
Aug 06 22:27:53 T800 kernel: .__slab_alloc+0x54/0xc0
Aug 06 22:27:53 T800 kernel: .kmem_cache_alloc_node+0xf8/0x460
Aug 06 22:27:53 T800 kernel: .bfq_get_queue+0x27c/0x600
Aug 06 22:27:53 T800 kernel: .bfq_init_rq+0x720/0x940
Aug 06 22:27:53 T800 kernel: .bfq_insert_requests+0x130/0x1120
Aug 06 22:27:53 T800 kernel: .blk_mq_sched_insert_requests+0x138/0x420
Aug 06 22:27:53 T800 kernel: .blk_mq_flush_plug_list+0x224/0x4e0
Aug 06 22:27:53 T800 kernel: .blk_flush_plug_list+0x128/0x170
Aug 06 22:27:53 T800 kernel: .blk_finish_plug+0x24/0x40
Aug 06 22:27:53 T800 kernel: .read_pages+0xa0/0x240
Aug 06 22:27:53 T800 kernel: .__do_page_cache_readahead+0x238/0x2b0
Aug 06 22:27:53 T800 kernel: .force_page_cache_readahead+0xbc/0x1c0
Aug 06 22:27:53 T800 kernel: .generic_file_read_iter+0x914/0xd80
Aug 06 22:27:53 T800 kernel: .blkdev_read_iter+0x40/0x70
Aug 06 22:27:53 T800 kernel: .new_sync_read+0x140/0x1c0
Aug 06 22:27:53 T800 kernel: .vfs_read+0xb0/0x1b0
Aug 06 22:27:53 T800 kernel: INFO: Freed in .bfq_put_queue+0xc4/0x100 age=21892
cpu=0 pid=143
Aug 06 22:27:53 T800 kernel: .kmem_cache_free+0x52c/0x530
Aug 06 22:27:53 T800 kernel: .bfq_put_queue+0xc4/0x100
Aug 06 22:27:53 T800 kernel: .bfq_put_idle_entity+0x74/0xc0
Aug 06 22:27:53 T800 kernel: .bfq_bfqq_served+0xc4/0x120
Aug 06 22:27:53 T800 kernel: .bfq_dispatch_request+0x344/0xbd0
Aug 06 22:27:53 T800 kernel: .blk_mq_do_dispatch_sched+0x104/0x180
Aug 06 22:27:53 T800 kernel:
.blk_mq_sched_dispatch_requests+0x144/0x230
Aug 06 22:27:53 T800 kernel: .__blk_mq_run_hw_queue+0xa4/0x140
Aug 06 22:27:53 T800 kernel: .__blk_mq_delay_run_hw_queue+0x234/0x240
Aug 06 22:27:53 T800 kernel: .blk_mq_run_hw_queue+0xac/0x130
Aug 06 22:27:53 T800 kernel: .blk_mq_sched_insert_requests+0x190/0x420
Aug 06 22:27:53 T800 kernel: .blk_mq_flush_plug_list+0x224/0x4e0
Aug 06 22:27:53 T800 kernel: .blk_flush_plug_list+0x128/0x170
Aug 06 22:27:53 T800 kernel: .blk_finish_plug+0x24/0x40
Aug 06 22:27:53 T800 kernel: .read_pages+0xa0/0x240
Aug 06 22:27:53 T800 kernel: .__do_page_cache_readahead+0x238/0x2b0
Aug 06 22:27:53 T800 kernel: INFO: Slab 0x00000000559e0a9c objects=19 used=19
fp=0x0000000016708aa5 flags=0x7fe00000010200
Aug 06 22:27:53 T800 kernel: INFO: Object 0x00000000d181f14b @offset=8
fp=0x0000000035f5f997
Aug 06 22:27:53 T800 kernel: Redzone 000000006c7b1db8: bb bb bb bb bb bb bb bb
........
Aug 06 22:27:53 T800 kernel: Object 00000000d181f14b: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000f4600676: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 000000009ecde695: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 000000007dfb2519: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 000000004c46d89f: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000b68dc230: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000b6fcf14d: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000f3752aca: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 000000007662c42e: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 0000000086080f07: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 000000003df14b51: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000769dc0ba: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 000000006f036f9c: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 000000005fbbe251: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 000000001c3da628: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 000000003535f2cc: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 000000006c4f0b17: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000aa181422: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000e632967b: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 0000000083919b29: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000ae24557c: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000dc2cc57d: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000995c45ac: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000632e218e: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000c0c20784: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000f48aad9c: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000f5449c05: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000146f6d20: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000e78d4c0d: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 0000000038d3f642: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
Aug 06 22:27:53 T800 kernel: Object 00000000c9784ba9: 6b 6b 6b 6b 6b 6b 6b 6b
00 00 00 00 00 00 00 00 kkkkkkkk........
Aug 06 22:27:53 T800 kernel: Object 00000000d0fb292a: 6b 6b 6b 6b 6b 6b 6b 6b
6b 6b 6b 6b 6b 6b 6b a5 kkkkkkkkkkkkkkk.
Aug 06 22:27:53 T800 kernel: Redzone 0000000033bfd673: bb bb bb bb bb bb bb bb
........
Aug 06 22:27:53 T800 kernel: Padding 00000000833b50bf: 5a 5a 5a 5a 5a 5a 5a 5a
ZZZZZZZZ
Aug 06 22:27:53 T800 kernel: CPU: 0 PID: 284 Comm: (direxec) Tainted: G B
W 5.3.0-rc3 #5
Aug 06 22:27:53 T800 kernel: Call Trace:
Aug 06 22:27:53 T800 kernel: [c00000045d93ea30] [c0000000009e1a74]
.dump_stack+0xe0/0x15c (unreliable)
Aug 06 22:27:53 T800 kernel: [c00000045d93ead0] [c0000000002d4640]
.print_trailer+0x228/0x250
Aug 06 22:27:53 T800 kernel: [c00000045d93eb70] [c0000000002c81f8]
.check_bytes_and_report+0x118/0x140
Aug 06 22:27:53 T800 kernel: [c00000045d93ec20] [c0000000002cac48]
.check_object+0x318/0x3a0
Aug 06 22:27:53 T800 kernel: [c00000045d93ecd0] [c0000000002cc6b8]
.alloc_debug_processing+0x158/0x210
Aug 06 22:27:53 T800 kernel: [c00000045d93ed60] [c0000000002cce28]
.___slab_alloc+0x6b8/0x860
Aug 06 22:27:53 T800 kernel: [c00000045d93eea0] [c0000000002cd024]
.__slab_alloc+0x54/0xc0
Aug 06 22:27:53 T800 kernel: [c00000045d93ef20] [c0000000002cda98]
.kmem_cache_alloc_node+0xf8/0x460
Aug 06 22:27:53 T800 kernel: [c00000045d93efd0] [c00000000062a53c]
.bfq_get_queue+0x27c/0x600
Aug 06 22:27:53 T800 kernel: [c00000045d93f0a0] [c00000000062d80c]
.bfq_init_rq+0x43c/0x940
Aug 06 22:27:53 T800 kernel: [c00000045d93f180] [c00000000062e0c0]
.bfq_insert_requests+0x130/0x1120
Aug 06 22:27:53 T800 kernel: [c00000045d93f2e0] [c000000000606118]
.blk_mq_sched_insert_requests+0x138/0x420
Aug 06 22:27:53 T800 kernel: [c00000045d93f390] [c0000000005ff2f4]
.blk_mq_flush_plug_list+0x224/0x4e0
Aug 06 22:27:53 T800 kernel: [c00000045d93f490] [c0000000005ef978]
.blk_flush_plug_list+0x128/0x170
Aug 06 22:27:53 T800 kernel: [c00000045d93f550] [c0000000005ef9e4]
.blk_finish_plug+0x24/0x40
Aug 06 22:27:53 T800 kernel: [c00000045d93f5c0] [c000000000234fc0]
.read_pages+0xa0/0x240
Aug 06 22:27:53 T800 kernel: [c00000045d93f6b0] [c000000000235398]
.__do_page_cache_readahead+0x238/0x2b0
Aug 06 22:27:53 T800 kernel: [c00000045d93f7b0] [c0000000002356f8]
.ondemand_readahead+0x2e8/0x640
Aug 06 22:27:53 T800 kernel: [c00000045d93f870] [c000000000224fb4]
.generic_file_read_iter+0x914/0xd80
Aug 06 22:27:53 T800 kernel: [c00000045d93f9f0] [c0000000002fd7a0]
.new_sync_read+0x140/0x1c0
Aug 06 22:27:53 T800 kernel: [c00000045d93fae0] [c000000000300490]
.vfs_read+0xb0/0x1b0
Aug 06 22:27:53 T800 kernel: [c00000045d93fb80] [c0000000003005d8]
.kernel_read+0x48/0x80
Aug 06 22:27:53 T800 kernel: [c00000045d93fc00] [c000000000309bc4]
.prepare_binprm+0x194/0x210
Aug 06 22:27:53 T800 kernel: [c00000045d93fca0] [c00000000030b3d4]
.__do_execve_file.isra.46+0x6c4/0xca0
Aug 06 22:27:53 T800 kernel: [c00000045d93fda0] [c00000000030c948]
.__se_sys_execve+0x48/0x60
Aug 06 22:27:53 T800 kernel: [c00000045d93fe20] [c00000000000a324]
system_call+0x5c/0x70
Aug 06 22:27:53 T800 kernel: FIX bfq_queue: Restoring
0x00000000c2bbc60e-0x00000000710e6222=0x6b
Aug 06 22:27:53 T800 kernel: FIX bfq_queue: Marking all objects used
[...]
On the G4 DP I use a SSD with kyber scheduler, on the G5 it's a HDD with bfq.
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply
* [Bug 204371] BUG kmalloc-4k (Tainted: G W ): Object padding overwritten
From: bugzilla-daemon @ 2019-08-06 20:48 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-204371-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=204371
--- Comment #7 from Erhard F. (erhard_f@mailbox.org) ---
Created attachment 284241
--> https://bugzilla.kernel.org/attachment.cgi?id=284241&action=edit
dmesg (PowerMac G5 11,2, kernel 5.3-rc3)
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply
* [Bug 204371] BUG kmalloc-4k (Tainted: G W ): Object padding overwritten
From: bugzilla-daemon @ 2019-08-06 20:51 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-204371-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=204371
--- Comment #8 from Erhard F. (erhard_f@mailbox.org) ---
Created attachment 284243
--> https://bugzilla.kernel.org/attachment.cgi?id=284243&action=edit
kernel .config (PowerMac G5 11,2, kernel 5.3-rc3)
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply
* [PATCH AUTOSEL 5.2 21/59] powerpc/nvdimm: Pick nearby online node if the device node is not online
From: Sasha Levin @ 2019-08-06 21:32 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Aneesh Kumar K.V, linuxppc-dev
In-Reply-To: <20190806213319.19203-1-sashal@kernel.org>
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
[ Upstream commit da1115fdbd6e86c62185cdd2b4bf7add39f2f82b ]
Currently, nvdimm subsystem expects the device numa node for SCM device to be
an online node. It also doesn't try to bring the device numa node online. Hence
if we use a non-online numa node as device node we hit crashes like below. This
is because we try to access uninitialized NODE_DATA in different code paths.
cpu 0x0: Vector: 300 (Data Access) at [c0000000fac53170]
pc: c0000000004bbc50: ___slab_alloc+0x120/0xca0
lr: c0000000004bc834: __slab_alloc+0x64/0xc0
sp: c0000000fac53400
msr: 8000000002009033
dar: 73e8
dsisr: 80000
current = 0xc0000000fabb6d80
paca = 0xc000000003870000 irqmask: 0x03 irq_happened: 0x01
pid = 7, comm = kworker/u16:0
Linux version 5.2.0-06234-g76bd729b2644 (kvaneesh@ltc-boston123) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #135 SMP Thu Jul 11 05:36:30 CDT 2019
enter ? for help
[link register ] c0000000004bc834 __slab_alloc+0x64/0xc0
[c0000000fac53400] c0000000fac53480 (unreliable)
[c0000000fac53500] c0000000004bc818 __slab_alloc+0x48/0xc0
[c0000000fac53560] c0000000004c30a0 __kmalloc_node_track_caller+0x3c0/0x6b0
[c0000000fac535d0] c000000000cfafe4 devm_kmalloc+0x74/0xc0
[c0000000fac53600] c000000000d69434 nd_region_activate+0x144/0x560
[c0000000fac536d0] c000000000d6b19c nd_region_probe+0x17c/0x370
[c0000000fac537b0] c000000000d6349c nvdimm_bus_probe+0x10c/0x230
[c0000000fac53840] c000000000cf3cc4 really_probe+0x254/0x4e0
[c0000000fac538d0] c000000000cf429c driver_probe_device+0x16c/0x1e0
[c0000000fac53950] c000000000cf0b44 bus_for_each_drv+0x94/0x130
[c0000000fac539b0] c000000000cf392c __device_attach+0xdc/0x200
[c0000000fac53a50] c000000000cf231c bus_probe_device+0x4c/0xf0
[c0000000fac53a90] c000000000ced268 device_add+0x528/0x810
[c0000000fac53b60] c000000000d62a58 nd_async_device_register+0x28/0xa0
[c0000000fac53bd0] c0000000001ccb8c async_run_entry_fn+0xcc/0x1f0
[c0000000fac53c50] c0000000001bcd9c process_one_work+0x46c/0x860
[c0000000fac53d20] c0000000001bd4f4 worker_thread+0x364/0x5f0
[c0000000fac53db0] c0000000001c7260 kthread+0x1b0/0x1c0
[c0000000fac53e20] c00000000000b954 ret_from_kernel_thread+0x5c/0x68
The patch tries to fix this by picking the nearest online node as the SCM node.
This does have a problem of us losing the information that SCM node is
equidistant from two other online nodes. If applications need to understand these
fine-grained details we should express then like x86 does via
/sys/devices/system/node/nodeX/accessY/initiators/
With the patch we get
# numactl -H
available: 2 nodes (0-1)
node 0 cpus:
node 0 size: 0 MB
node 0 free: 0 MB
node 1 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
node 1 size: 130865 MB
node 1 free: 129130 MB
node distances:
node 0 1
0: 10 20
1: 20 10
# cat /sys/bus/nd/devices/region0/numa_node
0
# dmesg | grep papr_scm
[ 91.332305] papr_scm ibm,persistent-memory:ibm,pmemory@44104001: Region registered with target node 2 and online node 0
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190729095128.23707-1-aneesh.kumar@linux.ibm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/platforms/pseries/papr_scm.c | 29 +++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index 96c53b23e58f9..30af5019a68fe 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -194,12 +194,32 @@ static const struct attribute_group *papr_scm_dimm_groups[] = {
NULL,
};
+static inline int papr_scm_node(int node)
+{
+ int min_dist = INT_MAX, dist;
+ int nid, min_node;
+
+ if ((node == NUMA_NO_NODE) || node_online(node))
+ return node;
+
+ min_node = first_online_node;
+ for_each_online_node(nid) {
+ dist = node_distance(node, nid);
+ if (dist < min_dist) {
+ min_dist = dist;
+ min_node = nid;
+ }
+ }
+ return min_node;
+}
+
static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
{
struct device *dev = &p->pdev->dev;
struct nd_mapping_desc mapping;
struct nd_region_desc ndr_desc;
unsigned long dimm_flags;
+ int target_nid, online_nid;
p->bus_desc.ndctl = papr_scm_ndctl;
p->bus_desc.module = THIS_MODULE;
@@ -238,8 +258,10 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
memset(&ndr_desc, 0, sizeof(ndr_desc));
ndr_desc.attr_groups = region_attr_groups;
- ndr_desc.numa_node = dev_to_node(&p->pdev->dev);
- ndr_desc.target_node = ndr_desc.numa_node;
+ target_nid = dev_to_node(&p->pdev->dev);
+ online_nid = papr_scm_node(target_nid);
+ ndr_desc.numa_node = online_nid;
+ ndr_desc.target_node = target_nid;
ndr_desc.res = &p->res;
ndr_desc.of_node = p->dn;
ndr_desc.provider_data = p;
@@ -254,6 +276,9 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
ndr_desc.res, p->dn);
goto err;
}
+ if (target_nid != online_nid)
+ dev_info(dev, "Region registered with target node %d and online node %d",
+ target_nid, online_nid);
return 0;
--
2.20.1
^ permalink raw reply related
* Re: [PATCH net-next v2] ibmveth: Allow users to update reported speed and duplex
From: Jakub Kicinski @ 2019-08-06 22:15 UTC (permalink / raw)
To: Thomas Falcon; +Cc: linuxppc-dev, netdev
In-Reply-To: <1565108588-17331-1-git-send-email-tlfalcon@linux.ibm.com>
On Tue, 6 Aug 2019 11:23:08 -0500, Thomas Falcon wrote:
> Reported ethtool link settings for the ibmveth driver are currently
> hardcoded and no longer reflect the actual capabilities of supported
> hardware. There is no interface designed for retrieving this information
> from device firmware nor is there any way to update current settings
> to reflect observed or expected link speeds.
>
> To avoid breaking existing configurations, retain current values as
> default settings but let users update them to match the expected
> capabilities of underlying hardware if needed. This update would
> allow the use of configurations that rely on certain link speed
> settings, such as LACP. This patch is based on the implementation
> in virtio_net.
>
> Signed-off-by: Thomas Falcon <tlfalcon@linux.ibm.com>
Looks like this is the third copy of the same code virtio and
netvsc have :( Is there a chance we could factor this out into
helpers in the core?
^ permalink raw reply
* [PATCH 0/4] powerpc: KASAN for 64-bit Book3S on Radix
From: Daniel Axtens @ 2019-08-06 23:38 UTC (permalink / raw)
To: aneesh.kumar, christophe.leroy, bsingharora
Cc: linuxppc-dev, kasan-dev, Daniel Axtens
Building on the work of Christophe, Aneesh and Balbir, I've ported
KASAN to 64-bit Book3S kernels running on the Radix MMU.
It builds on top Christophe's work on 32bit. It also builds on my
generic KASAN_VMALLOC series, available at:
https://patchwork.kernel.org/project/linux-mm/list/?series=153209
This provides full inline instrumentation on radix, but does require
that you be able to specify the amount of memory on the system at
compile time. More details in patch 4.
Notable changes from the RFC:
- I've dropped Book3E 64-bit for now.
- Now instead of hacking into the KASAN core to disable module
allocations, we use KASAN_VMALLOC.
- More testing, including on real hardware. This revealed that
discontiguous memory is a bit of a headache, at the moment we
must disable memory not contiguous from 0.
- Update to deal with kasan bitops instrumentation that landed
between RFC and now.
- Documentation!
- Various cleanups and tweaks.
I am getting occasional problems on boot of real hardware where it
seems vmalloc space mappings don't get installed in time. (We get a
BUG that memory is not accessible, but by the time we hit xmon the
memory then is accessible!) It happens once every few boots. I haven't
yet been able to figure out what is happening and why. I'm going to
look in to it, but I think the patches are in good enough shape to
review while I work on it.
Regards,
Daniel
Daniel Axtens (4):
kasan: allow arches to provide their own early shadow setup
kasan: support instrumented bitops with generic non-atomic bitops
powerpc: support KASAN instrumentation of bitops
powerpc: Book3S 64-bit "heavyweight" KASAN support
Documentation/dev-tools/kasan.rst | 7 +-
Documentation/powerpc/kasan.txt | 111 ++++++++++++++
arch/powerpc/Kconfig | 4 +
arch/powerpc/Kconfig.debug | 21 +++
arch/powerpc/Makefile | 7 +
arch/powerpc/include/asm/bitops.h | 25 ++--
arch/powerpc/include/asm/book3s/64/radix.h | 5 +
arch/powerpc/include/asm/kasan.h | 35 ++++-
arch/powerpc/kernel/process.c | 8 ++
arch/powerpc/kernel/prom.c | 57 +++++++-
arch/powerpc/mm/kasan/Makefile | 1 +
arch/powerpc/mm/kasan/kasan_init_book3s_64.c | 76 ++++++++++
include/asm-generic/bitops-instrumented.h | 144 ++++++++++---------
include/linux/kasan.h | 2 +
lib/Kconfig.kasan | 3 +
mm/kasan/init.c | 10 ++
16 files changed, 431 insertions(+), 85 deletions(-)
create mode 100644 Documentation/powerpc/kasan.txt
create mode 100644 arch/powerpc/mm/kasan/kasan_init_book3s_64.c
--
2.20.1
^ permalink raw reply
* [PATCH 1/4] kasan: allow arches to provide their own early shadow setup
From: Daniel Axtens @ 2019-08-06 23:38 UTC (permalink / raw)
To: aneesh.kumar, christophe.leroy, bsingharora
Cc: linuxppc-dev, kasan-dev, Daniel Axtens
In-Reply-To: <20190806233827.16454-1-dja@axtens.net>
powerpc supports several different MMUs. In particular, book3s
machines support both a hash-table based MMU and a radix MMU.
These MMUs support different numbers of entries per directory
level: the PTES_PER_* defines evaluate to variables, not constants.
This leads to complier errors as global variables must have constant
sizes.
Allow architectures to manage their own early shadow variables so we
can work around this on powerpc.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
Changes from RFC:
- To make checkpatch happy, move ARCH_HAS_KASAN_EARLY_SHADOW from
a random #define to a config option selected when building for
ppc64 book3s
---
include/linux/kasan.h | 2 ++
lib/Kconfig.kasan | 3 +++
mm/kasan/init.c | 10 ++++++++++
3 files changed, 15 insertions(+)
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index ec81113fcee4..15933da52a3e 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -14,11 +14,13 @@ struct task_struct;
#include <asm/kasan.h>
#include <asm/pgtable.h>
+#ifndef CONFIG_ARCH_HAS_KASAN_EARLY_SHADOW
extern unsigned char kasan_early_shadow_page[PAGE_SIZE];
extern pte_t kasan_early_shadow_pte[PTRS_PER_PTE];
extern pmd_t kasan_early_shadow_pmd[PTRS_PER_PMD];
extern pud_t kasan_early_shadow_pud[PTRS_PER_PUD];
extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D];
+#endif
int kasan_populate_early_shadow(const void *shadow_start,
const void *shadow_end);
diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan
index a320dc2e9317..0621a0129c04 100644
--- a/lib/Kconfig.kasan
+++ b/lib/Kconfig.kasan
@@ -9,6 +9,9 @@ config HAVE_ARCH_KASAN_SW_TAGS
config HAVE_ARCH_KASAN_VMALLOC
bool
+config ARCH_HAS_KASAN_EARLY_SHADOW
+ bool
+
config CC_HAS_KASAN_GENERIC
def_bool $(cc-option, -fsanitize=kernel-address)
diff --git a/mm/kasan/init.c b/mm/kasan/init.c
index ce45c491ebcd..7ef2b87a7988 100644
--- a/mm/kasan/init.c
+++ b/mm/kasan/init.c
@@ -31,10 +31,14 @@
* - Latter it reused it as zero shadow to cover large ranges of memory
* that allowed to access, but not handled by kasan (vmalloc/vmemmap ...).
*/
+#ifndef CONFIG_ARCH_HAS_KASAN_EARLY_SHADOW
unsigned char kasan_early_shadow_page[PAGE_SIZE] __page_aligned_bss;
+#endif
#if CONFIG_PGTABLE_LEVELS > 4
+#ifndef CONFIG_ARCH_HAS_KASAN_EARLY_SHADOW
p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D] __page_aligned_bss;
+#endif
static inline bool kasan_p4d_table(pgd_t pgd)
{
return pgd_page(pgd) == virt_to_page(lm_alias(kasan_early_shadow_p4d));
@@ -46,7 +50,9 @@ static inline bool kasan_p4d_table(pgd_t pgd)
}
#endif
#if CONFIG_PGTABLE_LEVELS > 3
+#ifndef CONFIG_ARCH_HAS_KASAN_EARLY_SHADOW
pud_t kasan_early_shadow_pud[PTRS_PER_PUD] __page_aligned_bss;
+#endif
static inline bool kasan_pud_table(p4d_t p4d)
{
return p4d_page(p4d) == virt_to_page(lm_alias(kasan_early_shadow_pud));
@@ -58,7 +64,9 @@ static inline bool kasan_pud_table(p4d_t p4d)
}
#endif
#if CONFIG_PGTABLE_LEVELS > 2
+#ifndef CONFIG_ARCH_HAS_KASAN_EARLY_SHADOW
pmd_t kasan_early_shadow_pmd[PTRS_PER_PMD] __page_aligned_bss;
+#endif
static inline bool kasan_pmd_table(pud_t pud)
{
return pud_page(pud) == virt_to_page(lm_alias(kasan_early_shadow_pmd));
@@ -69,7 +77,9 @@ static inline bool kasan_pmd_table(pud_t pud)
return false;
}
#endif
+#ifndef CONFIG_ARCH_HAS_KASAN_EARLY_SHADOW
pte_t kasan_early_shadow_pte[PTRS_PER_PTE] __page_aligned_bss;
+#endif
static inline bool kasan_pte_table(pmd_t pmd)
{
--
2.20.1
^ permalink raw reply related
* [PATCH 2/4] kasan: support instrumented bitops with generic non-atomic bitops
From: Daniel Axtens @ 2019-08-06 23:38 UTC (permalink / raw)
To: aneesh.kumar, christophe.leroy, bsingharora
Cc: linuxppc-dev, kasan-dev, Daniel Axtens
In-Reply-To: <20190806233827.16454-1-dja@axtens.net>
Currently bitops-instrumented.h assumes that the architecture provides
both the atomic and non-atomic versions of the bitops (e.g. both
set_bit and __set_bit). This is true on x86, but is not always true:
there is a generic bitops/non-atomic.h header that provides generic
non-atomic versions. powerpc uses this generic version, so it does
not have it's own e.g. __set_bit that could be renamed arch___set_bit.
Rearrange bitops-instrumented.h. As operations in bitops/non-atomic.h
will already be instrumented (they use regular memory accesses), put
the instrumenting wrappers for them behind an ifdef. Only include
these instrumentation wrappers if non-atomic.h has not been included.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
include/asm-generic/bitops-instrumented.h | 144 ++++++++++++----------
1 file changed, 76 insertions(+), 68 deletions(-)
diff --git a/include/asm-generic/bitops-instrumented.h b/include/asm-generic/bitops-instrumented.h
index ddd1c6d9d8db..2fe8f7e12a11 100644
--- a/include/asm-generic/bitops-instrumented.h
+++ b/include/asm-generic/bitops-instrumented.h
@@ -29,21 +29,6 @@ static inline void set_bit(long nr, volatile unsigned long *addr)
arch_set_bit(nr, addr);
}
-/**
- * __set_bit - Set a bit in memory
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * Unlike set_bit(), this function is non-atomic. If it is called on the same
- * region of memory concurrently, the effect may be that only one operation
- * succeeds.
- */
-static inline void __set_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch___set_bit(nr, addr);
-}
-
/**
* clear_bit - Clears a bit in memory
* @nr: Bit to clear
@@ -57,21 +42,6 @@ static inline void clear_bit(long nr, volatile unsigned long *addr)
arch_clear_bit(nr, addr);
}
-/**
- * __clear_bit - Clears a bit in memory
- * @nr: the bit to clear
- * @addr: the address to start counting from
- *
- * Unlike clear_bit(), this function is non-atomic. If it is called on the same
- * region of memory concurrently, the effect may be that only one operation
- * succeeds.
- */
-static inline void __clear_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch___clear_bit(nr, addr);
-}
-
/**
* clear_bit_unlock - Clear a bit in memory, for unlock
* @nr: the bit to set
@@ -116,21 +86,6 @@ static inline void change_bit(long nr, volatile unsigned long *addr)
arch_change_bit(nr, addr);
}
-/**
- * __change_bit - Toggle a bit in memory
- * @nr: the bit to change
- * @addr: the address to start counting from
- *
- * Unlike change_bit(), this function is non-atomic. If it is called on the same
- * region of memory concurrently, the effect may be that only one operation
- * succeeds.
- */
-static inline void __change_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch___change_bit(nr, addr);
-}
-
/**
* test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
@@ -144,20 +99,6 @@ static inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
return arch_test_and_set_bit(nr, addr);
}
-/**
- * __test_and_set_bit - Set a bit and return its old value
- * @nr: Bit to set
- * @addr: Address to count from
- *
- * This operation is non-atomic. If two instances of this operation race, one
- * can appear to succeed but actually fail.
- */
-static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch___test_and_set_bit(nr, addr);
-}
-
/**
* test_and_set_bit_lock - Set a bit and return its old value, for lock
* @nr: Bit to set
@@ -187,30 +128,96 @@ static inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
}
/**
- * __test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
+ * test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to change
+ * @addr: Address to count from
+ *
+ * This is an atomic fully-ordered operation (implied full memory barrier).
+ */
+static inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ return arch_test_and_change_bit(nr, addr);
+}
+
+/*
+ * If the arch is using the generic non-atomic bit ops, they are already
+ * instrumented, and we don't need to create wrappers. Only wrap if we
+ * haven't included that header.
+ */
+#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
+
+/**
+ * __set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike set_bit(), this function is non-atomic. If it is called on the same
+ * region of memory concurrently, the effect may be that only one operation
+ * succeeds.
+ */
+static inline void __set_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch___set_bit(nr, addr);
+}
+
+/**
+ * __clear_bit - Clears a bit in memory
+ * @nr: the bit to clear
+ * @addr: the address to start counting from
+ *
+ * Unlike clear_bit(), this function is non-atomic. If it is called on the same
+ * region of memory concurrently, the effect may be that only one operation
+ * succeeds.
+ */
+static inline void __clear_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch___clear_bit(nr, addr);
+}
+
+/**
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to change
+ * @addr: the address to start counting from
+ *
+ * Unlike change_bit(), this function is non-atomic. If it is called on the same
+ * region of memory concurrently, the effect may be that only one operation
+ * succeeds.
+ */
+static inline void __change_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch___change_bit(nr, addr);
+}
+
+/**
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
* @addr: Address to count from
*
* This operation is non-atomic. If two instances of this operation race, one
* can appear to succeed but actually fail.
*/
-static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
+static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
{
kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch___test_and_clear_bit(nr, addr);
+ return arch___test_and_set_bit(nr, addr);
}
/**
- * test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to change
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
* @addr: Address to count from
*
- * This is an atomic fully-ordered operation (implied full memory barrier).
+ * This operation is non-atomic. If two instances of this operation race, one
+ * can appear to succeed but actually fail.
*/
-static inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
+static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
{
kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch_test_and_change_bit(nr, addr);
+ return arch___test_and_clear_bit(nr, addr);
}
/**
@@ -237,6 +244,7 @@ static inline bool test_bit(long nr, const volatile unsigned long *addr)
kasan_check_read(addr + BIT_WORD(nr), sizeof(long));
return arch_test_bit(nr, addr);
}
+#endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
#if defined(arch_clear_bit_unlock_is_negative_byte)
/**
--
2.20.1
^ permalink raw reply related
* [PATCH 3/4] powerpc: support KASAN instrumentation of bitops
From: Daniel Axtens @ 2019-08-06 23:38 UTC (permalink / raw)
To: aneesh.kumar, christophe.leroy, bsingharora
Cc: linuxppc-dev, Nicholas Piggin, kasan-dev, Daniel Axtens
In-Reply-To: <20190806233827.16454-1-dja@axtens.net>
In KASAN development I noticed that the powerpc-specific bitops
were not being picked up by the KASAN test suite.
Instrumentation is done via the bitops-instrumented.h header. It
requies that arch-specific versions of bitop functions are renamed
to arch_*. Do this renaming.
For clear_bit_unlock_is_negative_byte, the current implementation
uses the PG_waiter constant. This works because it's a preprocessor
macro - so it's only actually evaluated in contexts where PG_waiter
is defined. With instrumentation however, it becomes a static inline
function, and all of a sudden we need the actual value of PG_waiter.
Because of the order of header includes, it's not available and we
fail to compile. Instead, manually specify that we care about bit 7.
This is still correct: bit 7 is the bit that would mark a negative
byte, but it does obscure the origin a little bit.
Cc: Nicholas Piggin <npiggin@gmail.com> # clear_bit_unlock_negative_byte
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
arch/powerpc/include/asm/bitops.h | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index 603aed229af7..19dc16e62e6a 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -86,22 +86,22 @@ DEFINE_BITOP(clear_bits, andc, "")
DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER)
DEFINE_BITOP(change_bits, xor, "")
-static __inline__ void set_bit(int nr, volatile unsigned long *addr)
+static __inline__ void arch_set_bit(int nr, volatile unsigned long *addr)
{
set_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
}
-static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
+static __inline__ void arch_clear_bit(int nr, volatile unsigned long *addr)
{
clear_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
}
-static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
+static __inline__ void arch_clear_bit_unlock(int nr, volatile unsigned long *addr)
{
clear_bits_unlock(BIT_MASK(nr), addr + BIT_WORD(nr));
}
-static __inline__ void change_bit(int nr, volatile unsigned long *addr)
+static __inline__ void arch_change_bit(int nr, volatile unsigned long *addr)
{
change_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
}
@@ -138,26 +138,26 @@ DEFINE_TESTOP(test_and_clear_bits, andc, PPC_ATOMIC_ENTRY_BARRIER,
DEFINE_TESTOP(test_and_change_bits, xor, PPC_ATOMIC_ENTRY_BARRIER,
PPC_ATOMIC_EXIT_BARRIER, 0)
-static __inline__ int test_and_set_bit(unsigned long nr,
+static __inline__ int arch_test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
{
return test_and_set_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
}
-static __inline__ int test_and_set_bit_lock(unsigned long nr,
+static __inline__ int arch_test_and_set_bit_lock(unsigned long nr,
volatile unsigned long *addr)
{
return test_and_set_bits_lock(BIT_MASK(nr),
addr + BIT_WORD(nr)) != 0;
}
-static __inline__ int test_and_clear_bit(unsigned long nr,
+static __inline__ int arch_test_and_clear_bit(unsigned long nr,
volatile unsigned long *addr)
{
return test_and_clear_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
}
-static __inline__ int test_and_change_bit(unsigned long nr,
+static __inline__ int arch_test_and_change_bit(unsigned long nr,
volatile unsigned long *addr)
{
return test_and_change_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
@@ -186,14 +186,14 @@ static __inline__ unsigned long clear_bit_unlock_return_word(int nr,
}
/* This is a special function for mm/filemap.c */
-#define clear_bit_unlock_is_negative_byte(nr, addr) \
- (clear_bit_unlock_return_word(nr, addr) & BIT_MASK(PG_waiters))
+#define arch_clear_bit_unlock_is_negative_byte(nr, addr) \
+ (clear_bit_unlock_return_word(nr, addr) & BIT_MASK(7))
#endif /* CONFIG_PPC64 */
#include <asm-generic/bitops/non-atomic.h>
-static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
+static __inline__ void arch___clear_bit_unlock(int nr, volatile unsigned long *addr)
{
__asm__ __volatile__(PPC_RELEASE_BARRIER "" ::: "memory");
__clear_bit(nr, addr);
@@ -239,6 +239,9 @@ unsigned long __arch_hweight64(__u64 w);
#include <asm-generic/bitops/find.h>
+/* wrappers that deal with KASAN instrumentation */
+#include <asm-generic/bitops-instrumented.h>
+
/* Little-endian versions */
#include <asm-generic/bitops/le.h>
--
2.20.1
^ permalink raw reply related
* [PATCH 4/4] powerpc: Book3S 64-bit "heavyweight" KASAN support
From: Daniel Axtens @ 2019-08-06 23:38 UTC (permalink / raw)
To: aneesh.kumar, christophe.leroy, bsingharora
Cc: linuxppc-dev, kasan-dev, Daniel Axtens
In-Reply-To: <20190806233827.16454-1-dja@axtens.net>
KASAN support on powerpc64 is interesting:
- We want to be able to support inline instrumentation so as to be
able to catch global and stack issues.
- We run a lot of code at boot in real mode. This includes stuff like
printk(), so it's not feasible to just disable instrumentation
around it.
[For those not immersed in ppc64, in real mode, the top nibble or
2 bits (depending on radix/hash mmu) of the address is ignored. To
make things work, we put the linear mapping at
0xc000000000000000. This means that a pointer to part of the linear
mapping will work both in real mode, where it will be interpreted
as a physical address of the form 0x000..., and out of real mode,
where it will go via the linear mapping.]
- Inline instrumentation requires a fixed offset.
- Because of our running things in real mode, the offset has to
point to valid memory both in and out of real mode.
This makes finding somewhere to put the KASAN shadow region a bit fun.
One approach is just to give up on inline instrumentation and override
the address->shadow calculation. This way we can delay all checking
until after we get everything set up to our satisfaction. However,
we'd really like to do better.
What we can do - if we know _at compile time_ how much contiguous
physical memory we have - is to set aside the top 1/8th of the memory
and use that. This is a big hammer (hence the "heavyweight" name) and
comes with 3 big consequences:
- kernels will simply fail to boot on machines with less memory than
specified when compiling.
- kernels running on machines with more memory than specified when
compiling will simply ignore the extra memory.
- there's no nice way to handle physically discontiguous memory, so
you are restricted to the first physical memory block.
If you can bear all this, you get pretty full support for KASAN.
Despite the limitations, it can still find bugs,
e.g. http://patchwork.ozlabs.org/patch/1103775/
The current implementation is Radix only. I am open to extending
it to hash at some point but I don't think it should hold up v1.
Massive thanks to mpe, who had the idea for the initial design.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
Changes since the rfc:
- Boots real and virtual hardware, kvm works.
- disabled reporting when we're checking the stack for exception
frames. The behaviour isn't wrong, just incompatible with KASAN.
- Documentation!
- Dropped old module stuff in favour of KASAN_VMALLOC.
The bugs with ftrace and kuap were due to kernel bloat pushing
prom_init calls to be done via the plt. Because we did not have
a relocatable kernel, and they are done very early, this caused
everything to explode. Compile with CONFIG_RELOCATABLE!
---
Documentation/dev-tools/kasan.rst | 7 +-
Documentation/powerpc/kasan.txt | 111 +++++++++++++++++++
arch/powerpc/Kconfig | 4 +
arch/powerpc/Kconfig.debug | 21 ++++
arch/powerpc/Makefile | 7 ++
arch/powerpc/include/asm/book3s/64/radix.h | 5 +
arch/powerpc/include/asm/kasan.h | 35 +++++-
arch/powerpc/kernel/process.c | 8 ++
arch/powerpc/kernel/prom.c | 57 +++++++++-
arch/powerpc/mm/kasan/Makefile | 1 +
arch/powerpc/mm/kasan/kasan_init_book3s_64.c | 76 +++++++++++++
11 files changed, 326 insertions(+), 6 deletions(-)
create mode 100644 Documentation/powerpc/kasan.txt
create mode 100644 arch/powerpc/mm/kasan/kasan_init_book3s_64.c
diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst
index 35fda484a672..48d3b669e577 100644
--- a/Documentation/dev-tools/kasan.rst
+++ b/Documentation/dev-tools/kasan.rst
@@ -22,7 +22,9 @@ global variables yet.
Tag-based KASAN is only supported in Clang and requires version 7.0.0 or later.
Currently generic KASAN is supported for the x86_64, arm64, xtensa and s390
-architectures, and tag-based KASAN is supported only for arm64.
+architectures. It is also supported on powerpc for 32-bit kernels, and for
+64-bit kernels running under the radix MMU. Tag-based KASAN is supported only
+for arm64.
Usage
-----
@@ -252,7 +254,8 @@ CONFIG_KASAN_VMALLOC
~~~~~~~~~~~~~~~~~~~~
With ``CONFIG_KASAN_VMALLOC``, KASAN can cover vmalloc space at the
-cost of greater memory usage. Currently this is only supported on x86.
+cost of greater memory usage. Currently this is optional on x86, and
+required on 64-bit powerpc.
This works by hooking into vmalloc and vmap, and dynamically
allocating real shadow memory to back the mappings.
diff --git a/Documentation/powerpc/kasan.txt b/Documentation/powerpc/kasan.txt
new file mode 100644
index 000000000000..a5592454353b
--- /dev/null
+++ b/Documentation/powerpc/kasan.txt
@@ -0,0 +1,111 @@
+KASAN is supported on powerpc on 32-bit and 64-bit Radix only.
+
+32 bit support
+==============
+
+KASAN is supported on both hash and nohash MMUs on 32-bit.
+
+The shadow area sits at the top of the kernel virtual memory space above the
+fixmap area and occupies one eighth of the total kernel virtual memory space.
+
+Instrumentation of the vmalloc area is not currently supported, but modules are.
+
+64 bit support
+==============
+
+Currently, only the radix MMU is supported. There have been versions for Book3E
+processors floating around on the mailing list, but nothing has been merged.
+
+KASAN support on Book3S is interesting:
+
+ - We want to be able to support inline instrumentation so as to be able to
+ catch global and stack issues.
+
+ - Inline instrumentation requires a fixed offset.
+
+ - We run a lot of code at boot in real mode. This includes stuff like printk(),
+ so it's not feasible to just disable instrumentation around it.
+
+ - Because of our running things in real mode, the offset has to point to valid
+ memory both in and out of real mode.
+
+This makes finding somewhere to put the KASAN shadow region a bit fun.
+
+One approach is just to give up on inline instrumentation. This way we can delay
+all checks until after we get everything set up to our satisfaction. However,
+we'd really like to do better.
+
+If we know _at compile time_ how much contiguous physical memory we have, we can
+set aside the top 1/8th of physical memory and use that. This is a big hammer
+and comes with 2 big consequences:
+
+ - kernels will simply fail to boot on machines with less memory than specified
+ when compiling.
+
+ - kernels running on machines with more memory than specified when compiling
+ will simply ignore the extra memory.
+
+If you can live with this, you get full support for KASAN.
+
+Tips
+----
+
+ - Compile with CONFIG_RELOCATABLE.
+
+ In development, we found boot hangs when building with ftrace and KUAP. These
+ ended up being due to kernel bloat pushing prom_init calls to be done via the
+ PLT. Because we did not have a relocatable kernel, and they are done very
+ early, this caused us to jump off into somewhere invalid. Enabling relocation
+ fixes this.
+
+NUMA/discontiguous physical memory
+----------------------------------
+
+We currently cannot really deal with discontiguous physical memory. You are
+restricted to the physical memory that is contiguous from physical address zero,
+and must specify the size of that memory, not total memory, when configuring
+your kernel.
+
+Discontiguous memory can occur when you have a machine with memory spread across
+multiple nodes. For example, on a Talos II with 64GB of RAM:
+
+ - 32GB runs from 0x0 to 0x0000_0008_0000_0000,
+ - then there's a gap,
+ - then the final 32GB runs from 0x0000_2000_0000_0000 to 0x0000_2008_0000_0000.
+
+This can create _significant_ issues:
+
+ - If we try to treat the machine as having 64GB of _contiguous_ RAM, we would
+ assume that ran from 0x0 to 0x0000_0010_0000_0000. We'd then reserve the last
+ 1/8th - 0x0000_000e_0000_0000 to 0x0000_0010_0000_0000 as the shadow
+ region. But when we try to access any of that, we'll try to access pages that
+ are not physically present.
+
+ - If we try to base the shadow region size on the top address, we'll need to
+ reserve 0x2008_0000_0000 / 8 = 0x0401_0000_0000 bytes = 4100 GB of memory,
+ which will clearly not work on a system with 64GB of RAM.
+
+Therefore, you are restricted to the memory in the node starting at 0x0. For
+this system, that's 32GB. If you specify a contiguous physical memory size
+greater than the size of the first contiguous region of memory, the system will
+be unable to boot or even print an error message warning you.
+
+You can determine the layout of your system's memory by observing the messages
+that the Radix MMU prints on boot. The Talos II discussed earlier has:
+
+radix-mmu: Mapped 0x0000000000000000-0x0000000040000000 with 1.00 GiB pages (exec)
+radix-mmu: Mapped 0x0000000040000000-0x0000000800000000 with 1.00 GiB pages
+radix-mmu: Mapped 0x0000200000000000-0x0000200800000000 with 1.00 GiB pages
+
+As discussed, you'd configure this system for 32768 MB.
+
+Another system prints:
+
+radix-mmu: Mapped 0x0000000000000000-0x0000000040000000 with 1.00 GiB pages (exec)
+radix-mmu: Mapped 0x0000000040000000-0x0000002000000000 with 1.00 GiB pages
+radix-mmu: Mapped 0x0000200000000000-0x0000202000000000 with 1.00 GiB pages
+
+This machine has more memory: 0x0000_0040_0000_0000 total, but only
+0x0000_0020_0000_0000 is physically contiguous from zero, so we'd configure the
+kernel for 131072 MB of physically contiguous memory.
+
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index d8dcd8820369..3d6deee100e2 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -171,6 +171,10 @@ config PPC
select HAVE_ARCH_HUGE_VMAP if PPC_BOOK3S_64 && PPC_RADIX_MMU
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_KASAN if PPC32
+ select HAVE_ARCH_KASAN if PPC_BOOK3S_64 && PPC_RADIX_MMU
+ select ARCH_HAS_KASAN_EARLY_SHADOW if PPC_BOOK3S_64
+ select HAVE_ARCH_KASAN_VMALLOC if PPC_BOOK3S_64
+ select KASAN_VMALLOC if KASAN
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index c59920920ddc..2d6fb7b1ba59 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -394,6 +394,27 @@ config PPC_FAST_ENDIAN_SWITCH
help
If you're unsure what this is, say N.
+config PHYS_MEM_SIZE_FOR_KASAN
+ int "Contiguous physical memory size for KASAN (MB)"
+ depends on KASAN && PPC_BOOK3S_64
+ help
+
+ To get inline instrumentation support for KASAN on 64-bit Book3S
+ machines, you need to know how much contiguous physical memory your
+ system has. A shadow offset will be calculated based on this figure,
+ which will be compiled in to the kernel. KASAN will use this offset
+ to access its shadow region, which is used to verify memory accesses.
+
+ If you attempt to boot on a system with less memory than you specify
+ here, your system will fail to boot very early in the process. If you
+ boot on a system with more memory than you specify, the extra memory
+ will wasted - it will be reserved and not used.
+
+ For systems with discontiguous blocks of physical memory, specify the
+ size of the block starting at 0x0. You can determine this by looking
+ at the memory layout info printed to dmesg by the radix MMU code
+ early in boot. See Documentation/powerpc/kasan.txt.
+
config KASAN_SHADOW_OFFSET
hex
depends on KASAN
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index c345b79414a9..33e7bba4c8db 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -229,6 +229,13 @@ ifdef CONFIG_476FPE_ERR46
-T $(srctree)/arch/powerpc/platforms/44x/ppc476_modules.lds
endif
+ifdef CONFIG_KASAN
+ifdef CONFIG_PPC_BOOK3S_64
+# 0xa800000000000000 = 12105675798371893248
+KASAN_SHADOW_OFFSET = $(shell echo 7 \* 1024 \* 1024 \* $(CONFIG_PHYS_MEM_SIZE_FOR_KASAN) / 8 + 12105675798371893248 | bc)
+endif
+endif
+
# No AltiVec or VSX instructions when building kernel
KBUILD_CFLAGS += $(call cc-option,-mno-altivec)
KBUILD_CFLAGS += $(call cc-option,-mno-vsx)
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index e04a839cb5b9..4c011cc15e05 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -35,6 +35,11 @@
#define RADIX_PMD_SHIFT (PAGE_SHIFT + RADIX_PTE_INDEX_SIZE)
#define RADIX_PUD_SHIFT (RADIX_PMD_SHIFT + RADIX_PMD_INDEX_SIZE)
#define RADIX_PGD_SHIFT (RADIX_PUD_SHIFT + RADIX_PUD_INDEX_SIZE)
+
+#define R_PTRS_PER_PTE (1 << RADIX_PTE_INDEX_SIZE)
+#define R_PTRS_PER_PMD (1 << RADIX_PMD_INDEX_SIZE)
+#define R_PTRS_PER_PUD (1 << RADIX_PUD_INDEX_SIZE)
+
/*
* Size of EA range mapped by our pagetables.
*/
diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
index 296e51c2f066..d6b4028c296b 100644
--- a/arch/powerpc/include/asm/kasan.h
+++ b/arch/powerpc/include/asm/kasan.h
@@ -14,13 +14,20 @@
#ifndef __ASSEMBLY__
-#include <asm/page.h>
+#ifdef CONFIG_KASAN
+void kasan_init(void);
+#else
+static inline void kasan_init(void) { }
+#endif
#define KASAN_SHADOW_SCALE_SHIFT 3
#define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET + \
(PAGE_OFFSET >> KASAN_SHADOW_SCALE_SHIFT))
+#ifdef CONFIG_PPC32
+#include <asm/page.h>
+
#define KASAN_SHADOW_OFFSET ASM_CONST(CONFIG_KASAN_SHADOW_OFFSET)
#define KASAN_SHADOW_END 0UL
@@ -30,11 +37,33 @@
#ifdef CONFIG_KASAN
void kasan_early_init(void);
void kasan_mmu_init(void);
-void kasan_init(void);
#else
-static inline void kasan_init(void) { }
static inline void kasan_mmu_init(void) { }
#endif
+#endif
+
+#ifdef CONFIG_PPC_BOOK3S_64
+#include <asm/pgtable.h>
+
+/*
+ * The KASAN shadow offset is such that linear map (0xc000...) is shadowed by
+ * the last 8th of linearly mapped physical memory. This way, if the code uses
+ * 0xc addresses throughout, accesses work both in in real mode (where the top
+ * 2 bits are ignored) and outside of real mode.
+ */
+#define KASAN_SHADOW_OFFSET ((u64)CONFIG_PHYS_MEM_SIZE_FOR_KASAN * \
+ 1024 * 1024 * 7 / 8 + 0xa800000000000000UL)
+
+#define KASAN_SHADOW_SIZE ((u64)CONFIG_PHYS_MEM_SIZE_FOR_KASAN * \
+ 1024 * 1024 * 1 / 8)
+
+extern unsigned char kasan_early_shadow_page[PAGE_SIZE];
+
+extern pte_t kasan_early_shadow_pte[R_PTRS_PER_PTE];
+extern pmd_t kasan_early_shadow_pmd[R_PTRS_PER_PMD];
+extern pud_t kasan_early_shadow_pud[R_PTRS_PER_PUD];
+extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D];
+#endif /* CONFIG_PPC_BOOK3S_64 */
#endif /* __ASSEMBLY */
#endif
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 8fc4de0d22b4..31602536e72b 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -2097,7 +2097,14 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
/*
* See if this is an exception frame.
* We look for the "regshere" marker in the current frame.
+ *
+ * KASAN may complain about this. If it is an exception frame,
+ * we won't have unpoisoned the stack in asm when we set the
+ * exception marker. If it's not an exception frame, who knows
+ * how things are laid out - the shadow could be in any state
+ * at all. Just disable KASAN reporting for now.
*/
+ kasan_disable_current();
if (validate_sp(sp, tsk, STACK_INT_FRAME_SIZE)
&& stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
struct pt_regs *regs = (struct pt_regs *)
@@ -2107,6 +2114,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
regs->trap, (void *)regs->nip, (void *)lr);
firstframe = 1;
}
+ kasan_enable_current();
sp = newsp;
} while (count++ < kstack_depth_to_print);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 7159e791a70d..dde5f2896ab6 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -71,6 +71,7 @@ unsigned long tce_alloc_start, tce_alloc_end;
u64 ppc64_rma_size;
#endif
static phys_addr_t first_memblock_size;
+static phys_addr_t top_phys_addr;
static int __initdata boot_cpu_count;
static int __init early_parse_mem(char *p)
@@ -448,6 +449,21 @@ static bool validate_mem_limit(u64 base, u64 *size)
{
u64 max_mem = 1UL << (MAX_PHYSMEM_BITS);
+#ifdef CONFIG_KASAN
+ /*
+ * To handle the NUMA/discontiguous memory case, don't allow a block
+ * to be added if it falls completely beyond the configured physical
+ * memory.
+ *
+ * See Documentation/powerpc/kasan.txt
+ */
+ if (base >= (u64)CONFIG_PHYS_MEM_SIZE_FOR_KASAN * 1024 * 1024) {
+ pr_warn("KASAN: not adding mem block at %llx (size %llx)",
+ base, *size);
+ return false;
+ }
+#endif
+
if (base >= max_mem)
return false;
if ((base + *size) > max_mem)
@@ -571,8 +587,11 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
/* Add the chunk to the MEMBLOCK list */
if (add_mem_to_memblock) {
- if (validate_mem_limit(base, &size))
+ if (validate_mem_limit(base, &size)) {
memblock_add(base, size);
+ if (base + size > top_phys_addr)
+ top_phys_addr = base + size;
+ }
}
}
@@ -612,6 +631,8 @@ static void __init early_reserve_mem_dt(void)
static void __init early_reserve_mem(void)
{
__be64 *reserve_map;
+ phys_addr_t kasan_shadow_start __maybe_unused;
+ phys_addr_t kasan_memory_size __maybe_unused;
reserve_map = (__be64 *)(((unsigned long)initial_boot_params) +
fdt_off_mem_rsvmap(initial_boot_params));
@@ -650,6 +671,40 @@ static void __init early_reserve_mem(void)
return;
}
#endif
+
+#if defined(CONFIG_KASAN) && defined(CONFIG_PPC_BOOK3S_64)
+ kasan_memory_size = ((phys_addr_t)CONFIG_PHYS_MEM_SIZE_FOR_KASAN
+ * 1024 * 1024);
+
+ if (top_phys_addr < kasan_memory_size) {
+ /*
+ * We are doomed. Attempts to call e.g. panic() are likely to
+ * fail because they call out into instrumented code, which
+ * will almost certainly access memory beyond the end of
+ * physical memory. Hang here so that at least the NIP points
+ * somewhere that will help you debug it if you look at it in
+ * qemu.
+ */
+ while (true)
+ ;
+ } else if (top_phys_addr > kasan_memory_size) {
+ /* print a biiiig warning in hopes people notice */
+ pr_err("===========================================\n"
+ "Physical memory exceeds compiled-in maximum!\n"
+ "This kernel was compiled for KASAN with %u MB physical memory.\n"
+ "The actual physical memory detected is %llu MB.\n"
+ "Memory above the compiled limit will not be used!\n"
+ "===========================================\n",
+ CONFIG_PHYS_MEM_SIZE_FOR_KASAN,
+ top_phys_addr / (1024 * 1024));
+ }
+
+ kasan_shadow_start = _ALIGN_DOWN(kasan_memory_size * 7 / 8, PAGE_SIZE);
+ DBG("reserving %llx -> %llx for KASAN",
+ kasan_shadow_start, top_phys_addr);
+ memblock_reserve(kasan_shadow_start,
+ top_phys_addr - kasan_shadow_start);
+#endif
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
diff --git a/arch/powerpc/mm/kasan/Makefile b/arch/powerpc/mm/kasan/Makefile
index 6577897673dd..ff8143ba1e4d 100644
--- a/arch/powerpc/mm/kasan/Makefile
+++ b/arch/powerpc/mm/kasan/Makefile
@@ -3,3 +3,4 @@
KASAN_SANITIZE := n
obj-$(CONFIG_PPC32) += kasan_init_32.o
+obj-$(CONFIG_PPC_BOOK3S_64) += kasan_init_book3s_64.o
diff --git a/arch/powerpc/mm/kasan/kasan_init_book3s_64.c b/arch/powerpc/mm/kasan/kasan_init_book3s_64.c
new file mode 100644
index 000000000000..fafda3d5e9a3
--- /dev/null
+++ b/arch/powerpc/mm/kasan/kasan_init_book3s_64.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KASAN for 64-bit Book3S powerpc
+ *
+ * Copyright (C) 2019 IBM Corporation
+ * Author: Daniel Axtens <dja@axtens.net>
+ */
+
+#define DISABLE_BRANCH_PROFILING
+
+#include <linux/kasan.h>
+#include <linux/printk.h>
+#include <linux/sched/task.h>
+#include <asm/pgalloc.h>
+
+unsigned char kasan_early_shadow_page[PAGE_SIZE] __page_aligned_bss;
+
+pte_t kasan_early_shadow_pte[R_PTRS_PER_PTE] __page_aligned_bss;
+pmd_t kasan_early_shadow_pmd[R_PTRS_PER_PMD] __page_aligned_bss;
+pud_t kasan_early_shadow_pud[R_PTRS_PER_PUD] __page_aligned_bss;
+p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D] __page_aligned_bss;
+
+void __init kasan_init(void)
+{
+ int i;
+ void *k_start = kasan_mem_to_shadow((void *)RADIX_KERN_VIRT_START);
+ void *k_end = kasan_mem_to_shadow((void *)RADIX_VMEMMAP_END);
+
+ unsigned long pte_val = __pa(kasan_early_shadow_page)
+ | pgprot_val(PAGE_KERNEL) | _PAGE_PTE;
+
+ if (!early_radix_enabled())
+ panic("KASAN requires radix!");
+
+ for (i = 0; i < PTRS_PER_PTE; i++)
+ kasan_early_shadow_pte[i] = __pte(pte_val);
+
+ for (i = 0; i < PTRS_PER_PMD; i++)
+ pmd_populate_kernel(&init_mm, &kasan_early_shadow_pmd[i],
+ kasan_early_shadow_pte);
+
+ for (i = 0; i < PTRS_PER_PUD; i++)
+ pud_populate(&init_mm, &kasan_early_shadow_pud[i],
+ kasan_early_shadow_pmd);
+
+
+ memset(kasan_mem_to_shadow((void *)PAGE_OFFSET), KASAN_SHADOW_INIT,
+ KASAN_SHADOW_SIZE);
+
+ kasan_populate_early_shadow(
+ kasan_mem_to_shadow((void *)RADIX_KERN_VIRT_START),
+ kasan_mem_to_shadow((void *)RADIX_VMALLOC_START));
+
+ /* leave a hole here for vmalloc */
+
+ kasan_populate_early_shadow(
+ kasan_mem_to_shadow((void *)RADIX_VMALLOC_END),
+ kasan_mem_to_shadow((void *)RADIX_VMEMMAP_END));
+
+ flush_tlb_kernel_range((unsigned long)k_start, (unsigned long)k_end);
+
+ /* mark early shadow region as RO and wipe */
+ for (i = 0; i < PTRS_PER_PTE; i++)
+ __set_pte_at(&init_mm, (unsigned long)kasan_early_shadow_page,
+ &kasan_early_shadow_pte[i],
+ pfn_pte(virt_to_pfn(kasan_early_shadow_page),
+ __pgprot(_PAGE_PTE | _PAGE_KERNEL_RO | _PAGE_BASE)),
+ 0);
+ memset(kasan_early_shadow_page, 0, PAGE_SIZE);
+
+ kasan_init_tags();
+
+ /* Enable error messages */
+ init_task.kasan_depth = 0;
+ pr_info("KASAN init done (64-bit Book3S heavyweight mode)\n");
+}
--
2.20.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox