linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] aarch64: always map VDSO at worst case alignment
@ 2014-01-15 21:41 Kyle McMartin
  2014-01-16 17:43 ` Will Deacon
  0 siblings, 1 reply; 5+ messages in thread
From: Kyle McMartin @ 2014-01-15 21:41 UTC (permalink / raw)
  To: linux-arm-kernel

Currently on ARM64 with 4K pages set, GDB fails to load the VDSO with
the error "Failed to read a valid object file image from memory" as it
is applying the phdr alignment to the vma, and attempting to read below
where the VDSO is mapped. This is because our segment alignment is 64K
in the ELF headers, but the VDSO only has PAGE_SIZE alignment from
get_unmapped_area.

Work around this by calling vm_unmapped_area directly, and specifying
the worst case alignment (64K) directly.

With this patch applied, I no longer have issues loading the VDSO in
gdb (and no more error message every time I run a program inside it.)

Signed-off-by: Kyle McMartin <kyle@redhat.com>

--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -163,7 +163,18 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 	vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
 
 	down_write(&mm->mmap_sem);
-	vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
+	{
+		/* the VDSO must be worst-case aligned to 64K */
+		struct vm_unmapped_area_info info =
+			{
+				.flags = 0,
+				.length = vdso_mapping_len,
+				.low_limit = mm->mmap_base,
+				.high_limit = TASK_SIZE,
+				.align_mask = (1 << 16) - 1,
+			};
+		vdso_base = vm_unmapped_area(&info);
+	}
 	if (IS_ERR_VALUE(vdso_base)) {
 		ret = vdso_base;
 		goto up_fail;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] aarch64: always map VDSO at worst case alignment
  2014-01-15 21:41 [PATCH] aarch64: always map VDSO at worst case alignment Kyle McMartin
@ 2014-01-16 17:43 ` Will Deacon
  2014-01-16 17:53   ` Kyle McMartin
  0 siblings, 1 reply; 5+ messages in thread
From: Will Deacon @ 2014-01-16 17:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Kyle,

On Wed, Jan 15, 2014 at 09:41:44PM +0000, Kyle McMartin wrote:
> Currently on ARM64 with 4K pages set, GDB fails to load the VDSO with
> the error "Failed to read a valid object file image from memory" as it
> is applying the phdr alignment to the vma, and attempting to read below
> where the VDSO is mapped. This is because our segment alignment is 64K
> in the ELF headers, but the VDSO only has PAGE_SIZE alignment from
> get_unmapped_area.
> 
> Work around this by calling vm_unmapped_area directly, and specifying
> the worst case alignment (64K) directly.
> 
> With this patch applied, I no longer have issues loading the VDSO in
> gdb (and no more error message every time I run a program inside it.)
> 
> Signed-off-by: Kyle McMartin <kyle@redhat.com>
> 
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -163,7 +163,18 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
>  	vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
>  
>  	down_write(&mm->mmap_sem);
> -	vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
> +	{
> +		/* the VDSO must be worst-case aligned to 64K */
> +		struct vm_unmapped_area_info info =
> +			{
> +				.flags = 0,
> +				.length = vdso_mapping_len,
> +				.low_limit = mm->mmap_base,
> +				.high_limit = TASK_SIZE,
> +				.align_mask = (1 << 16) - 1,
> +			};
> +		vdso_base = vm_unmapped_area(&info);
> +	}

I don't like this fix. The kernel is perfectly alright mapping the vdso at
the actual page size, as opposed to the maximum. Since the vdso isn't
demand-paged, we can actually just tell the linker not to bother forcing 64k
(worst case) alignment for PT_LOAD segments. Please can you try the patch
below?

Will

--->8

diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index d8064af42e62..6d20b7d162d8 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -48,7 +48,7 @@ $(obj-vdso): %.o: %.S
 
 # Actual build commands
 quiet_cmd_vdsold = VDSOL $@
-      cmd_vdsold = $(CC) $(c_flags) -Wl,-T $^ -o $@
+      cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@
 quiet_cmd_vdsoas = VDSOA $@
       cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
 

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH] aarch64: always map VDSO at worst case alignment
  2014-01-16 17:43 ` Will Deacon
@ 2014-01-16 17:53   ` Kyle McMartin
  2014-01-16 19:28     ` Kyle McMartin
  0 siblings, 1 reply; 5+ messages in thread
From: Kyle McMartin @ 2014-01-16 17:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 16, 2014 at 05:43:44PM +0000, Will Deacon wrote:
> > +		struct vm_unmapped_area_info info =
> > +			{
> > +				.flags = 0,
> > +				.length = vdso_mapping_len,
> > +				.low_limit = mm->mmap_base,
> > +				.high_limit = TASK_SIZE,
> > +				.align_mask = (1 << 16) - 1,
> > +			};
> > +		vdso_base = vm_unmapped_area(&info);
> > +	}
> 
> I don't like this fix. The kernel is perfectly alright mapping the vdso at
> the actual page size, as opposed to the maximum. Since the vdso isn't
> demand-paged, we can actually just tell the linker not to bother forcing 64k
> (worst case) alignment for PT_LOAD segments. Please can you try the patch
> below?
> 

Me either, tbh. ;-)

I was testing out using -Wl,-z,max-page-size for the
!CONFIG_ARM64_64K_PAGES case, and that seemed to work. A quick compile
check shows the segment alignment being 0x10 with -Wl,-n:

kmcmarti ~/linux $ eu-readelf -l
arch/arm64/kernel/vdso/vdso.so
Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz
MemSiz   Flg Align
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x000700
0x000700 R E 0x10

so I think that should work nicely!

I'll reboot a machine with this fix to test it as soon as possible.

Acked-by: Kyle McMartin <kyle@redhat.com>

> --- a/arch/arm64/kernel/vdso/Makefile
> +++ b/arch/arm64/kernel/vdso/Makefile
> @@ -48,7 +48,7 @@ $(obj-vdso): %.o: %.S
>  
>  # Actual build commands
>  quiet_cmd_vdsold = VDSOL $@
> -      cmd_vdsold = $(CC) $(c_flags) -Wl,-T $^ -o $@
> +      cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@
>  quiet_cmd_vdsoas = VDSOA $@
>        cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $<
>  

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] aarch64: always map VDSO at worst case alignment
  2014-01-16 17:53   ` Kyle McMartin
@ 2014-01-16 19:28     ` Kyle McMartin
  2014-01-16 19:32       ` Will Deacon
  0 siblings, 1 reply; 5+ messages in thread
From: Kyle McMartin @ 2014-01-16 19:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 16, 2014 at 12:53:18PM -0500, Kyle McMartin wrote:
> I'll reboot a machine with this fix to test it as soon as possible.
> 
> Acked-by: Kyle McMartin <kyle@redhat.com>
> 

Yeah, looks to work properly, although I didn't test 64K pages in the
simulator.

--Kyle

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] aarch64: always map VDSO at worst case alignment
  2014-01-16 19:28     ` Kyle McMartin
@ 2014-01-16 19:32       ` Will Deacon
  0 siblings, 0 replies; 5+ messages in thread
From: Will Deacon @ 2014-01-16 19:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 16, 2014 at 07:28:42PM +0000, Kyle McMartin wrote:
> On Thu, Jan 16, 2014 at 12:53:18PM -0500, Kyle McMartin wrote:
> > I'll reboot a machine with this fix to test it as soon as possible.
> > 
> > Acked-by: Kyle McMartin <kyle@redhat.com>
> > 
> 
> Yeah, looks to work properly, although I didn't test 64K pages in the
> simulator.

No problem. I did try testing 64k pages in the simulator, and found that
earlyprintk is broken (now fixed).

Cheers,

Will

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-01-16 19:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-15 21:41 [PATCH] aarch64: always map VDSO at worst case alignment Kyle McMartin
2014-01-16 17:43 ` Will Deacon
2014-01-16 17:53   ` Kyle McMartin
2014-01-16 19:28     ` Kyle McMartin
2014-01-16 19:32       ` Will Deacon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).