[2/2] powerpc/fadump: avoid holes in boot memory area when fadump is registered

Submitted by Hari Bathini on May 4, 2017, 5:54 p.m.

Details

Message ID 149392044508.10802.11008391107873058533.stgit@hbathini.in.ibm.com
State Superseded
Headers show

Commit Message

Hari Bathini May 4, 2017, 5:54 p.m.
To register fadump, boot memory area - the size of low memory chunk that
is required for a kernel to boot successfully when booted with restricted
memory, is assumed to have no holes. But this memory area is currently
not protected from hot-remove operations. So, fadump could fail to
re-register after a memory hot-remove operation, if memory is removed
from boot memory area. To avoid this, ensure that memory from boot
memory area is not hot-removed when fadump is registered.

Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/fadump.h               |    1 +
 arch/powerpc/kernel/fadump.c                    |   12 ++++++++++++
 arch/powerpc/platforms/pseries/hotplug-memory.c |    7 +++++++
 3 files changed, 20 insertions(+)

Comments

Mahesh Salgaonkar May 5, 2017, 6:54 a.m.
On 05/04/2017 11:24 PM, Hari Bathini wrote:
> To register fadump, boot memory area - the size of low memory chunk that
> is required for a kernel to boot successfully when booted with restricted
> memory, is assumed to have no holes. But this memory area is currently
> not protected from hot-remove operations. So, fadump could fail to
> re-register after a memory hot-remove operation, if memory is removed
> from boot memory area. To avoid this, ensure that memory from boot
> memory area is not hot-removed when fadump is registered.
> 
> Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>

Reviewed-by: Mahesh J Salgaonkar <mahesh@linux.vnet.ibm.com>

> ---
>  arch/powerpc/include/asm/fadump.h               |    1 +
>  arch/powerpc/kernel/fadump.c                    |   12 ++++++++++++
>  arch/powerpc/platforms/pseries/hotplug-memory.c |    7 +++++++
>  3 files changed, 20 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h
> index 0031806..609fccc 100644
> --- a/arch/powerpc/include/asm/fadump.h
> +++ b/arch/powerpc/include/asm/fadump.h
> @@ -198,6 +198,7 @@ struct fad_crash_memory_ranges {
>  	unsigned long long	size;
>  };
> 
> +extern int is_fadump_boot_memory_area(u64 addr, ulong size);
>  extern int early_init_dt_scan_fw_dump(unsigned long node,
>  		const char *uname, int depth, void *data);
>  extern int fadump_reserve_mem(void);
> diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
> index 03563c6..ea7dfdc 100644
> --- a/arch/powerpc/kernel/fadump.c
> +++ b/arch/powerpc/kernel/fadump.c
> @@ -114,6 +114,18 @@ int __init early_init_dt_scan_fw_dump(unsigned long node,
>  	return 1;
>  }
> 
> +/*
> + * If fadump is registered, check if the memory provided
> + * falls within boot memory area.
> + */
> +int is_fadump_boot_memory_area(u64 addr, ulong size)
> +{
> +	if (!fw_dump.dump_registered)
> +		return 0;
> +
> +	return (addr + size) > RMA_START && addr <= fw_dump.boot_memory_size;
> +}
> +
>  int is_fadump_active(void)
>  {
>  	return fw_dump.dump_active;
> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
> index e104c71..a186b8e 100644
> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
> @@ -22,6 +22,7 @@
>  #include <asm/machdep.h>
>  #include <asm/prom.h>
>  #include <asm/sparsemem.h>
> +#include <asm/fadump.h>
>  #include "pseries.h"
> 
>  static bool rtas_hp_event;
> @@ -406,6 +407,12 @@ static bool lmb_is_removable(struct of_drconf_cell *lmb)
>  	scns_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
>  	phys_addr = lmb->base_addr;
> 
> +#ifdef CONFIG_FA_DUMP
> +	/* Don't hot-remove memory that falls in fadump boot memory area */
> +	if (is_fadump_boot_memory_area(phys_addr, block_sz))
> +		return false;
> +#endif
> +
>  	for (i = 0; i < scns_per_block; i++) {
>  		pfn = PFN_DOWN(phys_addr);
>  		if (!pfn_present(pfn))
>
Pingfan Liu May 5, 2017, 11:43 a.m.
----- Original Message -----
> From: "Hari Bathini" <hbathini@linux.vnet.ibm.com>
> To: "Michael Ellerman" <mpe@ellerman.id.au>
> Cc: "linuxppc-dev" <linuxppc-dev@ozlabs.org>, "Pingfan Liu" <piliu@redhat.com>, "Mahesh J Salgaonkar"
> <mahesh@linux.vnet.ibm.com>
> Sent: Friday, May 5, 2017 1:54:05 AM
> Subject: [PATCH 2/2] powerpc/fadump: avoid holes in boot memory area when fadump is registered
> 
> To register fadump, boot memory area - the size of low memory chunk that
> is required for a kernel to boot successfully when booted with restricted
> memory, is assumed to have no holes. But this memory area is currently

The continuous is required by fadump code, not by the firmware itself, right?

Thanks and regards,
Pingfan

> not protected from hot-remove operations. So, fadump could fail to
> re-register after a memory hot-remove operation, if memory is removed
> from boot memory area. To avoid this, ensure that memory from boot
> memory area is not hot-removed when fadump is registered.
> 
> Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
> ---
>  arch/powerpc/include/asm/fadump.h               |    1 +
>  arch/powerpc/kernel/fadump.c                    |   12 ++++++++++++
>  arch/powerpc/platforms/pseries/hotplug-memory.c |    7 +++++++
>  3 files changed, 20 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/fadump.h
> b/arch/powerpc/include/asm/fadump.h
> index 0031806..609fccc 100644
> --- a/arch/powerpc/include/asm/fadump.h
> +++ b/arch/powerpc/include/asm/fadump.h
> @@ -198,6 +198,7 @@ struct fad_crash_memory_ranges {
>  	unsigned long long	size;
>  };
>  
> +extern int is_fadump_boot_memory_area(u64 addr, ulong size);
>  extern int early_init_dt_scan_fw_dump(unsigned long node,
>  		const char *uname, int depth, void *data);
>  extern int fadump_reserve_mem(void);
> diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
> index 03563c6..ea7dfdc 100644
> --- a/arch/powerpc/kernel/fadump.c
> +++ b/arch/powerpc/kernel/fadump.c
> @@ -114,6 +114,18 @@ int __init early_init_dt_scan_fw_dump(unsigned long
> node,
>  	return 1;
>  }
>  
> +/*
> + * If fadump is registered, check if the memory provided
> + * falls within boot memory area.
> + */
> +int is_fadump_boot_memory_area(u64 addr, ulong size)
> +{
> +	if (!fw_dump.dump_registered)
> +		return 0;
> +
> +	return (addr + size) > RMA_START && addr <= fw_dump.boot_memory_size;
> +}
> +
>  int is_fadump_active(void)
>  {
>  	return fw_dump.dump_active;
> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c
> b/arch/powerpc/platforms/pseries/hotplug-memory.c
> index e104c71..a186b8e 100644
> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
> @@ -22,6 +22,7 @@
>  #include <asm/machdep.h>
>  #include <asm/prom.h>
>  #include <asm/sparsemem.h>
> +#include <asm/fadump.h>
>  #include "pseries.h"
>  
>  static bool rtas_hp_event;
> @@ -406,6 +407,12 @@ static bool lmb_is_removable(struct of_drconf_cell *lmb)
>  	scns_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
>  	phys_addr = lmb->base_addr;
>  
> +#ifdef CONFIG_FA_DUMP
> +	/* Don't hot-remove memory that falls in fadump boot memory area */
> +	if (is_fadump_boot_memory_area(phys_addr, block_sz))
> +		return false;
> +#endif
> +
>  	for (i = 0; i < scns_per_block; i++) {
>  		pfn = PFN_DOWN(phys_addr);
>  		if (!pfn_present(pfn))
> 
>
Hari Bathini May 5, 2017, 2:31 p.m.
On Friday 05 May 2017 05:13 PM, Pingfan Liu wrote:
>
>
>
> ----- Original Message -----
>> From: "Hari Bathini" <hbathini@linux.vnet.ibm.com>
>> To: "Michael Ellerman" <mpe@ellerman.id.au>
>> Cc: "linuxppc-dev" <linuxppc-dev@ozlabs.org>, "Pingfan Liu" <piliu@redhat.com>, "Mahesh J Salgaonkar"
>> <mahesh@linux.vnet.ibm.com>
>> Sent: Friday, May 5, 2017 1:54:05 AM
>> Subject: [PATCH 2/2] powerpc/fadump: avoid holes in boot memory area when fadump is registered
>>
>> To register fadump, boot memory area - the size of low memory chunk that
>> is required for a kernel to boot successfully when booted with restricted
>> memory, is assumed to have no holes. But this memory area is currently
> The continuous is required by fadump code, not by the firmware itself, right?
>

Hmmm... Firmware takes a memory region,what we are calling boot memory
area, as input to be backed up at the time of crash. The same memory
region is used by kernel to boot after the crash. Firmware doesn't allow
holes in this memory region at the time of registering...

Thanks
Hari

Patch hide | download patch | download mbox

diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h
index 0031806..609fccc 100644
--- a/arch/powerpc/include/asm/fadump.h
+++ b/arch/powerpc/include/asm/fadump.h
@@ -198,6 +198,7 @@  struct fad_crash_memory_ranges {
 	unsigned long long	size;
 };
 
+extern int is_fadump_boot_memory_area(u64 addr, ulong size);
 extern int early_init_dt_scan_fw_dump(unsigned long node,
 		const char *uname, int depth, void *data);
 extern int fadump_reserve_mem(void);
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 03563c6..ea7dfdc 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -114,6 +114,18 @@  int __init early_init_dt_scan_fw_dump(unsigned long node,
 	return 1;
 }
 
+/*
+ * If fadump is registered, check if the memory provided
+ * falls within boot memory area.
+ */
+int is_fadump_boot_memory_area(u64 addr, ulong size)
+{
+	if (!fw_dump.dump_registered)
+		return 0;
+
+	return (addr + size) > RMA_START && addr <= fw_dump.boot_memory_size;
+}
+
 int is_fadump_active(void)
 {
 	return fw_dump.dump_active;
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index e104c71..a186b8e 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -22,6 +22,7 @@ 
 #include <asm/machdep.h>
 #include <asm/prom.h>
 #include <asm/sparsemem.h>
+#include <asm/fadump.h>
 #include "pseries.h"
 
 static bool rtas_hp_event;
@@ -406,6 +407,12 @@  static bool lmb_is_removable(struct of_drconf_cell *lmb)
 	scns_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
 	phys_addr = lmb->base_addr;
 
+#ifdef CONFIG_FA_DUMP
+	/* Don't hot-remove memory that falls in fadump boot memory area */
+	if (is_fadump_boot_memory_area(phys_addr, block_sz))
+		return false;
+#endif
+
 	for (i = 0; i < scns_per_block; i++) {
 		pfn = PFN_DOWN(phys_addr);
 		if (!pfn_present(pfn))