NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/52252: uvm_km_check_empty panic when loading any module



The following reply was made to PR kern/52252; it has been noted by GNATS.

From: Anthony Mallet <tho%netbsd.org@localhost>
To: gnats-bugs%NetBSD.org@localhost,
    kern-bug-people%netbsd.org@localhost
Cc: Maxime Villard <max%m00nbsd.net@localhost>
Subject: Re: kern/52252: uvm_km_check_empty panic when loading any module
Date: Wed, 31 May 2017 18:35:45 +0200

 Here is an updated patch, replacing the previous one that had some
 flaws.
 
 The patch adds a test on esym and eblob, to check that they are above
 __kernel_end. This is required because the .ALIGN(__LARGE_PAGE_SIZE)
 directive in kern.ldscript does not actually increase the bss section
 size. So the bootloader is free to load symbols/module right after the
 bss section, and thus possibly before __kernel_end.
 
 In the general case, we end up with something like this:
 
  +------+--------+------+-----+--------+---------------------+----------
  | TEXT | RODATA | DATA | BSS | [SYMS] | [PRELOADED MODULES] | L4 ->
  +------+--------+------+-----+--------+---------------------+----------
                               ^        ^           ^         ^
                              bss_end  esym         ^       eblob
                                               __kernel_end
                                           (== bss_end + large page alignment)
 
 The goal is to take the max(__kernel_end, esym, eblob) to find the
 start of the bootstrap tables.
 
 Only the part until __kernel_end may be mapped with large pages, so
 potentially [SYMS] and [PRELOADED MODULES] may not be on large
 pages. I guess it is not a big deal, but to fix this the __kernel_end
 symbol should be changed to a variable so that it can be modified at
 run time.
 
 In the patch, instead of mapping separately the pages from (data+bss)
 and (syms + modules), I merged the two statements. I think it makes it
 clearer that __kernel_end is usually in the middle of (syms + modules).
 
 I tested with different bootloader (grub knetbsd and netbsd boot) and
 it's now fine for me in all situations.
 
 
 Index: sys/arch/amd64/amd64/locore.S
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/amd64/amd64/locore.S,v
 retrieving revision 1.123
 diff -u -r1.123 locore.S
 --- sys/arch/amd64/amd64/locore.S	25 Mar 2017 15:07:21 -0000	1.123
 +++ sys/arch/amd64/amd64/locore.S	31 May 2017 16:05:09 -0000
 @@ -621,6 +621,8 @@
  	testl	%eax,%eax
  	jz	1f
  	subl	$KERNBASE_LO,%eax	/* XXX */
 +	cmpl	%edi,%eax
 +	jle	1f			/* esym <= __kernel_end */
  	movl	%eax,%edi
  1:
  #endif
 @@ -629,6 +631,8 @@
  	testl	%eax,%eax
  	jz	1f
  	subl	$KERNBASE_LO,%eax	/* XXX */
 +	cmpl	%edi,%eax
 +	jle	1f			/* eblob <= __kernel_end */
  	movl	%eax,%edi
  1:
 
 @@ -682,16 +686,8 @@
  	orl	$(PG_V|PG_KR),%eax
  	fillkpt_nox
 
 -	/* Map the kernel data+bss RW. */
 +	/* Map the kernel data+bss+[SYMS]+[PRELOADED MODULES] RW. */
  	movl	$RELOC(__data_start),%eax
 -	movl	$RELOC(__kernel_end),%ecx
 -	subl	%eax,%ecx
 -	shrl	$PGSHIFT,%ecx
 -	orl	$(PG_V|PG_KW),%eax
 -	fillkpt_nox
 -
 -	/* Map [SYMS]+[PRELOADED MODULES] RW. */
 -	movl	$RELOC(__kernel_end),%eax
  	movl	%esi,%ecx		/* start of BOOTSTRAP TABLES */
  	subl	%eax,%ecx
  	shrl	$PGSHIFT,%ecx
 



Home | Main Index | Thread Index | Old Index