* Re: [PATCH v2] powerpc: setup_64: set up PACA earlier to avoid kcov problems
From: Christophe Leroy @ 2020-02-13 6:23 UTC (permalink / raw)
To: Daniel Axtens, linuxppc-dev; +Cc: ajd
In-Reply-To: <20200213052327.24207-1-dja@axtens.net>
Le 13/02/2020 à 06:23, Daniel Axtens a écrit :
> diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
> index e05e6dd67ae6..ef455da7efa3 100644
> --- a/arch/powerpc/kernel/setup_64.c
> +++ b/arch/powerpc/kernel/setup_64.c
> @@ -285,18 +285,25 @@ void __init early_setup(unsigned long dt_ptr)
>
> /* -------- printk is _NOT_ safe to use here ! ------- */
>
> - /* Try new device tree based feature discovery ... */
> - if (!dt_cpu_ftrs_init(__va(dt_ptr)))
> - /* Otherwise use the old style CPU table */
> - identify_cpu(0, mfspr(SPRN_PVR));
> + /* Assume we're on cpu 0 for now. Don't write to the paca yet!
> + *
> + * We need to load a PACA very early if we are using kcov. kcov will
> + * call in_task() in its instrumentation, which relies on the current
> + * task from the PACA. dt_cpu_ftrs_init is coveraged-enabled and also
> + * calls into the coverage-enabled generic dt library.
> + */
Checkpatch won't be happy I guess. For multiline comments, there should
be no text on the first line starting with /*
Christophe
^ permalink raw reply
* Re: [Regression 5.6-rc1][Bisected b6231ea2b3c6] Powerpc 8xx doesn't boot anymore
From: Christophe Leroy @ 2020-02-13 6:17 UTC (permalink / raw)
To: Qiang Zhao, Rasmus Villemoes, Leo Li, Greg Kroah-Hartman
Cc: Scott Wood, linuxppc-dev@lists.ozlabs.org, LKML,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <VE1PR04MB6768B3B0F369280338370B87911A0@VE1PR04MB6768.eurprd04.prod.outlook.com>
Le 13/02/2020 à 04:35, Qiang Zhao a écrit :
> On 02/12/2020 22:50 PM, Christophe Leroy wrote:
>> -----Original Message-----
>> From: Christophe Leroy <christophe.leroy@c-s.fr>
>> Sent: 2020年2月12日 22:50
>> To: Rasmus Villemoes <linux@rasmusvillemoes.dk>; Leo Li
>> <leoyang.li@nxp.com>; Qiang Zhao <qiang.zhao@nxp.com>; Greg
>> Kroah-Hartman <gregkh@linuxfoundation.org>
>> Cc: Scott Wood <oss@buserror.net>; linuxppc-dev@lists.ozlabs.org; LKML
>> <linux-kernel@vger.kernel.org>; linux-arm-kernel@lists.infradead.org
>> Subject: Re: [Regression 5.6-rc1][Bisected b6231ea2b3c6] Powerpc 8xx doesn't
>> boot anymore
>>
>> ---
>> diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
>> b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
>> index 4cabded8390b..341d682ec6eb 100644
>> --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
>> +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
>> @@ -1351,6 +1351,7 @@ static int __init cpm_uart_console_setup(struct
>> console *co, char *options)
>> clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR |
>> SCC_GSMRL_ENT);
>> }
>>
>> + cpm_muram_init();
>> ret = cpm_uart_allocbuf(pinfo, 1);
>>
>> if (ret)
>>
> How about the patch like below? Just a draft.
Yes, I see the idea. I think we could go for something like that.
But in the powerpc 8xx case, we are talking about cpm_init(), not qe_init().
And maybe the return code should be checked, because if it's not 0,
cpm_muram_init() won't have been called.
Thanks,
Christophe
^ permalink raw reply
* Re: [PATCH v7 4/4] powerpc: Book3S 64-bit "heavyweight" KASAN support
From: Christophe Leroy @ 2020-02-13 6:08 UTC (permalink / raw)
To: Daniel Axtens, linux-kernel, linux-mm, linuxppc-dev, kasan-dev,
aneesh.kumar, bsingharora
In-Reply-To: <20200213004752.11019-5-dja@axtens.net>
Le 13/02/2020 à 01:47, Daniel Axtens a écrit :
> KASAN support on Book3S is a bit tricky to get right:
>
> - It would be good to support inline instrumentation so as to be able to
> catch stack issues that cannot be caught with outline mode.
>
> - Inline instrumentation requires a fixed offset.
>
> - Book3S runs code in real mode after booting. Most notably a lot of KVM
> runs in real mode, and it would be good to be able to instrument it.
>
> - Because code runs in real mode after boot, the offset has to point to
> valid memory both in and out of real mode.
>
> [ppc64 mm note: The kernel installs a linear mapping at effective
> address c000... onward. This is a one-to-one mapping with physical
> memory from 0000... onward. Because of how memory accesses work on
> powerpc 64-bit Book3S, a kernel pointer in the linear map accesses the
> same memory both with translations on (accessing as an 'effective
> address'), and with translations off (accessing as a 'real
> address'). This works in both guests and the hypervisor. For more
> details, see s5.7 of Book III of version 3 of the ISA, in particular
> the Storage Control Overview, s5.7.3, and s5.7.5 - noting that this
> KASAN implementation currently only supports Radix.]
>
> One approach is just to give up on inline instrumentation. This way all
> checks can be delayed until after everything set is up correctly, and the
> address-to-shadow calculations can be overridden. However, the features and
> speed boost provided by inline instrumentation are worth trying to do
> better.
>
> If _at compile time_ it is known how much contiguous physical memory a
> system has, the top 1/8th of the first block of physical memory can be set
> aside for the shadow. This is a big hammer and comes with 3 big
> consequences:
>
> - there's no nice way to handle physically discontiguous memory, so only
> the first physical memory block can be used.
>
> - 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.
>
> Implement and document KASAN this way. The current implementation is Radix
> only.
>
> Despite the limitations, it can still find bugs,
> e.g. http://patchwork.ozlabs.org/patch/1103775/
>
> At the moment, this physical memory limit must be set _even for outline
> mode_. This may be changed in a later series - a different implementation
> could be added for outline mode that dynamically allocates shadow at a
> fixed offset. For example, see https://patchwork.ozlabs.org/patch/795211/
>
> Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Balbir Singh <bsingharora@gmail.com> # ppc64 out-of-line radix version
> Cc: Christophe Leroy <christophe.leroy@c-s.fr> # ppc32 version
> Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: <christophe.leroy@c-s.fr> # focussed mainly on
Documentation and things impacting PPC32
^ permalink raw reply
* [PATCH v2] powerpc: setup_64: set up PACA earlier to avoid kcov problems
From: Daniel Axtens @ 2020-02-13 5:23 UTC (permalink / raw)
To: linuxppc-dev; +Cc: ajd, Daniel Axtens
kcov instrumentation is collected the __sanitizer_cov_trace_pc hook in
kernel/kcov.c. The compiler inserts these hooks into every basic block
unless kcov is disabled for that file.
We then have a deep call-chain:
- __sanitizer_cov_trace_pc calls to check_kcov_mode()
- check_kcov_mode() (kernel/kcov.c) calls in_task()
- in_task() (include/linux/preempt.h) calls preempt_count().
- preempt_count() (include/asm-generic/preempt.h) calls
current_thread_info()
- because powerpc has THREAD_INFO_IN_TASK, current_thread_info()
(include/linux/thread_info.h) is defined to 'current'
- current (arch/powerpc/include/asm/current.h) is defined to
get_current().
- get_current (same file) loads an offset of r13.
- arch/powerpc/include/asm/paca.h makes r13 a register variable
called local_paca - it is the PACA for the current CPU, so
this has the effect of loading the current task from PACA.
- get_current returns the current task from PACA,
- current_thread_info returns the task cast to a thread_info
- preempt_count dereferences the thread_info to load preempt_count
- that value is used by in_task and so on up the chain
The problem is:
- kcov instrumentation is enabled for arch/powerpc/kernel/dt_cpu_ftrs.c
- even if it were not, dt_cpu_ftrs_init calls generic dt parsing code
which should definitely have instrumentation enabled.
- setup_64.c calls dt_cpu_ftrs_init before it sets up a PACA.
- If we don't set up a paca, r13 will contain unpredictable data.
- In a zImage compiled with kcov and KASAN, we see r13 containing a value
that leads to dereferencing invalid memory (something like
912a72603d420015).
- Weirdly, the same kernel as a vmlinux loaded directly by qemu does not
crash. Investigating with gdb, it seems that in the vmlinux boot case,
r13 is near enough to zero that we just happen to be able to read that
part of memory (we're operating with translation off at this point) and
the current pointer also happens to land in readable memory and
everything just works.
- PACA setup refers to CPU features - setup_paca() looks at
early_cpu_has_feature(CPU_FTR_HVMODE)
There's no generic kill switch for kcov (as far as I can tell), and we
don't want to have to turn off instrumentation in the generic dt parsing
code (which lives outside arch/powerpc/) just because we don't have a real
paca or task yet.
So:
- change the test when setting up a PACA to consider the actual value of
the MSR rather than the CPU feature.
- move the PACA setup to before the cpu feature parsing.
Translations get switched on once we leave early_setup, so I think we'd
already catch any other cases where the PACA or task aren't set up.
Boot tested on a P9 guest and host.
Fixes: fb0b0a73b223 ("powerpc: Enable kcov")
Cc: Andrew Donnellan <ajd@linux.ibm.com>
Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
Regarding moving the comment about printk()-safety:
I am about 75% sure that the thing that makes printk() safe is the PACA,
not the CPU features. That's what commit 24d9649574fb ("[POWERPC] Document
when printk is useable") seems to indicate, but as someone wise recently
told me, "bootstrapping is hard", so I may be totally wrong.
---
arch/powerpc/kernel/paca.c | 2 +-
arch/powerpc/kernel/setup_64.c | 17 ++++++++++++-----
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 949eceb254d8..347e947b9d4b 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -218,7 +218,7 @@ void setup_paca(struct paca_struct *new_paca)
* if we do a GET_PACA() before the feature fixups have been
* applied
*/
- if (early_cpu_has_feature(CPU_FTR_HVMODE))
+ if (mfmsr() & MSR_HV)
mtspr(SPRN_SPRG_HPACA, local_paca);
#endif
mtspr(SPRN_SPRG_PACA, local_paca);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e05e6dd67ae6..ef455da7efa3 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -285,18 +285,25 @@ void __init early_setup(unsigned long dt_ptr)
/* -------- printk is _NOT_ safe to use here ! ------- */
- /* Try new device tree based feature discovery ... */
- if (!dt_cpu_ftrs_init(__va(dt_ptr)))
- /* Otherwise use the old style CPU table */
- identify_cpu(0, mfspr(SPRN_PVR));
+ /* Assume we're on cpu 0 for now. Don't write to the paca yet!
+ *
+ * We need to load a PACA very early if we are using kcov. kcov will
+ * call in_task() in its instrumentation, which relies on the current
+ * task from the PACA. dt_cpu_ftrs_init is coveraged-enabled and also
+ * calls into the coverage-enabled generic dt library.
+ */
- /* Assume we're on cpu 0 for now. Don't write to the paca yet! */
initialise_paca(&boot_paca, 0);
setup_paca(&boot_paca);
fixup_boot_paca();
/* -------- printk is now safe to use ------- */
+ /* Try new device tree based feature discovery ... */
+ if (!dt_cpu_ftrs_init(__va(dt_ptr)))
+ /* Otherwise use the old style CPU table */
+ identify_cpu(0, mfspr(SPRN_PVR));
+
/* Enable early debugging if any specified (see udbg.h) */
udbg_early_init();
--
2.20.1
^ permalink raw reply related
* RE: [Regression 5.6-rc1][Bisected b6231ea2b3c6] Powerpc 8xx doesn't boot anymore
From: Qiang Zhao @ 2020-02-13 3:35 UTC (permalink / raw)
To: Christophe Leroy, Rasmus Villemoes, Leo Li, Greg Kroah-Hartman
Cc: Scott Wood, linuxppc-dev@lists.ozlabs.org, LKML,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <aee10440-c244-7c93-d3bb-fd29d8a83be4@c-s.fr>
On 02/12/2020 22:50 PM, Christophe Leroy wrote:
> -----Original Message-----
> From: Christophe Leroy <christophe.leroy@c-s.fr>
> Sent: 2020年2月12日 22:50
> To: Rasmus Villemoes <linux@rasmusvillemoes.dk>; Leo Li
> <leoyang.li@nxp.com>; Qiang Zhao <qiang.zhao@nxp.com>; Greg
> Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Scott Wood <oss@buserror.net>; linuxppc-dev@lists.ozlabs.org; LKML
> <linux-kernel@vger.kernel.org>; linux-arm-kernel@lists.infradead.org
> Subject: Re: [Regression 5.6-rc1][Bisected b6231ea2b3c6] Powerpc 8xx doesn't
> boot anymore
>
> ---
> diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
> b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
> index 4cabded8390b..341d682ec6eb 100644
> --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
> +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
> @@ -1351,6 +1351,7 @@ static int __init cpm_uart_console_setup(struct
> console *co, char *options)
> clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR |
> SCC_GSMRL_ENT);
> }
>
> + cpm_muram_init();
> ret = cpm_uart_allocbuf(pinfo, 1);
>
> if (ret)
>
How about the patch like below? Just a draft.
diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
index 96c2057..c5c2464 100644
--- a/drivers/soc/fsl/qe/qe.c
+++ b/drivers/soc/fsl/qe/qe.c
@@ -29,6 +29,8 @@
#include <soc/fsl/qe/immap_qe.h>
#include <soc/fsl/qe/qe.h>
+static int qe_inited;
+
static void qe_snums_init(void);
static int qe_sdma_init(void);
@@ -637,15 +639,19 @@ unsigned int qe_get_num_of_snums(void)
}
EXPORT_SYMBOL(qe_get_num_of_snums);
-static int __init qe_init(void)
+int __init qe_init(void)
{
struct device_node *np;
+ if(qe_inited)
+ return 0;
+
np = of_find_compatible_node(NULL, NULL, "fsl,qe");
if (!np)
return -ENODEV;
qe_reset();
of_node_put(np);
+ qe_inited = 1
return 0;
}
subsys_initcall(qe_init);
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
index 19d5a4c..cbf2c32 100644
--- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
@@ -1373,6 +1373,7 @@ static struct console cpm_scc_uart_console = {
static int __init cpm_uart_console_init(void)
{
+ qe_init();
register_console(&cpm_scc_uart_console);
return 0;
}
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h
index e282ac0..531ba05 100644
--- a/include/soc/fsl/qe/qe.h
+++ b/include/soc/fsl/qe/qe.h
@@ -88,6 +88,7 @@ static inline bool qe_clock_is_brg(enum qe_clock clk)
extern spinlock_t cmxgcr_lock;
+int __init qe_init(void);
/* Export QE common operations */
#ifdef CONFIG_QUICC_ENGINE
extern void qe_reset(void);
Best Regards
Qiang Zhao
^ permalink raw reply related
* Re: [PATCH v3 0/6] implement KASLR for powerpc/fsl_booke/64
From: Jason Yan @ 2020-02-13 3:00 UTC (permalink / raw)
To: mpe, linuxppc-dev, diana.craciun, christophe.leroy, benh, paulus,
npiggin, keescook, kernel-hardening, oss
Cc: linux-kernel, zhaohongjiang
In-Reply-To: <20200206025825.22934-1-yanaijie@huawei.com>
Hi everyone, any comments or suggestions?
Thanks,
Jason
on 2020/2/6 10:58, Jason Yan wrote:
> This is a try to implement KASLR for Freescale BookE64 which is based on
> my earlier implementation for Freescale BookE32:
> https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=131718
>
> The implementation for Freescale BookE64 is similar as BookE32. One
> difference is that Freescale BookE64 set up a TLB mapping of 1G during
> booting. Another difference is that ppc64 needs the kernel to be
> 64K-aligned. So we can randomize the kernel in this 1G mapping and make
> it 64K-aligned. This can save some code to creat another TLB map at
> early boot. The disadvantage is that we only have about 1G/64K = 16384
> slots to put the kernel in.
>
> KERNELBASE
>
> 64K |--> kernel <--|
> | | |
> +--+--+--+ +--+--+--+--+--+--+--+--+--+ +--+--+
> | | | |....| | | | | | | | | |....| | |
> +--+--+--+ +--+--+--+--+--+--+--+--+--+ +--+--+
> | | 1G
> |-----> offset <-----|
>
> kernstart_virt_addr
>
> I'm not sure if the slot numbers is enough or the design has any
> defects. If you have some better ideas, I would be happy to hear that.
>
> Thank you all.
>
> v2->v3:
> Fix build error when KASLR is disabled.
> v1->v2:
> Add __kaslr_offset for the secondary cpu boot up.
>
> Jason Yan (6):
> powerpc/fsl_booke/kaslr: refactor kaslr_legal_offset() and
> kaslr_early_init()
> powerpc/fsl_booke/64: introduce reloc_kernel_entry() helper
> powerpc/fsl_booke/64: implement KASLR for fsl_booke64
> powerpc/fsl_booke/64: do not clear the BSS for the second pass
> powerpc/fsl_booke/64: clear the original kernel if randomized
> powerpc/fsl_booke/kaslr: rename kaslr-booke32.rst to kaslr-booke.rst
> and add 64bit part
>
> .../{kaslr-booke32.rst => kaslr-booke.rst} | 35 +++++++--
> arch/powerpc/Kconfig | 2 +-
> arch/powerpc/kernel/exceptions-64e.S | 23 ++++++
> arch/powerpc/kernel/head_64.S | 14 ++++
> arch/powerpc/kernel/setup_64.c | 4 +-
> arch/powerpc/mm/mmu_decl.h | 19 ++---
> arch/powerpc/mm/nohash/kaslr_booke.c | 71 +++++++++++++------
> 7 files changed, 132 insertions(+), 36 deletions(-)
> rename Documentation/powerpc/{kaslr-booke32.rst => kaslr-booke.rst} (59%)
>
^ permalink raw reply
* Re: [PATCH V12] mm/debug: Add tests validating architecture page table helpers
From: Anshuman Khandual @ 2020-02-13 2:15 UTC (permalink / raw)
To: Gerald Schaefer
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra,
Catalin Marinas, Heiko Carstens, Michal Hocko, linux-mm,
Paul Mackerras, sparclinux, Ingo Molnar, linux-s390,
Jason Gunthorpe, x86, Russell King - ARM Linux, Matthew Wilcox,
Steven Price, Tetsuo Handa, Vlastimil Babka, James Hogan,
linux-snps-arc, Kees Cook, Masahiro Yamada, Dan Williams,
Mark Brown, Kirill A . Shutemov, Thomas Gleixner,
linux-arm-kernel, Sri Krishna chowdary, Dave Hansen,
Greg Kroah-Hartman, Ard Biesheuvel, linux-mips, Ralf Baechle,
linux-kernel, Paul Burton, Mike Rapoport, Vineet Gupta,
Martin Schwidefsky, Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <20200212185548.3274ec2e@thinkpad>
On 02/12/2020 11:25 PM, Gerald Schaefer wrote:
> On Wed, 12 Feb 2020 15:12:54 +0530
> Anshuman Khandual <anshuman.khandual@arm.com> wrote:
>
>>>> +/*
>>>> + * On s390 platform, the lower 12 bits are used to identify given page table
>>>> + * entry type and for other arch specific requirements. But these bits might
>>>> + * affect the ability to clear entries with pxx_clear(). So while loading up
>>>> + * the entries skip all lower 12 bits in order to accommodate s390 platform.
>>>> + * It does not have affect any other platform.
>>>> + */
>>>> +#define RANDOM_ORVALUE (0xfffffffffffff000UL)
>>>
>>> I'd suggest you generate this mask with something like
>>> GENMASK(BITS_PER_LONG, PAGE_SHIFT).
>>
>> IIRC the lower 12 bits constrains on s390 platform might not be really related
>> to it's PAGE_SHIFT which can be a variable, but instead just a constant number.
>> But can definitely use GENMASK or it's variants here.
>>
>> https://lkml.org/lkml/2019/9/5/862
>
> PAGE_SHIFT would be fine, it is 12 on s390. However, in order to be
> more precise, we do not really need all 12 bits, only the last 4 bits.
> So, something like this would work:
>
> #define RANDOM_ORVALUE GENMASK(BITS_PER_LONG - 1, 4)
>
> The text in the comment could then also be changed from 12 to 4, and
> be a bit more specific on the fact that the impact on pxx_clear()
> results from the dynamic page table folding logic on s390:
>
> /*
> * On s390 platform, the lower 4 bits are used to identify given page table
> * entry type. But these bits might affect the ability to clear entries with
> * pxx_clear() because of how dynamic page table folding works on s390. So
> * while loading up the entries do not change the lower 4 bits.
> * It does not have affect any other platform.
> */
Sure, will update accordingly.
^ permalink raw reply
* Re: [alsa-devel] [PATCH 2/3] ASoC: dt-bindings: fsl_easrc: Add document for EASRC
From: Shengjiu Wang @ 2020-02-13 2:10 UTC (permalink / raw)
To: Fabio Estevam
Cc: Mark Rutland,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Linux-ALSA, Timur Tabi, Xiubo Li, Liam Girdwood, Shengjiu Wang,
linux-kernel, Takashi Iwai, Nicolin Chen, Rob Herring, Mark Brown,
linuxppc-dev
In-Reply-To: <CAOMZO5Do=dzh4WXvm44mB7-PeesWuA6qRtMXwHCH9piXd1dZEw@mail.gmail.com>
Hi
On Thu, Feb 13, 2020 at 1:26 AM Fabio Estevam <festevam@gmail.com> wrote:
>
> On Wed, Feb 12, 2020 at 1:35 AM Shengjiu Wang <shengjiu.wang@nxp.com> wrote:
> >
> > EASRC (Enhanced Asynchronous Sample Rate Converter) is a new
> > IP module found on i.MX815.
>
> i.MX815 in an internal terminology. Please avoid it on the commit log.
>
Ok, will use i.MX8MN instead.
^ permalink raw reply
* [PATCH v2 4/4] libnvdimm/region: Introduce an 'align' attribute
From: Dan Williams @ 2020-02-13 0:48 UTC (permalink / raw)
To: linux-nvdimm
Cc: Aneesh Kumar K.V, Jeff Moyer, linuxppc-dev, linux-kernel,
vishal.l.verma
In-Reply-To: <158155489850.3343782.2687127373754434980.stgit@dwillia2-desk3.amr.corp.intel.com>
The align attribute applies an alignment constraint for namespace
creation in a region. Whereas the 'align' attribute of a namespace
applied alignment padding via an info block, the 'align' attribute
applies alignment constraints to the free space allocation.
The default for 'align' is the maximum known memremap_compat_align()
across all archs (16MiB from PowerPC at time of writing) multiplied by
the number of interleave ways if there is blk-aliasing. The minimum is
PAGE_SIZE and allows for the creation of cross-arch incompatible
namespaces, just as previous kernels allowed, but the expectation is
cross-arch and mode-independent compatibility by default.
The regression risk with this change is limited to cases that were
dependent on the ability to create unaligned namespaces, *and* for some
reason are unable to opt-out of aligned namespaces by writing to
'regionX/align'. If such a scenario arises the default can be flipped
from opt-out to opt-in of compat-aligned namespace creation, but that is
a last resort. The kernel will otherwise continue to support existing
defined misaligned namespaces.
Unfortunately this change needs to touch several parts of the
implementation at once:
- region/available_size: expand busy extents to current align
- region/max_available_extent: expand busy extents to current align
- namespace/size: trim free space to current align
...to keep the free space accounting conforming to the dynamic align
setting.
Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Reported-by: Jeff Moyer <jmoyer@redhat.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Link: https://lore.kernel.org/r/158041478371.3889308.14542630147672668068.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/nvdimm/dimm_devs.c | 86 +++++++++++++++++++++++----
drivers/nvdimm/namespace_devs.c | 9 ++-
drivers/nvdimm/nd.h | 1
drivers/nvdimm/region_devs.c | 122 ++++++++++++++++++++++++++++++++++++---
4 files changed, 192 insertions(+), 26 deletions(-)
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index 64159d4d4b8f..b4994abb655f 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -563,6 +563,21 @@ int nvdimm_security_freeze(struct nvdimm *nvdimm)
return rc;
}
+static unsigned long dpa_align(struct nd_region *nd_region)
+{
+ struct device *dev = &nd_region->dev;
+
+ if (dev_WARN_ONCE(dev, !is_nvdimm_bus_locked(dev),
+ "bus lock required for capacity provision\n"))
+ return 0;
+ if (dev_WARN_ONCE(dev, !nd_region->ndr_mappings || nd_region->align
+ % nd_region->ndr_mappings,
+ "invalid region align %#lx mappings: %d\n",
+ nd_region->align, nd_region->ndr_mappings))
+ return 0;
+ return nd_region->align / nd_region->ndr_mappings;
+}
+
int alias_dpa_busy(struct device *dev, void *data)
{
resource_size_t map_end, blk_start, new;
@@ -571,6 +586,7 @@ int alias_dpa_busy(struct device *dev, void *data)
struct nd_region *nd_region;
struct nvdimm_drvdata *ndd;
struct resource *res;
+ unsigned long align;
int i;
if (!is_memory(dev))
@@ -608,13 +624,21 @@ int alias_dpa_busy(struct device *dev, void *data)
* Find the free dpa from the end of the last pmem allocation to
* the end of the interleave-set mapping.
*/
+ align = dpa_align(nd_region);
+ if (!align)
+ return 0;
+
for_each_dpa_resource(ndd, res) {
+ resource_size_t start, end;
+
if (strncmp(res->name, "pmem", 4) != 0)
continue;
- if ((res->start >= blk_start && res->start < map_end)
- || (res->end >= blk_start
- && res->end <= map_end)) {
- new = max(blk_start, min(map_end + 1, res->end + 1));
+
+ start = ALIGN_DOWN(res->start, align);
+ end = ALIGN(res->end + 1, align) - 1;
+ if ((start >= blk_start && start < map_end)
+ || (end >= blk_start && end <= map_end)) {
+ new = max(blk_start, min(map_end, end) + 1);
if (new != blk_start) {
blk_start = new;
goto retry;
@@ -654,6 +678,7 @@ resource_size_t nd_blk_available_dpa(struct nd_region *nd_region)
.res = NULL,
};
struct resource *res;
+ unsigned long align;
if (!ndd)
return 0;
@@ -661,10 +686,20 @@ resource_size_t nd_blk_available_dpa(struct nd_region *nd_region)
device_for_each_child(&nvdimm_bus->dev, &info, alias_dpa_busy);
/* now account for busy blk allocations in unaliased dpa */
+ align = dpa_align(nd_region);
+ if (!align)
+ return 0;
for_each_dpa_resource(ndd, res) {
+ resource_size_t start, end, size;
+
if (strncmp(res->name, "blk", 3) != 0)
continue;
- info.available -= resource_size(res);
+ start = ALIGN_DOWN(res->start, align);
+ end = ALIGN(res->end + 1, align) - 1;
+ size = end - start + 1;
+ if (size >= info.available)
+ return 0;
+ info.available -= size;
}
return info.available;
@@ -683,19 +718,31 @@ resource_size_t nd_pmem_max_contiguous_dpa(struct nd_region *nd_region,
struct nvdimm_bus *nvdimm_bus;
resource_size_t max = 0;
struct resource *res;
+ unsigned long align;
/* if a dimm is disabled the available capacity is zero */
if (!ndd)
return 0;
+ align = dpa_align(nd_region);
+ if (!align)
+ return 0;
+
nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
if (__reserve_free_pmem(&nd_region->dev, nd_mapping->nvdimm))
return 0;
for_each_dpa_resource(ndd, res) {
+ resource_size_t start, end;
+
if (strcmp(res->name, "pmem-reserve") != 0)
continue;
- if (resource_size(res) > max)
- max = resource_size(res);
+ /* trim free space relative to current alignment setting */
+ start = ALIGN(res->start, align);
+ end = ALIGN_DOWN(res->end + 1, align) - 1;
+ if (end < start)
+ continue;
+ if (end - start + 1 > max)
+ max = end - start + 1;
}
release_free_pmem(nvdimm_bus, nd_mapping);
return max;
@@ -723,24 +770,33 @@ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
struct resource *res;
const char *reason;
+ unsigned long align;
if (!ndd)
return 0;
+ align = dpa_align(nd_region);
+ if (!align)
+ return 0;
+
map_start = nd_mapping->start;
map_end = map_start + nd_mapping->size - 1;
blk_start = max(map_start, map_end + 1 - *overlap);
for_each_dpa_resource(ndd, res) {
- if (res->start >= map_start && res->start < map_end) {
+ resource_size_t start, end;
+
+ start = ALIGN_DOWN(res->start, align);
+ end = ALIGN(res->end + 1, align) - 1;
+ if (start >= map_start && start < map_end) {
if (strncmp(res->name, "blk", 3) == 0)
blk_start = min(blk_start,
- max(map_start, res->start));
- else if (res->end > map_end) {
+ max(map_start, start));
+ else if (end > map_end) {
reason = "misaligned to iset";
goto err;
} else
- busy += resource_size(res);
- } else if (res->end >= map_start && res->end <= map_end) {
+ busy += end - start + 1;
+ } else if (end >= map_start && end <= map_end) {
if (strncmp(res->name, "blk", 3) == 0) {
/*
* If a BLK allocation overlaps the start of
@@ -749,8 +805,8 @@ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
*/
blk_start = map_start;
} else
- busy += resource_size(res);
- } else if (map_start > res->start && map_start < res->end) {
+ busy += end - start + 1;
+ } else if (map_start > start && map_start < end) {
/* total eclipse of the mapping */
busy += nd_mapping->size;
blk_start = map_start;
@@ -760,7 +816,7 @@ resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
*overlap = map_end + 1 - blk_start;
available = blk_start - map_start;
if (busy < available)
- return available - busy;
+ return ALIGN_DOWN(available - busy, align);
return 0;
err:
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 30cda9f235de..4720ad69e1c5 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -541,6 +541,11 @@ static void space_valid(struct nd_region *nd_region, struct nvdimm_drvdata *ndd,
{
bool is_reserve = strcmp(label_id->id, "pmem-reserve") == 0;
bool is_pmem = strncmp(label_id->id, "pmem", 4) == 0;
+ unsigned long align;
+
+ align = nd_region->align / nd_region->ndr_mappings;
+ valid->start = ALIGN(valid->start, align);
+ valid->end = ALIGN_DOWN(valid->end + 1, align) - 1;
if (valid->start >= valid->end)
goto invalid;
@@ -980,10 +985,10 @@ static ssize_t __size_store(struct device *dev, unsigned long long val)
return -ENXIO;
}
- div_u64_rem(val, PAGE_SIZE * nd_region->ndr_mappings, &remainder);
+ div_u64_rem(val, nd_region->align, &remainder);
if (remainder) {
dev_dbg(dev, "%llu is not %ldK aligned\n", val,
- (PAGE_SIZE * nd_region->ndr_mappings) / SZ_1K);
+ nd_region->align / SZ_1K);
return -EINVAL;
}
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index ca39abe29c7c..c4d69c1cce55 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -146,6 +146,7 @@ struct nd_region {
struct device *btt_seed;
struct device *pfn_seed;
struct device *dax_seed;
+ unsigned long align;
u16 ndr_mappings;
u64 ndr_size;
u64 ndr_start;
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index a5fc6e4c56ff..bf239e783940 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -216,21 +216,25 @@ int nd_region_to_nstype(struct nd_region *nd_region)
}
EXPORT_SYMBOL(nd_region_to_nstype);
-static ssize_t size_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static unsigned long long region_size(struct nd_region *nd_region)
{
- struct nd_region *nd_region = to_nd_region(dev);
- unsigned long long size = 0;
-
- if (is_memory(dev)) {
- size = nd_region->ndr_size;
+ if (is_memory(&nd_region->dev)) {
+ return nd_region->ndr_size;
} else if (nd_region->ndr_mappings == 1) {
struct nd_mapping *nd_mapping = &nd_region->mapping[0];
- size = nd_mapping->size;
+ return nd_mapping->size;
}
- return sprintf(buf, "%llu\n", size);
+ return 0;
+}
+
+static ssize_t size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct nd_region *nd_region = to_nd_region(dev);
+
+ return sprintf(buf, "%llu\n", region_size(nd_region));
}
static DEVICE_ATTR_RO(size);
@@ -529,6 +533,55 @@ static ssize_t read_only_store(struct device *dev,
}
static DEVICE_ATTR_RW(read_only);
+static ssize_t align_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct nd_region *nd_region = to_nd_region(dev);
+
+ return sprintf(buf, "%#lx\n", nd_region->align);
+}
+
+static ssize_t align_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ struct nd_region *nd_region = to_nd_region(dev);
+ unsigned long val, dpa;
+ u32 remainder;
+ int rc;
+
+ rc = kstrtoul(buf, 0, &val);
+ if (rc)
+ return rc;
+
+ if (!nd_region->ndr_mappings)
+ return -ENXIO;
+
+ /*
+ * Ensure space-align is evenly divisible by the region
+ * interleave-width because the kernel typically has no facility
+ * to determine which DIMM(s), dimm-physical-addresses, would
+ * contribute to the tail capacity in system-physical-address
+ * space for the namespace.
+ */
+ dpa = val;
+ remainder = do_div(dpa, nd_region->ndr_mappings);
+ if (!is_power_of_2(dpa) || dpa < PAGE_SIZE
+ || val > region_size(nd_region) || remainder)
+ return -EINVAL;
+
+ /*
+ * Given that space allocation consults this value multiple
+ * times ensure it does not change for the duration of the
+ * allocation.
+ */
+ nvdimm_bus_lock(dev);
+ nd_region->align = val;
+ nvdimm_bus_unlock(dev);
+
+ return len;
+}
+static DEVICE_ATTR_RW(align);
+
static ssize_t region_badblocks_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -571,6 +624,7 @@ static DEVICE_ATTR_RO(persistence_domain);
static struct attribute *nd_region_attributes[] = {
&dev_attr_size.attr,
+ &dev_attr_align.attr,
&dev_attr_nstype.attr,
&dev_attr_mappings.attr,
&dev_attr_btt_seed.attr,
@@ -626,6 +680,19 @@ static umode_t region_visible(struct kobject *kobj, struct attribute *a, int n)
return a->mode;
}
+ if (a == &dev_attr_align.attr) {
+ int i;
+
+ for (i = 0; i < nd_region->ndr_mappings; i++) {
+ struct nd_mapping *nd_mapping = &nd_region->mapping[i];
+ struct nvdimm *nvdimm = nd_mapping->nvdimm;
+
+ if (test_bit(NDD_LABELING, &nvdimm->flags))
+ return a->mode;
+ }
+ return 0;
+ }
+
if (a != &dev_attr_set_cookie.attr
&& a != &dev_attr_available_size.attr)
return a->mode;
@@ -935,6 +1002,42 @@ void nd_region_release_lane(struct nd_region *nd_region, unsigned int lane)
}
EXPORT_SYMBOL(nd_region_release_lane);
+/*
+ * PowerPC requires this alignment for memremap_pages(). All other archs
+ * should be ok with SUBSECTION_SIZE (see memremap_compat_align()).
+ */
+#define MEMREMAP_COMPAT_ALIGN_MAX SZ_16M
+
+static unsigned long default_align(struct nd_region *nd_region)
+{
+ unsigned long align, per_mapping;
+ int i, mappings;
+ u32 remainder;
+
+ if (is_nd_blk(&nd_region->dev))
+ align = PAGE_SIZE;
+ else
+ align = MEMREMAP_COMPAT_ALIGN_MAX;
+
+ for (i = 0; i < nd_region->ndr_mappings; i++) {
+ struct nd_mapping *nd_mapping = &nd_region->mapping[i];
+ struct nvdimm *nvdimm = nd_mapping->nvdimm;
+
+ if (test_bit(NDD_ALIASING, &nvdimm->flags)) {
+ align = MEMREMAP_COMPAT_ALIGN_MAX;
+ break;
+ }
+ }
+
+ mappings = max_t(u16, 1, nd_region->ndr_mappings);
+ per_mapping = align;
+ remainder = do_div(per_mapping, mappings);
+ if (remainder)
+ align *= mappings;
+
+ return align;
+}
+
static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus,
struct nd_region_desc *ndr_desc,
const struct device_type *dev_type, const char *caller)
@@ -1039,6 +1142,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus,
dev->of_node = ndr_desc->of_node;
nd_region->ndr_size = resource_size(ndr_desc->res);
nd_region->ndr_start = ndr_desc->res->start;
+ nd_region->align = default_align(nd_region);
if (ndr_desc->flush)
nd_region->flush = ndr_desc->flush;
else
^ permalink raw reply related
* [PATCH v2 3/4] libnvdimm/region: Introduce NDD_LABELING
From: Dan Williams @ 2020-02-13 0:48 UTC (permalink / raw)
To: linux-nvdimm
Cc: Vishal Verma, linuxppc-dev, Oliver O'Halloran, linux-kernel,
Aneesh Kumar K.V
In-Reply-To: <158155489850.3343782.2687127373754434980.stgit@dwillia2-desk3.amr.corp.intel.com>
The NDD_ALIASING flag is used to indicate where pmem capacity might
alias with blk capacity and require labeling. It is also used to
indicate whether the DIMM supports labeling. Separate this latter
capability into its own flag so that the NDD_ALIASING flag is scoped to
true aliased configurations.
To my knowledge aliased configurations only exist in the ACPI spec,
there are no known platforms that ship this support in production.
This clarity allows namespace-capacity alignment constraints around
interleave-ways to be relaxed.
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Oliver O'Halloran <oohall@gmail.com>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Link: https://lore.kernel.org/r/158041477856.3889308.4212605617834097674.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
arch/powerpc/platforms/pseries/papr_scm.c | 2 +-
drivers/acpi/nfit/core.c | 4 +++-
drivers/nvdimm/dimm.c | 2 +-
drivers/nvdimm/dimm_devs.c | 9 +++++----
drivers/nvdimm/namespace_devs.c | 2 +-
drivers/nvdimm/nd.h | 2 +-
drivers/nvdimm/region_devs.c | 10 +++++-----
include/linux/libnvdimm.h | 2 ++
8 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index 0b4467e378e5..589858cb3203 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -328,7 +328,7 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
}
dimm_flags = 0;
- set_bit(NDD_ALIASING, &dimm_flags);
+ set_bit(NDD_LABELING, &dimm_flags);
p->nvdimm = nvdimm_create(p->bus, p, NULL, dimm_flags,
PAPR_SCM_DIMM_CMD_MASK, 0, NULL);
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index a3320f93616d..71d7f2aa1b12 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2026,8 +2026,10 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
continue;
}
- if (nfit_mem->bdw && nfit_mem->memdev_pmem)
+ if (nfit_mem->bdw && nfit_mem->memdev_pmem) {
set_bit(NDD_ALIASING, &flags);
+ set_bit(NDD_LABELING, &flags);
+ }
/* collate flags across all memdevs for this dimm */
list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c
index 64776ed15bb3..7d4ddc4d9322 100644
--- a/drivers/nvdimm/dimm.c
+++ b/drivers/nvdimm/dimm.c
@@ -99,7 +99,7 @@ static int nvdimm_probe(struct device *dev)
if (ndd->ns_current >= 0) {
rc = nd_label_reserve_dpa(ndd);
if (rc == 0)
- nvdimm_set_aliasing(dev);
+ nvdimm_set_labeling(dev);
}
nvdimm_bus_unlock(dev);
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index 94ea6dba6b4f..64159d4d4b8f 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -32,7 +32,7 @@ int nvdimm_check_config_data(struct device *dev)
if (!nvdimm->cmd_mask ||
!test_bit(ND_CMD_GET_CONFIG_DATA, &nvdimm->cmd_mask)) {
- if (test_bit(NDD_ALIASING, &nvdimm->flags))
+ if (test_bit(NDD_LABELING, &nvdimm->flags))
return -ENXIO;
else
return -ENOTTY;
@@ -173,11 +173,11 @@ int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
return rc;
}
-void nvdimm_set_aliasing(struct device *dev)
+void nvdimm_set_labeling(struct device *dev)
{
struct nvdimm *nvdimm = to_nvdimm(dev);
- set_bit(NDD_ALIASING, &nvdimm->flags);
+ set_bit(NDD_LABELING, &nvdimm->flags);
}
void nvdimm_set_locked(struct device *dev)
@@ -312,8 +312,9 @@ static ssize_t flags_show(struct device *dev,
{
struct nvdimm *nvdimm = to_nvdimm(dev);
- return sprintf(buf, "%s%s\n",
+ return sprintf(buf, "%s%s%s\n",
test_bit(NDD_ALIASING, &nvdimm->flags) ? "alias " : "",
+ test_bit(NDD_LABELING, &nvdimm->flags) ? "label" : "",
test_bit(NDD_LOCKED, &nvdimm->flags) ? "lock " : "");
}
static DEVICE_ATTR_RO(flags);
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index aff1f32fdb4f..30cda9f235de 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -2531,7 +2531,7 @@ static int init_active_labels(struct nd_region *nd_region)
if (!ndd) {
if (test_bit(NDD_LOCKED, &nvdimm->flags))
/* fail, label data may be unreadable */;
- else if (test_bit(NDD_ALIASING, &nvdimm->flags))
+ else if (test_bit(NDD_LABELING, &nvdimm->flags))
/* fail, labels needed to disambiguate dpa */;
else
return 0;
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index c9f6a5b5253a..ca39abe29c7c 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -252,7 +252,7 @@ int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
void *buf, size_t len);
long nvdimm_clear_poison(struct device *dev, phys_addr_t phys,
unsigned int len);
-void nvdimm_set_aliasing(struct device *dev);
+void nvdimm_set_labeling(struct device *dev);
void nvdimm_set_locked(struct device *dev);
void nvdimm_clear_locked(struct device *dev);
int nvdimm_security_setup_events(struct device *dev);
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index a19e535830d9..a5fc6e4c56ff 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -195,16 +195,16 @@ EXPORT_SYMBOL_GPL(nd_blk_region_set_provider_data);
int nd_region_to_nstype(struct nd_region *nd_region)
{
if (is_memory(&nd_region->dev)) {
- u16 i, alias;
+ u16 i, label;
- for (i = 0, alias = 0; i < nd_region->ndr_mappings; i++) {
+ for (i = 0, label = 0; i < nd_region->ndr_mappings; i++) {
struct nd_mapping *nd_mapping = &nd_region->mapping[i];
struct nvdimm *nvdimm = nd_mapping->nvdimm;
- if (test_bit(NDD_ALIASING, &nvdimm->flags))
- alias++;
+ if (test_bit(NDD_LABELING, &nvdimm->flags))
+ label++;
}
- if (alias)
+ if (label)
return ND_DEVICE_NAMESPACE_PMEM;
else
return ND_DEVICE_NAMESPACE_IO;
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index 9df091bd30ba..18da4059be09 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -37,6 +37,8 @@ enum {
NDD_WORK_PENDING = 4,
/* ignore / filter NSLABEL_FLAG_LOCAL for this DIMM, i.e. no aliasing */
NDD_NOBLK = 5,
+ /* dimm supports namespace labels */
+ NDD_LABELING = 6,
/* need to set a limit somewhere, but yes, this is likely overkill */
ND_IOCTL_MAX_BUFLEN = SZ_4M,
^ permalink raw reply related
* [PATCH v2 2/4] libnvdimm/namespace: Enforce memremap_compat_align()
From: Dan Williams @ 2020-02-13 0:48 UTC (permalink / raw)
To: linux-nvdimm
Cc: Aneesh Kumar K.V, Jeff Moyer, linuxppc-dev, linux-kernel,
vishal.l.verma
In-Reply-To: <158155489850.3343782.2687127373754434980.stgit@dwillia2-desk3.amr.corp.intel.com>
The pmem driver on PowerPC crashes with the following signature when
instantiating misaligned namespaces that map their capacity via
memremap_pages().
BUG: Unable to handle kernel data access at 0xc001000406000000
Faulting instruction address: 0xc000000000090790
NIP [c000000000090790] arch_add_memory+0xc0/0x130
LR [c000000000090744] arch_add_memory+0x74/0x130
Call Trace:
arch_add_memory+0x74/0x130 (unreliable)
memremap_pages+0x74c/0xa30
devm_memremap_pages+0x3c/0xa0
pmem_attach_disk+0x188/0x770
nvdimm_bus_probe+0xd8/0x470
With the assumption that only memremap_pages() has alignment
constraints, enforce memremap_compat_align() for
pmem_should_map_pages(), nd_pfn, or nd_dax cases.
Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Jeff Moyer <jmoyer@redhat.com>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Link: https://lore.kernel.org/r/158041477336.3889308.4581652885008605170.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/nvdimm/namespace_devs.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 032dc61725ff..aff1f32fdb4f 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -1739,6 +1739,16 @@ struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev)
return ERR_PTR(-ENODEV);
}
+ if (pmem_should_map_pages(dev) || nd_pfn || nd_dax) {
+ struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
+ resource_size_t start = nsio->res.start;
+
+ if (!IS_ALIGNED(start | size, memremap_compat_align())) {
+ dev_dbg(&ndns->dev, "misaligned, unable to map\n");
+ return ERR_PTR(-EOPNOTSUPP);
+ }
+ }
+
if (is_namespace_pmem(&ndns->dev)) {
struct nd_namespace_pmem *nspm;
^ permalink raw reply related
* [PATCH v2 1/4] mm/memremap_pages: Introduce memremap_compat_align()
From: Dan Williams @ 2020-02-13 0:48 UTC (permalink / raw)
To: linux-nvdimm
Cc: Aneesh Kumar K.V, linux-kernel, Jeff Moyer, Paul Mackerras,
vishal.l.verma, linuxppc-dev
In-Reply-To: <158155489850.3343782.2687127373754434980.stgit@dwillia2-desk3.amr.corp.intel.com>
The "sub-section memory hotplug" facility allows memremap_pages() users
like libnvdimm to compensate for hardware platforms like x86 that have a
section size larger than their hardware memory mapping granularity. The
compensation that sub-section support affords is being tolerant of
physical memory resources shifting by units smaller (64MiB on x86) than
the memory-hotplug section size (128 MiB). Where the platform
physical-memory mapping granularity is limited by the number and
capability of address-decode-registers in the memory controller.
While the sub-section support allows memremap_pages() to operate on
sub-section (2MiB) granularity, the Power architecture may still
require 16MiB alignment on "!radix_enabled()" platforms.
In order for libnvdimm to be able to detect and manage this per-arch
limitation, introduce memremap_compat_align() as a common minimum
alignment across all driver-facing memory-mapping interfaces, and let
Power override it to 16MiB in the "!radix_enabled()" case.
The assumption / requirement for 16MiB to be a viable
memremap_compat_align() value is that Power does not have platforms
where its equivalent of address-decode-registers never hardware remaps a
persistent memory resource on smaller than 16MiB boundaries. Note that I
tried my best to not add a new Kconfig symbol, but header include
entanglements defeated the #ifndef memremap_compat_align design pattern
and the need to export it defeats the __weak design pattern for arch
overrides.
Based on an initial patch by Aneesh.
Link: http://lore.kernel.org/r/CAPcyv4gBGNP95APYaBcsocEa50tQj9b5h__83vgngjq3ouGX_Q@mail.gmail.com
Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Reported-by: Jeff Moyer <jmoyer@redhat.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/mm/ioremap.c | 12 ++++++++++++
drivers/nvdimm/pfn_devs.c | 2 +-
include/linux/memremap.h | 8 ++++++++
include/linux/mmzone.h | 1 +
lib/Kconfig | 3 +++
mm/memremap.c | 13 +++++++++++++
7 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 497b7d0b2d7e..e6ffe905e2b9 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -122,6 +122,7 @@ config PPC
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_KCOV
select ARCH_HAS_HUGEPD if HUGETLB_PAGE
+ select ARCH_HAS_MEMREMAP_COMPAT_ALIGN
select ARCH_HAS_MMIOWB if PPC64
select ARCH_HAS_PHYS_TO_DMA
select ARCH_HAS_PMEM_API
diff --git a/arch/powerpc/mm/ioremap.c b/arch/powerpc/mm/ioremap.c
index fc669643ce6a..38b5ba7d3e2d 100644
--- a/arch/powerpc/mm/ioremap.c
+++ b/arch/powerpc/mm/ioremap.c
@@ -2,6 +2,7 @@
#include <linux/io.h>
#include <linux/slab.h>
+#include <linux/mmzone.h>
#include <linux/vmalloc.h>
#include <asm/io-workarounds.h>
@@ -97,3 +98,14 @@ void __iomem *do_ioremap(phys_addr_t pa, phys_addr_t offset, unsigned long size,
return NULL;
}
+
+#ifdef CONFIG_ZONE_DEVICE
+/* override of the generic version in mm/memremap.c */
+unsigned long memremap_compat_align(void)
+{
+ if (radix_enabled())
+ return SUBSECTION_SIZE;
+ return (1UL << mmu_psize_defs[mmu_linear_psize].shift);
+}
+EXPORT_SYMBOL_GPL(memremap_compat_align);
+#endif
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index b94f7a7e94b8..a5c25cb87116 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -750,7 +750,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
start = nsio->res.start;
size = resource_size(&nsio->res);
npfns = PHYS_PFN(size - SZ_8K);
- align = max(nd_pfn->align, (1UL << SUBSECTION_SHIFT));
+ align = max(nd_pfn->align, SUBSECTION_SIZE);
end_trunc = start + size - ALIGN_DOWN(start + size, align);
if (nd_pfn->mode == PFN_MODE_PMEM) {
/*
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 6fefb09af7c3..8af1cbd8f293 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -132,6 +132,7 @@ struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
unsigned long vmem_altmap_offset(struct vmem_altmap *altmap);
void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns);
+unsigned long memremap_compat_align(void);
#else
static inline void *devm_memremap_pages(struct device *dev,
struct dev_pagemap *pgmap)
@@ -165,6 +166,12 @@ static inline void vmem_altmap_free(struct vmem_altmap *altmap,
unsigned long nr_pfns)
{
}
+
+/* when memremap_pages() is disabled all archs can remap a single page */
+static inline unsigned long memremap_compat_align(void)
+{
+ return PAGE_SIZE;
+}
#endif /* CONFIG_ZONE_DEVICE */
static inline void put_dev_pagemap(struct dev_pagemap *pgmap)
@@ -172,4 +179,5 @@ static inline void put_dev_pagemap(struct dev_pagemap *pgmap)
if (pgmap)
percpu_ref_put(pgmap->ref);
}
+
#endif /* _LINUX_MEMREMAP_H_ */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 462f6873905a..6b77f7239af5 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -1170,6 +1170,7 @@ static inline unsigned long section_nr_to_pfn(unsigned long sec)
#define SECTION_ALIGN_DOWN(pfn) ((pfn) & PAGE_SECTION_MASK)
#define SUBSECTION_SHIFT 21
+#define SUBSECTION_SIZE (1UL << SUBSECTION_SHIFT)
#define PFN_SUBSECTION_SHIFT (SUBSECTION_SHIFT - PAGE_SHIFT)
#define PAGES_PER_SUBSECTION (1UL << PFN_SUBSECTION_SHIFT)
diff --git a/lib/Kconfig b/lib/Kconfig
index 0cf875fd627c..17dbc7bd3895 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -618,6 +618,9 @@ config ARCH_HAS_PMEM_API
config MEMREGION
bool
+config ARCH_HAS_MEMREMAP_COMPAT_ALIGN
+ bool
+
# use memcpy to implement user copies for nommu architectures
config UACCESS_MEMCPY
bool
diff --git a/mm/memremap.c b/mm/memremap.c
index 09b5b7adc773..a6905d28fe91 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -7,6 +7,7 @@
#include <linux/mm.h>
#include <linux/pfn_t.h>
#include <linux/swap.h>
+#include <linux/mmzone.h>
#include <linux/swapops.h>
#include <linux/types.h>
#include <linux/wait_bit.h>
@@ -14,6 +15,18 @@
static DEFINE_XARRAY(pgmap_array);
+/*
+ * Minimum compatible alignment of the resource (start, end) across
+ * memremap interfaces (i.e. memremap + memremap_pages)
+ */
+#ifndef CONFIG_ARCH_HAS_MEMREMAP_COMPAT_ALIGN
+unsigned long memremap_compat_align(void)
+{
+ return SUBSECTION_SIZE;
+}
+EXPORT_SYMBOL_GPL(memremap_compat_align);
+#endif
+
#ifdef CONFIG_DEV_PAGEMAP_OPS
DEFINE_STATIC_KEY_FALSE(devmap_managed_key);
EXPORT_SYMBOL(devmap_managed_key);
^ permalink raw reply related
* [PATCH v2 0/4] libnvdimm: Cross-arch compatible namespace alignment
From: Dan Williams @ 2020-02-13 0:48 UTC (permalink / raw)
To: linux-nvdimm
Cc: Vishal Verma, linux-kernel, Jeff Moyer, Oliver O'Halloran,
Aneesh Kumar K.V, Paul Mackerras, linuxppc-dev
Changes since v1 [1]:
- Fix build errors with the PowerPC override for memremap_compat_align()
- Move the memremap_compat_align() override definition to
arch/powerpc/mm/ioremap.c (Aneesh)
[1]: http://lore.kernel.org/r/158041475480.3889308.655103391935006598.stgit@dwillia2-desk3.amr.corp.intel.com
---
Explicit review requests, but any other feedback is of course
appreciated:
Patch1 needs an ack from ppc arch maintainers, and I'd like a tested-by
from Aneesh that this still works to solve the ppc issue. Jeff, does
this look good to you?
---
Aneesh reports that PowerPC requires 16MiB alignment for the address
range passed to devm_memremap_pages(), and Jeff reports that it is
possible to create a misaligned namespace which blocks future namespace
creation in that region. Both of these issues require namespace
alignment to be managed at the region level rather than padding at the
namespace level which has been a broken approach to date.
Introduce memremap_compat_align() to indicate the hard requirements of
an arch's memremap_pages() implementation. Use the maximum known
memremap_compat_align() to set the default namespace alignment for
libnvdimm. Consult that alignment when allocating free space. Finally,
allow the default region alignment to be overridden to maintain the same
namespace creation capability as previous kernels.
The ndctl unit tests, which have some misaligned namespace assumptions,
are updated to use the alignment override where necessary.
Thanks to Aneesh for early feedback and testing on this improved
alignment handling.
---
Dan Williams (4):
mm/memremap_pages: Introduce memremap_compat_align()
libnvdimm/namespace: Enforce memremap_compat_align()
libnvdimm/region: Introduce NDD_LABELING
libnvdimm/region: Introduce an 'align' attribute
arch/powerpc/Kconfig | 1
arch/powerpc/mm/ioremap.c | 12 +++
arch/powerpc/platforms/pseries/papr_scm.c | 2
drivers/acpi/nfit/core.c | 4 +
drivers/nvdimm/dimm.c | 2
drivers/nvdimm/dimm_devs.c | 95 +++++++++++++++++----
drivers/nvdimm/namespace_devs.c | 21 ++++-
drivers/nvdimm/nd.h | 3 -
drivers/nvdimm/pfn_devs.c | 2
drivers/nvdimm/region_devs.c | 132 ++++++++++++++++++++++++++---
include/linux/libnvdimm.h | 2
include/linux/memremap.h | 8 ++
include/linux/mmzone.h | 1
lib/Kconfig | 3 +
mm/memremap.c | 13 +++
15 files changed, 260 insertions(+), 41 deletions(-)
--
base-commit: 543506a2936aaced94bcc8731aae5d29d0442e90
^ permalink raw reply
* [PATCH v7 4/4] powerpc: Book3S 64-bit "heavyweight" KASAN support
From: Daniel Axtens @ 2020-02-13 0:47 UTC (permalink / raw)
To: linux-kernel, linux-mm, linuxppc-dev, kasan-dev, christophe.leroy,
aneesh.kumar, bsingharora
Cc: Daniel Axtens
In-Reply-To: <20200213004752.11019-1-dja@axtens.net>
KASAN support on Book3S is a bit tricky to get right:
- It would be good to support inline instrumentation so as to be able to
catch stack issues that cannot be caught with outline mode.
- Inline instrumentation requires a fixed offset.
- Book3S runs code in real mode after booting. Most notably a lot of KVM
runs in real mode, and it would be good to be able to instrument it.
- Because code runs in real mode after boot, the offset has to point to
valid memory both in and out of real mode.
[ppc64 mm note: The kernel installs a linear mapping at effective
address c000... onward. This is a one-to-one mapping with physical
memory from 0000... onward. Because of how memory accesses work on
powerpc 64-bit Book3S, a kernel pointer in the linear map accesses the
same memory both with translations on (accessing as an 'effective
address'), and with translations off (accessing as a 'real
address'). This works in both guests and the hypervisor. For more
details, see s5.7 of Book III of version 3 of the ISA, in particular
the Storage Control Overview, s5.7.3, and s5.7.5 - noting that this
KASAN implementation currently only supports Radix.]
One approach is just to give up on inline instrumentation. This way all
checks can be delayed until after everything set is up correctly, and the
address-to-shadow calculations can be overridden. However, the features and
speed boost provided by inline instrumentation are worth trying to do
better.
If _at compile time_ it is known how much contiguous physical memory a
system has, the top 1/8th of the first block of physical memory can be set
aside for the shadow. This is a big hammer and comes with 3 big
consequences:
- there's no nice way to handle physically discontiguous memory, so only
the first physical memory block can be used.
- 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.
Implement and document KASAN this way. The current implementation is Radix
only.
Despite the limitations, it can still find bugs,
e.g. http://patchwork.ozlabs.org/patch/1103775/
At the moment, this physical memory limit must be set _even for outline
mode_. This may be changed in a later series - a different implementation
could be added for outline mode that dynamically allocates shadow at a
fixed offset. For example, see https://patchwork.ozlabs.org/patch/795211/
Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Cc: Balbir Singh <bsingharora@gmail.com> # ppc64 out-of-line radix version
Cc: Christophe Leroy <christophe.leroy@c-s.fr> # ppc32 version
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
Changes since v6:
- rework kasan_late_init support, which also fixes book3e problem that snowpatch
picked up (I think)
- fix a checkpatch error that snowpatch picked up
- don't needlessly move the include in kasan.h
Changes since v5:
- rebase on powerpc/merge, with Christophe's latest changes integrating
kasan-vmalloc
- documentation tweaks based on latest 32-bit changes
Changes since v4:
- fix some ppc32 build issues
- support ptdump
- clean up the header file. It turns out we don't need or use KASAN_SHADOW_SIZE,
so just dump it, and make KASAN_SHADOW_END the thing that varies between 32
and 64 bit. As part of this, make sure KASAN_SHADOW_OFFSET is only configured for
32 bit - it is calculated in the Makefile for ppc64.
- various cleanups
Changes since v3:
- Address further feedback from Christophe.
- Drop changes to stack walking, it looks like the issue I observed is
related to that particular stack, not stack-walking generally.
Changes since v2:
- Address feedback from Christophe around cleanups and docs.
- Address feedback from Balbir: at this point I don't have a good solution
for the issues you identify around the limitations of the inline implementation
but I think that it's worth trying to get the stack instrumentation support.
I'm happy to have an alternative and more flexible outline mode - I had
envisoned this would be called 'lightweight' mode as it imposes fewer restrictions.
I've linked to your implementation. I think it's best to add it in a follow-up series.
- Made the default PHYS_MEM_SIZE_FOR_KASAN value 1024MB. I think most people have
guests with at least that much memory in the Radix 64s case so it's a much
saner default - it means that if you just turn on KASAN without reading the
docs you're much more likely to have a bootable kernel, which you will never
have if the value is set to zero! I'm happy to bikeshed the value if we want.
Changes since v1:
- Landed kasan vmalloc support upstream
- Lots of feedback from Christophe.
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 | 9 +-
Documentation/powerpc/kasan.txt | 112 ++++++++++++++++++-
arch/powerpc/Kconfig | 2 +
arch/powerpc/Kconfig.debug | 23 +++-
arch/powerpc/Makefile | 11 ++
arch/powerpc/include/asm/book3s/64/hash.h | 4 +
arch/powerpc/include/asm/book3s/64/pgtable.h | 7 ++
arch/powerpc/include/asm/book3s/64/radix.h | 5 +
arch/powerpc/include/asm/kasan.h | 11 +-
arch/powerpc/kernel/prom.c | 61 +++++++++-
arch/powerpc/mm/kasan/Makefile | 1 +
arch/powerpc/mm/kasan/init_book3s_64.c | 73 ++++++++++++
arch/powerpc/mm/ptdump/ptdump.c | 10 +-
arch/powerpc/platforms/Kconfig.cputype | 1 +
14 files changed, 320 insertions(+), 10 deletions(-)
create mode 100644 arch/powerpc/mm/kasan/init_book3s_64.c
diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst
index 012ef3d91d1f..5722de91ccce 100644
--- a/Documentation/dev-tools/kasan.rst
+++ b/Documentation/dev-tools/kasan.rst
@@ -22,8 +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, s390 and
-riscv architectures. It is also supported on 32-bit powerpc kernels. Tag-based
-KASAN is supported only on arm64.
+riscv 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 on arm64.
Usage
-----
@@ -257,8 +258,8 @@ CONFIG_KASAN_VMALLOC
With ``CONFIG_KASAN_VMALLOC``, KASAN can cover vmalloc space at the
cost of greater memory usage. Currently this supported on x86, s390
-and 32-bit powerpc. It is optional, except on 32-bit powerpc kernels
-with module support, where it is required.
+and powerpc. It is optional, except on 64-bit powerpc kernels, and on
+32-bit powerpc kernels with module support, where it is required.
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
index 26bb0e8bb18c..bf645a5cd486 100644
--- a/Documentation/powerpc/kasan.txt
+++ b/Documentation/powerpc/kasan.txt
@@ -1,4 +1,4 @@
-KASAN is supported on powerpc on 32-bit only.
+KASAN is supported on powerpc on 32-bit and Radix 64-bit only.
32 bit support
==============
@@ -10,3 +10,113 @@ fixmap area and occupies one eighth of the total kernel virtual memory space.
Instrumentation of the vmalloc area is optional, unless built with modules,
in which case it is required.
+
+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 a bit tricky to get right:
+
+ - It would be good to support inline instrumentation so as to be able to catch
+ stack issues that cannot be caught with outline mode.
+
+ - Inline instrumentation requires a fixed offset.
+
+ - Book3S runs code in real mode after booting. Most notably a lot of KVM runs
+ in real mode, and it would be good to be able to instrument it.
+
+ - Because code runs in real mode after boot, the offset has to point to
+ valid memory both in and out of real mode.
+
+One approach is just to give up on inline instrumentation. This way all checks
+can be delayed until after everything set is up correctly, and the
+address-to-shadow calculations can be overridden. However, the features and
+speed boost provided by inline instrumentation are worth trying to do better.
+
+If _at compile time_ it is known how much contiguous physical memory a system
+has, the top 1/8th of the first block of physical memory can be set aside for
+the shadow. This is a big hammer and comes with 3 big consequences:
+
+ - there's no nice way to handle physically discontiguous memory, so only the
+ first physical memory block can be used.
+
+ - 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.
+
+At the moment, this physical memory limit must be set _even for outline mode_.
+This may be changed in a future version - a different implementation could be
+added for outline mode that dynamically allocates shadow at a fixed offset.
+For example, see https://patchwork.ozlabs.org/patch/795211/
+
+This value is configured in CONFIG_PHYS_MEM_SIZE_FOR_KASAN.
+
+Tips
+----
+
+ - Compile with CONFIG_RELOCATABLE.
+
+ In development, boot hangs were observed when building with ftrace and KUAP
+ on. These ended up being due to kernel bloat pushing prom_init calls to be
+ done via the PLT. Because the kernel was not relocatable, and the calls are
+ done very early, this caused execution to jump off into somewhere
+ invalid. Enabling relocation fixes this.
+
+NUMA/discontiguous physical memory
+----------------------------------
+
+Currently the code cannot really deal with discontiguous physical memory. Only
+physical memory that is contiguous from physical address zero can be used. The
+size of that memory, not total memory, must be specified when configuring the
+kernel.
+
+Discontiguous memory can occur on machines 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 the machine is treated as having 64GB of _contiguous_ RAM, the
+ instrumentation would assume that it ran from 0x0 to
+ 0x0000_0010_0000_0000. The last 1/8th - 0x0000_000e_0000_0000 to
+ 0x0000_0010_0000_0000 would be reserved as the shadow region. But when the
+ kernel tried to access any of that, it would be trying to access pages that
+ are not physically present.
+
+ - If the shadow region size is based on the top address, then the shadow
+ region would be 0x2008_0000_0000 / 8 = 0x0401_0000_0000 bytes = 4100 GB of
+ memory, clearly more than the 64GB of RAM physically present.
+
+Therefore, the code currently is restricted to dealing with memory in the node
+starting at 0x0. For this system, that's 32GB. If a contiguous physical memory
+size greater than the size of the first contiguous region of memory is
+specified, the system will be unable to boot or even print an error message.
+
+The layout of a system's memory can be observed in 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, this system would be configured 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 it would be
+configured for 131072 MB of physically contiguous memory.
+
+This restriction currently also affects outline mode, but this could be
+changed in future if an alternative outline implementation is added.
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 497b7d0b2d7e..f1c54c08a88e 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -169,7 +169,9 @@ 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 HAVE_ARCH_KASAN_VMALLOC if PPC32
+ select HAVE_ARCH_KASAN_VMALLOC if PPC_BOOK3S_64 && PPC_RADIX_MMU
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 0b063830eea8..faed301a3b10 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -394,7 +394,28 @@ 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)" if KASAN && PPC_BOOK3S_64
+ default 1024
+ 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
+ depends on KASAN && PPC32
default 0xe0000000
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index f35730548e42..eb47dc768c0a 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -230,6 +230,17 @@ ifdef CONFIG_476FPE_ERR46
-T $(srctree)/arch/powerpc/platforms/44x/ppc476_modules.lds
endif
+ifdef CONFIG_PPC_BOOK3S_64
+# 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
+# bits are ignored) and outside of real mode.
+#
+# 0xc000000000000000 >> 3 = 0xa800000000000000 = 12105675798371893248
+KASAN_SHADOW_OFFSET = $(shell echo 7 \* 1024 \* 1024 \* $(CONFIG_PHYS_MEM_SIZE_FOR_KASAN) / 8 + 12105675798371893248 | bc)
+KBUILD_CFLAGS += -DKASAN_SHADOW_OFFSET=$(KASAN_SHADOW_OFFSET)UL
+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/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h
index 2781ebf6add4..fce329b8452e 100644
--- a/arch/powerpc/include/asm/book3s/64/hash.h
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -18,6 +18,10 @@
#include <asm/book3s/64/hash-4k.h>
#endif
+#define H_PTRS_PER_PTE (1 << H_PTE_INDEX_SIZE)
+#define H_PTRS_PER_PMD (1 << H_PMD_INDEX_SIZE)
+#define H_PTRS_PER_PUD (1 << H_PUD_INDEX_SIZE)
+
/* Bits to set in a PMD/PUD/PGD entry valid bit*/
#define HASH_PMD_VAL_BITS (0x8000000000000000UL)
#define HASH_PUD_VAL_BITS (0x8000000000000000UL)
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 201a69e6a355..309fb925a96e 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -231,6 +231,13 @@ extern unsigned long __pmd_frag_size_shift;
#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE)
#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
+#define MAX_PTRS_PER_PTE ((H_PTRS_PER_PTE > R_PTRS_PER_PTE) ? \
+ H_PTRS_PER_PTE : R_PTRS_PER_PTE)
+#define MAX_PTRS_PER_PMD ((H_PTRS_PER_PMD > R_PTRS_PER_PMD) ? \
+ H_PTRS_PER_PMD : R_PTRS_PER_PMD)
+#define MAX_PTRS_PER_PUD ((H_PTRS_PER_PUD > R_PTRS_PER_PUD) ? \
+ H_PTRS_PER_PUD : R_PTRS_PER_PUD)
+
/* PMD_SHIFT determines what a second-level page table entry can map */
#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
#define PMD_SIZE (1UL << PMD_SHIFT)
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index d97db3ad9aae..4f826259de71 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 fbff9ff9032e..b21d3ef88214 100644
--- a/arch/powerpc/include/asm/kasan.h
+++ b/arch/powerpc/include/asm/kasan.h
@@ -21,11 +21,18 @@
#define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET + \
(PAGE_OFFSET >> KASAN_SHADOW_SCALE_SHIFT))
+#ifdef CONFIG_KASAN_SHADOW_OFFSET
#define KASAN_SHADOW_OFFSET ASM_CONST(CONFIG_KASAN_SHADOW_OFFSET)
+#endif
+#ifdef CONFIG_PPC32
#define KASAN_SHADOW_END 0UL
+#endif
-#define KASAN_SHADOW_SIZE (KASAN_SHADOW_END - KASAN_SHADOW_START)
+#ifdef CONFIG_PPC_BOOK3S_64
+#define KASAN_SHADOW_END (KASAN_SHADOW_OFFSET + \
+ (RADIX_VMEMMAP_END >> KASAN_SHADOW_SCALE_SHIFT))
+#endif
#ifdef CONFIG_KASAN
void kasan_early_init(void);
@@ -38,5 +45,5 @@ static inline void kasan_mmu_init(void) { }
static inline void kasan_late_init(void) { }
#endif
-#endif /* __ASSEMBLY */
+#endif /* !__ASSEMBLY__ */
#endif
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 6620f37abe73..2857c3d44e9c 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -72,6 +72,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)
@@ -449,6 +450,26 @@ static bool validate_mem_limit(u64 base, u64 *size)
{
u64 max_mem = 1UL << (MAX_PHYSMEM_BITS);
+ /*
+ * To handle the NUMA/discontiguous memory case, don't allow a block
+ * to be added if it falls completely beyond the configured physical
+ * memory. Print an informational message.
+ *
+ * Frustratingly we also see this with qemu - it seems to split the
+ * specified memory into a number of smaller blocks. If this happens
+ * under qemu, it probably represents misconfiguration. So we want
+ * the message to be noticeable, but not shouty.
+ *
+ * See Documentation/powerpc/kasan.txt
+ */
+ if (IS_ENABLED(CONFIG_KASAN) &&
+ (base >= ((u64)CONFIG_PHYS_MEM_SIZE_FOR_KASAN * SZ_1M))) {
+ pr_warn("KASAN: not adding memory block at %llx (size %llx)\n"
+ "This could be due to discontiguous memory or kernel misconfiguration.",
+ base, *size);
+ return false;
+ }
+
if (base >= max_mem)
return false;
if ((base + *size) > max_mem)
@@ -572,8 +593,10 @@ 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);
+ top_phys_addr = max(top_phys_addr, (phys_addr_t)(base + size));
+ }
}
}
@@ -613,6 +636,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;
+ phys_addr_t kasan_memory_size;
reserve_map = (__be64 *)(((unsigned long)initial_boot_params) +
fdt_off_mem_rsvmap(initial_boot_params));
@@ -651,6 +676,40 @@ static void __init early_reserve_mem(void)
return;
}
#endif
+
+ if (IS_ENABLED(CONFIG_KASAN) && IS_ENABLED(CONFIG_PPC_BOOK3S_64)) {
+ kasan_memory_size =
+ ((phys_addr_t)CONFIG_PHYS_MEM_SIZE_FOR_KASAN * SZ_1M);
+
+ if (top_phys_addr < kasan_memory_size) {
+ /*
+ * We are doomed. We shouldn't even be able to get this
+ * far, but we do in qemu. If we continue and turn
+ * relocations on, we'll take fatal page faults for
+ * memory that's not physically present. Instead,
+ * panic() here: it will be saved to __log_buf even if
+ * it doesn't get printed to the console.
+ */
+ panic("Tried to boot a KASAN kernel configured for %u MB with only %llu MB! Aborting.",
+ CONFIG_PHYS_MEM_SIZE_FOR_KASAN,
+ (u64)(top_phys_addr * SZ_1M));
+ } 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 physical memory detected is at least %llu MB.\n"
+ "Memory above the compiled limit will not be used!\n"
+ "===========================================\n",
+ CONFIG_PHYS_MEM_SIZE_FOR_KASAN,
+ (u64)(top_phys_addr * SZ_1M));
+ }
+
+ 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);
+ }
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
diff --git a/arch/powerpc/mm/kasan/Makefile b/arch/powerpc/mm/kasan/Makefile
index 36a4e1b10b2d..f02b15c78e4d 100644
--- a/arch/powerpc/mm/kasan/Makefile
+++ b/arch/powerpc/mm/kasan/Makefile
@@ -3,3 +3,4 @@
KASAN_SANITIZE := n
obj-$(CONFIG_PPC32) += init_32.o
+obj-$(CONFIG_PPC_BOOK3S_64) += init_book3s_64.o
diff --git a/arch/powerpc/mm/kasan/init_book3s_64.c b/arch/powerpc/mm/kasan/init_book3s_64.c
new file mode 100644
index 000000000000..1c95fe6495c7
--- /dev/null
+++ b/arch/powerpc/mm/kasan/init_book3s_64.c
@@ -0,0 +1,73 @@
+// 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>
+
+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);
+
+ pte_t pte = pte_mkpte(pfn_pte(virt_to_pfn(kasan_early_shadow_page),
+ PAGE_KERNEL));
+
+ if (!early_radix_enabled())
+ panic("KASAN requires radix!");
+
+ for (i = 0; i < PTRS_PER_PTE; i++)
+ __set_pte_at(&init_mm, (unsigned long)kasan_early_shadow_page,
+ &kasan_early_shadow_pte[i], pte, 0);
+
+ 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((void *)KASAN_SHADOW_START, KASAN_SHADOW_INIT,
+ ((u64)CONFIG_PHYS_MEM_SIZE_FOR_KASAN *
+ SZ_1M >> KASAN_SHADOW_SCALE_SHIFT));
+
+ 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 */
+ pte = pte_mkpte(pfn_pte(virt_to_pfn(kasan_early_shadow_page), PAGE_KERNEL_RO));
+ for (i = 0; i < PTRS_PER_PTE; i++)
+ __set_pte_at(&init_mm, (unsigned long)kasan_early_shadow_page,
+ &kasan_early_shadow_pte[i], pte, 0);
+
+ /*
+ * clear_page relies on some cache info that hasn't been set up yet.
+ * It ends up looping ~forever and blows up other data.
+ * Use memset instead.
+ */
+ memset(kasan_early_shadow_page, 0, PAGE_SIZE);
+
+ /* Enable error messages */
+ init_task.kasan_depth = 0;
+ pr_info("KASAN init done (64-bit Book3S heavyweight mode)\n");
+}
+
+void __init kasan_late_init(void) { }
diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c
index 206156255247..b982dc5441c0 100644
--- a/arch/powerpc/mm/ptdump/ptdump.c
+++ b/arch/powerpc/mm/ptdump/ptdump.c
@@ -73,6 +73,10 @@ struct addr_marker {
static struct addr_marker address_markers[] = {
{ 0, "Start of kernel VM" },
+#if defined(CONFIG_PPC64) && defined(CONFIG_KASAN)
+ { 0, "kasan shadow mem start" },
+ { 0, "kasan shadow mem end" },
+#endif
{ 0, "vmalloc() Area" },
{ 0, "vmalloc() End" },
#ifdef CONFIG_PPC64
@@ -92,10 +96,10 @@ static struct addr_marker address_markers[] = {
#endif
{ 0, "Fixmap start" },
{ 0, "Fixmap end" },
-#endif
#ifdef CONFIG_KASAN
{ 0, "kasan shadow mem start" },
{ 0, "kasan shadow mem end" },
+#endif
#endif
{ -1, NULL },
};
@@ -317,6 +321,10 @@ static void populate_markers(void)
int i = 0;
address_markers[i++].start_address = PAGE_OFFSET;
+#if defined(CONFIG_PPC64) && defined(CONFIG_KASAN)
+ address_markers[i++].start_address = KASAN_SHADOW_START;
+ address_markers[i++].start_address = KASAN_SHADOW_END;
+#endif
address_markers[i++].start_address = VMALLOC_START;
address_markers[i++].start_address = VMALLOC_END;
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 6caedc88474f..cedc86686e65 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -99,6 +99,7 @@ config PPC_BOOK3S_64
select ARCH_SUPPORTS_NUMA_BALANCING
select IRQ_WORK
select PPC_MM_SLICES
+ select KASAN_VMALLOC if KASAN
config PPC_BOOK3E_64
bool "Embedded processors"
--
2.20.1
^ permalink raw reply related
* [PATCH v7 3/4] powerpc/mm/kasan: rename kasan_init_32.c to init_32.c
From: Daniel Axtens @ 2020-02-13 0:47 UTC (permalink / raw)
To: linux-kernel, linux-mm, linuxppc-dev, kasan-dev, christophe.leroy,
aneesh.kumar, bsingharora
Cc: Daniel Axtens
In-Reply-To: <20200213004752.11019-1-dja@axtens.net>
kasan is already implied by the directory name, we don't need to
repeat it.
Suggested-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
arch/powerpc/mm/kasan/Makefile | 2 +-
arch/powerpc/mm/kasan/{kasan_init_32.c => init_32.c} | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename arch/powerpc/mm/kasan/{kasan_init_32.c => init_32.c} (100%)
diff --git a/arch/powerpc/mm/kasan/Makefile b/arch/powerpc/mm/kasan/Makefile
index 6577897673dd..36a4e1b10b2d 100644
--- a/arch/powerpc/mm/kasan/Makefile
+++ b/arch/powerpc/mm/kasan/Makefile
@@ -2,4 +2,4 @@
KASAN_SANITIZE := n
-obj-$(CONFIG_PPC32) += kasan_init_32.o
+obj-$(CONFIG_PPC32) += init_32.o
diff --git a/arch/powerpc/mm/kasan/kasan_init_32.c b/arch/powerpc/mm/kasan/init_32.c
similarity index 100%
rename from arch/powerpc/mm/kasan/kasan_init_32.c
rename to arch/powerpc/mm/kasan/init_32.c
--
2.20.1
^ permalink raw reply related
* [PATCH v7 2/4] kasan: Document support on 32-bit powerpc
From: Daniel Axtens @ 2020-02-13 0:47 UTC (permalink / raw)
To: linux-kernel, linux-mm, linuxppc-dev, kasan-dev, christophe.leroy,
aneesh.kumar, bsingharora
Cc: Daniel Axtens
In-Reply-To: <20200213004752.11019-1-dja@axtens.net>
KASAN is supported on 32-bit powerpc and the docs should reflect this.
Document s390 support while we're at it.
Suggested-by: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
Changes since v5:
- rebase - riscv has now got support.
- document s390 support while we're at it
- clarify when kasan_vmalloc support is required
---
Documentation/dev-tools/kasan.rst | 7 +++++--
Documentation/powerpc/kasan.txt | 12 ++++++++++++
2 files changed, 17 insertions(+), 2 deletions(-)
create mode 100644 Documentation/powerpc/kasan.txt
diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst
index c652d740735d..012ef3d91d1f 100644
--- a/Documentation/dev-tools/kasan.rst
+++ b/Documentation/dev-tools/kasan.rst
@@ -22,7 +22,8 @@ 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, s390 and
-riscv architectures, and tag-based KASAN is supported only for arm64.
+riscv architectures. It is also supported on 32-bit powerpc kernels. Tag-based
+KASAN is supported only on arm64.
Usage
-----
@@ -255,7 +256,9 @@ 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 supported on x86, s390
+and 32-bit powerpc. It is optional, except on 32-bit powerpc kernels
+with module support, where it is required.
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..26bb0e8bb18c
--- /dev/null
+++ b/Documentation/powerpc/kasan.txt
@@ -0,0 +1,12 @@
+KASAN is supported on powerpc on 32-bit 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 optional, unless built with modules,
+in which case it is required.
--
2.20.1
^ permalink raw reply related
* [PATCH v7 1/4] kasan: define and use MAX_PTRS_PER_* for early shadow tables
From: Daniel Axtens @ 2020-02-13 0:47 UTC (permalink / raw)
To: linux-kernel, linux-mm, linuxppc-dev, kasan-dev, christophe.leroy,
aneesh.kumar, bsingharora
Cc: Daniel Axtens
In-Reply-To: <20200213004752.11019-1-dja@axtens.net>
powerpc has a variable number of PTRS_PER_*, set at runtime based
on the MMU that the kernel is booted under.
This means the PTRS_PER_* are no longer constants, and therefore
breaks the build.
Define default MAX_PTRS_PER_*s in the same style as MAX_PTRS_PER_P4D.
As KASAN is the only user at the moment, just define them in the kasan
header, and have them default to PTRS_PER_* unless overridden in arch
code.
Suggested-by: Christophe Leroy <christophe.leroy@c-s.fr>
Suggested-by: Balbir Singh <bsingharora@gmail.com>
Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: Balbir Singh <bsingharora@gmail.com>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
include/linux/kasan.h | 18 +++++++++++++++---
mm/kasan/init.c | 6 +++---
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 5cde9e7c2664..b3a4500633f5 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -14,10 +14,22 @@ struct task_struct;
#include <asm/kasan.h>
#include <asm/pgtable.h>
+#ifndef MAX_PTRS_PER_PTE
+#define MAX_PTRS_PER_PTE PTRS_PER_PTE
+#endif
+
+#ifndef MAX_PTRS_PER_PMD
+#define MAX_PTRS_PER_PMD PTRS_PER_PMD
+#endif
+
+#ifndef MAX_PTRS_PER_PUD
+#define MAX_PTRS_PER_PUD PTRS_PER_PUD
+#endif
+
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 pte_t kasan_early_shadow_pte[MAX_PTRS_PER_PTE];
+extern pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD];
+extern pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD];
extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D];
int kasan_populate_early_shadow(const void *shadow_start,
diff --git a/mm/kasan/init.c b/mm/kasan/init.c
index ce45c491ebcd..8b54a96d3b3e 100644
--- a/mm/kasan/init.c
+++ b/mm/kasan/init.c
@@ -46,7 +46,7 @@ static inline bool kasan_p4d_table(pgd_t pgd)
}
#endif
#if CONFIG_PGTABLE_LEVELS > 3
-pud_t kasan_early_shadow_pud[PTRS_PER_PUD] __page_aligned_bss;
+pud_t kasan_early_shadow_pud[MAX_PTRS_PER_PUD] __page_aligned_bss;
static inline bool kasan_pud_table(p4d_t p4d)
{
return p4d_page(p4d) == virt_to_page(lm_alias(kasan_early_shadow_pud));
@@ -58,7 +58,7 @@ static inline bool kasan_pud_table(p4d_t p4d)
}
#endif
#if CONFIG_PGTABLE_LEVELS > 2
-pmd_t kasan_early_shadow_pmd[PTRS_PER_PMD] __page_aligned_bss;
+pmd_t kasan_early_shadow_pmd[MAX_PTRS_PER_PMD] __page_aligned_bss;
static inline bool kasan_pmd_table(pud_t pud)
{
return pud_page(pud) == virt_to_page(lm_alias(kasan_early_shadow_pmd));
@@ -69,7 +69,7 @@ static inline bool kasan_pmd_table(pud_t pud)
return false;
}
#endif
-pte_t kasan_early_shadow_pte[PTRS_PER_PTE] __page_aligned_bss;
+pte_t kasan_early_shadow_pte[MAX_PTRS_PER_PTE] __page_aligned_bss;
static inline bool kasan_pte_table(pmd_t pmd)
{
--
2.20.1
^ permalink raw reply related
* [PATCH v7 0/4] KASAN for powerpc64 radix
From: Daniel Axtens @ 2020-02-13 0:47 UTC (permalink / raw)
To: linux-kernel, linux-mm, linuxppc-dev, kasan-dev, christophe.leroy,
aneesh.kumar, bsingharora
Cc: 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.
This provides full inline instrumentation on radix, but does require
that you be able to specify the amount of physically contiguous memory
on the system at compile time. More details in patch 4.
v7: Tweaks from Christophe, fix issues detected by snowpatch.
v6: Rebase on the latest changes in powerpc/merge. Minor tweaks
to the documentation. Small tweaks to the header to work
with the kasan_late_init() function that Christophe added
for 32-bit kasan-vmalloc support.
No functional change.
v5: ptdump support. More cleanups, tweaks and fixes, thanks
Christophe. Details in patch 4.
I have seen another stack walk splat, but I don't think it's
related to the patch set, I think there's a bug somewhere else,
probably in stack frame manipulation in the kernel or (more
unlikely) in the compiler.
v4: More cleanups, split renaming out, clarify bits and bobs.
Drop the stack walk disablement, that isn't needed. No other
functional change.
v3: Reduce the overly ambitious scope of the MAX_PTRS change.
Document more things, including around why some of the
restrictions apply.
Clean up the code more, thanks Christophe.
v2: The big change is the introduction of tree-wide(ish)
MAX_PTRS_PER_{PTE,PMD,PUD} macros in preference to the previous
approach, which was for the arch to override the page table array
definitions with their own. (And I squashed the annoying
intermittent crash!)
Apart from that there's just a lot of cleanup. Christophe, I've
addressed most of what you asked for and I will reply to your v1
emails to clarify what remains unchanged.
^ permalink raw reply
* [Bug 206501] Kernel 5.6-rc1 fails to boot on a PowerMac G4 3,6 with CONFIG_VMAP_STACK=y: Oops! Machine check, sig: 7 [#1]
From: bugzilla-daemon @ 2020-02-12 18:15 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-206501-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=206501
--- Comment #6 from Christophe Leroy (christophe.leroy@c-s.fr) ---
I found the reason I think. I just realised that the things saved to SPRN_SPRG
and in thread struct get overwriten by the DSI taken at stack write.
I'll prepare something to fix that.
--
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* Re: QEMU/KVM snapshot restore bug
From: dftxbs3e @ 2020-02-12 17:59 UTC (permalink / raw)
To: Greg Kurz; +Cc: linuxppc-dev, Cédric Le Goater
In-Reply-To: <20200212120508.18be4f0c@bahia.lan>
[-- Attachment #1.1: Type: text/plain, Size: 3912 bytes --]
Hello,
> A big endian guest doing XIVE ?!? I'm pretty sure we didn't do much testing, if
> any, on such a setup... What distro is used in the VM ?
A live Void Linux ISO ;
https://repo.voidlinux-ppc.org/live/current/void-live-ppc64-20190901.iso
> This indicates that QEMU failed to configure the source targeting
> for the HW interrupt 0x1309, which is an MSI interrupt used by
> a PCI device plugged in the default PHB. Especially, -EBUSY means
>
> -EBUSY: No CPU available to serve interrupt
>
Okay.
> This warning means that we have vCPU without a configured event queue.
>
> Since kvmppc_xive_select_target() is trying all vCPUs before bailing out
> with -EBUSY, you might be seeing several WARNINGs (1 per vCPU) in dmesg,
> correct ?
>
> Anyway, this looks wrong since QEMU is supposed to have already configured
> the event queues at this point... Not sure what's happening here...
>
Indeed. VM core count + 1 such messages in dmesg.
> Yeah, QEMU command line, QEMU version, guest kernel version can help. Also,
> what kind of workload is running inside the guest ? Is this easy to reproduce ?
/usr/bin/qemu-system-ppc64 -name guest=voidlinux-ppc64,debug-threads=on
-S -object
secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-13-voidlinux-ppc64/master-key.aes
-machine pseries-4.1,accel=kvm,usb=off,dump-guest-core=off -m 8192
-overcommit mem-lock=off -smp 8,sockets=8,cores=1,threads=1 -uuid
5dd7af48-f00d-43c1-86ed-df5e0f7b4f1c -no-user-config -nodefaults
-chardev socket,id=charmonitor,fd=41,server,nowait -mon
chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown
-boot strict=on -device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.0,addr=0x2
-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x3 -device
virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4 -drive
file=/var/lib/libvirt/images/voidlinux-ppc64.qcow2,format=qcow2,if=none,id=drive-virtio-disk0
-device
virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
-drive
file=/home/jdoe/Downloads/void-live-ppc64-20190901.iso,format=raw,if=none,id=drive-scsi0-0-0-0,readonly=on
-device
scsi-cd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi0-0-0-0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=2
-netdev tap,fd=43,id=hostnet0,vhost=on,vhostfd=44 -device
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:ae:d7:62,bus=pci.0,addr=0x1
-chardev pty,id=charserial0 -device
spapr-vty,chardev=charserial0,id=serial0,reg=0x30000000 -chardev
socket,id=charchannel0,fd=45,server,nowait -device
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0
-device usb-tablet,id=input0,bus=usb.0,port=1 -device
usb-kbd,id=input1,bus=usb.0,port=2 -vnc 127.0.0.1:2 -device
VGA,id=video0,vgamem_mb=16,bus=pci.0,addr=0x8 -device
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6 -object
rng-random,id=objrng0,filename=/dev/urandom -device
virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0x7 -loadvm
guix-gentoo -sandbox
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny
-msg timestamp=on
I am using virt-manager, which is why the command line is so long.
And ;
$ qemu-system-ppc64 --version
QEMU emulator version 4.1.1 (qemu-4.1.1-1.fc31)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
Workload at snapshot time, the VM was idle, I was compiling software
using a Gentoo ppc64 big endian chroot inside the Void Linux ppc64 big
endian headless live system.
And yes it is easy to reproduce, download that Void Linux ppc64 big
endian ISO, using virt-manager, create a ppc64 vm with a disk, set the
VM to 8192MB of RAM and 8 cores (less RAM and cores might work,
untested) and it should reproduce the issue. It seems that a 1 core,
512MB of RAM VM suffers from no issue with snapshotting.
Thanks!
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH V12] mm/debug: Add tests validating architecture page table helpers
From: Gerald Schaefer @ 2020-02-12 17:55 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra,
Catalin Marinas, Heiko Carstens, Michal Hocko, linux-mm,
Paul Mackerras, sparclinux, Ingo Molnar, linux-s390,
Jason Gunthorpe, x86, Russell King - ARM Linux, Matthew Wilcox,
Steven Price, Tetsuo Handa, Vlastimil Babka, James Hogan,
linux-snps-arc, Kees Cook, Masahiro Yamada, Dan Williams,
Mark Brown, Kirill A . Shutemov, Thomas Gleixner,
linux-arm-kernel, Sri Krishna chowdary, Dave Hansen,
Greg Kroah-Hartman, Ard Biesheuvel, linux-mips, Ralf Baechle,
linux-kernel, Paul Burton, Mike Rapoport, Vineet Gupta,
Martin Schwidefsky, Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <b169ff9d-7b87-91f4-b3d0-e97f86680d0c@arm.com>
On Wed, 12 Feb 2020 15:12:54 +0530
Anshuman Khandual <anshuman.khandual@arm.com> wrote:
> >> +/*
> >> + * On s390 platform, the lower 12 bits are used to identify given page table
> >> + * entry type and for other arch specific requirements. But these bits might
> >> + * affect the ability to clear entries with pxx_clear(). So while loading up
> >> + * the entries skip all lower 12 bits in order to accommodate s390 platform.
> >> + * It does not have affect any other platform.
> >> + */
> >> +#define RANDOM_ORVALUE (0xfffffffffffff000UL)
> >
> > I'd suggest you generate this mask with something like
> > GENMASK(BITS_PER_LONG, PAGE_SHIFT).
>
> IIRC the lower 12 bits constrains on s390 platform might not be really related
> to it's PAGE_SHIFT which can be a variable, but instead just a constant number.
> But can definitely use GENMASK or it's variants here.
>
> https://lkml.org/lkml/2019/9/5/862
PAGE_SHIFT would be fine, it is 12 on s390. However, in order to be
more precise, we do not really need all 12 bits, only the last 4 bits.
So, something like this would work:
#define RANDOM_ORVALUE GENMASK(BITS_PER_LONG - 1, 4)
The text in the comment could then also be changed from 12 to 4, and
be a bit more specific on the fact that the impact on pxx_clear()
results from the dynamic page table folding logic on s390:
/*
* On s390 platform, the lower 4 bits are used to identify given page table
* entry type. But these bits might affect the ability to clear entries with
* pxx_clear() because of how dynamic page table folding works on s390. So
* while loading up the entries do not change the lower 4 bits.
* It does not have affect any other platform.
*/
^ permalink raw reply
* [Bug 206501] Kernel 5.6-rc1 fails to boot on a PowerMac G4 3,6 with CONFIG_VMAP_STACK=y: Oops! Machine check, sig: 7 [#1]
From: bugzilla-daemon @ 2020-02-12 17:47 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-206501-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=206501
--- Comment #5 from Christophe Leroy (christophe.leroy@c-s.fr) ---
Interesting.
NIP: 00000550
NIP: 0000045c
NIP: 00000c38
NIP: 00000370
The kernel seems to badly fault on the first write to the stack. This suggests
that there is no page allocated for the stack yet. Which is unexpected because
in copy_thread_tls() several writes to the stack are performed so the pages
must exist in page tables.
--
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* Re: [PATCH 2/3] ASoC: dt-bindings: fsl_easrc: Add document for EASRC
From: Fabio Estevam @ 2020-02-12 17:24 UTC (permalink / raw)
To: Shengjiu Wang
Cc: Mark Rutland,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Linux-ALSA, Timur Tabi, Xiubo Li, linux-kernel, Takashi Iwai,
Liam Girdwood, Rob Herring, Jaroslav Kysela, Nicolin Chen,
Mark Brown, linuxppc-dev
In-Reply-To: <1ae9af586a2003e23885ccc7ef58ee2b1dce29f7.1581475981.git.shengjiu.wang@nxp.com>
On Wed, Feb 12, 2020 at 1:35 AM Shengjiu Wang <shengjiu.wang@nxp.com> wrote:
>
> EASRC (Enhanced Asynchronous Sample Rate Converter) is a new
> IP module found on i.MX815.
i.MX815 in an internal terminology. Please avoid it on the commit log.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> ---
> .../devicetree/bindings/sound/fsl,easrc.txt | 57 +++++++++++++++++++
> 1 file changed, 57 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/sound/fsl,easrc.txt
>
> diff --git a/Documentation/devicetree/bindings/sound/fsl,easrc.txt b/Documentation/devicetree/bindings/sound/fsl,easrc.txt
> new file mode 100644
> index 000000000000..0e8153165e3b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/fsl,easrc.txt
> @@ -0,0 +1,57 @@
> +NXP Asynchronous Sample Rate Converter (ASRC) Controller
> +
> +The Asynchronous Sample Rate Converter (ASRC) converts the sampling rate of a
> +signal associated with an input clock into a signal associated with a different
> +output clock. The driver currently works as a Front End of DPCM with other Back
> +Ends Audio controller such as ESAI, SSI and SAI. It has four context to support
> +four substreams within totally 32 channels.
> +
> +Required properties:
> +- compatible: Contains "fsl,imx8mn-easrc".
> +
> +- reg: Offset and length of the register set for the
> + device.
> +
> +- interrupts: Contains the asrc interrupt.
> +
> +- dmas: Generic dma devicetree binding as described in
> + Documentation/devicetree/bindings/dma/dma.txt.
> +
> +- dma-names: Contains "ctx0_rx", "ctx0_tx",
> + "ctx1_rx", "ctx1_tx",
> + "ctx2_rx", "ctx2_tx",
> + "ctx3_rx", "ctx3_tx".
> +
> +- clocks: Contains an entry for each entry in clock-names.
> +
> +- clock-names: "mem" - Peripheral clock to driver module.
> +
> +- fsl,easrc-ram-script-name: The coefficient table for the filters
> +
> +- fsl,asrc-rate: Defines a mutual sample rate used by DPCM Back
> + Ends.
> +
> +- fsl,asrc-width: Defines a mutual sample width used by DPCM Back
> + Ends.
> +
> +Example:
> +
> +easrc: easrc@300C0000 {
> + compatible = "fsl,imx8mn-easrc";
> + reg = <0x0 0x300C0000 0x0 0x10000>;
> + interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clk IMX8MN_CLK_ASRC_ROOT>;
> + clock-names = "mem";
> + dmas = <&sdma2 16 23 0> , <&sdma2 17 23 0>,
> + <&sdma2 18 23 0> , <&sdma2 19 23 0>,
> + <&sdma2 20 23 0> , <&sdma2 21 23 0>,
> + <&sdma2 22 23 0> , <&sdma2 23 23 0>;
> + dma-names = "ctx0_rx", "ctx0_tx",
> + "ctx1_rx", "ctx1_tx",
> + "ctx2_rx", "ctx2_tx",
> + "ctx3_rx", "ctx3_tx";
> + fsl,easrc-ram-script-name = "imx/easrc/easrc-imx8mn.bin";
> + fsl,asrc-rate = <8000>;
> + fsl,asrc-width = <16>;
> + status = "disabled";
> +};
> --
> 2.21.0
>
^ permalink raw reply
* Re: [PATCH v5 01/10] capabilities: introduce CAP_PERFMON to kernel and user space
From: Stephen Smalley @ 2020-02-12 17:09 UTC (permalink / raw)
To: Alexey Budankov
Cc: Mark Rutland, Song Liu, Peter Zijlstra,
joonas.lahtinen@linux.intel.com, Will Deacon, Alexei Starovoitov,
Stephane Eranian, james.bottomley@hansenpartnership.com,
Paul Mackerras, Jiri Olsa, Alexei Starovoitov, Andi Kleen,
Igor Lubashev, James Morris, Alexander Shishkin, Ingo Molnar,
oprofile-list, Serge Hallyn, Robert Richter,
selinux@vger.kernel.org, intel-gfx@lists.freedesktop.org,
jani.nikula@linux.intel.com, Arnaldo Carvalho de Melo,
rodrigo.vivi@intel.com, Namhyung Kim, Thomas Gleixner,
linux-arm-kernel, linux-parisc@vger.kernel.org, linux-kernel,
Lionel Landwerlin, Andy Lutomirski,
linux-perf-users@vger.kernel.org,
linux-security-module@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <950cc6a4-5823-d607-1210-6f62c96cf67f@linux.intel.com>
On 2/12/20 11:56 AM, Alexey Budankov wrote:
>
>
> On 12.02.2020 18:45, Stephen Smalley wrote:
>> On 2/12/20 10:21 AM, Stephen Smalley wrote:
>>> On 2/12/20 8:53 AM, Alexey Budankov wrote:
>>>> On 12.02.2020 16:32, Stephen Smalley wrote:
>>>>> On 2/12/20 3:53 AM, Alexey Budankov wrote:
>>>>>> Hi Stephen,
>>>>>>
>>>>>> On 22.01.2020 17:07, Stephen Smalley wrote:
>>>>>>> On 1/22/20 5:45 AM, Alexey Budankov wrote:
>>>>>>>>
>>>>>>>> On 21.01.2020 21:27, Alexey Budankov wrote:
>>>>>>>>>
>>>>>>>>> On 21.01.2020 20:55, Alexei Starovoitov wrote:
>>>>>>>>>> On Tue, Jan 21, 2020 at 9:31 AM Alexey Budankov
>>>>>>>>>> <alexey.budankov@linux.intel.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On 21.01.2020 17:43, Stephen Smalley wrote:
>>>>>>>>>>>> On 1/20/20 6:23 AM, Alexey Budankov wrote:
>>>>>>>>>>>>>
>>>>>> <SNIP>
>>>>>>>>>>>>> Introduce CAP_PERFMON capability designed to secure system performance
>>>>>>>>>>>>
>>>>>>>>>>>> Why _noaudit()? Normally only used when a permission failure is non-fatal to the operation. Otherwise, we want the audit message.
>>>>>>>>
>>>>>>>> So far so good, I suggest using the simplest version for v6:
>>>>>>>>
>>>>>>>> static inline bool perfmon_capable(void)
>>>>>>>> {
>>>>>>>> return capable(CAP_PERFMON) || capable(CAP_SYS_ADMIN);
>>>>>>>> }
>>>>>>>>
>>>>>>>> It keeps the implementation simple and readable. The implementation is more
>>>>>>>> performant in the sense of calling the API - one capable() call for CAP_PERFMON
>>>>>>>> privileged process.
>>>>>>>>
>>>>>>>> Yes, it bloats audit log for CAP_SYS_ADMIN privileged and unprivileged processes,
>>>>>>>> but this bloating also advertises and leverages using more secure CAP_PERFMON
>>>>>>>> based approach to use perf_event_open system call.
>>>>>>>
>>>>>>> I can live with that. We just need to document that when you see both a CAP_PERFMON and a CAP_SYS_ADMIN audit message for a process, try only allowing CAP_PERFMON first and see if that resolves the issue. We have a similar issue with CAP_DAC_READ_SEARCH versus CAP_DAC_OVERRIDE.
>>>>>>
>>>>>> I am trying to reproduce this double logging with CAP_PERFMON.
>>>>>> I am using the refpolicy version with enabled perf_event tclass [1], in permissive mode.
>>>>>> When running perf stat -a I am observing this AVC audit messages:
>>>>>>
>>>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { open } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { kernel } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { cpu } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>>>> type=AVC msg=audit(1581496695.666:8692): avc: denied { write } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>>>>
>>>>>> However there is no capability related messages around. I suppose my refpolicy should
>>>>>> be modified somehow to observe capability related AVCs.
>>>>>>
>>>>>> Could you please comment or clarify on how to enable caps related AVCs in order
>>>>>> to test the concerned logging.
>>>>>
>>>>> The new perfmon permission has to be defined in your policy; you'll have a message in dmesg about "Permission perfmon in class capability2 not defined in policy.". You can either add it to the common cap2 definition in refpolicy/policy/flask/access_vectors and rebuild your policy or extract your base module as CIL, add it there, and insert the updated module.
>>>>
>>>> Yes, I already have it like this:
>>>> common cap2
>>>> {
>>>> <------>mac_override<--># unused by SELinux
>>>> <------>mac_admin
>>>> <------>syslog
>>>> <------>wake_alarm
>>>> <------>block_suspend
>>>> <------>audit_read
>>>> <------>perfmon
>>>> }
>>>>
>>>> dmesg stopped reporting perfmon as not defined but audit.log still doesn't report CAP_PERFMON denials.
>>>> BTW, audit even doesn't report CAP_SYS_ADMIN denials, however perfmon_capable() does check for it.
>>>
>>> Some denials may be silenced by dontaudit rules; semodule -DB will strip those and semodule -B will restore them. Other possibility is that the process doesn't have CAP_PERFMON in its effective set and therefore never reaches SELinux at all; denied first by the capability module.
>>
>> Also, the fact that your denials are showing up in user_systemd_t suggests that something is off in your policy or userspace/distro; I assume that is a domain type for the systemd --user instance, but your shell and commands shouldn't be running in that domain (user_t would be more appropriate for that).
>
> It is user_t for local terminal session:
> ps -Z
> LABEL PID TTY TIME CMD
> user_u:user_r:user_t 11317 pts/9 00:00:00 bash
> user_u:user_r:user_t 11796 pts/9 00:00:00 ps
>
> For local terminal root session:
> ps -Z
> LABEL PID TTY TIME CMD
> user_u:user_r:user_su_t 2926 pts/3 00:00:00 bash
> user_u:user_r:user_su_t 10995 pts/3 00:00:00 ps
>
> For remote ssh session:
> ps -Z
> LABEL PID TTY TIME CMD
> user_u:user_r:user_t 7540 pts/8 00:00:00 ps
> user_u:user_r:user_systemd_t 8875 pts/8 00:00:00 bash
That's a bug in either your policy or your userspace/distro integration.
In any event, unless user_systemd_t is allowed all capability2
permissions by your policy, you should see the denials if CAP_PERFMON is
set in the effective capability set of the process.
^ permalink raw reply
* Re: [PATCH] powerpc/time: Replace <linux/clk-provider.h> by <linux/of_clk.h>
From: Stephen Boyd @ 2020-02-12 17:04 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Geert Uytterhoeven, Michael Ellerman,
Paul Mackerras
Cc: linuxppc-dev, linux-clk, Geert Uytterhoeven, linux-kernel
In-Reply-To: <20200212101736.9126-1-geert+renesas@glider.be>
Quoting Geert Uytterhoeven (2020-02-12 02:17:36)
> The PowerPC time code is not a clock provider, and just needs to call
> of_clk_init().
>
> Hence it can include <linux/of_clk.h> instead of <linux/clk-provider.h>.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
This has an ifdef around the of_clk_init() call. Can you remove that too
given that we stub it out in the header?
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox