Skip to contentSkip to conversation

x86, boot, 64bit: Add support for loading ramdisk and bzImage high

PATCH Superseded Yinghai Lu 3 participants 26 messages Nov 16, 2012 – Nov 20, 2012

Subsystems (2)

v1 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

Yinghai Lu

author
#0 lore raw

cover x86, boot, 64bit: Add support for loading ramdisk and bzImage high

Now we have limit kdump reseved under 896M, because kexec has the limitation. and also bzImage need to stay under 4g.

To make kexec/kdump could use range above 4g, we need to make bzImage and ramdisk could be loaded above 4g.
During booting bzImage will be unpacked on same postion and stay high.

The patches add field in boot header to
1. get info about ramdisk position info above 4g from bootloader/kexec
2. set code64_start_offset in header for bzImage and bootloader/kexec load could check that to decide if need to put bzImage high.

This patches is tested with kexec tools with local changes, will send kexec tools change to kexec list later.

could be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-x86-boot

and it is on top of for-x86-mm

Thanks

Yinghai

Yinghai Lu (9):
x86, boot: Move lldt/ltr out of 64bit only path
x86: Add macro for 64bit entry for bzImage
x86, 64bit: set extra ident page table for whole kernel range x86, 64bit: add support for loading kernel above 512G
x86: Merge early_reserve_initrd for 32bit and 64bit
x86: add get_ramdisk_image/size
x86, boot: add field to support load bzImage and ramdisk high
x86: ramdisk info print with high bits.
x86: remove 1024g limitation for kexec buffer on 64bit

 Documentation/x86/boot.txt         |    4 ++
 arch/x86/boot/compressed/head_64.S |   11 ++++--
 arch/x86/boot/header.S             |   11 ++++++-
 arch/x86/include/asm/boot.h        |    2 +
 arch/x86/include/asm/bootparam.h   |    3 ++
 arch/x86/include/asm/kexec.h       |    6 ++--
 arch/x86/kernel/head32.c           |   11 ------
 arch/x86/kernel/head64.c           |   11 ------
 arch/x86/kernel/head_64.S          |   45 ++++++++++++++++++++++-----
 arch/x86/kernel/setup.c            |   61 +++++++++++++++++++++++++++--------
 10 files changed, 113 insertions(+), 52 deletions(-)
Signature · 1 line
1.7.7
author
#1 lore raw

PATCH 1/9 x86, boot: Move lldt/ltr out of 64bit only path

commit 08da5a2ca

x86_64: Early segment setup for VT

add lldt/ltr to clean more segments.

but those code are put in code64, and it is using gdt that is only loaded from code32 path.

that breaks booting with 64bit bootloader that does not go that code32 path, because they have different gdt.

Move those lines into code32 after their gdt is loaded.

Also it push down startup_64 to 0x208.

Cc Zachary Amsden <[email protected]>
Cc Matt Fleming <[email protected]>
---
 arch/x86/boot/compressed/head_64.S |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
arch/x86/boot/compressed/head_64.S +7 -4
index 2c4b171..4c8af67 100644
@@ -154,6 +154,12 @@ ENTRY(startup_32)
 	btsl	$_EFER_LME, %eax
 	wrmsr
 
+	/* After gdt is loaded */
+	xorl	%eax, %eax
+	lldt	%ax
+	movl    $0x20, %eax
+	ltr	%ax
+
 	/*
 	 * Setup for the jump to 64bit mode
 	 *
@@ -191,7 +197,7 @@ no_longmode:
 	 * it may change in the future.
 	 */
 	.code64
-	.org 0x200
+	.org 0x208
 ENTRY(startup_64)
 	/*
 	 * We come here either from startup_32 or directly from a
@@ -247,9 +253,6 @@ preferred_addr:
 	movl	%eax, %ss
 	movl	%eax, %fs
 	movl	%eax, %gs
-	lldt	%ax
-	movl    $0x20, %eax
-	ltr	%ax
 
 	/*
 	 * Compute the decompressed kernel start address.  It is where
Signature · 1 line
1.7.7
#2 lore raw

Re: [PATCH 1/9] x86, boot: Move lldt/ltr out of 64bit only path

Quoted 3 lines · Yinghai Lu

Also it push down startup_64 to 0x208.

NAK. 0x200 is an ABI, you can't change it.

-hpa

author
#3 lore raw

Re: [PATCH 1/9] x86, boot: Move lldt/ltr out of 64bit only path

Quoted 7 lines · H. Peter Anvin
Quoted 3 lines · Yinghai Lu

Also it push down startup_64 to 0x208.

NAK. 0x200 is an ABI, you can't change it.

ok, will add attached patche before this one and keep 0x200.

Thanks

Yinghai

Subject: [PATCH] x86, boot: move verify_cpu.S after 0x200

We are short of space before 0x200 for startup_64.

before that are 32 bit code. We could move function verify_cpu down

---
 arch/x86/boot/compressed/head_64.S |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
arch/x86/boot/compressed/head_64.S +3 -2
Index: linux-2.6/arch/x86/boot/compressed/head_64.S
===================================================================
@@ -182,8 +182,6 @@ no_longmode:
 	hlt
 	jmp     1b
 
-#include "../../kernel/verify_cpu.S"
-
 	/*
 	 * Be careful here startup_64 needs to be at a predictable
 	 * address so I can export it in an ELF header.  Bootloaders
@@ -349,6 +347,9 @@ relocated:
  */
 	jmp	*%rbp
 
+	.code32
+#include "../../kernel/verify_cpu.S"
+
 	.data
 gdt:
 	.word	gdt_end - gdt
author
#4 lore raw

PATCH 2/9 x86: Add macro for 64bit entry for bzImage

In reply to Yinghai Lu

will use it with bzImage header.

---
 arch/x86/boot/compressed/head_64.S |    2 +-
 arch/x86/include/asm/boot.h        |    2 ++
 2 files changed, 3 insertions(+), 1 deletions(-)
arch/x86/boot/compressed/head_64.S +1 -1
index 4c8af67..0733638 100644
@@ -197,7 +197,7 @@ no_longmode:
 	 * it may change in the future.
 	 */
 	.code64
-	.org 0x208
+	.org BOOT_CODE64_START_OFFSET
 ENTRY(startup_64)
 	/*
 	 * We come here either from startup_32 or directly from a
arch/x86/include/asm/boot.h +2 -0
index b13fe63..bcae405 100644
@@ -38,8 +38,10 @@
 
 #ifdef CONFIG_X86_64
 #define BOOT_STACK_SIZE	0x4000
+#define BOOT_CODE64_START_OFFSET 0x208
 #else
 #define BOOT_STACK_SIZE	0x1000
+#define BOOT_CODE64_START_OFFSET 0
 #endif
 
 #endif /* __KERNEL__ */
Signature · 1 line
1.7.7
#5 lore raw

Re: [PATCH 2/9] x86: Add macro for 64bit entry for bzImage

Quoted 1 line · Yinghai Lu

will use it with bzImage header.

This isn't really a decent description. The subject line should stand alone from the patch comment. Think of it as a newspaper headline versus the newspaper article.

-hpa

author
#6 lore raw

PATCH 3/9 x86, 64bit: set extra ident page table for whole kernel range

In reply to Yinghai Lu

Current when kernel is loaded above 1G, only [_text, _text+2M] is set up with extra ident page table.
That is not enough, some variables that could be used early are out of that range. (like gdt...)

Just set map with [_text, _end] for all text/data/bss/brk...

Cc "Eric W. Biederman" <[email protected]>
---
 arch/x86/kernel/head_64.S |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)
arch/x86/kernel/head_64.S +10 -1
index 94bf9cc..efc0c08 100644
@@ -115,7 +115,16 @@ startup_64:
 	andq	$(PTRS_PER_PMD - 1), %rax
 	leaq	__PAGE_KERNEL_IDENT_LARGE_EXEC(%rdi), %rdx
 	leaq	level2_spare_pgt(%rip), %rbx
-	movq	%rdx, 0(%rbx, %rax, 8)
+	leaq	_end(%rip), %r8
+	decq	%r8
+	shrq	$PMD_SHIFT, %r8
+	andq	$(PTRS_PER_PMD - 1), %r8
+1:	movq	%rdx, 0(%rbx, %rax, 8)
+	addq	$PMD_SIZE, %rdx
+	incq	%rax
+	cmp	%r8, %rax
+	jle	1b
+
 ident_complete:
 
 	/*
Signature · 1 line
1.7.7
author
#7 lore raw

PATCH 4/9 x86, 64bit: add support for loading kernel above 512G

In reply to Yinghai Lu

Current kernel is not allowed to be loaded above 512g, it thinks that address is too big.

We only need to add one extra one spare page for needed level3 to point another 512g range.

Need to check _text range and set level4 pg to point to that spare level3 page, and set level3 to point to level2 page to cover [_text, _end] with extra mapping.

We need this to put relocatable bzImage high above 512g.

Cc "Eric W. Biederman" <[email protected]>
---
 arch/x86/kernel/head_64.S |   34 +++++++++++++++++++++++++++-------
 1 files changed, 27 insertions(+), 7 deletions(-)
arch/x86/kernel/head_64.S +27 -7
index efc0c08..32fa9d0 100644
@@ -78,12 +78,6 @@ startup_64:
 	testl	%eax, %eax
 	jnz	bad_address
 
-	/* Is the address too large? */
-	leaq	_text(%rip), %rdx
-	movq	$PGDIR_SIZE, %rax
-	cmpq	%rax, %rdx
-	jae	bad_address
-
 	/* Fixup the physical addresses in the page table
 	 */
 	addq	%rbp, init_level4_pgt + 0(%rip)
@@ -102,12 +96,35 @@ startup_64:
 	andq	$PMD_PAGE_MASK, %rdi
 
 	movq	%rdi, %rax
+	shrq	$PGDIR_SHIFT, %rax
+	andq	$(PTRS_PER_PGD - 1), %rax
+	jz	skip_level3_spare
+
+	/* Set level3 at first */
+	leaq	(level3_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx
+	leaq	init_level4_pgt(%rip), %rbx
+	movq	%rdx, 0(%rbx, %rax, 8)
+	addq	$L4_PAGE_OFFSET, %rax
+	movq	%rdx, 0(%rbx, %rax, 8)
+
+	/* always need to set level2 */
+	movq	%rdi, %rax
+	shrq	$PUD_SHIFT, %rax
+	andq	$(PTRS_PER_PUD - 1), %rax
+	leaq	level3_spare_pgt(%rip), %rbx
+	jmp	set_level2_spare
+
+skip_level3_spare:
+	movq	%rdi, %rax
 	shrq	$PUD_SHIFT, %rax
 	andq	$(PTRS_PER_PUD - 1), %rax
 	jz	ident_complete
 
-	leaq	(level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx
+	/* only set level2 with out level3 spare */
 	leaq	level3_ident_pgt(%rip), %rbx
+
+set_level2_spare:
+	leaq	(level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx
 	movq	%rdx, 0(%rbx, %rax, 8)
 
 	movq	%rdi, %rax
@@ -435,6 +452,9 @@ NEXT_PAGE(level2_kernel_pgt)
 	PMDS(0, __PAGE_KERNEL_LARGE_EXEC,
 		KERNEL_IMAGE_SIZE/PMD_SIZE)
 
+NEXT_PAGE(level3_spare_pgt)
+	.fill   512, 8, 0
+
 NEXT_PAGE(level2_spare_pgt)
 	.fill   512, 8, 0
 
Signature · 1 line
1.7.7
author
#8 lore raw

PATCH 5/9 x86: Merge early_reserve_initrd for 32bit and 64bit

In reply to Yinghai Lu

They are the same, could move them out from head32/64.c to setup.c.

We are using memblock, and it could handle overlapping properly, so we don't need to reserve some at first, and just need to make sure we reserve them before we are using memblock to find free mem to use.

---
 arch/x86/kernel/head32.c |   11 -----------
 arch/x86/kernel/head64.c |   11 -----------
 arch/x86/kernel/setup.c  |   22 ++++++++++++++++++----
 3 files changed, 18 insertions(+), 26 deletions(-)
arch/x86/kernel/head32.c +0 -11
index c18f59d..4c52efc 100644
@@ -33,17 +33,6 @@ void __init i386_start_kernel(void)
 	memblock_reserve(__pa_symbol(&_text),
 			 __pa_symbol(&__bss_stop) - __pa_symbol(&_text));
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	/* Reserve INITRD */
-	if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
-		/* Assume only end is not page aligned */
-		u64 ramdisk_image = boot_params.hdr.ramdisk_image;
-		u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
-		u64 ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
-		memblock_reserve(ramdisk_image, ramdisk_end - ramdisk_image);
-	}
-#endif
-
 	/* Call the subarch specific early setup function */
 	switch (boot_params.hdr.hardware_subarch) {
 	case X86_SUBARCH_MRST:
arch/x86/kernel/head64.c +0 -11
index 037df57..00e612a 100644
@@ -100,17 +100,6 @@ void __init x86_64_start_reservations(char *real_mode_data)
 	memblock_reserve(__pa_symbol(&_text),
 			 __pa_symbol(&__bss_stop) - __pa_symbol(&_text));
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	/* Reserve INITRD */
-	if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
-		/* Assume only end is not page aligned */
-		unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
-		unsigned long ramdisk_size  = boot_params.hdr.ramdisk_size;
-		unsigned long ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
-		memblock_reserve(ramdisk_image, ramdisk_end - ramdisk_image);
-	}
-#endif
-
 	reserve_ebda_region();
 
 	/*
arch/x86/kernel/setup.c +18 -4
index 6d29d1f..ee6d267 100644
@@ -364,6 +364,19 @@ static u64 __init get_mem_size(unsigned long limit_pfn)
 
 	return mapped_pages << PAGE_SHIFT;
 }
+static void __init early_reserve_initrd(void)
+{
+	/* Assume only end is not page aligned */
+	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
+	u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
+	u64 ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
+
+	if (!boot_params.hdr.type_of_loader ||
+	    !ramdisk_image || !ramdisk_size)
+		return;		/* No initrd provided by bootloader */
+
+	memblock_reserve(ramdisk_image, ramdisk_end - ramdisk_image);
+}
 static void __init reserve_initrd(void)
 {
 	/* Assume only end is not page aligned */
@@ -390,10 +403,6 @@ static void __init reserve_initrd(void)
 	if (pfn_range_is_mapped(PFN_DOWN(ramdisk_image),
 				PFN_DOWN(ramdisk_end))) {
 		/* All are mapped, easy case */
-		/*
-		 * don't need to reserve again, already reserved early
-		 * in i386_start_kernel
-		 */
 		initrd_start = ramdisk_image + PAGE_OFFSET;
 		initrd_end = initrd_start + ramdisk_size;
 		return;
@@ -404,6 +413,9 @@ static void __init reserve_initrd(void)
 	memblock_free(ramdisk_image, ramdisk_end - ramdisk_image);
 }
 #else
+static void __init early_reserve_initrd(void)
+{
+}
 static void __init reserve_initrd(void)
 {
 }
@@ -665,6 +677,8 @@ early_param("reservelow", parse_reservelow);
 
 void __init setup_arch(char **cmdline_p)
 {
+	early_reserve_initrd();
+
 #ifdef CONFIG_X86_32
 	memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
 	visws_early_detect();
Signature · 1 line
1.7.7
author
#9 lore raw

PATCH 6/9 x86: add get_ramdisk_image/size

In reply to Yinghai Lu

There several places to find ramdisk early for reserving and relocating.

use functions to make code more readable and consistent.

later will add ext_ramdisk_image/size with those functions to support loading ramdisk above 4g.

---
 arch/x86/kernel/setup.c |   29 +++++++++++++++++++++--------
 1 files changed, 21 insertions(+), 8 deletions(-)
arch/x86/kernel/setup.c +21 -8
index ee6d267..194e151 100644
@@ -298,12 +298,25 @@ static void __init reserve_brk(void)
 
 #ifdef CONFIG_BLK_DEV_INITRD
 
+static u64 __init get_ramdisk_image(void)
+{
+	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
+
+	return ramdisk_image;
+}
+static u64 __init get_ramdisk_size(void)
+{
+	u64 ramdisk_size = boot_params.hdr.ramdisk_size;
+
+	return ramdisk_size;
+}
+
 #define MAX_MAP_CHUNK	(NR_FIX_BTMAPS << PAGE_SHIFT)
 static void __init relocate_initrd(void)
 {
 	/* Assume only end is not page aligned */
-	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
-	u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
+	u64 ramdisk_image = get_ramdisk_image();
+	u64 ramdisk_size  = get_ramdisk_size();
 	u64 area_size     = PAGE_ALIGN(ramdisk_size);
 	u64 ramdisk_here;
 	unsigned long slop, clen, mapaddr;
@@ -342,8 +355,8 @@ static void __init relocate_initrd(void)
 		ramdisk_size  -= clen;
 	}
 
-	ramdisk_image = boot_params.hdr.ramdisk_image;
-	ramdisk_size  = boot_params.hdr.ramdisk_size;
+	ramdisk_image = get_ramdisk_image();
+	ramdisk_size  = get_ramdisk_size();
 	printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
 		" [mem %#010llx-%#010llx]\n",
 		ramdisk_image, ramdisk_image + ramdisk_size - 1,
@@ -367,8 +380,8 @@ static u64 __init get_mem_size(unsigned long limit_pfn)
 static void __init early_reserve_initrd(void)
 {
 	/* Assume only end is not page aligned */
-	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
-	u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
+	u64 ramdisk_image = get_ramdisk_image();
+	u64 ramdisk_size  = get_ramdisk_size();
 	u64 ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
 
 	if (!boot_params.hdr.type_of_loader ||
@@ -380,8 +393,8 @@ static void __init early_reserve_initrd(void)
 static void __init reserve_initrd(void)
 {
 	/* Assume only end is not page aligned */
-	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
-	u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
+	u64 ramdisk_image = get_ramdisk_image();
+	u64 ramdisk_size  = get_ramdisk_size();
 	u64 ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
 	u64 mapped_size;
 
Signature · 1 line
1.7.7
author
#10 lore raw

PATCH 7/9 x86, boot: add field to support load bzImage and ramdisk high

In reply to Yinghai Lu

ext_ramdisk_image/size will record high 32bits for ramdisk info.

code64_start_offset will be set for bzImage that support 64bit.

Cc Rob Landley <[email protected]>
Cc Matt Fleming <[email protected]>
---
 Documentation/x86/boot.txt       |    4 ++++
 arch/x86/boot/header.S           |   11 ++++++++++-
 arch/x86/include/asm/bootparam.h |    3 +++
 arch/x86/kernel/setup.c          |    6 ++++++
 4 files changed, 23 insertions(+), 1 deletions(-)
Documentation/x86/boot.txt +4 -0
index 9efceff..26c7dcc 100644
@@ -193,6 +193,10 @@ Offset	Proto	Name		Meaning
 0258/8	2.10+	pref_address	Preferred loading address
 0260/4	2.10+	init_size	Linear memory required during initialization
 0264/4	2.11+	handover_offset	Offset of handover entry point
+0268/4	2.12+	ext_ramdisk_image initrd load address high 32 bits
+				(set by boot loader)
+026C/4	2.12+	ext_ramdisk_size initrd size high 32 bits (set by boot loader)
+0270/4	2.12+   code64_start_offset 64bit start offset for bzImage
 
 (1) For backwards compatibility, if the setup_sects field contains 0, the
     real value is 4.
arch/x86/boot/header.S +10 -1
index 2a01744..85ce1a4 100644
@@ -279,7 +279,7 @@ _start:
 	# Part 2 of the header, from the old setup.S
 
 		.ascii	"HdrS"		# header signature
-		.word	0x020b		# header version number (>= 0x0105)
+		.word	0x020c		# header version number (>= 0x0105)
 					# or else old loadlin-1.5 will fail)
 		.globl realmode_swtch
 realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
@@ -400,6 +400,15 @@ init_size:		.long INIT_SIZE		# kernel initialization size
 handover_offset:	.long 0x30		# offset to the handover
 						# protocol entry point
 
+ext_ramdisk_image:	.long	0	# address of loaded ramdisk image
+					# Here the loader puts the high 32 bits
+					# address where it loaded the image.
+					# This only will be read by the kernel.
+
+ext_ramdisk_size:	.long	0	# its size in bytes high 32 bits.
+code64_start_offset:	.long	BOOT_CODE64_START_OFFSET	# startup_64 in
+					# arch/x86/boot/compressed/head_64.S
+
 # End of setup header #####################################################
 
 	.section ".entrytext", "ax"
arch/x86/include/asm/bootparam.h +3 -0
index 2ad874c..4e42fd1 100644
@@ -67,6 +67,9 @@ struct setup_header {
 	__u64	pref_address;
 	__u32	init_size;
 	__u32	handover_offset;
+	__u32	ext_ramdisk_image;
+	__u32	ext_ramdisk_size;
+	__u32	code64_start_offset;
 } __attribute__((packed));
 
 struct sys_desc_table {
arch/x86/kernel/setup.c +6 -0
index 194e151..c2eb535 100644
@@ -302,12 +302,18 @@ static u64 __init get_ramdisk_image(void)
 {
 	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
 
+	if (boot_params.hdr.version >= 0x020c)
+		ramdisk_image |= (u64)boot_params.hdr.ext_ramdisk_image << 32;
+
 	return ramdisk_image;
 }
 static u64 __init get_ramdisk_size(void)
 {
 	u64 ramdisk_size = boot_params.hdr.ramdisk_size;
 
+	if (boot_params.hdr.version >= 0x020c)
+		ramdisk_size |= (u64)boot_params.hdr.ext_ramdisk_size << 32;
+
 	return ramdisk_size;
 }
 
Signature · 1 line
1.7.7
author
#11 lore raw

PATCH 8/9 x86: ramdisk info print with high bits.

In reply to Yinghai Lu

ramdisk could be loaded high now for 64bit.

So need to print more digits for them.

---
 arch/x86/kernel/setup.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
arch/x86/kernel/setup.c +4 -4
index c2eb535..0e13c6e 100644
@@ -341,7 +341,7 @@ static void __init relocate_initrd(void)
 	memblock_reserve(ramdisk_here, area_size);
 	initrd_start = ramdisk_here + PAGE_OFFSET;
 	initrd_end   = initrd_start + ramdisk_size;
-	printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
+	printk(KERN_INFO "Allocated new RAMDISK: [mem %#018llx-%#018llx]\n",
 			 ramdisk_here, ramdisk_here + ramdisk_size - 1);
 
 	q = (char *)initrd_start;
@@ -363,8 +363,8 @@ static void __init relocate_initrd(void)
 
 	ramdisk_image = get_ramdisk_image();
 	ramdisk_size  = get_ramdisk_size();
-	printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
-		" [mem %#010llx-%#010llx]\n",
+	printk(KERN_INFO "Move RAMDISK from [mem %#018llx-%#018llx] to"
+		" [mem %#018llx-%#018llx]\n",
 		ramdisk_image, ramdisk_image + ramdisk_size - 1,
 		ramdisk_here, ramdisk_here + ramdisk_size - 1);
 }
@@ -416,7 +416,7 @@ static void __init reserve_initrd(void)
 		       "disabling initrd (%lld needed, %lld available)\n",
 		       ramdisk_size, mapped_size>>1);
 
-	printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk_image,
+	printk(KERN_INFO "RAMDISK: [mem %#018llx-%#018llx]\n", ramdisk_image,
 			ramdisk_end - 1);
 
 	if (pfn_range_is_mapped(PFN_DOWN(ramdisk_image),
Signature · 1 line
1.7.7
reviewer NAK
#12 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

Quoted 15 lines · Yinghai Lu

ramdisk could be loaded high now for 64bit.

So need to print more digits for them.

---
 arch/x86/kernel/setup.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
arch/x86/kernel/setup.c +0 -0
index c2eb535..0e13c6e 100644

arch/x86/kernel/setup.c static void __init relocate_initrd(void) · line 345

Quoted 6 lines
arch/x86/kernel/setup.c +1 -1
@@ -341,7 +341,7 @@ static void __init relocate_initrd(void)
 	memblock_reserve(ramdisk_here, area_size);
 	initrd_start = ramdisk_here + PAGE_OFFSET;
 	initrd_end   = initrd_start + ramdisk_size;
-	printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
+	printk(KERN_INFO "Allocated new RAMDISK: [mem %#018llx-%#018llx]\n",
 			 ramdisk_here, ramdisk_here + ramdisk_size - 1);

NAK, this is expected to match the resource print format (%pR), which prints 10 digits by default and then expands. Furthermore, printing *18* digits is downright silly since we still don't have 72-bit addressing.

-hpa

author
#13 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

Quoted 11 lines · H. Peter Anvin
Quoted 10 lines · Yinghai Lu

ramdisk could be loaded high now for 64bit.

So need to print more digits for them.

---
 arch/x86/kernel/setup.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
Quoted 15 lines

arch/x86/kernel/setup.c static void __init relocate_initrd(void) · line 345

Quoted 11 lines
arch/x86/kernel/setup.c +1 -1
index c2eb535..0e13c6e 100644
@@ -341,7 +341,7 @@ static void __init relocate_initrd(void)
      memblock_reserve(ramdisk_here, area_size);
      initrd_start = ramdisk_here + PAGE_OFFSET;
      initrd_end   = initrd_start + ramdisk_size;
-     printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
+     printk(KERN_INFO "Allocated new RAMDISK: [mem %#018llx-%#018llx]\n",
                       ramdisk_here, ramdisk_here + ramdisk_size - 1);

NAK, this is expected to match the resource print format (%pR), which prints 10 digits by default and then expands. Furthermore, printing *18* digits is downright silly since we still don't have 72-bit addressing.

that is the same as in e820_print_map::

                printk(KERN_INFO "%s: [mem %#018Lx-%#018Lx] ", who,
                       (unsigned long long) e820.map[i].addr,
                       (unsigned long long)
                       (e820.map[i].addr + e820.map[i].size - 1));

that is for 64bit address.

that extra 2 is for "0x"

or you prefer to cast them to pointer and use %pR for them all?

or fix printk to add extra 2 for "0x" when # is found?

author
#14 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

Quoted 36 lines · Yinghai Lu
Quoted 11 lines · H. Peter Anvin
Quoted 10 lines · Yinghai Lu

ramdisk could be loaded high now for 64bit.

So need to print more digits for them.

---
 arch/x86/kernel/setup.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
Quoted 15 lines

arch/x86/kernel/setup.c static void __init relocate_initrd(void) · line 345

Quoted 11 lines
arch/x86/kernel/setup.c +1 -1
index c2eb535..0e13c6e 100644
@@ -341,7 +341,7 @@ static void __init relocate_initrd(void)
      memblock_reserve(ramdisk_here, area_size);
      initrd_start = ramdisk_here + PAGE_OFFSET;
      initrd_end   = initrd_start + ramdisk_size;
-     printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
+     printk(KERN_INFO "Allocated new RAMDISK: [mem %#018llx-%#018llx]\n",
                       ramdisk_here, ramdisk_here + ramdisk_size - 1);

NAK, this is expected to match the resource print format (%pR), which prints 10 digits by default and then expands. Furthermore, printing *18* digits is downright silly since we still don't have 72-bit addressing.

that is the same as in e820_print_map::

                printk(KERN_INFO "%s: [mem %#018Lx-%#018Lx] ", who,
                       (unsigned long long) e820.map[i].addr,
                       (unsigned long long)
                       (e820.map[i].addr + e820.map[i].size - 1));
Quoted 7 lines

that is for 64bit address.

that extra 2 is for "0x"

or you prefer to cast them to pointer and use %pR for them all?

or fix printk to add extra 2 for "0x" when # is found?

looks like we have lots of %#010llx or %#010Lx there in arch/x86.

We need to fix printk to make it acting like %pR ?

#15 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

Quoted 7 lines · Yinghai Lu
Quoted 2 lines

or fix printk to add extra 2 for "0x" when # is found?

looks like we have lots of %#010llx or %#010Lx there in arch/x86.

We need to fix printk to make it acting like %pR ?

No, it was a thinko on my part.

-hpa

#16 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

In reply to Yinghai Lu
Quoted 9 lines · Yinghai Lu
Quoted 3 lines · Yinghai Lu

or you prefer to cast them to pointer and use %pR for them all?

or fix printk to add extra 2 for "0x" when # is found?

looks like we have lots of %#010llx or %#010Lx there in arch/x86.

We need to fix printk to make it acting like %pR ?

I'd prefer fixing the code to use %pR - when I'm looking at the code, that tells me more about the intended semantics than $# does.

But I'm basically just a crash test dummy here - the x86 maintainers of course get to make the decision what they'd prefer to have.

#17 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

In reply to Yinghai Lu
Quoted 7 lines · Yinghai Lu
Quoted 4 lines

NAK, this is expected to match the resource print format (%pR), which prints 10 digits by default and then expands. Furthermore, printing *18* digits is downright silly since we still don't have 72-bit addressing.

that is the same as in e820_print_map::

Quoted 9 lines
                printk(KERN_INFO "%s: [mem %#018Lx-%#018Lx] ", who,
                       (unsigned long long) e820.map[i].addr,
                       (unsigned long long)
                       (e820.map[i].addr + e820.map[i].size - 1));

that is for 64bit address.
that extra 2 is for "0x"

Oh, right. It's the use of %#... I usually use 0x%... so I didn't think of it.

Quoted 3 lines

or you prefer to cast them to pointer and use %pR for them all?

or fix printk to add extra 2 for "0x" when # is found?

We should normally use %pR or the equivalent format. The only reason we do it different for e820_print_map is because it prints a whole bunch of lines in which we want the columns to line up.

-hpa

author
#18 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

Quoted 21 lines · H. Peter Anvin
Quoted 7 lines · Yinghai Lu
Quoted 4 lines

NAK, this is expected to match the resource print format (%pR), which prints 10 digits by default and then expands. Furthermore, printing *18* digits is downright silly since we still don't have 72-bit addressing.

that is the same as in e820_print_map::

Quoted 9 lines
                printk(KERN_INFO "%s: [mem %#018Lx-%#018Lx] ", who,
                       (unsigned long long) e820.map[i].addr,
                       (unsigned long long)
                       (e820.map[i].addr + e820.map[i].size - 1));

that is for 64bit address.
that extra 2 is for "0x"

Oh, right. It's the use of %#... I usually use 0x%... so I didn't think of it.

Quoted 7 lines
Quoted 3 lines

or you prefer to cast them to pointer and use %pR for them all?

or fix printk to add extra 2 for "0x" when # is found?

We should normally use %pR or the equivalent format. The only reason we do it different for e820_print_map is because it prints a whole bunch of lines in which we want the columns to line up.

so we just use #llx or #Lx instead in this patch?

#19 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

Use %#010llx

Quoted 37 lines · Yinghai Lu
Quoted 3 lines · H. Peter Anvin
Quoted 2 lines · Yinghai Lu
Quoted 2 lines

NAK, this is expected to match the resource print format (%pR),

which

Quoted 1 line
Quoted 1 line
Quoted 1 line

prints 10 digits by default and then expands. Furthermore,

printing

Quoted 1 line
Quoted 1 line
Quoted 1 line

*18* digits is downright silly since we still don't have 72-bit

addressing.

Quoted 9 lines
Quoted 9 lines

that is the same as in e820_print_map::

                printk(KERN_INFO "%s: [mem %#018Lx-%#018Lx] ", who,
                       (unsigned long long) e820.map[i].addr,
                       (unsigned long long)
                       (e820.map[i].addr + e820.map[i].size - 1));
Quoted 5 lines
Quoted 3 lines

that is for 64bit address.
that extra 2 is for "0x"

Oh, right. It's the use of %#... I usually use 0x%... so I didn't

think

Quoted 7 lines

of it.

Quoted 3 lines

or you prefer to cast them to pointer and use %pR for them all?

or fix printk to add extra 2 for "0x" when # is found?

We should normally use %pR or the equivalent format. The only reason

we

Quoted 1 line

do it different for e820_print_map is because it prints a whole bunch

of

Quoted 1 line

lines in which we want the columns to line up.

so we just use #llx or #Lx instead in this patch?

Signature · 1 line
Sent from my mobile phone. Please excuse brevity and lack of formatting.
author
#20 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

Quoted 1 line · H. Peter Anvin

Use %#010llx

that will only print out 0x87654321 when val is 0xa987654321

#21 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

No, it won't... try it.

Quoted 4 lines · Yinghai Lu
Quoted 1 line · H. Peter Anvin

Use %#010llx

that will only print out 0x87654321 when val is 0xa987654321

Signature · 1 line
Sent from my mobile phone. Please excuse brevity and lack of formatting.
author
#22 lore raw

Re: [PATCH 8/9] x86: ramdisk info print with high bits.

Quoted 2 lines · H. Peter Anvin

No, it won't... try it.

yes, you are right. this patch is not needed.

Thanks

Yinghai

author
#23 lore raw

PATCH 9/9 x86: remove 1024g limitation for kexec buffer on 64bit

In reply to Yinghai Lu

could find buffer above that, remove that obsolete limitation. use MAXMEM instead.

Tested on sytem more than 1024g ram.

Cc "Eric W. Biederman" <[email protected]>
---
 arch/x86/include/asm/kexec.h |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
arch/x86/include/asm/kexec.h +3 -3
index 317ff17..11bfdc5 100644
@@ -48,11 +48,11 @@
 # define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
 #else
 /* Maximum physical address we can use pages from */
-# define KEXEC_SOURCE_MEMORY_LIMIT      (0xFFFFFFFFFFUL)
+# define KEXEC_SOURCE_MEMORY_LIMIT      (MAXMEM-1)
 /* Maximum address we can reach in physical address mode */
-# define KEXEC_DESTINATION_MEMORY_LIMIT (0xFFFFFFFFFFUL)
+# define KEXEC_DESTINATION_MEMORY_LIMIT (MAXMEM-1)
 /* Maximum address we can use for the control pages */
-# define KEXEC_CONTROL_MEMORY_LIMIT     (0xFFFFFFFFFFUL)
+# define KEXEC_CONTROL_MEMORY_LIMIT     (MAXMEM-1)
 
 /* Allocate one page for the pdp and the second for the code */
 # define KEXEC_CONTROL_PAGE_SIZE  (4096UL + 4096UL)
Signature · 1 line
1.7.7
#24 lore raw
In reply to Yinghai Lu
Quoted 12 lines · Yinghai Lu

Now we have limit kdump reseved under 896M, because kexec has the limitation. and also bzImage need to stay under 4g.

To make kexec/kdump could use range above 4g, we need to make bzImage and ramdisk could be loaded above 4g.
During booting bzImage will be unpacked on same postion and stay high.

The patches add field in boot header to
1. get info about ramdisk position info above 4g from bootloader/kexec
2. set code64_start_offset in header for bzImage and bootloader/kexec load could check that to decide if need to put bzImage high.

Quoted 8 lines

This patches is tested with kexec tools with local changes, will send kexec tools change to kexec list later.

could be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-x86-boot

and it is on top of for-x86-mm

Mostly a good series, but the 0x208 is a showstopper. 0x200 is awkward as an ABI (too big to just make a jump table, but potentially too small to hold all the code needed.) I have sent some other comments, too.

If 0x200 is too small, it isn't a huge problem; we can put a jump at 0x200 and continue the 32-bit code afterwards:

	/* 32-bit code */

	jmp	1f

	.org	0x200
	.code64
ENTRY(startup_64)
	jmp	start_64_real

	.code32
1:
	/* 32-bit code continues... */

It is annoying because it has to be placed by hand, but isn't actually a problem. The easy way to do this is probably to push verify_cpu.S into the post-entry-point area. The .code64/.code32 don't actually do anything for a simple jmp, but are added for documentation.

How is collecting comments and ACKs for for-x86-mm coming? I'd like to do another review pass today and putting it in -tip if it is in better shape. Otherwise I suspect we'll be looking at 3.9, which is OK, of course.

-hpa

author
#25 lore raw
Quoted 3 lines · H. Peter Anvin

How is collecting comments and ACKs for for-x86-mm coming? I'd like to do another review pass today and putting it in -tip if it is in better shape. Otherwise I suspect we'll be looking at 3.9, which is OK, of course.

get three Acks from Stefano.

Konard test -v6 and found one bug, and it is address in -v7. --- xen domU does not have hole under 4G when 8G ram is configured.

please check updated one with acks and updated log from
git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git
for-x86-mm

Hope you can put them in tip early for more test coverage.

Thanks

Yinghai