All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
@ 2009-07-11 15:14 Laurent Desnogues
  2009-10-17 15:42 ` [Qemu-devel] " Laurent Desnogues
  2009-10-17 19:57 ` [Qemu-devel] " Edgar E. Iglesias
  0 siblings, 2 replies; 20+ messages in thread
From: Laurent Desnogues @ 2009-07-11 15:14 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 495 bytes --]

Hello,

the attached patch implements two of the three x86_64 vsyscall's.
Also attached is a test that demonstrates the issue and hopefully
the fix.

Note there is a trick in there:  since vsyscall functions are in high
memory, page_l1_map will return NULL resulting in an abort when
calling tb_link_phys in tb_gen_code.  Also perhaps not very nice
is the way a ret is simulated in cpu_loop.

I didn't implement vgetcpu.


Laurent

Signed-off-by: Laurent Desnogues <laurent.desnogues@gmail.com>

[-- Attachment #2: vsyscall.patch --]
[-- Type: application/octet-stream, Size: 6006 bytes --]

diff --git a/exec.c b/exec.c
index d6e5d3c..8b8bea5 100644
--- a/exec.c
+++ b/exec.c
@@ -41,6 +41,9 @@
 #include "kvm.h"
 #if defined(CONFIG_USER_ONLY)
 #include <qemu.h>
+#ifdef TARGET_X86_64
+#include "vsyscall.h"
+#endif
 #endif
 
 //#define DEBUG_TB_INVALIDATE
@@ -908,6 +911,13 @@ TranslationBlock *tb_gen_code(CPUState *env,
     cpu_gen_code(env, tb, &code_gen_size);
     code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
 
+#if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
+    /* if we are doing vsyscall don't link the page as it lies in high memory
+       and tb_alloc_page will abort due to page_l1_map returning NULL */
+    if (unlikely(phys_pc >= TARGET_VSYSCALL_START
+                 && phys_pc < TARGET_VSYSCALL_END))
+        return tb;
+#endif
     /* check next page if needed */
     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
     phys_page2 = -1;
diff --git a/linux-user/main.c b/linux-user/main.c
index e331d65..761f1cc 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -30,6 +30,9 @@
 #include "qemu.h"
 #include "qemu-common.h"
 #include "cache-utils.h"
+#if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
+#include "vsyscall.h"
+#endif
 /* For tb_lock */
 #include "exec-all.h"
 
@@ -327,6 +330,9 @@ void cpu_loop(CPUX86State *env)
     int trapnr;
     abi_ulong pc;
     target_siginfo_t info;
+#ifdef TARGET_X86_64
+    int syscall_num;
+#endif
 
     for(;;) {
         trapnr = cpu_x86_exec(env);
@@ -356,6 +362,37 @@ void cpu_loop(CPUX86State *env)
             env->eip = env->exception_next_eip;
             break;
 #endif
+#ifdef TARGET_X86_64
+        case EXCP_VSYSCALL:
+            switch (env->eip) {
+            case TARGET_VSYSCALL_ADDR(__NR_vgettimeofday):
+                syscall_num = __NR_gettimeofday;
+                break;
+            case TARGET_VSYSCALL_ADDR(__NR_vtime):
+                syscall_num = __NR_time;
+                break;
+            case TARGET_VSYSCALL_ADDR(__NR_vgetcpu):
+                /* XXX: not yet implemented */
+                cpu_abort(env, "Unimplemented vsyscall vgetcpu");
+                break;
+            default:
+                cpu_abort(env,
+                          "Invalid vsyscall to address " TARGET_FMT_lx "\n",
+                          env->eip);
+            }
+            env->regs[R_EAX] = do_syscall(env,
+                                          syscall_num,
+                                          env->regs[R_EDI],
+                                          env->regs[R_ESI],
+                                          env->regs[R_EDX],
+                                          env->regs[10],
+                                          env->regs[8],
+                                          env->regs[9]);
+            /* simulate a ret */
+            env->eip = ldq(env->regs[R_ESP]);
+            env->regs[R_ESP] += 8;
+            break;
+#endif
         case EXCP0B_NOSEG:
         case EXCP0C_STACK:
             info.si_signo = SIGBUS;
diff --git a/linux-user/x86_64/vsyscall.h b/linux-user/x86_64/vsyscall.h
new file mode 100644
index 0000000..11dcc07
--- /dev/null
+++ b/linux-user/x86_64/vsyscall.h
@@ -0,0 +1,19 @@
+#ifndef VSYSCALL_H
+#define VSYSCALL_H
+
+/* This is based on asm/syscall.h in kernel 2.6.29. */
+
+enum vsyscall_num {
+    __NR_vgettimeofday,
+    __NR_vtime,
+    __NR_vgetcpu,
+};
+
+#define TARGET_VSYSCALL_START (-10UL << 20)
+#define TARGET_VSYSCALL_SIZE 1024
+#define TARGET_VSYSCALL_END (-2UL << 20)
+#define TARGET_VSYSCALL_MAPPED_PAGES 1
+#define TARGET_VSYSCALL_ADDR(vsyscall_nr) \
+    (TARGET_VSYSCALL_START+TARGET_VSYSCALL_SIZE*(vsyscall_nr))
+
+#endif /* !VSYSCALL_H */
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 6f7478a..a4281ae 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -437,6 +437,8 @@
 
 #define EXCP_SYSCALL    0x100 /* only happens in user only emulation
                                  for syscall instruction */
+#define EXCP_VSYSCALL   0x101 /* only happens in user only emulation
+                                 on x86_64 */
 
 enum {
     CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 68d57b1..3d39d7b 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -57,6 +57,7 @@ DEF_HELPER_1(sysexit, void, int)
 #ifdef TARGET_X86_64
 DEF_HELPER_1(syscall, void, int)
 DEF_HELPER_1(sysret, void, int)
+DEF_HELPER_0(vsyscall, void)
 #endif
 DEF_HELPER_1(hlt, void, int)
 DEF_HELPER_1(monitor, void, tl)
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index ed22c7a..6b558bf 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -1004,6 +1004,12 @@ void helper_syscall(int next_eip_addend)
     env->exception_next_eip = env->eip + next_eip_addend;
     cpu_loop_exit();
 }
+
+void helper_vsyscall(void)
+{
+    env->exception_index = EXCP_VSYSCALL;
+    cpu_loop_exit();
+}
 #else
 void helper_syscall(int next_eip_addend)
 {
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 4726009..d6daef4 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -33,6 +33,10 @@
 #define GEN_HELPER 1
 #include "helper.h"
 
+#if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
+#include "vsyscall.h"
+#endif
+
 #define PREFIX_REPZ   0x01
 #define PREFIX_REPNZ  0x02
 #define PREFIX_LOCK   0x04
@@ -7688,6 +7692,15 @@ static inline void gen_intermediate_code_internal(CPUState *env,
 
     gen_icount_start();
     for(;;) {
+#if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
+        /* Detect vsyscall's */
+        if (unlikely(pc_ptr >= TARGET_VSYSCALL_START
+                     && pc_ptr < TARGET_VSYSCALL_END)) {
+            gen_helper_vsyscall();
+            break;
+        }
+#endif
+
         if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
             TAILQ_FOREACH(bp, &env->breakpoints, entry) {
                 if (bp->pc == pc_ptr &&

[-- Attachment #3: check-vsyscall.c --]
[-- Type: text/x-csrc, Size: 1877 bytes --]

#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>

static void print_tod(const struct timeval *tv, const struct timezone *tz)
{
  if (tv)
    printf(" tv=%10ld.%06ld us",
	   tv->tv_sec, tv->tv_usec);
  else
    fputs(" (tv null)", stdout);
  if (tz)
    printf(" tz=%d/%d",
	   tz->tz_minuteswest, tz->tz_dsttime);
  else
    fputs(" (tz null)", stdout);
  fputc('\n', stdout);
}

static time_t t1, t2;
static struct timeval tv1, tv2;
static struct timezone tz1, tz2;

int main(void)
{
  int ret;

  fputs("Checking vtime with NULL param\n", stdout);
  t1 = time(NULL);
  printf("  %ld\n", t1);
  sleep(1);
  t2 = time(NULL);
  printf("  %ld (should be t1 + 1)\n", t2);

  fputs("Checking vtime with non NULL param\n", stdout);
  time(&t1);
  printf("  %ld\n", t1);
  sleep(1);
  time(&t2);
  printf("  %ld (should be t1 + 1)\n", t2);
  fputc('\n', stdout);


  fputs("Checking gettimeofday\n", stdout);
  ret = gettimeofday(&tv1, &tz1);
  printf("  ret=%d", ret);
  print_tod(&tv1, &tz1);
  sleep(1);
  ret = gettimeofday(&tv2, &tz2);
  printf("  ret=%d", ret);
  print_tod(&tv2, &tz2);

  fputs("Checking gettimeofday (tv NULL)\n", stdout);
  ret = gettimeofday(NULL, &tz1);
  printf("  ret=%d", ret);
  print_tod(NULL, &tz1);
  sleep(1);
  ret = gettimeofday(NULL, &tz2);
  printf("  ret=%d", ret);
  print_tod(NULL, &tz2);

  fputs("Checking gettimeofday (tz NULL)\n", stdout);
  ret = gettimeofday(&tv1, NULL);
  printf("  ret=%d", ret);
  print_tod(&tv1, NULL);
  sleep(1);
  ret = gettimeofday(&tv2, NULL);
  printf("  ret=%d", ret);
  print_tod(&tv2, NULL);

  fputs("Checking gettimeofday (tv and tz NULL)\n", stdout);
  ret = gettimeofday(NULL, NULL);
  printf("  ret=%d", ret);
  print_tod(NULL, NULL);
  sleep(1);
  ret = gettimeofday(NULL, NULL);
  printf("  ret=%d", ret);
  print_tod(NULL, NULL);

  return 0;
}

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

* [Qemu-devel] Re: [PATCH] User mode: Handle x86_64 vsyscall
  2009-07-11 15:14 [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall Laurent Desnogues
@ 2009-10-17 15:42 ` Laurent Desnogues
  2009-10-17 19:57 ` [Qemu-devel] " Edgar E. Iglesias
  1 sibling, 0 replies; 20+ messages in thread
From: Laurent Desnogues @ 2009-10-17 15:42 UTC (permalink / raw)
  To: qemu-devel

On Sat, Jul 11, 2009 at 5:14 PM, Laurent Desnogues
<laurent.desnogues@gmail.com> wrote:
> Hello,
>
> the attached patch implements two of the three x86_64 vsyscall's.
> Also attached is a test that demonstrates the issue and hopefully
> the fix.
>
> Note there is a trick in there:  since vsyscall functions are in high
> memory, page_l1_map will return NULL resulting in an abort when
> calling tb_link_phys in tb_gen_code.  Also perhaps not very nice
> is the way a ret is simulated in cpu_loop.
>
> I didn't implement vgetcpu.
>
>
> Laurent
>
> Signed-off-by: Laurent Desnogues <laurent.desnogues@gmail.com>

No one has any comment on this patch?


Laurent

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2009-07-11 15:14 [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall Laurent Desnogues
  2009-10-17 15:42 ` [Qemu-devel] " Laurent Desnogues
@ 2009-10-17 19:57 ` Edgar E. Iglesias
  2009-10-18  0:16   ` Laurent Desnogues
  2009-10-18  3:09   ` Jamie Lokier
  1 sibling, 2 replies; 20+ messages in thread
From: Edgar E. Iglesias @ 2009-10-17 19:57 UTC (permalink / raw)
  To: Laurent Desnogues; +Cc: qemu-devel

On Sat, Jul 11, 2009 at 05:14:47PM +0200, Laurent Desnogues wrote:
> Hello,
> 
> the attached patch implements two of the three x86_64 vsyscall's.
> Also attached is a test that demonstrates the issue and hopefully
> the fix.
> 
> Note there is a trick in there:  since vsyscall functions are in high
> memory, page_l1_map will return NULL resulting in an abort when
> calling tb_link_phys in tb_gen_code.  Also perhaps not very nice
> is the way a ret is simulated in cpu_loop.
> 
> I didn't implement vgetcpu.


Hello Laurent,

It feels a bit strange to have the CPU model know about linux vsyscalls.
Did you consider having the linux-user loader pass a qemu version of the
x86_64 vdso to the guest through the auxvector? That version could probably
implement the vsyscalls by translating them into syscalls with x86_64 code.
It probably doesn't even need to do that btw, just make sure to fill it
with syscall insns to raise exceptions and then have the linux-user/ code
treat syscalls with eip from vdso page differently. That way the CPU model
doesn't need to know about vdso and you can implement vsyscalls that may
need magic interactions with qemu.

Or does that not work for some reason? Performance?
Are there maybe old binaries that don't look in the auxvector and just assume
a fixed address for the vdso?


@@ -327,6 +330,9 @@ void cpu_loop(CPUX86State *env)
     int trapnr;
     abi_ulong pc;
     target_siginfo_t info;
+#ifdef TARGET_X86_64
+    int syscall_num;
+#endif

     for(;;) {
         trapnr = cpu_x86_exec(env);
@@ -356,6 +362,37 @@ void cpu_loop(CPUX86State *env)
             env->eip = env->exception_next_eip;
             break;
 #endif
+#ifdef TARGET_X86_64
+        case EXCP_VSYSCALL:

if you open up a new block here, the declaration of syscall_num can
be moved here (eliminating one #ifdef).

You could maybe also do the syscall mapping in the vsyscall.h file.
Something like this:

      env->regs[R_EAX] = do_syscall(env,
                                    x86_64_vdsoaddr2syscall(env->eip),
                                    env->regs[R_EDI],
                                    env->regs[R_ESI],

Cheers




> 
> 
> Laurent
> 
> Signed-off-by: Laurent Desnogues <laurent.desnogues@gmail.com>


> #include <stdio.h>
> #include <stdint.h>
> #include <time.h>
> #include <unistd.h>
> #include <sys/time.h>
> 
> static void print_tod(const struct timeval *tv, const struct timezone *tz)
> {
>   if (tv)
>     printf(" tv=%10ld.%06ld us",
> 	   tv->tv_sec, tv->tv_usec);
>   else
>     fputs(" (tv null)", stdout);
>   if (tz)
>     printf(" tz=%d/%d",
> 	   tz->tz_minuteswest, tz->tz_dsttime);
>   else
>     fputs(" (tz null)", stdout);
>   fputc('\n', stdout);
> }
> 
> static time_t t1, t2;
> static struct timeval tv1, tv2;
> static struct timezone tz1, tz2;
> 
> int main(void)
> {
>   int ret;
> 
>   fputs("Checking vtime with NULL param\n", stdout);
>   t1 = time(NULL);
>   printf("  %ld\n", t1);
>   sleep(1);
>   t2 = time(NULL);
>   printf("  %ld (should be t1 + 1)\n", t2);
> 
>   fputs("Checking vtime with non NULL param\n", stdout);
>   time(&t1);
>   printf("  %ld\n", t1);
>   sleep(1);
>   time(&t2);
>   printf("  %ld (should be t1 + 1)\n", t2);
>   fputc('\n', stdout);
> 
> 
>   fputs("Checking gettimeofday\n", stdout);
>   ret = gettimeofday(&tv1, &tz1);
>   printf("  ret=%d", ret);
>   print_tod(&tv1, &tz1);
>   sleep(1);
>   ret = gettimeofday(&tv2, &tz2);
>   printf("  ret=%d", ret);
>   print_tod(&tv2, &tz2);
> 
>   fputs("Checking gettimeofday (tv NULL)\n", stdout);
>   ret = gettimeofday(NULL, &tz1);
>   printf("  ret=%d", ret);
>   print_tod(NULL, &tz1);
>   sleep(1);
>   ret = gettimeofday(NULL, &tz2);
>   printf("  ret=%d", ret);
>   print_tod(NULL, &tz2);
> 
>   fputs("Checking gettimeofday (tz NULL)\n", stdout);
>   ret = gettimeofday(&tv1, NULL);
>   printf("  ret=%d", ret);
>   print_tod(&tv1, NULL);
>   sleep(1);
>   ret = gettimeofday(&tv2, NULL);
>   printf("  ret=%d", ret);
>   print_tod(&tv2, NULL);
> 
>   fputs("Checking gettimeofday (tv and tz NULL)\n", stdout);
>   ret = gettimeofday(NULL, NULL);
>   printf("  ret=%d", ret);
>   print_tod(NULL, NULL);
>   sleep(1);
>   ret = gettimeofday(NULL, NULL);
>   printf("  ret=%d", ret);
>   print_tod(NULL, NULL);
> 
>   return 0;
> }

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2009-10-17 19:57 ` [Qemu-devel] " Edgar E. Iglesias
@ 2009-10-18  0:16   ` Laurent Desnogues
  2009-10-18  2:47     ` Jamie Lokier
  2009-10-18  3:09   ` Jamie Lokier
  1 sibling, 1 reply; 20+ messages in thread
From: Laurent Desnogues @ 2009-10-18  0:16 UTC (permalink / raw)
  To: Edgar E. Iglesias; +Cc: qemu-devel

Hi Edgar,

On Sat, Oct 17, 2009 at 9:57 PM, Edgar E. Iglesias
<edgar.iglesias@gmail.com> wrote:
>
> It feels a bit strange to have the CPU model know about linux vsyscalls.
> Did you consider having the linux-user loader pass a qemu version of the
> x86_64 vdso to the guest through the auxvector? That version could probably
> implement the vsyscalls by translating them into syscalls with x86_64 code.
> It probably doesn't even need to do that btw, just make sure to fill it
> with syscall insns to raise exceptions and then have the linux-user/ code
> treat syscalls with eip from vdso page differently. That way the CPU model
> doesn't need to know about vdso and you can implement vsyscalls that may
> need magic interactions with qemu.
>
> Or does that not work for some reason? Performance?
> Are there maybe old binaries that don't look in the auxvector and just assume
> a fixed address for the vdso?

A recent compiler (gcc 4.4.0) produces this code for a statically
compiled program:

00000000005779e0 <time>:
  5779e0:	48 83 ec 08          	sub    $0x8,%rsp
  5779e4:	48 c7 c0 00 04 60 ff 	mov    $0xffffffffff600400,%rax
  5779eb:	ff d0                	callq  *%rax
  5779ed:	48 83 c4 08          	add    $0x8,%rsp
  5779f1:	c3                   	retq

I never heard of "auxvector" before.  Is this related to what is
discussed here?

http://manugarg.googlepages.com/aboutelfauxiliaryvectors

I dumped 4KB mapped at AT_SYSINFO_EHDR and processed
it through readelf. Nothing matches the address above:

     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: ffffffffff70030c     0 SECTION LOCAL  DEFAULT    7
     2: ffffffffff700800    74 FUNC    WEAK   DEFAULT   12
clock_gettime@@LINUX_2.6
     3: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS LINUX_2.6
     4: ffffffffff7006c0   137 FUNC    GLOBAL DEFAULT   12
__vdso_gettimeofday@@LINUX_2.6
     5: ffffffffff700850    61 FUNC    GLOBAL DEFAULT   12
__vdso_getcpu@@LINUX_2.6
     6: ffffffffff7006c0   137 FUNC    WEAK   DEFAULT   12
gettimeofday@@LINUX_2.6
     7: ffffffffff700850    61 FUNC    WEAK   DEFAULT   12 getcpu@@LINUX_2.6
     8: ffffffffff700800    74 FUNC    GLOBAL DEFAULT   12
__vdso_clock_gettime@@LINUX_2.6

I probably missed your point :-)

Thanks,

Laurent

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2009-10-18  0:16   ` Laurent Desnogues
@ 2009-10-18  2:47     ` Jamie Lokier
  2009-10-18 11:23       ` Laurent Desnogues
  0 siblings, 1 reply; 20+ messages in thread
From: Jamie Lokier @ 2009-10-18  2:47 UTC (permalink / raw)
  To: Laurent Desnogues; +Cc: Edgar E. Iglesias, qemu-devel

Laurent Desnogues wrote:
> A recent compiler (gcc 4.4.0) produces this code for a statically
> compiled program:
> 
> 00000000005779e0 <time>:
>   5779e0:	48 83 ec 08          	sub    $0x8,%rsp
>   5779e4:	48 c7 c0 00 04 60 ff 	mov    $0xffffffffff600400,%rax
>   5779eb:	ff d0                	callq  *%rax
>   5779ed:	48 83 c4 08          	add    $0x8,%rsp
>   5779f1:	c3                   	retq

Yes.  It's a fixed address.  See the kernel at
linux/arch/x86/kernel/vsyscall_64.c.  There are only 3 vsyscall
functions defined: vgettimeofday, vtime and vgetcpu.

Even though it's a statically linked program, I'm not sure if the
above code will work on really old kernels.

The vsyscall page is different from the vdso, which has variable
address, and the address is supplied to Glibc.  vdso provides nearly
the same functions in a different way.

-- Jamie

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2009-10-17 19:57 ` [Qemu-devel] " Edgar E. Iglesias
  2009-10-18  0:16   ` Laurent Desnogues
@ 2009-10-18  3:09   ` Jamie Lokier
  2009-10-18  7:17     ` Edgar E. Iglesias
  2009-10-18 11:29     ` Laurent Desnogues
  1 sibling, 2 replies; 20+ messages in thread
From: Jamie Lokier @ 2009-10-18  3:09 UTC (permalink / raw)
  To: Edgar E. Iglesias; +Cc: Laurent Desnogues, qemu-devel

Edgar E. Iglesias wrote:
> Did you consider having the linux-user loader pass a qemu version of the
> x86_64 vdso to the guest through the auxvector? That version could probably
> implement the vsyscalls by translating them into syscalls with x86_64 code.

That seems like a good idea.

Note that on x86_64, there is _both_ a vsyscall page at a fixed
address, and a vdso page at a randomised address with different
contents.  Binary programs can call either or both.

On x86_32, there is only a vdso page.  It can be a variable or fixed
address.  To run old binaries (but not so old they don't know about
vsyscall), it needs to be mapped at a fixed address.  Modern kernels
have it mapped at a randomised address, and therefore won't work with
those binaries.

> It probably doesn't even need to do that btw, just make sure to fill it
> with syscall insns to raise exceptions and then have the linux-user/ code
> treat syscalls with eip from vdso page differently. That way the CPU model
> doesn't need to know about vdso and you can implement vsyscalls that may
> need magic interactions with qemu.
> 
> Or does that not work for some reason?

Please don't do that.  Some code traces instructions through the
vsyscall/vdso page, and will be surprised if a syscall instruction
does not do what's expected based on the registers at that point.

Also I don't know if anyone's done this, but I have played with the
idea of an optimising x86->x86 JIT translator (similar to valgrind or
qemu's TCG) which would include the vdso instruction sequence in it's
traces, just because it didn't treat that any differently from other
userspace code.  Making the syscall instruction behave differently due
to EIP would break that sort of thing.

There's no performance penalty in setting a few registers prior to
using the syscall instruction normally, so please do that.

> Performance?

syscall insns (sysenter/syscall/int $0x80/vsyscall/vdso) could be
translated to helpers for the exact type of system call if the system
call number is known, saving a little overhead.

> Are there maybe old binaries that don't look in the auxvector and
> just assume a fixed address for the vdso?

On x86_64, the vsyscall page has fixed address (see
linux/arch/x86/kernel/vsyscall_64.c), but the vdso usually has
variable address.

On x86_32, the vdso has randomised address unless configurd to be a
fixed address.  On older kernels it was a fixed address and some
binary programs assume they can call that.

-- Jamie

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2009-10-18  3:09   ` Jamie Lokier
@ 2009-10-18  7:17     ` Edgar E. Iglesias
  2009-10-18 11:29     ` Laurent Desnogues
  1 sibling, 0 replies; 20+ messages in thread
From: Edgar E. Iglesias @ 2009-10-18  7:17 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Laurent Desnogues, qemu-devel

On Sun, Oct 18, 2009 at 04:09:44AM +0100, Jamie Lokier wrote:
> Edgar E. Iglesias wrote:
> > Did you consider having the linux-user loader pass a qemu version of the
> > x86_64 vdso to the guest through the auxvector? That version could probably
> > implement the vsyscalls by translating them into syscalls with x86_64 code.
> 
> That seems like a good idea.
> 
> Note that on x86_64, there is _both_ a vsyscall page at a fixed
> address, and a vdso page at a randomised address with different
> contents.  Binary programs can call either or both.
> 
> On x86_32, there is only a vdso page.  It can be a variable or fixed
> address.  To run old binaries (but not so old they don't know about
> vsyscall), it needs to be mapped at a fixed address.  Modern kernels
> have it mapped at a randomised address, and therefore won't work with
> those binaries.

Thanks for clarifiying.

If I understand correctly, my suggestion won't work for vsyscalls because
the specific fixed address might be unavailable or already used by the
host...

Cheers

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2009-10-18  2:47     ` Jamie Lokier
@ 2009-10-18 11:23       ` Laurent Desnogues
  0 siblings, 0 replies; 20+ messages in thread
From: Laurent Desnogues @ 2009-10-18 11:23 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Edgar E. Iglesias, qemu-devel

On Sun, Oct 18, 2009 at 4:47 AM, Jamie Lokier <jamie@shareable.org> wrote:
> Laurent Desnogues wrote:
>> A recent compiler (gcc 4.4.0) produces this code for a statically
>> compiled program:
>>
>> 00000000005779e0 <time>:
>>   5779e0:     48 83 ec 08             sub    $0x8,%rsp
>>   5779e4:     48 c7 c0 00 04 60 ff    mov    $0xffffffffff600400,%rax
>>   5779eb:     ff d0                   callq  *%rax
>>   5779ed:     48 83 c4 08             add    $0x8,%rsp
>>   5779f1:     c3                      retq
>
> Yes.  It's a fixed address.  See the kernel at
> linux/arch/x86/kernel/vsyscall_64.c.  There are only 3 vsyscall
> functions defined: vgettimeofday, vtime and vgetcpu.

My proposed patch already implements vgettimeofday and
vtime. vgetcpu is TBD.

> Even though it's a statically linked program, I'm not sure if the
> above code will work on really old kernels.

All I can say is that it's what my toolchain generates.

Interestingly, dynamically shared programs don't run with
QEMU on my machine.  It looks like the PC is completely
wrong.

> The vsyscall page is different from the vdso, which has variable
> address, and the address is supplied to Glibc.  vdso provides nearly
> the same functions in a different way.

I don't understand how vdso and vsyscall interact (or don't
interact):  as I showed above, a statically linked program will
use vsyscall.  For dynamically linked program, I can't say,
given what I said above;  there might be a loader issue here.


Laurent

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2009-10-18  3:09   ` Jamie Lokier
  2009-10-18  7:17     ` Edgar E. Iglesias
@ 2009-10-18 11:29     ` Laurent Desnogues
  2010-02-04 22:15       ` Stefan Weil
  2010-02-05 22:57       ` Stefan Weil
  1 sibling, 2 replies; 20+ messages in thread
From: Laurent Desnogues @ 2009-10-18 11:29 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Edgar E. Iglesias, qemu-devel

On Sun, Oct 18, 2009 at 5:09 AM, Jamie Lokier <jamie@shareable.org> wrote:
[...]
>
> Please don't do that.  Some code traces instructions through the
> vsyscall/vdso page, and will be surprised if a syscall instruction
> does not do what's expected based on the registers at that point.
>
> Also I don't know if anyone's done this, but I have played with the
> idea of an optimising x86->x86 JIT translator (similar to valgrind or
> qemu's TCG) which would include the vdso instruction sequence in it's
> traces, just because it didn't treat that any differently from other
> userspace code.  Making the syscall instruction behave differently due
> to EIP would break that sort of thing.
>
> There's no performance penalty in setting a few registers prior to
> using the syscall instruction normally, so please do that.

My proposed patch intercepts vsyscall as soon as the PC is
in the [VSYSCALL_START, VSYSCALL_END[ range, so all
instructions in that range won't be translated.  Doing it
differently will cause problems due to the virtual address.

> On x86_64, the vsyscall page has fixed address (see
> linux/arch/x86/kernel/vsyscall_64.c), but the vdso usually has
> variable address.
>
> On x86_32, the vdso has randomised address unless configurd to be a
> fixed address.  On older kernels it was a fixed address and some
> binary programs assume they can call that.

So QEMU can't do things properly and some binaries will
fail, right?


Laurent

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2009-10-18 11:29     ` Laurent Desnogues
@ 2010-02-04 22:15       ` Stefan Weil
  2010-02-05 22:57       ` Stefan Weil
  1 sibling, 0 replies; 20+ messages in thread
From: Stefan Weil @ 2010-02-04 22:15 UTC (permalink / raw)
  To: Laurent Desnogues; +Cc: Edgar E. Iglesias, qemu-devel

Laurent Desnogues schrieb:
> On Sun, Oct 18, 2009 at 5:09 AM, Jamie Lokier <jamie@shareable.org> wrote:
> [...]
>> Please don't do that.  Some code traces instructions through the
>> vsyscall/vdso page, and will be surprised if a syscall instruction
>> does not do what's expected based on the registers at that point.
>>
>> Also I don't know if anyone's done this, but I have played with the
>> idea of an optimising x86->x86 JIT translator (similar to valgrind or
>> qemu's TCG) which would include the vdso instruction sequence in it's
>> traces, just because it didn't treat that any differently from other
>> userspace code.  Making the syscall instruction behave differently due
>> to EIP would break that sort of thing.
>>
>> There's no performance penalty in setting a few registers prior to
>> using the syscall instruction normally, so please do that.
>
> My proposed patch intercepts vsyscall as soon as the PC is
> in the [VSYSCALL_START, VSYSCALL_END[ range, so all
> instructions in that range won't be translated. Doing it
> differently will cause problems due to the virtual address.
>
>> On x86_64, the vsyscall page has fixed address (see
>> linux/arch/x86/kernel/vsyscall_64.c), but the vdso usually has
>> variable address.
>>
>> On x86_32, the vdso has randomised address unless configurd to be a
>> fixed address.  On older kernels it was a fixed address and some
>> binary programs assume they can call that.
>
> So QEMU can't do things properly and some binaries will
> fail, right?
>
>
> Laurent

I can confirm that some binaries fail:

x86_64-linux-user/qemu-x86_64 ./bntest

with bntest from openssl creates a core dump.

Will Laurent's patch be applied, or is there a
better way to fix the problem?

Stefan

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2009-10-18 11:29     ` Laurent Desnogues
  2010-02-04 22:15       ` Stefan Weil
@ 2010-02-05 22:57       ` Stefan Weil
  2010-02-06  1:37         ` Laurent Desnogues
  2010-02-06 20:12         ` Richard Henderson
  1 sibling, 2 replies; 20+ messages in thread
From: Stefan Weil @ 2010-02-05 22:57 UTC (permalink / raw)
  To: Laurent Desnogues; +Cc: Edgar E. Iglesias, qemu-devel

Laurent Desnogues schrieb:
> On Sun, Oct 18, 2009 at 5:09 AM, Jamie Lokier <jamie@shareable.org> wrote:
> [...]
>> Please don't do that.  Some code traces instructions through the
>> vsyscall/vdso page, and will be surprised if a syscall instruction
>> does not do what's expected based on the registers at that point.
>>
>> Also I don't know if anyone's done this, but I have played with the
>> idea of an optimising x86->x86 JIT translator (similar to valgrind or
>> qemu's TCG) which would include the vdso instruction sequence in it's
>> traces, just because it didn't treat that any differently from other
>> userspace code.  Making the syscall instruction behave differently due
>> to EIP would break that sort of thing.
>>
>> There's no performance penalty in setting a few registers prior to
>> using the syscall instruction normally, so please do that.
>
> My proposed patch intercepts vsyscall as soon as the PC is
> in the [VSYSCALL_START, VSYSCALL_END[ range, so all
> instructions in that range won't be translated. Doing it
> differently will cause problems due to the virtual address.
>
>> On x86_64, the vsyscall page has fixed address (see
>> linux/arch/x86/kernel/vsyscall_64.c), but the vdso usually has
>> variable address.
>>
>> On x86_32, the vdso has randomised address unless configurd to be a
>> fixed address.  On older kernels it was a fixed address and some
>> binary programs assume they can call that.
>
> So QEMU can't do things properly and some binaries will
> fail, right?
>
>
> Laurent


I'm still struggling with bntest and other x86_64-linux-user software
calling any of the vsyscall functions.

Laurent, your vsyscall patch only works on x86_64 hosts.

A lot of software calls time() which uses vsyscall on x86_64 which
does not work with x86_64-linux-user mode.

So the status of x86_64-linux-user is not more than experimental :-(

I tried to modify x86_64-linux-user to set up a vsyscall page in high
memory,
but this seems to be difficult (at least with 32 bit host).

Any hints how this should be done are welcome.

Stefan

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2010-02-05 22:57       ` Stefan Weil
@ 2010-02-06  1:37         ` Laurent Desnogues
  2010-02-06  7:49           ` Stefan Weil
  2010-02-06 20:12         ` Richard Henderson
  1 sibling, 1 reply; 20+ messages in thread
From: Laurent Desnogues @ 2010-02-06  1:37 UTC (permalink / raw)
  To: Stefan Weil; +Cc: Edgar E. Iglesias, qemu-devel

On Fri, Feb 5, 2010 at 11:57 PM, Stefan Weil <weil@mail.berlios.de> wrote:
> Laurent Desnogues schrieb:
[...]
>
> I'm still struggling with bntest and other x86_64-linux-user software
> calling any of the vsyscall functions.
>
> Laurent, your vsyscall patch only works on x86_64 hosts.
>
> A lot of software calls time() which uses vsyscall on x86_64 which
> does not work with x86_64-linux-user mode.

I'm not sure I understand what you mean.  Did you try
on some other host and it failed?  Was your host
32-bit?  If so, I'm afraid user-mode will fail for more
reasons than vsyscall.

> So the status of x86_64-linux-user is not more than experimental :-(
>
> I tried to modify x86_64-linux-user to set up a vsyscall page in high
> memory,
> but this seems to be difficult (at least with 32 bit host).
>
> Any hints how this should be done are welcome.

My patch explicitly prevents the linking of the vsyscall
page.

Could you provide more info about your host?


Laurent

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2010-02-06  1:37         ` Laurent Desnogues
@ 2010-02-06  7:49           ` Stefan Weil
  2010-02-06 23:50             ` Laurent Desnogues
  0 siblings, 1 reply; 20+ messages in thread
From: Stefan Weil @ 2010-02-06  7:49 UTC (permalink / raw)
  To: Laurent Desnogues; +Cc: qemu-devel

Laurent Desnogues schrieb:
> On Fri, Feb 5, 2010 at 11:57 PM, Stefan Weil <weil@mail.berlios.de> wrote:
>> Laurent Desnogues schrieb:
> [...]
>> I'm still struggling with bntest and other x86_64-linux-user software
>> calling any of the vsyscall functions.
>>
>> Laurent, your vsyscall patch only works on x86_64 hosts.
>>
>> A lot of software calls time() which uses vsyscall on x86_64 which
>> does not work with x86_64-linux-user mode.
>
> I'm not sure I understand what you mean. Did you try
> on some other host and it failed? Was your host
> 32-bit? If so, I'm afraid user-mode will fail for more
> reasons than vsyscall.
>
>> So the status of x86_64-linux-user is not more than experimental :-(
>>
>> I tried to modify x86_64-linux-user to set up a vsyscall page in high
>> memory,
>> but this seems to be difficult (at least with 32 bit host).
>>
>> Any hints how this should be done are welcome.
>
> My patch explicitly prevents the linking of the vsyscall
> page.
>
> Could you provide more info about your host?
>
>
> Laurent
>


I tested two different hosts with x86_64-linux-user:

* 32 bit Intel (i386) - does not work with your patch
* 64 bit AMD (x86_64)  - works with your patch

Your patch improves the emulation for 64 bit hosts.
Nevertheless, it has some open points:

* target-i386 code should not have to know about
  linux vsyscall

* there is no vsyscall page in memory,
  but very special programs might expect to see one
  (it is even worse: the target sees the memory page
  of the host)

* it is not possible to step into vsyscall code
  using a debugger

My favorite solution would be a vsyscall page mapped
to the correct fixed address and filled with QEMU
generated specific code, for example code which calls the
normal syscalls to do the work. This would only
need modifications for linux-user code.

Regards
Stefan

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2010-02-05 22:57       ` Stefan Weil
  2010-02-06  1:37         ` Laurent Desnogues
@ 2010-02-06 20:12         ` Richard Henderson
  1 sibling, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2010-02-06 20:12 UTC (permalink / raw)
  To: Stefan Weil; +Cc: Laurent Desnogues, Edgar E. Iglesias, qemu-devel

On 02/05/2010 02:57 PM, Stefan Weil wrote:
> I tried to modify x86_64-linux-user to set up a vsyscall page in high
> memory, but this seems to be difficult (at least with 32 bit host).

A 64-bit userland guest can only use the low 32-bits of its address 
space with a 32-bit host at the moment.  If you can set up the vsyscall 
page in low memory, then you may be able to get this to work.

Otherwise you'll have to wait for someone to re-write the userland 
memory management in qemu.


r~

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2010-02-06  7:49           ` Stefan Weil
@ 2010-02-06 23:50             ` Laurent Desnogues
  2010-02-07  0:22               ` Jamie Lokier
  2010-02-07 23:18               ` Richard Henderson
  0 siblings, 2 replies; 20+ messages in thread
From: Laurent Desnogues @ 2010-02-06 23:50 UTC (permalink / raw)
  To: Stefan Weil; +Cc: qemu-devel

On Sat, Feb 6, 2010 at 8:49 AM, Stefan Weil <weil@mail.berlios.de> wrote:
[...]
> I tested two different hosts with x86_64-linux-user:
>
> * 32 bit Intel (i386) - does not work with your patch

For me x86_64 on i386 has always failed without
even calling vsyscall :-)

> * 64 bit AMD (x86_64)  - works with your patch
>
> Your patch improves the emulation for 64 bit hosts.
> Nevertheless, it has some open points:
>
> * target-i386 code should not have to know about
>  linux vsyscall

Given that we have to workaround 64-bit virtual
address limitations (cf. Richard mail and previous
discussions on the list), doing otherwise looks
difficult.

> * there is no vsyscall page in memory,
>  but very special programs might expect to see one
>  (it is even worse: the target sees the memory page
>  of the host)
>
> * it is not possible to step into vsyscall code
>  using a debugger

How would you achieve that?  Your guest OS
doesn't necessarily have the code mapped.  I
think this has to be considered as other syscalls,
though slightly different.

> My favorite solution would be a vsyscall page mapped
> to the correct fixed address and filled with QEMU
> generated specific code, for example code which calls the
> normal syscalls to do the work. This would only
> need modifications for linux-user code.

You mean you'd explicitly put somewhere x86_64
code that simulates the behaviour of vsyscall?


Laurent

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2010-02-06 23:50             ` Laurent Desnogues
@ 2010-02-07  0:22               ` Jamie Lokier
  2010-02-07  3:11                 ` malc
  2010-02-07 10:06                 ` Laurent Desnogues
  2010-02-07 23:18               ` Richard Henderson
  1 sibling, 2 replies; 20+ messages in thread
From: Jamie Lokier @ 2010-02-07  0:22 UTC (permalink / raw)
  To: Laurent Desnogues; +Cc: qemu-devel

Laurent Desnogues wrote:
> On Sat, Feb 6, 2010 at 8:49 AM, Stefan Weil <weil@mail.berlios.de> wrote:
> [...]
> > I tested two different hosts with x86_64-linux-user:
> >
> > * 32 bit Intel (i386) - does not work with your patch
> 
> For me x86_64 on i386 has always failed without
> even calling vsyscall :-)
> 
> > * 64 bit AMD (x86_64)  - works with your patch

It's a bit worrying that it depends on the host architecture at all.

How well does x86_64-linux-user emulation work on non-x86 hosts?

Does the vsyscall emulation depend only on the hosts's address sixe,
or does it have to be an x86 host to work?

> > * it is not possible to step into vsyscall code
> >  using a debugger
> 
> How would you achieve that?  Your guest OS
> doesn't necessarily have the code mapped.  I
> think this has to be considered as other syscalls,
> though slightly different.

There is no guest OS when doing -user emulation.
Only qemu.

> > My favorite solution would be a vsyscall page mapped
> > to the correct fixed address and filled with QEMU
> > generated specific code, for example code which calls the
> > normal syscalls to do the work. This would only
> > need modifications for linux-user code.
> 
> You mean you'd explicitly put somewhere x86_64
> code that simulates the behaviour of vsyscall?

That seems like a good idea to me.

-- Jamie

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2010-02-07  0:22               ` Jamie Lokier
@ 2010-02-07  3:11                 ` malc
  2010-02-07 10:06                 ` Laurent Desnogues
  1 sibling, 0 replies; 20+ messages in thread
From: malc @ 2010-02-07  3:11 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Laurent Desnogues, qemu-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 962 bytes --]

On Sun, 7 Feb 2010, Jamie Lokier wrote:

> Laurent Desnogues wrote:
> > On Sat, Feb 6, 2010 at 8:49 AM, Stefan Weil <weil@mail.berlios.de> wrote:
> > [...]
> > > I tested two different hosts with x86_64-linux-user:
> > >
> > > * 32 bit Intel (i386) - does not work with your patch
> > 
> > For me x86_64 on i386 has always failed without
> > even calling vsyscall :-)
> > 
> > > * 64 bit AMD (x86_64)  - works with your patch
> 
> It's a bit worrying that it depends on the host architecture at all.
> 
> How well does x86_64-linux-user emulation work on non-x86 hosts?

x64user$ uname -a                                                               
Linux linmac 2.6.32.3 #4 Sun Jan 31 09:52:58 MSK 2010 ppc 7447A, altivec 
supported PowerMac10,2 GNU/Linux
x64user$ x86_64-linux-user/qemu-x86_64 -L ~/x/lut/gnemul/qemu-x86_64/ 
~/x/lut/x86_64/uname -a
Linux linmac 2.6.32.3 #4 Sun Jan 31 09:52:58 MSK 2010 x86-64 unknown

[..snip..]

-- 
mailto:av1474@comtv.ru

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2010-02-07  0:22               ` Jamie Lokier
  2010-02-07  3:11                 ` malc
@ 2010-02-07 10:06                 ` Laurent Desnogues
  1 sibling, 0 replies; 20+ messages in thread
From: Laurent Desnogues @ 2010-02-07 10:06 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: qemu-devel

On Sun, Feb 7, 2010 at 1:22 AM, Jamie Lokier <jamie@shareable.org> wrote:
[...]
>>
>> How would you achieve that?  Your guest OS
>> doesn't necessarily have the code mapped.  I
>> think this has to be considered as other syscalls,
>> though slightly different.
>
> There is no guest OS when doing -user emulation.
> Only qemu.

I meant that the vsyscall page doesn't exist on
other guest systems but x86_64 running Linux.
So if one wants to have it somehow mapped
then it would have to be installed by QEMU,
and QEMU can't install such a page due to
limitations in the way it handles virtual
addresses.

>> > My favorite solution would be a vsyscall page mapped
>> > to the correct fixed address and filled with QEMU
>> > generated specific code, for example code which calls the
>> > normal syscalls to do the work. This would only
>> > need modifications for linux-user code.
>>
>> You mean you'd explicitly put somewhere x86_64
>> code that simulates the behaviour of vsyscall?
>
> That seems like a good idea to me.

Why not indeed.  But someone will first have
to fix virtual memory management.


Laurent

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2010-02-06 23:50             ` Laurent Desnogues
  2010-02-07  0:22               ` Jamie Lokier
@ 2010-02-07 23:18               ` Richard Henderson
  2010-02-08 14:57                 ` Vince Weaver
  1 sibling, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2010-02-07 23:18 UTC (permalink / raw)
  To: Laurent Desnogues; +Cc: qemu-devel

On 02/06/2010 03:50 PM, Laurent Desnogues wrote:
>> * target-i386 code should not have to know about
>>   linux vsyscall
>
> Given that we have to workaround 64-bit virtual
> address limitations (cf. Richard mail and previous
> discussions on the list), doing otherwise looks
> difficult.

Actually, it should be easy for QEMU to handle this.

The application is given the address of the VDSO in the AT_SYSINFO and 
AT_SYSINFO_EHDR entries of the auxvec (on the stack above argv and 
environ).  We can place this anywhere we like; the fact that the kernel 
puts it in high memory is merely a convenience to the kernel.

There *is* a legacy vsyscall address in high memory, from before the 
whole VDSO arrangement was worked out, but we could probably get away 
with ignoring that.  Certainly well behaved applications will be 
honoring the VDSO when it is given.

>> * it is not possible to step into vsyscall code
>>   using a debugger
>
> How would you achieve that?  Your guest OS
> doesn't necessarily have the code mapped.  I
> think this has to be considered as other syscalls,
> though slightly different.

If QEMU implements the VDSO, the page *will* be mapped, and the debugger 
will Just Work.

I imagine that QEMU's VDSO would not have the complicated bits that the 
kernel's version does, where it arranges to read the clock without going 
into kernel space.  I imagine QEMU would simply stuff a normal syscall 
sequence in there, which would automatically be emulated in the normal way.

Have a stare at the linux/arch/x86/vdso directory to see how things work.


r~

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

* Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
  2010-02-07 23:18               ` Richard Henderson
@ 2010-02-08 14:57                 ` Vince Weaver
  0 siblings, 0 replies; 20+ messages in thread
From: Vince Weaver @ 2010-02-08 14:57 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Laurent Desnogues, qemu-devel

On Sun, 7 Feb 2010, Richard Henderson wrote:
> 
> I imagine that QEMU's VDSO would not have the complicated bits that the
> kernel's version does, where it arranges to read the clock without going into
> kernel space.  I imagine QEMU would simply stuff a normal syscall sequence in
> there, which would automatically be emulated in the normal way.

For what it's worth, this is how various other systems I'm aware of handle 
x86_64 VDSOs (both Valgrind and the m5 simulator do it this way).

Vince

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

end of thread, other threads:[~2010-02-08 14:58 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-11 15:14 [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall Laurent Desnogues
2009-10-17 15:42 ` [Qemu-devel] " Laurent Desnogues
2009-10-17 19:57 ` [Qemu-devel] " Edgar E. Iglesias
2009-10-18  0:16   ` Laurent Desnogues
2009-10-18  2:47     ` Jamie Lokier
2009-10-18 11:23       ` Laurent Desnogues
2009-10-18  3:09   ` Jamie Lokier
2009-10-18  7:17     ` Edgar E. Iglesias
2009-10-18 11:29     ` Laurent Desnogues
2010-02-04 22:15       ` Stefan Weil
2010-02-05 22:57       ` Stefan Weil
2010-02-06  1:37         ` Laurent Desnogues
2010-02-06  7:49           ` Stefan Weil
2010-02-06 23:50             ` Laurent Desnogues
2010-02-07  0:22               ` Jamie Lokier
2010-02-07  3:11                 ` malc
2010-02-07 10:06                 ` Laurent Desnogues
2010-02-07 23:18               ` Richard Henderson
2010-02-08 14:57                 ` Vince Weaver
2010-02-06 20:12         ` Richard Henderson

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.