* [PATCH] btrfs: fix allocation of bitmap pages.
From: Christophe Leroy @ 2019-08-17 7:44 UTC (permalink / raw)
To: erhard_f, Chris Mason, Josef Bacik, David Sterba, Andrew Morton
Cc: linux-mm, stable, linuxppc-dev, linux-kernel, linux-btrfs
Various notifications of type "BUG kmalloc-4096 () : Redzone
overwritten" have been observed recently in various parts of
the kernel. After some time, it has been made a relation with
the use of BTRFS filesystem.
[ 22.809700] BUG kmalloc-4096 (Tainted: G W ): Redzone overwritten
[ 22.809971] -----------------------------------------------------------------------------
[ 22.810286] INFO: 0xbe1a5921-0xfbfc06cd. First byte 0x0 instead of 0xcc
[ 22.810866] INFO: Allocated in __load_free_space_cache+0x588/0x780 [btrfs] age=22 cpu=0 pid=224
[ 22.811193] __slab_alloc.constprop.26+0x44/0x70
[ 22.811345] kmem_cache_alloc_trace+0xf0/0x2ec
[ 22.811588] __load_free_space_cache+0x588/0x780 [btrfs]
[ 22.811848] load_free_space_cache+0xf4/0x1b0 [btrfs]
[ 22.812090] cache_block_group+0x1d0/0x3d0 [btrfs]
[ 22.812321] find_free_extent+0x680/0x12a4 [btrfs]
[ 22.812549] btrfs_reserve_extent+0xec/0x220 [btrfs]
[ 22.812785] btrfs_alloc_tree_block+0x178/0x5f4 [btrfs]
[ 22.813032] __btrfs_cow_block+0x150/0x5d4 [btrfs]
[ 22.813262] btrfs_cow_block+0x194/0x298 [btrfs]
[ 22.813484] commit_cowonly_roots+0x44/0x294 [btrfs]
[ 22.813718] btrfs_commit_transaction+0x63c/0xc0c [btrfs]
[ 22.813973] close_ctree+0xf8/0x2a4 [btrfs]
[ 22.814107] generic_shutdown_super+0x80/0x110
[ 22.814250] kill_anon_super+0x18/0x30
[ 22.814437] btrfs_kill_super+0x18/0x90 [btrfs]
[ 22.814590] INFO: Freed in proc_cgroup_show+0xc0/0x248 age=41 cpu=0 pid=83
[ 22.814841] proc_cgroup_show+0xc0/0x248
[ 22.814967] proc_single_show+0x54/0x98
[ 22.815086] seq_read+0x278/0x45c
[ 22.815190] __vfs_read+0x28/0x17c
[ 22.815289] vfs_read+0xa8/0x14c
[ 22.815381] ksys_read+0x50/0x94
[ 22.815475] ret_from_syscall+0x0/0x38
Commit 69d2480456d1 ("btrfs: use copy_page for copying pages instead
of memcpy") changed the way bitmap blocks are copied. But allthough
bitmaps have the size of a page, they were allocated with kzalloc().
Most of the time, kzalloc() allocates aligned blocks of memory, so
copy_page() can be used. But when some debug options like SLAB_DEBUG
are activated, kzalloc() may return unaligned pointer.
On powerpc, memcpy(), copy_page() and other copying functions use
'dcbz' instruction which provides an entire zeroed cacheline to avoid
memory read when the intention is to overwrite a full line. Functions
like memcpy() are writen to care about partial cachelines at the start
and end of the destination, but copy_page() assumes it gets pages. As
pages are naturally cache aligned, copy_page() doesn't care about
partial lines. This means that when copy_page() is called with a
misaligned pointer, a few leading bytes are zeroed.
To fix it, allocate bitmaps with get_zeroed_page() instead of kzalloc()
Reported-by: Erhard F. <erhard_f@mailbox.org>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=204371
Fixes: 69d2480456d1 ("btrfs: use copy_page for copying pages instead of memcpy")
Cc: stable@vger.kernel.org
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Tested-by: Erhard F. <erhard_f@mailbox.org>
---
fs/btrfs/free-space-cache.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 062be9dde4c6..3229a058e025 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -764,7 +764,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
} else {
ASSERT(num_bitmaps);
num_bitmaps--;
- e->bitmap = kzalloc(PAGE_SIZE, GFP_NOFS);
+ e->bitmap = (void *)get_zeroed_page(GFP_NOFS);
if (!e->bitmap) {
kmem_cache_free(
btrfs_free_space_cachep, e);
@@ -1881,7 +1881,7 @@ static void free_bitmap(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *bitmap_info)
{
unlink_free_space(ctl, bitmap_info);
- kfree(bitmap_info->bitmap);
+ free_page((unsigned long)bitmap_info->bitmap);
kmem_cache_free(btrfs_free_space_cachep, bitmap_info);
ctl->total_bitmaps--;
ctl->op->recalc_thresholds(ctl);
@@ -2135,7 +2135,7 @@ static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl,
}
/* allocate the bitmap */
- info->bitmap = kzalloc(PAGE_SIZE, GFP_NOFS);
+ info->bitmap = (void *)get_zeroed_page(GFP_NOFS);
spin_lock(&ctl->tree_lock);
if (!info->bitmap) {
ret = -ENOMEM;
@@ -2146,7 +2146,7 @@ static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl,
out:
if (info) {
- kfree(info->bitmap);
+ free_page((unsigned long)info->bitmap);
kmem_cache_free(btrfs_free_space_cachep, info);
}
@@ -2802,7 +2802,7 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
if (entry->bytes == 0) {
ctl->free_extents--;
if (entry->bitmap) {
- kfree(entry->bitmap);
+ free_page((unsigned long)entry->bitmap);
ctl->total_bitmaps--;
ctl->op->recalc_thresholds(ctl);
}
@@ -3606,7 +3606,7 @@ int test_add_free_space_entry(struct btrfs_block_group_cache *cache,
}
if (!map) {
- map = kzalloc(PAGE_SIZE, GFP_NOFS);
+ map = (void *)get_zeroed_page(GFP_NOFS);
if (!map) {
kmem_cache_free(btrfs_free_space_cachep, info);
return -ENOMEM;
@@ -3635,7 +3635,7 @@ int test_add_free_space_entry(struct btrfs_block_group_cache *cache,
if (info)
kmem_cache_free(btrfs_free_space_cachep, info);
- kfree(map);
+ free_page((unsigned long)map);
return 0;
}
--
2.17.1
^ permalink raw reply related
* Re: [Bug 204371] BUG kmalloc-4k (Tainted: G W ): Object padding overwritten
From: christophe leroy @ 2019-08-17 8:09 UTC (permalink / raw)
To: bugzilla-daemon, linuxppc-dev, Andrew Morton,
Linux Memory Management List, linux-btrfs, erhard_f, Chris Mason,
Josef Bacik, David Sterba, Michael Ellerman
In-Reply-To: <bug-204371-206035-O9m4mwJN9f@https.bugzilla.kernel.org/>
Le 30/07/2019 à 20:52, bugzilla-daemon@bugzilla.kernel.org a écrit :
> https://bugzilla.kernel.org/show_bug.cgi?id=204371
>
> --- Comment #2 from Andrew Morton (akpm@linux-foundation.org) ---
> (switched to email. Please respond via emailed reply-to-all, not via the
> bugzilla web interface).
Reply all replies to bugzilla-daemon@bugzilla.kernel.org only.
[...]
>
> cc'ing various people here.
Hum ... only got that email through the bugzilla interface, and CC'ed
people don't show up.
>
> I suspect proc_cgroup_show() is innocent and that perhaps
> bpf_prepare_filter() had a memory scribble. iirc there has been at
> least one recent pretty serious bpf fix applied recently. Can others
> please take a look?
>
> (Seriously - please don't modify this report via the bugzilla web interface!)
>
Haven't got the original CC'ed list, so please reply with missing Cc's
if any.
We have well progressed on this case.
Erhard made a relation being this "Object padding overwritten" issue
arising on any driver, and the presence of the BTRFS driver.
Then he was able to bisect the issue to:
commit 69d2480456d1baf027a86e530989d7bedd698d5f
Author: David Sterba <dsterba@suse.com>
Date: Fri Jun 29 10:56:44 2018 +0200
btrfs: use copy_page for copying pages instead of memcpy
Use the helper that's possibly optimized for full page copies.
Signed-off-by: David Sterba <dsterba@suse.com>
After looking in the code, it has appeared that some of the said "pages"
were allocated with "kzalloc()".
Using the patch https://patchwork.ozlabs.org/patch/1148033/ Erhard
confirmed that some btrfs functions were calling copy_page() with
misaligned destinations.
copy_page(), at least on powerpc, expects cache aligned destination.
The patch https://patchwork.ozlabs.org/patch/1148606/ fixes the issue.
Christophe
---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus
^ permalink raw reply
* [Bug 204371] BUG kmalloc-4k (Tainted: G W ): Object padding overwritten
From: bugzilla-daemon @ 2019-08-17 8:09 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-204371-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=204371
--- Comment #38 from Christophe Leroy (christophe.leroy@c-s.fr) ---
Le 30/07/2019 à 20:52, bugzilla-daemon@bugzilla.kernel.org a écrit :
> https://bugzilla.kernel.org/show_bug.cgi?id=204371
>
> --- Comment #2 from Andrew Morton (akpm@linux-foundation.org) ---
> (switched to email. Please respond via emailed reply-to-all, not via the
> bugzilla web interface).
Reply all replies to bugzilla-daemon@bugzilla.kernel.org only.
[...]
>
> cc'ing various people here.
Hum ... only got that email through the bugzilla interface, and CC'ed
people don't show up.
>
> I suspect proc_cgroup_show() is innocent and that perhaps
> bpf_prepare_filter() had a memory scribble. iirc there has been at
> least one recent pretty serious bpf fix applied recently. Can others
> please take a look?
>
> (Seriously - please don't modify this report via the bugzilla web interface!)
>
Haven't got the original CC'ed list, so please reply with missing Cc's
if any.
We have well progressed on this case.
Erhard made a relation being this "Object padding overwritten" issue
arising on any driver, and the presence of the BTRFS driver.
Then he was able to bisect the issue to:
commit 69d2480456d1baf027a86e530989d7bedd698d5f
Author: David Sterba <dsterba@suse.com>
Date: Fri Jun 29 10:56:44 2018 +0200
btrfs: use copy_page for copying pages instead of memcpy
Use the helper that's possibly optimized for full page copies.
Signed-off-by: David Sterba <dsterba@suse.com>
After looking in the code, it has appeared that some of the said "pages"
were allocated with "kzalloc()".
Using the patch https://patchwork.ozlabs.org/patch/1148033/ Erhard
confirmed that some btrfs functions were calling copy_page() with
misaligned destinations.
copy_page(), at least on powerpc, expects cache aligned destination.
The patch https://patchwork.ozlabs.org/patch/1148606/ fixes the issue.
Christophe
---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel
antivirus Avast.
https://www.avast.com/antivirus
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply
* [PATCH] powerpc: optimise WARN_ON()
From: Christophe Leroy @ 2019-08-17 9:04 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Segher Boessenkool
Cc: linuxppc-dev, linux-kernel
Unlike BUG_ON(x), WARN_ON(x) uses !!(x) as the trigger
of the t(d/w)nei instruction instead of using directly the
value of x.
This leads to GCC adding unnecessary pair of addic/subfe. This was
revealed after adding a WARN_ON() on top of clear_page() in order
to detect misaligned destination:
@@ -49,6 +51,8 @@ static inline void clear_page(void *addr)
{
unsigned int i;
+ WARN_ON((unsigned long)addr & (L1_CACHE_BYTES - 1));
+
for (i = 0; i < PAGE_SIZE / L1_CACHE_BYTES; i++, addr += L1_CACHE_BYTES)
dcbz(addr);
}
This resulted on:
0000019c <clear_user_page>:
19c: 54 68 06 fe clrlwi r8,r3,27
1a0: 31 48 ff ff addic r10,r8,-1
1a4: 7d 4a 41 10 subfe r10,r10,r8
1a8: 0f 0a 00 00 twnei r10,0
1ac: 39 20 00 80 li r9,128
1b0: 7d 29 03 a6 mtctr r9
1b4: 7c 00 1f ec dcbz 0,r3
1b8: 38 63 00 20 addi r3,r3,32
1bc: 42 00 ff f8 bdnz 1b4 <clear_user_page+0x18>
1c0: 7c a3 2b 78 mr r3,r5
1c4: 48 00 00 00 b 1c4 <clear_user_page+0x28>
1c4: R_PPC_REL24 flush_dcache_page
By using (x) instead of !!(x) like BUG_ON() does, the additional
instructions go away:
0000019c <clear_user_page>:
19c: 54 6a 06 fe clrlwi r10,r3,27
1a0: 0f 0a 00 00 twnei r10,0
1a4: 39 20 00 80 li r9,128
1a8: 7d 29 03 a6 mtctr r9
1ac: 7c 00 1f ec dcbz 0,r3
1b0: 38 63 00 20 addi r3,r3,32
1b4: 42 00 ff f8 bdnz 1ac <clear_user_page+0x10>
1b8: 7c a3 2b 78 mr r3,r5
1bc: 48 00 00 00 b 1bc <clear_user_page+0x20>
1bc: R_PPC_REL24 flush_dcache_page
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/bug.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index fed7e6241349..77074582fe65 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -107,7 +107,7 @@
: : "i" (__FILE__), "i" (__LINE__), \
"i" (BUGFLAG_WARNING|BUGFLAG_TAINT(TAINT_WARN)),\
"i" (sizeof(struct bug_entry)), \
- "r" (__ret_warn_on)); \
+ "r" ((__force long)(x))); \
} \
unlikely(__ret_warn_on); \
})
--
2.17.1
^ permalink raw reply related
* Re: [PATCH] btrfs: fix allocation of bitmap pages.
From: Sasha Levin @ 2019-08-17 18:11 UTC (permalink / raw)
To: Sasha Levin, Christophe Leroy, erhard_f, Chris Mason
Cc: linuxppc-dev, linux-kernel, stable
In-Reply-To: <20190817074439.84C6C1056A3@localhost.localdomain>
Hi,
[This is an automated email]
This commit has been processed because it contains a "Fixes:" tag,
fixing commit: 69d2480456d1 btrfs: use copy_page for copying pages instead of memcpy.
The bot has tested the following trees: v5.2.9, v4.19.67.
v5.2.9: Build OK!
v4.19.67: Failed to apply! Possible dependencies:
f8b00e0f06e5 ("btrfs: remove unneeded NULL checks before kfree")
NOTE: The patch will not be queued to stable trees until it is upstream.
How should we proceed with this patch?
--
Thanks,
Sasha
^ permalink raw reply
* [RFC PATCH] powerpc: use __builtin_trap() in BUG/WARN macros.
From: Christophe Leroy @ 2019-08-17 18:37 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Segher Boessenkool
Cc: linuxppc-dev, linux-kernel
The below exemples of use of WARN_ON() show that the result
is sub-optimal in regard of the capabilities of powerpc.
void test_warn1(unsigned long long a)
{
WARN_ON(a);
}
void test_warn2(unsigned long a)
{
WARN_ON(a);
}
void test_warn3(unsigned long a, unsigned long b)
{
WARN_ON(a < b);
}
void test_warn4(unsigned long a, unsigned long b)
{
WARN_ON(!a);
}
void test_warn5(unsigned long a, unsigned long b)
{
WARN_ON(!a && b);
}
00000000 <test_warn1>:
0: 7c 64 23 78 or r4,r3,r4
4: 31 24 ff ff addic r9,r4,-1
8: 7c 89 21 10 subfe r4,r9,r4
c: 0f 04 00 00 twnei r4,0
10: 4e 80 00 20 blr
00000014 <test_warn2>:
14: 31 23 ff ff addic r9,r3,-1
18: 7c 69 19 10 subfe r3,r9,r3
1c: 0f 03 00 00 twnei r3,0
20: 4e 80 00 20 blr
00000024 <test_warn3>:
24: 7c 84 18 10 subfc r4,r4,r3
28: 7d 29 49 10 subfe r9,r9,r9
2c: 7d 29 00 d0 neg r9,r9
30: 0f 09 00 00 twnei r9,0
34: 4e 80 00 20 blr
00000038 <test_warn4>:
38: 7c 63 00 34 cntlzw r3,r3
3c: 54 63 d9 7e rlwinm r3,r3,27,5,31
40: 0f 03 00 00 twnei r3,0
44: 4e 80 00 20 blr
00000048 <test_warn5>:
48: 2f 83 00 00 cmpwi cr7,r3,0
4c: 39 20 00 00 li r9,0
50: 41 9e 00 0c beq cr7,5c <test_warn5+0x14>
54: 7c 84 00 34 cntlzw r4,r4
58: 54 89 d9 7e rlwinm r9,r4,27,5,31
5c: 0f 09 00 00 twnei r9,0
60: 4e 80 00 20 blr
RELOCATION RECORDS FOR [__bug_table]:
OFFSET TYPE VALUE
00000000 R_PPC_ADDR32 .text+0x0000000c
0000000c R_PPC_ADDR32 .text+0x0000001c
00000018 R_PPC_ADDR32 .text+0x00000030
00000018 R_PPC_ADDR32 .text+0x00000030
00000024 R_PPC_ADDR32 .text+0x00000040
00000030 R_PPC_ADDR32 .text+0x0000005c
Using __builtin_trap() instead of inline assembly of twnei/tdnei
provides a far better result:
00000000 <test_warn1>:
0: 7c 64 23 78 or r4,r3,r4
4: 0f 04 00 00 twnei r4,0
8: 4e 80 00 20 blr
0000000c <test_warn2>:
c: 0f 03 00 00 twnei r3,0
10: 4e 80 00 20 blr
00000014 <test_warn3>:
14: 7c 43 20 08 twllt r3,r4
18: 4e 80 00 20 blr
0000001c <test_warn4>:
1c: 0c 83 00 00 tweqi r3,0
20: 4e 80 00 20 blr
00000024 <test_warn5>:
24: 2f 83 00 00 cmpwi cr7,r3,0
28: 41 9e 00 08 beq cr7,30 <test_warn5+0xc>
2c: 0c 84 00 00 tweqi r4,0
30: 4e 80 00 20 blr
RELOCATION RECORDS FOR [__bug_table]:
OFFSET TYPE VALUE
00000000 R_PPC_ADDR32 .text+0x00000004
0000000c R_PPC_ADDR32 .text+0x0000000c
00000018 R_PPC_ADDR32 .text+0x00000014
00000024 R_PPC_ADDR32 .text+0x0000001c
00000030 R_PPC_ADDR32 .text+0x0000002c
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/bug.h | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index fed7e6241349..1a37c8d30b78 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -44,14 +44,14 @@
#ifdef CONFIG_DEBUG_BUGVERBOSE
#define _EMIT_BUG_ENTRY \
".section __bug_table,\"aw\"\n" \
- "2:\t" PPC_LONG "1b, %0\n" \
+ "2:\t" PPC_LONG "1b - 4, %0\n" \
"\t.short %1, %2\n" \
".org 2b+%3\n" \
".previous\n"
#else
#define _EMIT_BUG_ENTRY \
".section __bug_table,\"aw\"\n" \
- "2:\t" PPC_LONG "1b\n" \
+ "2:\t" PPC_LONG "1b - 4\n" \
"\t.short %2\n" \
".org 2b+%3\n" \
".previous\n"
@@ -64,8 +64,9 @@
*/
#define BUG() do { \
+ __builtin_trap(); \
__asm__ __volatile__( \
- "1: twi 31,0,0\n" \
+ "1:\n" \
_EMIT_BUG_ENTRY \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (0), "i" (sizeof(struct bug_entry))); \
@@ -77,18 +78,20 @@
if (x) \
BUG(); \
} else { \
+ if (x) \
+ __builtin_trap(); \
__asm__ __volatile__( \
- "1: "PPC_TLNEI" %4,0\n" \
+ "1:\n" \
_EMIT_BUG_ENTRY \
: : "i" (__FILE__), "i" (__LINE__), "i" (0), \
- "i" (sizeof(struct bug_entry)), \
- "r" ((__force long)(x))); \
+ "i" (sizeof(struct bug_entry))); \
} \
} while (0)
#define __WARN_FLAGS(flags) do { \
+ __builtin_trap(); \
__asm__ __volatile__( \
- "1: twi 31,0,0\n" \
+ "1:\n" \
_EMIT_BUG_ENTRY \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (BUGFLAG_WARNING|(flags)), \
@@ -101,13 +104,14 @@
if (__ret_warn_on) \
__WARN(); \
} else { \
+ if (__ret_warn_on) \
+ __builtin_trap(); \
__asm__ __volatile__( \
- "1: "PPC_TLNEI" %4,0\n" \
+ "1:\n" \
_EMIT_BUG_ENTRY \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (BUGFLAG_WARNING|BUGFLAG_TAINT(TAINT_WARN)),\
- "i" (sizeof(struct bug_entry)), \
- "r" (__ret_warn_on)); \
+ "i" (sizeof(struct bug_entry))); \
} \
unlikely(__ret_warn_on); \
})
--
2.17.1
^ permalink raw reply related
* Re: [PATCH] powerpc/32: Add VDSO version of getcpu
From: kbuild test robot @ 2019-08-18 2:03 UTC (permalink / raw)
To: Christophe Leroy; +Cc: linux-kernel, Paul Mackerras, kbuild-all, linuxppc-dev
In-Reply-To: <740c6923c313ff0c0c2394480d5691465919b52f.1565953624.git.christophe.leroy@c-s.fr>
[-- Attachment #1: Type: text/plain, Size: 1544 bytes --]
Hi Christophe,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on linus/master]
[cannot apply to v5.3-rc4 next-20190816]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Christophe-Leroy/powerpc-32-Add-VDSO-version-of-getcpu/20190818-075346
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> arch/powerpc/kernel/vdso32/getcpu.S:22:28: error: operator '*' has no right operand
#elif defined (CONFIG_SMP)*/
^
vim +22 arch/powerpc/kernel/vdso32/getcpu.S
10
11 .text
12 /*
13 * Exact prototype of getcpu
14 *
15 * int __kernel_getcpu(unsigned *cpu, unsigned *node);
16 *
17 */
18 V_FUNCTION_BEGIN(__kernel_getcpu)
19 .cfi_startproc
20 #if defined(CONFIG_PPC64)
21 mfspr r5,SPRN_SPRG_VDSO_READ
> 22 #elif defined (CONFIG_SMP)*/
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6359 bytes --]
^ permalink raw reply
* Re: [PATCH 1/2] powerpc/64s: remplement power4_idle code in C
From: Michael Ellerman @ 2019-08-18 3:49 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev; +Cc: Nicholas Piggin
In-Reply-To: <20190711022404.18132-1-npiggin@gmail.com>
Nicholas Piggin <npiggin@gmail.com> writes:
> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
> index eee5bef736c8..64d5ffbb07d1 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -2286,15 +2286,6 @@ USE_FIXED_SECTION(virt_trampolines)
> __end_interrupts:
> DEFINE_FIXED_SYMBOL(__end_interrupts)
>
> -#ifdef CONFIG_PPC_970_NAP
> -EXC_COMMON_BEGIN(power4_fixup_nap)
> - andc r9,r9,r10
> - std r9,TI_LOCAL_FLAGS(r11)
> - ld r10,_LINK(r1) /* make idle task do the */
> - std r10,_NIP(r1) /* equivalent of a blr */
> - blr
> -#endif
This breaks ppc64_defconfig build with:
ERROR: start_text address is c000000000008100, should be c000000000008000
Due to:
c000000000008000 <0000001a.long_branch.power4_fixup_nap>:
c000000000008000: 48 03 5a b4 b c00000000003dab4 <power4_fixup_nap>
Moving power4_fixup_nap back into exceptions-64s.S seems to fix it.
cheers
^ permalink raw reply
* Re: [PATCH] powerpc: optimise WARN_ON()
From: Segher Boessenkool @ 2019-08-18 12:01 UTC (permalink / raw)
To: Christophe Leroy; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <20190817090442.C5FEF106613@localhost.localdomain>
On Sat, Aug 17, 2019 at 09:04:42AM +0000, Christophe Leroy wrote:
> Unlike BUG_ON(x), WARN_ON(x) uses !!(x) as the trigger
> of the t(d/w)nei instruction instead of using directly the
> value of x.
>
> This leads to GCC adding unnecessary pair of addic/subfe.
And it has to, it is passed as an "r" to an asm, GCC has to put the "!!"
value into a register.
> By using (x) instead of !!(x) like BUG_ON() does, the additional
> instructions go away:
But is it correct? What happens if you pass an int to WARN_ON, on a
64-bit kernel?
(You might want to have 64-bit generate either tw or td. But, with
your __builtin_trap patch, all that will be automatic).
Segher
^ permalink raw reply
* Re: [RFC PATCH] powerpc: use __builtin_trap() in BUG/WARN macros.
From: Segher Boessenkool @ 2019-08-18 12:20 UTC (permalink / raw)
To: Christophe Leroy; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <20190817183750.D3018106766@localhost.localdomain>
Hi Christophe,
On Sat, Aug 17, 2019 at 06:37:50PM +0000, Christophe Leroy wrote:
> #define BUG() do { \
> + __builtin_trap(); \
GCC will optimise away all code after this, it knows it is unreachable.
But you want to keep that BUG_ENTRY stuff I think?
The same will happen with a BUG_ON if the compiler can prove your
condition is always true.
> __asm__ __volatile__( \
> - "1: twi 31,0,0\n" \
> + "1:\n" \
> _EMIT_BUG_ENTRY \
> : : "i" (__FILE__), "i" (__LINE__), \
> "i" (0), "i" (sizeof(struct bug_entry))); \
(GCC wil generate a different trap btw; what is called "trap" as extended
mnemonic, that is, "tw 31,0,0", not the same thing as "twi", if that
matters for the exception handler).
Segher
^ permalink raw reply
* [PATCH] powerpc: Don't add -mabi= flags when building with Clang
From: Nathan Chancellor @ 2019-08-18 19:13 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: clang-built-linux, Nathan Chancellor, linuxppc-dev, linux-kernel
When building pseries_defconfig, building vdso32 errors out:
error: unknown target ABI 'elfv1'
Commit 4dc831aa8813 ("powerpc: Fix compiling a BE kernel with a
powerpc64le toolchain") added these flags to fix building GCC but
clang is multitargeted and does not need these flags. The ABI is
properly set based on the target triple, which is derived from
CROSS_COMPILE.
https://github.com/llvm/llvm-project/blob/llvmorg-9.0.0-rc2/clang/lib/Driver/ToolChains/Clang.cpp#L1782-L1804
-mcall-aixdesc is not an implemented flag in clang so it can be
safely excluded as well, see commit 238abecde8ad ("powerpc: Don't
use gcc specific options on clang").
pseries_defconfig successfully builds after this patch and
powernv_defconfig and ppc44x_defconfig don't regress.
Link: https://github.com/ClangBuiltLinux/linux/issues/240
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
---
arch/powerpc/Makefile | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index c345b79414a9..971b04bc753d 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -93,11 +93,13 @@ MULTIPLEWORD := -mmultiple
endif
ifdef CONFIG_PPC64
+ifndef CONFIG_CC_IS_CLANG
cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mabi=elfv1)
cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mcall-aixdesc)
aflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mabi=elfv1)
aflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mabi=elfv2
endif
+endif
ifndef CONFIG_CC_IS_CLANG
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mno-strict-align
@@ -144,6 +146,7 @@ endif
endif
CFLAGS-$(CONFIG_PPC64) := $(call cc-option,-mtraceback=no)
+ifndef CONFIG_CC_IS_CLANG
ifdef CONFIG_CPU_LITTLE_ENDIAN
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2,$(call cc-option,-mcall-aixdesc))
AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2)
@@ -152,6 +155,7 @@ CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1)
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcall-aixdesc)
AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1)
endif
+endif
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,$(call cc-option,-mminimal-toc))
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions)
--
2.23.0
^ permalink raw reply related
* [PATCH kernel] vfio/spapr_tce: Fix incorrect tce_iommu_group memory free
From: Alexey Kardashevskiy @ 2019-08-19 1:51 UTC (permalink / raw)
To: linuxppc-dev
Cc: kvm, Jose Ricardo Ziviani, Alexey Kardashevskiy, kvm-ppc,
Alex Williamson, David Gibson
The @tcegrp variable is used in 1) a loop over attached groups
2) it stores a pointer to a newly allocated tce_iommu_group if 1) found
nothing. However the error handler does not distinguish how we got there
and incorrectly releases memory for a found+incompatible group.
This fixes it by adding another error handling case.
Fixes: 0bd971676e68 ("powerpc/powernv/npu: Add compound IOMMU groups")
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
The bug is there since 2157e7b82f3b but it would not appear in practice
before 0bd971676e68, hence that "Fixes". Or it still should be
157e7b82f3b ("vfio: powerpc/spapr: Register memory and define IOMMU v2")
?
Found it when tried adding a "compound PE" (GPU + NPUs) to a container
with a passed through xHCI host. The compatibility test (->create_table
should be equal) treats them as incompatible which might a bug (or
we are just suboptimal here) on its own.
---
drivers/vfio/vfio_iommu_spapr_tce.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
index 8ce9ad21129f..babef8b00daf 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -1234,7 +1234,7 @@ static long tce_iommu_take_ownership_ddw(struct tce_container *container,
static int tce_iommu_attach_group(void *iommu_data,
struct iommu_group *iommu_group)
{
- int ret;
+ int ret = 0;
struct tce_container *container = iommu_data;
struct iommu_table_group *table_group;
struct tce_iommu_group *tcegrp = NULL;
@@ -1287,13 +1287,13 @@ static int tce_iommu_attach_group(void *iommu_data,
!table_group->ops->release_ownership) {
if (container->v2) {
ret = -EPERM;
- goto unlock_exit;
+ goto free_exit;
}
ret = tce_iommu_take_ownership(container, table_group);
} else {
if (!container->v2) {
ret = -EPERM;
- goto unlock_exit;
+ goto free_exit;
}
ret = tce_iommu_take_ownership_ddw(container, table_group);
if (!tce_groups_attached(container) && !container->tables[0])
@@ -1305,10 +1305,11 @@ static int tce_iommu_attach_group(void *iommu_data,
list_add(&tcegrp->next, &container->group_list);
}
-unlock_exit:
+free_exit:
if (ret && tcegrp)
kfree(tcegrp);
+unlock_exit:
mutex_unlock(&container->lock);
return ret;
--
2.17.1
^ permalink raw reply related
* Re: [PATCH 2/3] powerpc/64s/radix: all CPUs should flush local translation structure before turning MMU on
From: Michael Ellerman @ 2019-08-19 2:00 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev; +Cc: Aneesh Kumar K.V, Nicholas Piggin, kvm-ppc
In-Reply-To: <20190816040733.5737-3-npiggin@gmail.com>
Nicholas Piggin <npiggin@gmail.com> writes:
> Rather than sprinkle various translation structure invalidations
> around different places in early boot, have each CPU flush everything
> from its local translation structures before enabling its MMU.
>
> Radix guests can execute tlbie(l), so have them tlbiel_all in the same
> place as radix host does.
>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> arch/powerpc/mm/book3s64/radix_pgtable.c | 11 ++---------
> 1 file changed, 2 insertions(+), 9 deletions(-)
>
> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
> index d60cfa05447a..839e01795211 100644
> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
> @@ -382,11 +382,6 @@ static void __init radix_init_pgtable(void)
> */
> register_process_table(__pa(process_tb), 0, PRTB_SIZE_SHIFT - 12);
> pr_info("Process table %p and radix root for kernel: %p\n", process_tb, init_mm.pgd);
> - asm volatile("ptesync" : : : "memory");
> - asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
> - "r" (TLBIEL_INVAL_SET_LPID), "r" (0));
> - asm volatile("eieio; tlbsync; ptesync" : : : "memory");
> - trace_tlbie(0, 0, TLBIEL_INVAL_SET_LPID, 0, 2, 1, 1);
>
> /*
> * The init_mm context is given the first available (non-zero) PID,
> @@ -633,8 +628,7 @@ void __init radix__early_init_mmu(void)
> radix_init_pgtable();
> /* Switch to the guard PID before turning on MMU */
> radix__switch_mmu_context(NULL, &init_mm);
> - if (cpu_has_feature(CPU_FTR_HVMODE))
> - tlbiel_all();
> + tlbiel_all();
> }
This is oopsing for me in a guest on Power9:
[ 0.000000] radix-mmu: Page sizes from device-tree:
[ 0.000000] radix-mmu: Page size shift = 12 AP=0x0
[ 0.000000] radix-mmu: Page size shift = 16 AP=0x5
[ 0.000000] radix-mmu: Page size shift = 21 AP=0x1
[ 0.000000] radix-mmu: Page size shift = 30 AP=0x2
[ 0.000000] -> fw_vec5_feature_init()
[ 0.000000] <- fw_vec5_feature_init()
[ 0.000000] -> fw_hypertas_feature_init()
[ 0.000000] <- fw_hypertas_feature_init()
[ 0.000000] radix-mmu: Activating Kernel Userspace Execution Prevention
[ 0.000000] radix-mmu: Activating Kernel Userspace Access Prevention
[ 0.000000] lpar: Using radix MMU under hypervisor
[ 0.000000] radix-mmu: Mapped 0x0000000000000000-0x0000000040000000 with 1.00 GiB pages (exec)
[ 0.000000] radix-mmu: Mapped 0x0000000040000000-0x0000000100000000 with 1.00 GiB pages
[ 0.000000] radix-mmu: Process table (____ptrval____) and radix root for kernel: (____ptrval____)
[ 0.000000] Oops: Exception in kernel mode, sig: 4 [#1]
[ 0.000000] LE PAGE_SIZE=64K MMU=Radix MMU=Hash SMP NR_CPUS=2048 NUMA
[ 0.000000] Modules linked in:
[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.3.0-rc2-gcc-8.2.0-00063-gef906dcf7b75 #633
[ 0.000000] NIP: c0000000000838f8 LR: c000000001066864 CTR: c0000000000838c0
[ 0.000000] REGS: c000000001647c40 TRAP: 0700 Not tainted (5.3.0-rc2-gcc-8.2.0-00063-gef906dcf7b75)
[ 0.000000] MSR: 8000000000043003 <SF,FP,ME,RI,LE> CR: 48000222 XER: 20040000
[ 0.000000] CFAR: c0000000000839b4 IRQMASK: 1
[ 0.000000] GPR00: c000000001066864 c000000001647ed0 c000000001649700 0000000000000000
[ 0.000000] GPR04: c000000001608830 0000000000000000 0000000000000010 2000000000000000
[ 0.000000] GPR08: 0000000000000c00 0000000000000000 0000000000000002 726f6620746f6f72
[ 0.000000] GPR12: c0000000000838c0 c000000001930000 000000000dc5bef0 0000000001309e10
[ 0.000000] GPR16: 0000000001309c90 fffffffffffffffd 000000000dc5bef0 0000000001339800
[ 0.000000] GPR20: 0000000000000014 0000000001ac0000 000000000dc5bf38 000000000daf0000
[ 0.000000] GPR24: 0000000001f4000c c000000000000000 0000000000400000 c000000001802858
[ 0.000000] GPR28: c007ffffffffffff c000000001803954 c000000001681cb0 c000000001608830
[ 0.000000] NIP [c0000000000838f8] radix__tlbiel_all+0x48/0x110
[ 0.000000] LR [c000000001066864] radix__early_init_mmu+0x494/0x4c8
[ 0.000000] Call Trace:
[ 0.000000] [c000000001647ed0] [c000000001066820] radix__early_init_mmu+0x450/0x4c8 (unreliable)
[ 0.000000] [c000000001647f60] [c00000000105c628] early_setup+0x160/0x198
[ 0.000000] [c000000001647f90] [000000000000b460] 0xb460
[ 0.000000] Instruction dump:
[ 0.000000] 2b830001 39000002 409e00e8 3d220003 3929c318 e9290000 e9290010 75290002
[ 0.000000] 41820088 7c4004ac 39200000 79085564 <7d294224> 3940007f 39201000 38e00000
[ 0.000000] random: get_random_bytes called from print_oops_end_marker+0x40/0x80 with crng_init=0
[ 0.000000] ---[ end trace 0000000000000000 ]---
So I think we still need a HV check in there somewhere.
cheers
^ permalink raw reply
* Re: [PATCH v4 1/3] kasan: support backing vmalloc space with real shadow memory
From: Daniel Axtens @ 2019-08-19 3:58 UTC (permalink / raw)
To: Mark Rutland, Christophe Leroy
Cc: gor, x86, linux-kernel, kasan-dev, linux-mm, glider, luto,
aryabinin, linuxppc-dev, dvyukov
In-Reply-To: <20190816170813.GA7417@lakrids.cambridge.arm.com>
>> > Instead, share backing space across multiple mappings. Allocate
>> > a backing page the first time a mapping in vmalloc space uses a
>> > particular page of the shadow region. Keep this page around
>> > regardless of whether the mapping is later freed - in the mean time
>> > the page could have become shared by another vmalloc mapping.
>> >
>> > This can in theory lead to unbounded memory growth, but the vmalloc
>> > allocator is pretty good at reusing addresses, so the practical memory
>> > usage grows at first but then stays fairly stable.
>>
>> I guess people having gigabytes of memory don't mind, but I'm concerned
>> about tiny targets with very little amount of memory. I have boards with as
>> little as 32Mbytes of RAM. The shadow region for the linear space already
>> takes one eighth of the RAM. I'd rather avoid keeping unused shadow pages
>> busy.
>
> I think this depends on how much shadow would be in constant use vs what
> would get left unused. If the amount in constant use is sufficiently
> large (or the residue is sufficiently small), then it may not be
> worthwhile to support KASAN_VMALLOC on such small systems.
I'm not unsympathetic to the cause of small-memory systems, but this is
useful as-is for x86, especially for VMAP_STACK. arm64 and s390 have
already been able to make use of it as well. So unless the design is
going to make it difficult to extend to small-memory systems - if it
bakes in concepts or APIs that are going to make things harder - I think
it might be worth merging as is. (pending the fixes for documentation
nits etc that you point out.)
>> Each page of shadow memory represent 8 pages of real memory. Could we use
>> page_ref to count how many pieces of a shadow page are used so that we can
>> free it when the ref count decreases to 0.
I'm not sure how much of a difference it will make, but I'll have a look.
>> > This requires architecture support to actually use: arches must stop
>> > mapping the read-only zero page over portion of the shadow region that
>> > covers the vmalloc space and instead leave it unmapped.
>>
>> Why 'must' ? Couldn't we switch back and forth from the zero page to real
>> page on demand ?
This code as currently written will not work if the architecture maps
the zero page over the portion of the shadow region that covers the
vmalloc space. So it's an implementation 'must' rather than a laws of
the universe 'must'.
We could perhaps map the zero page, but:
- you have to be really careful to get it right. If you accidentally
map the zero page onto memory where you shouldn't, you may permit
memory accesses that you should catch.
We could ameliorate this by taking Mark's suggestion and mapping a
poision page over the vmalloc space instead.
- I'm not sure what benefit is provided by having something mapped vs
leaving a hole, other than making the fault addresses more obvious.
- This gets complex, especially to do swapping correctly with respect
to various architectures' quirks (see e.g. 56eecdb912b5 "mm: Use
ptep/pmdp_set_numa() for updating _PAGE_NUMA bit" - ppc64 at least
requires that set_pte_at is never called on a valid PTE).
>> If the zero page is not mapped for unused vmalloc space, bad memory accesses
>> will Oops on the shadow memory access instead of Oopsing on the real bad
>> access, making it more difficult to locate and identify the issue.
I suppose. It's pretty easy on at least x86 and my draft ppc64
implementation to identify when an access falls into the shadow region
and then to reverse engineer the memory access that was being checked
based on the offset. As Andy points out, the fault handler could do this
automatically.
> I agree this isn't nice, though FWIW this can already happen today for
> bad addresses that fall outside of the usual kernel address space. We
> could make the !KASAN_INLINE checks resilient to this by using
> probe_kernel_read() to check the shadow, and treating unmapped shadow as
> poison.
>
> It's also worth noting that flipping back and forth isn't generally safe
> unless going via an invalid table entry, so there'd still be windows
> where a bad access might not have shadow mapped.
>
> We'd need to reuse the common p4d/pud/pmd/pte tables for unallocated
> regions, or the tables alone would consume significant amounts of memory
> (e..g ~32GiB for arm64 defconfig), and thus we'd need to be able to
> switch all levels between pgd and pte, which is much more complicated.
>
> I strongly suspect that the additional complexity will outweigh the
> benefit.
>
I'm not opposed to this in principle but I am also concerned about the
complexity involved.
Regards,
Daniel
> [...]
>
>> > +#ifdef CONFIG_KASAN_VMALLOC
>> > +static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
>> > + void *unused)
>> > +{
>> > + unsigned long page;
>> > + pte_t pte;
>> > +
>> > + if (likely(!pte_none(*ptep)))
>> > + return 0;
>>
>> Prior to this, the zero shadow area should be mapped, and the test should
>> be:
>>
>> if (likely(pte_pfn(*ptep) != PHYS_PFN(__pa(kasan_early_shadow_page))))
>> return 0;
>
> As above, this would need a more comprehensive redesign, so I don't
> think it's worth going into that level of nit here. :)
>
> If we do try to use common shadow for unallocate VA ranges, it probably
> makes sense to have a common poison page that we can use, so that we can
> report vmalloc-out-of-bounfds.
>
> Thanks,
> Mark.
^ permalink raw reply
* Re: [PATCH] powerpc: remove meaningless KBUILD_ARFLAGS addition
From: Masahiro Yamada @ 2019-08-19 4:25 UTC (permalink / raw)
To: Michael Ellerman
Cc: Stephen Rothwell, Linux Kernel Mailing List, Nicholas Piggin,
Paul Mackerras, linuxppc-dev
In-Reply-To: <87blxq8zhf.fsf@concordia.ellerman.id.au>
Hi,
On Fri, Jul 19, 2019 at 12:43 PM Michael Ellerman <mpe@ellerman.id.au> wrote:
>
> Segher Boessenkool <segher@kernel.crashing.org> writes:
> > On Thu, Jul 18, 2019 at 11:19:58AM +0900, Masahiro Yamada wrote:
> >> On Thu, Jul 18, 2019 at 1:46 AM Segher Boessenkool
> >> <segher@kernel.crashing.org> wrote:
> >> Kbuild always uses thin archives as far as vmlinux is concerned.
> >>
> >> But, there are some other call-sites.
> >>
> >> masahiro@pug:~/ref/linux$ git grep '$(AR)' -- :^Documentation :^tools
> >> arch/powerpc/boot/Makefile: BOOTAR := $(AR)
> >> arch/unicore32/lib/Makefile: $(Q)$(AR) p $(GNU_LIBC_A) $(notdir $@) > $@
> >> arch/unicore32/lib/Makefile: $(Q)$(AR) p $(GNU_LIBGCC_A) $(notdir $@) > $@
> >> lib/raid6/test/Makefile: $(AR) cq $@ $^
> >> scripts/Kbuild.include:ar-option = $(call try-run, $(AR) rc$(1)
> >> "$$TMP",$(1),$(2))
> >> scripts/Makefile.build: cmd_ar_builtin = rm -f $@; $(AR)
> >> rcSTP$(KBUILD_ARFLAGS) $@ $(real-prereqs)
> >> scripts/Makefile.lib: cmd_ar = rm -f $@; $(AR)
> >> rcsTP$(KBUILD_ARFLAGS) $@ $(real-prereqs)
> >>
> >> Probably, you are interested in arch/powerpc/boot/Makefile.
> >
> > That one seems fine actually. The raid6 one I don't know.
> >
> >
> > My original commit message was
> >
> > Without this, some versions of GNU ar fail to create
> > an archive index if the object files it is packing
> > together are of a different object format than ar's
> > default format (for example, binutils compiled to
> > default to 64-bit, with 32-bit objects).
> >
> > but I cannot reproduce the problem anymore. Shortly after my patch the
> > thin archive code happened to binutils, and that overhauled some other
> > things, which might have fixed it already?
> >
> >> > Yes, I know. This isn't about built-in.[oa], it is about *other*
> >> > archives we at least *used to* create. If we *know* we do not anymore,
> >> > then this workaround can of course be removed (and good riddance).
> >>
> >> If it is not about built-in.[oa],
> >> which archive are you talking about?
> >>
> >> Can you pin-point the one?
> >
> > No, not anymore. Lost in the mists of time, I guess? I think we'll
> > just have to file it as "it seems to work fine now".
>
> Yeah I think so. If someone finds a case it breaks we can fix it then.
>
> > Thank you (and everyone else) for the time looking at this!
>
> Likewise.
>
> cheers
So, we agreed to apply this patch, right?
Please let me know if there is some improvement that should be get done.
--
Best Regards
Masahiro Yamada
^ permalink raw reply
* [PATCH kernel] KVM: PPC: vfio/spapr_tce: Split out TCE invalidation from TCE updates
From: Alexey Kardashevskiy @ 2019-08-19 5:15 UTC (permalink / raw)
To: linuxppc-dev
Cc: kvm, Jose Ricardo Ziviani, Alexey Kardashevskiy, Alistair Popple,
kvm-ppc, Alex Williamson, David Gibson
The VFIO IOMMU implementation on SPAPR uses iommu_table::exchange() hook
to update hardware TCE tables (a table where an index is a IOBA>>pageshift
and the value is a host physical address). Each TCE update requires
TCE cache invalidation, both at the PHB and NPU levels. The invalidation
interface allows invalidation of 1) a single TCE, 2) all TCEs belonging
to a specific IOMMU group (or "PE"), 3) entire cache. The invalidation
is implemented in the host system firmware (skiboot) via an OPAL call and
writes to the registers called "TCE Kill" (hence the naming).
At the moment iommu_tce_xchg() is the only interface to
update-and-invalidate a TCE, i.e. we call OPAL for each TCE update.
This is not a problem for relatively small guests (32GB guest takes
less than 2s to map everything into the huge window) but it is for
bigger guests. It gets worse with GPU+NVLinks as NPU (a hardware bit
implementing NVLinks) needs its own TCE cache to be invalidated.
To map a 100GB guest with 1 GPU + 2xNVLinks, a loop over the guest RAM
takes 20s where 10s and 9s go to NPU and PHB TCE cache invalidation.
This is that slow because:
1) we call OPAL for every TCE entry;
2) invalidating many TCEs takes longer than flushing the entire TCE cache.
This implements iommu_tce_kill() and removes TCE cache invalidation from
iommu_tce_xchg. This greatly reduces the number of OPAL calls and halves
the time spent in invalidation. Also, since now OPAL is called for more
just a single TCE, skiboot can choose to invalidate the entire TCE cache
depending on the number of TCEs or entirely (NPU).
This implements iommu_tce_kill_rm() locally in the realmode handlers file
similar to iommu_tce_xchg_rm() as, unlike iommu_tce_kill(), it is not
shared between VFIO IOMMU driver and KVM.
While at this, this fixes incorrect early returns in KVM's
H_PUT_TCE_INDIRECT handlers which skips unlocking locks:
both kvmppc_h_put_tce_indirect and kvmppc_rm_h_put_tce_indirect used
to return H_PARAMETER instead of jumping to unlock_exit.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
This came up after debugging https://patchwork.ozlabs.org/patch/1134763/
"powerpc/pseries/iommu: Add cond_resched() for huge updates"
which we do not actually need.
This should fix bz https://bugzilla.linux.ibm.com/show_bug.cgi?id=175630#c19
I have also backported it at https://github.ibm.com/alexey/linux/commit/25271aa004de51f518408a1f105e36fabe823bf5
---
arch/powerpc/include/asm/iommu.h | 7 ++++++
arch/powerpc/kernel/iommu.c | 8 +++++++
arch/powerpc/kvm/book3s_64_vio.c | 21 ++++++++++++----
arch/powerpc/kvm/book3s_64_vio_hv.c | 29 +++++++++++++++++++----
arch/powerpc/platforms/powernv/pci-ioda.c | 15 +++---------
drivers/vfio/vfio_iommu_spapr_tce.c | 8 ++++++-
6 files changed, 66 insertions(+), 22 deletions(-)
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 18d342b815e4..0dd50e299d79 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -58,6 +58,11 @@ struct iommu_table_ops {
unsigned long *hpa,
enum dma_data_direction *direction);
+ void (*tce_kill)(struct iommu_table *tbl,
+ unsigned long index,
+ unsigned long pages,
+ bool realmode);
+
__be64 *(*useraddrptr)(struct iommu_table *tbl, long index, bool alloc);
#endif
void (*clear)(struct iommu_table *tbl,
@@ -206,6 +211,8 @@ extern void iommu_del_device(struct device *dev);
extern long iommu_tce_xchg(struct mm_struct *mm, struct iommu_table *tbl,
unsigned long entry, unsigned long *hpa,
enum dma_data_direction *direction);
+extern void iommu_tce_kill(struct iommu_table *tbl,
+ unsigned long entry, unsigned long pages);
#else
static inline void iommu_register_group(struct iommu_table_group *table_group,
int pci_domain_number,
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 0a67ce9f827e..48e3c2940327 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1005,6 +1005,14 @@ long iommu_tce_xchg(struct mm_struct *mm, struct iommu_table *tbl,
}
EXPORT_SYMBOL_GPL(iommu_tce_xchg);
+void iommu_tce_kill(struct iommu_table *tbl,
+ unsigned long entry, unsigned long pages)
+{
+ if (tbl->it_ops->tce_kill)
+ tbl->it_ops->tce_kill(tbl, entry, pages, false);
+}
+EXPORT_SYMBOL_GPL(iommu_tce_kill);
+
int iommu_take_ownership(struct iommu_table *tbl)
{
unsigned long flags, i, sz = (tbl->it_size + 7) >> 3;
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index e99a14798ab0..3bd17ed0250f 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -579,6 +579,8 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
ret = kvmppc_tce_iommu_map(vcpu->kvm, stt, stit->tbl,
entry, ua, dir);
+ iommu_tce_kill(stit->tbl, entry, 1);
+
if (ret != H_SUCCESS) {
kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, entry);
goto unlock_exit;
@@ -660,8 +662,10 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
}
tce = be64_to_cpu(tce);
- if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua))
- return H_PARAMETER;
+ if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua)) {
+ ret = H_PARAMETER;
+ goto invalidate_exit;
+ }
list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
ret = kvmppc_tce_iommu_map(vcpu->kvm, stt,
@@ -678,6 +682,10 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
kvmppc_tce_put(stt, entry + i, tce);
}
+invalidate_exit:
+ list_for_each_entry_lockless(stit, &stt->iommu_tables, next)
+ iommu_tce_kill(stit->tbl, entry, npages);
+
unlock_exit:
srcu_read_unlock(&vcpu->kvm->srcu, idx);
@@ -716,7 +724,7 @@ long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu,
continue;
if (ret == H_TOO_HARD)
- return ret;
+ goto invalidate_exit;
WARN_ON_ONCE(1);
kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, entry);
@@ -726,6 +734,11 @@ long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu,
for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift))
kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value);
- return H_SUCCESS;
+invalidate_exit:
+ list_for_each_entry_lockless(stit, &stt->iommu_tables, next)
+ iommu_tce_kill(stit->tbl, ioba >> stt->page_shift, npages);
+
+
+ return ret;
}
EXPORT_SYMBOL_GPL(kvmppc_h_stuff_tce);
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index f50bbeedfc66..1170673c898f 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -240,6 +240,13 @@ static long iommu_tce_xchg_rm(struct mm_struct *mm, struct iommu_table *tbl,
return ret;
}
+static void iommu_tce_kill_rm(struct iommu_table *tbl,
+ unsigned long entry, unsigned long pages)
+{
+ if (tbl->it_ops->tce_kill)
+ tbl->it_ops->tce_kill(tbl, entry, pages, true);
+}
+
static void kvmppc_rm_clear_tce(struct kvm *kvm, struct iommu_table *tbl,
unsigned long entry)
{
@@ -417,6 +424,8 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
ret = kvmppc_rm_tce_iommu_map(vcpu->kvm, stt,
stit->tbl, entry, ua, dir);
+ iommu_tce_kill_rm(stit->tbl, entry, 1);
+
if (ret != H_SUCCESS) {
kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
return ret;
@@ -556,8 +565,10 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
unsigned long tce = be64_to_cpu(((u64 *)tces)[i]);
ua = 0;
- if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua, NULL))
- return H_PARAMETER;
+ if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua, NULL)) {
+ ret = H_PARAMETER;
+ goto invalidate_exit;
+ }
list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
ret = kvmppc_rm_tce_iommu_map(vcpu->kvm, stt,
@@ -567,13 +578,17 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
if (ret != H_SUCCESS) {
kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl,
entry);
- goto unlock_exit;
+ goto invalidate_exit;
}
}
kvmppc_rm_tce_put(stt, entry + i, tce);
}
+invalidate_exit:
+ list_for_each_entry_lockless(stit, &stt->iommu_tables, next)
+ iommu_tce_kill_rm(stit->tbl, entry, npages);
+
unlock_exit:
if (rmap)
unlock_rmap(rmap);
@@ -616,7 +631,7 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
continue;
if (ret == H_TOO_HARD)
- return ret;
+ goto invalidate_exit;
WARN_ON_ONCE_RM(1);
kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry);
@@ -626,7 +641,11 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift))
kvmppc_rm_tce_put(stt, ioba >> stt->page_shift, tce_value);
- return H_SUCCESS;
+invalidate_exit:
+ list_for_each_entry_lockless(stit, &stt->iommu_tables, next)
+ iommu_tce_kill_rm(stit->tbl, ioba >> stt->page_shift, npages);
+
+ return ret;
}
/* This can be called in either virtual mode or real mode */
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index d8080558d020..ae1263bd9256 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2107,23 +2107,13 @@ static int pnv_ioda2_tce_build(struct iommu_table *tbl, long index,
static int pnv_ioda2_tce_xchg(struct iommu_table *tbl, long index,
unsigned long *hpa, enum dma_data_direction *direction)
{
- long ret = pnv_tce_xchg(tbl, index, hpa, direction, true);
-
- if (!ret)
- pnv_pci_ioda2_tce_invalidate(tbl, index, 1, false);
-
- return ret;
+ return pnv_tce_xchg(tbl, index, hpa, direction, true);
}
static int pnv_ioda2_tce_xchg_rm(struct iommu_table *tbl, long index,
unsigned long *hpa, enum dma_data_direction *direction)
{
- long ret = pnv_tce_xchg(tbl, index, hpa, direction, false);
-
- if (!ret)
- pnv_pci_ioda2_tce_invalidate(tbl, index, 1, true);
-
- return ret;
+ return pnv_tce_xchg(tbl, index, hpa, direction, false);
}
#endif
@@ -2140,6 +2130,7 @@ static struct iommu_table_ops pnv_ioda2_iommu_ops = {
#ifdef CONFIG_IOMMU_API
.exchange = pnv_ioda2_tce_xchg,
.exchange_rm = pnv_ioda2_tce_xchg_rm,
+ .tce_kill = pnv_pci_ioda2_tce_invalidate,
.useraddrptr = pnv_tce_useraddrptr,
#endif
.clear = pnv_ioda2_tce_free,
diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
index babef8b00daf..91100afcf696 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -435,7 +435,7 @@ static int tce_iommu_clear(struct tce_container *container,
unsigned long oldhpa;
long ret;
enum dma_data_direction direction;
- unsigned long lastentry = entry + pages;
+ unsigned long lastentry = entry + pages, firstentry = entry;
for ( ; entry < lastentry; ++entry) {
if (tbl->it_indirect_levels && tbl->it_userspace) {
@@ -476,6 +476,8 @@ static int tce_iommu_clear(struct tce_container *container,
tce_iommu_unuse_page(container, oldhpa);
}
+ iommu_tce_kill(tbl, firstentry, pages);
+
return 0;
}
@@ -536,6 +538,8 @@ static long tce_iommu_build(struct tce_container *container,
if (ret)
tce_iommu_clear(container, tbl, entry, i);
+ else
+ iommu_tce_kill(tbl, entry, pages);
return ret;
}
@@ -593,6 +597,8 @@ static long tce_iommu_build_v2(struct tce_container *container,
if (ret)
tce_iommu_clear(container, tbl, entry, i);
+ else
+ iommu_tce_kill(tbl, entry, pages);
return ret;
}
--
2.17.1
^ permalink raw reply related
* Re: [PATCH 0/6] drm+dma: cache support for arm, etc
From: Christoph Hellwig @ 2019-08-19 5:23 UTC (permalink / raw)
To: Rob Clark
Cc: Kate Stewart, Masayoshi Mizuma, Maciej W. Rozycki, Eric Biggers,
Catalin Marinas, Imre Deak, dri-devel, Chris Wilson,
Masahiro Yamada, Benjamin Gaignard, Mauro Carvalho Chehab,
Will Deacon, Christoph Hellwig, Emil Velikov, Deepak Sharma,
Paul Burton, Mike Rapoport, Geert Uytterhoeven,
moderated list:ARM64 PORT (AARCH64 ARCHITECTURE), Daniel Vetter,
open list:MIPS, Linus Walleij, Robin Murphy,
open list:DRM DRIVER FOR MSM ADRENO GPU, Joerg Roedel,
Arnd Bergmann, Anshuman Khandual, Hauke Mehrtens,
Jesper Dangaard Brouer, Wolfram Sang (Renesas),
open list:LINUX FOR POWERPC (32-BIT AND 64-BIT), Alexios Zavras,
Russell King, Doug Anderson, Thomas Gleixner, Sean Paul,
Allison Randal, Enrico Weigelt, Ard Biesheuvel,
Greg Kroah-Hartman, open list, Rob Clark, Souptick Joarder,
Andrew Morton, open list:DRM DRIVER FOR MSM ADRENO GPU,
christian.koenig
In-Reply-To: <CAJs_Fx6am7TeDFSG=CcTT=4KwhqrZX_jnn56NaWcDkGVizuakg@mail.gmail.com>
On Fri, Aug 16, 2019 at 02:04:35PM -0700, Rob Clark wrote:
> I don't disagree about needing an API to get uncached memory (or
> ideally just something outside of the linear map). But I think this
> is a separate problem.
>
> What I was hoping for, for v5.4, is a way to stop abusing dma_map/sync
> for cache ops to get rid of the hack I had to make for v5.3. And also
> to fix vgem on non-x86. (Unfortunately changing vgem to used cached
> mappings breaks x86 CI, but fixes CI on arm/arm64..) We can do that
> without any changes in allocation. There is still the possibility for
> problems due to cached alias, but that has been a problem this whole
> time, it isn't something new.
But that just means we start exposing random low-level APIs that
people will quickly abuse.. In fact even your simple plan to some
extent already is an abuse of the intent of these functions, and
it also requires a lot of knowledge in the driver that in the normal
cases drivers can't know (e.g. is the device dma coherent or not).
^ permalink raw reply
* Re: [PATCH] powerpc: optimise WARN_ON()
From: Christophe Leroy @ 2019-08-19 5:40 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <20190818120135.GV31406@gate.crashing.org>
Le 18/08/2019 à 14:01, Segher Boessenkool a écrit :
> On Sat, Aug 17, 2019 at 09:04:42AM +0000, Christophe Leroy wrote:
>> Unlike BUG_ON(x), WARN_ON(x) uses !!(x) as the trigger
>> of the t(d/w)nei instruction instead of using directly the
>> value of x.
>>
>> This leads to GCC adding unnecessary pair of addic/subfe.
>
> And it has to, it is passed as an "r" to an asm, GCC has to put the "!!"
> value into a register.
>
>> By using (x) instead of !!(x) like BUG_ON() does, the additional
>> instructions go away:
>
> But is it correct? What happens if you pass an int to WARN_ON, on a
> 64-bit kernel?
On a 64-bit kernel, an int is still in a 64-bit register, so there would
be no problem with tdnei, would it ? an int 0 is the same as an long 0,
right ?
It is on 32-bit kernel that I see a problem, if one passes a long long
to WARN_ON(), the forced cast to long will just drop the upper size of
it. So as of today, BUG_ON() is buggy for that.
>
> (You might want to have 64-bit generate either tw or td. But, with
> your __builtin_trap patch, all that will be automatic).
>
Yes I'll discard this patch and focus on the __builtin_trap() one which
should solve most issues.
Christophe
^ permalink raw reply
* Re: [PATCH v6 00/12] implement KASLR for powerpc/fsl_booke/32
From: Jason Yan @ 2019-08-19 6:12 UTC (permalink / raw)
To: mpe, linuxppc-dev, diana.craciun, christophe.leroy, benh, paulus,
npiggin, keescook, kernel-hardening
Cc: wangkefeng.wang, linux-kernel, jingxiangfeng, zhaohongjiang,
thunder.leizhen, fanchengyang, yebin10
In-Reply-To: <20190809100800.5426-1-yanaijie@huawei.com>
Hi Michael,
Is there anything more I should do to get this feature meeting the
requirements of the mainline?
Thanks,
Jason
On 2019/8/9 18:07, Jason Yan wrote:
> This series implements KASLR for powerpc/fsl_booke/32, as a security
> feature that deters exploit attempts relying on knowledge of the location
> of kernel internals.
>
> Since CONFIG_RELOCATABLE has already supported, what we need to do is
> map or copy kernel to a proper place and relocate. Freescale Book-E
> parts expect lowmem to be mapped by fixed TLB entries(TLB1). The TLB1
> entries are not suitable to map the kernel directly in a randomized
> region, so we chose to copy the kernel to a proper place and restart to
> relocate.
>
> Entropy is derived from the banner and timer base, which will change every
> build and boot. This not so much safe so additionally the bootloader may
> pass entropy via the /chosen/kaslr-seed node in device tree.
>
> We will use the first 512M of the low memory to randomize the kernel
> image. The memory will be split in 64M zones. We will use the lower 8
> bit of the entropy to decide the index of the 64M zone. Then we chose a
> 16K aligned offset inside the 64M zone to put the kernel in.
>
> KERNELBASE
>
> |--> 64M <--|
> | |
> +---------------+ +----------------+---------------+
> | |....| |kernel| | |
> +---------------+ +----------------+---------------+
> | |
> |-----> offset <-----|
>
> kernstart_virt_addr
>
> We also check if we will overlap with some areas like the dtb area, the
> initrd area or the crashkernel area. If we cannot find a proper area,
> kaslr will be disabled and boot from the original kernel.
>
> Changes since v5:
> - Rename M_IF_NEEDED to MAS2_M_IF_NEEDED
> - Define some global variable as __ro_after_init
> - Replace kimage_vaddr with kernstart_virt_addr
> - Depend on RELOCATABLE, not select it
> - Modify the comment block below the SPDX tag
> - Remove some useless headers in kaslr_booke.c and move is_second_reloc
> declarationto mmu_decl.h
> - Remove DBG() and use pr_debug() and rewrite comment above get_boot_seed().
> - Add a patch to document the KASLR implementation.
> - Split a patch from patch #10 which exports kaslr offset in VMCOREINFO ELF notes.
> - Remove extra logic around finding nokaslr string in cmdline.
> - Make regions static global and __initdata
>
> Changes since v4:
> - Add Reviewed-by tag from Christophe
> - Remove an unnecessary cast
> - Remove unnecessary parenthesis
> - Fix checkpatch warning
>
> Changes since v3:
> - Add Reviewed-by and Tested-by tag from Diana
> - Change the comment in fsl_booke_entry_mapping.S to be consistent
> with the new code.
>
> Changes since v2:
> - Remove unnecessary #ifdef
> - Use SZ_64M instead of0x4000000
> - Call early_init_dt_scan_chosen() to init boot_command_line
> - Rename kaslr_second_init() to kaslr_late_init()
>
> Changes since v1:
> - Remove some useless 'extern' keyword.
> - Replace EXPORT_SYMBOL with EXPORT_SYMBOL_GPL
> - Improve some assembly code
> - Use memzero_explicit instead of memset
> - Use boot_command_line and remove early_command_line
> - Do not print kaslr offset if kaslr is disabled
>
> Jason Yan (12):
> powerpc: unify definition of M_IF_NEEDED
> powerpc: move memstart_addr and kernstart_addr to init-common.c
> powerpc: introduce kernstart_virt_addr to store the kernel base
> powerpc/fsl_booke/32: introduce create_tlb_entry() helper
> powerpc/fsl_booke/32: introduce reloc_kernel_entry() helper
> powerpc/fsl_booke/32: implement KASLR infrastructure
> powerpc/fsl_booke/32: randomize the kernel image offset
> powerpc/fsl_booke/kaslr: clear the original kernel if randomized
> powerpc/fsl_booke/kaslr: support nokaslr cmdline parameter
> powerpc/fsl_booke/kaslr: dump out kernel offset information on panic
> powerpc/fsl_booke/kaslr: export offset in VMCOREINFO ELF notes
> powerpc/fsl_booke/32: Document KASLR implementation
>
> Documentation/powerpc/kaslr-booke32.rst | 42 ++
> arch/powerpc/Kconfig | 11 +
> arch/powerpc/include/asm/nohash/mmu-book3e.h | 10 +
> arch/powerpc/include/asm/page.h | 7 +
> arch/powerpc/kernel/Makefile | 1 +
> arch/powerpc/kernel/early_32.c | 2 +-
> arch/powerpc/kernel/exceptions-64e.S | 12 +-
> arch/powerpc/kernel/fsl_booke_entry_mapping.S | 27 +-
> arch/powerpc/kernel/head_fsl_booke.S | 55 ++-
> arch/powerpc/kernel/kaslr_booke.c | 393 ++++++++++++++++++
> arch/powerpc/kernel/machine_kexec.c | 1 +
> arch/powerpc/kernel/misc_64.S | 7 +-
> arch/powerpc/kernel/setup-common.c | 20 +
> arch/powerpc/mm/init-common.c | 7 +
> arch/powerpc/mm/init_32.c | 5 -
> arch/powerpc/mm/init_64.c | 5 -
> arch/powerpc/mm/mmu_decl.h | 11 +
> arch/powerpc/mm/nohash/fsl_booke.c | 8 +-
> 18 files changed, 572 insertions(+), 52 deletions(-)
> create mode 100644 Documentation/powerpc/kaslr-booke32.rst
> create mode 100644 arch/powerpc/kernel/kaslr_booke.c
>
^ permalink raw reply
* [PATCH 1/2] kasan: support instrumented bitops combined with generic bitops
From: Daniel Axtens @ 2019-08-19 6:28 UTC (permalink / raw)
To: christophe.leroy, linux-s390, linux-arch, x86, linuxppc-dev
Cc: kasan-dev, Daniel Axtens
Currently bitops-instrumented.h assumes that the architecture provides
atomic, non-atomic and locking bitops (e.g. both set_bit and __set_bit).
This is true on x86 and s390, but is not always true: there is a
generic bitops/non-atomic.h header that provides generic non-atomic
operations, and also a generic bitops/lock.h for locking operations.
powerpc uses the generic non-atomic version, so it does not have it's
own e.g. __set_bit that could be renamed arch___set_bit.
Split up bitops-instrumented.h to mirror the atomic/non-atomic/lock
split. This allows arches to only include the headers where they
have arch-specific versions to rename. Update x86 and s390.
(The generic operations are automatically instrumented because they're
written in C, not asm.)
Suggested-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
Documentation/core-api/kernel-api.rst | 17 +-
arch/s390/include/asm/bitops.h | 4 +-
arch/x86/include/asm/bitops.h | 4 +-
include/asm-generic/bitops-instrumented.h | 263 ------------------
.../asm-generic/bitops/instrumented-atomic.h | 100 +++++++
.../asm-generic/bitops/instrumented-lock.h | 81 ++++++
.../bitops/instrumented-non-atomic.h | 114 ++++++++
7 files changed, 317 insertions(+), 266 deletions(-)
delete mode 100644 include/asm-generic/bitops-instrumented.h
create mode 100644 include/asm-generic/bitops/instrumented-atomic.h
create mode 100644 include/asm-generic/bitops/instrumented-lock.h
create mode 100644 include/asm-generic/bitops/instrumented-non-atomic.h
diff --git a/Documentation/core-api/kernel-api.rst b/Documentation/core-api/kernel-api.rst
index 08af5caf036d..2e21248277e3 100644
--- a/Documentation/core-api/kernel-api.rst
+++ b/Documentation/core-api/kernel-api.rst
@@ -54,7 +54,22 @@ The Linux kernel provides more basic utility functions.
Bit Operations
--------------
-.. kernel-doc:: include/asm-generic/bitops-instrumented.h
+Atomic Operations
+~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/asm-generic/bitops/instrumented-atomic.h
+ :internal:
+
+Non-atomic Operations
+~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/asm-generic/bitops/instrumented-non-atomic.h
+ :internal:
+
+Locking Operations
+~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/asm-generic/bitops/instrumented-lock.h
:internal:
Bitmap Operations
diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h
index b8833ac983fa..0ceb12593a68 100644
--- a/arch/s390/include/asm/bitops.h
+++ b/arch/s390/include/asm/bitops.h
@@ -241,7 +241,9 @@ static inline void arch___clear_bit_unlock(unsigned long nr,
arch___clear_bit(nr, ptr);
}
-#include <asm-generic/bitops-instrumented.h>
+#include <asm-generic/bitops/instrumented-atomic.h>
+#include <asm-generic/bitops/instrumented-non-atomic.h>
+#include <asm-generic/bitops/instrumented-lock.h>
/*
* Functions which use MSB0 bit numbering.
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index ba15d53c1ca7..4a2e2432238f 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -389,7 +389,9 @@ static __always_inline int fls64(__u64 x)
#include <asm-generic/bitops/const_hweight.h>
-#include <asm-generic/bitops-instrumented.h>
+#include <asm-generic/bitops/instrumented-atomic.h>
+#include <asm-generic/bitops/instrumented-non-atomic.h>
+#include <asm-generic/bitops/instrumented-lock.h>
#include <asm-generic/bitops/le.h>
diff --git a/include/asm-generic/bitops-instrumented.h b/include/asm-generic/bitops-instrumented.h
deleted file mode 100644
index ddd1c6d9d8db..000000000000
--- a/include/asm-generic/bitops-instrumented.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/*
- * This file provides wrappers with sanitizer instrumentation for bit
- * operations.
- *
- * To use this functionality, an arch's bitops.h file needs to define each of
- * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
- * arch___set_bit(), etc.).
- */
-#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_H
-#define _ASM_GENERIC_BITOPS_INSTRUMENTED_H
-
-#include <linux/kasan-checks.h>
-
-/**
- * set_bit - Atomically set a bit in memory
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * This is a relaxed atomic operation (no implied memory barriers).
- *
- * Note that @nr may be almost arbitrarily large; this function is not
- * restricted to acting on a single-word quantity.
- */
-static inline void set_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch_set_bit(nr, addr);
-}
-
-/**
- * __set_bit - Set a bit in memory
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * Unlike set_bit(), this function is non-atomic. If it is called on the same
- * region of memory concurrently, the effect may be that only one operation
- * succeeds.
- */
-static inline void __set_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch___set_bit(nr, addr);
-}
-
-/**
- * clear_bit - Clears a bit in memory
- * @nr: Bit to clear
- * @addr: Address to start counting from
- *
- * This is a relaxed atomic operation (no implied memory barriers).
- */
-static inline void clear_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch_clear_bit(nr, addr);
-}
-
-/**
- * __clear_bit - Clears a bit in memory
- * @nr: the bit to clear
- * @addr: the address to start counting from
- *
- * Unlike clear_bit(), this function is non-atomic. If it is called on the same
- * region of memory concurrently, the effect may be that only one operation
- * succeeds.
- */
-static inline void __clear_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch___clear_bit(nr, addr);
-}
-
-/**
- * clear_bit_unlock - Clear a bit in memory, for unlock
- * @nr: the bit to set
- * @addr: the address to start counting from
- *
- * This operation is atomic and provides release barrier semantics.
- */
-static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch_clear_bit_unlock(nr, addr);
-}
-
-/**
- * __clear_bit_unlock - Clears a bit in memory
- * @nr: Bit to clear
- * @addr: Address to start counting from
- *
- * This is a non-atomic operation but implies a release barrier before the
- * memory operation. It can be used for an unlock if no other CPUs can
- * concurrently modify other bits in the word.
- */
-static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch___clear_bit_unlock(nr, addr);
-}
-
-/**
- * change_bit - Toggle a bit in memory
- * @nr: Bit to change
- * @addr: Address to start counting from
- *
- * This is a relaxed atomic operation (no implied memory barriers).
- *
- * Note that @nr may be almost arbitrarily large; this function is not
- * restricted to acting on a single-word quantity.
- */
-static inline void change_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch_change_bit(nr, addr);
-}
-
-/**
- * __change_bit - Toggle a bit in memory
- * @nr: the bit to change
- * @addr: the address to start counting from
- *
- * Unlike change_bit(), this function is non-atomic. If it is called on the same
- * region of memory concurrently, the effect may be that only one operation
- * succeeds.
- */
-static inline void __change_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- arch___change_bit(nr, addr);
-}
-
-/**
- * test_and_set_bit - Set a bit and return its old value
- * @nr: Bit to set
- * @addr: Address to count from
- *
- * This is an atomic fully-ordered operation (implied full memory barrier).
- */
-static inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch_test_and_set_bit(nr, addr);
-}
-
-/**
- * __test_and_set_bit - Set a bit and return its old value
- * @nr: Bit to set
- * @addr: Address to count from
- *
- * This operation is non-atomic. If two instances of this operation race, one
- * can appear to succeed but actually fail.
- */
-static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch___test_and_set_bit(nr, addr);
-}
-
-/**
- * test_and_set_bit_lock - Set a bit and return its old value, for lock
- * @nr: Bit to set
- * @addr: Address to count from
- *
- * This operation is atomic and provides acquire barrier semantics if
- * the returned value is 0.
- * It can be used to implement bit locks.
- */
-static inline bool test_and_set_bit_lock(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch_test_and_set_bit_lock(nr, addr);
-}
-
-/**
- * test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
- * @addr: Address to count from
- *
- * This is an atomic fully-ordered operation (implied full memory barrier).
- */
-static inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch_test_and_clear_bit(nr, addr);
-}
-
-/**
- * __test_and_clear_bit - Clear a bit and return its old value
- * @nr: Bit to clear
- * @addr: Address to count from
- *
- * This operation is non-atomic. If two instances of this operation race, one
- * can appear to succeed but actually fail.
- */
-static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch___test_and_clear_bit(nr, addr);
-}
-
-/**
- * test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to change
- * @addr: Address to count from
- *
- * This is an atomic fully-ordered operation (implied full memory barrier).
- */
-static inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch_test_and_change_bit(nr, addr);
-}
-
-/**
- * __test_and_change_bit - Change a bit and return its old value
- * @nr: Bit to change
- * @addr: Address to count from
- *
- * This operation is non-atomic. If two instances of this operation race, one
- * can appear to succeed but actually fail.
- */
-static inline bool __test_and_change_bit(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch___test_and_change_bit(nr, addr);
-}
-
-/**
- * test_bit - Determine whether a bit is set
- * @nr: bit number to test
- * @addr: Address to start counting from
- */
-static inline bool test_bit(long nr, const volatile unsigned long *addr)
-{
- kasan_check_read(addr + BIT_WORD(nr), sizeof(long));
- return arch_test_bit(nr, addr);
-}
-
-#if defined(arch_clear_bit_unlock_is_negative_byte)
-/**
- * clear_bit_unlock_is_negative_byte - Clear a bit in memory and test if bottom
- * byte is negative, for unlock.
- * @nr: the bit to clear
- * @addr: the address to start counting from
- *
- * This operation is atomic and provides release barrier semantics.
- *
- * This is a bit of a one-trick-pony for the filemap code, which clears
- * PG_locked and tests PG_waiters,
- */
-static inline bool
-clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr)
-{
- kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
- return arch_clear_bit_unlock_is_negative_byte(nr, addr);
-}
-/* Let everybody know we have it. */
-#define clear_bit_unlock_is_negative_byte clear_bit_unlock_is_negative_byte
-#endif
-
-#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_H */
diff --git a/include/asm-generic/bitops/instrumented-atomic.h b/include/asm-generic/bitops/instrumented-atomic.h
new file mode 100644
index 000000000000..18ce3c9e8eec
--- /dev/null
+++ b/include/asm-generic/bitops/instrumented-atomic.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file provides wrappers with sanitizer instrumentation for atomic bit
+ * operations.
+ *
+ * To use this functionality, an arch's bitops.h file needs to define each of
+ * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
+ * arch___set_bit(), etc.).
+ */
+#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
+#define _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
+
+#include <linux/kasan-checks.h>
+
+/**
+ * set_bit - Atomically set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This is a relaxed atomic operation (no implied memory barriers).
+ *
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static inline void set_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch_set_bit(nr, addr);
+}
+
+/**
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * This is a relaxed atomic operation (no implied memory barriers).
+ */
+static inline void clear_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch_clear_bit(nr, addr);
+}
+
+/**
+ * change_bit - Toggle a bit in memory
+ * @nr: Bit to change
+ * @addr: Address to start counting from
+ *
+ * This is a relaxed atomic operation (no implied memory barriers).
+ *
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static inline void change_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch_change_bit(nr, addr);
+}
+
+/**
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This is an atomic fully-ordered operation (implied full memory barrier).
+ */
+static inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ return arch_test_and_set_bit(nr, addr);
+}
+
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * This is an atomic fully-ordered operation (implied full memory barrier).
+ */
+static inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ return arch_test_and_clear_bit(nr, addr);
+}
+
+/**
+ * test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to change
+ * @addr: Address to count from
+ *
+ * This is an atomic fully-ordered operation (implied full memory barrier).
+ */
+static inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ return arch_test_and_change_bit(nr, addr);
+}
+
+#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */
diff --git a/include/asm-generic/bitops/instrumented-lock.h b/include/asm-generic/bitops/instrumented-lock.h
new file mode 100644
index 000000000000..ec53fdeea9ec
--- /dev/null
+++ b/include/asm-generic/bitops/instrumented-lock.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file provides wrappers with sanitizer instrumentation for bit
+ * locking operations.
+ *
+ * To use this functionality, an arch's bitops.h file needs to define each of
+ * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
+ * arch___set_bit(), etc.).
+ */
+#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H
+#define _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H
+
+#include <linux/kasan-checks.h>
+
+/**
+ * clear_bit_unlock - Clear a bit in memory, for unlock
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This operation is atomic and provides release barrier semantics.
+ */
+static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch_clear_bit_unlock(nr, addr);
+}
+
+/**
+ * __clear_bit_unlock - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * This is a non-atomic operation but implies a release barrier before the
+ * memory operation. It can be used for an unlock if no other CPUs can
+ * concurrently modify other bits in the word.
+ */
+static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch___clear_bit_unlock(nr, addr);
+}
+
+/**
+ * test_and_set_bit_lock - Set a bit and return its old value, for lock
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and provides acquire barrier semantics if
+ * the returned value is 0.
+ * It can be used to implement bit locks.
+ */
+static inline bool test_and_set_bit_lock(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ return arch_test_and_set_bit_lock(nr, addr);
+}
+
+#if defined(arch_clear_bit_unlock_is_negative_byte)
+/**
+ * clear_bit_unlock_is_negative_byte - Clear a bit in memory and test if bottom
+ * byte is negative, for unlock.
+ * @nr: the bit to clear
+ * @addr: the address to start counting from
+ *
+ * This operation is atomic and provides release barrier semantics.
+ *
+ * This is a bit of a one-trick-pony for the filemap code, which clears
+ * PG_locked and tests PG_waiters,
+ */
+static inline bool
+clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ return arch_clear_bit_unlock_is_negative_byte(nr, addr);
+}
+/* Let everybody know we have it. */
+#define clear_bit_unlock_is_negative_byte clear_bit_unlock_is_negative_byte
+#endif
+
+#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H */
diff --git a/include/asm-generic/bitops/instrumented-non-atomic.h b/include/asm-generic/bitops/instrumented-non-atomic.h
new file mode 100644
index 000000000000..95ff28d128a1
--- /dev/null
+++ b/include/asm-generic/bitops/instrumented-non-atomic.h
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file provides wrappers with sanitizer instrumentation for non-atomic
+ * bit operations.
+ *
+ * To use this functionality, an arch's bitops.h file needs to define each of
+ * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
+ * arch___set_bit(), etc.).
+ */
+#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
+#define _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
+
+#include <linux/kasan-checks.h>
+
+/**
+ * __set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike set_bit(), this function is non-atomic. If it is called on the same
+ * region of memory concurrently, the effect may be that only one operation
+ * succeeds.
+ */
+static inline void __set_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch___set_bit(nr, addr);
+}
+
+/**
+ * __clear_bit - Clears a bit in memory
+ * @nr: the bit to clear
+ * @addr: the address to start counting from
+ *
+ * Unlike clear_bit(), this function is non-atomic. If it is called on the same
+ * region of memory concurrently, the effect may be that only one operation
+ * succeeds.
+ */
+static inline void __clear_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch___clear_bit(nr, addr);
+}
+
+/**
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to change
+ * @addr: the address to start counting from
+ *
+ * Unlike change_bit(), this function is non-atomic. If it is called on the same
+ * region of memory concurrently, the effect may be that only one operation
+ * succeeds.
+ */
+static inline void __change_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ arch___change_bit(nr, addr);
+}
+
+/**
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic. If two instances of this operation race, one
+ * can appear to succeed but actually fail.
+ */
+static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ return arch___test_and_set_bit(nr, addr);
+}
+
+/**
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic. If two instances of this operation race, one
+ * can appear to succeed but actually fail.
+ */
+static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ return arch___test_and_clear_bit(nr, addr);
+}
+
+/**
+ * __test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to change
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic. If two instances of this operation race, one
+ * can appear to succeed but actually fail.
+ */
+static inline bool __test_and_change_bit(long nr, volatile unsigned long *addr)
+{
+ kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
+ return arch___test_and_change_bit(nr, addr);
+}
+
+/**
+ * test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ */
+static inline bool test_bit(long nr, const volatile unsigned long *addr)
+{
+ kasan_check_read(addr + BIT_WORD(nr), sizeof(long));
+ return arch_test_bit(nr, addr);
+}
+
+#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */
--
2.20.1
^ permalink raw reply related
* [PATCH 2/2] powerpc: support KASAN instrumentation of bitops
From: Daniel Axtens @ 2019-08-19 6:28 UTC (permalink / raw)
To: christophe.leroy, linux-s390, linux-arch, x86, linuxppc-dev
Cc: Nicholas Piggin, kasan-dev, Daniel Axtens
In-Reply-To: <20190819062814.5315-1-dja@axtens.net>
In KASAN development I noticed that the powerpc-specific bitops
were not being picked up by the KASAN test suite.
Instrumentation is done via the bitops/instrumented-{atomic,lock}.h
headers. They require that arch-specific versions of bitop functions
are renamed to arch_*. Do this renaming.
For clear_bit_unlock_is_negative_byte, the current implementation
uses the PG_waiters constant. This works because it's a preprocessor
macro - so it's only actually evaluated in contexts where PG_waiters
is defined. With instrumentation however, it becomes a static inline
function, and all of a sudden we need the actual value of PG_waiters.
Because of the order of header includes, it's not available and we
fail to compile. Instead, manually specify that we care about bit 7.
This is still correct: bit 7 is the bit that would mark a negative
byte.
Cc: Nicholas Piggin <npiggin@gmail.com> # clear_bit_unlock_negative_byte
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
arch/powerpc/include/asm/bitops.h | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index 603aed229af7..8615b2bc35fe 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -86,22 +86,22 @@ DEFINE_BITOP(clear_bits, andc, "")
DEFINE_BITOP(clear_bits_unlock, andc, PPC_RELEASE_BARRIER)
DEFINE_BITOP(change_bits, xor, "")
-static __inline__ void set_bit(int nr, volatile unsigned long *addr)
+static __inline__ void arch_set_bit(int nr, volatile unsigned long *addr)
{
set_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
}
-static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
+static __inline__ void arch_clear_bit(int nr, volatile unsigned long *addr)
{
clear_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
}
-static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
+static __inline__ void arch_clear_bit_unlock(int nr, volatile unsigned long *addr)
{
clear_bits_unlock(BIT_MASK(nr), addr + BIT_WORD(nr));
}
-static __inline__ void change_bit(int nr, volatile unsigned long *addr)
+static __inline__ void arch_change_bit(int nr, volatile unsigned long *addr)
{
change_bits(BIT_MASK(nr), addr + BIT_WORD(nr));
}
@@ -138,26 +138,26 @@ DEFINE_TESTOP(test_and_clear_bits, andc, PPC_ATOMIC_ENTRY_BARRIER,
DEFINE_TESTOP(test_and_change_bits, xor, PPC_ATOMIC_ENTRY_BARRIER,
PPC_ATOMIC_EXIT_BARRIER, 0)
-static __inline__ int test_and_set_bit(unsigned long nr,
+static __inline__ int arch_test_and_set_bit(unsigned long nr,
volatile unsigned long *addr)
{
return test_and_set_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
}
-static __inline__ int test_and_set_bit_lock(unsigned long nr,
+static __inline__ int arch_test_and_set_bit_lock(unsigned long nr,
volatile unsigned long *addr)
{
return test_and_set_bits_lock(BIT_MASK(nr),
addr + BIT_WORD(nr)) != 0;
}
-static __inline__ int test_and_clear_bit(unsigned long nr,
+static __inline__ int arch_test_and_clear_bit(unsigned long nr,
volatile unsigned long *addr)
{
return test_and_clear_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
}
-static __inline__ int test_and_change_bit(unsigned long nr,
+static __inline__ int arch_test_and_change_bit(unsigned long nr,
volatile unsigned long *addr)
{
return test_and_change_bits(BIT_MASK(nr), addr + BIT_WORD(nr)) != 0;
@@ -185,15 +185,18 @@ static __inline__ unsigned long clear_bit_unlock_return_word(int nr,
return old;
}
-/* This is a special function for mm/filemap.c */
-#define clear_bit_unlock_is_negative_byte(nr, addr) \
- (clear_bit_unlock_return_word(nr, addr) & BIT_MASK(PG_waiters))
+/*
+ * This is a special function for mm/filemap.c
+ * Bit 7 corresponds to PG_waiters.
+ */
+#define arch_clear_bit_unlock_is_negative_byte(nr, addr) \
+ (clear_bit_unlock_return_word(nr, addr) & BIT_MASK(7))
#endif /* CONFIG_PPC64 */
#include <asm-generic/bitops/non-atomic.h>
-static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
+static __inline__ void arch___clear_bit_unlock(int nr, volatile unsigned long *addr)
{
__asm__ __volatile__(PPC_RELEASE_BARRIER "" ::: "memory");
__clear_bit(nr, addr);
@@ -239,6 +242,10 @@ unsigned long __arch_hweight64(__u64 w);
#include <asm-generic/bitops/find.h>
+/* wrappers that deal with KASAN instrumentation */
+#include <asm-generic/bitops/instrumented-atomic.h>
+#include <asm-generic/bitops/instrumented-lock.h>
+
/* Little-endian versions */
#include <asm-generic/bitops/le.h>
--
2.20.1
^ permalink raw reply related
* [PATCH] powerpc/603: fix handling of the DIRTY flag
From: Christophe Leroy @ 2019-08-19 6:40 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Doug Crawford
Cc: linuxppc-dev, linux-kernel
If a page is already mapped RW without the DIRTY flag, the DIRTY
flag is never set and a TLB store miss exception is taken forever.
This is easily reproduced with the following app:
void main(void)
{
volatile char *ptr = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
*ptr = *ptr;
}
When DIRTY flag is not set, bail out of TLB miss handler and take
a minor page fault which will set the DIRTY flag.
Fixes: f8b58c64eaef ("powerpc/603: let's handle PAGE_DIRTY directly")
Cc: stable@vger.kernel.org
Reported-by: Doug Crawford <doug.crawford@intelight-its.com>
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/kernel/head_32.S | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index f255e22184b4..534dd2718795 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -557,9 +557,9 @@ DataStoreTLBMiss:
cmplw 0,r1,r3
mfspr r2, SPRN_SPRG_PGDIR
#ifdef CONFIG_SWAP
- li r1, _PAGE_RW | _PAGE_PRESENT | _PAGE_ACCESSED
+ li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
#else
- li r1, _PAGE_RW | _PAGE_PRESENT
+ li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT
#endif
bge- 112f
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
--
2.13.3
^ permalink raw reply related
* Re: [PATCH v5 1/4] nvdimm: Consider probe return -EOPNOTSUPP as success
From: Aneesh Kumar K.V @ 2019-08-19 7:05 UTC (permalink / raw)
To: Dan Williams; +Cc: Linux MM, linuxppc-dev, linux-nvdimm
In-Reply-To: <CAPcyv4hxo4HvtqZ-B6JG5iATo_vEAKPzO5EU5Lugs2_edEbW7Q@mail.gmail.com>
Dan Williams <dan.j.williams@intel.com> writes:
> On Tue, Aug 13, 2019 at 9:22 PM Dan Williams <dan.j.williams@intel.com> wrote:
>>
>> Hi Aneesh, logic looks correct but there are some cleanups I'd like to
>> see and a lead-in patch that I attached.
>>
>> I've started prefixing nvdimm patches with:
>>
>> libnvdimm/$component:
>>
>> ...since this patch mostly impacts the pmem driver lets prefix it
>> "libnvdimm/pmem: "
>>
>> On Fri, Aug 9, 2019 at 12:45 AM Aneesh Kumar K.V
>> <aneesh.kumar@linux.ibm.com> wrote:
>> >
>> > This patch add -EOPNOTSUPP as return from probe callback to
>>
>> s/This patch add/Add/
>>
>> No need to say "this patch" it's obviously a patch.
>>
>> > indicate we were not able to initialize a namespace due to pfn superblock
>> > feature/version mismatch. We want to consider this a probe success so that
>> > we can create new namesapce seed and there by avoid marking the failed
>> > namespace as the seed namespace.
>>
>> Please replace usage of "we" with the exact agent involved as which
>> "we" is being referred to gets confusing for the reader.
>>
>> i.e. "indicate that the pmem driver was not..." "The nvdimm core wants
>> to consider this...".
>>
>> >
>> > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
>> > ---
>> > drivers/nvdimm/bus.c | 2 +-
>> > drivers/nvdimm/pmem.c | 26 ++++++++++++++++++++++----
>> > 2 files changed, 23 insertions(+), 5 deletions(-)
>> >
>> > diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
>> > index 798c5c4aea9c..16c35e6446a7 100644
>> > --- a/drivers/nvdimm/bus.c
>> > +++ b/drivers/nvdimm/bus.c
>> > @@ -95,7 +95,7 @@ static int nvdimm_bus_probe(struct device *dev)
>> > rc = nd_drv->probe(dev);
>> > debug_nvdimm_unlock(dev);
>> >
>> > - if (rc == 0)
>> > + if (rc == 0 || rc == -EOPNOTSUPP)
>> > nd_region_probe_success(nvdimm_bus, dev);
>>
>> This now makes the nd_region_probe_success() helper obviously misnamed
>> since it now wants to take actions on non-probe success. I attached a
>> lead-in cleanup that you can pull into your series that renames that
>> routine to nd_region_advance_seeds().
>>
>> When you rebase this needs a comment about why EOPNOTSUPP has special handling.
>>
>> > else
>> > nd_region_disable(nvdimm_bus, dev);
>> > diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
>> > index 4c121dd03dd9..3f498881dd28 100644
>> > --- a/drivers/nvdimm/pmem.c
>> > +++ b/drivers/nvdimm/pmem.c
>> > @@ -490,6 +490,7 @@ static int pmem_attach_disk(struct device *dev,
>> >
>> > static int nd_pmem_probe(struct device *dev)
>> > {
>> > + int ret;
>> > struct nd_namespace_common *ndns;
>> >
>> > ndns = nvdimm_namespace_common_probe(dev);
>> > @@ -505,12 +506,29 @@ static int nd_pmem_probe(struct device *dev)
>> > if (is_nd_pfn(dev))
>> > return pmem_attach_disk(dev, ndns);
>> >
>> > - /* if we find a valid info-block we'll come back as that personality */
>> > - if (nd_btt_probe(dev, ndns) == 0 || nd_pfn_probe(dev, ndns) == 0
>> > - || nd_dax_probe(dev, ndns) == 0)
>>
>> Similar need for an updated comment here to explain the special
>> translation of error codes.
>>
>> > + ret = nd_btt_probe(dev, ndns);
>> > + if (ret == 0)
>> > return -ENXIO;
>> > + else if (ret == -EOPNOTSUPP)
>>
>> Are there cases where the btt driver needs to return EOPNOTSUPP? I'd
>> otherwise like to keep this special casing constrained to the pfn /
>> dax info block cases.
>
> In fact I think EOPNOTSUPP is only something that the device-dax case
> would be concerned with because that's the only interface that
> attempts to guarantee a given mapping granularity.
We need to do similar error handling w.r.t fsdax when the pfn superblock
indicates different PAGE_SIZE and struct page size? I don't think btt
needs to support EOPNOTSUPP. But we can keep it for consistency?
-aneesh
^ permalink raw reply
* Re: [PATCH v5 3/4] mm/nvdimm: Use correct #defines instead of open coding
From: Aneesh Kumar K.V @ 2019-08-19 7:11 UTC (permalink / raw)
To: Dan Williams; +Cc: Linux MM, linuxppc-dev, linux-nvdimm
In-Reply-To: <CAPcyv4hc_-oGMp6jGVknnYs+rmj4W1A_gFCbmAX2LFw0hsfL5g@mail.gmail.com>
Dan Williams <dan.j.williams@intel.com> writes:
> On Fri, Aug 9, 2019 at 12:45 AM Aneesh Kumar K.V
> <aneesh.kumar@linux.ibm.com> wrote:
>>
>> Use PAGE_SIZE instead of SZ_4K and sizeof(struct page) instead of 64.
>> If we have a kernel built with different struct page size the previous
>> patch should handle marking the namespace disabled.
>
> Each of these changes carry independent non-overlapping regression
> risk, so lets split them into separate patches. Others might
>
>> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
>> ---
>> drivers/nvdimm/label.c | 2 +-
>> drivers/nvdimm/namespace_devs.c | 6 +++---
>> drivers/nvdimm/pfn_devs.c | 3 ++-
>> drivers/nvdimm/region_devs.c | 8 ++++----
>> 4 files changed, 10 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c
>> index 73e197babc2f..7ee037063be7 100644
>> --- a/drivers/nvdimm/label.c
>> +++ b/drivers/nvdimm/label.c
>> @@ -355,7 +355,7 @@ static bool slot_valid(struct nvdimm_drvdata *ndd,
>>
>> /* check that DPA allocations are page aligned */
>> if ((__le64_to_cpu(nd_label->dpa)
>> - | __le64_to_cpu(nd_label->rawsize)) % SZ_4K)
>> + | __le64_to_cpu(nd_label->rawsize)) % PAGE_SIZE)
>
> The UEFI label specification has no concept of PAGE_SIZE, so this
> check is a pure Linux-ism. There's no strict requirement why
> slot_valid() needs to check for page alignment and it would seem to
> actively hurt cross-page-size compatibility, so let's delete the check
> and rely on checksum validation.
Will do a separate patch to drop that check.
>
>> return false;
>>
>> /* check checksum */
>> diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
>> index a16e52251a30..a9c76df12cb9 100644
>> --- a/drivers/nvdimm/namespace_devs.c
>> +++ b/drivers/nvdimm/namespace_devs.c
>> @@ -1006,10 +1006,10 @@ static ssize_t __size_store(struct device *dev, unsigned long long val)
>> return -ENXIO;
>> }
>>
>> - div_u64_rem(val, SZ_4K * nd_region->ndr_mappings, &remainder);
>> + div_u64_rem(val, PAGE_SIZE * nd_region->ndr_mappings, &remainder);
>> if (remainder) {
>> - dev_dbg(dev, "%llu is not %dK aligned\n", val,
>> - (SZ_4K * nd_region->ndr_mappings) / SZ_1K);
>> + dev_dbg(dev, "%llu is not %ldK aligned\n", val,
>> + (PAGE_SIZE * nd_region->ndr_mappings) / SZ_1K);
>> return -EINVAL;
>
> Yes, looks good, but this deserves its own independent patch.
>
>> }
>>
>> diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
>> index 37e96811c2fc..c1d9be609322 100644
>> --- a/drivers/nvdimm/pfn_devs.c
>> +++ b/drivers/nvdimm/pfn_devs.c
>> @@ -725,7 +725,8 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
>> * when populating the vmemmap. This *should* be equal to
>> * PMD_SIZE for most architectures.
>> */
>> - offset = ALIGN(start + SZ_8K + 64 * npfns, align) - start;
>> + offset = ALIGN(start + SZ_8K + sizeof(struct page) * npfns,
>
> I'd prefer if this was not dynamic and was instead set to the maximum
> size of 'struct page' across all archs just to enhance cross-arch
> compatibility. I think that answer is '64'.
That still doesn't take care of the case where we add new elements to
struct page later. If we have struct page size changing across
architectures, we should still be ok as long as new size is less than what is
stored in pfn superblock? I understand the desire to keep it
non-dynamic. But we also need to make sure we don't reserve less space
when creating a new namespace on a config that got struct page size >
64?
>> + align) - start;
>> } else if (nd_pfn->mode == PFN_MODE_RAM)
>> offset = ALIGN(start + SZ_8K, align) - start;
>> else
>> diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
>> index af30cbe7a8ea..20e265a534f8 100644
>> --- a/drivers/nvdimm/region_devs.c
>> +++ b/drivers/nvdimm/region_devs.c
>> @@ -992,10 +992,10 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus,
>> struct nd_mapping_desc *mapping = &ndr_desc->mapping[i];
>> struct nvdimm *nvdimm = mapping->nvdimm;
>>
>> - if ((mapping->start | mapping->size) % SZ_4K) {
>> - dev_err(&nvdimm_bus->dev, "%s: %s mapping%d is not 4K aligned\n",
>> - caller, dev_name(&nvdimm->dev), i);
>> -
>> + if ((mapping->start | mapping->size) % PAGE_SIZE) {
>> + dev_err(&nvdimm_bus->dev,
>> + "%s: %s mapping%d is not %ld aligned\n",
>> + caller, dev_name(&nvdimm->dev), i, PAGE_SIZE);
>> return NULL;
>> }
>>
>> --
>> 2.21.0
>>
^ permalink raw reply
* Re: [PATCH] powerpc: Don't add -mabi= flags when building with Clang
From: Daniel Axtens @ 2019-08-19 7:25 UTC (permalink / raw)
To: Nathan Chancellor, Benjamin Herrenschmidt, Paul Mackerras,
Michael Ellerman
Cc: clang-built-linux, Nathan Chancellor, linuxppc-dev, linux-kernel
In-Reply-To: <20190818191321.58185-1-natechancellor@gmail.com>
Hi Nathan,
> When building pseries_defconfig, building vdso32 errors out:
>
> error: unknown target ABI 'elfv1'
>
> Commit 4dc831aa8813 ("powerpc: Fix compiling a BE kernel with a
> powerpc64le toolchain") added these flags to fix building GCC but
> clang is multitargeted and does not need these flags. The ABI is
> properly set based on the target triple, which is derived from
> CROSS_COMPILE.
>
> https://github.com/llvm/llvm-project/blob/llvmorg-9.0.0-rc2/clang/lib/Driver/ToolChains/Clang.cpp#L1782-L1804
>
> -mcall-aixdesc is not an implemented flag in clang so it can be
> safely excluded as well, see commit 238abecde8ad ("powerpc: Don't
> use gcc specific options on clang").
>
This all looks good to me, thanks for picking it up, and sorry I hadn't
got around to it!
The makefile is a bit messy and there are a few ways it could probably
be reorganised to reduce ifdefs. But I don't think this is the right
place to do that. With that in mind,
Reviewed-by: Daniel Axtens <dja@axtens.net>
Regards,
Daniel
> pseries_defconfig successfully builds after this patch and
> powernv_defconfig and ppc44x_defconfig don't regress.
>
> Link: https://github.com/ClangBuiltLinux/linux/issues/240
> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> ---
> arch/powerpc/Makefile | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
> index c345b79414a9..971b04bc753d 100644
> --- a/arch/powerpc/Makefile
> +++ b/arch/powerpc/Makefile
> @@ -93,11 +93,13 @@ MULTIPLEWORD := -mmultiple
> endif
>
> ifdef CONFIG_PPC64
> +ifndef CONFIG_CC_IS_CLANG
> cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mabi=elfv1)
> cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mcall-aixdesc)
> aflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mabi=elfv1)
> aflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mabi=elfv2
> endif
> +endif
>
> ifndef CONFIG_CC_IS_CLANG
> cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mno-strict-align
> @@ -144,6 +146,7 @@ endif
> endif
>
> CFLAGS-$(CONFIG_PPC64) := $(call cc-option,-mtraceback=no)
> +ifndef CONFIG_CC_IS_CLANG
> ifdef CONFIG_CPU_LITTLE_ENDIAN
> CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2,$(call cc-option,-mcall-aixdesc))
> AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2)
> @@ -152,6 +155,7 @@ CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1)
> CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcall-aixdesc)
> AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1)
> endif
> +endif
> CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,$(call cc-option,-mminimal-toc))
> CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions)
>
> --
> 2.23.0
^ 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