X86: Enable x86_64 vsyscall support
authorVince Weaver <vince@csl.cornell.edu>
Wed, 4 Nov 2009 05:47:12 +0000 (00:47 -0500)
committerVince Weaver <vince@csl.cornell.edu>
Wed, 4 Nov 2009 05:47:12 +0000 (00:47 -0500)
64-bit vsyscall is different than 32-bit.
There are only two syscalls, time and gettimeofday.
On a real system, there is complicated code that implements these
without entering the kernel.  That would be complicated to implement in m5.
Instead we just place code that calls the regular syscalls (this is how
tools such as valgrind handle this case).

This is needed for the perlbmk spec2k benchmark.

src/arch/x86/process.cc
src/arch/x86/process.hh

index f7b3ce24ae16c5d06d59db5e97d37de62790fe0e..7cc889d7cc170f2186d121567f8d8ed2c144732a 100644 (file)
@@ -139,6 +139,12 @@ X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params,
         int _numSyscallDescs) :
     X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs)
 {
+
+    vsyscallPage.base = 0xffffffffff600000ULL;
+    vsyscallPage.size = VMPageSize;
+    vsyscallPage.vtimeOffset = 0x400;
+    vsyscallPage.vgettimeofdayOffset = 0x410;
+
     // Set up stack. On X86_64 Linux, stack goes from the top of memory
     // downward, less the hole for the kernel address space plus one page
     // for undertermined purposes.
@@ -205,6 +211,24 @@ X86_64LiveProcess::startup()
 
     argsInit(sizeof(uint64_t), VMPageSize);
 
+       // Set up the vsyscall page for this process.
+    pTable->allocate(vsyscallPage.base, vsyscallPage.size);
+    uint8_t vtimeBlob[] = {
+        0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00,    // mov    $0xc9,%rax
+        0x0f,0x05,                             // syscall
+        0xc3                                   // retq
+    };
+    initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vtimeOffset,
+            vtimeBlob, sizeof(vtimeBlob));
+
+    uint8_t vgettimeofdayBlob[] = {
+        0x48,0xc7,0xc0,0x60,0x00,0x00,0x00,    // mov    $0x60,%rax
+        0x0f,0x05,                             // syscall
+        0xc3                                   // retq
+    };
+    initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vgettimeofdayOffset,
+            vgettimeofdayBlob, sizeof(vgettimeofdayBlob));
+
     for (int i = 0; i < contextIds.size(); i++) {
         ThreadContext * tc = system->getThreadContext(contextIds[i]);
 
index 4d031bd5a37986200f03011fab2d2e884d8ecfff..3ad2abe08b8f7ae525a56f9263d947282f533363 100644 (file)
@@ -101,6 +101,16 @@ namespace X86ISA
         X86_64LiveProcess(LiveProcessParams *params, ObjectFile *objFile,
                 SyscallDesc *_syscallDescs, int _numSyscallDescs);
 
+        class VSyscallPage
+        {
+          public:
+            Addr base;
+            Addr size;
+            Addr vtimeOffset;
+            Addr vgettimeofdayOffset;
+        };
+        VSyscallPage vsyscallPage;
+
       public:
         void argsInit(int intSize, int pageSize);
         void startup();