All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
@ 2007-03-05 11:14 Jan Beulich
  2007-03-05 13:42 ` Keir Fraser
  2007-03-05 20:07   ` [Xen-devel] " Jeremy Fitzhardinge
  0 siblings, 2 replies; 11+ messages in thread
From: Jan Beulich @ 2007-03-05 11:14 UTC (permalink / raw)
  To: xen-devel

This adds support for CONFIG_COMPAT_VDSO. As this will certainly raise
questions, I left in the code needed for an alternative approach (which
requires mode C code, but less build script changes).

Signed-off-by: Jan Beulich <jbeulich@novell.com>

Index: head-2007-02-27/arch/i386/Kconfig
===================================================================
--- head-2007-02-27.orig/arch/i386/Kconfig	2007-03-05 10:00:18.000000000 +0100
+++ head-2007-02-27/arch/i386/Kconfig	2007-02-27 16:27:37.000000000 +0100
@@ -819,7 +819,6 @@ config HOTPLUG_CPU
 
 config COMPAT_VDSO
 	bool "Compat VDSO support"
-	depends on !X86_XEN
 	default y
 	help
 	  Map the VDSO to the predictable old-style address too.
Index: head-2007-02-27/arch/i386/kernel/Makefile
===================================================================
--- head-2007-02-27.orig/arch/i386/kernel/Makefile	2007-03-05 10:00:18.000000000 +0100
+++ head-2007-02-27/arch/i386/kernel/Makefile	2007-02-27 16:27:37.000000000 +0100
@@ -74,6 +74,52 @@ $(obj)/vsyscall-%.so: $(src)/vsyscall.ld
 		      $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE
 	$(call if_changed,syscall)
 
+ifeq ($(CONFIG_XEN)$(CONFIG_COMPAT_VDSO),yy)
+
+# vsyscall.o also contains the vsyscall DSO relocation info as __initdata.
+# We must build both alternative images before we can assemble it.
+# Note: kbuild does not track this dependency due to usage of .include
+$(obj)/vsyscall.o: $(obj)/vsyscall-int80.rel $(obj)/vsyscall-sysenter.rel
+targets += $(foreach F,int80 sysenter,vsyscall-$F.so.alt vsyscall-$F.rel)
+targets += vsyscall.lds.alt
+
+# The alternative DSO images are built using an alternate base address.
+quiet_cmd_syscall_alt = REBASE  $@
+      cmd_syscall_alt = sed 's,^\([[:space:]]*\.[[:space:]]*=[[:space:]]*\),\1-0x55AA0000 + ,' $< >$@
+
+quiet_cmd_syscall_rel = COMPARE $@
+      cmd_syscall_rel = set -e; \
+			cmp -l $(basename $<) $< \
+			| { read off1 old1 new1; \
+			    read off2 old2 new2; \
+			    test $$(expr $$off1 + 1) = $$off2; \
+			    echo " .long $$(expr $$off1 - 3)"; \
+			    while read off1 old3 new3; do \
+				read off2 old4 new4; \
+				test $$(expr $$off1 + 1) = $$off2; \
+				test $$old1 = $$old3 -a $$new1 = $$new3; \
+				test $$old2 = $$old4 -a $$new2 = $$new4; \
+				echo " .long $$(expr $$off1 - 3)"; \
+			    done; \
+			  } >$@
+
+SYSCFLAGS_vsyscall-sysenter.so.alt = $(vsyscall-flags)
+SYSCFLAGS_vsyscall-int80.so.alt    = $(vsyscall-flags)
+
+$(obj)/vsyscall.lds.alt: $(obj)/vsyscall.lds FORCE
+	$(call if_changed,syscall_alt)
+
+$(obj)/vsyscall-int80.so.alt $(obj)/vsyscall-sysenter.so.alt: \
+$(obj)/vsyscall-%.so.alt: $(obj)/vsyscall.lds.alt \
+		      $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE
+	$(call if_changed,syscall)
+
+$(obj)/vsyscall-int80.rel $(obj)/vsyscall-sysenter.rel: \
+$(obj)/vsyscall-%.rel: $(obj)/vsyscall-%.so.alt FORCE
+	$(call if_changed,syscall_rel)
+
+endif
+
 # We also create a special relocatable object that should mirror the symbol
 # table and layout of the linked DSO.  With ld -R we can then refer to
 # these symbols in the kernel code rather than hand-coded addresses.
Index: head-2007-02-27/arch/i386/kernel/sysenter.c
===================================================================
--- head-2007-02-27.orig/arch/i386/kernel/sysenter.c	2007-03-05 10:00:18.000000000 +0100
+++ head-2007-02-27/arch/i386/kernel/sysenter.c	2007-02-27 16:27:37.000000000 +0100
@@ -25,6 +25,8 @@
 
 #ifdef CONFIG_XEN
 #include <xen/interface/callback.h>
+extern const unsigned long vdso_rel_int80_start[], vdso_rel_int80_end[];
+extern const unsigned long vdso_rel_sysenter_start[], vdso_rel_sysenter_end[];
 #endif
 
 /*
@@ -66,6 +68,142 @@ void enable_sep_cpu(void)
 #endif
 }
 
+#if defined(CONFIG_XEN) && defined(CONFIG_COMPAT_VDSO)
+static void __init relocate_vdso(Elf32_Ehdr *ehdr, unsigned long old_base, unsigned long new_base,
+                                 const unsigned long *reloc_start, const unsigned long *reloc_end)
+{
+#if 1
+	const unsigned long *reloc;
+
+	for (reloc = reloc_start; reloc < reloc_end; ++reloc) {
+		unsigned long *ptr = (void *)((unsigned long)ehdr + *reloc);
+
+		*ptr += new_base - old_base;
+	}
+#else
+	unsigned i, ndynsym = 0, szdynsym = 0;
+	unsigned long dynsym = 0;
+
+	BUG_ON(ehdr->e_ident[EI_MAG0] != ELFMAG0);
+	BUG_ON(ehdr->e_ident[EI_MAG1] != ELFMAG1);
+	BUG_ON(ehdr->e_ident[EI_MAG2] != ELFMAG2);
+	BUG_ON(ehdr->e_ident[EI_MAG3] != ELFMAG3);
+	BUG_ON(ehdr->e_ident[EI_CLASS] != ELFCLASS32);
+	BUG_ON(ehdr->e_ident[EI_DATA] != ELFDATA2LSB);
+	BUG_ON(ehdr->e_ehsize < sizeof(*ehdr));
+	ehdr->e_entry += new_base - old_base;
+	BUG_ON(ehdr->e_phentsize < sizeof(Elf32_Phdr));
+	for (i = 0; i < ehdr->e_phnum; ++i) {
+		Elf32_Phdr *phdr = (void *)((unsigned long)ehdr + ehdr->e_phoff + i * ehdr->e_phentsize);
+
+		phdr->p_vaddr += new_base - old_base;
+		switch(phdr->p_type) {
+		case PT_LOAD:
+		case PT_NOTE:
+			break;
+		case PT_DYNAMIC: {
+				Elf32_Dyn *dyn = (void *)(phdr->p_vaddr - new_base + (unsigned long)ehdr);
+				unsigned j;
+
+				for(j = 0; dyn[j].d_tag != DT_NULL; ++j) {
+					switch(dyn[j].d_tag) {
+					case DT_HASH:
+					case DT_STRTAB:
+					case DT_SYMTAB:
+					case 0x6ffffff0: /* DT_VERSYM */
+					case 0x6ffffffc: /* DT_VERDEF */
+						break;
+					case DT_SONAME:
+					case DT_STRSZ:
+					case 0x6ffffffd: /* DT_VERDEFNUM */
+						continue;
+					case DT_SYMENT:
+						szdynsym = dyn[j].d_un.d_val;
+						continue;
+					default:
+						if (dyn[j].d_tag >= 0x60000000 /* OLD_DT_LOOS */
+						    || dyn[j].d_tag < 31 /* DT_ENCODING */
+						    || !(dyn[j].d_tag & 1)) {
+							printk(KERN_WARNING "vDSO dynamic info %u has unsupported tag
%08X\n", j, dyn[j].d_tag);
+							WARN_ON(1);
+							continue;
+						}
+						break;
+					}
+					dyn[j].d_un.d_ptr += new_base - old_base;
+					switch(dyn[j].d_tag) {
+					case DT_HASH:
+						ndynsym = ((Elf32_Word *)dyn[j].d_un.d_ptr)[1];
+						break;
+					case DT_SYMTAB:
+						dynsym = dyn[j].d_un.d_ptr;
+						break;
+					}
+				}
+			}
+			break;
+		case PT_GNU_EH_FRAME:
+			/* XXX */
+			break;
+		default:
+			printk(KERN_WARNING "vDSO program header %u has unsupported type %08X\n", i, phdr->p_type);
+			WARN_ON(1);
+			break;
+		}
+	}
+	BUG_ON(ehdr->e_shentsize < sizeof(Elf32_Shdr));
+	BUG_ON(ehdr->e_shnum >= SHN_LORESERVE);
+	for (i = 1; i < ehdr->e_shnum; ++i) {
+		Elf32_Shdr *shdr = (void *)((unsigned long)ehdr + ehdr->e_shoff + i * ehdr->e_shentsize);
+
+		if (!(shdr->sh_flags & SHF_ALLOC))
+			continue;
+		shdr->sh_addr += new_base - old_base;
+		switch(shdr->sh_type) {
+		case SHT_DYNAMIC:
+		case SHT_HASH:
+		case SHT_NOBITS:
+		case SHT_NOTE:
+		case SHT_PROGBITS:
+		case SHT_STRTAB:
+		case 0x6ffffffd: /* SHT_GNU_verdef */
+		case 0x6fffffff: /* SHT_GNU_versym */
+			break;
+		case SHT_DYNSYM:
+			BUG_ON(shdr->sh_entsize < sizeof(Elf32_Sym));
+			if (!szdynsym)
+				szdynsym = shdr->sh_entsize;
+			else
+				WARN_ON(szdynsym != shdr->sh_entsize);
+			if (!ndynsym)
+				ndynsym = shdr->sh_size / szdynsym;
+			else
+				WARN_ON(ndynsym != shdr->sh_size / szdynsym);
+			if (!dynsym)
+				dynsym = shdr->sh_addr;
+			else
+				WARN_ON(dynsym != shdr->sh_addr);
+			break;
+		default:
+			printk(KERN_WARNING "vDSO section %u has unsupported type %08X\n", i, shdr->sh_type);
+			WARN_ON(shdr->sh_size);
+			break;
+		}
+	}
+	dynsym += (unsigned long)ehdr - new_base;
+	for(i = 1; i < ndynsym; ++i) {
+		Elf32_Sym *sym = (void *)(dynsym + i * szdynsym);
+
+		if (sym->st_shndx == SHN_ABS)
+			continue;
+		sym->st_value += new_base - old_base;
+	}
+#endif
+}
+#else
+#define relocate_vdso(ehdr, old, new, start, end) ((void)0)
+#endif
+
 /*
  * These symbols are defined by vsyscall.o to mark the bounds
  * of the ELF DSO images included therein.
@@ -104,12 +245,16 @@ int __init sysenter_setup(void)
 		memcpy(syscall_page,
 		       &vsyscall_int80_start,
 		       &vsyscall_int80_end - &vsyscall_int80_start);
+		relocate_vdso(syscall_page, VDSO_PRELINK, __fix_to_virt(FIX_VDSO),
+		              vdso_rel_int80_start, vdso_rel_int80_end);
 		return 0;
 	}
 
 	memcpy(syscall_page,
 	       &vsyscall_sysenter_start,
 	       &vsyscall_sysenter_end - &vsyscall_sysenter_start);
+	relocate_vdso(syscall_page, VDSO_PRELINK, __fix_to_virt(FIX_VDSO),
+	              vdso_rel_sysenter_start, vdso_rel_sysenter_end);
 
 	return 0;
 }
Index: head-2007-02-27/arch/i386/kernel/vsyscall.S
===================================================================
--- head-2007-02-27.orig/arch/i386/kernel/vsyscall.S	2007-03-05 10:00:18.000000000 +0100
+++ head-2007-02-27/arch/i386/kernel/vsyscall.S	2007-02-27 16:27:37.000000000 +0100
@@ -12,4 +12,20 @@ vsyscall_sysenter_start:
 	.incbin "arch/i386/kernel/vsyscall-sysenter.so"
 vsyscall_sysenter_end:
 
+#if defined(CONFIG_XEN) && defined(CONFIG_COMPAT_VDSO)
+
+	.align 4
+
+	.globl vdso_rel_int80_start, vdso_rel_int80_end
+vdso_rel_int80_start:
+	.include "arch/i386/kernel/vsyscall-int80.rel"
+vdso_rel_int80_end:
+
+	.globl vdso_rel_sysenter_start, vdso_rel_sysenter_end
+vdso_rel_sysenter_start:
+	.include "arch/i386/kernel/vsyscall-sysenter.rel"
+vdso_rel_sysenter_end:
+
+#endif
+
 __FINIT
Index: head-2007-02-27/include/asm-i386/elf.h
===================================================================
--- head-2007-02-27.orig/include/asm-i386/elf.h	2007-03-05 10:00:18.000000000 +0100
+++ head-2007-02-27/include/asm-i386/elf.h	2007-02-27 16:27:37.000000000 +0100
@@ -137,7 +137,11 @@ extern int dump_task_extended_fpu (struc
 
 #ifdef CONFIG_COMPAT_VDSO
 # define VDSO_COMPAT_BASE	VDSO_HIGH_BASE
-# define VDSO_PRELINK		VDSO_HIGH_BASE
+# ifndef CONFIG_XEN
+#  define VDSO_PRELINK		VDSO_HIGH_BASE
+# else
+#  define VDSO_PRELINK		(0UL - FIX_VDSO * PAGE_SIZE)
+# endif
 #else
 # define VDSO_COMPAT_BASE	VDSO_BASE
 # define VDSO_PRELINK		0

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

* Re: [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
  2007-03-05 11:14 [PATCH 2/10] linux 2.6.18: COMPAT_VDSO Jan Beulich
@ 2007-03-05 13:42 ` Keir Fraser
  2007-03-05 14:48   ` Jan Beulich
  2007-03-05 20:07   ` [Xen-devel] " Jeremy Fitzhardinge
  1 sibling, 1 reply; 11+ messages in thread
From: Keir Fraser @ 2007-03-05 13:42 UTC (permalink / raw)
  To: Jan Beulich, xen-devel

On 5/3/07 11:14, "Jan Beulich" <jbeulich@novell.com> wrote:

> This adds support for CONFIG_COMPAT_VDSO. As this will certainly raise
> questions, I left in the code needed for an alternative approach (which
> requires mode C code, but less build script changes).

I thought COMPAT_VDSO meant that the VDSO had to be mapped at a fixed
location at top of memory, which is impossible when running on Xen?

 -- Keir

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

* Re: [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
  2007-03-05 13:42 ` Keir Fraser
@ 2007-03-05 14:48   ` Jan Beulich
  2007-03-05 15:55     ` Keir Fraser
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2007-03-05 14:48 UTC (permalink / raw)
  To: Keir Fraser; +Cc: xen-devel

>>> Keir Fraser <keir@xensource.com> 05.03.07 14:42 >>>
>On 5/3/07 11:14, "Jan Beulich" <jbeulich@novell.com> wrote:
>
>> This adds support for CONFIG_COMPAT_VDSO. As this will certainly raise
>> questions, I left in the code needed for an alternative approach (which
>> requires mode C code, but less build script changes).
>
>I thought COMPAT_VDSO meant that the VDSO had to be mapped at a fixed
>location at top of memory, which is impossible when running on Xen?

It's gonna be really old libc-s that need an absolutely invariable address. But
you certainly recall that in 2.6.16 (and probably earlier) we had a hack to map
it in right below PAGE_OFFSET, which worked too for not really new but also
not really old libc-s. It is those intermediate libc (supporting AT_SYSINFO but
not AT_SYSINFO_EHDR) versions that the option attempts to address for
Xen. I happen to have a SuSE 9.0 system still in active use that doesn't work
without this option, and I think glibc 2.3.2 shouldn't be considered entirely
obsolete, yet.

Jan

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

* Re: [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
  2007-03-05 14:48   ` Jan Beulich
@ 2007-03-05 15:55     ` Keir Fraser
  2007-03-09 10:17       ` Jan Beulich
  0 siblings, 1 reply; 11+ messages in thread
From: Keir Fraser @ 2007-03-05 15:55 UTC (permalink / raw)
  To: Jan Beulich, Keir Fraser; +Cc: xen-devel

On 5/3/07 14:48, "Jan Beulich" <jbeulich@novell.com> wrote:

> It's gonna be really old libc-s that need an absolutely invariable address.
> But
> you certainly recall that in 2.6.16 (and probably earlier) we had a hack to
> map
> it in right below PAGE_OFFSET, which worked too for not really new but also
> not really old libc-s. It is those intermediate libc (supporting AT_SYSINFO
> but
> not AT_SYSINFO_EHDR) versions that the option attempts to address for
> Xen. I happen to have a SuSE 9.0 system still in active use that doesn't work
> without this option, and I think glibc 2.3.2 shouldn't be considered entirely
> obsolete, yet.

The build-system approach looks simplest (certainly smaller than the C code)
but is impenetrable to read. I think we'd take that approach if you add some
comments to explain what's going on in the makefile runes.

 -- Keir

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

* Re: [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
  2007-03-05 11:14 [PATCH 2/10] linux 2.6.18: COMPAT_VDSO Jan Beulich
@ 2007-03-05 20:07   ` Jeremy Fitzhardinge
  2007-03-05 20:07   ` [Xen-devel] " Jeremy Fitzhardinge
  1 sibling, 0 replies; 11+ messages in thread
From: Jeremy Fitzhardinge @ 2007-03-05 20:07 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Virtualization Mailing List, Rusty Russell, xen-devel, Andi Kleen,
	Linux Kernel Mailing List

Jan Beulich wrote:
> This adds support for CONFIG_COMPAT_VDSO. As this will certainly raise
> questions, I left in the code needed for an alternative approach (which
> requires mode C code, but less build script changes).
>   

Ingo just raised this as an issue for paravirt_ops as well.  I don't
quite follow what's going on there.   My understanding is that there are
some old versions of glibc (which were unreleased CVS snapshots shipped
by some vendors) which don't use the vdso's ELF header, but instead have
their own canned one which built into the library itself.

If that's the case (and I suspect I'm wrong about the detail here), then
how does this patch help?

And either way, we lose COMPAT_VDSO support for very old glibcs which
support the vdso at a really at a fixed address.  I don't know how many
real systems that would effect at this point though.

The C version looks more appealing to be, for a couple of reasons.  One,
its actually more comprehensible.  And two, it opens the possibility of
generating other customised vdsos.  One complaint about the Xen pv_ops
patches is that we unconditionally put the non-negative-offset-tls vdso
in place regardless of the actual hypervisor; if we can switch vdsos
depending on the hypervisor then that would be good.  Though that
wouldn't actually require anything more than fiddling with the ELF
notes, so it wouldn't actually require any relocs.

    J

[patch below for reference]

> Signed-off-by: Jan Beulich <jbeulich@novell.com>
>
> Index: head-2007-02-27/arch/i386/Kconfig
> ===================================================================
> --- head-2007-02-27.orig/arch/i386/Kconfig	2007-03-05 10:00:18.000000000 +0100
> +++ head-2007-02-27/arch/i386/Kconfig	2007-02-27 16:27:37.000000000 +0100
> @@ -819,7 +819,6 @@ config HOTPLUG_CPU
>  
>  config COMPAT_VDSO
>  	bool "Compat VDSO support"
> -	depends on !X86_XEN
>  	default y
>  	help
>  	  Map the VDSO to the predictable old-style address too.
> Index: head-2007-02-27/arch/i386/kernel/Makefile
> ===================================================================
> --- head-2007-02-27.orig/arch/i386/kernel/Makefile	2007-03-05 10:00:18.000000000 +0100
> +++ head-2007-02-27/arch/i386/kernel/Makefile	2007-02-27 16:27:37.000000000 +0100
> @@ -74,6 +74,52 @@ $(obj)/vsyscall-%.so: $(src)/vsyscall.ld
>  		      $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE
>  	$(call if_changed,syscall)
>  
> +ifeq ($(CONFIG_XEN)$(CONFIG_COMPAT_VDSO),yy)
> +
> +# vsyscall.o also contains the vsyscall DSO relocation info as __initdata.
> +# We must build both alternative images before we can assemble it.
> +# Note: kbuild does not track this dependency due to usage of .include
> +$(obj)/vsyscall.o: $(obj)/vsyscall-int80.rel $(obj)/vsyscall-sysenter.rel
> +targets += $(foreach F,int80 sysenter,vsyscall-$F.so.alt vsyscall-$F.rel)
> +targets += vsyscall.lds.alt
> +
> +# The alternative DSO images are built using an alternate base address.
> +quiet_cmd_syscall_alt = REBASE  $@
> +      cmd_syscall_alt = sed 's,^\([[:space:]]*\.[[:space:]]*=[[:space:]]*\),\1-0x55AA0000 + ,' $< >$@
> +
> +quiet_cmd_syscall_rel = COMPARE $@
> +      cmd_syscall_rel = set -e; \
> +			cmp -l $(basename $<) $< \
> +			| { read off1 old1 new1; \
> +			    read off2 old2 new2; \
> +			    test $$(expr $$off1 + 1) = $$off2; \
> +			    echo " .long $$(expr $$off1 - 3)"; \
> +			    while read off1 old3 new3; do \
> +				read off2 old4 new4; \
> +				test $$(expr $$off1 + 1) = $$off2; \
> +				test $$old1 = $$old3 -a $$new1 = $$new3; \
> +				test $$old2 = $$old4 -a $$new2 = $$new4; \
> +				echo " .long $$(expr $$off1 - 3)"; \
> +			    done; \
> +			  } >$@
> +
> +SYSCFLAGS_vsyscall-sysenter.so.alt = $(vsyscall-flags)
> +SYSCFLAGS_vsyscall-int80.so.alt    = $(vsyscall-flags)
> +
> +$(obj)/vsyscall.lds.alt: $(obj)/vsyscall.lds FORCE
> +	$(call if_changed,syscall_alt)
> +
> +$(obj)/vsyscall-int80.so.alt $(obj)/vsyscall-sysenter.so.alt: \
> +$(obj)/vsyscall-%.so.alt: $(obj)/vsyscall.lds.alt \
> +		      $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE
> +	$(call if_changed,syscall)
> +
> +$(obj)/vsyscall-int80.rel $(obj)/vsyscall-sysenter.rel: \
> +$(obj)/vsyscall-%.rel: $(obj)/vsyscall-%.so.alt FORCE
> +	$(call if_changed,syscall_rel)
> +
> +endif
> +
>  # We also create a special relocatable object that should mirror the symbol
>  # table and layout of the linked DSO.  With ld -R we can then refer to
>  # these symbols in the kernel code rather than hand-coded addresses.
> Index: head-2007-02-27/arch/i386/kernel/sysenter.c
> ===================================================================
> --- head-2007-02-27.orig/arch/i386/kernel/sysenter.c	2007-03-05 10:00:18.000000000 +0100
> +++ head-2007-02-27/arch/i386/kernel/sysenter.c	2007-02-27 16:27:37.000000000 +0100
> @@ -25,6 +25,8 @@
>  
>  #ifdef CONFIG_XEN
>  #include <xen/interface/callback.h>
> +extern const unsigned long vdso_rel_int80_start[], vdso_rel_int80_end[];
> +extern const unsigned long vdso_rel_sysenter_start[], vdso_rel_sysenter_end[];
>  #endif
>  
>  /*
> @@ -66,6 +68,142 @@ void enable_sep_cpu(void)
>  #endif
>  }
>  
> +#if defined(CONFIG_XEN) && defined(CONFIG_COMPAT_VDSO)
> +static void __init relocate_vdso(Elf32_Ehdr *ehdr, unsigned long old_base, unsigned long new_base,
> +                                 const unsigned long *reloc_start, const unsigned long *reloc_end)
> +{
> +#if 1
> +	const unsigned long *reloc;
> +
> +	for (reloc = reloc_start; reloc < reloc_end; ++reloc) {
> +		unsigned long *ptr = (void *)((unsigned long)ehdr + *reloc);
> +
> +		*ptr += new_base - old_base;
> +	}
> +#else
> +	unsigned i, ndynsym = 0, szdynsym = 0;
> +	unsigned long dynsym = 0;
> +
> +	BUG_ON(ehdr->e_ident[EI_MAG0] != ELFMAG0);
> +	BUG_ON(ehdr->e_ident[EI_MAG1] != ELFMAG1);
> +	BUG_ON(ehdr->e_ident[EI_MAG2] != ELFMAG2);
> +	BUG_ON(ehdr->e_ident[EI_MAG3] != ELFMAG3);
> +	BUG_ON(ehdr->e_ident[EI_CLASS] != ELFCLASS32);
> +	BUG_ON(ehdr->e_ident[EI_DATA] != ELFDATA2LSB);
> +	BUG_ON(ehdr->e_ehsize < sizeof(*ehdr));
> +	ehdr->e_entry += new_base - old_base;
> +	BUG_ON(ehdr->e_phentsize < sizeof(Elf32_Phdr));
> +	for (i = 0; i < ehdr->e_phnum; ++i) {
> +		Elf32_Phdr *phdr = (void *)((unsigned long)ehdr + ehdr->e_phoff + i * ehdr->e_phentsize);
> +
> +		phdr->p_vaddr += new_base - old_base;
> +		switch(phdr->p_type) {
> +		case PT_LOAD:
> +		case PT_NOTE:
> +			break;
> +		case PT_DYNAMIC: {
> +				Elf32_Dyn *dyn = (void *)(phdr->p_vaddr - new_base + (unsigned long)ehdr);
> +				unsigned j;
> +
> +				for(j = 0; dyn[j].d_tag != DT_NULL; ++j) {
> +					switch(dyn[j].d_tag) {
> +					case DT_HASH:
> +					case DT_STRTAB:
> +					case DT_SYMTAB:
> +					case 0x6ffffff0: /* DT_VERSYM */
> +					case 0x6ffffffc: /* DT_VERDEF */
> +						break;
> +					case DT_SONAME:
> +					case DT_STRSZ:
> +					case 0x6ffffffd: /* DT_VERDEFNUM */
> +						continue;
> +					case DT_SYMENT:
> +						szdynsym = dyn[j].d_un.d_val;
> +						continue;
> +					default:
> +						if (dyn[j].d_tag >= 0x60000000 /* OLD_DT_LOOS */
> +						    || dyn[j].d_tag < 31 /* DT_ENCODING */
> +						    || !(dyn[j].d_tag & 1)) {
> +							printk(KERN_WARNING "vDSO dynamic info %u has unsupported tag
> %08X\n", j, dyn[j].d_tag);
> +							WARN_ON(1);
> +							continue;
> +						}
> +						break;
> +					}
> +					dyn[j].d_un.d_ptr += new_base - old_base;
> +					switch(dyn[j].d_tag) {
> +					case DT_HASH:
> +						ndynsym = ((Elf32_Word *)dyn[j].d_un.d_ptr)[1];
> +						break;
> +					case DT_SYMTAB:
> +						dynsym = dyn[j].d_un.d_ptr;
> +						break;
> +					}
> +				}
> +			}
> +			break;
> +		case PT_GNU_EH_FRAME:
> +			/* XXX */
> +			break;
> +		default:
> +			printk(KERN_WARNING "vDSO program header %u has unsupported type %08X\n", i, phdr->p_type);
> +			WARN_ON(1);
> +			break;
> +		}
> +	}
> +	BUG_ON(ehdr->e_shentsize < sizeof(Elf32_Shdr));
> +	BUG_ON(ehdr->e_shnum >= SHN_LORESERVE);
> +	for (i = 1; i < ehdr->e_shnum; ++i) {
> +		Elf32_Shdr *shdr = (void *)((unsigned long)ehdr + ehdr->e_shoff + i * ehdr->e_shentsize);
> +
> +		if (!(shdr->sh_flags & SHF_ALLOC))
> +			continue;
> +		shdr->sh_addr += new_base - old_base;
> +		switch(shdr->sh_type) {
> +		case SHT_DYNAMIC:
> +		case SHT_HASH:
> +		case SHT_NOBITS:
> +		case SHT_NOTE:
> +		case SHT_PROGBITS:
> +		case SHT_STRTAB:
> +		case 0x6ffffffd: /* SHT_GNU_verdef */
> +		case 0x6fffffff: /* SHT_GNU_versym */
> +			break;
> +		case SHT_DYNSYM:
> +			BUG_ON(shdr->sh_entsize < sizeof(Elf32_Sym));
> +			if (!szdynsym)
> +				szdynsym = shdr->sh_entsize;
> +			else
> +				WARN_ON(szdynsym != shdr->sh_entsize);
> +			if (!ndynsym)
> +				ndynsym = shdr->sh_size / szdynsym;
> +			else
> +				WARN_ON(ndynsym != shdr->sh_size / szdynsym);
> +			if (!dynsym)
> +				dynsym = shdr->sh_addr;
> +			else
> +				WARN_ON(dynsym != shdr->sh_addr);
> +			break;
> +		default:
> +			printk(KERN_WARNING "vDSO section %u has unsupported type %08X\n", i, shdr->sh_type);
> +			WARN_ON(shdr->sh_size);
> +			break;
> +		}
> +	}
> +	dynsym += (unsigned long)ehdr - new_base;
> +	for(i = 1; i < ndynsym; ++i) {
> +		Elf32_Sym *sym = (void *)(dynsym + i * szdynsym);
> +
> +		if (sym->st_shndx == SHN_ABS)
> +			continue;
> +		sym->st_value += new_base - old_base;
> +	}
> +#endif
> +}
> +#else
> +#define relocate_vdso(ehdr, old, new, start, end) ((void)0)
> +#endif
> +
>  /*
>   * These symbols are defined by vsyscall.o to mark the bounds
>   * of the ELF DSO images included therein.
> @@ -104,12 +245,16 @@ int __init sysenter_setup(void)
>  		memcpy(syscall_page,
>  		       &vsyscall_int80_start,
>  		       &vsyscall_int80_end - &vsyscall_int80_start);
> +		relocate_vdso(syscall_page, VDSO_PRELINK, __fix_to_virt(FIX_VDSO),
> +		              vdso_rel_int80_start, vdso_rel_int80_end);
>  		return 0;
>  	}
>  
>  	memcpy(syscall_page,
>  	       &vsyscall_sysenter_start,
>  	       &vsyscall_sysenter_end - &vsyscall_sysenter_start);
> +	relocate_vdso(syscall_page, VDSO_PRELINK, __fix_to_virt(FIX_VDSO),
> +	              vdso_rel_sysenter_start, vdso_rel_sysenter_end);
>  
>  	return 0;
>  }
> Index: head-2007-02-27/arch/i386/kernel/vsyscall.S
> ===================================================================
> --- head-2007-02-27.orig/arch/i386/kernel/vsyscall.S	2007-03-05 10:00:18.000000000 +0100
> +++ head-2007-02-27/arch/i386/kernel/vsyscall.S	2007-02-27 16:27:37.000000000 +0100
> @@ -12,4 +12,20 @@ vsyscall_sysenter_start:
>  	.incbin "arch/i386/kernel/vsyscall-sysenter.so"
>  vsyscall_sysenter_end:
>  
> +#if defined(CONFIG_XEN) && defined(CONFIG_COMPAT_VDSO)
> +
> +	.align 4
> +
> +	.globl vdso_rel_int80_start, vdso_rel_int80_end
> +vdso_rel_int80_start:
> +	.include "arch/i386/kernel/vsyscall-int80.rel"
> +vdso_rel_int80_end:
> +
> +	.globl vdso_rel_sysenter_start, vdso_rel_sysenter_end
> +vdso_rel_sysenter_start:
> +	.include "arch/i386/kernel/vsyscall-sysenter.rel"
> +vdso_rel_sysenter_end:
> +
> +#endif
> +
>  __FINIT
> Index: head-2007-02-27/include/asm-i386/elf.h
> ===================================================================
> --- head-2007-02-27.orig/include/asm-i386/elf.h	2007-03-05 10:00:18.000000000 +0100
> +++ head-2007-02-27/include/asm-i386/elf.h	2007-02-27 16:27:37.000000000 +0100
> @@ -137,7 +137,11 @@ extern int dump_task_extended_fpu (struc
>  
>  #ifdef CONFIG_COMPAT_VDSO
>  # define VDSO_COMPAT_BASE	VDSO_HIGH_BASE
> -# define VDSO_PRELINK		VDSO_HIGH_BASE
> +# ifndef CONFIG_XEN
> +#  define VDSO_PRELINK		VDSO_HIGH_BASE
> +# else
> +#  define VDSO_PRELINK		(0UL - FIX_VDSO * PAGE_SIZE)
> +# endif
>  #else
>  # define VDSO_COMPAT_BASE	VDSO_BASE
>  # define VDSO_PRELINK		0
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
>   

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

* Re: [Xen-devel] [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
@ 2007-03-05 20:07   ` Jeremy Fitzhardinge
  0 siblings, 0 replies; 11+ messages in thread
From: Jeremy Fitzhardinge @ 2007-03-05 20:07 UTC (permalink / raw)
  To: Jan Beulich
  Cc: xen-devel, Virtualization Mailing List, Rusty Russell, Andi Kleen,
	Linux Kernel Mailing List

Jan Beulich wrote:
> This adds support for CONFIG_COMPAT_VDSO. As this will certainly raise
> questions, I left in the code needed for an alternative approach (which
> requires mode C code, but less build script changes).
>   

Ingo just raised this as an issue for paravirt_ops as well.  I don't
quite follow what's going on there.   My understanding is that there are
some old versions of glibc (which were unreleased CVS snapshots shipped
by some vendors) which don't use the vdso's ELF header, but instead have
their own canned one which built into the library itself.

If that's the case (and I suspect I'm wrong about the detail here), then
how does this patch help?

And either way, we lose COMPAT_VDSO support for very old glibcs which
support the vdso at a really at a fixed address.  I don't know how many
real systems that would effect at this point though.

The C version looks more appealing to be, for a couple of reasons.  One,
its actually more comprehensible.  And two, it opens the possibility of
generating other customised vdsos.  One complaint about the Xen pv_ops
patches is that we unconditionally put the non-negative-offset-tls vdso
in place regardless of the actual hypervisor; if we can switch vdsos
depending on the hypervisor then that would be good.  Though that
wouldn't actually require anything more than fiddling with the ELF
notes, so it wouldn't actually require any relocs.

    J

[patch below for reference]

> Signed-off-by: Jan Beulich <jbeulich@novell.com>
>
> Index: head-2007-02-27/arch/i386/Kconfig
> ===================================================================
> --- head-2007-02-27.orig/arch/i386/Kconfig	2007-03-05 10:00:18.000000000 +0100
> +++ head-2007-02-27/arch/i386/Kconfig	2007-02-27 16:27:37.000000000 +0100
> @@ -819,7 +819,6 @@ config HOTPLUG_CPU
>  
>  config COMPAT_VDSO
>  	bool "Compat VDSO support"
> -	depends on !X86_XEN
>  	default y
>  	help
>  	  Map the VDSO to the predictable old-style address too.
> Index: head-2007-02-27/arch/i386/kernel/Makefile
> ===================================================================
> --- head-2007-02-27.orig/arch/i386/kernel/Makefile	2007-03-05 10:00:18.000000000 +0100
> +++ head-2007-02-27/arch/i386/kernel/Makefile	2007-02-27 16:27:37.000000000 +0100
> @@ -74,6 +74,52 @@ $(obj)/vsyscall-%.so: $(src)/vsyscall.ld
>  		      $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE
>  	$(call if_changed,syscall)
>  
> +ifeq ($(CONFIG_XEN)$(CONFIG_COMPAT_VDSO),yy)
> +
> +# vsyscall.o also contains the vsyscall DSO relocation info as __initdata.
> +# We must build both alternative images before we can assemble it.
> +# Note: kbuild does not track this dependency due to usage of .include
> +$(obj)/vsyscall.o: $(obj)/vsyscall-int80.rel $(obj)/vsyscall-sysenter.rel
> +targets += $(foreach F,int80 sysenter,vsyscall-$F.so.alt vsyscall-$F.rel)
> +targets += vsyscall.lds.alt
> +
> +# The alternative DSO images are built using an alternate base address.
> +quiet_cmd_syscall_alt = REBASE  $@
> +      cmd_syscall_alt = sed 's,^\([[:space:]]*\.[[:space:]]*=[[:space:]]*\),\1-0x55AA0000 + ,' $< >$@
> +
> +quiet_cmd_syscall_rel = COMPARE $@
> +      cmd_syscall_rel = set -e; \
> +			cmp -l $(basename $<) $< \
> +			| { read off1 old1 new1; \
> +			    read off2 old2 new2; \
> +			    test $$(expr $$off1 + 1) = $$off2; \
> +			    echo " .long $$(expr $$off1 - 3)"; \
> +			    while read off1 old3 new3; do \
> +				read off2 old4 new4; \
> +				test $$(expr $$off1 + 1) = $$off2; \
> +				test $$old1 = $$old3 -a $$new1 = $$new3; \
> +				test $$old2 = $$old4 -a $$new2 = $$new4; \
> +				echo " .long $$(expr $$off1 - 3)"; \
> +			    done; \
> +			  } >$@
> +
> +SYSCFLAGS_vsyscall-sysenter.so.alt = $(vsyscall-flags)
> +SYSCFLAGS_vsyscall-int80.so.alt    = $(vsyscall-flags)
> +
> +$(obj)/vsyscall.lds.alt: $(obj)/vsyscall.lds FORCE
> +	$(call if_changed,syscall_alt)
> +
> +$(obj)/vsyscall-int80.so.alt $(obj)/vsyscall-sysenter.so.alt: \
> +$(obj)/vsyscall-%.so.alt: $(obj)/vsyscall.lds.alt \
> +		      $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE
> +	$(call if_changed,syscall)
> +
> +$(obj)/vsyscall-int80.rel $(obj)/vsyscall-sysenter.rel: \
> +$(obj)/vsyscall-%.rel: $(obj)/vsyscall-%.so.alt FORCE
> +	$(call if_changed,syscall_rel)
> +
> +endif
> +
>  # We also create a special relocatable object that should mirror the symbol
>  # table and layout of the linked DSO.  With ld -R we can then refer to
>  # these symbols in the kernel code rather than hand-coded addresses.
> Index: head-2007-02-27/arch/i386/kernel/sysenter.c
> ===================================================================
> --- head-2007-02-27.orig/arch/i386/kernel/sysenter.c	2007-03-05 10:00:18.000000000 +0100
> +++ head-2007-02-27/arch/i386/kernel/sysenter.c	2007-02-27 16:27:37.000000000 +0100
> @@ -25,6 +25,8 @@
>  
>  #ifdef CONFIG_XEN
>  #include <xen/interface/callback.h>
> +extern const unsigned long vdso_rel_int80_start[], vdso_rel_int80_end[];
> +extern const unsigned long vdso_rel_sysenter_start[], vdso_rel_sysenter_end[];
>  #endif
>  
>  /*
> @@ -66,6 +68,142 @@ void enable_sep_cpu(void)
>  #endif
>  }
>  
> +#if defined(CONFIG_XEN) && defined(CONFIG_COMPAT_VDSO)
> +static void __init relocate_vdso(Elf32_Ehdr *ehdr, unsigned long old_base, unsigned long new_base,
> +                                 const unsigned long *reloc_start, const unsigned long *reloc_end)
> +{
> +#if 1
> +	const unsigned long *reloc;
> +
> +	for (reloc = reloc_start; reloc < reloc_end; ++reloc) {
> +		unsigned long *ptr = (void *)((unsigned long)ehdr + *reloc);
> +
> +		*ptr += new_base - old_base;
> +	}
> +#else
> +	unsigned i, ndynsym = 0, szdynsym = 0;
> +	unsigned long dynsym = 0;
> +
> +	BUG_ON(ehdr->e_ident[EI_MAG0] != ELFMAG0);
> +	BUG_ON(ehdr->e_ident[EI_MAG1] != ELFMAG1);
> +	BUG_ON(ehdr->e_ident[EI_MAG2] != ELFMAG2);
> +	BUG_ON(ehdr->e_ident[EI_MAG3] != ELFMAG3);
> +	BUG_ON(ehdr->e_ident[EI_CLASS] != ELFCLASS32);
> +	BUG_ON(ehdr->e_ident[EI_DATA] != ELFDATA2LSB);
> +	BUG_ON(ehdr->e_ehsize < sizeof(*ehdr));
> +	ehdr->e_entry += new_base - old_base;
> +	BUG_ON(ehdr->e_phentsize < sizeof(Elf32_Phdr));
> +	for (i = 0; i < ehdr->e_phnum; ++i) {
> +		Elf32_Phdr *phdr = (void *)((unsigned long)ehdr + ehdr->e_phoff + i * ehdr->e_phentsize);
> +
> +		phdr->p_vaddr += new_base - old_base;
> +		switch(phdr->p_type) {
> +		case PT_LOAD:
> +		case PT_NOTE:
> +			break;
> +		case PT_DYNAMIC: {
> +				Elf32_Dyn *dyn = (void *)(phdr->p_vaddr - new_base + (unsigned long)ehdr);
> +				unsigned j;
> +
> +				for(j = 0; dyn[j].d_tag != DT_NULL; ++j) {
> +					switch(dyn[j].d_tag) {
> +					case DT_HASH:
> +					case DT_STRTAB:
> +					case DT_SYMTAB:
> +					case 0x6ffffff0: /* DT_VERSYM */
> +					case 0x6ffffffc: /* DT_VERDEF */
> +						break;
> +					case DT_SONAME:
> +					case DT_STRSZ:
> +					case 0x6ffffffd: /* DT_VERDEFNUM */
> +						continue;
> +					case DT_SYMENT:
> +						szdynsym = dyn[j].d_un.d_val;
> +						continue;
> +					default:
> +						if (dyn[j].d_tag >= 0x60000000 /* OLD_DT_LOOS */
> +						    || dyn[j].d_tag < 31 /* DT_ENCODING */
> +						    || !(dyn[j].d_tag & 1)) {
> +							printk(KERN_WARNING "vDSO dynamic info %u has unsupported tag
> %08X\n", j, dyn[j].d_tag);
> +							WARN_ON(1);
> +							continue;
> +						}
> +						break;
> +					}
> +					dyn[j].d_un.d_ptr += new_base - old_base;
> +					switch(dyn[j].d_tag) {
> +					case DT_HASH:
> +						ndynsym = ((Elf32_Word *)dyn[j].d_un.d_ptr)[1];
> +						break;
> +					case DT_SYMTAB:
> +						dynsym = dyn[j].d_un.d_ptr;
> +						break;
> +					}
> +				}
> +			}
> +			break;
> +		case PT_GNU_EH_FRAME:
> +			/* XXX */
> +			break;
> +		default:
> +			printk(KERN_WARNING "vDSO program header %u has unsupported type %08X\n", i, phdr->p_type);
> +			WARN_ON(1);
> +			break;
> +		}
> +	}
> +	BUG_ON(ehdr->e_shentsize < sizeof(Elf32_Shdr));
> +	BUG_ON(ehdr->e_shnum >= SHN_LORESERVE);
> +	for (i = 1; i < ehdr->e_shnum; ++i) {
> +		Elf32_Shdr *shdr = (void *)((unsigned long)ehdr + ehdr->e_shoff + i * ehdr->e_shentsize);
> +
> +		if (!(shdr->sh_flags & SHF_ALLOC))
> +			continue;
> +		shdr->sh_addr += new_base - old_base;
> +		switch(shdr->sh_type) {
> +		case SHT_DYNAMIC:
> +		case SHT_HASH:
> +		case SHT_NOBITS:
> +		case SHT_NOTE:
> +		case SHT_PROGBITS:
> +		case SHT_STRTAB:
> +		case 0x6ffffffd: /* SHT_GNU_verdef */
> +		case 0x6fffffff: /* SHT_GNU_versym */
> +			break;
> +		case SHT_DYNSYM:
> +			BUG_ON(shdr->sh_entsize < sizeof(Elf32_Sym));
> +			if (!szdynsym)
> +				szdynsym = shdr->sh_entsize;
> +			else
> +				WARN_ON(szdynsym != shdr->sh_entsize);
> +			if (!ndynsym)
> +				ndynsym = shdr->sh_size / szdynsym;
> +			else
> +				WARN_ON(ndynsym != shdr->sh_size / szdynsym);
> +			if (!dynsym)
> +				dynsym = shdr->sh_addr;
> +			else
> +				WARN_ON(dynsym != shdr->sh_addr);
> +			break;
> +		default:
> +			printk(KERN_WARNING "vDSO section %u has unsupported type %08X\n", i, shdr->sh_type);
> +			WARN_ON(shdr->sh_size);
> +			break;
> +		}
> +	}
> +	dynsym += (unsigned long)ehdr - new_base;
> +	for(i = 1; i < ndynsym; ++i) {
> +		Elf32_Sym *sym = (void *)(dynsym + i * szdynsym);
> +
> +		if (sym->st_shndx == SHN_ABS)
> +			continue;
> +		sym->st_value += new_base - old_base;
> +	}
> +#endif
> +}
> +#else
> +#define relocate_vdso(ehdr, old, new, start, end) ((void)0)
> +#endif
> +
>  /*
>   * These symbols are defined by vsyscall.o to mark the bounds
>   * of the ELF DSO images included therein.
> @@ -104,12 +245,16 @@ int __init sysenter_setup(void)
>  		memcpy(syscall_page,
>  		       &vsyscall_int80_start,
>  		       &vsyscall_int80_end - &vsyscall_int80_start);
> +		relocate_vdso(syscall_page, VDSO_PRELINK, __fix_to_virt(FIX_VDSO),
> +		              vdso_rel_int80_start, vdso_rel_int80_end);
>  		return 0;
>  	}
>  
>  	memcpy(syscall_page,
>  	       &vsyscall_sysenter_start,
>  	       &vsyscall_sysenter_end - &vsyscall_sysenter_start);
> +	relocate_vdso(syscall_page, VDSO_PRELINK, __fix_to_virt(FIX_VDSO),
> +	              vdso_rel_sysenter_start, vdso_rel_sysenter_end);
>  
>  	return 0;
>  }
> Index: head-2007-02-27/arch/i386/kernel/vsyscall.S
> ===================================================================
> --- head-2007-02-27.orig/arch/i386/kernel/vsyscall.S	2007-03-05 10:00:18.000000000 +0100
> +++ head-2007-02-27/arch/i386/kernel/vsyscall.S	2007-02-27 16:27:37.000000000 +0100
> @@ -12,4 +12,20 @@ vsyscall_sysenter_start:
>  	.incbin "arch/i386/kernel/vsyscall-sysenter.so"
>  vsyscall_sysenter_end:
>  
> +#if defined(CONFIG_XEN) && defined(CONFIG_COMPAT_VDSO)
> +
> +	.align 4
> +
> +	.globl vdso_rel_int80_start, vdso_rel_int80_end
> +vdso_rel_int80_start:
> +	.include "arch/i386/kernel/vsyscall-int80.rel"
> +vdso_rel_int80_end:
> +
> +	.globl vdso_rel_sysenter_start, vdso_rel_sysenter_end
> +vdso_rel_sysenter_start:
> +	.include "arch/i386/kernel/vsyscall-sysenter.rel"
> +vdso_rel_sysenter_end:
> +
> +#endif
> +
>  __FINIT
> Index: head-2007-02-27/include/asm-i386/elf.h
> ===================================================================
> --- head-2007-02-27.orig/include/asm-i386/elf.h	2007-03-05 10:00:18.000000000 +0100
> +++ head-2007-02-27/include/asm-i386/elf.h	2007-02-27 16:27:37.000000000 +0100
> @@ -137,7 +137,11 @@ extern int dump_task_extended_fpu (struc
>  
>  #ifdef CONFIG_COMPAT_VDSO
>  # define VDSO_COMPAT_BASE	VDSO_HIGH_BASE
> -# define VDSO_PRELINK		VDSO_HIGH_BASE
> +# ifndef CONFIG_XEN
> +#  define VDSO_PRELINK		VDSO_HIGH_BASE
> +# else
> +#  define VDSO_PRELINK		(0UL - FIX_VDSO * PAGE_SIZE)
> +# endif
>  #else
>  # define VDSO_COMPAT_BASE	VDSO_BASE
>  # define VDSO_PRELINK		0
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
>   


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

* Re: [Xen-devel] [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
  2007-03-05 20:07   ` [Xen-devel] " Jeremy Fitzhardinge
@ 2007-03-06  7:52     ` Jan Beulich
  -1 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2007-03-06  7:52 UTC (permalink / raw)
  To: Jeremy Fitzhardinge
  Cc: Virtualization Mailing List, xen-devel, Linux Kernel Mailing List

>Ingo just raised this as an issue for paravirt_ops as well.  I don't
>quite follow what's going on there.   My understanding is that there are
>some old versions of glibc (which were unreleased CVS snapshots shipped
>by some vendors) which don't use the vdso's ELF header, but instead have
>their own canned one which built into the library itself.

Perhaps you meanwhile saw the similar question from Keir regarding this
(and my answer), but in short: plain glibc 2.3.2 (at least) supports AT_SYSINFO
but not AT_SYSINFO_HDR. In this scenario, moving the vDSO around is fine,
but glibc-internal (arguably broken) consistency checks prevent the vDSO from
being accepted when not using COMPAT_VDSO.

Jan

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

* Re: [Xen-devel] [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
@ 2007-03-06  7:52     ` Jan Beulich
  0 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2007-03-06  7:52 UTC (permalink / raw)
  To: Jeremy Fitzhardinge
  Cc: Virtualization Mailing List, xen-devel, Rusty Russell, Andi Kleen,
	Linux Kernel Mailing List

>Ingo just raised this as an issue for paravirt_ops as well.  I don't
>quite follow what's going on there.   My understanding is that there are
>some old versions of glibc (which were unreleased CVS snapshots shipped
>by some vendors) which don't use the vdso's ELF header, but instead have
>their own canned one which built into the library itself.

Perhaps you meanwhile saw the similar question from Keir regarding this
(and my answer), but in short: plain glibc 2.3.2 (at least) supports AT_SYSINFO
but not AT_SYSINFO_HDR. In this scenario, moving the vDSO around is fine,
but glibc-internal (arguably broken) consistency checks prevent the vDSO from
being accepted when not using COMPAT_VDSO.

Jan

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

* Re: [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
  2007-03-05 15:55     ` Keir Fraser
@ 2007-03-09 10:17       ` Jan Beulich
  2007-03-09 10:39         ` Keir Fraser
  2007-03-09 14:59         ` Jeremy Fitzhardinge
  0 siblings, 2 replies; 11+ messages in thread
From: Jan Beulich @ 2007-03-09 10:17 UTC (permalink / raw)
  To: Keir Fraser; +Cc: jeremy, xen-devel

>>> Keir Fraser <keir@xensource.com> 05.03.07 16:55 >>>
>On 5/3/07 14:48, "Jan Beulich" <jbeulich@novell.com> wrote:
>
>> It's gonna be really old libc-s that need an absolutely invariable address.
>> But
>> you certainly recall that in 2.6.16 (and probably earlier) we had a hack to
>> map
>> it in right below PAGE_OFFSET, which worked too for not really new but also
>> not really old libc-s. It is those intermediate libc (supporting AT_SYSINFO
>> but
>> not AT_SYSINFO_EHDR) versions that the option attempts to address for
>> Xen. I happen to have a SuSE 9.0 system still in active use that doesn't work
>> without this option, and I think glibc 2.3.2 shouldn't be considered entirely
>> obsolete, yet.
>
>The build-system approach looks simplest (certainly smaller than the C code)
>but is impenetrable to read. I think we'd take that approach if you add some
>comments to explain what's going on in the makefile runes.

I didn't follow up on this so far because kernel mainline seems to want the fix
for paravirt guests, too, but seems more favorable of the C approach. I haven't
seen anything new on this during the last two days anymore, so would want
to re-inquire whether you wouldn't then change your mind on which approach
to take.

Jan

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

* Re: [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
  2007-03-09 10:17       ` Jan Beulich
@ 2007-03-09 10:39         ` Keir Fraser
  2007-03-09 14:59         ` Jeremy Fitzhardinge
  1 sibling, 0 replies; 11+ messages in thread
From: Keir Fraser @ 2007-03-09 10:39 UTC (permalink / raw)
  To: Jan Beulich, Keir Fraser; +Cc: jeremy, xen-devel

On 9/3/07 10:17, "Jan Beulich" <jbeulich@novell.com> wrote:

>> The build-system approach looks simplest (certainly smaller than the C code)
>> but is impenetrable to read. I think we'd take that approach if you add some
>> comments to explain what's going on in the makefile runes.
> 
> I didn't follow up on this so far because kernel mainline seems to want the
> fix
> for paravirt guests, too, but seems more favorable of the C approach. I
> haven't
> seen anything new on this during the last two days anymore, so would want
> to re-inquire whether you wouldn't then change your mind on which approach
> to take.

I'm happy to follow mainline's preferences, since they've expressed them.

 -- Keir

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

* Re: [PATCH 2/10] linux 2.6.18: COMPAT_VDSO
  2007-03-09 10:17       ` Jan Beulich
  2007-03-09 10:39         ` Keir Fraser
@ 2007-03-09 14:59         ` Jeremy Fitzhardinge
  1 sibling, 0 replies; 11+ messages in thread
From: Jeremy Fitzhardinge @ 2007-03-09 14:59 UTC (permalink / raw)
  To: Jan Beulich; +Cc: xen-devel, Keir Fraser

Jan Beulich wrote:
> I didn't follow up on this so far because kernel mainline seems to want the fix
> for paravirt guests, too, but seems more favorable of the C approach. I haven't
> seen anything new on this during the last two days anymore, so would want
> to re-inquire whether you wouldn't then change your mind on which approach
> to take.
>   

Zach Amsden is working on polishing up a patch to be posted as part of
the pv_ops work. I hope it will be ready in the next day or so.

J

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

end of thread, other threads:[~2007-03-09 14:59 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-05 11:14 [PATCH 2/10] linux 2.6.18: COMPAT_VDSO Jan Beulich
2007-03-05 13:42 ` Keir Fraser
2007-03-05 14:48   ` Jan Beulich
2007-03-05 15:55     ` Keir Fraser
2007-03-09 10:17       ` Jan Beulich
2007-03-09 10:39         ` Keir Fraser
2007-03-09 14:59         ` Jeremy Fitzhardinge
2007-03-05 20:07 ` Jeremy Fitzhardinge
2007-03-05 20:07   ` [Xen-devel] " Jeremy Fitzhardinge
2007-03-06  7:52   ` Jan Beulich
2007-03-06  7:52     ` Jan Beulich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.