* [uml-devel] Implement vsyscall/sysenter, patch 1/4
@ 2004-10-08 19:12 bodo.stroesser
[not found] ` <200410130030.i9D0UF3P004368@ccure.user-mode-linux.org>
0 siblings, 1 reply; 2+ messages in thread
From: bodo.stroesser @ 2004-10-08 19:12 UTC (permalink / raw)
To: user-mode-linux-devel; +Cc: jdike, blaisorblade_spam
This is the first patch of a series of four.
These patches allow the use of sysenter-systemcalls in UML
if the host support sysenter.
Some facts have to be noted:
- the sysenter instruction does not save anything, not even the
return address. Thus the host-kernel builds a stackframe with an
fixed return address for the backjump to the vsyscall-page. All
kernels that support sysenter thus must have a vsyscall-page
- The hosts vsyscall-page is visible in all memory-contexts on the
host, even in those of the processes running on UML. This cannot
be changed.
So the best way to implement sysenter is to integrate the host's
vsyscall-page into UML, if available.
This patch creates a new source file containing an UML
initialization function. The function scans the Elf-auxiliary vector
that is prepared by the host for relevant information about:
- vsyscall elf-header
- vsyscall entry
- machine type (called "platform", e.g. "i586" or "i686")
- hardware capabilities
These informations are inserted into the Elf-auxiliary-vector that is
generated if an UML process calls "execXX()". If the information from
the auxiliray-vector is not complete, UML uses the previos default
values, with one exception: if the host has no vsyscall-page, UML now
does no longer insert AT_SYSINFO or AT_SYSINFO_EHDR elements. (I think,
that's better than writing dummies)
Since the host's vsyscall-page is always visible to UML processes, this
change is enough to let UML with an i686-compiled glibc use sysenter.
what's missing:
- is_syscall() in SKAS cannot access the code in the vsyscall-page via
copy_from_user(), thus singlesteppers still could break out. (Note:
that's not new, if someone jumps willingly to the sysenter-entry in
the vsyscall-page, he can do that without the patch, too).
- a debugger cannot access the code in the vsyscall-page via
ptrace( PEEKTEXT, ...)
Risks:
could there by any feature of the host's processor, that is indicated in
the hardware capabilities, but must not be used in UML?
Signed-off-by: Bodo Stroesser <bodo.stroesser@fujitsu-siemens.com>
---
--- linux-2.6.9-rc2-orig/arch/um/kernel/Makefile 2004-09-29 14:49:59.000000000 +0200
+++ linux-2.6.9-rc2/arch/um/kernel/Makefile 2004-10-05 16:45:39.835901012 +0200
@@ -12,7 +12,7 @@
sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \
time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \
- um_arch.o umid.o user_util.o
+ um_arch.o umid.o user_util.o elf_aux.o
obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
obj-$(CONFIG_GPROF) += gprof_syms.o
@@ -25,7 +25,8 @@
user-objs-$(CONFIG_TTY_LOG) += tty_log.o
USER_OBJS := $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
- main.o process.o tempfile.o time.o tty_log.o umid.o user_util.o frame.o
+ main.o process.o tempfile.o time.o tty_log.o umid.o user_util.o \
+ frame.o elf_aux.o
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
CFLAGS_frame.o := -fno-omit-frame-pointer
--- linux-2.6.9-rc2-orig/arch/um/kernel/main.c 2004-09-27 19:24:56.000000000 +0200
+++ linux-2.6.9-rc2/arch/um/kernel/main.c 2004-10-05 16:47:16.520923249 +0200
@@ -78,6 +78,8 @@
extern int uml_exitcode;
+extern void scan_elf_aux( char **envp);
+
int main(int argc, char **argv, char **envp)
{
char **new_argv;
@@ -144,6 +146,8 @@
set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
+ scan_elf_aux( envp);
+
do_uml_initcalls();
ret = linux_main(argc, argv);
--- linux-2.6.9-rc2-orig/arch/um/kernel/elf_aux.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.9-rc2/arch/um/kernel/elf_aux.c 2004-10-05 16:50:33.238414539 +0200
@@ -0,0 +1,66 @@
+/*
+ * arch/um/kernel/elf_aux.c
+ *
+ * Scan the Elf auxiliary vector provided by the host to extract
+ * information about vsyscall-page, etc.
+ *
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Author: Bodo Stroesser (bodo.stroesser@fujitsu-siemens.com)
+ */
+#include <elf.h>
+#include <stddef.h>
+#include "init.h"
+
+#if ELF_CLASS == ELFCLASS32
+typedef Elf32_auxv_t elf_auxv_t;
+#else
+typedef Elf64_auxv_t elf_auxv_t;
+#endif
+
+char * elf_aux_platform;
+long elf_aux_hwcap;
+
+long vsyscall_ehdr;
+long vsyscall_end;
+
+long __kernel_vsyscall;
+
+
+__init void scan_elf_aux( char **envp)
+{
+ long page_size = 0;
+ elf_auxv_t * auxv;
+
+ while ( *envp++ != NULL) ;
+
+ for ( auxv = (elf_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) {
+ switch ( auxv->a_type ) {
+ case AT_SYSINFO:
+ __kernel_vsyscall = auxv->a_un.a_val;
+ break;
+ case AT_SYSINFO_EHDR:
+ vsyscall_ehdr = auxv->a_un.a_val;
+ break;
+ case AT_HWCAP:
+ elf_aux_hwcap = auxv->a_un.a_val;
+ break;
+ case AT_PLATFORM:
+ elf_aux_platform = auxv->a_un.a_ptr;
+ break;
+ case AT_PAGESZ:
+ page_size = auxv->a_un.a_val;
+ break;
+ }
+ }
+ if ( ! __kernel_vsyscall || ! vsyscall_ehdr ||
+ ! elf_aux_hwcap || ! elf_aux_platform ||
+ ! page_size || (vsyscall_ehdr % page_size) ) {
+ __kernel_vsyscall = 0;
+ vsyscall_ehdr = 0;
+ elf_aux_hwcap = 0;
+ elf_aux_platform = "i586";
+ }
+ else {
+ vsyscall_end = vsyscall_ehdr + page_size;
+ }
+}
--- linux-2.6.9-rc2-orig/arch/um/kernel/um_arch.c 2004-09-27 19:24:56.000000000 +0200
+++ linux-2.6.9-rc2/arch/um/kernel/um_arch.c 2004-10-04 19:20:05.112436437 +0200
@@ -44,11 +44,6 @@
.ipi_pipe = { -1, -1 }
};
-/* Placeholder to make UML link until the vsyscall stuff is actually
- * implemented
- */
-void *__kernel_vsyscall;
-
unsigned long thread_saved_pc(struct task_struct *task)
{
return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
--- linux-2.6.9-rc2-orig/include/asm-um/elf.h 2004-09-13 07:32:55.000000000 +0200
+++ linux-2.6.9-rc2/include/asm-um/elf.h 2004-10-05 16:16:08.747583665 +0200
@@ -3,7 +3,8 @@
#include "asm/archparam.h"
-#define ELF_HWCAP (0)
+extern long elf_aux_hwcap;
+#define ELF_HWCAP (elf_aux_hwcap)
#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
--- linux-2.6.9-rc2-orig/include/asm-um/archparam-i386.h 2004-09-13 07:33:11.000000000 +0200
+++ linux-2.6.9-rc2/include/asm-um/archparam-i386.h 2004-10-05 16:15:44.488592605 +0200
@@ -10,7 +10,8 @@
#include "user.h"
-#define ELF_PLATFORM "i586"
+extern char * elf_aux_platform;
+#define ELF_PLATFORM (elf_aux_platform)
#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
@@ -56,15 +57,13 @@
pr_reg[16] = PT_REGS_SS(regs); \
} while(0);
-#if 0 /* Turn this back on when UML has VSYSCALL working */
-#define VSYSCALL_BASE (__fix_to_virt(FIX_VSYSCALL))
-#else
-#define VSYSCALL_BASE 0
-#endif
-#define VSYSCALL_EHDR ((const struct elfhdr *) VSYSCALL_BASE)
-#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
-extern void *__kernel_vsyscall;
+extern long vsyscall_ehdr;
+extern long vsyscall_end;
+extern long __kernel_vsyscall;
+
+#define VSYSCALL_BASE vsyscall_ehdr
+#define VSYSCALL_END vsyscall_end
/*
* Architecture-neutral AT_ values in 0-17, leave some room
@@ -75,8 +74,10 @@
#define ARCH_DLINFO \
do { \
- NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY); \
- NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE); \
+ if ( vsyscall_ehdr ) { \
+ NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \
+ } \
} while (0)
/*
-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
* [uml-devel] Re: Implement vsyscall/sysenter, patch 1/4
[not found] ` <200410130030.i9D0UF3P004368@ccure.user-mode-linux.org>
@ 2004-10-25 14:28 ` Bodo Stroesser
0 siblings, 0 replies; 2+ messages in thread
From: Bodo Stroesser @ 2004-10-25 14:28 UTC (permalink / raw)
To: Jeff Dike; +Cc: user-mode-linux-devel
Jeff Dike wrote:
>>+ (size <= (FIXADDR_USER_END - FIXADDR_USER_START)) && \
>>+ ((unsigned long) (addr) >= FIXADDR_USER_START) && \
>>+ ((unsigned long) (addr) + (size) <= FIXADDR_USER_END)))
>
>
> Don't the last two tests imply the truth of the first?
As you pointed out, the check is obsolete. But another check has
to be added, to avoid the possibility of wrong result because of
address wrapping.
The following fix should make it clean. Also, it defines some
address values to be unsigned long instead of long only.
And it exports the symbols vsyscall_ehdr and vsyscall_end by adding
EXPORT_SYMBOL() calls to user_syms.c
Bodo
---
diff -puNr a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess.h
--- a/arch/um/kernel/skas/include/uaccess.h 2004-10-25 11:25:25.000000000 +0200
+++ b/arch/um/kernel/skas/include/uaccess.h 2004-10-25 13:39:16.216138051 +0200
@@ -14,9 +14,9 @@
(((unsigned long) (addr) < TASK_SIZE) && \
((unsigned long) (addr) + (size) <= TASK_SIZE)) || \
((type == VERIFY_READ ) && \
- (size <= (FIXADDR_USER_END - FIXADDR_USER_START)) && \
((unsigned long) (addr) >= FIXADDR_USER_START) && \
- ((unsigned long) (addr) + (size) <= FIXADDR_USER_END)))
+ ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
+ ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
static inline int verify_area_skas(int type, const void * addr,
unsigned long size)
diff -puNr a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
--- a/arch/um/os-Linux/elf_aux.c 2004-10-25 11:25:25.000000000 +0200
+++ b/arch/um/os-Linux/elf_aux.c 2004-10-25 13:22:53.454545125 +0200
@@ -20,10 +20,10 @@ typedef Elf64_auxv_t elf_auxv_t;
char * elf_aux_platform;
long elf_aux_hwcap;
-long vsyscall_ehdr;
-long vsyscall_end;
+unsigned long vsyscall_ehdr;
+unsigned long vsyscall_end;
-long __kernel_vsyscall;
+unsigned long __kernel_vsyscall;
__init void scan_elf_aux( char **envp)
diff -puNr a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
--- a/arch/um/os-Linux/user_syms.c 2004-10-18 23:54:39.000000000 +0200
+++ b/arch/um/os-Linux/user_syms.c 2004-10-25 13:24:00.862405583 +0200
@@ -26,6 +26,9 @@ EXPORT_SYMBOL(printf);
EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(vsyscall_ehdr);
+EXPORT_SYMBOL(vsyscall_end);
+
/* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms.
* However, the modules will use the CRC defined *here*, no matter if it is
* good; so the versions of these symbols will always match
diff -puNr a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
--- a/include/asm-um/archparam-i386.h 2004-10-25 11:25:25.000000000 +0200
+++ b/include/asm-um/archparam-i386.h 2004-10-25 13:24:58.975802006 +0200
@@ -58,9 +58,9 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
} while(0);
-extern long vsyscall_ehdr;
-extern long vsyscall_end;
-extern long __kernel_vsyscall;
+extern unsigned long vsyscall_ehdr;
+extern unsigned long vsyscall_end;
+extern unsigned long __kernel_vsyscall;
#define VSYSCALL_BASE vsyscall_ehdr
#define VSYSCALL_END vsyscall_end
-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2004-10-25 14:20 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-08 19:12 [uml-devel] Implement vsyscall/sysenter, patch 1/4 bodo.stroesser
[not found] ` <200410130030.i9D0UF3P004368@ccure.user-mode-linux.org>
2004-10-25 14:28 ` [uml-devel] " Bodo Stroesser
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox