* Re: BUG: KASAN: stack-out-of-bounds
From: Andrey Ryabinin @ 2019-02-27 9:19 UTC (permalink / raw)
To: Christophe Leroy, Alexander Potapenko, Dmitry Vyukov
Cc: linux-mm, linuxppc-dev, kasan-dev, Daniel Axtens
In-Reply-To: <c6d80735-0cfe-b4ab-0349-673fc65b2e15@c-s.fr>
On 2/27/19 11:25 AM, Christophe Leroy wrote:
> With version v8 of the series implementing KASAN on 32 bits powerpc (https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=94309), I'm now able to activate KASAN on a mac99 is QEMU.
>
> Then I get the following reports at startup. Which of the two reports I get seems to depend on the option used to build the kernel, but for a given kernel I always get the same report.
>
> Is that a real bug, in which case how could I spot it ? Or is it something wrong in my implementation of KASAN ?
>
> I checked that after kasan_init(), the entire shadow memory is full of 0 only.
>
> I also made a try with the strong STACK_PROTECTOR compiled in, but no difference and nothing detected by the stack protector.
>
> ==================================================================
> BUG: KASAN: stack-out-of-bounds in memchr+0x24/0x74
> Read of size 1 at addr c0ecdd40 by task swapper/0
>
> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1133
> Call Trace:
> [c0e9dca0] [c01c42a0] print_address_description+0x64/0x2bc (unreliable)
> [c0e9dcd0] [c01c4684] kasan_report+0xfc/0x180
> [c0e9dd10] [c089579c] memchr+0x24/0x74
> [c0e9dd30] [c00a9e38] msg_print_text+0x124/0x574
> [c0e9dde0] [c00ab710] console_unlock+0x114/0x4f8
> [c0e9de40] [c00adc60] vprintk_emit+0x188/0x1c4
> --- interrupt: c0e9df00 at 0x400f330
> LR = init_stack+0x1f00/0x2000
> [c0e9de80] [c00ae3c4] printk+0xa8/0xcc (unreliable)
> [c0e9df20] [c0c28e44] early_irq_init+0x38/0x108
> [c0e9df50] [c0c16434] start_kernel+0x310/0x488
> [c0e9dff0] [00003484] 0x3484
>
> The buggy address belongs to the variable:
> __log_buf+0xec0/0x4020
> The buggy address belongs to the page:
> page:c6eac9a0 count:1 mapcount:0 mapping:00000000 index:0x0
> flags: 0x1000(reserved)
> raw: 00001000 c6eac9a4 c6eac9a4 00000000 00000000 00000000 ffffffff 00000001
> page dumped because: kasan: bad access detected
>
> Memory state around the buggy address:
> c0ecdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> c0ecdc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>c0ecdd00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00
> ^
> c0ecdd80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
> c0ecde00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> ==================================================================
>
This one doesn't look good. Notice that it says stack-out-of-bounds, but at the same time there is
"The buggy address belongs to the variable: __log_buf+0xec0/0x4020"
which is printed by following code:
if (kernel_or_module_addr(addr) && !init_task_stack_addr(addr)) {
pr_err("The buggy address belongs to the variable:\n");
pr_err(" %pS\n", addr);
}
So the stack unrelated address got stack-related poisoning. This could be a stack overflow, did you increase THREAD_SHIFT?
KASAN with stack instrumentation significantly increases stack usage.
^ permalink raw reply
* Re: BUG: KASAN: stack-out-of-bounds
From: Dmitry Vyukov @ 2019-02-27 9:25 UTC (permalink / raw)
To: Andrey Ryabinin
Cc: kasan-dev, Linux-MM, Alexander Potapenko, linuxppc-dev,
Daniel Axtens
In-Reply-To: <5f0203bd-77ea-d94c-11b7-1befba439cd4@virtuozzo.com>
On Wed, Feb 27, 2019 at 10:18 AM Andrey Ryabinin
<aryabinin@virtuozzo.com> wrote:
> On 2/27/19 11:25 AM, Christophe Leroy wrote:
> > With version v8 of the series implementing KASAN on 32 bits powerpc (https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=94309), I'm now able to activate KASAN on a mac99 is QEMU.
> >
> > Then I get the following reports at startup. Which of the two reports I get seems to depend on the option used to build the kernel, but for a given kernel I always get the same report.
> >
> > Is that a real bug, in which case how could I spot it ? Or is it something wrong in my implementation of KASAN ?
> >
> > I checked that after kasan_init(), the entire shadow memory is full of 0 only.
> >
> > I also made a try with the strong STACK_PROTECTOR compiled in, but no difference and nothing detected by the stack protector.
> >
> > ==================================================================
> > BUG: KASAN: stack-out-of-bounds in memchr+0x24/0x74
> > Read of size 1 at addr c0ecdd40 by task swapper/0
> >
> > CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1133
> > Call Trace:
> > [c0e9dca0] [c01c42a0] print_address_description+0x64/0x2bc (unreliable)
> > [c0e9dcd0] [c01c4684] kasan_report+0xfc/0x180
> > [c0e9dd10] [c089579c] memchr+0x24/0x74
> > [c0e9dd30] [c00a9e38] msg_print_text+0x124/0x574
> > [c0e9dde0] [c00ab710] console_unlock+0x114/0x4f8
> > [c0e9de40] [c00adc60] vprintk_emit+0x188/0x1c4
> > --- interrupt: c0e9df00 at 0x400f330
> > LR = init_stack+0x1f00/0x2000
> > [c0e9de80] [c00ae3c4] printk+0xa8/0xcc (unreliable)
> > [c0e9df20] [c0c28e44] early_irq_init+0x38/0x108
> > [c0e9df50] [c0c16434] start_kernel+0x310/0x488
> > [c0e9dff0] [00003484] 0x3484
> >
> > The buggy address belongs to the variable:
> > __log_buf+0xec0/0x4020
> > The buggy address belongs to the page:
> > page:c6eac9a0 count:1 mapcount:0 mapping:00000000 index:0x0
> > flags: 0x1000(reserved)
> > raw: 00001000 c6eac9a4 c6eac9a4 00000000 00000000 00000000 ffffffff 00000001
> > page dumped because: kasan: bad access detected
> >
> > Memory state around the buggy address:
> > c0ecdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > c0ecdc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>c0ecdd00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00
> > ^
> > c0ecdd80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
> > c0ecde00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > ==================================================================
> >
>
> This one doesn't look good. Notice that it says stack-out-of-bounds, but at the same time there is
> "The buggy address belongs to the variable: __log_buf+0xec0/0x4020"
> which is printed by following code:
> if (kernel_or_module_addr(addr) && !init_task_stack_addr(addr)) {
> pr_err("The buggy address belongs to the variable:\n");
> pr_err(" %pS\n", addr);
> }
>
> So the stack unrelated address got stack-related poisoning. This could be a stack overflow, did you increase THREAD_SHIFT?
> KASAN with stack instrumentation significantly increases stack usage.
A straightforward explanation would be that this happens before real
shadow is mapped and we don't turn off KASAN reports. Should be easy
to check so worth eliminating this possibility before any other
debugging.
^ permalink raw reply
* Re: BUG: KASAN: stack-out-of-bounds
From: Christophe Leroy @ 2019-02-27 9:33 UTC (permalink / raw)
To: Dmitry Vyukov, Andrey Ryabinin
Cc: Linux-MM, Alexander Potapenko, linuxppc-dev, kasan-dev,
Daniel Axtens
In-Reply-To: <CACT4Y+Ze0Ezi4uKVZR1nk_EOjNcHd=JLhYq8ahqbfOL_8Jq9iw@mail.gmail.com>
Le 27/02/2019 à 10:25, Dmitry Vyukov a écrit :
> On Wed, Feb 27, 2019 at 10:18 AM Andrey Ryabinin
> <aryabinin@virtuozzo.com> wrote:
>> On 2/27/19 11:25 AM, Christophe Leroy wrote:
>>> With version v8 of the series implementing KASAN on 32 bits powerpc (https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=94309), I'm now able to activate KASAN on a mac99 is QEMU.
>>>
>>> Then I get the following reports at startup. Which of the two reports I get seems to depend on the option used to build the kernel, but for a given kernel I always get the same report.
>>>
>>> Is that a real bug, in which case how could I spot it ? Or is it something wrong in my implementation of KASAN ?
>>>
>>> I checked that after kasan_init(), the entire shadow memory is full of 0 only.
>>>
>>> I also made a try with the strong STACK_PROTECTOR compiled in, but no difference and nothing detected by the stack protector.
>>>
>>> ==================================================================
>>> BUG: KASAN: stack-out-of-bounds in memchr+0x24/0x74
>>> Read of size 1 at addr c0ecdd40 by task swapper/0
>>>
>>> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1133
>>> Call Trace:
>>> [c0e9dca0] [c01c42a0] print_address_description+0x64/0x2bc (unreliable)
>>> [c0e9dcd0] [c01c4684] kasan_report+0xfc/0x180
>>> [c0e9dd10] [c089579c] memchr+0x24/0x74
>>> [c0e9dd30] [c00a9e38] msg_print_text+0x124/0x574
>>> [c0e9dde0] [c00ab710] console_unlock+0x114/0x4f8
>>> [c0e9de40] [c00adc60] vprintk_emit+0x188/0x1c4
>>> --- interrupt: c0e9df00 at 0x400f330
>>> LR = init_stack+0x1f00/0x2000
>>> [c0e9de80] [c00ae3c4] printk+0xa8/0xcc (unreliable)
>>> [c0e9df20] [c0c28e44] early_irq_init+0x38/0x108
>>> [c0e9df50] [c0c16434] start_kernel+0x310/0x488
>>> [c0e9dff0] [00003484] 0x3484
>>>
>>> The buggy address belongs to the variable:
>>> __log_buf+0xec0/0x4020
>>> The buggy address belongs to the page:
>>> page:c6eac9a0 count:1 mapcount:0 mapping:00000000 index:0x0
>>> flags: 0x1000(reserved)
>>> raw: 00001000 c6eac9a4 c6eac9a4 00000000 00000000 00000000 ffffffff 00000001
>>> page dumped because: kasan: bad access detected
>>>
>>> Memory state around the buggy address:
>>> c0ecdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> c0ecdc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>>> c0ecdd00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00
>>> ^
>>> c0ecdd80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
>>> c0ecde00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ==================================================================
>>>
>>
>> This one doesn't look good. Notice that it says stack-out-of-bounds, but at the same time there is
>> "The buggy address belongs to the variable: __log_buf+0xec0/0x4020"
>> which is printed by following code:
>> if (kernel_or_module_addr(addr) && !init_task_stack_addr(addr)) {
>> pr_err("The buggy address belongs to the variable:\n");
>> pr_err(" %pS\n", addr);
>> }
>>
>> So the stack unrelated address got stack-related poisoning. This could be a stack overflow, did you increase THREAD_SHIFT?
>> KASAN with stack instrumentation significantly increases stack usage.
>
> A straightforward explanation would be that this happens before real
> shadow is mapped and we don't turn off KASAN reports. Should be easy
> to check so worth eliminating this possibility before any other
> debugging.
>
I confirm this happens _after_ the call of kasan_init() which sets up
the final shadow mapping. And after the call of kasan_init() I can
confirm that the entire shadow area is zeroized.
kasan_init() is called at the top of setup_arch() which is called soon
after the begining of start_kernel() (see 'KASAN init done' below).
early_irq_init() is called long after that.
Booting Linux via __start() @ 0x01000000 ...
Hello World !
Total memory = 128MB; using 256kB for hash table (at (ptrval))
Linux version 5.0.0-rc7+ (root@po16846vm.idsi0.si.c-s.fr) (gcc version
5.4.0 (GCC)) #1133 Tue Feb 26 03:30:01 UTC 2019
KASAN init done
Found UniNorth memory controller & host bridge @ 0xf8000000 revision: 0x07
Mapped at 0xf77c0000
Found a Keylargo mac-io controller, rev: 0, mapped at 0x(ptrval)
PowerMac motherboard: PowerMac G4 AGP Graphics
boot stdout isn't a display !
Using PowerMac machine description
printk: bootconsole [udbg0] enabled
-----------------------------------------------------
Hash_size = 0x40000
phys_mem_size = 0x8000000
dcache_bsize = 0x20
icache_bsize = 0x20
cpu_features = 0x000000000401a00a
possible = 0x000000002f7ff14b
always = 0x0000000000000000
cpu_user_features = 0x9c000001 0x00000000
mmu_features = 0x00000001
Hash = 0x(ptrval)
Hash_mask = 0xfff
-----------------------------------------------------
Found UniNorth PCI host bridge at 0x00000000f2000000. Firmware bus
number: 0->0
PCI host bridge /pci@f2000000 (primary) ranges:
IO 0x00000000f2000000..0x00000000f27fffff -> 0x0000000000000000
MEM 0x0000000080000000..0x000000008fffffff -> 0x0000000080000000
nvram: Checking bank 0...
Invalid signature
Invalid checksum
nvram: gen0=0, gen1=0
nvram: Active bank is: 0
nvram: OF partition at 0xffffffff
nvram: XP partition at 0xffffffff
nvram: NR partition at 0xffffffff
Zone ranges:
Normal [mem 0x0000000000000000-0x0000000007ffffff]
HighMem empty
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x0000000000000000-0x0000000007ffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x0000000007ffffff]
Built 1 zonelists, mobility grouping on. Total pages: 32512
Kernel command line: console=/dev/ttyS0
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 93544K/131072K available (8868K kernel code, 1700K rwdata, 3484K
rodata, 1004K init, 4434K bss, 37528K reserved, 0K cma-reserved, 0K highmem)
Kernel virtual memory layout:
* 0xf8000000..0x00000000 : kasan shadow mem
* 0xf7fd0000..0xf8000000 : fixmap
* 0xf7800000..0xf7c00000 : highmem PTEs
* 0xf6f36000..0xf7800000 : early ioremap
* 0xc9000000..0xf6f36000 : vmalloc & ioremap
SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS: 512, nr_irqs: 512, preallocated irqs: 16
mpic: Setting up MPIC " MPIC 1 " version 1.2 at 80040000, max 1 CPUs
mpic: ISU size: 64, shift: 6, mask: 3f
mpic: Initializing for 64 sources
GMT Delta read from XPRAM: 0 minutes, DST: on
clocksource: timebase: mask: 0xffffffffffffffff max_cycles:
0x171024e7e0, max_idle_ns: 440795205315 ns
clocksource: timebase mult[a000000] shift[24] registered
==================================================================
BUG: KASAN: stack-out-of-bounds in memchr+0x24/0x74
Read of size 1 at addr c0ecdd40 by task swapper/0
...
Christophe
^ permalink raw reply
* [PATCH] powernv: powercap: Add hard minimum powercap
From: Shilpasri G Bhat @ 2019-02-27 9:33 UTC (permalink / raw)
To: mpe; +Cc: ego, linuxppc-dev, linux-kernel, Shilpasri G Bhat
In POWER9, OCC(On-Chip-Controller) provides for hard and soft system
powercapping range. The hard powercap range is guaranteed while soft
powercap may or may not be asserted due to various power-thermal
reasons based on system configuration and workloads. This patch adds
a sysfs file to export the hard minimum powercap limit to allow the
user to set the appropriate powercap value that can be managed by the
system.
Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
---
.../ABI/testing/sysfs-firmware-opal-powercap | 10 ++++
arch/powerpc/platforms/powernv/opal-powercap.c | 66 +++++++++-------------
2 files changed, 37 insertions(+), 39 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-firmware-opal-powercap b/Documentation/ABI/testing/sysfs-firmware-opal-powercap
index c9b66ec..65db4c1 100644
--- a/Documentation/ABI/testing/sysfs-firmware-opal-powercap
+++ b/Documentation/ABI/testing/sysfs-firmware-opal-powercap
@@ -29,3 +29,13 @@ Description: System powercap directory and attributes applicable for
creates a request for setting a new-powercap. The
powercap requested must be between powercap-min
and powercap-max.
+
+What: /sys/firmware/opal/powercap/system-powercap/powercap-hard-min
+Date: Feb 2019
+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
+Description: Hard minimum powercap
+
+ This file provides the hard minimum powercap limit in
+ Watts. The powercap value above hard minimum is always
+ guaranteed to be asserted and the powercap value below
+ the hard minimum limit may or may not be guaranteed.
diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c
index d90ee4f..38408e7 100644
--- a/arch/powerpc/platforms/powernv/opal-powercap.c
+++ b/arch/powerpc/platforms/powernv/opal-powercap.c
@@ -139,10 +139,24 @@ static void powercap_add_attr(int handle, const char *name,
attr->handle = handle;
sysfs_attr_init(&attr->attr.attr);
attr->attr.attr.name = name;
- attr->attr.attr.mode = 0444;
+
+ if (!strncmp(name, "powercap-current", strlen(name))) {
+ attr->attr.attr.mode = 0664;
+ attr->attr.store = powercap_store;
+ } else {
+ attr->attr.attr.mode = 0444;
+ }
+
attr->attr.show = powercap_show;
}
+static const char * const powercap_strs[] = {
+ "powercap-max",
+ "powercap-min",
+ "powercap-current",
+ "powercap-hard-min",
+};
+
void __init opal_powercap_init(void)
{
struct device_node *powercap, *node;
@@ -167,60 +181,34 @@ void __init opal_powercap_init(void)
i = 0;
for_each_child_of_node(powercap, node) {
- u32 cur, min, max;
- int j = 0;
- bool has_cur = false, has_min = false, has_max = false;
+ u32 id;
+ int j, count = 0;
- if (!of_property_read_u32(node, "powercap-min", &min)) {
- j++;
- has_min = true;
- }
-
- if (!of_property_read_u32(node, "powercap-max", &max)) {
- j++;
- has_max = true;
- }
+ for (j = 0; j < ARRAY_SIZE(powercap_strs); j++)
+ if (!of_property_read_u32(node, powercap_strs[j], &id))
+ count++;
- if (!of_property_read_u32(node, "powercap-current", &cur)) {
- j++;
- has_cur = true;
- }
-
- pcaps[i].pattrs = kcalloc(j, sizeof(struct powercap_attr),
+ pcaps[i].pattrs = kcalloc(count, sizeof(struct powercap_attr),
GFP_KERNEL);
if (!pcaps[i].pattrs)
goto out_pcaps_pattrs;
- pcaps[i].pg.attrs = kcalloc(j + 1, sizeof(struct attribute *),
+ pcaps[i].pg.attrs = kcalloc(count + 1,
+ sizeof(struct attribute *),
GFP_KERNEL);
if (!pcaps[i].pg.attrs) {
kfree(pcaps[i].pattrs);
goto out_pcaps_pattrs;
}
- j = 0;
pcaps[i].pg.name = kasprintf(GFP_KERNEL, "%pOFn", node);
- if (has_min) {
- powercap_add_attr(min, "powercap-min",
- &pcaps[i].pattrs[j]);
- pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
- j++;
- }
-
- if (has_max) {
- powercap_add_attr(max, "powercap-max",
- &pcaps[i].pattrs[j]);
- pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
- j++;
- }
+ for (j = 0; j < ARRAY_SIZE(powercap_strs); j++) {
+ if (of_property_read_u32(node, powercap_strs[j], &id))
+ continue;
- if (has_cur) {
- powercap_add_attr(cur, "powercap-current",
+ powercap_add_attr(id, powercap_strs[j],
&pcaps[i].pattrs[j]);
- pcaps[i].pattrs[j].attr.attr.mode |= 0220;
- pcaps[i].pattrs[j].attr.store = powercap_store;
pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
- j++;
}
if (sysfs_create_group(powercap_kobj, &pcaps[i].pg)) {
--
1.8.3.1
^ permalink raw reply related
* [PATCH v3 1/2] arch: powerpc/kexec: Add missing of_node-put() in default_machine_kexec_prepare()
From: Himadri Pandya @ 2019-02-27 9:51 UTC (permalink / raw)
To: benh, paulus, mpe, tyreld; +Cc: linuxppc-dev, Himadri Pandya
In-Reply-To: <20190225090056.19055-1-himadri18.07@gmail.com>
Decrement the reference count on device_node "node" while breaking out
of the loop. Issue identified by Coccinelle.
Signed-off-by: Himadri Pandya <himadri18.07@gmail.com>
---
Changes in V2:
- Change subject line
---
Changes in V3:
- Add braces around the if block
---
arch/powerpc/kernel/machine_kexec_64.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index a0f6f45005bd..ef484a25fc50 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -64,8 +64,10 @@ int default_machine_kexec_prepare(struct kimage *image)
begin = image->segment[i].mem;
end = begin + image->segment[i].memsz;
- if ((begin < high) && (end > low))
+ if ((begin < high) && (end > low)) {
+ of_node_put(node);
return -ETXTBSY;
+ }
}
}
--
2.17.1
^ permalink raw reply related
* [PATCH v3 2/2] arch: powerpc/hlwd-pic: Add missing of_node-put() in hlwd_pic_probe()
From: Himadri Pandya @ 2019-02-27 9:51 UTC (permalink / raw)
To: benh, paulus, mpe, tyreld; +Cc: linuxppc-dev, Himadri Pandya
In-Reply-To: <20190227095138.30263-1-himadri18.07@gmail.com>
Decrement the reference count on device_node "np" while breaking out of
the loop. Issue identified by Coccinelle.
Signed-off-by: Himadri Pandya <himadri18.07@gmail.com>
---
Changes in V2:
- Change subject line
---
Changes in V3:
- Do not remove the blank line at end of the file
---
arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 8112b39879d6..df098989e373 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -220,6 +220,7 @@ void hlwd_pic_probe(void)
irq_set_chained_handler(cascade_virq,
hlwd_pic_irq_cascade);
hlwd_irq_host = host;
+ of_node_put(np);
break;
}
}
@@ -232,7 +233,7 @@ void hlwd_pic_probe(void)
*
*/
void hlwd_quiesce(void)
-{
+{i
void __iomem *io_base = hlwd_irq_host->host_data;
__hlwd_quiesce(io_base);
--
2.17.1
^ permalink raw reply related
* Re: build failure of current mmotm with skiroot_defconfig
From: Paul Mackerras @ 2019-02-27 11:13 UTC (permalink / raw)
To: Christophe Leroy; +Cc: Andrew Morton, linuxppc-dev, Mike Rapoport
In-Reply-To: <fea8a5ef-2c90-8222-fc80-3ae77a2fd473@c-s.fr>
On Wed, Feb 27, 2019 at 07:41:21AM +0100, Christophe Leroy wrote:
>
>
> Le 26/02/2019 à 23:24, Paul Mackerras a écrit :
> >On Tue, Feb 26, 2019 at 11:59:08AM +0200, Mike Rapoport wrote:
> >>On Tue, Feb 26, 2019 at 10:39:54AM +0100, Christophe Leroy wrote:
> >>>
> >>>
> >>>Le 26/02/2019 à 09:12, Mike Rapoport a écrit :
> >>>>Hi,
> >>>>
> >>>>I've encountered the following error when building skyroot_defconfig with
> >>>>current mmotm tree:
> >>>>
> >>>>make CONFIG_OF_ALL_DTBS=y CONFIG_DTC=y CROSS_COMPILE=/opt/gcc-8.1.0-nolibc/powerpc64-linux/bin/powerpc64-linux- ARCH=powerpc vmlinux
> >>>> ...
> >>>> CC arch/powerpc/kernel/dbell.o
> >>>>In file included from arch/powerpc/kernel/dbell.c:20:
> >>>>arch/powerpc/include/asm/kvm_ppc.h: In function 'xics_on_xive':
> >>>>arch/powerpc/include/asm/kvm_ppc.h:625:9: error: implicit declaration of function 'xive_enabled'; did you mean 'eeh_enabled'? [-Werror=implicit-function-declaration]
> >>>> return xive_enabled() && cpu_has_feature(CPU_FTR_HVMODE);
> >>>> ^~~~~~~~~~~~
> >>>> eeh_enabled
> >>>
> >>>I can neither find the above in arch/powerpc/include/asm/kvm_ppc.h in the
> >>>powerpc tree, nor a patch removing it.
> >>>
> >>>Where does that comes from ?
> >>
> >>It's from current mmotm, probably some merge conflict...
> >
> >It's not a merge conflict; see http://patchwork.ozlabs.org/patch/1048584/
> >for the fix.
> >
>
> Why not include asm/xive.h all the time, as it defines xive_enabled() for
> when CONFIG_PPC_XIVE is set and for when it is not set ?
I wasn't sure it wouldn't break the build for 32-bit configs.
Paul.
^ permalink raw reply
* Re: [PATCH V7 0/4] mm/kvm/vfio/ppc64: Migrate compound pages out of CMA region
From: Michael Ellerman @ 2019-02-27 11:29 UTC (permalink / raw)
To: Aneesh Kumar K.V, Andrew Morton
Cc: Andrea Arcangeli, Alexey Kardashevskiy, linux-kernel,
Michal Hocko, linux-mm, linuxppc-dev, David Gibson
In-Reply-To: <87mumhtxxx.fsf@linux.ibm.com>
"Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> writes:
> Andrew Morton <akpm@linux-foundation.org> writes:
>
>> [patch 1/4]: OK. I guess. Was this worth consuming our last PF_ flag?
>
> That was done based on request from Andrea and it also helps in avoiding
> allocating pages from CMA region where we know we are anyway going to
> migrate them out. So yes, this helps.
>
>> [patch 2/4]: unreviewed
>> [patch 3/4]: unreviewed, mpe still unhappy, I expect?
>
> I did reply to that email. I guess mpe is ok with that?
It would be nice to fold your explanation about DAX into the change log,
so it's there for people to see.
And I think my comment about initialising ret still stands.
cheers
^ permalink raw reply
* [PATCH] powerpc/32: Clear on-stack exception marker upon exception return
From: Christophe Leroy @ 2019-02-27 11:45 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Nicolai Stange
Cc: linuxppc-dev, linux-kernel, stable
Clear the on-stack STACK_FRAME_REGS_MARKER on exception exit in order
to avoid confusing stacktrace like the one below.
Call Trace:
[c0e9dca0] [c01c42a0] print_address_description+0x64/0x2bc (unreliable)
[c0e9dcd0] [c01c4684] kasan_report+0xfc/0x180
[c0e9dd10] [c0895130] memchr+0x24/0x74
[c0e9dd30] [c00a9e38] msg_print_text+0x124/0x574
[c0e9dde0] [c00ab710] console_unlock+0x114/0x4f8
[c0e9de40] [c00adc60] vprintk_emit+0x188/0x1c4
--- interrupt: c0e9df00 at 0x400f330
LR = init_stack+0x1f00/0x2000
[c0e9de80] [c00ae3c4] printk+0xa8/0xcc (unreliable)
[c0e9df20] [c0c27e44] early_irq_init+0x38/0x108
[c0e9df50] [c0c15434] start_kernel+0x310/0x488
[c0e9dff0] [00003484] 0x3484
With this patch the trace becomes:
Call Trace:
[c0e9dca0] [c01c42c0] print_address_description+0x64/0x2bc (unreliable)
[c0e9dcd0] [c01c46a4] kasan_report+0xfc/0x180
[c0e9dd10] [c0895150] memchr+0x24/0x74
[c0e9dd30] [c00a9e58] msg_print_text+0x124/0x574
[c0e9dde0] [c00ab730] console_unlock+0x114/0x4f8
[c0e9de40] [c00adc80] vprintk_emit+0x188/0x1c4
[c0e9de80] [c00ae3e4] printk+0xa8/0xcc
[c0e9df20] [c0c27e44] early_irq_init+0x38/0x108
[c0e9df50] [c0c15434] start_kernel+0x310/0x488
[c0e9dff0] [00003484] 0x3484
Cc: stable@vger.kernel.org
Cc: Nicolai Stange <nstange@suse.de>
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/kernel/entry_32.S | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 96dce6a4b61e..b61cfd29c76f 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -730,6 +730,9 @@ fast_exception_return:
mtcr r10
lwz r10,_LINK(r11)
mtlr r10
+ /* Clear the exception_marker on the stack to avoid confusing stacktrace */
+ li r10, 0
+ stw r10, 8(r11)
REST_GPR(10, r11)
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
mtspr SPRN_NRI, r0
@@ -961,6 +964,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
mtcrf 0xFF,r10
mtlr r11
+ /* Clear the exception_marker on the stack to avoid confusing stacktrace */
+ li r10, 0
+ stw r10, 8(r1)
/*
* Once we put values in SRR0 and SRR1, we are in a state
* where exceptions are not recoverable, since taking an
@@ -997,6 +1003,9 @@ exc_exit_restart_end:
mtlr r11
lwz r10,_CCR(r1)
mtcrf 0xff,r10
+ /* Clear the exception_marker on the stack to avoid confusing stacktrace */
+ li r10, 0
+ stw r10, 8(r1)
REST_2GPRS(9, r1)
.globl exc_exit_restart
exc_exit_restart:
--
2.13.3
^ permalink raw reply related
* Re: [PATCH] powerpc/powernv: Make opal log only readable by root
From: Michael Ellerman @ 2019-02-27 11:54 UTC (permalink / raw)
To: Jordan Niethe, linuxppc-dev; +Cc: Jordan Niethe, Stewart Smith
In-Reply-To: <20190227030229.12814-1-jniethe5@gmail.com>
Jordan Niethe <jniethe5@gmail.com> writes:
> Currently the opal log is globally readable. It is kernel policy to limit
> the visibility of physical addresses / kernel pointers to root.
> Given this and the fact the opal log may contain this information it would
> be better to limit the readability to root.
Yikes, thanks for fixing that.
I'll add a Fixes: tag and Cc stable.
I also see symbol_map is 0444, I think that should be fixed too.
cheers
> diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c b/arch/powerpc/platforms/powernv/opal-msglog.c
> index acd3206dfae3..06628c71cef6 100644
> --- a/arch/powerpc/platforms/powernv/opal-msglog.c
> +++ b/arch/powerpc/platforms/powernv/opal-msglog.c
> @@ -98,7 +98,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
> }
>
> static struct bin_attribute opal_msglog_attr = {
> - .attr = {.name = "msglog", .mode = 0444},
> + .attr = {.name = "msglog", .mode = 0400},
> .read = opal_msglog_read
> };
>
> --
> 2.20.1
^ permalink raw reply
* Re: [PATCH v2] powerpc/powernv/idle: Restore IAMR after idle
From: Akshay Adiga @ 2019-02-27 12:06 UTC (permalink / raw)
To: Russell Currey; +Cc: linuxppc-dev
In-Reply-To: <20190208111103.4901-1-ruscur@russell.cc>
The changes look good to me.
On Fri, Feb 08, 2019 at 10:11:03PM +1100, Russell Currey wrote:
> Without restoring the IAMR after idle, execution prevention on POWER9
> with Radix MMU is overwritten and the kernel can freely execute userspace without
> faulting.
>
> This is necessary when returning from any stop state that modifies user
> state, as well as hypervisor state.
>
> To test how this fails without this patch, load the lkdtm driver and
> do the following:
>
> echo EXEC_USERSPACE > /sys/kernel/debug/provoke-crash/DIRECT
>
> which won't fault, then boot the kernel with powersave=off, where it
> will fault. Applying this patch will fix this.
>
> Fixes: 3b10d0095a1e ("powerpc/mm/radix: Prevent kernel execution of user
> space")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Russell Currey <ruscur@russell.cc>
Reviewed-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>
^ permalink raw reply
* Re: BUG: KASAN: stack-out-of-bounds
From: Christophe Leroy @ 2019-02-27 12:35 UTC (permalink / raw)
To: Dmitry Vyukov
Cc: kasan-dev, Linux-MM, Alexander Potapenko, Andrey Ryabinin,
linuxppc-dev, Daniel Axtens
In-Reply-To: <CACT4Y+bTBGfsLq+bE9-no8sj8yvrkPN6iaELZMi7DX4Vr59zrA@mail.gmail.com>
On 02/27/2019 08:34 AM, Dmitry Vyukov wrote:
> On Wed, Feb 27, 2019 at 9:25 AM Christophe Leroy
> <christophe.leroy@c-s.fr> wrote:
>>
>> With version v8 of the series implementing KASAN on 32 bits powerpc
>> (https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=94309),
>> I'm now able to activate KASAN on a mac99 is QEMU.
>>
>> Then I get the following reports at startup. Which of the two reports I
>> get seems to depend on the option used to build the kernel, but for a
>> given kernel I always get the same report.
>>
>> Is that a real bug, in which case how could I spot it ? Or is it
>> something wrong in my implementation of KASAN ?
>
> What is the state of your source tree?
> Please pass output through some symbolization script, function offsets
> are not too useful.
> There was some in scripts/ dir IIRC, but here is another one (though,
> never tested on powerpc):
> https://github.com/google/sanitizers/blob/master/address-sanitizer/tools/kasan_symbolize.py
I get the following. It doesn't seem much interesting, does it ?
==================================================================
BUG: KASAN: stack-out-of-bounds in[< none >]
memchr+0x24/0x74 lib/string.c:958
Read of size 1 at addr c0ecdd40 by task swapper/0
CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1142
Call Trace:
[c0e9dca0] [c01c42c0] print_address_description+0x64/0x2bc (unreliable)
[c0e9dcd0] [c01c46a4] kasan_report+0xfc/0x180
[c0e9dd10] [c0895150] memchr+0x24/0x74
[c0e9dd30] [c00a9e58] msg_print_text+0x124/0x574
[c0e9dde0] [c00ab730] console_unlock+0x114/0x4f8
[c0e9de40] [c00adc80] vprintk_emit+0x188/0x1c4
[c0e9de80] [c00ae3e4] printk+0xa8/0xcc
[c0e9df20] [c0c27e44] early_irq_init+0x38/0x108
[c0e9df50] [c0c15434] start_kernel+0x310/0x488
[c0e9dff0] [00003484] 0x3484
The buggy address belongs to the variable:
[< none >] __log_buf+0xec0/0x4020
arch/powerpc/kernel/head_32.S:?
The buggy address belongs to the page:
page:c6eac9a0 count:1 mapcount:0 mapping:00000000 index:0x0
flags: 0x1000(reserved)
raw: 00001000 c6eac9a4 c6eac9a4 00000000 00000000 00000000 ffffffff 00000001
page dumped because: kasan: bad access detected
Memory state around the buggy address:
c0ecdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0ecdc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>c0ecdd00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00
^
c0ecdd80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
c0ecde00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
==================================================================
Christophe
>
>
>
>> I checked that after kasan_init(), the entire shadow memory is full of 0
>> only.
>>
>> I also made a try with the strong STACK_PROTECTOR compiled in, but no
>> difference and nothing detected by the stack protector.
>>
>> ==================================================================
>> BUG: KASAN: stack-out-of-bounds in memchr+0x24/0x74
>> Read of size 1 at addr c0ecdd40 by task swapper/0
>>
>> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1133
>> Call Trace:
>> [c0e9dca0] [c01c42a0] print_address_description+0x64/0x2bc (unreliable)
>> [c0e9dcd0] [c01c4684] kasan_report+0xfc/0x180
>> [c0e9dd10] [c089579c] memchr+0x24/0x74
>> [c0e9dd30] [c00a9e38] msg_print_text+0x124/0x574
>> [c0e9dde0] [c00ab710] console_unlock+0x114/0x4f8
>> [c0e9de40] [c00adc60] vprintk_emit+0x188/0x1c4
>> --- interrupt: c0e9df00 at 0x400f330
>> LR = init_stack+0x1f00/0x2000
>> [c0e9de80] [c00ae3c4] printk+0xa8/0xcc (unreliable)
>> [c0e9df20] [c0c28e44] early_irq_init+0x38/0x108
>> [c0e9df50] [c0c16434] start_kernel+0x310/0x488
>> [c0e9dff0] [00003484] 0x3484
>>
>> The buggy address belongs to the variable:
>> __log_buf+0xec0/0x4020
>> The buggy address belongs to the page:
>> page:c6eac9a0 count:1 mapcount:0 mapping:00000000 index:0x0
>> flags: 0x1000(reserved)
>> raw: 00001000 c6eac9a4 c6eac9a4 00000000 00000000 00000000 ffffffff 00000001
>> page dumped because: kasan: bad access detected
>>
>> Memory state around the buggy address:
>> c0ecdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> c0ecdc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >c0ecdd00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00
>> ^
>> c0ecdd80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
>> c0ecde00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> ==================================================================
>>
>> ==================================================================
>> BUG: KASAN: stack-out-of-bounds in pmac_nvram_init+0x1ec/0x600
>> Read of size 1 at addr f6f37de0 by task swapper/0
>>
>> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1134
>> Call Trace:
>> [c0ff7d60] [c01fe808] print_address_description+0x6c/0x2b0 (unreliable)
>> [c0ff7d90] [c01fe4fc] kasan_report+0x13c/0x1ac
>> [c0ff7dd0] [c0d34324] pmac_nvram_init+0x1ec/0x600
>> [c0ff7ef0] [c0d31148] pmac_setup_arch+0x280/0x308
>> [c0ff7f20] [c0d2c30c] setup_arch+0x250/0x280
>> [c0ff7f50] [c0d26354] start_kernel+0xb8/0x4d8
>> [c0ff7ff0] [00003484] 0x3484
>>
>>
>> Memory state around the buggy address:
>> f6f37c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> f6f37d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >f6f37d80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
>> ^
>> f6f37e00: 00 00 00 00 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2
>> f6f37e80: 00 00 01 f2 00 00 00 00 00 00 00 00 00 00 00 00
>> ==================================================================
>>
>> ==================================================================
>> BUG: KASAN: stack-out-of-bounds in memchr+0xa0/0xac
>> Read of size 1 at addr c17cdd30 by task swapper/0
>>
>> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1135
>> Call Trace:
>> [c179dc90] [c032fe28] print_address_description+0x64/0x2bc (unreliable)
>> [c179dcc0] [c033020c] kasan_report+0xfc/0x180
>> [c179dd00] [c115ef50] memchr+0xa0/0xac
>> [c179dd20] [c01297f8] msg_print_text+0xc8/0x67c
>> [c179ddd0] [c012bc8c] console_unlock+0x17c/0x818
>> [c179de40] [c012f420] vprintk_emit+0x188/0x1c4
>> --- interrupt: c179df30 at 0x400def0
>> LR = init_stack+0x1ef0/0x2000
>> [c179de80] [c012fff0] printk+0xa8/0xcc (unreliable)
>> [c179df20] [c150b4b8] early_irq_init+0x38/0x108
>> [c179df50] [c14ef7f8] start_kernel+0x30c/0x530
>> [c179dff0] [00003484] 0x3484
>>
>> The buggy address belongs to the variable:
>> __log_buf+0xeb0/0x4020
>> The buggy address belongs to the page:
>> page:c6ebe9a0 count:1 mapcount:0 mapping:00000000 index:0x0
>> flags: 0x1000(reserved)
>> raw: 00001000 c6ebe9a4 c6ebe9a4 00000000 00000000 00000000 ffffffff 00000001
>> page dumped because: kasan: bad access detected
>>
>> Memory state around the buggy address:
>> c17cdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> c17cdc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >c17cdd00: 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00 f3 f3
>> ^
>> c17cdd80: f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> c17cde00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> ==================================================================
>>
>> ==================================================================
>> BUG: KASAN: stack-out-of-bounds in pmac_nvram_init+0x228/0xae0
>> Read of size 1 at addr f6f37dd0 by task swapper/0
>>
>> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1136
>> Call Trace:
>> [c1c37d50] [c03f7e88] print_address_description+0x6c/0x2b0 (unreliable)
>> [c1c37d80] [c03f7bd4] kasan_report+0x10c/0x16c
>> [c1c37dc0] [c19879b4] pmac_nvram_init+0x228/0xae0
>> [c1c37ef0] [c19826bc] pmac_setup_arch+0x578/0x6a8
>> [c1c37f20] [c19792bc] setup_arch+0x5f4/0x620
>> [c1c37f50] [c196f898] start_kernel+0xb8/0x588
>> [c1c37ff0] [00003484] 0x3484
>>
>>
>> Memory state around the buggy address:
>> f6f37c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> f6f37d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >f6f37d80: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00
>> ^
>> f6f37e00: 01 f2 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 00
>> f6f37e80: 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00
>> ==================================================================
>>
>> ==================================================================
>> BUG: KASAN: stack-out-of-bounds in pmac_nvram_init+0x1ec/0x5ec
>> Read of size 1 at addr f6f37de0 by task swapper/0
>>
>> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1137
>> Call Trace:
>> [c0fb7d60] [c01f8184] print_address_description+0x6c/0x2b0 (unreliable)
>> [c0fb7d90] [c01f7ed0] kasan_report+0x10c/0x16c
>> [c0fb7dd0] [c0d1dfe8] pmac_nvram_init+0x1ec/0x5ec
>> [c0fb7ef0] [c0d1ae90] pmac_setup_arch+0x280/0x308
>> [c0fb7f20] [c0d16138] setup_arch+0x250/0x280
>> [c0fb7f50] [c0d1032c] start_kernel+0xb8/0x4a4
>> [c0fb7ff0] [00003484] 0x3484
>>
>>
>> Memory state around the buggy address:
>> f6f37c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> f6f37d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >f6f37d80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
>> ^
>> f6f37e00: 00 00 01 f2 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2
>> f6f37e80: 00 00 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00
>> ==================================================================
>>
>> Thanks
>> Christophe
^ permalink raw reply
* Re: BUG: KASAN: stack-out-of-bounds
From: Dmitry Vyukov @ 2019-02-27 13:07 UTC (permalink / raw)
To: Christophe Leroy
Cc: kasan-dev, Linux-MM, Alexander Potapenko, Andrey Ryabinin,
linuxppc-dev, Daniel Axtens
In-Reply-To: <5c8058fe-ac6a-2b50-3d52-fe89bb48b6f5@c-s.fr>
On Wed, Feb 27, 2019 at 1:35 PM Christophe Leroy
<christophe.leroy@c-s.fr> wrote:
>
>
>
> On 02/27/2019 08:34 AM, Dmitry Vyukov wrote:
> > On Wed, Feb 27, 2019 at 9:25 AM Christophe Leroy
> > <christophe.leroy@c-s.fr> wrote:
> >>
> >> With version v8 of the series implementing KASAN on 32 bits powerpc
> >> (https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=94309),
> >> I'm now able to activate KASAN on a mac99 is QEMU.
> >>
> >> Then I get the following reports at startup. Which of the two reports I
> >> get seems to depend on the option used to build the kernel, but for a
> >> given kernel I always get the same report.
> >>
> >> Is that a real bug, in which case how could I spot it ? Or is it
> >> something wrong in my implementation of KASAN ?
> >
> > What is the state of your source tree?
> > Please pass output through some symbolization script, function offsets
> > are not too useful.
> > There was some in scripts/ dir IIRC, but here is another one (though,
> > never tested on powerpc):
> > https://github.com/google/sanitizers/blob/master/address-sanitizer/tools/kasan_symbolize.py
>
> I get the following. It doesn't seem much interesting, does it ?
Yes, it does not seem to work for powerpc32.
Then please pass addresses through addr2line -fi.
> ==================================================================
> BUG: KASAN: stack-out-of-bounds in[< none >]
> memchr+0x24/0x74 lib/string.c:958
> Read of size 1 at addr c0ecdd40 by task swapper/0
>
> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1142
> Call Trace:
> [c0e9dca0] [c01c42c0] print_address_description+0x64/0x2bc (unreliable)
> [c0e9dcd0] [c01c46a4] kasan_report+0xfc/0x180
> [c0e9dd10] [c0895150] memchr+0x24/0x74
> [c0e9dd30] [c00a9e58] msg_print_text+0x124/0x574
> [c0e9dde0] [c00ab730] console_unlock+0x114/0x4f8
> [c0e9de40] [c00adc80] vprintk_emit+0x188/0x1c4
> [c0e9de80] [c00ae3e4] printk+0xa8/0xcc
> [c0e9df20] [c0c27e44] early_irq_init+0x38/0x108
> [c0e9df50] [c0c15434] start_kernel+0x310/0x488
> [c0e9dff0] [00003484] 0x3484
>
> The buggy address belongs to the variable:
> [< none >] __log_buf+0xec0/0x4020
> arch/powerpc/kernel/head_32.S:?
> The buggy address belongs to the page:
> page:c6eac9a0 count:1 mapcount:0 mapping:00000000 index:0x0
> flags: 0x1000(reserved)
> raw: 00001000 c6eac9a4 c6eac9a4 00000000 00000000 00000000 ffffffff 00000001
> page dumped because: kasan: bad access detected
>
> Memory state around the buggy address:
> c0ecdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> c0ecdc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >c0ecdd00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00
> ^
> c0ecdd80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
> c0ecde00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> ==================================================================
>
>
> Christophe
>
> >
> >
> >
> >> I checked that after kasan_init(), the entire shadow memory is full of 0
> >> only.
> >>
> >> I also made a try with the strong STACK_PROTECTOR compiled in, but no
> >> difference and nothing detected by the stack protector.
> >>
> >> ==================================================================
> >> BUG: KASAN: stack-out-of-bounds in memchr+0x24/0x74
> >> Read of size 1 at addr c0ecdd40 by task swapper/0
> >>
> >> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1133
> >> Call Trace:
> >> [c0e9dca0] [c01c42a0] print_address_description+0x64/0x2bc (unreliable)
> >> [c0e9dcd0] [c01c4684] kasan_report+0xfc/0x180
> >> [c0e9dd10] [c089579c] memchr+0x24/0x74
> >> [c0e9dd30] [c00a9e38] msg_print_text+0x124/0x574
> >> [c0e9dde0] [c00ab710] console_unlock+0x114/0x4f8
> >> [c0e9de40] [c00adc60] vprintk_emit+0x188/0x1c4
> >> --- interrupt: c0e9df00 at 0x400f330
> >> LR = init_stack+0x1f00/0x2000
> >> [c0e9de80] [c00ae3c4] printk+0xa8/0xcc (unreliable)
> >> [c0e9df20] [c0c28e44] early_irq_init+0x38/0x108
> >> [c0e9df50] [c0c16434] start_kernel+0x310/0x488
> >> [c0e9dff0] [00003484] 0x3484
> >>
> >> The buggy address belongs to the variable:
> >> __log_buf+0xec0/0x4020
> >> The buggy address belongs to the page:
> >> page:c6eac9a0 count:1 mapcount:0 mapping:00000000 index:0x0
> >> flags: 0x1000(reserved)
> >> raw: 00001000 c6eac9a4 c6eac9a4 00000000 00000000 00000000 ffffffff 00000001
> >> page dumped because: kasan: bad access detected
> >>
> >> Memory state around the buggy address:
> >> c0ecdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> c0ecdc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> >c0ecdd00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00
> >> ^
> >> c0ecdd80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
> >> c0ecde00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> ==================================================================
> >>
> >> ==================================================================
> >> BUG: KASAN: stack-out-of-bounds in pmac_nvram_init+0x1ec/0x600
> >> Read of size 1 at addr f6f37de0 by task swapper/0
> >>
> >> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1134
> >> Call Trace:
> >> [c0ff7d60] [c01fe808] print_address_description+0x6c/0x2b0 (unreliable)
> >> [c0ff7d90] [c01fe4fc] kasan_report+0x13c/0x1ac
> >> [c0ff7dd0] [c0d34324] pmac_nvram_init+0x1ec/0x600
> >> [c0ff7ef0] [c0d31148] pmac_setup_arch+0x280/0x308
> >> [c0ff7f20] [c0d2c30c] setup_arch+0x250/0x280
> >> [c0ff7f50] [c0d26354] start_kernel+0xb8/0x4d8
> >> [c0ff7ff0] [00003484] 0x3484
> >>
> >>
> >> Memory state around the buggy address:
> >> f6f37c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> f6f37d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> >f6f37d80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
> >> ^
> >> f6f37e00: 00 00 00 00 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2
> >> f6f37e80: 00 00 01 f2 00 00 00 00 00 00 00 00 00 00 00 00
> >> ==================================================================
> >>
> >> ==================================================================
> >> BUG: KASAN: stack-out-of-bounds in memchr+0xa0/0xac
> >> Read of size 1 at addr c17cdd30 by task swapper/0
> >>
> >> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1135
> >> Call Trace:
> >> [c179dc90] [c032fe28] print_address_description+0x64/0x2bc (unreliable)
> >> [c179dcc0] [c033020c] kasan_report+0xfc/0x180
> >> [c179dd00] [c115ef50] memchr+0xa0/0xac
> >> [c179dd20] [c01297f8] msg_print_text+0xc8/0x67c
> >> [c179ddd0] [c012bc8c] console_unlock+0x17c/0x818
> >> [c179de40] [c012f420] vprintk_emit+0x188/0x1c4
> >> --- interrupt: c179df30 at 0x400def0
> >> LR = init_stack+0x1ef0/0x2000
> >> [c179de80] [c012fff0] printk+0xa8/0xcc (unreliable)
> >> [c179df20] [c150b4b8] early_irq_init+0x38/0x108
> >> [c179df50] [c14ef7f8] start_kernel+0x30c/0x530
> >> [c179dff0] [00003484] 0x3484
> >>
> >> The buggy address belongs to the variable:
> >> __log_buf+0xeb0/0x4020
> >> The buggy address belongs to the page:
> >> page:c6ebe9a0 count:1 mapcount:0 mapping:00000000 index:0x0
> >> flags: 0x1000(reserved)
> >> raw: 00001000 c6ebe9a4 c6ebe9a4 00000000 00000000 00000000 ffffffff 00000001
> >> page dumped because: kasan: bad access detected
> >>
> >> Memory state around the buggy address:
> >> c17cdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> c17cdc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> >c17cdd00: 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00 f3 f3
> >> ^
> >> c17cdd80: f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> c17cde00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> ==================================================================
> >>
> >> ==================================================================
> >> BUG: KASAN: stack-out-of-bounds in pmac_nvram_init+0x228/0xae0
> >> Read of size 1 at addr f6f37dd0 by task swapper/0
> >>
> >> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1136
> >> Call Trace:
> >> [c1c37d50] [c03f7e88] print_address_description+0x6c/0x2b0 (unreliable)
> >> [c1c37d80] [c03f7bd4] kasan_report+0x10c/0x16c
> >> [c1c37dc0] [c19879b4] pmac_nvram_init+0x228/0xae0
> >> [c1c37ef0] [c19826bc] pmac_setup_arch+0x578/0x6a8
> >> [c1c37f20] [c19792bc] setup_arch+0x5f4/0x620
> >> [c1c37f50] [c196f898] start_kernel+0xb8/0x588
> >> [c1c37ff0] [00003484] 0x3484
> >>
> >>
> >> Memory state around the buggy address:
> >> f6f37c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> f6f37d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> >f6f37d80: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00
> >> ^
> >> f6f37e00: 01 f2 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 00
> >> f6f37e80: 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00
> >> ==================================================================
> >>
> >> ==================================================================
> >> BUG: KASAN: stack-out-of-bounds in pmac_nvram_init+0x1ec/0x5ec
> >> Read of size 1 at addr f6f37de0 by task swapper/0
> >>
> >> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1137
> >> Call Trace:
> >> [c0fb7d60] [c01f8184] print_address_description+0x6c/0x2b0 (unreliable)
> >> [c0fb7d90] [c01f7ed0] kasan_report+0x10c/0x16c
> >> [c0fb7dd0] [c0d1dfe8] pmac_nvram_init+0x1ec/0x5ec
> >> [c0fb7ef0] [c0d1ae90] pmac_setup_arch+0x280/0x308
> >> [c0fb7f20] [c0d16138] setup_arch+0x250/0x280
> >> [c0fb7f50] [c0d1032c] start_kernel+0xb8/0x4a4
> >> [c0fb7ff0] [00003484] 0x3484
> >>
> >>
> >> Memory state around the buggy address:
> >> f6f37c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> f6f37d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >> >f6f37d80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
> >> ^
> >> f6f37e00: 00 00 01 f2 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2
> >> f6f37e80: 00 00 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00
> >> ==================================================================
> >>
> >> Thanks
> >> Christophe
^ permalink raw reply
* Re: BUG: KASAN: stack-out-of-bounds
From: Christophe Leroy @ 2019-02-27 13:11 UTC (permalink / raw)
To: Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov
Cc: linux-mm, linuxppc-dev, kasan-dev, Daniel Axtens
In-Reply-To: <5f0203bd-77ea-d94c-11b7-1befba439cd4@virtuozzo.com>
Le 27/02/2019 à 10:19, Andrey Ryabinin a écrit :
>
>
> On 2/27/19 11:25 AM, Christophe Leroy wrote:
>> With version v8 of the series implementing KASAN on 32 bits powerpc (https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=94309), I'm now able to activate KASAN on a mac99 is QEMU.
>>
>> Then I get the following reports at startup. Which of the two reports I get seems to depend on the option used to build the kernel, but for a given kernel I always get the same report.
>>
>> Is that a real bug, in which case how could I spot it ? Or is it something wrong in my implementation of KASAN ?
>>
>> I checked that after kasan_init(), the entire shadow memory is full of 0 only.
>>
>> I also made a try with the strong STACK_PROTECTOR compiled in, but no difference and nothing detected by the stack protector.
>>
>> ==================================================================
>> BUG: KASAN: stack-out-of-bounds in memchr+0x24/0x74
>> Read of size 1 at addr c0ecdd40 by task swapper/0
>>
>> CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1133
>> Call Trace:
>> [c0e9dca0] [c01c42a0] print_address_description+0x64/0x2bc (unreliable)
>> [c0e9dcd0] [c01c4684] kasan_report+0xfc/0x180
>> [c0e9dd10] [c089579c] memchr+0x24/0x74
>> [c0e9dd30] [c00a9e38] msg_print_text+0x124/0x574
>> [c0e9dde0] [c00ab710] console_unlock+0x114/0x4f8
>> [c0e9de40] [c00adc60] vprintk_emit+0x188/0x1c4
>> --- interrupt: c0e9df00 at 0x400f330
>> LR = init_stack+0x1f00/0x2000
>> [c0e9de80] [c00ae3c4] printk+0xa8/0xcc (unreliable)
>> [c0e9df20] [c0c28e44] early_irq_init+0x38/0x108
>> [c0e9df50] [c0c16434] start_kernel+0x310/0x488
>> [c0e9dff0] [00003484] 0x3484
>>
>> The buggy address belongs to the variable:
>> __log_buf+0xec0/0x4020
>> The buggy address belongs to the page:
>> page:c6eac9a0 count:1 mapcount:0 mapping:00000000 index:0x0
>> flags: 0x1000(reserved)
>> raw: 00001000 c6eac9a4 c6eac9a4 00000000 00000000 00000000 ffffffff 00000001
>> page dumped because: kasan: bad access detected
>>
>> Memory state around the buggy address:
>> c0ecdc00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> c0ecdc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> c0ecdd00: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00
>> ^
>> c0ecdd80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
>> c0ecde00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> ==================================================================
>>
>
> This one doesn't look good. Notice that it says stack-out-of-bounds, but at the same time there is
> "The buggy address belongs to the variable: __log_buf+0xec0/0x4020"
> which is printed by following code:
> if (kernel_or_module_addr(addr) && !init_task_stack_addr(addr)) {
> pr_err("The buggy address belongs to the variable:\n");
> pr_err(" %pS\n", addr);
> }
>
> So the stack unrelated address got stack-related poisoning. This could be a stack overflow, did you increase THREAD_SHIFT?
> KASAN with stack instrumentation significantly increases stack usage.
>
I get the above with THREAD_SHIFT set to 13 (default value).
If increasing it to 14, I get the following instead. That means that in
that case the problem arises a lot earlier in the boot process (but
still after the final kasan shadow setup).
==================================================================
BUG: KASAN: stack-out-of-bounds in pmac_nvram_init+0x1f8/0x5d0
Read of size 1 at addr f6f37de0 by task swapper/0
CPU: 0 PID: 0 Comm: swapper Not tainted 5.0.0-rc7+ #1143
Call Trace:
[c0e9fd60] [c01c43c0] print_address_description+0x164/0x2bc (unreliable)
[c0e9fd90] [c01c46a4] kasan_report+0xfc/0x180
[c0e9fdd0] [c0c226d4] pmac_nvram_init+0x1f8/0x5d0
[c0e9fef0] [c0c1f73c] pmac_setup_arch+0x298/0x314
[c0e9ff20] [c0c1ac40] setup_arch+0x250/0x268
[c0e9ff50] [c0c151dc] start_kernel+0xb8/0x488
[c0e9fff0] [00003484] 0x3484
Memory state around the buggy address:
f6f37c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f6f37d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>f6f37d80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
^
f6f37e00: 00 00 01 f4 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2
f6f37e80: 00 00 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00
==================================================================
Christophe
^ permalink raw reply
* Re: [PATCH 3/5] ocxl: read_pasid never returns an error, so make it void
From: Frederic Barrat @ 2019-02-27 13:25 UTC (permalink / raw)
To: Alastair D'Silva, alastair
Cc: Arnd Bergmann, Greg Kroah-Hartman, Greg Kurz, linux-kernel,
Andrew Donnellan, linuxppc-dev
In-Reply-To: <20190227045741.21412-4-alastair@au1.ibm.com>
Le 27/02/2019 à 05:57, Alastair D'Silva a écrit :
> From: Alastair D'Silva <alastair@d-silva.org>
>
> No need for a return value in read_pasid as it only returns 0.
>
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
> Reviewed-by: Greg Kurz <groug@kaod.org>
> ---
Thanks!
Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
> drivers/misc/ocxl/config.c | 9 ++-------
> 1 file changed, 2 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
> index 0ee7856b033d..026ac2ac4f9c 100644
> --- a/drivers/misc/ocxl/config.c
> +++ b/drivers/misc/ocxl/config.c
> @@ -68,7 +68,7 @@ static int find_dvsec_afu_ctrl(struct pci_dev *dev, u8 afu_idx)
> return 0;
> }
>
> -static int read_pasid(struct pci_dev *dev, struct ocxl_fn_config *fn)
> +static void read_pasid(struct pci_dev *dev, struct ocxl_fn_config *fn)
> {
> u16 val;
> int pos;
> @@ -89,7 +89,6 @@ static int read_pasid(struct pci_dev *dev, struct ocxl_fn_config *fn)
> out:
> dev_dbg(&dev->dev, "PASID capability:\n");
> dev_dbg(&dev->dev, " Max PASID log = %d\n", fn->max_pasid_log);
> - return 0;
> }
>
> static int read_dvsec_tl(struct pci_dev *dev, struct ocxl_fn_config *fn)
> @@ -205,11 +204,7 @@ int ocxl_config_read_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
> {
> int rc;
>
> - rc = read_pasid(dev, fn);
> - if (rc) {
> - dev_err(&dev->dev, "Invalid PASID configuration: %d\n", rc);
> - return -ENODEV;
> - }
> + read_pasid(dev, fn);
>
> rc = read_dvsec_tl(dev, fn);
> if (rc) {
>
^ permalink raw reply
* Re: [PATCH 4/5] ocxl: Remove superfluous 'extern' from headers
From: Frederic Barrat @ 2019-02-27 13:36 UTC (permalink / raw)
To: Alastair D'Silva, alastair
Cc: Greg Kroah-Hartman, linuxppc-dev, Arnd Bergmann, Andrew Donnellan,
linux-kernel
In-Reply-To: <20190227045741.21412-5-alastair@au1.ibm.com>
Le 27/02/2019 à 05:57, Alastair D'Silva a écrit :
> From: Alastair D'Silva <alastair@d-silva.org>
>
> The 'extern' keyword adds no value here.
>
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
> ---
Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
> drivers/misc/ocxl/ocxl_internal.h | 54 +++++++++++++++----------------
> include/misc/ocxl.h | 36 ++++++++++-----------
> 2 files changed, 44 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/misc/ocxl/ocxl_internal.h b/drivers/misc/ocxl/ocxl_internal.h
> index a32f2151029f..321b29e77f45 100644
> --- a/drivers/misc/ocxl/ocxl_internal.h
> +++ b/drivers/misc/ocxl/ocxl_internal.h
> @@ -16,7 +16,6 @@
>
> extern struct pci_driver ocxl_pci_driver;
>
> -
> struct ocxl_fn {
> struct device dev;
> int bar_used[3];
> @@ -92,41 +91,40 @@ struct ocxl_process_element {
> __be32 software_state;
> };
>
> +struct ocxl_afu *ocxl_afu_get(struct ocxl_afu *afu);
> +void ocxl_afu_put(struct ocxl_afu *afu);
>
> -extern struct ocxl_afu *ocxl_afu_get(struct ocxl_afu *afu);
> -extern void ocxl_afu_put(struct ocxl_afu *afu);
> -
> -extern int ocxl_create_cdev(struct ocxl_afu *afu);
> -extern void ocxl_destroy_cdev(struct ocxl_afu *afu);
> -extern int ocxl_register_afu(struct ocxl_afu *afu);
> -extern void ocxl_unregister_afu(struct ocxl_afu *afu);
> +int ocxl_create_cdev(struct ocxl_afu *afu);
> +void ocxl_destroy_cdev(struct ocxl_afu *afu);
> +int ocxl_register_afu(struct ocxl_afu *afu);
> +void ocxl_unregister_afu(struct ocxl_afu *afu);
>
> -extern int ocxl_file_init(void);
> -extern void ocxl_file_exit(void);
> +int ocxl_file_init(void);
> +void ocxl_file_exit(void);
>
> -extern int ocxl_pasid_afu_alloc(struct ocxl_fn *fn, u32 size);
> -extern void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
> -extern int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size);
> -extern void ocxl_actag_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
> +int ocxl_pasid_afu_alloc(struct ocxl_fn *fn, u32 size);
> +void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
> +int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size);
> +void ocxl_actag_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
>
> -extern struct ocxl_context *ocxl_context_alloc(void);
> -extern int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
> +struct ocxl_context *ocxl_context_alloc(void);
> +int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
> struct address_space *mapping);
> -extern int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
> -extern int ocxl_context_mmap(struct ocxl_context *ctx,
> +int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
> +int ocxl_context_mmap(struct ocxl_context *ctx,
> struct vm_area_struct *vma);
> -extern int ocxl_context_detach(struct ocxl_context *ctx);
> -extern void ocxl_context_detach_all(struct ocxl_afu *afu);
> -extern void ocxl_context_free(struct ocxl_context *ctx);
> +int ocxl_context_detach(struct ocxl_context *ctx);
> +void ocxl_context_detach_all(struct ocxl_afu *afu);
> +void ocxl_context_free(struct ocxl_context *ctx);
>
> -extern int ocxl_sysfs_add_afu(struct ocxl_afu *afu);
> -extern void ocxl_sysfs_remove_afu(struct ocxl_afu *afu);
> +int ocxl_sysfs_add_afu(struct ocxl_afu *afu);
> +void ocxl_sysfs_remove_afu(struct ocxl_afu *afu);
>
> -extern int ocxl_afu_irq_alloc(struct ocxl_context *ctx, u64 *irq_offset);
> -extern int ocxl_afu_irq_free(struct ocxl_context *ctx, u64 irq_offset);
> -extern void ocxl_afu_irq_free_all(struct ocxl_context *ctx);
> -extern int ocxl_afu_irq_set_fd(struct ocxl_context *ctx, u64 irq_offset,
> +int ocxl_afu_irq_alloc(struct ocxl_context *ctx, u64 *irq_offset);
> +int ocxl_afu_irq_free(struct ocxl_context *ctx, u64 irq_offset);
> +void ocxl_afu_irq_free_all(struct ocxl_context *ctx);
> +int ocxl_afu_irq_set_fd(struct ocxl_context *ctx, u64 irq_offset,
> int eventfd);
> -extern u64 ocxl_afu_irq_get_addr(struct ocxl_context *ctx, u64 irq_offset);
> +u64 ocxl_afu_irq_get_addr(struct ocxl_context *ctx, u64 irq_offset);
>
> #endif /* _OCXL_INTERNAL_H_ */
> diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h
> index 9ff6ddc28e22..4544573cc93c 100644
> --- a/include/misc/ocxl.h
> +++ b/include/misc/ocxl.h
> @@ -53,7 +53,7 @@ struct ocxl_fn_config {
> * Read the configuration space of a function and fill in a
> * ocxl_fn_config structure with all the function details
> */
> -extern int ocxl_config_read_function(struct pci_dev *dev,
> +int ocxl_config_read_function(struct pci_dev *dev,
> struct ocxl_fn_config *fn);
>
> /*
> @@ -62,14 +62,14 @@ extern int ocxl_config_read_function(struct pci_dev *dev,
> * AFU indexes can be sparse, so a driver should check all indexes up
> * to the maximum found in the function description
> */
> -extern int ocxl_config_check_afu_index(struct pci_dev *dev,
> +int ocxl_config_check_afu_index(struct pci_dev *dev,
> struct ocxl_fn_config *fn, int afu_idx);
>
> /*
> * Read the configuration space of a function for the AFU specified by
> * the index 'afu_idx'. Fills in a ocxl_afu_config structure
> */
> -extern int ocxl_config_read_afu(struct pci_dev *dev,
> +int ocxl_config_read_afu(struct pci_dev *dev,
> struct ocxl_fn_config *fn,
> struct ocxl_afu_config *afu,
> u8 afu_idx);
> @@ -77,7 +77,7 @@ extern int ocxl_config_read_afu(struct pci_dev *dev,
> /*
> * Get the max PASID value that can be used by the function
> */
> -extern int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
> +int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
>
> /*
> * Tell an AFU, by writing in the configuration space, the PASIDs that
> @@ -87,7 +87,7 @@ extern int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
> * 'afu_control_offset' is the offset of the AFU control DVSEC which
> * can be found in the function configuration
> */
> -extern void ocxl_config_set_afu_pasid(struct pci_dev *dev,
> +void ocxl_config_set_afu_pasid(struct pci_dev *dev,
> int afu_control_offset,
> int pasid_base, u32 pasid_count_log);
>
> @@ -98,7 +98,7 @@ extern void ocxl_config_set_afu_pasid(struct pci_dev *dev,
> * 'supported' is the total number of actags desired by all the AFUs
> * of the function.
> */
> -extern int ocxl_config_get_actag_info(struct pci_dev *dev,
> +int ocxl_config_get_actag_info(struct pci_dev *dev,
> u16 *base, u16 *enabled, u16 *supported);
>
> /*
> @@ -108,7 +108,7 @@ extern int ocxl_config_get_actag_info(struct pci_dev *dev,
> * 'func_offset' is the offset of the Function DVSEC that can found in
> * the function configuration
> */
> -extern void ocxl_config_set_actag(struct pci_dev *dev, int func_offset,
> +void ocxl_config_set_actag(struct pci_dev *dev, int func_offset,
> u32 actag_base, u32 actag_count);
>
> /*
> @@ -118,7 +118,7 @@ extern void ocxl_config_set_actag(struct pci_dev *dev, int func_offset,
> * 'afu_control_offset' is the offset of the AFU control DVSEC for the
> * desired AFU. It can be found in the AFU configuration
> */
> -extern void ocxl_config_set_afu_actag(struct pci_dev *dev,
> +void ocxl_config_set_afu_actag(struct pci_dev *dev,
> int afu_control_offset,
> int actag_base, int actag_count);
>
> @@ -128,7 +128,7 @@ extern void ocxl_config_set_afu_actag(struct pci_dev *dev,
> * 'afu_control_offset' is the offset of the AFU control DVSEC for the
> * desired AFU. It can be found in the AFU configuration
> */
> -extern void ocxl_config_set_afu_state(struct pci_dev *dev,
> +void ocxl_config_set_afu_state(struct pci_dev *dev,
> int afu_control_offset, int enable);
>
> /*
> @@ -139,7 +139,7 @@ extern void ocxl_config_set_afu_state(struct pci_dev *dev,
> * between the host and device, and set the Transaction Layer on both
> * accordingly.
> */
> -extern int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec);
> +int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec);
>
> /*
> * Request an AFU to terminate a PASID.
> @@ -152,7 +152,7 @@ extern int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec);
> * 'afu_control_offset' is the offset of the AFU control DVSEC for the
> * desired AFU. It can be found in the AFU configuration
> */
> -extern int ocxl_config_terminate_pasid(struct pci_dev *dev,
> +int ocxl_config_terminate_pasid(struct pci_dev *dev,
> int afu_control_offset, int pasid);
>
> /*
> @@ -165,13 +165,13 @@ extern int ocxl_config_terminate_pasid(struct pci_dev *dev,
> * Returns a 'link handle' that should be used for further calls for
> * the link
> */
> -extern int ocxl_link_setup(struct pci_dev *dev, int PE_mask,
> +int ocxl_link_setup(struct pci_dev *dev, int PE_mask,
> void **link_handle);
>
> /*
> * Remove the association between the function and its link.
> */
> -extern void ocxl_link_release(struct pci_dev *dev, void *link_handle);
> +void ocxl_link_release(struct pci_dev *dev, void *link_handle);
>
> /*
> * Add a Process Element to the Shared Process Area for a link.
> @@ -183,7 +183,7 @@ extern void ocxl_link_release(struct pci_dev *dev, void *link_handle);
> * 'xsl_err_data' is an argument passed to the above callback, if
> * defined
> */
> -extern int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
> +int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
> u64 amr, struct mm_struct *mm,
> void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr),
> void *xsl_err_data);
> @@ -195,12 +195,12 @@ extern int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
> * pasid: the PASID for the AFU context
> * tid: the new thread id for the process element
> */
> -extern int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
> +int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
>
> /*
> * Remove a Process Element from the Shared Process Area for a link
> */
> -extern int ocxl_link_remove_pe(void *link_handle, int pasid);
> +int ocxl_link_remove_pe(void *link_handle, int pasid);
>
> /*
> * Allocate an AFU interrupt associated to the link.
> @@ -212,12 +212,12 @@ extern int ocxl_link_remove_pe(void *link_handle, int pasid);
> * interrupt. It is an MMIO address which needs to be remapped (one
> * page).
> */
> -extern int ocxl_link_irq_alloc(void *link_handle, int *hw_irq,
> +int ocxl_link_irq_alloc(void *link_handle, int *hw_irq,
> u64 *obj_handle);
>
> /*
> * Free a previously allocated AFU interrupt
> */
> -extern void ocxl_link_free_irq(void *link_handle, int hw_irq);
> +void ocxl_link_free_irq(void *link_handle, int hw_irq);
>
> #endif /* _MISC_OCXL_H_ */
>
^ permalink raw reply
* Re: [PATCH 5/5] ocxl: Remove some unused exported symbols
From: Frederic Barrat @ 2019-02-27 13:39 UTC (permalink / raw)
To: Alastair D'Silva, alastair
Cc: Greg Kroah-Hartman, linuxppc-dev, Arnd Bergmann, Andrew Donnellan,
linux-kernel
In-Reply-To: <20190227045741.21412-6-alastair@au1.ibm.com>
Le 27/02/2019 à 05:57, Alastair D'Silva a écrit :
> From: Alastair D'Silva <alastair@d-silva.org>
>
> Remove some unused exported symbols.
>
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
> ---
If you have a respin of the series, that patch also adds a comment
around ocxl_context_attach(), which is for later.
But in any case:
Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
> drivers/misc/ocxl/config.c | 2 --
> drivers/misc/ocxl/ocxl_internal.h | 26 +++++++++++++++++++++++++-
> include/misc/ocxl.h | 23 -----------------------
> 3 files changed, 25 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
> index 026ac2ac4f9c..c90c2e4875bf 100644
> --- a/drivers/misc/ocxl/config.c
> +++ b/drivers/misc/ocxl/config.c
> @@ -299,7 +299,6 @@ int ocxl_config_check_afu_index(struct pci_dev *dev,
> }
> return 1;
> }
> -EXPORT_SYMBOL_GPL(ocxl_config_check_afu_index);
>
> static int read_afu_name(struct pci_dev *dev, struct ocxl_fn_config *fn,
> struct ocxl_afu_config *afu)
> @@ -535,7 +534,6 @@ int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count)
> {
> return pnv_ocxl_get_pasid_count(dev, count);
> }
> -EXPORT_SYMBOL_GPL(ocxl_config_get_pasid_info);
>
> void ocxl_config_set_afu_pasid(struct pci_dev *dev, int pos, int pasid_base,
> u32 pasid_count_log)
> diff --git a/drivers/misc/ocxl/ocxl_internal.h b/drivers/misc/ocxl/ocxl_internal.h
> index 321b29e77f45..cd5a1e3cc950 100644
> --- a/drivers/misc/ocxl/ocxl_internal.h
> +++ b/drivers/misc/ocxl/ocxl_internal.h
> @@ -107,10 +107,34 @@ void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
> int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size);
> void ocxl_actag_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
>
> +/*
> + * Get the max PASID value that can be used by the function
> + */
> +int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
> +
> +int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
> +
> +/*
> + * Check if an AFU index is valid for the given function.
> + *
> + * AFU indexes can be sparse, so a driver should check all indexes up
> + * to the maximum found in the function description
> + */
> +int ocxl_config_check_afu_index(struct pci_dev *dev,
> + struct ocxl_fn_config *fn, int afu_idx);
> +
> +/**
> + * Update values within a Process Element
> + *
> + * link_handle: the link handle associated with the process element
> + * pasid: the PASID for the AFU context
> + * tid: the new thread id for the process element
> + */
> +int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
> +
> struct ocxl_context *ocxl_context_alloc(void);
> int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
> struct address_space *mapping);
> -int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
> int ocxl_context_mmap(struct ocxl_context *ctx,
> struct vm_area_struct *vma);
> int ocxl_context_detach(struct ocxl_context *ctx);
> diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h
> index 4544573cc93c..9530d3be1b30 100644
> --- a/include/misc/ocxl.h
> +++ b/include/misc/ocxl.h
> @@ -56,15 +56,6 @@ struct ocxl_fn_config {
> int ocxl_config_read_function(struct pci_dev *dev,
> struct ocxl_fn_config *fn);
>
> -/*
> - * Check if an AFU index is valid for the given function.
> - *
> - * AFU indexes can be sparse, so a driver should check all indexes up
> - * to the maximum found in the function description
> - */
> -int ocxl_config_check_afu_index(struct pci_dev *dev,
> - struct ocxl_fn_config *fn, int afu_idx);
> -
> /*
> * Read the configuration space of a function for the AFU specified by
> * the index 'afu_idx'. Fills in a ocxl_afu_config structure
> @@ -74,11 +65,6 @@ int ocxl_config_read_afu(struct pci_dev *dev,
> struct ocxl_afu_config *afu,
> u8 afu_idx);
>
> -/*
> - * Get the max PASID value that can be used by the function
> - */
> -int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
> -
> /*
> * Tell an AFU, by writing in the configuration space, the PASIDs that
> * it can use. Range starts at 'pasid_base' and its size is a multiple
> @@ -188,15 +174,6 @@ int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
> void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr),
> void *xsl_err_data);
>
> -/**
> - * Update values within a Process Element
> - *
> - * link_handle: the link handle associated with the process element
> - * pasid: the PASID for the AFU context
> - * tid: the new thread id for the process element
> - */
> -int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
> -
> /*
> * Remove a Process Element from the Shared Process Area for a link
> */
>
^ permalink raw reply
* Re: [PATCH 2/5] ocxl: Clean up printf formats
From: Frederic Barrat @ 2019-02-27 13:40 UTC (permalink / raw)
To: Alastair D'Silva, alastair
Cc: Greg Kroah-Hartman, linuxppc-dev, Arnd Bergmann, Andrew Donnellan,
linux-kernel
In-Reply-To: <20190227045741.21412-3-alastair@au1.ibm.com>
Le 27/02/2019 à 05:57, Alastair D'Silva a écrit :
> From: Alastair D'Silva <alastair@d-silva.org>
>
> Use %# instead of using a literal '0x'
>
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
> ---
I don't really care either way, but it looks ok.
Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
> drivers/misc/ocxl/config.c | 6 +++---
> drivers/misc/ocxl/context.c | 2 +-
> drivers/misc/ocxl/trace.h | 10 +++++-----
> 3 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
> index 8f2c5d8bd2ee..0ee7856b033d 100644
> --- a/drivers/misc/ocxl/config.c
> +++ b/drivers/misc/ocxl/config.c
> @@ -178,9 +178,9 @@ static int read_dvsec_vendor(struct pci_dev *dev)
> pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_DLX_VERS, &dlx);
>
> dev_dbg(&dev->dev, "Vendor specific DVSEC:\n");
> - dev_dbg(&dev->dev, " CFG version = 0x%x\n", cfg);
> - dev_dbg(&dev->dev, " TLX version = 0x%x\n", tlx);
> - dev_dbg(&dev->dev, " DLX version = 0x%x\n", dlx);
> + dev_dbg(&dev->dev, " CFG version = %#x\n", cfg);
> + dev_dbg(&dev->dev, " TLX version = %#x\n", tlx);
> + dev_dbg(&dev->dev, " DLX version = %#x\n", dlx);
> return 0;
> }
>
> diff --git a/drivers/misc/ocxl/context.c b/drivers/misc/ocxl/context.c
> index c10a940e3b38..3498a0199bde 100644
> --- a/drivers/misc/ocxl/context.c
> +++ b/drivers/misc/ocxl/context.c
> @@ -134,7 +134,7 @@ static vm_fault_t ocxl_mmap_fault(struct vm_fault *vmf)
> vm_fault_t ret;
>
> offset = vmf->pgoff << PAGE_SHIFT;
> - pr_debug("%s: pasid %d address 0x%lx offset 0x%llx\n", __func__,
> + pr_debug("%s: pasid %d address %#lx offset %#llx\n", __func__,
> ctx->pasid, vmf->address, offset);
>
> if (offset < ctx->afu->irq_base_offset)
> diff --git a/drivers/misc/ocxl/trace.h b/drivers/misc/ocxl/trace.h
> index bcb7ff330c1e..8d2f53812edd 100644
> --- a/drivers/misc/ocxl/trace.h
> +++ b/drivers/misc/ocxl/trace.h
> @@ -28,7 +28,7 @@ DECLARE_EVENT_CLASS(ocxl_context,
> __entry->tidr = tidr;
> ),
>
> - TP_printk("linux pid=%d spa=0x%p pasid=0x%x pidr=0x%x tidr=0x%x",
> + TP_printk("linux pid=%d spa=%p pasid=%#x pidr=%#x tidr=%#x",
> __entry->pid,
> __entry->spa,
> __entry->pasid,
> @@ -61,7 +61,7 @@ TRACE_EVENT(ocxl_terminate_pasid,
> __entry->rc = rc;
> ),
>
> - TP_printk("pasid=0x%x rc=%d",
> + TP_printk("pasid=%#x rc=%d",
> __entry->pasid,
> __entry->rc
> )
> @@ -87,7 +87,7 @@ DECLARE_EVENT_CLASS(ocxl_fault_handler,
> __entry->tfc = tfc;
> ),
>
> - TP_printk("spa=%p pe=0x%llx dsisr=0x%llx dar=0x%llx tfc=0x%llx",
> + TP_printk("spa=%p pe=%#llx dsisr=%#llx dar=%#llx tfc=%#llx",
> __entry->spa,
> __entry->pe,
> __entry->dsisr,
> @@ -127,7 +127,7 @@ TRACE_EVENT(ocxl_afu_irq_alloc,
> __entry->irq_offset = irq_offset;
> ),
>
> - TP_printk("pasid=0x%x irq_id=%d virq=%u hw_irq=%d irq_offset=0x%llx",
> + TP_printk("pasid=%#x irq_id=%d virq=%u hw_irq=%d irq_offset=0x%llx",
> __entry->pasid,
> __entry->irq_id,
> __entry->virq,
> @@ -150,7 +150,7 @@ TRACE_EVENT(ocxl_afu_irq_free,
> __entry->irq_id = irq_id;
> ),
>
> - TP_printk("pasid=0x%x irq_id=%d",
> + TP_printk("pasid=%#x irq_id=%d",
> __entry->pasid,
> __entry->irq_id
> )
>
^ permalink raw reply
* Re: [PATCH 1/5] ocxl: Rename struct link to ocxl_link
From: Frederic Barrat @ 2019-02-27 13:45 UTC (permalink / raw)
To: Andrew Donnellan, Alastair D'Silva,
'Alastair D'Silva'
Cc: 'Greg Kroah-Hartman', linuxppc-dev, 'Greg Kurz',
'Arnd Bergmann', linux-kernel
In-Reply-To: <97ad5218-4876-956e-e6ef-fb3449eca68e@au1.ibm.com>
Le 27/02/2019 à 09:18, Andrew Donnellan a écrit :
> On 27/2/19 7:04 pm, Alastair D'Silva wrote:
>>> -----Original Message-----
>>> From: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
>>> Sent: Wednesday, 27 February 2019 6:55 PM
>>> To: Alastair D'Silva <alastair@d-silva.org>; 'Alastair D'Silva'
>>> <alastair@au1.ibm.com>
>>> Cc: 'Greg Kurz' <groug@kaod.org>; 'Frederic Barrat'
>>> <fbarrat@linux.ibm.com>; 'Arnd Bergmann' <arnd@arndb.de>; 'Greg Kroah-
>>> Hartman' <gregkh@linuxfoundation.org>; linuxppc-dev@lists.ozlabs.org;
>>> linux-kernel@vger.kernel.org
>>> Subject: Re: [PATCH 1/5] ocxl: Rename struct link to ocxl_link
>>>
>>> On 27/2/19 6:34 pm, Alastair D'Silva wrote:>>> diff --git
>>> a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index
>>>>>> e6a607488f8a..16eb8a60d5c7 100644
>>>>>> --- a/drivers/misc/ocxl/file.c
>>>>>> +++ b/drivers/misc/ocxl/file.c
>>>>>> @@ -152,7 +152,7 @@ static long afu_ioctl_enable_p9_wait(struct
>>>>>> ocxl_context *ctx,
>>>>>>
>>>>>> if (status == ATTACHED) {
>>>>>> int rc;
>>>>>> - struct link *link = ctx->afu->fn->link;
>>>>>> + void *link = ctx->afu->fn->link;
>>>>>
>>>>> This doesn't look like a rename...
>>>>
>>>> That corrects the type to what the member (and prototype for
>>> ocxl_link_update_pe) declare it as.
>>>>
>>>> The struct link there is bogus, it shouldn't even compile (since the
>>>> intended
>>> struct link is defined in a different compilation unit), but instead
>>> picks up a
>>> different definition of 'struct link' from elsewhere.
>>>>
>>>
>>> Given there's only a handful of struct links defined across the
>>> entire kernel,
>>> I'm going to guess that the definition it's picking up is in fact the
>>> ocxl one.
>>>
>>
>> Unlikely, since that's never in a header. It wasn't caught since it
>> was assigned to/from a void*.
>
> Ah, yeah that'd explain it... and it's a pointer so it never needs to
> know its size. I'm clearly not very good at C.
>
>>
>>> I think the better solution here is to move struct ocxl_link into
>>> ocxl_internal.h, change ocxl_fn::link to be struct ocxl_link * rather
>>> than void
>>> *, and update the function signature for ocxl_link_update_pe() as well.
>> Not move it, but we could have an opaque declaration there.
>>
>
> Putting it there would fit with all the other ocxl_* structs, but either
> way, we definitely need a declaration in there and get rid of the void*, t
Mmm, it might turn out to be more invasive that planned...
The point was only to have it as an opaque to the outside world, for
APIs we'd like to deprecate at some point, so I wouldn't sweat too much
over it.
Fred
^ permalink raw reply
* Re: [PATCH 1/5] ocxl: Rename struct link to ocxl_link
From: Greg Kurz @ 2019-02-27 13:59 UTC (permalink / raw)
To: Frederic Barrat
Cc: 'Alastair D'Silva', 'Arnd Bergmann',
'Greg Kroah-Hartman', linux-kernel, Andrew Donnellan,
Alastair D'Silva, linuxppc-dev
In-Reply-To: <13209edc-d027-4d2f-668b-ad969a25eb06@linux.ibm.com>
On Wed, 27 Feb 2019 14:45:44 +0100
Frederic Barrat <fbarrat@linux.ibm.com> wrote:
> Le 27/02/2019 à 09:18, Andrew Donnellan a écrit :
> > On 27/2/19 7:04 pm, Alastair D'Silva wrote:
> >>> -----Original Message-----
> >>> From: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
> >>> Sent: Wednesday, 27 February 2019 6:55 PM
> >>> To: Alastair D'Silva <alastair@d-silva.org>; 'Alastair D'Silva'
> >>> <alastair@au1.ibm.com>
> >>> Cc: 'Greg Kurz' <groug@kaod.org>; 'Frederic Barrat'
> >>> <fbarrat@linux.ibm.com>; 'Arnd Bergmann' <arnd@arndb.de>; 'Greg Kroah-
> >>> Hartman' <gregkh@linuxfoundation.org>; linuxppc-dev@lists.ozlabs.org;
> >>> linux-kernel@vger.kernel.org
> >>> Subject: Re: [PATCH 1/5] ocxl: Rename struct link to ocxl_link
> >>>
> >>> On 27/2/19 6:34 pm, Alastair D'Silva wrote:>>> diff --git
> >>> a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index
> >>>>>> e6a607488f8a..16eb8a60d5c7 100644
> >>>>>> --- a/drivers/misc/ocxl/file.c
> >>>>>> +++ b/drivers/misc/ocxl/file.c
> >>>>>> @@ -152,7 +152,7 @@ static long afu_ioctl_enable_p9_wait(struct
> >>>>>> ocxl_context *ctx,
> >>>>>>
> >>>>>> if (status == ATTACHED) {
> >>>>>> int rc;
> >>>>>> - struct link *link = ctx->afu->fn->link;
> >>>>>> + void *link = ctx->afu->fn->link;
> >>>>>
> >>>>> This doesn't look like a rename...
> >>>>
> >>>> That corrects the type to what the member (and prototype for
> >>> ocxl_link_update_pe) declare it as.
> >>>>
> >>>> The struct link there is bogus, it shouldn't even compile (since the
> >>>> intended
> >>> struct link is defined in a different compilation unit), but instead
> >>> picks up a
> >>> different definition of 'struct link' from elsewhere.
> >>>>
> >>>
> >>> Given there's only a handful of struct links defined across the
> >>> entire kernel,
> >>> I'm going to guess that the definition it's picking up is in fact the
> >>> ocxl one.
> >>>
> >>
> >> Unlikely, since that's never in a header. It wasn't caught since it
> >> was assigned to/from a void*.
> >
> > Ah, yeah that'd explain it... and it's a pointer so it never needs to
> > know its size. I'm clearly not very good at C.
> >
> >>
> >>> I think the better solution here is to move struct ocxl_link into
> >>> ocxl_internal.h, change ocxl_fn::link to be struct ocxl_link * rather
> >>> than void
> >>> *, and update the function signature for ocxl_link_update_pe() as well.
> >> Not move it, but we could have an opaque declaration there.
> >>
> >
> > Putting it there would fit with all the other ocxl_* structs, but either
> > way, we definitely need a declaration in there and get rid of the void*, t
>
>
> Mmm, it might turn out to be more invasive that planned...
> The point was only to have it as an opaque to the outside world, for
> APIs we'd like to deprecate at some point, so I wouldn't sweat too much
> over it.
>
I concur. And even if an API change turns out to be beneficial, it
clearly belongs to some other patch/series. Hence my proposal to
simply drop that controversial and unneeded link variable in
afu_ioctl_enable_p9_wait().
> Fred
>
^ permalink raw reply
* [PATCH v8 4/4] powerpc/mm/iommu: Allow large IOMMU page size only for hugetlb backing
From: Aneesh Kumar K.V @ 2019-02-27 14:47 UTC (permalink / raw)
To: akpm, Michal Hocko, Alexey Kardashevskiy, David Gibson,
Andrea Arcangeli, mpe
Cc: linux-mm, linuxppc-dev, linux-kernel, Aneesh Kumar K.V
In-Reply-To: <20190227144736.5872-1-aneesh.kumar@linux.ibm.com>
THP pages can get split during different code paths. An incremented reference
count does imply we will not split the compound page. But the pmd entry can be
converted to level 4 pte entries. Keep the code simpler by allowing large
IOMMU page size only if the guest ram is backed by hugetlb pages.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
arch/powerpc/mm/mmu_context_iommu.c | 24 +++++++-----------------
1 file changed, 7 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c
index 85b4e9f5c615..e7a9c4f6bfca 100644
--- a/arch/powerpc/mm/mmu_context_iommu.c
+++ b/arch/powerpc/mm/mmu_context_iommu.c
@@ -98,8 +98,6 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua,
struct mm_iommu_table_group_mem_t *mem;
long i, ret, locked_entries = 0;
unsigned int pageshift;
- unsigned long flags;
- unsigned long cur_ua;
mutex_lock(&mem_list_mutex);
@@ -167,22 +165,14 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua,
for (i = 0; i < entries; ++i) {
struct page *page = mem->hpages[i];
- cur_ua = ua + (i << PAGE_SHIFT);
- if (mem->pageshift > PAGE_SHIFT && PageCompound(page)) {
- pte_t *pte;
+ /*
+ * Allow to use larger than 64k IOMMU pages. Only do that
+ * if we are backed by hugetlb.
+ */
+ if ((mem->pageshift > PAGE_SHIFT) && PageHuge(page)) {
struct page *head = compound_head(page);
- unsigned int compshift = compound_order(head);
- unsigned int pteshift;
-
- local_irq_save(flags); /* disables as well */
- pte = find_linux_pte(mm->pgd, cur_ua, NULL, &pteshift);
-
- /* Double check it is still the same pinned page */
- if (pte && pte_page(*pte) == head &&
- pteshift == compshift + PAGE_SHIFT)
- pageshift = max_t(unsigned int, pteshift,
- PAGE_SHIFT);
- local_irq_restore(flags);
+
+ pageshift = compound_order(head) + PAGE_SHIFT;
}
mem->pageshift = min(mem->pageshift, pageshift);
/*
--
2.20.1
^ permalink raw reply related
* [PATCH v8 1/4] mm/cma: Add PF flag to force non cma alloc
From: Aneesh Kumar K.V @ 2019-02-27 14:47 UTC (permalink / raw)
To: akpm, Michal Hocko, Alexey Kardashevskiy, David Gibson,
Andrea Arcangeli, mpe
Cc: linux-mm, linuxppc-dev, linux-kernel, Aneesh Kumar K.V
In-Reply-To: <20190227144736.5872-1-aneesh.kumar@linux.ibm.com>
This patch adds PF_MEMALLOC_NOCMA which make sure any allocation in that context
is marked non-movable and hence cannot be satisfied by CMA region.
This is useful with get_user_pages_longterm where we want to take a page pin by
migrating pages from CMA region. Marking the section PF_MEMALLOC_NOCMA ensures
that we avoid unnecessary page migration later.
Suggested-by: Andrea Arcangeli <aarcange@redhat.com>
Reviewed-by: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
include/linux/sched.h | 1 +
include/linux/sched/mm.h | 48 +++++++++++++++++++++++++++++++++-------
2 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f9b43c989577..dfa90088ba08 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1403,6 +1403,7 @@ extern struct pid *cad_pid;
#define PF_UMH 0x02000000 /* I'm an Usermodehelper process */
#define PF_NO_SETAFFINITY 0x04000000 /* Userland is not allowed to meddle with cpus_allowed */
#define PF_MCE_EARLY 0x08000000 /* Early kill for mce process policy */
+#define PF_MEMALLOC_NOCMA 0x10000000 /* All allocation request will have _GFP_MOVABLE cleared */
#define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */
#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */
#define PF_SUSPEND_TASK 0x80000000 /* This thread called freeze_processes() and should not be frozen */
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index 3bfa6a0cbba4..0cd9f10423fb 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -148,17 +148,25 @@ static inline bool in_vfork(struct task_struct *tsk)
* Applies per-task gfp context to the given allocation flags.
* PF_MEMALLOC_NOIO implies GFP_NOIO
* PF_MEMALLOC_NOFS implies GFP_NOFS
+ * PF_MEMALLOC_NOCMA implies no allocation from CMA region.
*/
static inline gfp_t current_gfp_context(gfp_t flags)
{
- /*
- * NOIO implies both NOIO and NOFS and it is a weaker context
- * so always make sure it makes precedence
- */
- if (unlikely(current->flags & PF_MEMALLOC_NOIO))
- flags &= ~(__GFP_IO | __GFP_FS);
- else if (unlikely(current->flags & PF_MEMALLOC_NOFS))
- flags &= ~__GFP_FS;
+ if (unlikely(current->flags &
+ (PF_MEMALLOC_NOIO | PF_MEMALLOC_NOFS | PF_MEMALLOC_NOCMA))) {
+ /*
+ * NOIO implies both NOIO and NOFS and it is a weaker context
+ * so always make sure it makes precedence
+ */
+ if (current->flags & PF_MEMALLOC_NOIO)
+ flags &= ~(__GFP_IO | __GFP_FS);
+ else if (current->flags & PF_MEMALLOC_NOFS)
+ flags &= ~__GFP_FS;
+#ifdef CONFIG_CMA
+ if (current->flags & PF_MEMALLOC_NOCMA)
+ flags &= ~__GFP_MOVABLE;
+#endif
+ }
return flags;
}
@@ -248,6 +256,30 @@ static inline void memalloc_noreclaim_restore(unsigned int flags)
current->flags = (current->flags & ~PF_MEMALLOC) | flags;
}
+#ifdef CONFIG_CMA
+static inline unsigned int memalloc_nocma_save(void)
+{
+ unsigned int flags = current->flags & PF_MEMALLOC_NOCMA;
+
+ current->flags |= PF_MEMALLOC_NOCMA;
+ return flags;
+}
+
+static inline void memalloc_nocma_restore(unsigned int flags)
+{
+ current->flags = (current->flags & ~PF_MEMALLOC_NOCMA) | flags;
+}
+#else
+static inline unsigned int memalloc_nocma_save(void)
+{
+ return 0;
+}
+
+static inline void memalloc_nocma_restore(unsigned int flags)
+{
+}
+#endif
+
#ifdef CONFIG_MEMCG
/**
* memalloc_use_memcg - Starts the remote memcg charging scope.
--
2.20.1
^ permalink raw reply related
* [PATCH v8 0/4] mm/kvm/vfio/ppc64: Migrate compound pages out of CMA region
From: Aneesh Kumar K.V @ 2019-02-27 14:47 UTC (permalink / raw)
To: akpm, Michal Hocko, Alexey Kardashevskiy, David Gibson,
Andrea Arcangeli, mpe
Cc: linux-mm, linuxppc-dev, linux-kernel, Aneesh Kumar K.V
ppc64 use CMA area for the allocation of guest page table (hash page table). We won't
be able to start guest if we fail to allocate hash page table. We have observed
hash table allocation failure because we failed to migrate pages out of CMA region
because they were pinned. This happen when we are using VFIO. VFIO on ppc64 pins
the entire guest RAM. If the guest RAM pages get allocated out of CMA region, we
won't be able to migrate those pages. The pages are also pinned for the lifetime of the
guest.
Currently we support migration of non-compound pages. With THP and with the addition of
hugetlb migration we can end up allocating compound pages from CMA region. This
patch series add support for migrating compound pages.
Changes from V7:
* update commit descrption for patch 3
* Address review feedback.
* Move PF_MEMALLOC_NOCMA to a different value.
Changes from V6:
* use get_user_pages_longterm instead of get_user_pages_cma_migrate()
Changes from V5:
* Add PF_MEMALLOC_NOCMA
* remote __GFP_THISNODE when allocating target page for migration
Changes from V4:
* use __GFP_NOWARN when allocating pages to avoid page allocation failure warnings.
Changes from V3:
* Move the hugetlb check before transhuge check
* Use compound head page when isolating hugetlb page
*** BLURB HERE ***
Aneesh Kumar K.V (4):
mm/cma: Add PF flag to force non cma alloc
mm: Update get_user_pages_longterm to migrate pages allocated from CMA
region
powerpc/mm/iommu: Allow migration of cma allocated pages during
mm_iommu_do_alloc
powerpc/mm/iommu: Allow large IOMMU page size only for hugetlb backing
arch/powerpc/mm/mmu_context_iommu.c | 145 ++++++--------------
include/linux/hugetlb.h | 2 +
include/linux/mm.h | 3 +-
include/linux/sched.h | 1 +
include/linux/sched/mm.h | 48 +++++--
mm/gup.c | 200 ++++++++++++++++++++++++----
mm/hugetlb.c | 4 +-
7 files changed, 266 insertions(+), 137 deletions(-)
--
2.20.1
^ permalink raw reply
* [PATCH v8 3/4] powerpc/mm/iommu: Allow migration of cma allocated pages during mm_iommu_do_alloc
From: Aneesh Kumar K.V @ 2019-02-27 14:47 UTC (permalink / raw)
To: akpm, Michal Hocko, Alexey Kardashevskiy, David Gibson,
Andrea Arcangeli, mpe
Cc: linux-mm, linuxppc-dev, linux-kernel, Aneesh Kumar K.V
In-Reply-To: <20190227144736.5872-1-aneesh.kumar@linux.ibm.com>
The current code doesn't do page migration if the page allocated is a compound page.
With HugeTLB migration support, we can end up allocating hugetlb pages from
CMA region. Also, THP pages can be allocated from CMA region. This patch updates
the code to handle compound pages correctly. The patch also switches to a single
get_user_pages with the right count, instead of doing one get_user_pages per page.
That avoids reading page table multiple times. This is done by using
get_user_pages_longterm, because that also takes care of DAX backed pages.
DAX pages lifetime is dictated by file system rules and as such, we need
to make sure that we free these pages on operations like truncate and
punch hole. If we have long term pin on these pages, which are mostly
return to userspace with elevated page count, the entity holding the
long term pin may not be aware of the fact that file got truncated and
the file system blocks possibly got reused. That can result in corruption.
The patch also converts the hpas member of mm_iommu_table_group_mem_t to a union.
We use the same storage location to store pointers to struct page. We cannot
update all the code path use struct page *, because we access hpas in real mode
and we can't do that struct page * to pfn conversion in real mode.
Reviewed-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
arch/powerpc/mm/mmu_context_iommu.c | 125 +++++++++-------------------
1 file changed, 38 insertions(+), 87 deletions(-)
diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c
index a712a650a8b6..85b4e9f5c615 100644
--- a/arch/powerpc/mm/mmu_context_iommu.c
+++ b/arch/powerpc/mm/mmu_context_iommu.c
@@ -21,6 +21,7 @@
#include <linux/sizes.h>
#include <asm/mmu_context.h>
#include <asm/pte-walk.h>
+#include <linux/mm_inline.h>
static DEFINE_MUTEX(mem_list_mutex);
@@ -34,8 +35,18 @@ struct mm_iommu_table_group_mem_t {
atomic64_t mapped;
unsigned int pageshift;
u64 ua; /* userspace address */
- u64 entries; /* number of entries in hpas[] */
- u64 *hpas; /* vmalloc'ed */
+ u64 entries; /* number of entries in hpas/hpages[] */
+ /*
+ * in mm_iommu_get we temporarily use this to store
+ * struct page address.
+ *
+ * We need to convert ua to hpa in real mode. Make it
+ * simpler by storing physical address.
+ */
+ union {
+ struct page **hpages; /* vmalloc'ed */
+ phys_addr_t *hpas;
+ };
#define MM_IOMMU_TABLE_INVALID_HPA ((uint64_t)-1)
u64 dev_hpa; /* Device memory base address */
};
@@ -80,64 +91,15 @@ bool mm_iommu_preregistered(struct mm_struct *mm)
}
EXPORT_SYMBOL_GPL(mm_iommu_preregistered);
-/*
- * Taken from alloc_migrate_target with changes to remove CMA allocations
- */
-struct page *new_iommu_non_cma_page(struct page *page, unsigned long private)
-{
- gfp_t gfp_mask = GFP_USER;
- struct page *new_page;
-
- if (PageCompound(page))
- return NULL;
-
- if (PageHighMem(page))
- gfp_mask |= __GFP_HIGHMEM;
-
- /*
- * We don't want the allocation to force an OOM if possibe
- */
- new_page = alloc_page(gfp_mask | __GFP_NORETRY | __GFP_NOWARN);
- return new_page;
-}
-
-static int mm_iommu_move_page_from_cma(struct page *page)
-{
- int ret = 0;
- LIST_HEAD(cma_migrate_pages);
-
- /* Ignore huge pages for now */
- if (PageCompound(page))
- return -EBUSY;
-
- lru_add_drain();
- ret = isolate_lru_page(page);
- if (ret)
- return ret;
-
- list_add(&page->lru, &cma_migrate_pages);
- put_page(page); /* Drop the gup reference */
-
- ret = migrate_pages(&cma_migrate_pages, new_iommu_non_cma_page,
- NULL, 0, MIGRATE_SYNC, MR_CONTIG_RANGE);
- if (ret) {
- if (!list_empty(&cma_migrate_pages))
- putback_movable_pages(&cma_migrate_pages);
- }
-
- return 0;
-}
-
static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua,
- unsigned long entries, unsigned long dev_hpa,
- struct mm_iommu_table_group_mem_t **pmem)
+ unsigned long entries, unsigned long dev_hpa,
+ struct mm_iommu_table_group_mem_t **pmem)
{
struct mm_iommu_table_group_mem_t *mem;
- long i, j, ret = 0, locked_entries = 0;
+ long i, ret, locked_entries = 0;
unsigned int pageshift;
unsigned long flags;
unsigned long cur_ua;
- struct page *page = NULL;
mutex_lock(&mem_list_mutex);
@@ -187,41 +149,25 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua,
goto unlock_exit;
}
+ down_read(&mm->mmap_sem);
+ ret = get_user_pages_longterm(ua, entries, FOLL_WRITE, mem->hpages, NULL);
+ up_read(&mm->mmap_sem);
+ if (ret != entries) {
+ /* free the reference taken */
+ for (i = 0; i < ret; i++)
+ put_page(mem->hpages[i]);
+
+ vfree(mem->hpas);
+ kfree(mem);
+ ret = -EFAULT;
+ goto unlock_exit;
+ }
+
+ pageshift = PAGE_SHIFT;
for (i = 0; i < entries; ++i) {
+ struct page *page = mem->hpages[i];
+
cur_ua = ua + (i << PAGE_SHIFT);
- if (1 != get_user_pages_fast(cur_ua,
- 1/* pages */, 1/* iswrite */, &page)) {
- ret = -EFAULT;
- for (j = 0; j < i; ++j)
- put_page(pfn_to_page(mem->hpas[j] >>
- PAGE_SHIFT));
- vfree(mem->hpas);
- kfree(mem);
- goto unlock_exit;
- }
- /*
- * If we get a page from the CMA zone, since we are going to
- * be pinning these entries, we might as well move them out
- * of the CMA zone if possible. NOTE: faulting in + migration
- * can be expensive. Batching can be considered later
- */
- if (is_migrate_cma_page(page)) {
- if (mm_iommu_move_page_from_cma(page))
- goto populate;
- if (1 != get_user_pages_fast(cur_ua,
- 1/* pages */, 1/* iswrite */,
- &page)) {
- ret = -EFAULT;
- for (j = 0; j < i; ++j)
- put_page(pfn_to_page(mem->hpas[j] >>
- PAGE_SHIFT));
- vfree(mem->hpas);
- kfree(mem);
- goto unlock_exit;
- }
- }
-populate:
- pageshift = PAGE_SHIFT;
if (mem->pageshift > PAGE_SHIFT && PageCompound(page)) {
pte_t *pte;
struct page *head = compound_head(page);
@@ -239,10 +185,15 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua,
local_irq_restore(flags);
}
mem->pageshift = min(mem->pageshift, pageshift);
+ /*
+ * We don't need struct page reference any more, switch
+ * to physical address.
+ */
mem->hpas[i] = page_to_pfn(page) << PAGE_SHIFT;
}
good_exit:
+ ret = 0;
atomic64_set(&mem->mapped, 1);
mem->used = 1;
mem->ua = ua;
--
2.20.1
^ permalink raw reply related
* [PATCH v8 2/4] mm: Update get_user_pages_longterm to migrate pages allocated from CMA region
From: Aneesh Kumar K.V @ 2019-02-27 14:47 UTC (permalink / raw)
To: akpm, Michal Hocko, Alexey Kardashevskiy, David Gibson,
Andrea Arcangeli, mpe
Cc: linux-mm, linuxppc-dev, linux-kernel, Aneesh Kumar K.V
In-Reply-To: <20190227144736.5872-1-aneesh.kumar@linux.ibm.com>
This patch updates get_user_pages_longterm to migrate pages allocated out
of CMA region. This makes sure that we don't keep non-movable pages (due to page
reference count) in the CMA area.
This will be used by ppc64 in a later patch to avoid pinning pages in the CMA
region. ppc64 uses CMA region for allocation of the hardware page table (hash page
table) and not able to migrate pages out of CMA region results in page table
allocation failures.
One case where we hit this easy is when a guest using a VFIO passthrough device.
VFIO locks all the guest's memory and if the guest memory is backed by CMA
region, it becomes unmovable resulting in fragmenting the CMA and possibly
preventing other guests from allocation a large enough hash page table.
NOTE: We allocate the new page without using __GFP_THISNODE
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
include/linux/hugetlb.h | 2 +
include/linux/mm.h | 3 +-
mm/gup.c | 200 +++++++++++++++++++++++++++++++++++-----
mm/hugetlb.c | 4 +-
4 files changed, 182 insertions(+), 27 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 087fd5f48c91..1eed0cdaec0e 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -371,6 +371,8 @@ struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid,
nodemask_t *nmask);
struct page *alloc_huge_page_vma(struct hstate *h, struct vm_area_struct *vma,
unsigned long address);
+struct page *alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask,
+ int nid, nodemask_t *nmask);
int huge_add_to_page_cache(struct page *page, struct address_space *mapping,
pgoff_t idx);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 80bb6408fe73..20ec56f8e2bb 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1536,7 +1536,8 @@ long get_user_pages_locked(unsigned long start, unsigned long nr_pages,
unsigned int gup_flags, struct page **pages, int *locked);
long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
struct page **pages, unsigned int gup_flags);
-#ifdef CONFIG_FS_DAX
+
+#if defined(CONFIG_FS_DAX) || defined(CONFIG_CMA)
long get_user_pages_longterm(unsigned long start, unsigned long nr_pages,
unsigned int gup_flags, struct page **pages,
struct vm_area_struct **vmas);
diff --git a/mm/gup.c b/mm/gup.c
index 75029649baca..22291db50013 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -13,6 +13,9 @@
#include <linux/sched/signal.h>
#include <linux/rwsem.h>
#include <linux/hugetlb.h>
+#include <linux/migrate.h>
+#include <linux/mm_inline.h>
+#include <linux/sched/mm.h>
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
@@ -1126,7 +1129,167 @@ long get_user_pages(unsigned long start, unsigned long nr_pages,
}
EXPORT_SYMBOL(get_user_pages);
+#if defined(CONFIG_FS_DAX) || defined (CONFIG_CMA)
+
#ifdef CONFIG_FS_DAX
+static bool check_dax_vmas(struct vm_area_struct **vmas, long nr_pages)
+{
+ long i;
+ struct vm_area_struct *vma_prev = NULL;
+
+ for (i = 0; i < nr_pages; i++) {
+ struct vm_area_struct *vma = vmas[i];
+
+ if (vma == vma_prev)
+ continue;
+
+ vma_prev = vma;
+
+ if (vma_is_fsdax(vma))
+ return true;
+ }
+ return false;
+}
+#else
+static inline bool check_dax_vmas(struct vm_area_struct **vmas, long nr_pages)
+{
+ return false;
+}
+#endif
+
+#ifdef CONFIG_CMA
+static struct page *new_non_cma_page(struct page *page, unsigned long private)
+{
+ /*
+ * We want to make sure we allocate the new page from the same node
+ * as the source page.
+ */
+ int nid = page_to_nid(page);
+ /*
+ * Trying to allocate a page for migration. Ignore allocation
+ * failure warnings. We don't force __GFP_THISNODE here because
+ * this node here is the node where we have CMA reservation and
+ * in some case these nodes will have really less non movable
+ * allocation memory.
+ */
+ gfp_t gfp_mask = GFP_USER | __GFP_NOWARN;
+
+ if (PageHighMem(page))
+ gfp_mask |= __GFP_HIGHMEM;
+
+#ifdef CONFIG_HUGETLB_PAGE
+ if (PageHuge(page)) {
+ struct hstate *h = page_hstate(page);
+ /*
+ * We don't want to dequeue from the pool because pool pages will
+ * mostly be from the CMA region.
+ */
+ return alloc_migrate_huge_page(h, gfp_mask, nid, NULL);
+ }
+#endif
+ if (PageTransHuge(page)) {
+ struct page *thp;
+ /*
+ * ignore allocation failure warnings
+ */
+ gfp_t thp_gfpmask = GFP_TRANSHUGE | __GFP_NOWARN;
+
+ /*
+ * Remove the movable mask so that we don't allocate from
+ * CMA area again.
+ */
+ thp_gfpmask &= ~__GFP_MOVABLE;
+ thp = __alloc_pages_node(nid, thp_gfpmask, HPAGE_PMD_ORDER);
+ if (!thp)
+ return NULL;
+ prep_transhuge_page(thp);
+ return thp;
+ }
+
+ return __alloc_pages_node(nid, gfp_mask, 0);
+}
+
+static long check_and_migrate_cma_pages(unsigned long start, long nr_pages,
+ unsigned int gup_flags,
+ struct page **pages,
+ struct vm_area_struct **vmas)
+{
+ long i;
+ bool drain_allow = true;
+ bool migrate_allow = true;
+ LIST_HEAD(cma_page_list);
+
+check_again:
+ for (i = 0; i < nr_pages; i++) {
+ /*
+ * If we get a page from the CMA zone, since we are going to
+ * be pinning these entries, we might as well move them out
+ * of the CMA zone if possible.
+ */
+ if (is_migrate_cma_page(pages[i])) {
+
+ struct page *head = compound_head(pages[i]);
+
+ if (PageHuge(head)) {
+ isolate_huge_page(head, &cma_page_list);
+ } else {
+ if (!PageLRU(head) && drain_allow) {
+ lru_add_drain_all();
+ drain_allow = false;
+ }
+
+ if (!isolate_lru_page(head)) {
+ list_add_tail(&head->lru, &cma_page_list);
+ mod_node_page_state(page_pgdat(head),
+ NR_ISOLATED_ANON +
+ page_is_file_cache(head),
+ hpage_nr_pages(head));
+ }
+ }
+ }
+ }
+
+ if (!list_empty(&cma_page_list)) {
+ /*
+ * drop the above get_user_pages reference.
+ */
+ for (i = 0; i < nr_pages; i++)
+ put_page(pages[i]);
+
+ if (migrate_pages(&cma_page_list, new_non_cma_page,
+ NULL, 0, MIGRATE_SYNC, MR_CONTIG_RANGE)) {
+ /*
+ * some of the pages failed migration. Do get_user_pages
+ * without migration.
+ */
+ migrate_allow = false;
+
+ if (!list_empty(&cma_page_list))
+ putback_movable_pages(&cma_page_list);
+ }
+ /*
+ * We did migrate all the pages, Try to get the page references again
+ * migrating any new CMA pages which we failed to isolate earlier.
+ */
+ nr_pages = get_user_pages(start, nr_pages, gup_flags, pages, vmas);
+ if ((nr_pages > 0) && migrate_allow) {
+ drain_allow = true;
+ goto check_again;
+ }
+ }
+
+ return nr_pages;
+}
+#else
+static inline long check_and_migrate_cma_pages(unsigned long start, long nr_pages,
+ unsigned int gup_flags,
+ struct page **pages,
+ struct vm_area_struct **vmas)
+{
+ return nr_pages;
+}
+#endif
+
/*
* This is the same as get_user_pages() in that it assumes we are
* operating on the current task's mm, but it goes further to validate
@@ -1140,11 +1303,11 @@ EXPORT_SYMBOL(get_user_pages);
* Contrast this to iov_iter_get_pages() usages which are transient.
*/
long get_user_pages_longterm(unsigned long start, unsigned long nr_pages,
- unsigned int gup_flags, struct page **pages,
- struct vm_area_struct **vmas_arg)
+ unsigned int gup_flags, struct page **pages,
+ struct vm_area_struct **vmas_arg)
{
struct vm_area_struct **vmas = vmas_arg;
- struct vm_area_struct *vma_prev = NULL;
+ unsigned long flags;
long rc, i;
if (!pages)
@@ -1157,31 +1320,20 @@ long get_user_pages_longterm(unsigned long start, unsigned long nr_pages,
return -ENOMEM;
}
+ flags = memalloc_nocma_save();
rc = get_user_pages(start, nr_pages, gup_flags, pages, vmas);
+ memalloc_nocma_restore(flags);
+ if (rc < 0)
+ goto out;
- for (i = 0; i < rc; i++) {
- struct vm_area_struct *vma = vmas[i];
-
- if (vma == vma_prev)
- continue;
-
- vma_prev = vma;
-
- if (vma_is_fsdax(vma))
- break;
- }
-
- /*
- * Either get_user_pages() failed, or the vma validation
- * succeeded, in either case we don't need to put_page() before
- * returning.
- */
- if (i >= rc)
+ if (check_dax_vmas(vmas, rc)) {
+ for (i = 0; i < rc; i++)
+ put_page(pages[i]);
+ rc = -EOPNOTSUPP;
goto out;
+ }
- for (i = 0; i < rc; i++)
- put_page(pages[i]);
- rc = -EOPNOTSUPP;
+ rc = check_and_migrate_cma_pages(start, rc, gup_flags, pages, vmas);
out:
if (vmas != vmas_arg)
kfree(vmas);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index afef61656c1e..c80f0c16a226 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1586,8 +1586,8 @@ static struct page *alloc_surplus_huge_page(struct hstate *h, gfp_t gfp_mask,
return page;
}
-static struct page *alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask,
- int nid, nodemask_t *nmask)
+struct page *alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask,
+ int nid, nodemask_t *nmask)
{
struct page *page;
--
2.20.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox