Age | Commit message (Collapse) | Author |
|
Now that Nothing inherits from PageTableBase directly, it can be
merged into FuncPageTable. This change also takes the opportunity to
rename the combined class to EmulationPageTable which lets you know
that it's specifically for SE mode.
Also remove the page table entry cache since it doesn't seem to
actually improve performance. The TLBs likely absorb the majority of
the locality, essentially acting like a cache like they would in real
hardware.
Change-Id: If1bcb91aed08686603bf7bee37298c0eee826e13
Reviewed-on: https://gem5-review.googlesource.com/7342
Reviewed-by: Brandon Potter <Brandon.Potter@amd.com>
Maintainer: Gabe Black <gabeblack@google.com>
|
|
This gets rid of an awkward NoArchPageTable class, and also gives the
arch a place to inject ISA specific parameters (specifically page size)
without having to have TheISA:: in the generic version of these types.
Change-Id: I1412f303460d5c43dafdb9b3cd07af81c908a441
Reviewed-on: https://gem5-review.googlesource.com/6981
Reviewed-by: Alexandru Duțu <alexandru.dutu@amd.com>
Maintainer: Gabe Black <gabeblack@google.com>
|
|
This fixes the function call to clone in syscall_emul.hh where
the x86 version should be called before the base implementation
of clone.
Change-Id: Iccd2f680ff6e3a5536037d688a80ab3f236bbd98
Signed-off-by: Sean Wilson <spwilson2@wisc.edu>
Reviewed-on: https://gem5-review.googlesource.com/3902
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
|
|
When the LiveProcess class was renamed to be just Process, the CL author
also changed the syscall function from a virtual function into a regular
one. Unfortunately, the I386Process class overrode the syscall function
to adjust the return address so that control would return to the right
place. Without that adjustment, 32 bit x86 process would segfault and die
immediately after their first system call.
This change reinstates the virtual specifier on the base syscall function,
and adds an override keyword on the I386Process's version so that it won't
be orphaned again in the future. It also fixes some small style issues the
style checker script complained about.
Change-Id: I0d1178ea0eda6676050c8fc043820a2bb4d99c0d
Reviewed-on: https://gem5-review.googlesource.com/3500
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Brandon Potter <Brandon.Potter@amd.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
|
|
Change-Id: I9ff21092876593237f919e9f7fb7283bd865ba2e
Reviewed-on: https://gem5-review.googlesource.com/2421
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Brandon Potter <Brandon.Potter@amd.com>
|
|
The Process class is full of implementation details and
structures related to SE Mode. This changeset factors out an
internal class from Process and moves it into a separate file.
The purpose behind doing this is to clean up the code and make
it a bit more modular.
Change-Id: Ic6941a1657751e8d51d5b6b1dcc04f1195884280
Reviewed-on: https://gem5-review.googlesource.com/2263
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
|
|
The WaitRec structure in the Process class is unnecessary. There
is a member declaration inside of the Process class, waitList,
that uses the WaitRec definition. However, waitList is unused so
they are both dead bits of code. This changeset removes both the
WaitRec struct and waitList member from Process.
Change-Id: Ia6ee7488b9f47fd0f0ae29c818fba6ea0710699c
Reviewed-on: https://gem5-review.googlesource.com/2262
Reviewed-by: Tony Gutierrez <anthony.gutierrez@amd.com>
Reviewed-by: Michael LeBeane <Michael.Lebeane@amd.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
|
|
simulations
Modifies the clone system call and adds execve system call. Requires allowing
processes to steal thread contexts from other processes in the same system
object and the ability to detach pieces of process state (such as MemState)
to allow dynamic sharing.
|
|
This changeset add fields to the process object and adds the following
three system calls: setpgid, gettid, getpid.
|
|
This changeset adds functionality that allows system calls to retry without
affecting thread context state such as the program counter or register values
for the associated thread context (when system calls return with a retry
fault).
This functionality is needed to solve problems with blocking system calls
in multi-process or multi-threaded simulations where information is passed
between processes/threads. Blocking system calls can cause deadlock because
the simulator itself is single threaded. There is only a single thread
servicing the event queue which can cause deadlock if the thread hits a
blocking system call instruction.
To illustrate the problem, consider two processes using the producer/consumer
sharing model. The processes can use file descriptors and the read and write
calls to pass information to one another. If the consumer calls the blocking
read system call before the producer has produced anything, the call will
block the event queue (while executing the system call instruction) and
deadlock the simulation.
The solution implemented in this changeset is to recognize that the system
calls will block and then generate a special retry fault. The fault will
be sent back up through the function call chain until it is exposed to the
cpu model's pipeline where the fault becomes visible. The fault will trigger
the cpu model to replay the instruction at a future tick where the call has
a chance to succeed without actually going into a blocking state.
In subsequent patches, we recognize that a syscall will block by calling a
non-blocking poll (from inside the system call implementation) and checking
for events. When events show up during the poll, it signifies that the call
would not have blocked and the syscall is allowed to proceed (calling an
underlying host system call if necessary). If no events are returned from the
poll, we generate the fault and try the instruction for the thread context
at a distant tick. Note that retrying every tick is not efficient.
As an aside, the simulator has some multi-threading support for the event
queue, but it is not used by default and needs work. Even if the event queue
was completely multi-threaded, meaning that there is a hardware thread on
the host servicing a single simulator thread contexts with a 1:1 mapping
between them, it's still possible to run into deadlock due to the event queue
barriers on quantum boundaries. The solution of replaying at a later tick
is the simplest solution and solves the problem generally.
|
|
Several large changes happen in this patch.
The FDEntry class is rewritten so that file descriptors now correspond to
types: 'File' which is normal file-backed file with the file open on the
host machine, 'Pipe' which is a pipe that has been opened on the host machine,
and 'Device' which does not have an open file on the host yet acts as a pseudo
device with which to issue ioctls. Other types which might be added in the
future are directory entries and sockets (off the top of my head).
The FDArray class was create to hold most of the file descriptor handling
that was stuffed into the Process class. It uses shared pointers and
the std::array type to hold the FDEntries mentioned above.
The changes to these two classes needed to be propagated out to the rest
of the code so there were quite a few changes for that. Also, comments were
added where I thought they were needed to help others and extend our
DOxygen coverage.
|
|
Moves aux_vector into its own .hh and .cc files just to get it out of the
already crowded Process files. Arguably, it could stay there, but it's
probably better just to move it and give it files.
The changeset looks ugly around the Process header file, but the goal here is
to move methods and members around so that they're not defined randomly
throughout the entire header file. I expect this is likely one of the reasons
why I several unused variables related to this class. So, the methods are
declared first followed by members. I've tried to aggregate them together
so that similar entries reside near one another.
There are other changes coming to this code so this is by no means the
final product.
|
|
The numCpus method is misleading in that it's not really a measure of
how many CPUs might be executing a process, but how many thread contexts
are assigned to the process at any given point in time.
It's nice to highlight this distinction because thread contexts are never
reused in the same way that a CPU can be reused for multiple processes.
The reason that there is no reuse is that there is no CPU scheduler for SE.
The tru64 code intends to use this method and the accompanying contextIDs
field to support SMT and track the number of threads with some system calls.
With the up coming clone and exec patches, this paradigm must change. There
needs to be a 1:1 mapping between the thread contexts and processes so that
the process state between threads is allowed to vary when needed by Linux.
This should not break SMT for tru64 if the Process class is refactored so that
multiple Processes can share state between themselves. The following patches
will do the refactoring incrementally as features are added.
|
|
It looks like tru64 has some nxm* system calls, but the two fields that
are defined in the Process class are unused by any of the code. There doesn't
appear to be any reference in the tru64 code.
|
|
The EIOProcess class was removed recently and it was the only other class
which derived from Process. Since every Process invocation is also a
LiveProcess invocation, it makes sense to simplify the organization by
combining the fields from LiveProcess into Process.
|
|
|
|
Used cppclean to help identify useless includes and removed them. This
involved erroneously included headers, but also cases where forward
declarations could have been used rather than a full include.
|
|
The class was crammed into syscall_emul.hh which has tons of forward
declarations and template definitions. To clean it up a bit, moved the
class into separate files and commented the class with doxygen style
comments. Also, provided some encapsulation by adding some accessors and
a mutator.
The syscallreturn.hh file was renamed syscall_return.hh to make it consistent
with other similarly named files in the src/sim directory.
The DPRINTF_SYSCALL macro was moved into its own header file with the
include the Base and Verbose flags as well.
--HG--
rename : src/sim/syscallreturn.hh => src/sim/syscall_return.hh
|
|
Libraries are loaded into the process address space using the
mmap system call. Conveniently, this happens to be a good
time to update the process symbol table with the library's
incoming symbols so we handle the table update from within the
system call.
This works just like an application's normal symbols. The only
difference between a dynamic library and a main executable is
when the symbol table update occurs. The symbol table update for
an executable happens at program load time and is finished before
the process ever begins executing. Since dynamic linking happens
at runtime, the symbol loading happens after the library is
first loaded into the process address space. The library binary
is examined at this time for a symbol section and that section
is parsed for symbol types with specific bindings (global,
local, weak). Subsequently, these symbols are added to the table
and are available for use by gem5 for things like trace
generation.
Checkpointing should work just as it did previously. The address
space (and therefore the library) will be recorded and the symbol
table will be entirely recorded. (It's not possible to do anything
clever like checkpoint a program and then load the program back
with different libraries with LD_LIBRARY_PATH, because the
library becomes part of the address space after being loaded.)
|
|
|
|
The mmapGrowsDown() method was a static method on the OperatingSystem
class (and derived classes), which worked OK for the templated syscall
emulation methods, but made it hard to access elsewhere. This patch
moves the method to be a virtual function on the LiveProcess method,
where it can be overridden for specific platforms (for now, Alpha).
This patch also changes the value of mmapGrowsDown() from being false
by default and true only on X86Linux32 to being true by default and
false only on Alpha, which seems closer to reality (though in reality
most people use ASLR and this doesn't really matter anymore).
In the process, also got rid of the unused mmap_start field on
LiveProcess and OperatingSystem mmapGrowsUp variable.
|
|
This patch adds explicit overrides as this is now required when using
"-Wall" with clang >= 3.5, the latter now part of the most recent
XCode. The patch consequently removes "virtual" for those methods
where "override" is added. The latter should be enough of an
indication.
As part of this patch, a few minor issues that clang >= 3.5 complains
about are also resolved (unused methods and variables).
|
|
This patch moves away from using M5_ATTR_OVERRIDE and the m5::hashmap
(and similar) abstractions, as these are no longer needed with gcc 4.7
and clang 3.1 as minimum compiler versions.
|
|
The recent changeset to readlink() to handle reading the /proc/self/exe link
introduces a number of problems. This patch fixes two:
1) Because readlink() called on /proc/self/exe now uses LiveProcess::progName()
to find the binary path, it will only get the zeroth parameter of the simulated
system command line. However, if a config script also specifies the process'
executable, the executable parameter is used to create the LiveProcess rather
than the zeroth command line parameter. Thus, the zeroth command line parameter
is not necessarily the correct path to the binary executing in the simulated
system. To fix this, add a LiveProcess data member, 'executable', which is
correctly set during instantiation and returned from progName().
2) If a config script allows a user to pass a relative path as the zeroth
simulated system command line parameter or process executable, readlink() will
incorrecly return a relative path when called on '/proc/self/exe'.
/proc/self/exe is always set to a full path, so running benchmarks can fail if
a relative path is returned. To fix this, clean up the handling of
LiveProcess::progName() within readlink() to get the full binary path.
NOTE: This patch still leaves the potential problem that host full path to the
binary bleeds into the simulated system, potentially causing the appearance of
non-deterministic simulated system execution.
|
|
Context IDs used to be declared as ad hoc (usually as int). This
changeset introduces a typedef for ContextIDs and a constant for
invalid context IDs.
|
|
The Process class methods were using an improper style and this subsequently
bled into the system call code. The following regular expressions should be
helpful if someone transitions private system call patches on top of these
changesets:
s/alloc_fd/allocFD/
s/sim_fd(/simFD(/
s/sim_fd_obj/getFDEntry/
s/fix_file_offsets/fixFileOffsets/
s/find_file_offsets/findFileOffsets/
|
|
This patch extends the previous patch's alterations around fd_map. It cleans
up some of the uglier code in the process file and replaces it with a more
concise C++11 version. As part of the changes, the FdMap class is pulled out
of the Process class and receives its own file.
|
|
This patch gets rid of unused Process::dup_fd method and does minor
refactoring in the process class files. The file descriptor max has been
changed to be the number of file descriptors since this clarifies the loop
boundary condition and cleans up the code a bit. The fd_map field has been
altered to be dynamically allocated as opposed to being an array; the
intention here is to build on this is subsequent patches to allow processes
to share their file descriptors with the clone system call.
|
|
The drain() call currently passes around a DrainManager pointer, which
is now completely pointless since there is only ever one global
DrainManager in the system. It also contains vestiges from the time
when SimObjects had to keep track of their child objects that needed
draining.
This changeset moves all of the DrainState handling to the Drainable
base class and changes the drain() and drainResume() calls to reflect
this. Particularly, the drain() call has been updated to take no
parameters (the DrainManager argument isn't needed) and return a
DrainState instead of an unsigned integer (there is no point returning
anything other than 0 or 1 any more). Drainable objects should return
either DrainState::Draining (equivalent to returning 1 in the old
system) if they need more time to drain or DrainState::Drained
(equivalent to returning 0 in the old system) if they are already in a
consistent state. Returning DrainState::Running is considered an
error.
Drain done signalling is now done through the signalDrainDone() method
in the Drainable class instead of using the DrainManager directly. The
new call checks if the state of the object is DrainState::Draining
before notifying the drain manager. This means that it is safe to call
signalDrainDone() without first checking if the simulator has
requested draining. The intention here is to reduce the code needed to
implement draining in simple objects.
|
|
Objects that are can be serialized are supposed to inherit from the
Serializable class. This class is meant to provide a unified API for
such objects. However, so far it has mainly been used by SimObjects
due to some fundamental design limitations. This changeset redesigns
to the serialization interface to make it more generic and hide the
underlying checkpoint storage. Specifically:
* Add a set of APIs to serialize into a subsection of the current
object. Previously, objects that needed this functionality would
use ad-hoc solutions using nameOut() and section name
generation. In the new world, an object that implements the
interface has the methods serializeSection() and
unserializeSection() that serialize into a named /subsection/ of
the current object. Calling serialize() serializes an object into
the current section.
* Move the name() method from Serializable to SimObject as it is no
longer needed for serialization. The fully qualified section name
is generated by the main serialization code on the fly as objects
serialize sub-objects.
* Add a scoped ScopedCheckpointSection helper class. Some objects
need to serialize data structures, that are not deriving from
Serializable, into subsections. Previously, this was done using
nameOut() and manual section name generation. To simplify this,
this changeset introduces a ScopedCheckpointSection() helper
class. When this class is instantiated, it adds a new /subsection/
and subsequent serialization calls during the lifetime of this
helper class happen inside this section (or a subsection in case
of nested sections).
* The serialize() call is now const which prevents accidental state
manipulation during serialization. Objects that rely on modifying
state can use the serializeOld() call instead. The default
implementation simply calls serialize(). Note: The old-style calls
need to be explicitly called using the
serializeOld()/serializeSectionOld() style APIs. These are used by
default when serializing SimObjects.
* Both the input and output checkpoints now use their own named
types. This hides underlying checkpoint implementation from
objects that need checkpointing and makes it easier to change the
underlying checkpoint storage code.
|
|
The filenames are initialized with NULL. So the test should be
checking for them to be == NULL instead == None.
|
|
This patch adds uncacheable/cacheable and read-only/read-write attributes to
the map method of PageTableBase. It also modifies the constructor of TlbEntry
structs for all architectures to consider the new attributes.
|
|
This patch sets up low and high privilege code and data segments and places them
in the following order: cs low, ds low, ds, cs, in the GDT. Additionally, a
syscall and page fault handler for KvmCPU in SE mode are defined. The order of
the segment selectors in GDT is required in this manner for interrupt handling
to work properly. Segment initialization is done for all the thread
contexts.
|
|
Fake SE-mode device drivers can now be added by
deriving from this abstract object.
|
|
This patch enables the use of page tables that are stored in system memory
and respect x86 specification, in SE mode. It defines an architectural
page table for x86 as a MultiLevelPageTable class and puts a placeholder
class for other ISAs page tables, giving the possibility for future
implementation.
|
|
This patch defines a multi-level page table class that stores the page table in
system memory, consistent with ISA specifications. In this way, cpu models that
use the actual hardware to execute (e.g. KvmCPU), are able to traverse the page
table.
|
|
This replaces a (potentially uninitialized) string
field with a virtual function so that we can have
a safe interface without requiring changes to the
eio code.
|
|
This enables configuration scripts to set up mappings
from process virtual addresses to specific physical
addresses in SE mode. This feature is needed to
support modeling of user-accessible memories or
devices in SE mode, avoiding the complexities of FS
mode and the need to write a device driver.
|
|
This patch is adding a clearer design intent to all objects that would
not be complete without a port proxy by making the proxies members
rathen than dynamically allocated. In essence, if NULL would not be a
valid value for the proxy, then we avoid using a pointer to make this
clear.
The same approach is used for the methods using these proxies, such as
loadSections, that now use references rather than pointers to better
reflect the fact that NULL would not be an acceptable value (in fact
the code would break and that is how this patch started out).
Overall the concept of "using a reference to express unconditional
composition where a NULL pointer is never valid" could be done on a
much broader scale throughout the code base, but for now it is only
done in the locations affected by the proxies.
|
|
|
|
This patch adds the necessary flags to the SConstruct and SConscript
files for compiling using clang 2.9 and later (on Ubuntu et al and OSX
XCode 4.2), and also cleans up a bunch of compiler warnings found by
clang. Most of the warnings are related to hidden virtual functions,
comparisons with unsigneds >= 0, and if-statements with empty
bodies. A number of mismatches between struct and class are also
fixed. clang 2.8 is not working as it has problems with class names
that occur in multiple namespaces (e.g. Statistics in
kernel_stats.hh).
clang has a bug (http://llvm.org/bugs/show_bug.cgi?id=7247) which
causes confusion between the container std::set and the function
Packet::set, and this is currently addressed by not including the
entire namespace std, but rather selecting e.g. "using std::vector" in
the appropriate places.
|
|
--HG--
rename : src/mem/vport.hh => src/mem/fs_translating_port_proxy.hh
rename : src/mem/translating_port.cc => src/mem/se_translating_port_proxy.cc
rename : src/mem/translating_port.hh => src/mem/se_translating_port_proxy.hh
|
|
Port proxies are used to replace non-structural ports, and thus enable
all ports in the system to correspond to a structural entity. This has
the advantage of accessing memory through the normal memory subsystem
and thus allowing any constellation of distributed memories, address
maps, etc. Most accesses are done through the "system port" that is
used for loading binaries, debugging etc. For the entities that belong
to the CPU, e.g. threads and thread contexts, they wrap the CPU data
port in a port proxy.
The following replacements are made:
FunctionalPort > PortProxy
TranslatingPort > SETranslatingPortProxy
VirtualPort > FSTranslatingPortProxy
--HG--
rename : src/mem/vport.cc => src/mem/fs_translating_port_proxy.cc
rename : src/mem/vport.hh => src/mem/fs_translating_port_proxy.hh
rename : src/mem/translating_port.cc => src/mem/se_translating_port_proxy.cc
rename : src/mem/translating_port.hh => src/mem/se_translating_port_proxy.hh
|
|
|
|
|
|
PageTable supported an allocate() call that called back
through the Process to allocate memory, but did not have
a method to map addresses without allocating new pages.
It makes more sense for Process to do the allocation, so
this method was renamed allocateMem() and moved to Process,
and uses a new map() call on PageTable.
The remaining uses of the process pointer in PageTable
were only to get the name and the PID, so by passing these
in directly in the constructor, we can make PageTable
completely independent of Process.
|
|
Do some minor cleanup of some recently added comments, a warning, and change
other instances of stack extension to be like what's now being done for x86.
|
|
|
|
Replace direct call to unserialize() on each SimObject with a pair of
calls for better control over initialization in both ckpt and non-ckpt
cases.
If restoring from a checkpoint, loadState(ckpt) is called on each
SimObject. The default implementation simply calls unserialize() if
there is a corresponding checkpoint section, so we get backward
compatibility for existing objects. However, objects can override
loadState() to get other behaviors, e.g., doing other programmed
initializations after unserialize(), or complaining if no checkpoint
section is found. (Note that the default warning for a missing
checkpoint section is now gone.)
If not restoring from a checkpoint, we call the new initState() method
on each SimObject instead. This provides a hook for state
initializations that are only required when *not* restoring from a
checkpoint.
Given this new framework, do some cleanup of LiveProcess subclasses
and X86System, which were (in some cases) emulating initState()
behavior in startup via a local flag or (in other cases) erroneously
doing initializations in startup() that clobbered state loaded earlier
by unserialize().
|
|
|