arch,cpu,sim: Push syscall number determination up to processes.
authorGabe Black <gabeblack@google.com>
Mon, 25 Nov 2019 09:07:41 +0000 (01:07 -0800)
committerGabe Black <gabeblack@google.com>
Tue, 10 Dec 2019 23:58:14 +0000 (23:58 +0000)
The logic that determines which syscall to call was built into the
implementation of faults/exceptions or even into the instruction
decoder, but that logic can depend on what OS is being used, and
sometimes even what version, for example 32bit vs. 64bit.

This change pushes that logic up into the Process objects since those
already handle a lot of the aspects of emulating the guest OS. Instead,
the ISA or fault implementations just notify the rest of the system
that a nebulous syscall has happened, and that gets propogated upward
until the process does something with it. That's very analogous to how
a system call would work on a real machine.

When a system call happens, the low level component which detects that
should call tc->syscall(&fault), where tc is the relevant thread (or
execution) context, and fault is a Fault which can ultimately be set
by the system call implementation.

The TC implementor (probably a CPU) will then have a chance to do
whatever it needs to to handle a system call. Currently only O3 does
anything special here. That implementor will end up calling the
Process's syscall() method.

Once in Process::syscall, the process object will use it's contextual
knowledge to determine what system call is being requested. It then
calls Process::doSyscall with the right syscall number, where doSyscall
centralizes the common mechanism for actually retrieving and calling
into the system call implementation.

Jira Issue: https://gem5.atlassian.net/browse/GEM5-187

Change-Id: I937ec1ef0576142c2a182ff33ca508d77ad0e7a1
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23176
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Brandon Potter <Brandon.Potter@amd.com>
46 files changed:
src/arch/alpha/isa/decoder.isa
src/arch/alpha/linux/process.cc
src/arch/alpha/linux/process.hh
src/arch/arm/fastmodel/iris/thread_context.hh
src/arch/arm/faults.cc
src/arch/arm/freebsd/process.cc
src/arch/arm/freebsd/process.hh
src/arch/arm/linux/process.cc
src/arch/arm/linux/process.hh
src/arch/mips/isa/decoder.isa
src/arch/mips/isa/operands.isa
src/arch/mips/linux/process.cc
src/arch/mips/linux/process.hh
src/arch/power/isa/decoder.isa
src/arch/power/isa/operands.isa
src/arch/power/linux/process.cc
src/arch/power/linux/process.hh
src/arch/riscv/faults.cc
src/arch/riscv/linux/process.cc
src/arch/riscv/linux/process.hh
src/arch/sparc/linux/process.cc
src/arch/sparc/linux/process.hh
src/arch/sparc/solaris/process.cc
src/arch/sparc/solaris/process.hh
src/arch/x86/isa/decoder/one_byte_opcodes.isa
src/arch/x86/isa/decoder/two_byte_opcodes.isa
src/arch/x86/linux/process.cc
src/arch/x86/linux/process.hh
src/arch/x86/process.cc
src/arch/x86/process.hh
src/arch/x86/pseudo_inst.cc
src/cpu/checker/cpu.hh
src/cpu/checker/thread_context.hh
src/cpu/exec_context.hh
src/cpu/minor/exec_context.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/dyn_inst.hh
src/cpu/o3/dyn_inst_impl.hh
src/cpu/o3/thread_context.hh
src/cpu/o3/thread_state.hh
src/cpu/simple/exec_context.hh
src/cpu/simple_thread.hh
src/cpu/thread_context.hh
src/sim/process.cc
src/sim/process.hh

index 020e43359f02cad5069d2624828bd06e253b71b2..abf6fb24a9a1c743cddac99b92168d6306e79459 100644 (file)
@@ -840,7 +840,7 @@ decode OPCODE default Unknown::unknown() {
                     exitSimLoop("halt instruction encountered");
                 }}, IsNonSpeculative);
                 0x83: callsys({{
-                    xc->syscall(R0, &fault);
+                    xc->syscall(&fault);
                 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall);
                 // Read uniq reg into ABI return value register (r0)
                 0x9e: rduniq({{ R0 = Runiq; }}, IsIprAccess);
index 1ac53a5a0f64a365d0a73d1439a294d739dbde3a..26d5f26cda6412f1d51da8a0b1e2831f594f9692 100644 (file)
@@ -620,3 +620,10 @@ AlphaLinuxProcess::getDesc(int callnum)
         return NULL;
     return &syscallDescs[callnum];
 }
+
+void
+AlphaLinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(0), tc, fault);
+}
+
index 46c22d2884426af8774b11bf7cccebc6a26c5ea1..991ddbd087d021314b30382644d88219ce1cf5ea 100644 (file)
@@ -42,6 +42,8 @@ class AlphaLinuxProcess : public AlphaProcess
     /// Constructor.
     AlphaLinuxProcess(ProcessParams * params, ObjectFile *objFile);
 
+    void syscall(ThreadContext *tc, Fault *fault) override;
+
     virtual SyscallDesc* getDesc(int callnum);
 
      /// Array of syscall descriptors, indexed by call number.
index c0f40d76cd6c07c17dd72f7cc43d77ab6cbdbe92..d0e920e609793296cfdec22bfd0d2b01bd2d2873 100644 (file)
@@ -419,7 +419,7 @@ class ThreadContext : public ::ThreadContext
     }
 
     void
-    syscall(int64_t callnum, Fault *fault) override
+    syscall(Fault *fault) override
     {
         panic("%s not implemented.", __FUNCTION__);
     }
index 85e9fa7e9c5e35f903cb72b74339c02d34c20484..5a7b8e8eaf70c3d15be699d7b40915a83bbf3c90 100644 (file)
@@ -845,15 +845,8 @@ SupervisorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst)
 
     // As of now, there isn't a 32 bit thumb version of this instruction.
     assert(!machInst.bigThumb);
-    uint32_t callNum;
-    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
-    OperatingMode mode = (OperatingMode)(uint8_t)cpsr.mode;
-    if (opModeIs64(mode))
-        callNum = tc->readIntReg(INTREG_X8);
-    else
-        callNum = tc->readIntReg(INTREG_R7);
     Fault fault;
-    tc->syscall(callNum, &fault);
+    tc->syscall(&fault);
 
     // Advance the PC since that won't happen automatically.
     PCState pc = tc->pcState();
index 901b2411b53d6de3329d79101fd190ccb042ccf4..a603777a15d40000801eefb848b6ddd69a5589f9 100644 (file)
@@ -1317,3 +1317,15 @@ ArmFreebsdProcess64::initState()
     ArmProcess64::initState();
     // The 64 bit equivalent of the comm page would be set up here.
 }
+
+void
+ArmFreebsdProcess32::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(INTREG_R7), tc, fault);
+}
+
+void
+ArmFreebsdProcess64::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(INTREG_X8), tc, fault);
+}
index 28504d7d8789f21013cac7cc954ede2e6dbfb0f8..5f4a89600a99b70039cde9408cff6cab98bd00e6 100644 (file)
@@ -63,6 +63,8 @@ class ArmFreebsdProcess32 : public ArmProcess32, public ArmFreebsdProcessBits
 
     void initState();
 
+    void syscall(ThreadContext *tc, Fault *fault) override;
+
     /// Explicitly import the otherwise hidden getSyscallArg
     using ArmProcess::getSyscallArg;
 
@@ -80,6 +82,7 @@ class ArmFreebsdProcess64 : public ArmProcess64, public ArmFreebsdProcessBits
                         ObjectFile::Arch _arch);
 
     void initState();
+    void syscall(ThreadContext *tc, Fault *fault) override;
     SyscallDesc* getDesc(int callnum);
 };
 
index d3d0e85be316489fef7d229383fb1f94042717d7..bc41932b8b8f1a1ca00ef512b2bef137a553bc88 100644 (file)
@@ -1777,3 +1777,15 @@ ArmLinuxProcess64::initState()
     ArmProcess64::initState();
     // The 64 bit equivalent of the comm page would be set up here.
 }
+
+void
+ArmLinuxProcess32::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(INTREG_R7), tc, fault);
+}
+
+void
+ArmLinuxProcess64::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(INTREG_X8), tc, fault);
+}
index d4b7ca7d3f1683716f9bd0deb46c3a331c08dc8d..8e2709fcdcca719e6a5f731e0096435808b19d0c 100644 (file)
@@ -73,6 +73,8 @@ class ArmLinuxProcess32 : public ArmProcess32, public ArmLinuxProcessBits
 
     void initState();
 
+    void syscall(ThreadContext *tc, Fault *fault) override;
+
     /// Explicitly import the otherwise hidden getSyscallArg
     using ArmProcess::getSyscallArg;
 
@@ -90,6 +92,7 @@ class ArmLinuxProcess64 : public ArmProcess64, public ArmLinuxProcessBits
                       ObjectFile::Arch _arch);
 
     void initState();
+    void syscall(ThreadContext *tc, Fault *fault) override;
     SyscallDesc* getDesc(int callnum);
 };
 
index 3406ed5d2b22e12e5c01f454dec2e377238ece5c..856a340834440187b35694305e5d3373b6d9df42 100644 (file)
@@ -163,7 +163,7 @@ decode OPCODE_HI default Unknown::unknown() {
                     0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
                     0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
                     0x4: decode FullSystemInt {
-                        0: syscall_se({{ xc->syscall(R2, &fault); }},
+                        0: syscall_se({{ xc->syscall(&fault); }},
                                 IsSerializeAfter, IsNonSpeculative);
                       default: syscall({{ fault = std::make_shared<SystemCallFault>(); }});
                     }
index 2d44bb30ee4cc6e93775d53c32db81537808cf43..f81df73fd958d18e796bf7f29ce11eb9903f599f 100644 (file)
@@ -51,9 +51,8 @@ def operands {{
     #Immediate Value operand
     'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
 
-    #Operands used for Link or Syscall Insts
+    #Operands used for Link Insts
     'R31': ('IntReg', 'uw','31','IsInteger', 4),
-    'R2':  ('IntReg', 'uw','2', 'IsInteger', 5),
 
     #Special Integer Reg operands
     'LO0':  ('IntReg', 'uw','INTREG_LO', 'IsInteger', 6),
index adfbfd3f649702d1e8d29d6538d20176c7971712..2dc1bcdaf8fc9dbf0ce664f9ca7cb39d8142dd24 100644 (file)
@@ -509,7 +509,8 @@ MipsLinuxProcess::getDesc(int callnum)
     return &syscallDescs[m5_sys_idx];
 }
 
-
-
-
-
+void
+MipsLinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(2), tc, fault);
+}
index cbf0d78ead3741fb06c095501db200d9341e37b0..7fcb6f014c9472c28bdafa1f2f40796c6cf3c82d 100644 (file)
@@ -51,6 +51,8 @@ class MipsLinuxProcess : public MipsProcess
     /// ID of the thread group leader for the process
     uint64_t __tgid;
 
+    void syscall(ThreadContext *tc, Fault *fault) override;
+
     /// Array of syscall descriptors, indexed by call number.
     static SyscallDesc syscallDescs[];
     const int Num_Syscall_Descs;
index 060d6a34d63b4fc2fb05f9ed436e12eeab7631b1..3f10fe48b04316a56be687887721a19a4faa7b12 100644 (file)
@@ -517,7 +517,7 @@ decode OPCODE default Unknown::unknown() {
         55: stfdu({{ Mem_df = Fs; }});
     }
 
-    17: IntOp::sc({{ xc->syscall(R0, &fault); }},
+    17: IntOp::sc({{ xc->syscall(&fault); }},
                   [ IsSyscall, IsNonSpeculative, IsSerializeAfter ]);
 
     format FloatArithOp {
index a72a0714d4a72b1a25d1dbe33ab6f6101b41c9ae..117c8ad02faa13f33a87b2c964005d7ae3eb1e58 100644 (file)
@@ -75,7 +75,4 @@ def operands {{
     'Rsv': ('IntReg', 'uw', 'INTREG_RSV', 'IsInteger', 9),
     'RsvLen': ('IntReg', 'uw', 'INTREG_RSV_LEN', 'IsInteger', 9),
     'RsvAddr': ('IntReg', 'uw', 'INTREG_RSV_ADDR', 'IsInteger', 9),
-
-    # Hack for non-full-system syscall emulation
-    'R0':  ('IntReg', 'uw', '0', None, 1),
 }};
index ac032275e4e8f9d859b9923cfe53ca490ba9d48d..a63d9a30c6a7252c8e76aa97e9b12d3a699881a2 100644 (file)
@@ -468,6 +468,12 @@ PowerLinuxProcess::initState()
     PowerProcess::initState();
 }
 
+void
+PowerLinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(0), tc, fault);
+}
+
 RegVal
 PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int &i)
 {
index 5a2ad92a4141249ba94f232dfd580465a9fcb75d..ef96dae5ffe7325449eb146995d256890f48cd0e 100644 (file)
@@ -45,6 +45,8 @@ class PowerLinuxProcess : public PowerProcess
 
     void initState();
 
+    void syscall(ThreadContext *tc, Fault *fault) override;
+
     RegVal getSyscallArg(ThreadContext *tc, int &i);
     /// Explicitly import the otherwise hidden getSyscallArg
     using Process::getSyscallArg;
index 6b79eb8383204a984a5819e432c59acf40502898..83adcba69f2c0238884d02bd1a67c3f8cd572df8 100644 (file)
@@ -191,7 +191,7 @@ void
 SyscallFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
 {
     Fault *fault = NoFault;
-    tc->syscall(tc->readIntReg(SyscallNumReg), fault);
+    tc->syscall(fault);
 }
 
 } // namespace RiscvISA
index d6a41e240026969d2da773b7d46af41bef277ef2..49e32de9285856609079c026b822b48fcba8291f 100644 (file)
@@ -795,6 +795,12 @@ RiscvLinuxProcess64::getDesc(int callnum)
         &syscallDescs.at(callnum) : nullptr;
 }
 
+void
+RiscvLinuxProcess64::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(SyscallNumReg), tc, fault);
+}
+
 RiscvLinuxProcess32::RiscvLinuxProcess32(ProcessParams * params,
     ObjectFile *objFile) : RiscvProcess32(params, objFile)
 {}
@@ -805,3 +811,9 @@ RiscvLinuxProcess32::getDesc(int callnum)
     return syscallDescs.find(callnum) != syscallDescs.end() ?
         &syscallDescs.at(callnum) : nullptr;
 }
+
+void
+RiscvLinuxProcess32::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(SyscallNumReg), tc, fault);
+}
index 1256ac66739e74db3ed4619977369dcc8c1b8482..65daca35e0e2132da5a59d3fcf1249231956e699 100644 (file)
@@ -55,6 +55,8 @@ class RiscvLinuxProcess64 : public RiscvProcess64
     /// ID of the thread group leader for the process
     uint64_t __tgid;
 
+    void syscall(ThreadContext *tc, Fault *fault) override;
+
     /// Array of syscall descriptors, indexed by call number.
     static std::map<int, SyscallDesc> syscallDescs;
 };
@@ -73,6 +75,8 @@ class RiscvLinuxProcess32 : public RiscvProcess32
     /// ID of the thread group leader for the process
     uint64_t __tgid;
 
+    void syscall(ThreadContext *tc, Fault *fault) override;
+
     /// Array of syscall descriptors, indexed by call number.
     static std::map<int, SyscallDesc> syscallDescs;
 };
index 5fb3b034844a0ff72d37f0638d6a6e87263c9b5a..530cf8512dde3ab34adbe2b80666a47845544509 100644 (file)
@@ -100,12 +100,18 @@ Sparc32LinuxProcess::Sparc32LinuxProcess(ProcessParams * params,
     : Sparc32Process(params, objFile)
 {}
 
-void Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc,
-                                     Fault *fault)
+void
+Sparc32LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(1), tc, fault);
+}
+
+void
+Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc, Fault *fault)
 {
     switch (trapNum) {
       case 0x10: //Linux 32 bit syscall trap
-        tc->syscall(tc->readIntReg(1), fault);
+        tc->syscall(fault);
         break;
       default:
         SparcProcess::handleTrap(trapNum, tc, fault);
@@ -117,13 +123,19 @@ Sparc64LinuxProcess::Sparc64LinuxProcess(ProcessParams * params,
     : Sparc64Process(params, objFile)
 {}
 
-void Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc,
-                                     Fault *fault)
+void
+Sparc64LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(1), tc, fault);
+}
+
+void
+Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc, Fault *fault)
 {
     switch (trapNum) {
       // case 0x10: // Linux 32 bit syscall trap
       case 0x6d: // Linux 64 bit syscall trap
-        tc->syscall(tc->readIntReg(1), fault);
+        tc->syscall(fault);
         break;
       default:
         SparcProcess::handleTrap(trapNum, tc, fault);
index f5260cdf13414f1ce1ab9d826983f4ec020c6a9e..5c673db260364f70d051d0f262c7ca597ce0961f 100644 (file)
@@ -70,6 +70,8 @@ class Sparc32LinuxProcess : public SparcLinuxProcess, public Sparc32Process
         return SparcLinuxProcess::getDesc32(callnum);
     }
 
+    void syscall(ThreadContext *tc, Fault *fault) override;
+
     void handleTrap(int trapNum, ThreadContext *tc, Fault *fault);
 };
 
@@ -86,6 +88,8 @@ class Sparc64LinuxProcess : public SparcLinuxProcess, public Sparc64Process
         return SparcLinuxProcess::getDesc(callnum);
     }
 
+    void syscall(ThreadContext *tc, Fault *fault) override;
+
     void handleTrap(int trapNum, ThreadContext *tc, Fault *fault);
 };
 
index 18f2316a26163e27a5014cdee30eb934b828d2de..d51b9519c99b290e0ddda8c5d6e98d9dd23f682c 100644 (file)
@@ -368,3 +368,9 @@ SparcSolarisProcess::getDesc(int callnum)
         return NULL;
     return &syscallDescs[callnum];
 }
+
+void
+SparcSolarisProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(1), tc, fault);
+}
index 660802cefaa5dbdd67869fc41078b1baa394dbb6..39e3aef17736bdcb943bc0221852c3e04a7ba34a 100644 (file)
@@ -49,6 +49,8 @@ class SparcSolarisProcess : public Sparc64Process
     /// The target system's hostname.
     static const char *hostname;
 
+    void syscall(ThreadContext *tc, Fault *fault) override;
+
      /// Array of syscall descriptors, indexed by call number.
     static SyscallDesc syscallDescs[];
 
index 95bc7a5c1a0350098ff5b5f93cc84969261eb197..1fbf32748c8eeb5602b0395125e84770b2507dbc 100644 (file)
                         // will sign extend it, and there's no easy way to
                         // specify only checking the first byte.
                         0xffffffffffffff80:
-                            SyscallInst::int80('xc->syscall(Rax, &fault)',
+                            SyscallInst::int80('xc->syscall(&fault)',
                                                IsSyscall, IsNonSpeculative,
                                                IsSerializeAfter);
                     }
index 51154d5b8495a1a59c57ccfeaa9af0d1c04b9f31..43a62d76cdee40c9d6f6a293e0c738ed129bac99 100644 (file)
                 }
             }
             0x05: decode FullSystemInt {
-                0: SyscallInst::syscall('xc->syscall(Rax, &fault)',
+                0: SyscallInst::syscall('xc->syscall(&fault)',
                                         IsSyscall, IsNonSpeculative,
                                         IsSerializeAfter);
                 default: decode MODE_MODE {
             0x2: Inst::RDMSR();
             0x3: rdpmc();
             0x4: decode FullSystemInt {
-                0: SyscallInst::sysenter('xc->syscall(Rax, &fault)',
+                0: SyscallInst::sysenter('xc->syscall(&fault)',
                                          IsSyscall, IsNonSpeculative,
                                          IsSerializeAfter);
                 default: sysenter();
index 6befafde42dcac2d0beac5b1cd0ba4419df0fff1..d58d965af6aa8ae4c0ccb773030f62541cf70000 100644 (file)
@@ -584,8 +584,15 @@ X86_64LinuxProcess::X86_64LinuxProcess(ProcessParams * params,
                     sizeof(syscallDescs64) / sizeof(SyscallDesc))
 {}
 
-void X86_64LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc,
-                               Process *process, RegVal flags)
+void
+X86_64LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+    doSyscall(tc->readIntReg(INTREG_RAX), tc, fault);
+}
+
+void
+X86_64LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc,
+                          Process *process, RegVal flags)
 {
     X86_64Process::clone(old_tc, new_tc, (X86_64Process*)process, flags);
 }
@@ -926,8 +933,22 @@ I386LinuxProcess::I386LinuxProcess(ProcessParams * params, ObjectFile *objFile)
                   sizeof(syscallDescs32) / sizeof(SyscallDesc))
 {}
 
-void I386LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc,
-                             Process *process, RegVal flags)
+void
+I386LinuxProcess::syscall(ThreadContext *tc, Fault *fault)
+{
+    PCState pc = tc->pcState();
+    Addr eip = pc.pc();
+    if (eip >= vsyscallPage.base &&
+            eip < vsyscallPage.base + vsyscallPage.size) {
+        pc.npc(vsyscallPage.base + vsyscallPage.vsysexitOffset);
+        tc->pcState(pc);
+    }
+    doSyscall(tc->readIntReg(INTREG_RAX), tc, fault);
+}
+
+void
+I386LinuxProcess::clone(ThreadContext *old_tc, ThreadContext *new_tc,
+                        Process *process, RegVal flags)
 {
     I386Process::clone(old_tc, new_tc, (I386Process*)process, flags);
 }
index d4c9b0cf66bb24079c08d989697a6b4eba02ecd0..5f3135dd96253b94b675022afd7ccd871595b213 100644 (file)
@@ -54,6 +54,7 @@ class X86_64LinuxProcess : public X86_64Process
   public:
     /// Constructor.
     X86_64LinuxProcess(ProcessParams * params, ObjectFile *objFile);
+    void syscall(ThreadContext *tc, Fault *fault) override;
     void clone(ThreadContext *old_tc, ThreadContext *new_tc, Process *process,
                RegVal flags);
 };
@@ -63,6 +64,7 @@ class I386LinuxProcess : public I386Process
   public:
     /// Constructor.
     I386LinuxProcess(ProcessParams * params, ObjectFile *objFile);
+    void syscall(ThreadContext *tc, Fault *fault) override;
     void clone(ThreadContext *old_tc, ThreadContext *new_tc, Process *process,
                RegVal flags);
 };
index f0e8ead98ac983e8402e39b3481c38f525ceca8c..df22f238a726db1cd080f1019b27a80a123b0d78 100644 (file)
@@ -146,19 +146,6 @@ X86_64Process::X86_64Process(ProcessParams *params, ObjectFile *objFile,
                                      next_thread_stack_base, mmap_end);
 }
 
-void
-I386Process::syscall(int64_t callnum, ThreadContext *tc, Fault *fault)
-{
-    PCState pc = tc->pcState();
-    Addr eip = pc.pc();
-    if (eip >= vsyscallPage.base &&
-            eip < vsyscallPage.base + vsyscallPage.size) {
-        pc.npc(vsyscallPage.base + vsyscallPage.vsysexitOffset);
-        tc->pcState(pc);
-    }
-    X86Process::syscall(callnum, tc, fault);
-}
-
 
 I386Process::I386Process(ProcessParams *params, ObjectFile *objFile,
                          SyscallDesc *_syscallDescs, int _numSyscallDescs)
index 37545e9d9a312f2c0a1b9f8d137af13beeefc973..4c424cd7d92b9ce80432754495776a4415918e46 100644 (file)
@@ -176,8 +176,6 @@ namespace X86ISA
         void argsInit(int pageSize);
         void initState() override;
 
-        void syscall(int64_t callnum, ThreadContext *tc,
-                     Fault *fault) override;
         RegVal getSyscallArg(ThreadContext *tc, int &i) override;
         RegVal getSyscallArg(ThreadContext *tc, int &i, int width) override;
         void clone(ThreadContext *old_tc, ThreadContext *new_tc,
index 62d8b25c53d25e8418e38cbf15552d1b0354dc01..68bc74accefdb4bce2fe422b30ce93cfd12625a5 100644 (file)
@@ -50,7 +50,7 @@ m5Syscall(ThreadContext *tc)
     DPRINTF(PseudoInst, "PseudoInst::m5Syscall()\n");
 
     Fault fault;
-    tc->syscall(tc->readIntReg(INTREG_RAX), &fault);
+    tc->syscall(&fault);
 }
 
 /*
index 8db6aa376801d0f347e81294b103f1fd51229f02..e50afebf5ef21eb7e2e584c950c493077de3577f 100644 (file)
@@ -581,7 +581,7 @@ class CheckerCPU : public BaseCPU, public ExecContext
     void wakeup(ThreadID tid) override { }
     // Assume that the normal CPU's call to syscall was successful.
     // The checker's state would have already been updated by the syscall.
-    void syscall(int64_t callnum, Fault *fault) override { }
+    void syscall(Fault *fault) override { }
 
     void
     handleError()
index dbdfa80cdd96ba56bc2f6b2eecfeb9096ead0df4..0fb75562a52d5d5e36c5669fc9ff8d641b7faae6 100644 (file)
@@ -184,9 +184,9 @@ class CheckerThreadContext : public ThreadContext
 
     /** Executes a syscall in SE mode. */
     void
-    syscall(int64_t callnum, Fault *fault) override
+    syscall(Fault *fault) override
     {
-        return actualTC->syscall(callnum, fault);
+        return actualTC->syscall(fault);
     }
 
     Status status() const override { return actualTC->status(); }
index a2b3924928d8ed8b077842940d168bc5532f1639..80f3edaee27259ef18933baae5454f0775ea3bba 100644 (file)
@@ -304,9 +304,9 @@ class ExecContext {
      */
 
     /**
-     * Executes a syscall specified by the callnum.
+     * Executes a syscall.
      */
-    virtual void syscall(int64_t callnum, Fault *fault) = 0;
+    virtual void syscall(Fault *fault) = 0;
 
     /** @} */
 
index 66e313eb37dfea032ff7523f492475011c9fdbdc..184dd29101ba86f5b3872670e8988cb1c42fd008 100644 (file)
@@ -387,9 +387,9 @@ class ExecContext : public ::ExecContext
     }
 
     void
-    syscall(int64_t callnum, Fault *fault) override
+    syscall(Fault *fault) override
     {
-        thread.syscall(callnum, fault);
+        thread.syscall(fault);
     }
 
     ThreadContext *tcBase() override { return thread.getTC(); }
index c843db3a015aae392557fe2646f30c4501feb365..996f6360bc434f6c3c1200384754cddb89dc42fc 100644 (file)
@@ -918,7 +918,7 @@ FullO3CPU<Impl>::trap(const Fault &fault, ThreadID tid,
 
 template <class Impl>
 void
-FullO3CPU<Impl>::syscall(int64_t callnum, ThreadID tid, Fault *fault)
+FullO3CPU<Impl>::syscall(ThreadID tid, Fault *fault)
 {
     DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid);
 
@@ -929,7 +929,7 @@ FullO3CPU<Impl>::syscall(int64_t callnum, ThreadID tid, Fault *fault)
     ++(this->thread[tid]->funcExeInst);
 
     // Execute the actual syscall.
-    this->thread[tid]->syscall(callnum, fault);
+    this->thread[tid]->syscall(fault);
 
     // Decrease funcExeInst by one as the normal commit will handle
     // incrementing it.
index b06182d43d5f8167f9ddf653b72631aa2a685bbf..7c0ea51662f281dff21dbff0be8d5de1f3e180ba 100644 (file)
@@ -284,7 +284,7 @@ class FullO3CPU : public BaseO3CPU
     /** Executes a syscall.
      * @todo: Determine if this needs to be virtual.
      */
-    void syscall(int64_t callnum, ThreadID tid, Fault *fault);
+    void syscall(ThreadID tid, Fault *fault);
 
     /** Starts draining the CPU's pipeline of all instructions in
      * order to stop all memory accesses. */
index 131ffd2589ab8f61e364730552027684c88e03ed..a136e901963821b9660b5443eadef4d8c0c414ea 100644 (file)
@@ -252,7 +252,7 @@ class BaseO3DynInst : public BaseDynInst<Impl>
     void trap(const Fault &fault);
 
     /** Emulates a syscall. */
-    void syscall(int64_t callnum, Fault *fault) override;
+    void syscall(Fault *fault) override;
 
   public:
 
index 22d89ec0b9364419be7f03d279bcd9e0bd7145bc..a9fc990ecafbd2800b8ea6b09be944bd1b270eaf 100644 (file)
@@ -192,13 +192,13 @@ BaseO3DynInst<Impl>::trap(const Fault &fault)
 
 template <class Impl>
 void
-BaseO3DynInst<Impl>::syscall(int64_t callnum, Fault *fault)
+BaseO3DynInst<Impl>::syscall(Fault *fault)
 {
     // HACK: check CPU's nextPC before and after syscall. If it
     // changes, update this instruction's nextPC because the syscall
     // must have changed the nextPC.
     TheISA::PCState curPC = this->cpu->pcState(this->threadNumber);
-    this->cpu->syscall(callnum, this->threadNumber, fault);
+    this->cpu->syscall(this->threadNumber, fault);
     TheISA::PCState newPC = this->cpu->pcState(this->threadNumber);
     if (!(curPC == newPC)) {
         this->pcState(newPC);
index c68f34c079f9e623b6ff17379dccb2f4ae4a8125..a01c0541396c6a1fac1f75d71ea71b61898d8438 100644 (file)
@@ -448,9 +448,9 @@ class O3ThreadContext : public ThreadContext
 
     /** Executes a syscall in SE mode. */
     void
-    syscall(int64_t callnum, Fault *fault) override
+    syscall(Fault *fault) override
     {
-        return cpu->syscall(callnum, thread->threadId(), fault);
+        return cpu->syscall(thread->threadId(), fault);
     }
 
     /** Reads the funcExeInst counter. */
index a0c3a8171b59e53e9817a59e5a5b5600eaa75d43..024ebd074f977946803fb7211a24bee6b6926155 100644 (file)
@@ -148,10 +148,9 @@ struct O3ThreadState : public ThreadState {
     ThreadContext *getTC() { return tc; }
 
     /** Handles the syscall. */
-    void syscall(int64_t callnum, Fault *fault)
+    void syscall(Fault *fault)
     {
-        fatal_if(FullSystem, "System call emulation is unavailable!");
-        process->syscall(callnum, tc, fault);
+        process->syscall(tc, fault);
     }
 
     void dumpFuncProfile()
index 4d26dfe2aa3e2b5ab20b47e46c309562ab3eb37a..48a9f94232b54be7b3223e36ae0ed6d22fb1fbb1 100644 (file)
@@ -497,9 +497,9 @@ class SimpleExecContext : public ExecContext {
      * Executes a syscall specified by the callnum.
      */
     void
-    syscall(int64_t callnum, Fault *fault) override
+    syscall(Fault *fault) override
     {
-        thread->syscall(callnum, fault);
+        thread->syscall(fault);
     }
 
     /** Returns a pointer to the ThreadContext. */
index 387e74546d2c229b6b8e0c507419bb51e549e442..b4afcbbc840ac504022aeef6c72c2f1db88d29fd 100644 (file)
@@ -609,10 +609,9 @@ class SimpleThread : public ThreadState, public ThreadContext
     }
 
     void
-    syscall(int64_t callnum, Fault *fault) override
+    syscall(Fault *fault) override
     {
-        fatal_if(FullSystem, "System call emulation is unavailable!");
-        process->syscall(callnum, this, fault);
+        process->syscall(this, fault);
     }
 
     RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; }
index a77ac48483559cf42a7ecdb9c56ab99407cabbdd..c14161d6f2022c40db1de6afcd5f0d7ec03268ab 100644 (file)
@@ -307,7 +307,7 @@ class ThreadContext : public PCEventScope
     // Same with st cond failures.
     virtual Counter readFuncExeInst() const = 0;
 
-    virtual void syscall(int64_t callnum, Fault *fault) = 0;
+    virtual void syscall(Fault *fault) = 0;
 
     // This function exits the thread context in the CPU and returns
     // 1 if the CPU has no more active threads (meaning it's OK to exit);
index db013aee08e2468fd6e7f4524ec756c03e8ee36d..e7f682aada3e138521257ef26e72d8f0ad81fa91 100644 (file)
@@ -437,7 +437,7 @@ Process::map(Addr vaddr, Addr paddr, int size, bool cacheable)
 }
 
 void
-Process::syscall(int64_t callnum, ThreadContext *tc, Fault *fault)
+Process::doSyscall(int64_t callnum, ThreadContext *tc, Fault *fault)
 {
     numSyscalls++;
 
index 5d4a9672ed9b468ac108ece4eaf048cb53c6b3d2..70be3ab8aeeeabb5d74cb649cc291df255901325 100644 (file)
@@ -63,6 +63,9 @@ class ThreadContext;
 
 class Process : public SimObject
 {
+  protected:
+    void doSyscall(int64_t callnum, ThreadContext *tc, Fault *fault);
+
   public:
     Process(ProcessParams *params, EmulationPageTable *pTable,
             ObjectFile *obj_file);
@@ -74,7 +77,7 @@ class Process : public SimObject
     void initState() override;
     DrainState drain() override;
 
-    virtual void syscall(int64_t callnum, ThreadContext *tc, Fault *fault);
+    virtual void syscall(ThreadContext *tc, Fault *fault) = 0;
     virtual RegVal getSyscallArg(ThreadContext *tc, int &i) = 0;
     virtual RegVal getSyscallArg(ThreadContext *tc, int &i, int width);
     virtual void setSyscallReturn(ThreadContext *tc,