Re: [PATCH v6 01/10] mm/memunmap: Don't access uninitialized memmap in memunmap_pages()

2019-10-14 Thread David Hildenbrand

On 06.10.19 10:56, David Hildenbrand wrote:

From: "Aneesh Kumar K.V" 

With an altmap, the memmap falling into the reserved altmap space are
not initialized and, therefore, contain a garbage NID and a garbage
zone. Make sure to read the NID/zone from a memmap that was initialzed.

This fixes a kernel crash that is observed when destroying a namespace:

[   81.356173] kernel BUG at include/linux/mm.h:1107!
cpu 0x1: Vector: 700 (Program Check) at [c00274087890]
 pc: c04b9728: memunmap_pages+0x238/0x340
 lr: c04b9724: memunmap_pages+0x234/0x340
...
 pid   = 3669, comm = ndctl
kernel BUG at include/linux/mm.h:1107!
[c00274087ba0] c09e3500 devm_action_release+0x30/0x50
[c00274087bc0] c09e4758 release_nodes+0x268/0x2d0
[c00274087c30] c09dd144 device_release_driver_internal+0x174/0x240
[c00274087c70] c09d9dfc unbind_store+0x13c/0x190
[c00274087cb0] c09d8a24 drv_attr_store+0x44/0x60
[c00274087cd0] c05a7470 sysfs_kf_write+0x70/0xa0
[c00274087d10] c05a5cac kernfs_fop_write+0x1ac/0x290
[c00274087d60] c04be45c __vfs_write+0x3c/0x70
[c00274087d80] c04c26e4 vfs_write+0xe4/0x200
[c00274087dd0] c04c2a6c ksys_write+0x7c/0x140
[c00274087e20] c000bbd0 system_call+0x5c/0x68

Cc: Dan Williams 
Cc: Andrew Morton 
Cc: Jason Gunthorpe 
Cc: Logan Gunthorpe 
Cc: Ira Weiny 
Signed-off-by: Aneesh Kumar K.V 
[ minimze code changes, rephrase description ]
Signed-off-by: David Hildenbrand 
---
  mm/memremap.c | 11 +++
  1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/mm/memremap.c b/mm/memremap.c
index 557e53c6fb46..8c2fb44c3b4d 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -123,6 +123,7 @@ static void dev_pagemap_cleanup(struct dev_pagemap *pgmap)
  void memunmap_pages(struct dev_pagemap *pgmap)
  {
struct resource *res = &pgmap->res;
+   struct page *first_page;
unsigned long pfn;
int nid;
  
@@ -131,14 +132,16 @@ void memunmap_pages(struct dev_pagemap *pgmap)

put_page(pfn_to_page(pfn));
dev_pagemap_cleanup(pgmap);
  
+	/* make sure to access a memmap that was actually initialized */

+   first_page = pfn_to_page(pfn_first(pgmap));
+
/* pages are dead and unused, undo the arch mapping */
-   nid = page_to_nid(pfn_to_page(PHYS_PFN(res->start)));
+   nid = page_to_nid(first_page);
  
  	mem_hotplug_begin();

if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
-   pfn = PHYS_PFN(res->start);
-   __remove_pages(page_zone(pfn_to_page(pfn)), pfn,
-PHYS_PFN(resource_size(res)), NULL);
+   __remove_pages(page_zone(first_page), PHYS_PFN(res->start),
+  PHYS_PFN(resource_size(res)), NULL);
} else {
arch_remove_memory(nid, res->start, resource_size(res),
pgmap_altmap(pgmap));



@Andrew, can you add

Fixes: 2c2a5af6fed2 ("mm, memory_hotplug: add nid parameter to 
arch_remove_memory")


(which basically introduced the nid = page_to_nid(first_page))

The "page_zone(pfn_to_page(pfn)" was introduced by 69324b8f4833 ("mm, 
devm_memremap_pages: add MEMORY_DEVICE_PRIVATE support"), however, I 
think we will never have driver reserved memory with 
MEMORY_DEVICE_PRIVATE (no altmap AFAIKS).


Also, I think

Cc: sta...@vger.kernel.org # v5.0+

makes sense.

--

Thanks,

David / dhildenb


Re: [PATCH v6 01/10] mm/memunmap: Don't access uninitialized memmap in memunmap_pages()

2019-10-06 Thread Damian Tometzki
Hello David,

patch 05/10 is missing in the patch series. 


On Sun, 06. Oct 10:56, David Hildenbrand wrote:
> From: "Aneesh Kumar K.V" 
> 
> With an altmap, the memmap falling into the reserved altmap space are
> not initialized and, therefore, contain a garbage NID and a garbage
> zone. Make sure to read the NID/zone from a memmap that was initialzed.
> 
> This fixes a kernel crash that is observed when destroying a namespace:
> 
> [   81.356173] kernel BUG at include/linux/mm.h:1107!
> cpu 0x1: Vector: 700 (Program Check) at [c00274087890]
> pc: c04b9728: memunmap_pages+0x238/0x340
> lr: c04b9724: memunmap_pages+0x234/0x340
> ...
> pid   = 3669, comm = ndctl
> kernel BUG at include/linux/mm.h:1107!
> [c00274087ba0] c09e3500 devm_action_release+0x30/0x50
> [c00274087bc0] c09e4758 release_nodes+0x268/0x2d0
> [c00274087c30] c09dd144 device_release_driver_internal+0x174/0x240
> [c00274087c70] c09d9dfc unbind_store+0x13c/0x190
> [c00274087cb0] c09d8a24 drv_attr_store+0x44/0x60
> [c00274087cd0] c05a7470 sysfs_kf_write+0x70/0xa0
> [c00274087d10] c05a5cac kernfs_fop_write+0x1ac/0x290
> [c00274087d60] c04be45c __vfs_write+0x3c/0x70
> [c00274087d80] c04c26e4 vfs_write+0xe4/0x200
> [c00274087dd0] c04c2a6c ksys_write+0x7c/0x140
> [c00274087e20] c000bbd0 system_call+0x5c/0x68
> 
> Cc: Dan Williams 
> Cc: Andrew Morton 
> Cc: Jason Gunthorpe 
> Cc: Logan Gunthorpe 
> Cc: Ira Weiny 
> Signed-off-by: Aneesh Kumar K.V 
> [ minimze code changes, rephrase description ]
> Signed-off-by: David Hildenbrand 
> ---
>  mm/memremap.c | 11 +++
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/mm/memremap.c b/mm/memremap.c
> index 557e53c6fb46..8c2fb44c3b4d 100644
> --- a/mm/memremap.c
> +++ b/mm/memremap.c
> @@ -123,6 +123,7 @@ static void dev_pagemap_cleanup(struct dev_pagemap *pgmap)
>  void memunmap_pages(struct dev_pagemap *pgmap)
>  {
>   struct resource *res = &pgmap->res;
> + struct page *first_page;
>   unsigned long pfn;
>   int nid;
>  
> @@ -131,14 +132,16 @@ void memunmap_pages(struct dev_pagemap *pgmap)
>   put_page(pfn_to_page(pfn));
>   dev_pagemap_cleanup(pgmap);
>  
> + /* make sure to access a memmap that was actually initialized */
> + first_page = pfn_to_page(pfn_first(pgmap));
> +
>   /* pages are dead and unused, undo the arch mapping */
> - nid = page_to_nid(pfn_to_page(PHYS_PFN(res->start)));
> + nid = page_to_nid(first_page);

Why we need 'nid = page_to_nid(first_page)' we didnt use it anymore in this 
function ?

>  
>   mem_hotplug_begin();
>   if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
> - pfn = PHYS_PFN(res->start);
> - __remove_pages(page_zone(pfn_to_page(pfn)), pfn,
> -  PHYS_PFN(resource_size(res)), NULL);
> + __remove_pages(page_zone(first_page), PHYS_PFN(res->start),
> +PHYS_PFN(resource_size(res)), NULL);
>   } else {
>   arch_remove_memory(nid, res->start, resource_size(res),
>   pgmap_altmap(pgmap));
> -- 
> 2.21.0
>
Best regards
Damian
 


Re: [PATCH v6 01/10] mm/memunmap: Don't access uninitialized memmap in memunmap_pages()

2019-10-06 Thread David Hildenbrand
On 06.10.19 21:58, Damian Tometzki wrote:
> Hello David,
> 
> patch 05/10 is missing in the patch series. 
> 

Hi Damian,

not really. Could be that lkml is slow today. E.g., check

https://marc.info/?l=linux-mm&m=157035222620403&w=2

and especially

https://marc.info/?l=linux-mm&m=157035225120440&w=2

All mails popped up on the mm list.

> 
> On Sun, 06. Oct 10:56, David Hildenbrand wrote:
>> From: "Aneesh Kumar K.V" 
>>
>> With an altmap, the memmap falling into the reserved altmap space are
>> not initialized and, therefore, contain a garbage NID and a garbage
>> zone. Make sure to read the NID/zone from a memmap that was initialzed.
>>
>> This fixes a kernel crash that is observed when destroying a namespace:
>>
>> [   81.356173] kernel BUG at include/linux/mm.h:1107!
>> cpu 0x1: Vector: 700 (Program Check) at [c00274087890]
>> pc: c04b9728: memunmap_pages+0x238/0x340
>> lr: c04b9724: memunmap_pages+0x234/0x340
>> ...
>> pid   = 3669, comm = ndctl
>> kernel BUG at include/linux/mm.h:1107!
>> [c00274087ba0] c09e3500 devm_action_release+0x30/0x50
>> [c00274087bc0] c09e4758 release_nodes+0x268/0x2d0
>> [c00274087c30] c09dd144 
>> device_release_driver_internal+0x174/0x240
>> [c00274087c70] c09d9dfc unbind_store+0x13c/0x190
>> [c00274087cb0] c09d8a24 drv_attr_store+0x44/0x60
>> [c00274087cd0] c05a7470 sysfs_kf_write+0x70/0xa0
>> [c00274087d10] c05a5cac kernfs_fop_write+0x1ac/0x290
>> [c00274087d60] c04be45c __vfs_write+0x3c/0x70
>> [c00274087d80] c04c26e4 vfs_write+0xe4/0x200
>> [c00274087dd0] c04c2a6c ksys_write+0x7c/0x140
>> [c00274087e20] c000bbd0 system_call+0x5c/0x68
>>
>> Cc: Dan Williams 
>> Cc: Andrew Morton 
>> Cc: Jason Gunthorpe 
>> Cc: Logan Gunthorpe 
>> Cc: Ira Weiny 
>> Signed-off-by: Aneesh Kumar K.V 
>> [ minimze code changes, rephrase description ]
>> Signed-off-by: David Hildenbrand 
>> ---
>>  mm/memremap.c | 11 +++
>>  1 file changed, 7 insertions(+), 4 deletions(-)
>>
>> diff --git a/mm/memremap.c b/mm/memremap.c
>> index 557e53c6fb46..8c2fb44c3b4d 100644
>> --- a/mm/memremap.c
>> +++ b/mm/memremap.c
>> @@ -123,6 +123,7 @@ static void dev_pagemap_cleanup(struct dev_pagemap 
>> *pgmap)
>>  void memunmap_pages(struct dev_pagemap *pgmap)
>>  {
>>  struct resource *res = &pgmap->res;
>> +struct page *first_page;
>>  unsigned long pfn;
>>  int nid;
>>  
>> @@ -131,14 +132,16 @@ void memunmap_pages(struct dev_pagemap *pgmap)
>>  put_page(pfn_to_page(pfn));
>>  dev_pagemap_cleanup(pgmap);
>>  
>> +/* make sure to access a memmap that was actually initialized */
>> +first_page = pfn_to_page(pfn_first(pgmap));
>> +
>>  /* pages are dead and unused, undo the arch mapping */
>> -nid = page_to_nid(pfn_to_page(PHYS_PFN(res->start)));
>> +nid = page_to_nid(first_page);
> 
> Why we need 'nid = page_to_nid(first_page)' we didnt use it anymore in this 
> function ?

Please see ...

> 
>>  
>>  mem_hotplug_begin();
>>  if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
>> -pfn = PHYS_PFN(res->start);
>> -__remove_pages(page_zone(pfn_to_page(pfn)), pfn,
>> - PHYS_PFN(resource_size(res)), NULL);
>> +__remove_pages(page_zone(first_page), PHYS_PFN(res->start),
>> +   PHYS_PFN(resource_size(res)), NULL);
>>  } else {
>>  arch_remove_memory(nid, res->start, resource_size(res),
   ^ here

:)

>>  pgmap_altmap(pgmap));



-- 

Thanks,

David / dhildenb


[PATCH v6 01/10] mm/memunmap: Don't access uninitialized memmap in memunmap_pages()

2019-10-06 Thread David Hildenbrand
From: "Aneesh Kumar K.V" 

With an altmap, the memmap falling into the reserved altmap space are
not initialized and, therefore, contain a garbage NID and a garbage
zone. Make sure to read the NID/zone from a memmap that was initialzed.

This fixes a kernel crash that is observed when destroying a namespace:

[   81.356173] kernel BUG at include/linux/mm.h:1107!
cpu 0x1: Vector: 700 (Program Check) at [c00274087890]
pc: c04b9728: memunmap_pages+0x238/0x340
lr: c04b9724: memunmap_pages+0x234/0x340
...
pid   = 3669, comm = ndctl
kernel BUG at include/linux/mm.h:1107!
[c00274087ba0] c09e3500 devm_action_release+0x30/0x50
[c00274087bc0] c09e4758 release_nodes+0x268/0x2d0
[c00274087c30] c09dd144 device_release_driver_internal+0x174/0x240
[c00274087c70] c09d9dfc unbind_store+0x13c/0x190
[c00274087cb0] c09d8a24 drv_attr_store+0x44/0x60
[c00274087cd0] c05a7470 sysfs_kf_write+0x70/0xa0
[c00274087d10] c05a5cac kernfs_fop_write+0x1ac/0x290
[c00274087d60] c04be45c __vfs_write+0x3c/0x70
[c00274087d80] c04c26e4 vfs_write+0xe4/0x200
[c00274087dd0] c04c2a6c ksys_write+0x7c/0x140
[c00274087e20] c000bbd0 system_call+0x5c/0x68

Cc: Dan Williams 
Cc: Andrew Morton 
Cc: Jason Gunthorpe 
Cc: Logan Gunthorpe 
Cc: Ira Weiny 
Signed-off-by: Aneesh Kumar K.V 
[ minimze code changes, rephrase description ]
Signed-off-by: David Hildenbrand 
---
 mm/memremap.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/mm/memremap.c b/mm/memremap.c
index 557e53c6fb46..8c2fb44c3b4d 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -123,6 +123,7 @@ static void dev_pagemap_cleanup(struct dev_pagemap *pgmap)
 void memunmap_pages(struct dev_pagemap *pgmap)
 {
struct resource *res = &pgmap->res;
+   struct page *first_page;
unsigned long pfn;
int nid;
 
@@ -131,14 +132,16 @@ void memunmap_pages(struct dev_pagemap *pgmap)
put_page(pfn_to_page(pfn));
dev_pagemap_cleanup(pgmap);
 
+   /* make sure to access a memmap that was actually initialized */
+   first_page = pfn_to_page(pfn_first(pgmap));
+
/* pages are dead and unused, undo the arch mapping */
-   nid = page_to_nid(pfn_to_page(PHYS_PFN(res->start)));
+   nid = page_to_nid(first_page);
 
mem_hotplug_begin();
if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
-   pfn = PHYS_PFN(res->start);
-   __remove_pages(page_zone(pfn_to_page(pfn)), pfn,
-PHYS_PFN(resource_size(res)), NULL);
+   __remove_pages(page_zone(first_page), PHYS_PFN(res->start),
+  PHYS_PFN(resource_size(res)), NULL);
} else {
arch_remove_memory(nid, res->start, resource_size(res),
pgmap_altmap(pgmap));
-- 
2.21.0