Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-22 Thread Baoquan He
On 02/21/15 at 10:49am, Baoquan He wrote:
> On 02/20/15 at 03:53pm, Yinghai Lu wrote:
> > Then you are not setting  the ident mapping correctly.
> > 
> > you should make sure add extra ident mapping for the new [output,
> > output+output_len - 1].
> > bootloader only cover old [output, output+output_len - 1]
> > 
> > and you should check if the mapping is present before add new one,
> > otherwise will overrite
> > the one from 64bit bootloader like kexec-tools or grub2-x86_64 etc.
> > 
> > You could use kernel_ident_mapping_init() from arch/x86/mm/init_64.c
> > --- may need to cut and paste or split and include to
> > arch/x86/boot/compressed/misc.c
> > also you need to find some pages for alloc_pgt_page.
> 
> At the beginning I did it just as you said, add IDT table and $PF
> handler. Get page fault address and built ident mapping around it when
> reload kernel above 4G. In this case 3 more pages are enough if kernel
  ~~
   typo, it should be 4

> is put to another 512G and cross the boundary of 512G.
> kernel_ident_mapping_init code can be borrowed and need be adjusted a
> little bit. This works as expected, but a GPF reported and reboot to
> BIOS. That's why I made a simple debug patch as I pasted before to
> filter unnecessary interference.
> 
> Since in arch/x86/boot/compressed/head_64.S 6 pages are used, 1 for pgd,
> 1 for pud, 4 for pmd, all of them cover 0~4G ident mapping. So I added 4
> more pages as pmd, then 0~8G are covered. Now I hardcoded the output of
> randomization of physical address as 5G, means kernel will be reloaded
> there and decompressed. With these ident mapping for this hard coded
> address should be correctly setted, still that GPF will happen. I
> borrowed a printf.c from arch/x86/boot and made it work for
> boot/compressed, can see in this case it will decompress successfully
> and jump into arch/x86/kernel/head_64.S, then it reboot there during a
> jump.
> 
> > 
> > Thanks
> > 
> > Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-22 Thread Baoquan He
On 02/21/15 at 10:49am, Baoquan He wrote:
 On 02/20/15 at 03:53pm, Yinghai Lu wrote:
  Then you are not setting  the ident mapping correctly.
  
  you should make sure add extra ident mapping for the new [output,
  output+output_len - 1].
  bootloader only cover old [output, output+output_len - 1]
  
  and you should check if the mapping is present before add new one,
  otherwise will overrite
  the one from 64bit bootloader like kexec-tools or grub2-x86_64 etc.
  
  You could use kernel_ident_mapping_init() from arch/x86/mm/init_64.c
  --- may need to cut and paste or split and include to
  arch/x86/boot/compressed/misc.c
  also you need to find some pages for alloc_pgt_page.
 
 At the beginning I did it just as you said, add IDT table and $PF
 handler. Get page fault address and built ident mapping around it when
 reload kernel above 4G. In this case 3 more pages are enough if kernel
  ~~
   typo, it should be 4

 is put to another 512G and cross the boundary of 512G.
 kernel_ident_mapping_init code can be borrowed and need be adjusted a
 little bit. This works as expected, but a GPF reported and reboot to
 BIOS. That's why I made a simple debug patch as I pasted before to
 filter unnecessary interference.
 
 Since in arch/x86/boot/compressed/head_64.S 6 pages are used, 1 for pgd,
 1 for pud, 4 for pmd, all of them cover 0~4G ident mapping. So I added 4
 more pages as pmd, then 0~8G are covered. Now I hardcoded the output of
 randomization of physical address as 5G, means kernel will be reloaded
 there and decompressed. With these ident mapping for this hard coded
 address should be correctly setted, still that GPF will happen. I
 borrowed a printf.c from arch/x86/boot and made it work for
 boot/compressed, can see in this case it will decompress successfully
 and jump into arch/x86/kernel/head_64.S, then it reboot there during a
 jump.
 
  
  Thanks
  
  Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-21 Thread Yinghai Lu
On Fri, Feb 20, 2015 at 6:49 PM, Baoquan He  wrote:
> On 02/20/15 at 03:53pm, Yinghai Lu wrote:
> At the beginning I did it just as you said, add IDT table and $PF
> handler. Get page fault address and built ident mapping around it when
> reload kernel above 4G. In this case 3 more pages are enough if kernel
> is put to another 512G and cross the boundary of 512G.
> kernel_ident_mapping_init code can be borrowed and need be adjusted a
> little bit. This works as expected, but a GPF reported and reboot to
> BIOS. That's why I made a simple debug patch as I pasted before to
> filter unnecessary interference.

Please use attached one to instead of the #PF handler in boot stage.
It works when hard-code to move output above 4G.

From: Yinghai Lu 
Subject: [PATCH] x86, boot: Enable ident_mapping for kasl above 4G for 64bit

split kernel_ident_mapping_init() and call that in boot::misc.c stage.
it will cover new range kernel space that is above 4G.

Signed-off-by: Yinghai Lu 

---
 arch/x86/boot/compressed/misc.c |   10 
 arch/x86/boot/compressed/misc_pgt.c |   61 +
 arch/x86/include/asm/page.h |5 ++
 arch/x86/mm/ident_map.c |   74 
 arch/x86/mm/init_64.c   |   74 
 5 files changed, 151 insertions(+), 73 deletions(-)

Index: linux-2.6/arch/x86/boot/compressed/misc.c
===
--- linux-2.6.orig/arch/x86/boot/compressed/misc.c
+++ linux-2.6/arch/x86/boot/compressed/misc.c
@@ -9,6 +9,11 @@
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  */

+#ifdef CONFIG_X86_64
+#define __pa(x)  ((unsigned long)(x))
+#define __va(x)  ((void *)((unsigned long)(x)))
+#endif
+
 #include "misc.h"
 #include "../string.h"

@@ -366,6 +371,8 @@ static void parse_elf(void *output)
 free(phdrs);
 }

+#include "misc_pgt.c"
+
 asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
   unsigned char *input_data,
   unsigned long input_len,
@@ -421,6 +428,9 @@ asmlinkage __visible void *decompress_ke
 error("Wrong destination address");
 #endif

+if (output != output_orig)
+fill_linux64_pagetable((unsigned long)output, output_len);
+
 debug_putstr("\nDecompressing Linux... ");
 decompress(input_data, input_len, NULL, NULL, output, NULL, error);
 parse_elf(output);
Index: linux-2.6/arch/x86/include/asm/page.h
===
--- linux-2.6.orig/arch/x86/include/asm/page.h
+++ linux-2.6/arch/x86/include/asm/page.h
@@ -37,7 +37,10 @@ static inline void copy_user_page(void *
 alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
 #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE

+#ifndef __pa
 #define __pa(x)__phys_addr((unsigned long)(x))
+#endif
+
 #define __pa_nodebug(x)__phys_addr_nodebug((unsigned long)(x))
 /* __pa_symbol should be used for C visible symbols.
This seems to be the official gcc blessed way to do such arithmetic. */
@@ -51,7 +54,9 @@ static inline void copy_user_page(void *
 #define __pa_symbol(x) \
 __phys_addr_symbol(__phys_reloc_hide((unsigned long)(x)))

+#ifndef __va
 #define __va(x)((void *)((unsigned long)(x)+PAGE_OFFSET))
+#endif

 #define __boot_va(x)__va(x)
 #define __boot_pa(x)__pa(x)
Index: linux-2.6/arch/x86/boot/compressed/misc_pgt.c
===
--- /dev/null
+++ linux-2.6/arch/x86/boot/compressed/misc_pgt.c
@@ -0,0 +1,61 @@
+
+#ifdef CONFIG_X86_64
+#include 
+#include 
+
+#include "../../mm/ident_map.h"
+
+struct alloc_pgt_data {
+unsigned char *pgt_buf;
+unsigned long pgt_buf_size;
+unsigned long pgt_buf_offset;
+};
+
+static void *alloc_pgt_page(void *context)
+{
+struct alloc_pgt_data *d = (struct alloc_pgt_data *)context;
+unsigned char *p = (unsigned char *)d->pgt_buf;
+
+if (d->pgt_buf_offset >= d->pgt_buf_size) {
+debug_putstr("out of pgt_buf in misc.c\n");
+return NULL;
+}
+
+p += d->pgt_buf_offset;
+d->pgt_buf_offset += 4096;
+memset(p, 0, 4096);
+
+return p;
+}
+
+#define PGT_BUF_SIZE (4096*4)
+
+unsigned long __force_order;
+static unsigned char pgt_buf[PGT_BUF_SIZE] __aligned(4096);
+
+static void fill_linux64_pagetable(unsigned long start, unsigned long size)
+{
+struct alloc_pgt_data data = {
+.pgt_buf = (unsigned char *) pgt_buf,
+.pgt_buf_size = sizeof(pgt_buf),
+.pgt_buf_offset = 0,
+};
+struct x86_mapping_info mapping_info = {
+.alloc_pgt_page = alloc_pgt_page,
+.context = ,
+.pmd_flag = __PAGE_KERNEL_LARGE_EXEC,
+};
+unsigned long end = start + size;
+pgd_t *level4p = (pgd_t *)read_cr3();
+
+/* align boundary to 2M */
+start = (start >> 21) << 21;
+end = ((end + (1<<21) - 1) >> 21) 

Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-21 Thread Yinghai Lu
On Fri, Feb 20, 2015 at 6:49 PM, Baoquan He b...@redhat.com wrote:
 On 02/20/15 at 03:53pm, Yinghai Lu wrote:
 At the beginning I did it just as you said, add IDT table and $PF
 handler. Get page fault address and built ident mapping around it when
 reload kernel above 4G. In this case 3 more pages are enough if kernel
 is put to another 512G and cross the boundary of 512G.
 kernel_ident_mapping_init code can be borrowed and need be adjusted a
 little bit. This works as expected, but a GPF reported and reboot to
 BIOS. That's why I made a simple debug patch as I pasted before to
 filter unnecessary interference.

Please use attached one to instead of the #PF handler in boot stage.
It works when hard-code to move output above 4G.

From: Yinghai Lu ying...@kernel.org
Subject: [PATCH] x86, boot: Enable ident_mapping for kasl above 4G for 64bit

split kernel_ident_mapping_init() and call that in boot::misc.c stage.
it will cover new range kernel space that is above 4G.

Signed-off-by: Yinghai Lu ying...@kernel.org

---
 arch/x86/boot/compressed/misc.c |   10 
 arch/x86/boot/compressed/misc_pgt.c |   61 +
 arch/x86/include/asm/page.h |5 ++
 arch/x86/mm/ident_map.c |   74 
 arch/x86/mm/init_64.c   |   74 
 5 files changed, 151 insertions(+), 73 deletions(-)

Index: linux-2.6/arch/x86/boot/compressed/misc.c
===
--- linux-2.6.orig/arch/x86/boot/compressed/misc.c
+++ linux-2.6/arch/x86/boot/compressed/misc.c
@@ -9,6 +9,11 @@
  * High loaded stuff by Hans Lermen  Werner Almesberger, Feb. 1996
  */

+#ifdef CONFIG_X86_64
+#define __pa(x)  ((unsigned long)(x))
+#define __va(x)  ((void *)((unsigned long)(x)))
+#endif
+
 #include misc.h
 #include ../string.h

@@ -366,6 +371,8 @@ static void parse_elf(void *output)
 free(phdrs);
 }

+#include misc_pgt.c
+
 asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
   unsigned char *input_data,
   unsigned long input_len,
@@ -421,6 +428,9 @@ asmlinkage __visible void *decompress_ke
 error(Wrong destination address);
 #endif

+if (output != output_orig)
+fill_linux64_pagetable((unsigned long)output, output_len);
+
 debug_putstr(\nDecompressing Linux... );
 decompress(input_data, input_len, NULL, NULL, output, NULL, error);
 parse_elf(output);
Index: linux-2.6/arch/x86/include/asm/page.h
===
--- linux-2.6.orig/arch/x86/include/asm/page.h
+++ linux-2.6/arch/x86/include/asm/page.h
@@ -37,7 +37,10 @@ static inline void copy_user_page(void *
 alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
 #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE

+#ifndef __pa
 #define __pa(x)__phys_addr((unsigned long)(x))
+#endif
+
 #define __pa_nodebug(x)__phys_addr_nodebug((unsigned long)(x))
 /* __pa_symbol should be used for C visible symbols.
This seems to be the official gcc blessed way to do such arithmetic. */
@@ -51,7 +54,9 @@ static inline void copy_user_page(void *
 #define __pa_symbol(x) \
 __phys_addr_symbol(__phys_reloc_hide((unsigned long)(x)))

+#ifndef __va
 #define __va(x)((void *)((unsigned long)(x)+PAGE_OFFSET))
+#endif

 #define __boot_va(x)__va(x)
 #define __boot_pa(x)__pa(x)
Index: linux-2.6/arch/x86/boot/compressed/misc_pgt.c
===
--- /dev/null
+++ linux-2.6/arch/x86/boot/compressed/misc_pgt.c
@@ -0,0 +1,61 @@
+
+#ifdef CONFIG_X86_64
+#include asm/init.h
+#include asm/pgtable.h
+
+#include ../../mm/ident_map.h
+
+struct alloc_pgt_data {
+unsigned char *pgt_buf;
+unsigned long pgt_buf_size;
+unsigned long pgt_buf_offset;
+};
+
+static void *alloc_pgt_page(void *context)
+{
+struct alloc_pgt_data *d = (struct alloc_pgt_data *)context;
+unsigned char *p = (unsigned char *)d-pgt_buf;
+
+if (d-pgt_buf_offset = d-pgt_buf_size) {
+debug_putstr(out of pgt_buf in misc.c\n);
+return NULL;
+}
+
+p += d-pgt_buf_offset;
+d-pgt_buf_offset += 4096;
+memset(p, 0, 4096);
+
+return p;
+}
+
+#define PGT_BUF_SIZE (4096*4)
+
+unsigned long __force_order;
+static unsigned char pgt_buf[PGT_BUF_SIZE] __aligned(4096);
+
+static void fill_linux64_pagetable(unsigned long start, unsigned long size)
+{
+struct alloc_pgt_data data = {
+.pgt_buf = (unsigned char *) pgt_buf,
+.pgt_buf_size = sizeof(pgt_buf),
+.pgt_buf_offset = 0,
+};
+struct x86_mapping_info mapping_info = {
+.alloc_pgt_page = alloc_pgt_page,
+.context = data,
+.pmd_flag = __PAGE_KERNEL_LARGE_EXEC,
+};
+unsigned long end = start + size;
+pgd_t *level4p = (pgd_t *)read_cr3();
+
+/* align boundary to 2M */
+start = (start  21)  

Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-20 Thread Baoquan He
On 02/20/15 at 03:53pm, Yinghai Lu wrote:
> On Fri, Feb 20, 2015 at 1:28 AM, Baoquan He  wrote:
> >
> > Actually kexec is a bootloader which can put kernel at any address. This
> > is done in user space program kexec-tools. However kexec-tools make
> > kernel jump from 64bit into 64bit directly, and has built ident mapping
> > of whole physical memory. I have tried this and it works. kexec is
> > mainly used for kernel developer, kaslr is meaningless for kexec.
> >
> > However kaslr focus on normal kernel, and jump from 32bit to 64bit mode.
> > I can't figure out a way to work around this.
> >
> > Now I just want to figure out what register setting cause GPF when
> > reload kernel above 4G in this jumping from 32bit to 64bit way.
> 
> Then you are not setting  the ident mapping correctly.
> 
> you should make sure add extra ident mapping for the new [output,
> output+output_len - 1].
> bootloader only cover old [output, output+output_len - 1]
> 
> and you should check if the mapping is present before add new one,
> otherwise will overrite
> the one from 64bit bootloader like kexec-tools or grub2-x86_64 etc.
> 
> You could use kernel_ident_mapping_init() from arch/x86/mm/init_64.c
> --- may need to cut and paste or split and include to
> arch/x86/boot/compressed/misc.c
> also you need to find some pages for alloc_pgt_page.

At the beginning I did it just as you said, add IDT table and $PF
handler. Get page fault address and built ident mapping around it when
reload kernel above 4G. In this case 3 more pages are enough if kernel
is put to another 512G and cross the boundary of 512G.
kernel_ident_mapping_init code can be borrowed and need be adjusted a
little bit. This works as expected, but a GPF reported and reboot to
BIOS. That's why I made a simple debug patch as I pasted before to
filter unnecessary interference.

Since in arch/x86/boot/compressed/head_64.S 6 pages are used, 1 for pgd,
1 for pud, 4 for pmd, all of them cover 0~4G ident mapping. So I added 4
more pages as pmd, then 0~8G are covered. Now I hardcoded the output of
randomization of physical address as 5G, means kernel will be reloaded
there and decompressed. With these ident mapping for this hard coded
address should be correctly setted, still that GPF will happen. I
borrowed a printf.c from arch/x86/boot and made it work for
boot/compressed, can see in this case it will decompress successfully
and jump into arch/x86/kernel/head_64.S, then it reboot there during a
jump.

> 
> Thanks
> 
> Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-20 Thread Yinghai Lu
On Fri, Feb 20, 2015 at 1:28 AM, Baoquan He  wrote:
>
> Actually kexec is a bootloader which can put kernel at any address. This
> is done in user space program kexec-tools. However kexec-tools make
> kernel jump from 64bit into 64bit directly, and has built ident mapping
> of whole physical memory. I have tried this and it works. kexec is
> mainly used for kernel developer, kaslr is meaningless for kexec.
>
> However kaslr focus on normal kernel, and jump from 32bit to 64bit mode.
> I can't figure out a way to work around this.
>
> Now I just want to figure out what register setting cause GPF when
> reload kernel above 4G in this jumping from 32bit to 64bit way.

Then you are not setting  the ident mapping correctly.

you should make sure add extra ident mapping for the new [output,
output+output_len - 1].
bootloader only cover old [output, output+output_len - 1]

and you should check if the mapping is present before add new one,
otherwise will overrite
the one from 64bit bootloader like kexec-tools or grub2-x86_64 etc.

You could use kernel_ident_mapping_init() from arch/x86/mm/init_64.c
--- may need to cut and paste or split and include to
arch/x86/boot/compressed/misc.c
also you need to find some pages for alloc_pgt_page.

Thanks

Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-20 Thread Baoquan He
On 02/19/15 at 07:35pm, Yinghai Lu wrote:
> On Thu, Feb 19, 2015 at 6:13 PM, Baoquan He  wrote:
> > On 02/18/15 at 11:47am, Yinghai Lu wrote:
> >
> > Kaslr need both virtual and physical address be randomized, otherwise
> > it doesn't make sense. Please check what hpa said about this issue:
> >
> > https://lkml.org/lkml/2014/10/13/350
> >
> 
> If I read correctly, it could be separated. phy one could be on bootloader
> and virtual could be in kernel.

I think people want physical address randomization too. This is
what Vivek replied to hpa's comment:

https://lkml.org/lkml/2014/10/13/377

And after I posted the patchset handling randomization of virtual and
physical address separately, Kees Cook also think it makes sense:
http://www.gossamer-threads.com/lists/linux/kernel/2090014

> 
> > And usually no bootloader often load kernel onto a random physical
> > address. Fow now we can often see kexec/kdump did this. I believe Kees
> > introduced kaslr to mainly solve security issue of normal kernel which
> > is not like kexec/kdump for testing or debugging. Randomizing physical
> > address makes sense for kaslr feature.
> 
> I put some grub2 patches that extend grub2 to load kernel/initrd above
> 4G into github tree.
> 
> https://github.com/yhlu/grub2.git
> 
> main purpose for that feature is to handle initrd that bigger than 4G.
> 
> or you can try you solution on system that have 64bit EFI support,
> then you will don't need to
> worry about set ident mapping even.

Actually kexec is a bootloader which can put kernel at any address. This
is done in user space program kexec-tools. However kexec-tools make
kernel jump from 64bit into 64bit directly, and has built ident mapping
of whole physical memory. I have tried this and it works. kexec is
mainly used for kernel developer, kaslr is meaningless for kexec.

However kaslr focus on normal kernel, and jump from 32bit to 64bit mode.
I can't figure out a way to work around this.

Now I just want to figure out what register setting cause GPF when
reload kernel above 4G in this jumping from 32bit to 64bit way.

> 
> Thanks
> 
> Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-20 Thread Baoquan He
On 02/19/15 at 07:35pm, Yinghai Lu wrote:
 On Thu, Feb 19, 2015 at 6:13 PM, Baoquan He b...@redhat.com wrote:
  On 02/18/15 at 11:47am, Yinghai Lu wrote:
 
  Kaslr need both virtual and physical address be randomized, otherwise
  it doesn't make sense. Please check what hpa said about this issue:
 
  https://lkml.org/lkml/2014/10/13/350
 
 
 If I read correctly, it could be separated. phy one could be on bootloader
 and virtual could be in kernel.

I think people want physical address randomization too. This is
what Vivek replied to hpa's comment:

https://lkml.org/lkml/2014/10/13/377

And after I posted the patchset handling randomization of virtual and
physical address separately, Kees Cook also think it makes sense:
http://www.gossamer-threads.com/lists/linux/kernel/2090014

 
  And usually no bootloader often load kernel onto a random physical
  address. Fow now we can often see kexec/kdump did this. I believe Kees
  introduced kaslr to mainly solve security issue of normal kernel which
  is not like kexec/kdump for testing or debugging. Randomizing physical
  address makes sense for kaslr feature.
 
 I put some grub2 patches that extend grub2 to load kernel/initrd above
 4G into github tree.
 
 https://github.com/yhlu/grub2.git
 
 main purpose for that feature is to handle initrd that bigger than 4G.
 
 or you can try you solution on system that have 64bit EFI support,
 then you will don't need to
 worry about set ident mapping even.

Actually kexec is a bootloader which can put kernel at any address. This
is done in user space program kexec-tools. However kexec-tools make
kernel jump from 64bit into 64bit directly, and has built ident mapping
of whole physical memory. I have tried this and it works. kexec is
mainly used for kernel developer, kaslr is meaningless for kexec.

However kaslr focus on normal kernel, and jump from 32bit to 64bit mode.
I can't figure out a way to work around this.

Now I just want to figure out what register setting cause GPF when
reload kernel above 4G in this jumping from 32bit to 64bit way.

 
 Thanks
 
 Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-20 Thread Yinghai Lu
On Fri, Feb 20, 2015 at 1:28 AM, Baoquan He b...@redhat.com wrote:

 Actually kexec is a bootloader which can put kernel at any address. This
 is done in user space program kexec-tools. However kexec-tools make
 kernel jump from 64bit into 64bit directly, and has built ident mapping
 of whole physical memory. I have tried this and it works. kexec is
 mainly used for kernel developer, kaslr is meaningless for kexec.

 However kaslr focus on normal kernel, and jump from 32bit to 64bit mode.
 I can't figure out a way to work around this.

 Now I just want to figure out what register setting cause GPF when
 reload kernel above 4G in this jumping from 32bit to 64bit way.

Then you are not setting  the ident mapping correctly.

you should make sure add extra ident mapping for the new [output,
output+output_len - 1].
bootloader only cover old [output, output+output_len - 1]

and you should check if the mapping is present before add new one,
otherwise will overrite
the one from 64bit bootloader like kexec-tools or grub2-x86_64 etc.

You could use kernel_ident_mapping_init() from arch/x86/mm/init_64.c
--- may need to cut and paste or split and include to
arch/x86/boot/compressed/misc.c
also you need to find some pages for alloc_pgt_page.

Thanks

Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-20 Thread Baoquan He
On 02/20/15 at 03:53pm, Yinghai Lu wrote:
 On Fri, Feb 20, 2015 at 1:28 AM, Baoquan He b...@redhat.com wrote:
 
  Actually kexec is a bootloader which can put kernel at any address. This
  is done in user space program kexec-tools. However kexec-tools make
  kernel jump from 64bit into 64bit directly, and has built ident mapping
  of whole physical memory. I have tried this and it works. kexec is
  mainly used for kernel developer, kaslr is meaningless for kexec.
 
  However kaslr focus on normal kernel, and jump from 32bit to 64bit mode.
  I can't figure out a way to work around this.
 
  Now I just want to figure out what register setting cause GPF when
  reload kernel above 4G in this jumping from 32bit to 64bit way.
 
 Then you are not setting  the ident mapping correctly.
 
 you should make sure add extra ident mapping for the new [output,
 output+output_len - 1].
 bootloader only cover old [output, output+output_len - 1]
 
 and you should check if the mapping is present before add new one,
 otherwise will overrite
 the one from 64bit bootloader like kexec-tools or grub2-x86_64 etc.
 
 You could use kernel_ident_mapping_init() from arch/x86/mm/init_64.c
 --- may need to cut and paste or split and include to
 arch/x86/boot/compressed/misc.c
 also you need to find some pages for alloc_pgt_page.

At the beginning I did it just as you said, add IDT table and $PF
handler. Get page fault address and built ident mapping around it when
reload kernel above 4G. In this case 3 more pages are enough if kernel
is put to another 512G and cross the boundary of 512G.
kernel_ident_mapping_init code can be borrowed and need be adjusted a
little bit. This works as expected, but a GPF reported and reboot to
BIOS. That's why I made a simple debug patch as I pasted before to
filter unnecessary interference.

Since in arch/x86/boot/compressed/head_64.S 6 pages are used, 1 for pgd,
1 for pud, 4 for pmd, all of them cover 0~4G ident mapping. So I added 4
more pages as pmd, then 0~8G are covered. Now I hardcoded the output of
randomization of physical address as 5G, means kernel will be reloaded
there and decompressed. With these ident mapping for this hard coded
address should be correctly setted, still that GPF will happen. I
borrowed a printf.c from arch/x86/boot and made it work for
boot/compressed, can see in this case it will decompress successfully
and jump into arch/x86/kernel/head_64.S, then it reboot there during a
jump.

 
 Thanks
 
 Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-19 Thread Yinghai Lu
On Thu, Feb 19, 2015 at 6:13 PM, Baoquan He  wrote:
> On 02/18/15 at 11:47am, Yinghai Lu wrote:
>
> Kaslr need both virtual and physical address be randomized, otherwise
> it doesn't make sense. Please check what hpa said about this issue:
>
> https://lkml.org/lkml/2014/10/13/350
>

If I read correctly, it could be separated. phy one could be on bootloader
and virtual could be in kernel.

> And usually no bootloader often load kernel onto a random physical
> address. Fow now we can often see kexec/kdump did this. I believe Kees
> introduced kaslr to mainly solve security issue of normal kernel which
> is not like kexec/kdump for testing or debugging. Randomizing physical
> address makes sense for kaslr feature.

I put some grub2 patches that extend grub2 to load kernel/initrd above
4G into github tree.

https://github.com/yhlu/grub2.git

main purpose for that feature is to handle initrd that bigger than 4G.

or you can try you solution on system that have 64bit EFI support,
then you will don't need to
worry about set ident mapping even.

Thanks

Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-19 Thread Baoquan He
On 02/18/15 at 11:47am, Yinghai Lu wrote:
> On Wed, Feb 18, 2015 at 3:29 AM, Baoquan He  wrote:
> > On 02/17/15 at 11:22pm, Yinghai Lu wrote:
> >> On Tue, Feb 10, 2015 at 10:11 PM, Baoquan He  wrote:
> > I am sorry I didn't get what you mean. I have tried to set another ident
> > mapping for new range and it is successful seeing from debug message
> > printing. However it always reboot because of GPF. That's why I made
> > that small debug patch which add another 4G ident mapping and hardcoded
> > to put kernel between 4G and 8G.
> >
> > Could you say more of it?  Or which direction should I go?
> 
> I would suggest:
> leave physical address random handling to bootloader, as bootloader always
> need to set ident mapping to cover kernel/bootparam/cmdline.
> 
> For virtual address random handling it should go kasl in kernel.

Kaslr need both virtual and physical address be randomized, otherwise
it doesn't make sense. Please check what hpa said about this issue:

https://lkml.org/lkml/2014/10/13/350

And usually no bootloader often load kernel onto a random physical
address. Fow now we can often see kexec/kdump did this. I believe Kees
introduced kaslr to mainly solve security issue of normal kernel which
is not like kexec/kdump for testing or debugging. Randomizing physical
address makes sense for kaslr feature.

In normal kernel it jump from 32bit to 64bit and enter into 64bit mode
of long mode. I am wondering why it will cause a GPF when kernel is put
above 4G. Adding a IDT and #PF handler to solve the ident page mapping
on demand has been done now, I am blocked by the GPF now, otherwise I can
post it very soon for testing.

Thanks
Baoquan
> 
> Thanks
> 
> Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-19 Thread Baoquan He
On 02/18/15 at 11:47am, Yinghai Lu wrote:
 On Wed, Feb 18, 2015 at 3:29 AM, Baoquan He b...@redhat.com wrote:
  On 02/17/15 at 11:22pm, Yinghai Lu wrote:
  On Tue, Feb 10, 2015 at 10:11 PM, Baoquan He b...@redhat.com wrote:
  I am sorry I didn't get what you mean. I have tried to set another ident
  mapping for new range and it is successful seeing from debug message
  printing. However it always reboot because of GPF. That's why I made
  that small debug patch which add another 4G ident mapping and hardcoded
  to put kernel between 4G and 8G.
 
  Could you say more of it?  Or which direction should I go?
 
 I would suggest:
 leave physical address random handling to bootloader, as bootloader always
 need to set ident mapping to cover kernel/bootparam/cmdline.
 
 For virtual address random handling it should go kasl in kernel.

Kaslr need both virtual and physical address be randomized, otherwise
it doesn't make sense. Please check what hpa said about this issue:

https://lkml.org/lkml/2014/10/13/350

And usually no bootloader often load kernel onto a random physical
address. Fow now we can often see kexec/kdump did this. I believe Kees
introduced kaslr to mainly solve security issue of normal kernel which
is not like kexec/kdump for testing or debugging. Randomizing physical
address makes sense for kaslr feature.

In normal kernel it jump from 32bit to 64bit and enter into 64bit mode
of long mode. I am wondering why it will cause a GPF when kernel is put
above 4G. Adding a IDT and #PF handler to solve the ident page mapping
on demand has been done now, I am blocked by the GPF now, otherwise I can
post it very soon for testing.

Thanks
Baoquan
 
 Thanks
 
 Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-19 Thread Yinghai Lu
On Thu, Feb 19, 2015 at 6:13 PM, Baoquan He b...@redhat.com wrote:
 On 02/18/15 at 11:47am, Yinghai Lu wrote:

 Kaslr need both virtual and physical address be randomized, otherwise
 it doesn't make sense. Please check what hpa said about this issue:

 https://lkml.org/lkml/2014/10/13/350


If I read correctly, it could be separated. phy one could be on bootloader
and virtual could be in kernel.

 And usually no bootloader often load kernel onto a random physical
 address. Fow now we can often see kexec/kdump did this. I believe Kees
 introduced kaslr to mainly solve security issue of normal kernel which
 is not like kexec/kdump for testing or debugging. Randomizing physical
 address makes sense for kaslr feature.

I put some grub2 patches that extend grub2 to load kernel/initrd above
4G into github tree.

https://github.com/yhlu/grub2.git

main purpose for that feature is to handle initrd that bigger than 4G.

or you can try you solution on system that have 64bit EFI support,
then you will don't need to
worry about set ident mapping even.

Thanks

Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-18 Thread Yinghai Lu
On Wed, Feb 18, 2015 at 3:29 AM, Baoquan He  wrote:
> On 02/17/15 at 11:22pm, Yinghai Lu wrote:
>> On Tue, Feb 10, 2015 at 10:11 PM, Baoquan He  wrote:
> I am sorry I didn't get what you mean. I have tried to set another ident
> mapping for new range and it is successful seeing from debug message
> printing. However it always reboot because of GPF. That's why I made
> that small debug patch which add another 4G ident mapping and hardcoded
> to put kernel between 4G and 8G.
>
> Could you say more of it?  Or which direction should I go?

I would suggest:
leave physical address random handling to bootloader, as bootloader always
need to set ident mapping to cover kernel/bootparam/cmdline.

For virtual address random handling it should go kasl in kernel.

Thanks

Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-18 Thread Baoquan He
On 02/17/15 at 11:22pm, Yinghai Lu wrote:
> On Tue, Feb 10, 2015 at 10:11 PM, Baoquan He  wrote:
> > Hi Yinghai,
> >
> > Could you please help to have a look at a problem which I encountered?
> >
> > I am trying to make kaslr randomize on both kernel physical and virtual
> > address separately. Now the separate randomization has been done,
> > kernel physical address can be randomized to [16M, 4G], and virtual
> > address can be randomzed to [16M, 1G]. Below is the post.
> > http://thread.gmane.org/gmane.linux.kernel/1870532
> >
> > Now I am trying to make kernel physical address randomize anywhere, not
> > limited to below 4G. As you know in arch/x86/boot/compressed/head_64.S a
> > identity mapping of 0~4G has been built, for address above 4G I added an
> > IDT and #PF handler. Then I hardcoded the output address of
> > choose_kernel_location as 5G, the #PF handler worked, however it will
> > reboot in arch/x86/kernel/head_64.S.
> 
> For 64bit, I'd like to see bootloader could load kernel to random hw address.
> 
> otherwise you will need to set another ident mapping for new range.

Hi Yinghai,

I am sorry I didn't get what you mean. I have tried to set another ident
mapping for new range and it is successful seeing from debug message
printing. However it always reboot because of GPF. That's why I made
that small debug patch which add another 4G ident mapping and hardcoded
to put kernel between 4G and 8G.

Could you say more of it?  Or which direction should I go?

Thanks a lot for your help!

Thanks
Baoquan

> 
> Thanks
> 
> Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-18 Thread Baoquan He
On 02/17/15 at 11:22pm, Yinghai Lu wrote:
 On Tue, Feb 10, 2015 at 10:11 PM, Baoquan He b...@redhat.com wrote:
  Hi Yinghai,
 
  Could you please help to have a look at a problem which I encountered?
 
  I am trying to make kaslr randomize on both kernel physical and virtual
  address separately. Now the separate randomization has been done,
  kernel physical address can be randomized to [16M, 4G], and virtual
  address can be randomzed to [16M, 1G]. Below is the post.
  http://thread.gmane.org/gmane.linux.kernel/1870532
 
  Now I am trying to make kernel physical address randomize anywhere, not
  limited to below 4G. As you know in arch/x86/boot/compressed/head_64.S a
  identity mapping of 0~4G has been built, for address above 4G I added an
  IDT and #PF handler. Then I hardcoded the output address of
  choose_kernel_location as 5G, the #PF handler worked, however it will
  reboot in arch/x86/kernel/head_64.S.
 
 For 64bit, I'd like to see bootloader could load kernel to random hw address.
 
 otherwise you will need to set another ident mapping for new range.

Hi Yinghai,

I am sorry I didn't get what you mean. I have tried to set another ident
mapping for new range and it is successful seeing from debug message
printing. However it always reboot because of GPF. That's why I made
that small debug patch which add another 4G ident mapping and hardcoded
to put kernel between 4G and 8G.

Could you say more of it?  Or which direction should I go?

Thanks a lot for your help!

Thanks
Baoquan

 
 Thanks
 
 Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-18 Thread Yinghai Lu
On Wed, Feb 18, 2015 at 3:29 AM, Baoquan He b...@redhat.com wrote:
 On 02/17/15 at 11:22pm, Yinghai Lu wrote:
 On Tue, Feb 10, 2015 at 10:11 PM, Baoquan He b...@redhat.com wrote:
 I am sorry I didn't get what you mean. I have tried to set another ident
 mapping for new range and it is successful seeing from debug message
 printing. However it always reboot because of GPF. That's why I made
 that small debug patch which add another 4G ident mapping and hardcoded
 to put kernel between 4G and 8G.

 Could you say more of it?  Or which direction should I go?

I would suggest:
leave physical address random handling to bootloader, as bootloader always
need to set ident mapping to cover kernel/bootparam/cmdline.

For virtual address random handling it should go kasl in kernel.

Thanks

Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-17 Thread Yinghai Lu
On Wed, Feb 4, 2015 at 10:09 PM, Dave Young  wrote:
> On 02/04/15 at 09:25pm, Yinghai Lu wrote:
>> On Wed, Feb 4, 2015 at 7:25 PM, Dave Young  wrote:
>> >> After this patch, could use patched grub2-x86_64.efi to place
>> >> kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
>> >> above 4G.
>> >
>> > Can you share the grub2 patch for testing?
>>
>> Please check attached 5 patches. last one is for debug purpose.
>>
>> You need to apply them on top of
>>
>> git://git.savannah.gnu.org/grub.git
>>
>> plus  
>> http://pkgs.fedoraproject.org/cgit/grub2.git/plain/0091-Add-support-for-linuxefi.patch
>

FYI, I put those patches together with patches that extend grub2 to load
kernel/initrd above 4G into github tree.

https://github.com/yhlu/grub2.git

Thanks

Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-17 Thread Yinghai Lu
On Tue, Feb 10, 2015 at 10:11 PM, Baoquan He  wrote:
> Hi Yinghai,
>
> Could you please help to have a look at a problem which I encountered?
>
> I am trying to make kaslr randomize on both kernel physical and virtual
> address separately. Now the separate randomization has been done,
> kernel physical address can be randomized to [16M, 4G], and virtual
> address can be randomzed to [16M, 1G]. Below is the post.
> http://thread.gmane.org/gmane.linux.kernel/1870532
>
> Now I am trying to make kernel physical address randomize anywhere, not
> limited to below 4G. As you know in arch/x86/boot/compressed/head_64.S a
> identity mapping of 0~4G has been built, for address above 4G I added an
> IDT and #PF handler. Then I hardcoded the output address of
> choose_kernel_location as 5G, the #PF handler worked, however it will
> reboot in arch/x86/kernel/head_64.S.

For 64bit, I'd like to see bootloader could load kernel to random hw address.

otherwise you will need to set another ident mapping for new range.

Thanks

Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-17 Thread Yinghai Lu
On Tue, Feb 10, 2015 at 10:11 PM, Baoquan He b...@redhat.com wrote:
 Hi Yinghai,

 Could you please help to have a look at a problem which I encountered?

 I am trying to make kaslr randomize on both kernel physical and virtual
 address separately. Now the separate randomization has been done,
 kernel physical address can be randomized to [16M, 4G], and virtual
 address can be randomzed to [16M, 1G]. Below is the post.
 http://thread.gmane.org/gmane.linux.kernel/1870532

 Now I am trying to make kernel physical address randomize anywhere, not
 limited to below 4G. As you know in arch/x86/boot/compressed/head_64.S a
 identity mapping of 0~4G has been built, for address above 4G I added an
 IDT and #PF handler. Then I hardcoded the output address of
 choose_kernel_location as 5G, the #PF handler worked, however it will
 reboot in arch/x86/kernel/head_64.S.

For 64bit, I'd like to see bootloader could load kernel to random hw address.

otherwise you will need to set another ident mapping for new range.

Thanks

Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-17 Thread Yinghai Lu
On Wed, Feb 4, 2015 at 10:09 PM, Dave Young dyo...@redhat.com wrote:
 On 02/04/15 at 09:25pm, Yinghai Lu wrote:
 On Wed, Feb 4, 2015 at 7:25 PM, Dave Young dyo...@redhat.com wrote:
  After this patch, could use patched grub2-x86_64.efi to place
  kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
  above 4G.
 
  Can you share the grub2 patch for testing?

 Please check attached 5 patches. last one is for debug purpose.

 You need to apply them on top of

 git://git.savannah.gnu.org/grub.git

 plus  
 http://pkgs.fedoraproject.org/cgit/grub2.git/plain/0091-Add-support-for-linuxefi.patch


FYI, I put those patches together with patches that extend grub2 to load
kernel/initrd above 4G into github tree.

https://github.com/yhlu/grub2.git

Thanks

Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-12 Thread Matt Fleming
On Wed, 11 Feb, at 11:29:58AM, Peter Jones wrote:
> 
> From grub's point of view I'm not sure why we'd care - the pages kernel
> and initramfs land in are both from the Boot Services allocator, so if the
> machine doesn't support high addresses, they won't be there.

It's not that some implementations don't "support" higher addresses,
it's that the EFI_FILE_PROTOCOL is buggy and it corrupts the memory when
reading into it; you can allocate it just fine. At least, that's what I
remember from the limited investigation I performed.

But since grub doesn't use EFI_FILE_PROTOCOL, we should be cool.

-- 
Matt Fleming, Intel Open Source Technology Center
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-12 Thread Matt Fleming
On Wed, 11 Feb, at 11:29:58AM, Peter Jones wrote:
 
 From grub's point of view I'm not sure why we'd care - the pages kernel
 and initramfs land in are both from the Boot Services allocator, so if the
 machine doesn't support high addresses, they won't be there.

It's not that some implementations don't support higher addresses,
it's that the EFI_FILE_PROTOCOL is buggy and it corrupts the memory when
reading into it; you can allocate it just fine. At least, that's what I
remember from the limited investigation I performed.

But since grub doesn't use EFI_FILE_PROTOCOL, we should be cool.

-- 
Matt Fleming, Intel Open Source Technology Center
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-11 Thread Peter Jones
On Wed, Feb 11, 2015 at 03:55:24PM +, Matt Fleming wrote:
> On Mon, 09 Feb, at 12:23:15PM, Yinghai Lu wrote:
> > On Mon, Feb 9, 2015 at 10:27 AM, Matt Fleming  
> > wrote:
> > > On Tue, 03 Feb, at 06:03:20PM, Yinghai Lu wrote:
> > >
> > > The first thing that comes to mind is the issues we experienced last
> > > year when adding support for loading initrds above 4GB to the EFI boot
> > > stub, c.f. commit 47226ad4f4cf ("x86/efi: Only load initrd above 4g on
> > > second try").
> > >
> > > Are things going to work correctly this time?
> > 
> > That should be addressed the grub2.
>  
> I vaguely remember thinking that the issue was only experienced when
> using the EFI_FILE protocol, which grub2 doesn't use. So the grub
> developers may be OK, but we should at least give them a heads up.

Looks correct to me.

> > I was thinking that we may need to add mem_limit command together with
> > linuxefi and initrdefi.
> > or add linuxefi64/initrdefi64?
>  
> No, we definitely do not want to add any more grub commands.

Definitely agree.

> > BTW, I tested loading kernel above grub2 on
> > virutalbox, qemu/kvm/OVMF, and real servers (ami ...) all work without 
> > problem.
> > 
> > wonder if we need have one black list for 64bit UEFI that does not
> > support access
> > memory above 4G.
>  
> We have been successful, so far, in not introducing these kind of
> blacklists. It would be a shame to start now.

>From grub's point of view I'm not sure why we'd care - the pages kernel
and initramfs land in are both from the Boot Services allocator, so if the
machine doesn't support high addresses, they won't be there.

-- 
Peter
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-11 Thread Matt Fleming
On Mon, 09 Feb, at 12:23:15PM, Yinghai Lu wrote:
> On Mon, Feb 9, 2015 at 10:27 AM, Matt Fleming  
> wrote:
> > On Tue, 03 Feb, at 06:03:20PM, Yinghai Lu wrote:
> >
> > The first thing that comes to mind is the issues we experienced last
> > year when adding support for loading initrds above 4GB to the EFI boot
> > stub, c.f. commit 47226ad4f4cf ("x86/efi: Only load initrd above 4g on
> > second try").
> >
> > Are things going to work correctly this time?
> 
> That should be addressed the grub2.
 
I vaguely remember thinking that the issue was only experienced when
using the EFI_FILE protocol, which grub2 doesn't use. So the grub
developers may be OK, but we should at least give them a heads up.

> I was thinking that we may need to add mem_limit command together with
> linuxefi and initrdefi.
> or add linuxefi64/initrdefi64?
 
No, we definitely do not want to add any more grub commands.

> BTW, I tested loading kernel above grub2 on
> virutalbox, qemu/kvm/OVMF, and real servers (ami ...) all work without 
> problem.
> 
> wonder if we need have one black list for 64bit UEFI that does not
> support access
> memory above 4G.
 
We have been successful, so far, in not introducing these kind of
blacklists. It would be a shame to start now.

-- 
Matt Fleming, Intel Open Source Technology Center
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-11 Thread Peter Jones
On Wed, Feb 11, 2015 at 03:55:24PM +, Matt Fleming wrote:
 On Mon, 09 Feb, at 12:23:15PM, Yinghai Lu wrote:
  On Mon, Feb 9, 2015 at 10:27 AM, Matt Fleming m...@codeblueprint.co.uk 
  wrote:
   On Tue, 03 Feb, at 06:03:20PM, Yinghai Lu wrote:
  
   The first thing that comes to mind is the issues we experienced last
   year when adding support for loading initrds above 4GB to the EFI boot
   stub, c.f. commit 47226ad4f4cf (x86/efi: Only load initrd above 4g on
   second try).
  
   Are things going to work correctly this time?
  
  That should be addressed the grub2.
  
 I vaguely remember thinking that the issue was only experienced when
 using the EFI_FILE protocol, which grub2 doesn't use. So the grub
 developers may be OK, but we should at least give them a heads up.

Looks correct to me.

  I was thinking that we may need to add mem_limit command together with
  linuxefi and initrdefi.
  or add linuxefi64/initrdefi64?
  
 No, we definitely do not want to add any more grub commands.

Definitely agree.

  BTW, I tested loading kernel above grub2 on
  virutalbox, qemu/kvm/OVMF, and real servers (ami ...) all work without 
  problem.
  
  wonder if we need have one black list for 64bit UEFI that does not
  support access
  memory above 4G.
  
 We have been successful, so far, in not introducing these kind of
 blacklists. It would be a shame to start now.

From grub's point of view I'm not sure why we'd care - the pages kernel
and initramfs land in are both from the Boot Services allocator, so if the
machine doesn't support high addresses, they won't be there.

-- 
Peter
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-11 Thread Matt Fleming
On Mon, 09 Feb, at 12:23:15PM, Yinghai Lu wrote:
 On Mon, Feb 9, 2015 at 10:27 AM, Matt Fleming m...@codeblueprint.co.uk 
 wrote:
  On Tue, 03 Feb, at 06:03:20PM, Yinghai Lu wrote:
 
  The first thing that comes to mind is the issues we experienced last
  year when adding support for loading initrds above 4GB to the EFI boot
  stub, c.f. commit 47226ad4f4cf (x86/efi: Only load initrd above 4g on
  second try).
 
  Are things going to work correctly this time?
 
 That should be addressed the grub2.
 
I vaguely remember thinking that the issue was only experienced when
using the EFI_FILE protocol, which grub2 doesn't use. So the grub
developers may be OK, but we should at least give them a heads up.

 I was thinking that we may need to add mem_limit command together with
 linuxefi and initrdefi.
 or add linuxefi64/initrdefi64?
 
No, we definitely do not want to add any more grub commands.

 BTW, I tested loading kernel above grub2 on
 virutalbox, qemu/kvm/OVMF, and real servers (ami ...) all work without 
 problem.
 
 wonder if we need have one black list for 64bit UEFI that does not
 support access
 memory above 4G.
 
We have been successful, so far, in not introducing these kind of
blacklists. It would be a shame to start now.

-- 
Matt Fleming, Intel Open Source Technology Center
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-10 Thread Baoquan He
Hi Yinghai,

Could you please help to have a look at a problem which I encountered?

I am trying to make kaslr randomize on both kernel physical and virtual
address separately. Now the separate randomization has been done,
kernel physical address can be randomized to [16M, 4G], and virtual
address can be randomzed to [16M, 1G]. Below is the post.
http://thread.gmane.org/gmane.linux.kernel/1870532

Now I am trying to make kernel physical address randomize anywhere, not
limited to below 4G. As you know in arch/x86/boot/compressed/head_64.S a
identity mapping of 0~4G has been built, for address above 4G I added an
IDT and #PF handler. Then I hardcoded the output address of
choose_kernel_location as 5G, the #PF handler worked, however it will
reboot in arch/x86/kernel/head_64.S.

I don't know how to debug asm code, and have no idea why it has been in
64 bit mode while it can't be in above 4G in boot/compressed/head_64.S.

Now for debugging this issue, I made a small debug patch as below. Four
more pages are added as pmd page table, so identity mapping cover
0~8G. Then hardcode the output address as 5G, and disable the relocation
handling to filter unnecessary interference. 

diff --git a/arch/x86/boot/compressed/head_64.S 
b/arch/x86/boot/compressed/head_64.S
index 6b1766c..74da678 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -123,7 +123,7 @@ ENTRY(startup_32)
/* Initialize Page tables to 0 */
lealpgtable(%ebx), %edi
xorl%eax, %eax
-   movl$((4096*6)/4), %ecx
+   movl$((4096*10)/4), %ecx
rep stosl
 
/* Build Level 4 */
@@ -134,7 +134,7 @@ ENTRY(startup_32)
/* Build Level 3 */
lealpgtable + 0x1000(%ebx), %edi
leal0x1007(%edi), %eax
-   movl$4, %ecx
+   movl$8, %ecx
 1: movl%eax, 0x00(%edi)
addl$0x1000, %eax
addl$8, %edi
@@ -144,7 +144,7 @@ ENTRY(startup_32)
/* Build Level 2 */
lealpgtable + 0x2000(%ebx), %edi
movl$0x0183, %eax
-   movl$2048, %ecx
+   movl$4096, %ecx
 1: movl%eax, 0(%edi)
addl$0x0020, %eax
addl$8, %edi
@@ -476,4 +476,4 @@ boot_stack_end:
.section ".pgtable","a",@nobits
.balign 4096
 pgtable:
-   .fill 6*4096, 1, 0
+   .fill 10*4096, 1, 0
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index a950864..47c8c80 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -404,6 +404,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, 
memptr heap,
output = choose_kernel_location(input_data, input_len, output,
output_len > run_size ? output_len
  : run_size);
+   output = 0x14000;
 
/* Validate memory location choices. */
if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1))
@@ -427,8 +428,10 @@ asmlinkage __visible void *decompress_kernel(void *rmode, 
memptr heap,
 * 32-bit always performs relocations. 64-bit relocations are only
 * needed if kASLR has chosen a different load address.
 */
+#if 0
if (!IS_ENABLED(CONFIG_X86_64) || output != output_orig)
handle_relocations(output, output_len);
+#endif
debug_putstr("done.\nBooting the kernel.\n");
return output;
 }


Thanks
Baoquan

On 02/03/15 at 06:03pm, Yinghai Lu wrote:
> Now could use kexec to place kernel/boot_params/cmd_line/initrd
> above 4G, but that is with legacy interface with startup_64 directly.
> 
> This patch will allow 64bit EFI kernel to be loaded above 4G
> and use EFI HANDOVER PROTOCOL to start the kernel.
> 
> Current code32_start is used for passing around loading address,
> so it will overflow when kernel is loaded abover 4G.
> 
> The patch mainly add ext_code32_start to take address high 32bit.
> 
> After this patch, could use patched grub2-x86_64.efi to place
> kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
> above 4G.
> 
> bootlog like:
> 
> params: [1618fc000,1618f]
> cmdline: [1618fb000,1618fb7fe]
> kernel: [15e00,161385fff]
> kernel: done   [ linux  9.25MiB  100%  6.66MiB/s ]
> initrd: [15bcbe000,15dbb]
> initrd: 1 file done [ initrd.img  35.26MiB  100%  11.93MiB/s ]
> early console in decompress_kernel
> decompress_kernel:
>   input: [0x15fd0b3b4-0x16063c803], output: 0x15e00, heap: 
> [0x160645b00-0x16064daff]
> 
> Decompressing Linux... xz... Parsing ELF... done.
> Booting the kernel.
> [0.00] bootconsole [uart0] enabled
> [0.00]real_mode_data :  phys 0001618fc000
> [0.00]real_mode_data :  virt 8801618fc000
> [0.00] Kernel Layout:
> [0.00]   .text: [0x15e00-0x15f08f72c]
> [0.00] .rodata: 

Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-10 Thread Baoquan He
Hi Yinghai,

Could you please help to have a look at a problem which I encountered?

I am trying to make kaslr randomize on both kernel physical and virtual
address separately. Now the separate randomization has been done,
kernel physical address can be randomized to [16M, 4G], and virtual
address can be randomzed to [16M, 1G]. Below is the post.
http://thread.gmane.org/gmane.linux.kernel/1870532

Now I am trying to make kernel physical address randomize anywhere, not
limited to below 4G. As you know in arch/x86/boot/compressed/head_64.S a
identity mapping of 0~4G has been built, for address above 4G I added an
IDT and #PF handler. Then I hardcoded the output address of
choose_kernel_location as 5G, the #PF handler worked, however it will
reboot in arch/x86/kernel/head_64.S.

I don't know how to debug asm code, and have no idea why it has been in
64 bit mode while it can't be in above 4G in boot/compressed/head_64.S.

Now for debugging this issue, I made a small debug patch as below. Four
more pages are added as pmd page table, so identity mapping cover
0~8G. Then hardcode the output address as 5G, and disable the relocation
handling to filter unnecessary interference. 

diff --git a/arch/x86/boot/compressed/head_64.S 
b/arch/x86/boot/compressed/head_64.S
index 6b1766c..74da678 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -123,7 +123,7 @@ ENTRY(startup_32)
/* Initialize Page tables to 0 */
lealpgtable(%ebx), %edi
xorl%eax, %eax
-   movl$((4096*6)/4), %ecx
+   movl$((4096*10)/4), %ecx
rep stosl
 
/* Build Level 4 */
@@ -134,7 +134,7 @@ ENTRY(startup_32)
/* Build Level 3 */
lealpgtable + 0x1000(%ebx), %edi
leal0x1007(%edi), %eax
-   movl$4, %ecx
+   movl$8, %ecx
 1: movl%eax, 0x00(%edi)
addl$0x1000, %eax
addl$8, %edi
@@ -144,7 +144,7 @@ ENTRY(startup_32)
/* Build Level 2 */
lealpgtable + 0x2000(%ebx), %edi
movl$0x0183, %eax
-   movl$2048, %ecx
+   movl$4096, %ecx
 1: movl%eax, 0(%edi)
addl$0x0020, %eax
addl$8, %edi
@@ -476,4 +476,4 @@ boot_stack_end:
.section .pgtable,a,@nobits
.balign 4096
 pgtable:
-   .fill 6*4096, 1, 0
+   .fill 10*4096, 1, 0
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index a950864..47c8c80 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -404,6 +404,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, 
memptr heap,
output = choose_kernel_location(input_data, input_len, output,
output_len  run_size ? output_len
  : run_size);
+   output = 0x14000;
 
/* Validate memory location choices. */
if ((unsigned long)output  (MIN_KERNEL_ALIGN - 1))
@@ -427,8 +428,10 @@ asmlinkage __visible void *decompress_kernel(void *rmode, 
memptr heap,
 * 32-bit always performs relocations. 64-bit relocations are only
 * needed if kASLR has chosen a different load address.
 */
+#if 0
if (!IS_ENABLED(CONFIG_X86_64) || output != output_orig)
handle_relocations(output, output_len);
+#endif
debug_putstr(done.\nBooting the kernel.\n);
return output;
 }


Thanks
Baoquan

On 02/03/15 at 06:03pm, Yinghai Lu wrote:
 Now could use kexec to place kernel/boot_params/cmd_line/initrd
 above 4G, but that is with legacy interface with startup_64 directly.
 
 This patch will allow 64bit EFI kernel to be loaded above 4G
 and use EFI HANDOVER PROTOCOL to start the kernel.
 
 Current code32_start is used for passing around loading address,
 so it will overflow when kernel is loaded abover 4G.
 
 The patch mainly add ext_code32_start to take address high 32bit.
 
 After this patch, could use patched grub2-x86_64.efi to place
 kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
 above 4G.
 
 bootlog like:
 
 params: [1618fc000,1618f]
 cmdline: [1618fb000,1618fb7fe]
 kernel: [15e00,161385fff]
 kernel: done   [ linux  9.25MiB  100%  6.66MiB/s ]
 initrd: [15bcbe000,15dbb]
 initrd: 1 file done [ initrd.img  35.26MiB  100%  11.93MiB/s ]
 early console in decompress_kernel
 decompress_kernel:
   input: [0x15fd0b3b4-0x16063c803], output: 0x15e00, heap: 
 [0x160645b00-0x16064daff]
 
 Decompressing Linux... xz... Parsing ELF... done.
 Booting the kernel.
 [0.00] bootconsole [uart0] enabled
 [0.00]real_mode_data :  phys 0001618fc000
 [0.00]real_mode_data :  virt 8801618fc000
 [0.00] Kernel Layout:
 [0.00]   .text: [0x15e00-0x15f08f72c]
 [0.00] .rodata: [0x15f20-0x15fa44fff]
 [0.00]   .data: 

Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-09 Thread Yinghai Lu
On Mon, Feb 9, 2015 at 10:27 AM, Matt Fleming  wrote:
> On Tue, 03 Feb, at 06:03:20PM, Yinghai Lu wrote:
>
> The first thing that comes to mind is the issues we experienced last
> year when adding support for loading initrds above 4GB to the EFI boot
> stub, c.f. commit 47226ad4f4cf ("x86/efi: Only load initrd above 4g on
> second try").
>
> Are things going to work correctly this time?

That should be addressed the grub2.

I was thinking that we may need to add mem_limit command together with
linuxefi and initrdefi.
or add linuxefi64/initrdefi64?

BTW, I tested loading kernel above grub2 on
virutalbox, qemu/kvm/OVMF, and real servers (ami ...) all work without problem.

wonder if we need have one black list for 64bit UEFI that does not
support access
memory above 4G.

>> @@ -1430,9 +1431,12 @@ struct boot_params *efi_main(struct efi_
>>* If the kernel isn't already loaded at the preferred load
>>* address, relocate it.
>>*/
>> - if (hdr->pref_address != hdr->code32_start) {
>> - unsigned long bzimage_addr = hdr->code32_start;
>> - status = efi_relocate_kernel(sys_table, _addr,
>> + loaded_addr = hdr->code32_start;
>> + loaded_addr |= (unsigned long)hdr->ext_code32_start << 32;
>
> Please compile this for CONFIG_X86_32 and fix any compiler warnings.

Ok.

>
>> @@ -738,6 +742,13 @@ Offset/size: 0x264/4
>>
>>See EFI HANDOVER PROTOCOL below for more details.
>>
>> +Field name:  ext_code32_start
>> +Type:modify (optional, reloc)
>> +Offset/size: 0x268/4
>> +Protocol:2.14+
>> +
>> +  The address is used with code32_start to compare pref_address
>> +  to support EFI 64bit kernel get loaded above 4G.
>
> It would be good to mention that this new field contains the upper
> 32-bits of the 64-bit address.

ok. that is: upper 32bits of the 64bit address of startup_32 when kernel
loaded above 4G.

Thanks

Yinghai
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-09 Thread Matt Fleming
On Tue, 03 Feb, at 06:03:20PM, Yinghai Lu wrote:
> Now could use kexec to place kernel/boot_params/cmd_line/initrd
> above 4G, but that is with legacy interface with startup_64 directly.
> 
> This patch will allow 64bit EFI kernel to be loaded above 4G
> and use EFI HANDOVER PROTOCOL to start the kernel.
> 
> Current code32_start is used for passing around loading address,
> so it will overflow when kernel is loaded abover 4G.
> 
> The patch mainly add ext_code32_start to take address high 32bit.
> 
> After this patch, could use patched grub2-x86_64.efi to place
> kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
> above 4G.
 
The first thing that comes to mind is the issues we experienced last
year when adding support for loading initrds above 4GB to the EFI boot
stub, c.f. commit 47226ad4f4cf ("x86/efi: Only load initrd above 4g on
second try").

Are things going to work correctly this time?

> Index: linux-2.6/arch/x86/boot/compressed/eboot.c
> ===
> --- linux-2.6.orig/arch/x86/boot/compressed/eboot.c
> +++ linux-2.6/arch/x86/boot/compressed/eboot.c
> @@ -1389,6 +1389,7 @@ struct boot_params *efi_main(struct efi_
>   void *handle;
>   efi_system_table_t *_table;
>   bool is64;
> + unsigned long loaded_addr;
>  
>   efi_early = c;
>  
> @@ -1430,9 +1431,12 @@ struct boot_params *efi_main(struct efi_
>* If the kernel isn't already loaded at the preferred load
>* address, relocate it.
>*/
> - if (hdr->pref_address != hdr->code32_start) {
> - unsigned long bzimage_addr = hdr->code32_start;
> - status = efi_relocate_kernel(sys_table, _addr,
> + loaded_addr = hdr->code32_start;
> + loaded_addr |= (unsigned long)hdr->ext_code32_start << 32;

Please compile this for CONFIG_X86_32 and fix any compiler warnings.

> @@ -738,6 +742,13 @@ Offset/size: 0x264/4
>  
>See EFI HANDOVER PROTOCOL below for more details.
>  
> +Field name:  ext_code32_start
> +Type:modify (optional, reloc)
> +Offset/size: 0x268/4
> +Protocol:2.14+
> +
> +  The address is used with code32_start to compare pref_address
> +  to support EFI 64bit kernel get loaded above 4G.

It would be good to mention that this new field contains the upper
32-bits of the 64-bit address.

-- 
Matt Fleming, Intel Open Source Technology Center
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-09 Thread Matt Fleming
On Tue, 03 Feb, at 06:03:20PM, Yinghai Lu wrote:
 Now could use kexec to place kernel/boot_params/cmd_line/initrd
 above 4G, but that is with legacy interface with startup_64 directly.
 
 This patch will allow 64bit EFI kernel to be loaded above 4G
 and use EFI HANDOVER PROTOCOL to start the kernel.
 
 Current code32_start is used for passing around loading address,
 so it will overflow when kernel is loaded abover 4G.
 
 The patch mainly add ext_code32_start to take address high 32bit.
 
 After this patch, could use patched grub2-x86_64.efi to place
 kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
 above 4G.
 
The first thing that comes to mind is the issues we experienced last
year when adding support for loading initrds above 4GB to the EFI boot
stub, c.f. commit 47226ad4f4cf (x86/efi: Only load initrd above 4g on
second try).

Are things going to work correctly this time?

 Index: linux-2.6/arch/x86/boot/compressed/eboot.c
 ===
 --- linux-2.6.orig/arch/x86/boot/compressed/eboot.c
 +++ linux-2.6/arch/x86/boot/compressed/eboot.c
 @@ -1389,6 +1389,7 @@ struct boot_params *efi_main(struct efi_
   void *handle;
   efi_system_table_t *_table;
   bool is64;
 + unsigned long loaded_addr;
  
   efi_early = c;
  
 @@ -1430,9 +1431,12 @@ struct boot_params *efi_main(struct efi_
* If the kernel isn't already loaded at the preferred load
* address, relocate it.
*/
 - if (hdr-pref_address != hdr-code32_start) {
 - unsigned long bzimage_addr = hdr-code32_start;
 - status = efi_relocate_kernel(sys_table, bzimage_addr,
 + loaded_addr = hdr-code32_start;
 + loaded_addr |= (unsigned long)hdr-ext_code32_start  32;

Please compile this for CONFIG_X86_32 and fix any compiler warnings.

 @@ -738,6 +742,13 @@ Offset/size: 0x264/4
  
See EFI HANDOVER PROTOCOL below for more details.
  
 +Field name:  ext_code32_start
 +Type:modify (optional, reloc)
 +Offset/size: 0x268/4
 +Protocol:2.14+
 +
 +  The address is used with code32_start to compare pref_address
 +  to support EFI 64bit kernel get loaded above 4G.

It would be good to mention that this new field contains the upper
32-bits of the 64-bit address.

-- 
Matt Fleming, Intel Open Source Technology Center
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-09 Thread Yinghai Lu
On Mon, Feb 9, 2015 at 10:27 AM, Matt Fleming m...@codeblueprint.co.uk wrote:
 On Tue, 03 Feb, at 06:03:20PM, Yinghai Lu wrote:

 The first thing that comes to mind is the issues we experienced last
 year when adding support for loading initrds above 4GB to the EFI boot
 stub, c.f. commit 47226ad4f4cf (x86/efi: Only load initrd above 4g on
 second try).

 Are things going to work correctly this time?

That should be addressed the grub2.

I was thinking that we may need to add mem_limit command together with
linuxefi and initrdefi.
or add linuxefi64/initrdefi64?

BTW, I tested loading kernel above grub2 on
virutalbox, qemu/kvm/OVMF, and real servers (ami ...) all work without problem.

wonder if we need have one black list for 64bit UEFI that does not
support access
memory above 4G.

 @@ -1430,9 +1431,12 @@ struct boot_params *efi_main(struct efi_
* If the kernel isn't already loaded at the preferred load
* address, relocate it.
*/
 - if (hdr-pref_address != hdr-code32_start) {
 - unsigned long bzimage_addr = hdr-code32_start;
 - status = efi_relocate_kernel(sys_table, bzimage_addr,
 + loaded_addr = hdr-code32_start;
 + loaded_addr |= (unsigned long)hdr-ext_code32_start  32;

 Please compile this for CONFIG_X86_32 and fix any compiler warnings.

Ok.


 @@ -738,6 +742,13 @@ Offset/size: 0x264/4

See EFI HANDOVER PROTOCOL below for more details.

 +Field name:  ext_code32_start
 +Type:modify (optional, reloc)
 +Offset/size: 0x268/4
 +Protocol:2.14+
 +
 +  The address is used with code32_start to compare pref_address
 +  to support EFI 64bit kernel get loaded above 4G.

 It would be good to mention that this new field contains the upper
 32-bits of the 64-bit address.

ok. that is: upper 32bits of the 64bit address of startup_32 when kernel
loaded above 4G.

Thanks

Yinghai
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-04 Thread Dave Young
On 02/04/15 at 09:25pm, Yinghai Lu wrote:
> On Wed, Feb 4, 2015 at 7:25 PM, Dave Young  wrote:
> >> After this patch, could use patched grub2-x86_64.efi to place
> >> kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
> >> above 4G.
> >
> > Can you share the grub2 patch for testing?
> 
> Please check attached 5 patches. last one is for debug purpose.
> 
> You need to apply them on top of
> 
> git://git.savannah.gnu.org/grub.git
> 
> plus  
> http://pkgs.fedoraproject.org/cgit/grub2.git/plain/0091-Add-support-for-linuxefi.patch

> Subject: [PATCH] update setup_header and boot_params to 2.12
> 
> the one that is used by kernel v3.8...

Thanks for quick feedback..
Dave
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-04 Thread Yinghai Lu
On Wed, Feb 4, 2015 at 7:25 PM, Dave Young  wrote:
>> After this patch, could use patched grub2-x86_64.efi to place
>> kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
>> above 4G.
>
> Can you share the grub2 patch for testing?

Please check attached 5 patches. last one is for debug purpose.

You need to apply them on top of

git://git.savannah.gnu.org/grub.git

plus  
http://pkgs.fedoraproject.org/cgit/grub2.git/plain/0091-Add-support-for-linuxefi.patch
Subject: [PATCH] update setup_header and boot_params to 2.12

the one that is used by kernel v3.8...


---
 include/grub/i386/linux.h |   16 
 1 file changed, 12 insertions(+), 4 deletions(-)

Index: grub/include/grub/i386/linux.h
===
--- grub.orig/include/grub/i386/linux.h
+++ grub/include/grub/i386/linux.h
@@ -130,7 +130,7 @@ struct linux_kernel_header
   grub_uint32_t kernel_alignment;
   grub_uint8_t relocatable;
   grub_uint8_t min_alignment;
-  grub_uint8_t pad[2];
+  grub_uint16_t xloadflags;
   grub_uint32_t cmdline_size;
   grub_uint32_t hardware_subarch;
   grub_uint64_t hardware_subarch_data;
@@ -221,7 +221,11 @@ struct linux_kernel_params
   grub_uint32_t ofw_cif_handler;	/* b8 */
   grub_uint32_t ofw_idt;		/* bc */
 
-  grub_uint8_t padding7[0x1b8 - 0xc0];
+  grub_uint32_t ext_ramdisk_image;	/* c0 */
+  grub_uint32_t ext_ramdisk_size;	/* c4 */
+  grub_uint32_t ext_cmd_line_ptr;	/* c8 */
+
+  grub_uint8_t padding7[0x1b8 - 0xcc];
 
   union
 {
@@ -300,14 +304,18 @@ struct linux_kernel_params
   grub_uint32_t initrd_addr_max;	/* Maximum initrd address */
   grub_uint32_t kernel_alignment;	/* Alignment of the kernel */
   grub_uint8_t relocatable_kernel;	/* Is the kernel relocatable */
-  grub_uint8_t pad1[3];
+  grub_uint8_t min_alignment;
+  grub_uint16_t xloadflags;
   grub_uint32_t cmdline_size;		/* Size of the kernel command line */
   grub_uint32_t hardware_subarch;
   grub_uint64_t hardware_subarch_data;
   grub_uint32_t payload_offset;
   grub_uint32_t payload_length;
   grub_uint64_t setup_data;
-  grub_uint8_t pad2[120];		/* 258 */
+  grub_uint64_t pref_address;
+  grub_uint32_t init_size;
+  grub_uint32_t handover_offset;
+  grub_uint8_t pad2[104];		/* 248 */
   struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20];	/* 2d0 */
 
 } GRUB_PACKED;
Subject: [PATCH] x86, efi: add allocate_pages_high

The allocate_pages_max one does not return above 4G.

translate the version in linux kernel.

---
 grub-core/kern/efi/mm.c |  144 
 include/grub/efi/efi.h  |3 +
 2 files changed, 147 insertions(+)

Index: grub/grub-core/kern/efi/mm.c
===
--- grub.orig/grub-core/kern/efi/mm.c
+++ grub/grub-core/kern/efi/mm.c
@@ -557,3 +557,147 @@ grub_efi_mm_init (void)
   grub_efi_free_pages ((grub_addr_t) memory_map,
 		   2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
 }
+
+#define EFI_PAGE_SIZE 0x1000
+static grub_efi_status_t grub2_efi_get_memory_map(grub_efi_uintn_t *map_size,
+ grub_efi_memory_descriptor_t **map,
+ grub_efi_uintn_t *key_ptr,
+ grub_efi_uintn_t *desc_size,
+ grub_efi_uint32_t *desc_ver)
+{
+  grub_efi_memory_descriptor_t *m = NULL;
+  grub_efi_status_t status;
+  grub_efi_uintn_t key;
+  grub_efi_uint32_t desc_version;
+  grub_efi_boot_services_t *b;
+
+  b = grub_efi_system_table->boot_services;
+
+  *map_size = 0;
+  *desc_size = 0;
+  key = 0;
+  status = efi_call_5 (b->get_memory_map, map_size, NULL, ,
+   desc_size, _version);
+
+  if (status != GRUB_EFI_BUFFER_TOO_SMALL)
+return GRUB_EFI_LOAD_ERROR;
+
+  /*
+   * Add an additional efi_memory_desc_t because we're doing an
+   * allocation which may be in a new descriptor region.
+   */
+  *map_size += *desc_size;
+  status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA,
+   *map_size, (void **));
+  if (status != GRUB_EFI_SUCCESS)
+goto fail;
+
+  status = efi_call_5 (b->get_memory_map, map_size, m, ,
+   desc_size, _version);
+  if (status == GRUB_EFI_BUFFER_TOO_SMALL)
+{
+  efi_call_1 (b->free_pool, m);
+  return GRUB_EFI_LOAD_ERROR;
+}
+
+  if (status != GRUB_EFI_SUCCESS)
+efi_call_1 (b->free_pool, m);
+
+  if (key_ptr && status == GRUB_EFI_SUCCESS)
+*key_ptr = key;
+  if (desc_ver && status == GRUB_EFI_SUCCESS)
+*desc_ver = desc_version;
+
+fail:
+  *map = m;
+  return status;
+}
+
+/*
+ * Allocate at the highest possible address that is not above 'max'.
+ */
+void *grub2_efi_allocate_pages_high(grub_efi_physical_address_t max,
+			grub_efi_uint64_t pages, grub_efi_uint64_t align)
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_uintn_t map_size, desc_size;
+  grub_efi_memory_descriptor_t *map= NULL;
+  grub_efi_status_t status;
+  grub_uint64_t max_addr = 0;
+  

Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-04 Thread Dave Young
Hi,

Thanks, it will be useful for possible efi rebooting to kdump reserved memory.

On 02/03/15 at 06:03pm, Yinghai Lu wrote:
> Now could use kexec to place kernel/boot_params/cmd_line/initrd
> above 4G, but that is with legacy interface with startup_64 directly.
> 
> This patch will allow 64bit EFI kernel to be loaded above 4G
> and use EFI HANDOVER PROTOCOL to start the kernel.
> 
> Current code32_start is used for passing around loading address,
> so it will overflow when kernel is loaded abover 4G.
> 
> The patch mainly add ext_code32_start to take address high 32bit.
> 
> After this patch, could use patched grub2-x86_64.efi to place
> kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
> above 4G.

Can you share the grub2 patch for testing?

> 
> bootlog like:
> 
> params: [1618fc000,1618f]
> cmdline: [1618fb000,1618fb7fe]
> kernel: [15e00,161385fff]
> kernel: done   [ linux  9.25MiB  100%  6.66MiB/s ]
> initrd: [15bcbe000,15dbb]
> initrd: 1 file done [ initrd.img  35.26MiB  100%  11.93MiB/s ]
> early console in decompress_kernel
> decompress_kernel:
>   input: [0x15fd0b3b4-0x16063c803], output: 0x15e00, heap: 
> [0x160645b00-0x16064daff]
> 
> Decompressing Linux... xz... Parsing ELF... done.
> Booting the kernel.
> [0.00] bootconsole [uart0] enabled
> [0.00]real_mode_data :  phys 0001618fc000
> [0.00]real_mode_data :  virt 8801618fc000
> [0.00] Kernel Layout:
> [0.00]   .text: [0x15e00-0x15f08f72c]
> [0.00] .rodata: [0x15f20-0x15fa44fff]
> [0.00]   .data: [0x15fc0-0x15fe545ff]
> [0.00]   .init: [0x15fe56000-0x16021afff]
> [0.00].bss: [0x160229000-0x16135]
> [0.00].brk: [0x16136-0x161385fff]
> [0.00] memblock_reserve: [0x09f000-0x0f] flags 
> 0x0 * BIOS reserved
> ...
> [0.00] memblock_reserve: [0x015e00-0x016135] flags 
> 0x0 TEXT DATA BSS
> [0.00] memblock_reserve: [0x015bcbe000-0x015dff] flags 
> 0x0 RAMDISK
> 
> 
> Signed-off-by: Yinghai Lu 
> 
> ---
>  Documentation/x86/boot.txt|   18 ++
>  arch/x86/boot/compressed/eboot.c  |   15 ++-
>  arch/x86/boot/compressed/head_64.S|7 ++-
>  arch/x86/boot/header.S|3 ++-
>  arch/x86/include/uapi/asm/bootparam.h |1 +
>  arch/x86/kernel/asm-offsets.c |1 +
>  6 files changed, 38 insertions(+), 7 deletions(-)
> 
> Index: linux-2.6/arch/x86/include/uapi/asm/bootparam.h
> ===
> --- linux-2.6.orig/arch/x86/include/uapi/asm/bootparam.h
> +++ linux-2.6/arch/x86/include/uapi/asm/bootparam.h
> @@ -83,6 +83,7 @@ struct setup_header {
>   __u64   pref_address;
>   __u32   init_size;
>   __u32   handover_offset;
> + __u32   ext_code32_start;
>  } __attribute__((packed));
>  
>  struct sys_desc_table {
> Index: linux-2.6/arch/x86/kernel/asm-offsets.c
> ===
> --- linux-2.6.orig/arch/x86/kernel/asm-offsets.c
> +++ linux-2.6/arch/x86/kernel/asm-offsets.c
> @@ -68,6 +68,7 @@ void common(void) {
>   OFFSET(BP_kernel_alignment, boot_params, hdr.kernel_alignment);
>   OFFSET(BP_pref_address, boot_params, hdr.pref_address);
>   OFFSET(BP_code32_start, boot_params, hdr.code32_start);
> + OFFSET(BP_ext_code32_start, boot_params, hdr.ext_code32_start);
>  
>   BLANK();
>   DEFINE(PTREGS_SIZE, sizeof(struct pt_regs));
> Index: linux-2.6/arch/x86/boot/compressed/head_64.S
> ===
> --- linux-2.6.orig/arch/x86/boot/compressed/head_64.S
> +++ linux-2.6/arch/x86/boot/compressed/head_64.S
> @@ -263,6 +263,8 @@ ENTRY(efi_pe_entry)
>   mov %rax, %rsi
>   leaqstartup_32(%rip), %rax
>   movl%eax, BP_code32_start(%rsi)
> + shr $32, %rax
> + movl%eax, BP_ext_code32_start(%rsi)
>   jmp 2f  /* Skip the relocation */
>  
>  handover_entry:
> @@ -286,7 +288,10 @@ fail:
>   hlt
>   jmp fail
>  2:
> - movlBP_code32_start(%esi), %eax
> + movlBP_code32_start(%rsi), %eax
> + movlBP_ext_code32_start(%rsi), %ebx
> + shl $32, %rbx
> + orq %rbx, %rax
>   leaqpreferred_addr(%rax), %rax
>   jmp *%rax
>  
> Index: linux-2.6/arch/x86/boot/compressed/eboot.c
> ===
> --- linux-2.6.orig/arch/x86/boot/compressed/eboot.c
> +++ linux-2.6/arch/x86/boot/compressed/eboot.c
> @@ -1389,6 +1389,7 @@ struct boot_params *efi_main(struct efi_
>   void *handle;
>   efi_system_table_t *_table;
>   bool is64;
> + unsigned long loaded_addr;
>  
>   efi_early = c;
>  
> @@ -1430,9 +1431,12 @@ struct boot_params *efi_main(struct efi_
>   

Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-04 Thread Dave Young
On 02/04/15 at 09:25pm, Yinghai Lu wrote:
 On Wed, Feb 4, 2015 at 7:25 PM, Dave Young dyo...@redhat.com wrote:
  After this patch, could use patched grub2-x86_64.efi to place
  kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
  above 4G.
 
  Can you share the grub2 patch for testing?
 
 Please check attached 5 patches. last one is for debug purpose.
 
 You need to apply them on top of
 
 git://git.savannah.gnu.org/grub.git
 
 plus  
 http://pkgs.fedoraproject.org/cgit/grub2.git/plain/0091-Add-support-for-linuxefi.patch

 Subject: [PATCH] update setup_header and boot_params to 2.12
 
 the one that is used by kernel v3.8...

Thanks for quick feedback..
Dave
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-04 Thread Dave Young
Hi,

Thanks, it will be useful for possible efi rebooting to kdump reserved memory.

On 02/03/15 at 06:03pm, Yinghai Lu wrote:
 Now could use kexec to place kernel/boot_params/cmd_line/initrd
 above 4G, but that is with legacy interface with startup_64 directly.
 
 This patch will allow 64bit EFI kernel to be loaded above 4G
 and use EFI HANDOVER PROTOCOL to start the kernel.
 
 Current code32_start is used for passing around loading address,
 so it will overflow when kernel is loaded abover 4G.
 
 The patch mainly add ext_code32_start to take address high 32bit.
 
 After this patch, could use patched grub2-x86_64.efi to place
 kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
 above 4G.

Can you share the grub2 patch for testing?

 
 bootlog like:
 
 params: [1618fc000,1618f]
 cmdline: [1618fb000,1618fb7fe]
 kernel: [15e00,161385fff]
 kernel: done   [ linux  9.25MiB  100%  6.66MiB/s ]
 initrd: [15bcbe000,15dbb]
 initrd: 1 file done [ initrd.img  35.26MiB  100%  11.93MiB/s ]
 early console in decompress_kernel
 decompress_kernel:
   input: [0x15fd0b3b4-0x16063c803], output: 0x15e00, heap: 
 [0x160645b00-0x16064daff]
 
 Decompressing Linux... xz... Parsing ELF... done.
 Booting the kernel.
 [0.00] bootconsole [uart0] enabled
 [0.00]real_mode_data :  phys 0001618fc000
 [0.00]real_mode_data :  virt 8801618fc000
 [0.00] Kernel Layout:
 [0.00]   .text: [0x15e00-0x15f08f72c]
 [0.00] .rodata: [0x15f20-0x15fa44fff]
 [0.00]   .data: [0x15fc0-0x15fe545ff]
 [0.00]   .init: [0x15fe56000-0x16021afff]
 [0.00].bss: [0x160229000-0x16135]
 [0.00].brk: [0x16136-0x161385fff]
 [0.00] memblock_reserve: [0x09f000-0x0f] flags 
 0x0 * BIOS reserved
 ...
 [0.00] memblock_reserve: [0x015e00-0x016135] flags 
 0x0 TEXT DATA BSS
 [0.00] memblock_reserve: [0x015bcbe000-0x015dff] flags 
 0x0 RAMDISK
 
 
 Signed-off-by: Yinghai Lu ying...@kernel.org
 
 ---
  Documentation/x86/boot.txt|   18 ++
  arch/x86/boot/compressed/eboot.c  |   15 ++-
  arch/x86/boot/compressed/head_64.S|7 ++-
  arch/x86/boot/header.S|3 ++-
  arch/x86/include/uapi/asm/bootparam.h |1 +
  arch/x86/kernel/asm-offsets.c |1 +
  6 files changed, 38 insertions(+), 7 deletions(-)
 
 Index: linux-2.6/arch/x86/include/uapi/asm/bootparam.h
 ===
 --- linux-2.6.orig/arch/x86/include/uapi/asm/bootparam.h
 +++ linux-2.6/arch/x86/include/uapi/asm/bootparam.h
 @@ -83,6 +83,7 @@ struct setup_header {
   __u64   pref_address;
   __u32   init_size;
   __u32   handover_offset;
 + __u32   ext_code32_start;
  } __attribute__((packed));
  
  struct sys_desc_table {
 Index: linux-2.6/arch/x86/kernel/asm-offsets.c
 ===
 --- linux-2.6.orig/arch/x86/kernel/asm-offsets.c
 +++ linux-2.6/arch/x86/kernel/asm-offsets.c
 @@ -68,6 +68,7 @@ void common(void) {
   OFFSET(BP_kernel_alignment, boot_params, hdr.kernel_alignment);
   OFFSET(BP_pref_address, boot_params, hdr.pref_address);
   OFFSET(BP_code32_start, boot_params, hdr.code32_start);
 + OFFSET(BP_ext_code32_start, boot_params, hdr.ext_code32_start);
  
   BLANK();
   DEFINE(PTREGS_SIZE, sizeof(struct pt_regs));
 Index: linux-2.6/arch/x86/boot/compressed/head_64.S
 ===
 --- linux-2.6.orig/arch/x86/boot/compressed/head_64.S
 +++ linux-2.6/arch/x86/boot/compressed/head_64.S
 @@ -263,6 +263,8 @@ ENTRY(efi_pe_entry)
   mov %rax, %rsi
   leaqstartup_32(%rip), %rax
   movl%eax, BP_code32_start(%rsi)
 + shr $32, %rax
 + movl%eax, BP_ext_code32_start(%rsi)
   jmp 2f  /* Skip the relocation */
  
  handover_entry:
 @@ -286,7 +288,10 @@ fail:
   hlt
   jmp fail
  2:
 - movlBP_code32_start(%esi), %eax
 + movlBP_code32_start(%rsi), %eax
 + movlBP_ext_code32_start(%rsi), %ebx
 + shl $32, %rbx
 + orq %rbx, %rax
   leaqpreferred_addr(%rax), %rax
   jmp *%rax
  
 Index: linux-2.6/arch/x86/boot/compressed/eboot.c
 ===
 --- linux-2.6.orig/arch/x86/boot/compressed/eboot.c
 +++ linux-2.6/arch/x86/boot/compressed/eboot.c
 @@ -1389,6 +1389,7 @@ struct boot_params *efi_main(struct efi_
   void *handle;
   efi_system_table_t *_table;
   bool is64;
 + unsigned long loaded_addr;
  
   efi_early = c;
  
 @@ -1430,9 +1431,12 @@ struct boot_params *efi_main(struct efi_
* If the kernel isn't already loaded at the preferred load
* address, relocate it.

Re: [PATCH] x86, boot: Allow 64bit EFI kernel to be loaded above 4G

2015-02-04 Thread Yinghai Lu
On Wed, Feb 4, 2015 at 7:25 PM, Dave Young dyo...@redhat.com wrote:
 After this patch, could use patched grub2-x86_64.efi to place
 kernel/boot_params/cmd_line/initrd all above 4G and execute the kernel
 above 4G.

 Can you share the grub2 patch for testing?

Please check attached 5 patches. last one is for debug purpose.

You need to apply them on top of

git://git.savannah.gnu.org/grub.git

plus  
http://pkgs.fedoraproject.org/cgit/grub2.git/plain/0091-Add-support-for-linuxefi.patch
Subject: [PATCH] update setup_header and boot_params to 2.12

the one that is used by kernel v3.8...


---
 include/grub/i386/linux.h |   16 
 1 file changed, 12 insertions(+), 4 deletions(-)

Index: grub/include/grub/i386/linux.h
===
--- grub.orig/include/grub/i386/linux.h
+++ grub/include/grub/i386/linux.h
@@ -130,7 +130,7 @@ struct linux_kernel_header
   grub_uint32_t kernel_alignment;
   grub_uint8_t relocatable;
   grub_uint8_t min_alignment;
-  grub_uint8_t pad[2];
+  grub_uint16_t xloadflags;
   grub_uint32_t cmdline_size;
   grub_uint32_t hardware_subarch;
   grub_uint64_t hardware_subarch_data;
@@ -221,7 +221,11 @@ struct linux_kernel_params
   grub_uint32_t ofw_cif_handler;	/* b8 */
   grub_uint32_t ofw_idt;		/* bc */
 
-  grub_uint8_t padding7[0x1b8 - 0xc0];
+  grub_uint32_t ext_ramdisk_image;	/* c0 */
+  grub_uint32_t ext_ramdisk_size;	/* c4 */
+  grub_uint32_t ext_cmd_line_ptr;	/* c8 */
+
+  grub_uint8_t padding7[0x1b8 - 0xcc];
 
   union
 {
@@ -300,14 +304,18 @@ struct linux_kernel_params
   grub_uint32_t initrd_addr_max;	/* Maximum initrd address */
   grub_uint32_t kernel_alignment;	/* Alignment of the kernel */
   grub_uint8_t relocatable_kernel;	/* Is the kernel relocatable */
-  grub_uint8_t pad1[3];
+  grub_uint8_t min_alignment;
+  grub_uint16_t xloadflags;
   grub_uint32_t cmdline_size;		/* Size of the kernel command line */
   grub_uint32_t hardware_subarch;
   grub_uint64_t hardware_subarch_data;
   grub_uint32_t payload_offset;
   grub_uint32_t payload_length;
   grub_uint64_t setup_data;
-  grub_uint8_t pad2[120];		/* 258 */
+  grub_uint64_t pref_address;
+  grub_uint32_t init_size;
+  grub_uint32_t handover_offset;
+  grub_uint8_t pad2[104];		/* 248 */
   struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20];	/* 2d0 */
 
 } GRUB_PACKED;
Subject: [PATCH] x86, efi: add allocate_pages_high

The allocate_pages_max one does not return above 4G.

translate the version in linux kernel.

---
 grub-core/kern/efi/mm.c |  144 
 include/grub/efi/efi.h  |3 +
 2 files changed, 147 insertions(+)

Index: grub/grub-core/kern/efi/mm.c
===
--- grub.orig/grub-core/kern/efi/mm.c
+++ grub/grub-core/kern/efi/mm.c
@@ -557,3 +557,147 @@ grub_efi_mm_init (void)
   grub_efi_free_pages ((grub_addr_t) memory_map,
 		   2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
 }
+
+#define EFI_PAGE_SIZE 0x1000
+static grub_efi_status_t grub2_efi_get_memory_map(grub_efi_uintn_t *map_size,
+ grub_efi_memory_descriptor_t **map,
+ grub_efi_uintn_t *key_ptr,
+ grub_efi_uintn_t *desc_size,
+ grub_efi_uint32_t *desc_ver)
+{
+  grub_efi_memory_descriptor_t *m = NULL;
+  grub_efi_status_t status;
+  grub_efi_uintn_t key;
+  grub_efi_uint32_t desc_version;
+  grub_efi_boot_services_t *b;
+
+  b = grub_efi_system_table-boot_services;
+
+  *map_size = 0;
+  *desc_size = 0;
+  key = 0;
+  status = efi_call_5 (b-get_memory_map, map_size, NULL, key,
+   desc_size, desc_version);
+
+  if (status != GRUB_EFI_BUFFER_TOO_SMALL)
+return GRUB_EFI_LOAD_ERROR;
+
+  /*
+   * Add an additional efi_memory_desc_t because we're doing an
+   * allocation which may be in a new descriptor region.
+   */
+  *map_size += *desc_size;
+  status = efi_call_3 (b-allocate_pool, GRUB_EFI_LOADER_DATA,
+   *map_size, (void **)m);
+  if (status != GRUB_EFI_SUCCESS)
+goto fail;
+
+  status = efi_call_5 (b-get_memory_map, map_size, m, key,
+   desc_size, desc_version);
+  if (status == GRUB_EFI_BUFFER_TOO_SMALL)
+{
+  efi_call_1 (b-free_pool, m);
+  return GRUB_EFI_LOAD_ERROR;
+}
+
+  if (status != GRUB_EFI_SUCCESS)
+efi_call_1 (b-free_pool, m);
+
+  if (key_ptr  status == GRUB_EFI_SUCCESS)
+*key_ptr = key;
+  if (desc_ver  status == GRUB_EFI_SUCCESS)
+*desc_ver = desc_version;
+
+fail:
+  *map = m;
+  return status;
+}
+
+/*
+ * Allocate at the highest possible address that is not above 'max'.
+ */
+void *grub2_efi_allocate_pages_high(grub_efi_physical_address_t max,
+			grub_efi_uint64_t pages, grub_efi_uint64_t align)
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_uintn_t map_size, desc_size;
+  grub_efi_memory_descriptor_t *map= NULL;
+  grub_efi_status_t status;
+  grub_uint64_t max_addr = 0;