kexec: put bzImage and ramdisk above 4G for x86 64bit
Subsystems (3)
v3 cover kexec: put bzImage and ramdisk above 4G for x86 64bit
Now we have limit kdump reserved under 896M, because kexec has the limitation. and also bzImage need to stay under 4g.
kernel parts changes could be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-x86-boot
here patches are for kexec tools to load bzImage and ramdisk high acccording to new added boot header fields.
-v3: address review from Eric to use locate_hole at first.
use xloadflags instead.
Yinghai Lu (4):
kexec, x86: add boot header member for version 2.12 kexec, x86: put ramdisk high for 64bit bzImage kexec, x86: set ext_cmd_line_ptr when boot_param is above 4g kexec, x86_64: Load bzImage64 above 4G
include/x86/x86-linux.h | 26 +++- kexec/arch/i386/x86-linux-setup.c | 25 +++- kexec/arch/x86_64/Makefile | 1 + kexec/arch/x86_64/kexec-bzImage64.c | 327 +++++++++++++++++++++++++++++++++++ kexec/arch/x86_64/kexec-x86_64.c | 1 + kexec/arch/x86_64/kexec-x86_64.h | 5 + 6 files changed, 378 insertions(+), 7 deletions(-) create mode 100644 kexec/arch/x86_64/kexec-bzImage64.c
Signature · 7 lines
1.7.7 _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 1/4 kexec, x86: add boot header member for version 2.12
will use ext_ramdisk_image/size, and xloadflags to put ramdisk and bzImage high for 64bit.
--- include/x86/x86-linux.h | 26 +++++++++++++++++++++++--- 1 files changed, 23 insertions(+), 3 deletions(-)
include/x86/x86-linux.h +23 -3
@@ -174,11 +174,21 @@ struct x86_linux_param_header {/* 2.04+ */ uint32_t kernel_alignment;/* 0x230 */ uint8_t relocatable_kernel;/* 0x234 */ -uint8_t reserved15[3 ];/* 0x235 */ +uint8_t min_alignment;/* 0x235 */ +uint16_t xloadflags;/* 0x236 */ uint32_t cmdline_size;/* 0x238 */ uint32_t hardware_subarch;/* 0x23C */ uint64_t hardware_subarch_data;/* 0x240 */ -uint8_t reserved16[0x290 -0x248 ];/* 0x248 */ +uint32_t payload_offset;/* 0x248 */ +uint32_t payload_length;/* 0x24C */ +uint64_t setup_data;/* 0x250 */ +uint64_t pref_address;/* 0x258 */ +uint32_t init_size;/* 0x260 */ +uint32_t handover_offset;/* 0x264 */ +uint32_t ext_ramdisk_image;/* 0x268 */ +uint32_t ext_ramdisk_size;/* 0x26C */ +uint32_t ext_cmd_line_ptr;/* 0x270 */ +uint8_t reserved16[0x290 -0x274 ];/* 0x274 */ uint32_t edd_mbr_sig_buffer[EDD_MBR_SIG_MAX ];/* 0x290 */ #endif struct e820entry e820_map[E820MAX ];/* 0x2d0 */
@@ -241,10 +251,20 @@ struct x86_linux_header {#else uint32_t kernel_alignment;/* 0x230 */ uint8_t relocatable_kernel;/* 0x234 */ -uint8_t reserved6[3 ];/* 0x235 */ +uint8_t min_alignment;/* 0x235 */ +uint16_t xloadflags;/* 0x236 */ uint32_t cmdline_size;/* 0x238 */ uint32_t hardware_subarch;/* 0x23C */ uint64_t hardware_subarch_data;/* 0x240 */ +uint32_t payload_offset;/* 0x248 */ +uint32_t payload_length;/* 0x24C */ +uint64_t setup_data;/* 0x250 */ +uint64_t pref_address;/* 0x258 */ +uint32_t init_size;/* 0x260 */ +uint32_t handover_offset;/* 0x264 */ +uint32_t ext_ramdisk_image;/* 0x268 */ +uint32_t ext_ramdisk_size;/* 0x26C */ +uint32_t ext_cmd_line_ptr;/* 0x270 */ #endif }PACKED ;
Signature · 7 lines
1.7.7 _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 2/4 kexec, x86: put ramdisk high for 64bit bzImage
In reply to Yinghai LuWe could put ramdisk high for bzImage on 64bit for protocol 2.12.
-v2: change ext_... handling to way that eric like.
--- kexec/arch/i386/x86-linux-setup.c | 18 +++++++++++++++--- 1 files changed, 15 insertions(+), 3 deletions(-)
kexec/arch/i386/x86-linux-setup.c +15 -3
@@ -64,7 +64,11 @@ void setup_linux_bootloader_parameters(/* Find the maximum initial ramdisk address */ initrd_addr_max =DEFAULT_INITRD_ADDR_MAX ;if (real_mode->protocol_version >=0x0203 ) { - initrd_addr_max = real_mode->initrd_addr_max; +if (real_mode->protocol_version >=0x020c && + real_mode->xloadflags &1 ) + initrd_addr_max =ULONG_MAX ; +else + initrd_addr_max = real_mode->initrd_addr_max;dbgprintf ("initrd_addr_max is 0x%lx\n" , initrd_addr_max); }
@@ -81,8 +85,16 @@ void setup_linux_bootloader_parameters( }/* Ramdisk address and size */ - real_mode->initrd_start = initrd_base; - real_mode->initrd_size = initrd_size; + real_mode->initrd_start = initrd_base &0xffffffffUL ; + real_mode->initrd_size = initrd_size &0xffffffffUL ; + +if (real_mode->protocol_version >=0x020c && + (initrd_base &0xffffffffUL ) != initrd_base) + real_mode->ext_ramdisk_image = initrd_base >>32 ; + +if (real_mode->protocol_version >=0x020c && + (initrd_size &0xffffffffUL ) != initrd_size) + real_mode->ext_ramdisk_size = initrd_size >>32 ;/* The location of the command line */ /* if (real_mode_base == 0x90000) { */
Signature · 7 lines
1.7.7 _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 3/4 kexec, x86: set ext_cmd_line_ptr when boot_param is above 4g
In reply to Yinghai Luupdate ext_cmd_line_ptr for bzImage from protocal 2.12 that could have command line above 4g.
-v2: update ext_... handling to the way that Eric likes.
--- kexec/arch/i386/x86-linux-setup.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-)
kexec/arch/i386/x86-linux-setup.c +6 -1
@@ -103,7 +103,12 @@ void setup_linux_bootloader_parameters(/* setup_move_size */ /* } */ if (real_mode->protocol_version >=0x0202 ) { - real_mode->cmd_line_ptr = real_mode_base + cmdline_offset; +unsigned long cmd_line_ptr = real_mode_base + cmdline_offset; + + real_mode->cmd_line_ptr = cmd_line_ptr &0xffffffffUL ; +if ((real_mode->protocol_version >=0x020c ) && + ((cmd_line_ptr &0xffffffffUL ) != cmd_line_ptr)) + real_mode->ext_cmd_line_ptr = cmd_line_ptr >>32 ; }/* Fill in the command line */
Signature · 7 lines
1.7.7 _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
PATCH v3 4/4 kexec, x86_64: Load bzImage64 above 4G
In reply to Yinghai Luneed to check xloadflags to see the bzImage is for 64bit relocatable.
-v2: add kexec-bzImage64.c according to Eric.
-v3: don't need to purgatory under 2g after Eric's change to purgatory code. -v4: use locate_hole find position first then add_buffer... suggested by Eric
add buffer for kernel image at last to make kexec-load faster. use xloadflags in setup_header to tell if is bzImage64.
--- kexec/arch/x86_64/Makefile | 1 + kexec/arch/x86_64/kexec-bzImage64.c | 327 +++++++++++++++++++++++++++++++++++ kexec/arch/x86_64/kexec-x86_64.c | 1 + kexec/arch/x86_64/kexec-x86_64.h | 5 + 4 files changed, 334 insertions(+), 0 deletions(-) create mode 100644 kexec/arch/x86_64/kexec-bzImage64.c
kexec/arch/x86_64/Makefile +1 -0
@@ -13,6 +13,7 @@ x86_64_KEXEC_SRCS += kexec/arch/i386/crashdump-x86.c x86_64_KEXEC_SRCS_native = kexec/arch/x86_64/kexec-x86_64.c x86_64_KEXEC_SRCS_native += kexec/arch/x86_64/kexec-elf-x86_64.c x86_64_KEXEC_SRCS_native += kexec/arch/x86_64/kexec-elf-rel-x86_64.c +x86_64_KEXEC_SRCS_native += kexec/arch/x86_64/kexec-bzImage64.c x86_64_KEXEC_SRCS += $(x86_64_KEXEC_SRCS_native)
kexec/arch/x86_64/kexec-bzImage64.c new file +327 -0
327 lines not on this page · raw message
kexec/arch/x86_64/kexec-x86_64.c +1 -0
@@ -37,6 +37,7 @@ struct file_type file_type[] = { {"multiboot-x86" , multiboot_x86_probe, multiboot_x86_load, multiboot_x86_usage }, { "elf-x86", elf_x86_probe, elf_x86_load, elf_x86_usage }, + { "bzImage64", bzImage64_probe, bzImage64_load, bzImage64_usage }, { "bzImage", bzImage_probe, bzImage_load, bzImage_usage }, { "beoboot-x86", beoboot_probe, beoboot_load, beoboot_usage }, { "nbi-x86", nbi_probe, nbi_load, nbi_usage },
kexec/arch/x86_64/kexec-x86_64.h +5 -0
@@ -28,4 +28,9 @@ int elf_x86_64_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info);void elf_x86_64_usage (void ); +int bzImage64_probe (const char *buf,off_t len); +int bzImage64_load (int argc,char **argv,const char *buf,off_t len, +struct kexec_info *info); +void bzImage64_usage (void ); +#endif /* KEXEC_X86_64_H */
Signature · 7 lines
1.7.7 _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
On Tue, Nov 20, 2012 at 11:31:38PM -0800, Yinghai Lu wrote:
[..]
kexec/arch/x86_64/kexec-bzImage64.c line 238
Quoted 13 lines
kexec/arch/x86_64/kexec-bzImage64.c new file +13
-0+/* avoid cross GB boundary */ + align = real_mode->kernel_alignment; + addr =locate_hole (info, size, align,0x100000 ,-1 ,-1 ); +if (addr ==ULONG_MAX ) +die ("can not load bzImage64" ); +/* same GB ? */ +while ((addr >>30 ) != ((addr + size -1 ) >>30 )) { + addr =locate_hole (info, size, align,0x100000 , +round_down (addr + size -1 , (1UL <<30 )),-1 ); +if (addr ==ULONG_MAX ) +die ("can not load bzImage64" ); + } +dbgprintf ("Found kernel buffer at %lx size %lx\n" , addr, size);
Where does this limitation of not loading kernel across GB boundary come from?
Vivek
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
H. Peter Anvin
reviewerRe: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 20 lines · Vivek Goyal
On Tue, Nov 20, 2012 at 11:31:38PM -0800, Yinghai Lu wrote:
[..]
kexec/arch/x86_64/kexec-bzImage64.c line 238
Quoted 13 lines
kexec/arch/x86_64/kexec-bzImage64.c new file +13
-0+/* avoid cross GB boundary */ + align = real_mode->kernel_alignment; + addr =locate_hole (info, size, align,0x100000 ,-1 ,-1 ); +if (addr ==ULONG_MAX ) +die ("can not load bzImage64" ); +/* same GB ? */ +while ((addr >>30 ) != ((addr + size -1 ) >>30 )) { + addr =locate_hole (info, size, align,0x100000 , +round_down (addr + size -1 , (1UL <<30 )),-1 ); +if (addr ==ULONG_MAX ) +die ("can not load bzImage64" ); + } +dbgprintf ("Found kernel buffer at %lx size %lx\n" , addr, size);Where does this limitation of not loading kernel across GB boundary come from?
Seriously... that is bizarre.
-hpa
Signature · 8 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
In reply to Vivek GoyalQuoted 17 lines · Vivek Goyal
On Tue, Nov 20, 2012 at 11:31:38PM -0800, Yinghai Lu wrote:
[..]
kexec/arch/x86_64/kexec-bzImage64.c line 238
Quoted 13 lines
kexec/arch/x86_64/kexec-bzImage64.c new file +13
-0+/* avoid cross GB boundary */ + align = real_mode->kernel_alignment; + addr =locate_hole (info, size, align,0x100000 ,-1 ,-1 ); +if (addr ==ULONG_MAX ) +die ("can not load bzImage64" ); +/* same GB ? */ +while ((addr >>30 ) != ((addr + size -1 ) >>30 )) { + addr =locate_hole (info, size, align,0x100000 , +round_down (addr + size -1 , (1UL <<30 )),-1 ); +if (addr ==ULONG_MAX ) +die ("can not load bzImage64" ); + } +dbgprintf ("Found kernel buffer at %lx size %lx\n" , addr, size);
Quoted 2 lines
Where does this limitation of not loading kernel across GB boundary come from?
in kernel arch/x86/kernel/head_64.S
it only set first 1G ident mapping. and if it find that code is above 1G, it will set extra ident mapping
for new _text.._end.
To make checking and add extra mapping simple and also save two extra pages for mapping.
Limit that _text.._end in them same GB range.
Thanks
Yinghai
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
H. Peter Anvin
reviewerRe: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 21 lines · Yinghai Lu
Quoted 17 lines · Vivek Goyal
On Tue, Nov 20, 2012 at 11:31:38PM -0800, Yinghai Lu wrote:
[..]
kexec/arch/x86_64/kexec-bzImage64.c line 238
Quoted 13 lines
kexec/arch/x86_64/kexec-bzImage64.c new file +13
-0+/* avoid cross GB boundary */ + align = real_mode->kernel_alignment; + addr =locate_hole (info, size, align,0x100000 ,-1 ,-1 ); +if (addr ==ULONG_MAX ) +die ("can not load bzImage64" ); +/* same GB ? */ +while ((addr >>30 ) != ((addr + size -1 ) >>30 )) { + addr =locate_hole (info, size, align,0x100000 , +round_down (addr + size -1 , (1UL <<30 )),-1 ); +if (addr ==ULONG_MAX ) +die ("can not load bzImage64" ); + } +dbgprintf ("Found kernel buffer at %lx size %lx\n" , addr, size);Quoted 2 lines
Where does this limitation of not loading kernel across GB boundary come from?
Quoted 9 lines
in kernel
arch/x86/kernel/head_64.Sit only set first 1G ident mapping. and if it find that code is above 1G, it will set extra ident mapping
for new _text.._end.
To make checking and add extra mapping simple and also save two extra pages for mapping.
Limit that _text.._end in them same GB range.
No, this is backwards.
We should fix that limitation instead.
-hpa
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 12 lines · H. Peter Anvin
Quoted 10 lines · Yinghai Lu
in kernel
arch/x86/kernel/head_64.Sit only set first 1G ident mapping. and if it find that code is above 1G, it will set extra ident mapping
for new _text.._end.
To make checking and add extra mapping simple and also save two extra pages for mapping.
Limit that _text.._end in them same GB range.
Quoted 1 line
No, this is backwards.
old one: it limited bzImage in [0,1G) aka the first 1G.
Now we can put it in any aligned 1G range.
So how could it be called backwards?
Quoted 2 lines
We should fix that limitation instead.
sure, but that will make arch/x86/boot/compressed/head_64.S not need complicated.
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
H. Peter Anvin
reviewerRe: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 13 lines · Yinghai Lu
Quoted 12 lines · H. Peter Anvin
Quoted 10 lines · Yinghai Lu
in kernel
arch/x86/kernel/head_64.Sit only set first 1G ident mapping. and if it find that code is above 1G, it will set extra ident mapping
for new _text.._end.
To make checking and add extra mapping simple and also save two extra pages for mapping.
Limit that _text.._end in them same GB range.
Quoted 8 lines
Quoted 1 line
No, this is backwards.
old one: it limited bzImage in [0,1G) aka the first 1G.
Now we can put it in any aligned 1G range.
So how could it be called backwards?
Because you're adding a more complicated hack.
Quoted 6 lines
Quoted 2 lines
We should fix that limitation instead.
sure, but that will make
arch/x86/boot/compressed/head_64.Snot need complicated.
But it makes the bootloaders more complicated, and the bootloaders are harder to fix.
-hpa
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 16 lines · H. Peter Anvin
Quoted 15 lines · Yinghai Lu
Quoted 13 lines · H. Peter Anvin
Quoted 10 lines · Yinghai Lu
in kernel
arch/x86/kernel/head_64.Sit only set first 1G ident mapping. and if it find that code is above 1G, it will set extra ident mapping
for new _text.._end.
To make checking and add extra mapping simple and also save two extra pages for mapping.
Limit that _text.._end in them same GB range.No, this is backwards.
Quoted 8 lines
Quoted 6 lines
old one: it limited bzImage in [0,1G) aka the first 1G.
Now we can put it in any aligned 1G range.
So how could it be called backwards?
Because you're adding a more complicated hack.
not that complicated, and it only add 7 lines
/* same GB ? */
while ((addr >> 30) != ((addr + size - 1) >> 30)) {
addr = locate_hole(info, size, align, 0x100000,
round_down(addr + size - 1, (1UL<<30)), -1);
if (addr == ULONG_MAX)
die("can not load bzImage64");
}Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
We should fix that limitation instead.
sure, but that will make
arch/x86/boot/compressed/head_64.Snot need complicated.
If that add cover cross GB boundary handling in head_64.S, may need another 100 line code
for checking and etc.
Also will need another two spare pages for cross 512G boundary.
Quoted 3 lines
But it makes the bootloaders more complicated, and the bootloaders are harder to fix.
current bootloader does not have this feature and will add the feature. and looks like kexec is only one at this point.
BTW, is there any 64bit boot loader?
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
H. Peter Anvin
reviewerRe: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Yes.
Quoted 61 lines · Yinghai Lu
Quoted 2 lines · H. Peter Anvin
Quoted 1 line · Yinghai Lu
On Wed, Nov 21, 2012 at 11:56 AM, H. Peter Anvin <[email protected]>
Quoted 5 lines · wrote:
Quoted 5 lines
Quoted 5 lines · Yinghai Lu
Quoted 4 lines
in kernel
arch/x86/kernel/head_64.Sit only set first 1G ident mapping. and if it find that code is
above
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
1G, it will set extra ident mapping
for new _text.._end.
To make checking and add extra mapping simple and also save twoextra
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 3 lines
pages for mapping.
Limit that _text.._end in them same GB range.No, this is backwards.
Quoted 8 lines
Quoted 6 lines
old one: it limited bzImage in [0,1G) aka the first 1G.
Now we can put it in any aligned 1G range.
So how could it be called backwards?
Because you're adding a more complicated hack.
not that complicated, and it only add 7 lines
/* same GB ? */ while ((addr >> 30) != ((addr + size - 1) >> 30)) { addr = locate_hole(info, size, align, 0x100000, round_down(addr + size - 1, (1UL<<30)), -1); if (addr == ULONG_MAX) die("can not load bzImage64"); }Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
We should fix that limitation instead.
sure, but that will make
arch/x86/boot/compressed/head_64.Snot need complicated.If that add cover cross GB boundary handling in
head_64.S, may need another 100 line code
for checking and etc.Also will need another two spare pages for cross 512G boundary.
Quoted 2 lines
But it makes the bootloaders more complicated, and the bootloaders
are
Quoted 1 line
harder to fix.
current bootloader does not have this feature and will add the feature. and looks like kexec is only one at this point.
BTW, is there any 64bit boot loader?
Signature · 6 lines
Sent from my mobile phone. Please excuse brevity and lack of formatting. _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
H. Peter Anvin
reviewerRe: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
In reply to Yinghai LuQuoted 10 lines · Yinghai Lu
Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
We should fix that limitation instead.
sure, but that will make
arch/x86/boot/compressed/head_64.Snot need complicated.If that add cover cross GB boundary handling in
head_64.S, may need another 100 line code
for checking and etc.
That seems unlikely.
Quoted 1 line
Also will need another two spare pages for cross 512G boundary.
Doesn't seem like a problem.
Let me be blunt: either we do it right or we don't do it at all.
-hpa
Signature · 8 lines
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 7 lines · H. Peter Anvin
Quoted 2 lines
Also will need another two spare pages for cross 512G boundary.
Doesn't seem like a problem.
Let me be blunt: either we do it right or we don't do it at all.
ok, please check the version that cover gb boundary.
it is about 100 lines more than the version that does not handle crossing.
test on cross 1G, 5G, 512G, 513G.
Thanks
Yinghai
Subject: [PATCH] x86, 64bit: add support for loading kernel above 512G
Current kernel is not allowed to be loaded above 512g, it thinks that address is too big.
We only need to add one extra 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.
-v2: handling cross GB boundary that hpa insists on.
test on cross 1G, 5G, 512g, 513g.
should double check on cross 1024g, but it should work.
--- arch/x86/kernel/head_64.S | 142 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 131 insertions(+), 11 deletions(-)
arch/x86/kernel/head_64.S +131 -11
@@ -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)
@@ -97,28 +91,147 @@ startup_64: addq %rbp, level2_fixmap_pgt + (506*8)(%rip) - /* Add an Identity mapping if I am above 1G */ + /* Add an Identity mapping if _end is above 1G */ + leaq _end(%rip), %r9 + decq %r9 + cmp $PUD_SIZE, %r9 + jl ident_complete + + /* get end */ + andq $PMD_PAGE_MASK, %r9 + /* round start to 1G if it is below 1G */ leaq _text(%rip), %rdi andq $PMD_PAGE_MASK, %rdi + cmp $PUD_SIZE, %rdi + jg 1f + movq $PUD_SIZE, %rdi +1: + /* get 512G index */ + movq %r9, %r10 + shrq $PGDIR_SHIFT, %r10 + andq $(PTRS_PER_PGD - 1), %r10 + movq %rdi, %rax + shrq $PGDIR_SHIFT, %rax + andq $(PTRS_PER_PGD - 1), %rax + + /* cross two 512G ? */ + cmp %r10, %rax + jne set_level3_other_512g + + /* all in first 512G ? */ + cmp $0, %rax + je skip_level3_spare + + /* same 512G other than first 512g */ + 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) + + /* get 1G index */ + movq %r9, %r10 + shrq $PUD_SHIFT, %r10 + andq $(PTRS_PER_PUD - 1), %r10 + movq %rdi, %rax + shrq $PUD_SHIFT, %rax + andq $(PTRS_PER_PUD - 1), %rax + + /* same 1G ? */ + cmp %r10, %rax + je set_level2_start_only_not_first_512g + + /* set level2 for end */ + leaq level3_spare_pgt(%rip), %rbx + leaq (level2_spare2_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx + movq %rdx, 0(%rbx, %r10, 8) + +set_level2_start_only_not_first_512g: + leaq level3_spare_pgt(%rip), %rbx + leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx + movq %rdx, 0(%rbx, %rax, 8) + + jmp set_level2_spare + +set_level3_other_512g: + /* start is in first 512G ? */ + cmp $0, %rax + /* for level2 last on first 512g */ + leaq level3_ident_pgt(%rip), %rcx + je set_level2_start_other_512g + + /* Set level3 for _text */ + 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) + /* for level2 last not on first 512G */ + leaq level3_spare_pgt(%rip), %rcx + +set_level2_start_other_512g: + /* always need to set level2 */ movq %rdi, %rax shrq $PUD_SHIFT, %rax andq $(PTRS_PER_PUD - 1), %rax - jz ident_complete - + movq %rcx, %rbx /* %rcx has level3_spare_pgt or level3_ident_pgt */ leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx + movq %rdx, 0(%rbx, %rax, 8) + +set_level3_end_other_512g: + leaq (level3_spare2_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx + leaq init_level4_pgt(%rip), %rbx + movq %rdx, 0(%rbx, %r10, 8) + addq $L4_PAGE_OFFSET, %r10 + movq %rdx, 0(%rbx, %r10, 8) + + /* always need to set level2 */ + movq %r9, %r10 + shrq $PUD_SHIFT, %r10 + andq $(PTRS_PER_PUD - 1), %r10 + leaq level3_spare2_pgt(%rip), %rbx + leaq (level2_spare2_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx + movq %rdx, 0(%rbx, %r10, 8) + + jmp set_level2_spare + +skip_level3_spare: + /* get 1G index */ + movq %r9, %r10 + shrq $PUD_SHIFT, %r10 + andq $(PTRS_PER_PUD - 1), %r10 + movq %rdi, %rax + shrq $PUD_SHIFT, %rax + andq $(PTRS_PER_PUD - 1), %rax + + /* same 1G ? */ + cmp %r10, %rax + je set_level2_start_only_first_512g + + /* set level2 without level3 spare */ leaq level3_ident_pgt(%rip), %rbx + leaq (level2_spare2_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx + movq %rdx, 0(%rbx, %r10, 8) + +set_level2_start_only_first_512g: + /* set level2 without level3 spare */ + leaq level3_ident_pgt(%rip), %rbx + leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx movq %rdx, 0(%rbx, %rax, 8) +set_level2_spare: movq %rdi, %rax shrq $PMD_SHIFT, %rax andq $(PTRS_PER_PMD - 1), %rax leaq __PAGE_KERNEL_IDENT_LARGE_EXEC(%rdi), %rdx leaq level2_spare_pgt(%rip), %rbx - leaq _end(%rip), %r8 - decq %r8 + movq %r9, %r8 shrq $PMD_SHIFT, %r8 andq $(PTRS_PER_PMD - 1), %r8 + cmp %r8, %rax + jl 1f + addq $PTRS_PER_PMD, %r8 1: movq %rdx, 0(%rbx, %rax, 8) addq $PMD_SIZE, %rdx incq %rax
@@ -435,8 +548,15 @@ 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(level3_spare2_pgt) + .fill 512, 8, 0 + NEXT_PAGE(level2_spare_pgt) .fill 512, 8, 0 +NEXT_PAGE(level2_spare2_pgt) + .fill 512, 8, 0 #undef PMDS #undef NEXT_PAGE
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
In reply to Yinghai LuOn Tue, Nov 20, 2012 at 11:31:38PM -0800, Yinghai Lu wrote:
[..]
Quoted 34 lines
kexec/arch/x86_64/kexec-bzImage64.c new file +34
-0+int bzImage64_probe (const char *buf,off_t len) +{ +const struct x86_linux_header *header; +if ((uintmax_t )len < (uintmax_t)(2 *512 )) { +if (probe_debug) { +fprintf (stderr,"File is too short to be a bzImage!\n" ); + } +return -1 ; + } + header = (const struct x86_linux_header *)buf; +if (memcmp (header->header_magic,"HdrS" ,4 ) !=0 ) { +if (probe_debug) { +fprintf (stderr,"Not a bzImage\n" ); + } +return -1 ; + } +if (header->boot_sector_magic !=0xAA55 ) { +if (probe_debug) { +fprintf (stderr,"No x86 boot sector present\n" ); + } +/* No x86 boot sector present */ +return -1 ; + } +if (header->protocol_version <0x020C ) { +if (probe_debug) { +fprintf (stderr,"Must be at least protocol version 2.12\n" ); + } +/* Must be at least protocol version 2.12 */ +return -1 ; + } +if ((header->loadflags &1 ) ==0 ) { +if (probe_debug) { +fprintf (stderr,"zImage not a bzImage\n" ); + }
kexec/arch/x86_64/kexec-bzImage64.c line 89
Quoted 10 lines
kexec/arch/x86_64/kexec-bzImage64.c new file +10
-0+/* Not a bzImage */ +return -1 ; + } +if (!(header->xloadflags &1 )) { +if (probe_debug) { +fprintf (stderr,"Not a bzImage64\n" ); + } +/* Must be LOADED_ABOVE_4G */ +return -1 ; + }
So how do I force a 16bit or 32bit entry using a bzImage64?
Thanks
Vivek
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 41 lines · Vivek Goyal
On Tue, Nov 20, 2012 at 11:31:38PM -0800, Yinghai Lu wrote:
[..]
Quoted 38 lines
kexec/arch/x86_64/kexec-bzImage64.c new file +38
-0+int bzImage64_probe (const char *buf,off_t len) +{ +const struct x86_linux_header *header; +if ((uintmax_t )len < (uintmax_t)(2 *512 )) { +if (probe_debug) { +fprintf (stderr,"File is too short to be a bzImage!\n" ); + } +return -1 ; + } + header = (const struct x86_linux_header *)buf; +if (memcmp (header->header_magic,"HdrS" ,4 ) !=0 ) { +if (probe_debug) { +fprintf (stderr,"Not a bzImage\n" ); + } +return -1 ; + } +if (header->boot_sector_magic !=0xAA55 ) { +if (probe_debug) { +fprintf (stderr,"No x86 boot sector present\n" ); + } +/* No x86 boot sector present */ +return -1 ; + } +if (header->protocol_version <0x020C ) { +if (probe_debug) { +fprintf (stderr,"Must be at least protocol version 2.12\n" ); + } +/* Must be at least protocol version 2.12 */ +return -1 ; + } +if ((header->loadflags &1 ) ==0 ) { +if (probe_debug) { +fprintf (stderr,"zImage not a bzImage\n" ); + } +/* Not a bzImage */ +return -1 ; + } +if (!(header->xloadflags &1 )) {
Quoted 8 lines
kexec/arch/x86_64/kexec-bzImage64.c line 89
Quoted 6 lines
kexec/arch/x86_64/kexec-bzImage64.c new file +6
-0+if (probe_debug) { +fprintf (stderr,"Not a bzImage64\n" ); + } +/* Must be LOADED_ABOVE_4G */ +return -1 ; + }So how do I force a 16bit or 32bit entry using a bzImage64?
kexec -t bzImage -l ....
will load low and use 32bit entry.
kexec -t bzImage64 -l ...
kexec -l ...
will try to load high and use 64bit entry.
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
H. Peter Anvin
reviewerRe: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 10 lines · Yinghai Lu
Quoted 2 lines
So how do I force a 16bit or 32bit entry using a bzImage64?
kexec -t bzImage -l ....
will load low and use 32bit entry.kexec -t bzImage64 -l ...
kexec -l ...
will try to load high and use 64bit entry.
I don't see any difference...
-hpa
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 7 lines · H. Peter Anvin
Quoted 6 lines · Yinghai Lu
Quoted 2 lines
So how do I force a 16bit or 32bit entry using a bzImage64?
kexec -t bzImage -l ....
will load low and use 32bit entry.
Quoted 8 lines
Quoted 4 lines
kexec -t bzImage64 -l ...
kexec -l ...
will try to load high and use 64bit entry.I don't see any difference...
kexec/arch/x86_64/kexec-x86_64.c +1 -0
@@ -37,6 +37,7 @@ struct file_type file_type[] = { {"multiboot-x86" , multiboot_x86_probe, multiboot_x86_load, multiboot_x86_usage }, { "elf-x86", elf_x86_probe, elf_x86_load, elf_x86_usage }, + { "bzImage64", bzImage64_probe, bzImage64_load, bzImage64_usage }, { "bzImage", bzImage_probe, bzImage_load, bzImage_usage }, { "beoboot-x86", beoboot_probe, beoboot_load, beoboot_usage }, { "nbi-x86", nbi_probe, nbi_load, nbi_usage },
bzImage64_probe will be run before bzImage_probe.
and if it find that is 64bit, bzImage_probe will not be executed.
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
In reply to Yinghai LuOn Wed, Nov 21, 2012 at 11:50:56AM -0800, Yinghai Lu wrote:
[..]
Quoted 5 lines
Quoted 1 line
So how do I force a 16bit or 32bit entry using a bzImage64?
kexec -t bzImage -l ....
will load low and use 32bit entry.
Ok, so user needs to enforce image type (using -t option) to bzImage (for a bzImage which supports 64bit entry point) to be able to use 32bit entry.
I think a better option is that bzImage64 loader parses the user specified entry options and call into 32bit bzImage loader if user is asking for 32bit or 16bit entry. For 16bit, we already have option --real-mode option. May be we need to introduce another one for forcing 32bit entry, say --entry-32bit or --protected-mode (whatever makes sense).
Eric will know better but I do think that bzImage64 loader should be able to parse user specified entry point and honor that.
Quoted 3 lines
kexec -t bzImage64 -l ...
kexec -l ...
will try to load high and use 64bit entry.
This one violates the existing syntax where --real-mode is supposed to jump to real mode entry point of bzImage.
Eric will know better but I do think that bzImage64 loader should be able to parse user specified entry point and honor that.
Thanks
Vivek
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 13 lines · Vivek Goyal
On Wed, Nov 21, 2012 at 11:50:56AM -0800, Yinghai Lu wrote:
[..]
Quoted 5 lines
Quoted 1 line
So how do I force a 16bit or 32bit entry using a bzImage64?
kexec -t bzImage -l ....
will load low and use 32bit entry.Ok, so user needs to enforce image type (using -t option) to bzImage (for a bzImage which supports 64bit entry point) to be able to use 32bit entry.
Quoted 5 lines
I think a better option is that bzImage64 loader parses the user specified entry options and call into 32bit bzImage loader if user is asking for 32bit or 16bit entry. For 16bit, we already have option --real-mode option. May be we need to introduce another one for forcing 32bit entry, say --entry-32bit or --protected-mode (whatever makes sense).
that is doable.
add checking entry-32bit and real-mode checking in kexec-bzImage64.c and bail early to leave kexec-bzImage.c to take over.
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 20 lines · Yinghai Lu
Quoted 13 lines · Vivek Goyal
On Wed, Nov 21, 2012 at 11:50:56AM -0800, Yinghai Lu wrote:
[..]
Quoted 5 lines
Quoted 1 line
So how do I force a 16bit or 32bit entry using a bzImage64?
kexec -t bzImage -l ....
will load low and use 32bit entry.Ok, so user needs to enforce image type (using -t option) to bzImage (for a bzImage which supports 64bit entry point) to be able to use 32bit entry.
Quoted 5 lines
I think a better option is that bzImage64 loader parses the user specified entry options and call into 32bit bzImage loader if user is asking for 32bit or 16bit entry. For 16bit, we already have option --real-mode option. May be we need to introduce another one for forcing 32bit entry, say --entry-32bit or --protected-mode (whatever makes sense).
Quoted 4 lines
that is doable.
add checking entry-32bit and real-mode checking in
kexec-bzImage64.cand bail early to leavekexec-bzImage.cto take over.
Or actually can we do reverse. Do not introduce new image format bzImage64. In existing bzImage loader if bzImage version is greater than 0x020c (or whatever version has 64bit entry extension), just call into load_bzImage64().
Thanks
Vivek
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 5 lines · Vivek Goyal
Or actually can we do reverse. Do not introduce new image format bzImage64. In existing bzImage loader if bzImage version is greater than
0x020c(or whatever version has 64bit entry extension), just call intoload_bzImage64().
Eric wanted me to separate that out.
and you want me to put them back?
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
In reply to Yinghai LuQuoted 51 lines · Yinghai Lu
Quoted 41 lines · Vivek Goyal
On Tue, Nov 20, 2012 at 11:31:38PM -0800, Yinghai Lu wrote:
[..]
Quoted 38 lines
kexec/arch/x86_64/kexec-bzImage64.c new file +38
-0+int bzImage64_probe (const char *buf,off_t len) +{ +const struct x86_linux_header *header; +if ((uintmax_t )len < (uintmax_t)(2 *512 )) { +if (probe_debug) { +fprintf (stderr,"File is too short to be a bzImage!\n" ); + } +return -1 ; + } + header = (const struct x86_linux_header *)buf; +if (memcmp (header->header_magic,"HdrS" ,4 ) !=0 ) { +if (probe_debug) { +fprintf (stderr,"Not a bzImage\n" ); + } +return -1 ; + } +if (header->boot_sector_magic !=0xAA55 ) { +if (probe_debug) { +fprintf (stderr,"No x86 boot sector present\n" ); + } +/* No x86 boot sector present */ +return -1 ; + } +if (header->protocol_version <0x020C ) { +if (probe_debug) { +fprintf (stderr,"Must be at least protocol version 2.12\n" ); + } +/* Must be at least protocol version 2.12 */ +return -1 ; + } +if ((header->loadflags &1 ) ==0 ) { +if (probe_debug) { +fprintf (stderr,"zImage not a bzImage\n" ); + } +/* Not a bzImage */ +return -1 ; + } +if (!(header->xloadflags &1 )) {Quoted 8 lines
kexec/arch/x86_64/kexec-bzImage64.c line 89
Quoted 6 lines
kexec/arch/x86_64/kexec-bzImage64.c new file +6
-0+if (probe_debug) { +fprintf (stderr,"Not a bzImage64\n" ); + } +/* Must be LOADED_ABOVE_4G */ +return -1 ; + }So how do I force a 16bit or 32bit entry using a bzImage64?
Quoted 6 lines
kexec -t bzImage -l ....
will load low and use 32bit entry.kexec -t bzImage64 -l ...
kexec -l ...
will try to load high and use 64bit entry.
Also bzImage64 is not really a new image format. It is just enhancement of bzImage format. We keep on doing extention of bzImage and don't call it a new image format. I am not sure how good an idea it is to export the notion of new image type bzImage64 to user.
Thanks
Vivek
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Re: [PATCH v3 4/4] kexec, x86_64: Load bzImage64 above 4G
Quoted 8 lines · Vivek Goyal
Quoted 7 lines · Yinghai Lu
Quoted 2 lines · Vivek Goyal
So how do I force a 16bit or 32bit entry using a bzImage64?
kexec -t bzImage -l ....
will load low and use 32bit entry.
Quoted 8 lines
Quoted 3 lines
kexec -t bzImage64 -l ...
kexec -l ...
will try to load high and use 64bit entry.Also bzImage64 is not really a new image format. It is just enhancement of bzImage format. We keep on doing extention of bzImage and don't call it a new image format. I am not sure how good an idea it is to export the notion of new image type bzImage64 to user.
For what the loader has to do bzImage64 is effectively a new format, and one way or another needs to be handled by separate functions so that the code remains readable.
I asked YH to add the code that way because it means only a 64bit kexec has to carry that code and we don't have 64bit dependencies in in the 32bit build that will break. The code to prepare boot_params is still shared.
Chaining to the 32bit loader if someone asks for --real-mode or perhaps --entry32 seems quite reasonable and only a couple of lines of code so I have not objections to that.
While development is on-going forcing the image type seems very reasonable, but when the smoke clears I would like to see the bzImage64 format chaining to bzImage for the cases it does not handle.
But with respect to autodetection only having bzImage64 kick in when loading a 64bit kernel is possible looks like the right way to go.
Eric
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec