All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v3] efi_loader: Reserve unaccessible memory
@ 2018-11-30 20:24 Alexander Graf
  2018-11-30 20:31 ` Heinrich Schuchardt
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Alexander Graf @ 2018-11-30 20:24 UTC (permalink / raw)
  To: u-boot

On some systems, not all RAM may be usable within U-Boot. Maybe the
memory maps are incomplete, maybe it's used as workaround for broken
DMA. But whatever the reason may be, a platform can say that it does
not wish to have its RAM accessed above a certain address by defining
board_get_usable_ram_top().

In the efi_loader world, we ignored that hint, mostly because very few
boards actually have real restrictions around this.

So let's honor the board's wish to not access high addresses during
boot time. The best way to do so is by indicating the respective pages
as "allocated by firmware". That way, Operating Systems will still
use the pages after boot, but before boot no allocation will use them.

Reported-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Stephen Warren <swarren@nvidia.com>

---

v1 -> v2:

  - Reserve banks that start above ram_top
  - Improve inline comments
  - Fix 32bit target with ram_top = 0 (>=4G)

v2 -> v3:

  - Fix 32bit target with ram_top = 0 for real (map to 1<<32
    rather than 1<<32-1)
---
 include/common.h            | 11 +++++++++++
 lib/efi_loader/efi_memory.c | 32 +++++++++++++++++++++++++++++---
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/include/common.h b/include/common.h
index 3f69943887..8f295c2f30 100644
--- a/include/common.h
+++ b/include/common.h
@@ -106,6 +106,17 @@ int mdm_init(void);
 void board_show_dram(phys_size_t size);
 
 /**
+ * Get the uppermost pointer that is valid to access
+ *
+ * Some systems may not map all of their address space. This function allows
+ * boards to indicate what their highest support pointer value is for DRAM
+ * access.
+ *
+ * @param total_size	Size of U-Boot (unused?)
+ */
+ulong board_get_usable_ram_top(ulong total_size);
+
+/**
  * arch_fixup_fdt() - Write arch-specific information to fdt
  *
  * Defined in arch/$(ARCH)/lib/bootm-fdt.c
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index f225a9028c..73bfbb65c4 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -551,8 +551,13 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
 
 __weak void efi_add_known_memory(void)
 {
+	u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK;
 	int i;
 
+	/* Fix for 32bit targets with ram_top@4G */
+	if (!ram_top)
+		ram_top = 0x100000000ULL;
+
 	/* Add RAM */
 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 		u64 ram_end, ram_start, pages;
@@ -564,11 +569,32 @@ __weak void efi_add_known_memory(void)
 		ram_end &= ~EFI_PAGE_MASK;
 		ram_start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
 
-		if (ram_end > ram_start) {
-			pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
+		if (ram_end <= ram_start) {
+			/* Invalid mapping, keep going. */
+			continue;
+		}
+
+		pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
 
+		efi_add_memory_map(ram_start, pages,
+				   EFI_CONVENTIONAL_MEMORY, false);
+
+		/*
+		 * Boards may indicate to the U-Boot memory core that they
+		 * can not support memory above ram_top. Let's honor this
+		 * in the efi_loader subsystem too by declaring any memory
+		 * above ram_top as "already occupied by firmware".
+		 */
+		if (ram_top < ram_start) {
+			/* ram_top is before this region, reserve all */
 			efi_add_memory_map(ram_start, pages,
-					   EFI_CONVENTIONAL_MEMORY, false);
+					   EFI_BOOT_SERVICES_DATA, true);
+		} else if ((ram_top >= ram_start) && (ram_top < ram_end)) {
+			/* ram_top is inside this region, reserve parts */
+			pages = (ram_end - ram_top) >> EFI_PAGE_SHIFT;
+
+			efi_add_memory_map(ram_top, pages,
+					   EFI_BOOT_SERVICES_DATA, true);
 		}
 	}
 }
-- 
2.12.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [U-Boot] [PATCH v3] efi_loader: Reserve unaccessible memory
  2018-11-30 20:24 [U-Boot] [PATCH v3] efi_loader: Reserve unaccessible memory Alexander Graf
@ 2018-11-30 20:31 ` Heinrich Schuchardt
  2018-11-30 23:21 ` [U-Boot] [U-Boot,v3] " Alexander Graf
  2018-12-02 15:41 ` [U-Boot] [PATCH v3] " Baruch Siach
  2 siblings, 0 replies; 4+ messages in thread
From: Heinrich Schuchardt @ 2018-11-30 20:31 UTC (permalink / raw)
  To: u-boot

On 11/30/18 9:24 PM, Alexander Graf wrote:
> On some systems, not all RAM may be usable within U-Boot. Maybe the
> memory maps are incomplete, maybe it's used as workaround for broken
> DMA. But whatever the reason may be, a platform can say that it does
> not wish to have its RAM accessed above a certain address by defining
> board_get_usable_ram_top().
> 
> In the efi_loader world, we ignored that hint, mostly because very few
> boards actually have real restrictions around this.
> 
> So let's honor the board's wish to not access high addresses during
> boot time. The best way to do so is by indicating the respective pages
> as "allocated by firmware". That way, Operating Systems will still
> use the pages after boot, but before boot no allocation will use them.
> 
> Reported-by: Baruch Siach <baruch@tkos.co.il>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> Reviewed-by: Stephen Warren <swarren@nvidia.com>

Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> 
> ---
> 
> v1 -> v2:
> 
>   - Reserve banks that start above ram_top
>   - Improve inline comments
>   - Fix 32bit target with ram_top = 0 (>=4G)
> 
> v2 -> v3:
> 
>   - Fix 32bit target with ram_top = 0 for real (map to 1<<32
>     rather than 1<<32-1)
> ---
>  include/common.h            | 11 +++++++++++
>  lib/efi_loader/efi_memory.c | 32 +++++++++++++++++++++++++++++---
>  2 files changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/include/common.h b/include/common.h
> index 3f69943887..8f295c2f30 100644
> --- a/include/common.h
> +++ b/include/common.h
> @@ -106,6 +106,17 @@ int mdm_init(void);
>  void board_show_dram(phys_size_t size);
>  
>  /**
> + * Get the uppermost pointer that is valid to access
> + *
> + * Some systems may not map all of their address space. This function allows
> + * boards to indicate what their highest support pointer value is for DRAM
> + * access.
> + *
> + * @param total_size	Size of U-Boot (unused?)
> + */
> +ulong board_get_usable_ram_top(ulong total_size);
> +
> +/**
>   * arch_fixup_fdt() - Write arch-specific information to fdt
>   *
>   * Defined in arch/$(ARCH)/lib/bootm-fdt.c
> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
> index f225a9028c..73bfbb65c4 100644
> --- a/lib/efi_loader/efi_memory.c
> +++ b/lib/efi_loader/efi_memory.c
> @@ -551,8 +551,13 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
>  
>  __weak void efi_add_known_memory(void)
>  {
> +	u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK;
>  	int i;
>  
> +	/* Fix for 32bit targets with ram_top at 4G */
> +	if (!ram_top)
> +		ram_top = 0x100000000ULL;
> +
>  	/* Add RAM */
>  	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
>  		u64 ram_end, ram_start, pages;
> @@ -564,11 +569,32 @@ __weak void efi_add_known_memory(void)
>  		ram_end &= ~EFI_PAGE_MASK;
>  		ram_start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
>  
> -		if (ram_end > ram_start) {
> -			pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
> +		if (ram_end <= ram_start) {
> +			/* Invalid mapping, keep going. */
> +			continue;
> +		}
> +
> +		pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
>  
> +		efi_add_memory_map(ram_start, pages,
> +				   EFI_CONVENTIONAL_MEMORY, false);
> +
> +		/*
> +		 * Boards may indicate to the U-Boot memory core that they
> +		 * can not support memory above ram_top. Let's honor this
> +		 * in the efi_loader subsystem too by declaring any memory
> +		 * above ram_top as "already occupied by firmware".
> +		 */
> +		if (ram_top < ram_start) {
> +			/* ram_top is before this region, reserve all */
>  			efi_add_memory_map(ram_start, pages,
> -					   EFI_CONVENTIONAL_MEMORY, false);
> +					   EFI_BOOT_SERVICES_DATA, true);
> +		} else if ((ram_top >= ram_start) && (ram_top < ram_end)) {
> +			/* ram_top is inside this region, reserve parts */
> +			pages = (ram_end - ram_top) >> EFI_PAGE_SHIFT;
> +
> +			efi_add_memory_map(ram_top, pages,
> +					   EFI_BOOT_SERVICES_DATA, true);
>  		}
>  	}
>  }
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [U-Boot] [U-Boot,v3] efi_loader: Reserve unaccessible memory
  2018-11-30 20:24 [U-Boot] [PATCH v3] efi_loader: Reserve unaccessible memory Alexander Graf
  2018-11-30 20:31 ` Heinrich Schuchardt
@ 2018-11-30 23:21 ` Alexander Graf
  2018-12-02 15:41 ` [U-Boot] [PATCH v3] " Baruch Siach
  2 siblings, 0 replies; 4+ messages in thread
From: Alexander Graf @ 2018-11-30 23:21 UTC (permalink / raw)
  To: u-boot

> On some systems, not all RAM may be usable within U-Boot. Maybe the
> memory maps are incomplete, maybe it's used as workaround for broken
> DMA. But whatever the reason may be, a platform can say that it does
> not wish to have its RAM accessed above a certain address by defining
> board_get_usable_ram_top().
> 
> In the efi_loader world, we ignored that hint, mostly because very few
> boards actually have real restrictions around this.
> 
> So let's honor the board's wish to not access high addresses during
> boot time. The best way to do so is by indicating the respective pages
> as "allocated by firmware". That way, Operating Systems will still
> use the pages after boot, but before boot no allocation will use them.
> 
> Reported-by: Baruch Siach <baruch@tkos.co.il>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> Reviewed-by: Stephen Warren <swarren@nvidia.com>
> Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>

Thanks, applied to efi-next

Alex

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [U-Boot] [PATCH v3] efi_loader: Reserve unaccessible memory
  2018-11-30 20:24 [U-Boot] [PATCH v3] efi_loader: Reserve unaccessible memory Alexander Graf
  2018-11-30 20:31 ` Heinrich Schuchardt
  2018-11-30 23:21 ` [U-Boot] [U-Boot,v3] " Alexander Graf
@ 2018-12-02 15:41 ` Baruch Siach
  2 siblings, 0 replies; 4+ messages in thread
From: Baruch Siach @ 2018-12-02 15:41 UTC (permalink / raw)
  To: u-boot

Hi Alexander,

Alexander Graf writes:

> On some systems, not all RAM may be usable within U-Boot. Maybe the
> memory maps are incomplete, maybe it's used as workaround for broken
> DMA. But whatever the reason may be, a platform can say that it does
> not wish to have its RAM accessed above a certain address by defining
> board_get_usable_ram_top().
>
> In the efi_loader world, we ignored that hint, mostly because very few
> boards actually have real restrictions around this.
>
> So let's honor the board's wish to not access high addresses during
> boot time. The best way to do so is by indicating the respective pages
> as "allocated by firmware". That way, Operating Systems will still
> use the pages after boot, but before boot no allocation will use them.
>
> Reported-by: Baruch Siach <baruch@tkos.co.il>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> Reviewed-by: Stephen Warren <swarren@nvidia.com>

This fixes the TFTP crash on a 16GB RAM Armada 8040 system.

Tested-by: Baruch Siach <baruch@tkos.co.il>

Thanks,
baruch

>
> ---
>
> v1 -> v2:
>
>   - Reserve banks that start above ram_top
>   - Improve inline comments
>   - Fix 32bit target with ram_top = 0 (>=4G)
>
> v2 -> v3:
>
>   - Fix 32bit target with ram_top = 0 for real (map to 1<<32
>     rather than 1<<32-1)
> ---
>  include/common.h            | 11 +++++++++++
>  lib/efi_loader/efi_memory.c | 32 +++++++++++++++++++++++++++++---
>  2 files changed, 40 insertions(+), 3 deletions(-)
>
> diff --git a/include/common.h b/include/common.h
> index 3f69943887..8f295c2f30 100644
> --- a/include/common.h
> +++ b/include/common.h
> @@ -106,6 +106,17 @@ int mdm_init(void);
>  void board_show_dram(phys_size_t size);
>  
>  /**
> + * Get the uppermost pointer that is valid to access
> + *
> + * Some systems may not map all of their address space. This function allows
> + * boards to indicate what their highest support pointer value is for DRAM
> + * access.
> + *
> + * @param total_size	Size of U-Boot (unused?)
> + */
> +ulong board_get_usable_ram_top(ulong total_size);
> +
> +/**
>   * arch_fixup_fdt() - Write arch-specific information to fdt
>   *
>   * Defined in arch/$(ARCH)/lib/bootm-fdt.c
> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
> index f225a9028c..73bfbb65c4 100644
> --- a/lib/efi_loader/efi_memory.c
> +++ b/lib/efi_loader/efi_memory.c
> @@ -551,8 +551,13 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
>  
>  __weak void efi_add_known_memory(void)
>  {
> +	u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK;
>  	int i;
>  
> +	/* Fix for 32bit targets with ram_top at 4G */
> +	if (!ram_top)
> +		ram_top = 0x100000000ULL;
> +
>  	/* Add RAM */
>  	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
>  		u64 ram_end, ram_start, pages;
> @@ -564,11 +569,32 @@ __weak void efi_add_known_memory(void)
>  		ram_end &= ~EFI_PAGE_MASK;
>  		ram_start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
>  
> -		if (ram_end > ram_start) {
> -			pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
> +		if (ram_end <= ram_start) {
> +			/* Invalid mapping, keep going. */
> +			continue;
> +		}
> +
> +		pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
>  
> +		efi_add_memory_map(ram_start, pages,
> +				   EFI_CONVENTIONAL_MEMORY, false);
> +
> +		/*
> +		 * Boards may indicate to the U-Boot memory core that they
> +		 * can not support memory above ram_top. Let's honor this
> +		 * in the efi_loader subsystem too by declaring any memory
> +		 * above ram_top as "already occupied by firmware".
> +		 */
> +		if (ram_top < ram_start) {
> +			/* ram_top is before this region, reserve all */
>  			efi_add_memory_map(ram_start, pages,
> -					   EFI_CONVENTIONAL_MEMORY, false);
> +					   EFI_BOOT_SERVICES_DATA, true);
> +		} else if ((ram_top >= ram_start) && (ram_top < ram_end)) {
> +			/* ram_top is inside this region, reserve parts */
> +			pages = (ram_end - ram_top) >> EFI_PAGE_SHIFT;
> +
> +			efi_add_memory_map(ram_top, pages,
> +					   EFI_BOOT_SERVICES_DATA, true);
>  		}
>  	}
>  }


-- 
     http://baruch.siach.name/blog/                  ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-12-02 15:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-30 20:24 [U-Boot] [PATCH v3] efi_loader: Reserve unaccessible memory Alexander Graf
2018-11-30 20:31 ` Heinrich Schuchardt
2018-11-30 23:21 ` [U-Boot] [U-Boot,v3] " Alexander Graf
2018-12-02 15:41 ` [U-Boot] [PATCH v3] " Baruch Siach

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.