X86: Enable x86_64 vsyscall support

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.
This commit is contained in:
Vince Weaver 2009-11-04 00:47:12 -05:00
parent 9b0a747dd4
commit a1042db290
2 changed files with 34 additions and 0 deletions

View 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]);

View 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();