Patchwork The filo crashes if the filo and corebootoverlap.

login
register
about
Submitter Bao, Zheng
Date 2009-11-05 01:28:27
Message ID <DD1CC71B621B004FA76856E5129D6B17032A05E7@sbjgexmb1.amd.com>
Download mbox | patch
Permalink /patch/536/
State Accepted
Headers show

Comments

Bao, Zheng - 2009-11-05 01:28:27
Ping, before we forget.
Can anyone ack or nack this?

Zheng


-----Original Message-----
From: coreboot-bounces@coreboot.org
[mailto:coreboot-bounces@coreboot.org] On Behalf Of Bao, Zheng
Sent: Tuesday, November 03, 2009 11:23 AM
To: coreboot@coreboot.org
Subject: Re: [coreboot] [PATCH] The filo crashes if the filo and
corebootoverlap.

If the coreboot and filo overlap, it will "slice off" a piece at the
beginning or end. In the beginning case, a new segment is inserted
before the current one.  The ptr will move forward and doesn't seem to
have any chance to process the "new" segment.

                ptr ---------+     move --->
                             |
                             V
        +--------+       +--------+
        |        |       |        |
        |  new   | <---> |current | <---> .....
        |        |       |        |
        +--------+       +--------+

Now we change the ptr to the previous one and restart the loop. The
new and current segment will both be processed.

      +----------------ptr      move --->
      |
      V
 +--------+        +--------+       +--------+
 |        |        |        |       |        |
 |  prev  | <--->  |  new   | <---> |current | <---> .....
 |        |        |        |       |        |
 +--------+        +--------+       +--------+

It is tested on my Family 10 board.

Zheng

Signed-off-by: Zheng Bao <zheng.bao@amd.com>


 	middle = start + seg->s_filesz;
@@ -270,6 +272,8 @@
 				new->s_dstaddr, 
 				new->s_dstaddr + new->s_filesz,
 				new->s_dstaddr + new->s_memsz);
+
+			ret = 1;
 		}
 			
 		/* Slice off a piece at the end 
@@ -319,6 +323,8 @@
 		seg->s_dstaddr, 
 		seg->s_dstaddr + seg->s_filesz, 
 		seg->s_dstaddr + seg->s_memsz);
+
+	return ret;
 }
 
 
@@ -446,7 +452,10 @@
 		
 		/* Modify the segment to load onto the bounce_buffer if
necessary.
 		 */
-		relocate_segment(bounce_buffer, ptr);
+		if (relocate_segment(bounce_buffer, ptr)) {
+			ptr = (ptr->prev)->prev;
+			continue;
+		}
 
 		printk_debug("Post relocation: addr: 0x%016lx memsz:
0x%016lx filesz: 0x%016lx\n",
 			ptr->s_dstaddr, ptr->s_memsz, ptr->s_filesz);

-----Original Message-----
From: coreboot-bounces@coreboot.org
[mailto:coreboot-bounces@coreboot.org] On Behalf Of Bao, Zheng
Sent: Monday, November 02, 2009 11:25 AM
To: Patrick Georgi
Cc: coreboot@coreboot.org
Subject: Re: [coreboot] The filo crashes if the filo and coreboot
overlap.

In relocate_segment().
If the coreboot and filo overlap, it will "slice off" a piece at the
beginning or end. A new segment is allocated. If it is inserted before
the "seg" that is being processed, is there any chance that the "new"
segment will be processed? I am confused about it. On my fam 10 board,
it seems that the "new" segment was not processed and an error happens
when the code jumps to filo which is actually middle of nowhere.


Zheng

-----Original Message-----
From: coreboot-bounces+zheng.bao=amd.com@coreboot.org
[mailto:coreboot-bounces+zheng.bao=amd.com@coreboot.org] On Behalf Of
Patrick Georgi
Sent: Sunday, November 01, 2009 12:13 AM
To: Zheng Bao
Cc: coreboot@coreboot.org
Subject: Re: [coreboot] The filo crashes if the filo and coreboot
overlap.

Am Samstag, den 31.10.2009, 15:43 +0000 schrieb Zheng Bao:
> The filo crashes if the filo and coreboot overlap.
> Since the CBFS is the must-have feature, my family 10
>  board crashes when it jumps to filo. I am trying to
>  find out why. I need help.
> Based on current code, the AMD Family 10 will cause the filo
> and coreboot overlap in RAM. The overlaps_coreboot() in selfboot.c
> will return 1. But I am not sure if it will make the system
> crashes.
What revision is that? There was an issue like that but I fixed it
several weeks ago.

> If anybody explains briefly what happens if they
> overlap.
When coreboot and payload overlap, coreboot uses a bounce buffer. The
bounce buffer is twice the size of coreboot. The first half is for the
part of the payload that overlaps coreboot, the other half is for
coreboot itself.

The SELF loader loads data that would overlap coreboot to the bounce
buffer, and jumps into jmp_to_elf_entry when it's done with loading.
The jmp_to_elf_entry function copies coreboot to the upper half of the
bounce buffer, and jumps in there, so the code is out of the way.

Then it copies the lower half to the coreboot area and jumps to the
entry point.

There are some complications to that because of the decompression
routine, so the code is not as nice as it should be. But I specifically
tested your scenario (payload from 1mb to 2.3mb or so, coreboot starting
at 2mb)

> The coreboot information:
> CONFIG_RAMBASE=0x00200000
Try changing that to 0x100000.


Patrick
Stefan Reinauer - 2009-11-05 09:15:25
Bao, Zheng wrote:
> Ping, before we forget.
> Can anyone ack or nack this?
>
> Zheng
>
>
> -----Original Message-----
> From: coreboot-bounces@coreboot.org
> [mailto:coreboot-bounces@coreboot.org] On Behalf Of Bao, Zheng
> Sent: Tuesday, November 03, 2009 11:23 AM
> To: coreboot@coreboot.org
> Subject: Re: [coreboot] [PATCH] The filo crashes if the filo and
> corebootoverlap.
>
> If the coreboot and filo overlap, it will "slice off" a piece at the
> beginning or end. In the beginning case, a new segment is inserted
> before the current one.  The ptr will move forward and doesn't seem to
> have any chance to process the "new" segment.
>
>                 ptr ---------+     move --->
>                              |
>                              V
>         +--------+       +--------+
>         |        |       |        |
>         |  new   | <---> |current | <---> .....
>         |        |       |        |
>         +--------+       +--------+
>
> Now we change the ptr to the previous one and restart the loop. The
> new and current segment will both be processed.
>
>       +----------------ptr      move --->
>       |
>       V
>  +--------+        +--------+       +--------+
>  |        |        |        |       |        |
>  |  prev  | <--->  |  new   | <---> |current | <---> .....
>  |        |        |        |       |        |
>  +--------+        +--------+       +--------+
>
> It is tested on my Family 10 board.
>
>   

Very nice explanation... :-)

Acked-by: Stefan Reinauer <stepan@coresystems.de>





> Zheng
>
> Signed-off-by: Zheng Bao <zheng.bao@amd.com>
>
>
> Index: src/boot/selfboot.c
> ===================================================================
> --- src/boot/selfboot.c	(revision 4892)
> +++ src/boot/selfboot.c	(working copy)
> @@ -211,19 +211,21 @@
>  	return !((end <= lb_start) || (start >= lb_end));
>  }
>  
> -static void relocate_segment(unsigned long buffer, struct segment *seg)
> +static int relocate_segment(unsigned long buffer, struct segment *seg)
>  {
>  	/* Modify all segments that want to load onto coreboot
>  	 * to load onto the bounce buffer instead.
>  	 */
> -	unsigned long start, middle, end;
> +	/* ret:  1 : A new segment is inserted before the seg.
> +	 *       0 : A new segment is inserted after the seg, or no new
> one. */
> +	unsigned long start, middle, end, ret = 0;
>  
>  	printk_spew("lb: [0x%016lx, 0x%016lx)\n", 
>  		lb_start, lb_end);
>  
>  	/* I don't conflict with coreboot so get out of here */
>  	if (!overlaps_coreboot(seg))
> -		return;
> +		return 0;
>  
>  	start = seg->s_dstaddr;
>  	middle = start + seg->s_filesz;
> @@ -270,6 +272,8 @@
>  				new->s_dstaddr, 
>  				new->s_dstaddr + new->s_filesz,
>  				new->s_dstaddr + new->s_memsz);
> +
> +			ret = 1;
>  		}
>  			
>  		/* Slice off a piece at the end 
> @@ -319,6 +323,8 @@
>  		seg->s_dstaddr, 
>  		seg->s_dstaddr + seg->s_filesz, 
>  		seg->s_dstaddr + seg->s_memsz);
> +
> +	return ret;
>  }
>  
>  
> @@ -446,7 +452,10 @@
>  		
>  		/* Modify the segment to load onto the bounce_buffer if
> necessary.
>  		 */
> -		relocate_segment(bounce_buffer, ptr);
> +		if (relocate_segment(bounce_buffer, ptr)) {
> +			ptr = (ptr->prev)->prev;
> +			continue;
> +		}
>  
>  		printk_debug("Post relocation: addr: 0x%016lx memsz:
> 0x%016lx filesz: 0x%016lx\n",
>  			ptr->s_dstaddr, ptr->s_memsz, ptr->s_filesz);
>
> -----Original Message-----
> From: coreboot-bounces@coreboot.org
> [mailto:coreboot-bounces@coreboot.org] On Behalf Of Bao, Zheng
> Sent: Monday, November 02, 2009 11:25 AM
> To: Patrick Georgi
> Cc: coreboot@coreboot.org
> Subject: Re: [coreboot] The filo crashes if the filo and coreboot
> overlap.
>
> In relocate_segment().
> If the coreboot and filo overlap, it will "slice off" a piece at the
> beginning or end. A new segment is allocated. If it is inserted before
> the "seg" that is being processed, is there any chance that the "new"
> segment will be processed? I am confused about it. On my fam 10 board,
> it seems that the "new" segment was not processed and an error happens
> when the code jumps to filo which is actually middle of nowhere.
>
>
> Zheng
>
> -----Original Message-----
> From: coreboot-bounces+zheng.bao=amd.com@coreboot.org
> [mailto:coreboot-bounces+zheng.bao=amd.com@coreboot.org] On Behalf Of
> Patrick Georgi
> Sent: Sunday, November 01, 2009 12:13 AM
> To: Zheng Bao
> Cc: coreboot@coreboot.org
> Subject: Re: [coreboot] The filo crashes if the filo and coreboot
> overlap.
>
> Am Samstag, den 31.10.2009, 15:43 +0000 schrieb Zheng Bao:
>   
>> The filo crashes if the filo and coreboot overlap.
>> Since the CBFS is the must-have feature, my family 10
>>  board crashes when it jumps to filo. I am trying to
>>  find out why. I need help.
>> Based on current code, the AMD Family 10 will cause the filo
>> and coreboot overlap in RAM. The overlaps_coreboot() in selfboot.c
>> will return 1. But I am not sure if it will make the system
>> crashes.
>>     
> What revision is that? There was an issue like that but I fixed it
> several weeks ago.
>
>   
>> If anybody explains briefly what happens if they
>> overlap.
>>     
> When coreboot and payload overlap, coreboot uses a bounce buffer. The
> bounce buffer is twice the size of coreboot. The first half is for the
> part of the payload that overlaps coreboot, the other half is for
> coreboot itself.
>
> The SELF loader loads data that would overlap coreboot to the bounce
> buffer, and jumps into jmp_to_elf_entry when it's done with loading.
> The jmp_to_elf_entry function copies coreboot to the upper half of the
> bounce buffer, and jumps in there, so the code is out of the way.
>
> Then it copies the lower half to the coreboot area and jumps to the
> entry point.
>
> There are some complications to that because of the decompression
> routine, so the code is not as nice as it should be. But I specifically
> tested your scenario (payload from 1mb to 2.3mb or so, coreboot starting
> at 2mb)
>
>   
>> The coreboot information:
>> CONFIG_RAMBASE=0x00200000
>>     
> Try changing that to 0x100000.
>
>
> Patrick
>
>
>
Bao, Zheng - 2009-11-05 10:04:22
r4912.
Delete some trailing whitespace.

-----Original Message-----
From: Stefan Reinauer [mailto:stepan@coresystems.de] 
Sent: Thursday, November 05, 2009 5:15 PM
To: Bao, Zheng
Cc: coreboot@coreboot.org
Subject: Re: [coreboot] [PATCH] The filo crashes if the filo and corebootoverlap.

Bao, Zheng wrote:
> Ping, before we forget.
> Can anyone ack or nack this?
>
> Zheng
>
>
> -----Original Message-----
> From: coreboot-bounces@coreboot.org
> [mailto:coreboot-bounces@coreboot.org] On Behalf Of Bao, Zheng
> Sent: Tuesday, November 03, 2009 11:23 AM
> To: coreboot@coreboot.org
> Subject: Re: [coreboot] [PATCH] The filo crashes if the filo and
> corebootoverlap.
>
> If the coreboot and filo overlap, it will "slice off" a piece at the
> beginning or end. In the beginning case, a new segment is inserted
> before the current one.  The ptr will move forward and doesn't seem to
> have any chance to process the "new" segment.
>
>                 ptr ---------+     move --->
>                              |
>                              V
>         +--------+       +--------+
>         |        |       |        |
>         |  new   | <---> |current | <---> .....
>         |        |       |        |
>         +--------+       +--------+
>
> Now we change the ptr to the previous one and restart the loop. The
> new and current segment will both be processed.
>
>       +----------------ptr      move --->
>       |
>       V
>  +--------+        +--------+       +--------+
>  |        |        |        |       |        |
>  |  prev  | <--->  |  new   | <---> |current | <---> .....
>  |        |        |        |       |        |
>  +--------+        +--------+       +--------+
>
> It is tested on my Family 10 board.
>
>   

Very nice explanation... :-)

Acked-by: Stefan Reinauer <stepan@coresystems.de>





> Zheng
>
> Signed-off-by: Zheng Bao <zheng.bao@amd.com>
>
>
> Index: src/boot/selfboot.c
> ===================================================================
> --- src/boot/selfboot.c	(revision 4892)
> +++ src/boot/selfboot.c	(working copy)
> @@ -211,19 +211,21 @@
>  	return !((end <= lb_start) || (start >= lb_end));
>  }
>  
> -static void relocate_segment(unsigned long buffer, struct segment *seg)
> +static int relocate_segment(unsigned long buffer, struct segment *seg)
>  {
>  	/* Modify all segments that want to load onto coreboot
>  	 * to load onto the bounce buffer instead.
>  	 */
> -	unsigned long start, middle, end;
> +	/* ret:  1 : A new segment is inserted before the seg.
> +	 *       0 : A new segment is inserted after the seg, or no new
> one. */
> +	unsigned long start, middle, end, ret = 0;
>  
>  	printk_spew("lb: [0x%016lx, 0x%016lx)\n", 
>  		lb_start, lb_end);
>  
>  	/* I don't conflict with coreboot so get out of here */
>  	if (!overlaps_coreboot(seg))
> -		return;
> +		return 0;
>  
>  	start = seg->s_dstaddr;
>  	middle = start + seg->s_filesz;
> @@ -270,6 +272,8 @@
>  				new->s_dstaddr, 
>  				new->s_dstaddr + new->s_filesz,
>  				new->s_dstaddr + new->s_memsz);
> +
> +			ret = 1;
>  		}
>  			
>  		/* Slice off a piece at the end 
> @@ -319,6 +323,8 @@
>  		seg->s_dstaddr, 
>  		seg->s_dstaddr + seg->s_filesz, 
>  		seg->s_dstaddr + seg->s_memsz);
> +
> +	return ret;
>  }
>  
>  
> @@ -446,7 +452,10 @@
>  		
>  		/* Modify the segment to load onto the bounce_buffer if
> necessary.
>  		 */
> -		relocate_segment(bounce_buffer, ptr);
> +		if (relocate_segment(bounce_buffer, ptr)) {
> +			ptr = (ptr->prev)->prev;
> +			continue;
> +		}
>  
>  		printk_debug("Post relocation: addr: 0x%016lx memsz:
> 0x%016lx filesz: 0x%016lx\n",
>  			ptr->s_dstaddr, ptr->s_memsz, ptr->s_filesz);
>
> -----Original Message-----
> From: coreboot-bounces@coreboot.org
> [mailto:coreboot-bounces@coreboot.org] On Behalf Of Bao, Zheng
> Sent: Monday, November 02, 2009 11:25 AM
> To: Patrick Georgi
> Cc: coreboot@coreboot.org
> Subject: Re: [coreboot] The filo crashes if the filo and coreboot
> overlap.
>
> In relocate_segment().
> If the coreboot and filo overlap, it will "slice off" a piece at the
> beginning or end. A new segment is allocated. If it is inserted before
> the "seg" that is being processed, is there any chance that the "new"
> segment will be processed? I am confused about it. On my fam 10 board,
> it seems that the "new" segment was not processed and an error happens
> when the code jumps to filo which is actually middle of nowhere.
>
>
> Zheng
>
> -----Original Message-----
> From: coreboot-bounces+zheng.bao=amd.com@coreboot.org
> [mailto:coreboot-bounces+zheng.bao=amd.com@coreboot.org] On Behalf Of
> Patrick Georgi
> Sent: Sunday, November 01, 2009 12:13 AM
> To: Zheng Bao
> Cc: coreboot@coreboot.org
> Subject: Re: [coreboot] The filo crashes if the filo and coreboot
> overlap.
>
> Am Samstag, den 31.10.2009, 15:43 +0000 schrieb Zheng Bao:
>   
>> The filo crashes if the filo and coreboot overlap.
>> Since the CBFS is the must-have feature, my family 10
>>  board crashes when it jumps to filo. I am trying to
>>  find out why. I need help.
>> Based on current code, the AMD Family 10 will cause the filo
>> and coreboot overlap in RAM. The overlaps_coreboot() in selfboot.c
>> will return 1. But I am not sure if it will make the system
>> crashes.
>>     
> What revision is that? There was an issue like that but I fixed it
> several weeks ago.
>
>   
>> If anybody explains briefly what happens if they
>> overlap.
>>     
> When coreboot and payload overlap, coreboot uses a bounce buffer. The
> bounce buffer is twice the size of coreboot. The first half is for the
> part of the payload that overlaps coreboot, the other half is for
> coreboot itself.
>
> The SELF loader loads data that would overlap coreboot to the bounce
> buffer, and jumps into jmp_to_elf_entry when it's done with loading.
> The jmp_to_elf_entry function copies coreboot to the upper half of the
> bounce buffer, and jumps in there, so the code is out of the way.
>
> Then it copies the lower half to the coreboot area and jumps to the
> entry point.
>
> There are some complications to that because of the decompression
> routine, so the code is not as nice as it should be. But I specifically
> tested your scenario (payload from 1mb to 2.3mb or so, coreboot starting
> at 2mb)
>
>   
>> The coreboot information:
>> CONFIG_RAMBASE=0x00200000
>>     
> Try changing that to 0x100000.
>
>
> Patrick
>
>
>

Patch

Index: src/boot/selfboot.c
===================================================================
--- src/boot/selfboot.c	(revision 4892)
+++ src/boot/selfboot.c	(working copy)
@@ -211,19 +211,21 @@ 
 	return !((end <= lb_start) || (start >= lb_end));
 }
 
-static void relocate_segment(unsigned long buffer, struct segment *seg)
+static int relocate_segment(unsigned long buffer, struct segment *seg)
 {
 	/* Modify all segments that want to load onto coreboot
 	 * to load onto the bounce buffer instead.
 	 */
-	unsigned long start, middle, end;
+	/* ret:  1 : A new segment is inserted before the seg.
+	 *       0 : A new segment is inserted after the seg, or no new
one. */
+	unsigned long start, middle, end, ret = 0;
 
 	printk_spew("lb: [0x%016lx, 0x%016lx)\n", 
 		lb_start, lb_end);
 
 	/* I don't conflict with coreboot so get out of here */
 	if (!overlaps_coreboot(seg))
-		return;
+		return 0;
 
 	start = seg->s_dstaddr;