#include <ros/memlayout.h>
#include <ros/syscall.h>
#include <ros/sysevent.h>
-#include <ros/error.h>
+#include <ros/procinfo.h>
+#include <error.h>
#include <ros/procdata.h>
+#include <ros/procinfo.h>
#include <ros/resource.h>
-#include <arch/trap.h>
+#include <trap.h>
#include <ros/common.h>
#include <arch/arch.h>
#include <sys/queue.h>
+#include <atomic.h>
+#include <mm.h>
+#include <vfs.h>
+#include <schedule.h>
+#include <devalarm.h>
+#include <ns.h>
-struct Env;
-typedef struct Env env_t;
-
-// An environment ID 'envid_t' has three parts:
-//
-// +1+---------------21-----------------+--------10--------+
-// |0| Uniqueifier | Environment |
-// | | | Index |
-// +------------------------------------+------------------+
-// \--- ENVX(eid) --/
-//
-// The environment index ENVX(eid) equals the environment's offset in the
-// 'envs[]' array. The uniqueifier distinguishes environments that were
-// created at different times, but share the same environment index.
-//
-// All real environments are greater than 0 (so the sign bit is zero).
-// envid_ts less than 0 signify errors. The envid_t == 0 is special, and
-// stands for the current environment.
-
-typedef int32_t envid_t;
-
-#define LOG2NENV 10
-#define NENV (1 << LOG2NENV)
-#define ENVX(envid) ((envid) & (NENV - 1))
+TAILQ_HEAD(vcore_tailq, vcore);
+/* 'struct proc_list' declared in sched.h (not ideal...) */
// TODO: clean this up.
-struct Env {
- TAILQ_ENTRY(Env) proc_link NOINIT; // Free list link pointers
+struct proc {
+ TAILQ_ENTRY(proc) proc_arsc_link;
+ TAILQ_ENTRY(proc) sibling_link;
spinlock_t proc_lock;
- trapframe_t env_tf; // Saved registers
- ancillary_state_t env_ancillary_state; // State saved when descheduled
- envid_t env_id; // Unique environment identifier
- envid_t env_parent_id; // env_id of this env's parent
+ struct user_context scp_ctx; /* context for an SCP. TODO: move to vc0 */
+ char user[64]; /* user name */
+ pid_t pid;
+ /* Tempting to add a struct proc *parent, but we'd need to protect the use
+ * of that reference from concurrent parent-death (letting init inherit
+ * children, etc), which is basically what we do when we do pid2proc. If we
+ * do add *parent, it'll be a weak ref, and you'll need to lock the child to
+ * kref_get or to remove the pointer. */
+ pid_t ppid; /* parent's pid, not a reference */
+ struct proc_list children; /* protected by the proc lock for now */
+ int exitcode; /* exit() param or main() return value */
+ struct cond_var child_wait; /* signal for dying or o/w waitable child */
uint32_t state; // Status of the process
- uint32_t env_runs; // Number of times environment has run
- uint32_t env_refcnt; // Reference count of kernel contexts using this
+ struct kref p_kref; /* Refcnt */
uint32_t env_flags;
- uint32_t env_entry;
- /* Virtual coremap: each index is the virtual core id, the contents at that
- * index is the physical core_id() corresponding to the vcore. -1 means it
- * is unused */
- int32_t vcoremap[MAX_NUM_CPUS];
- uint32_t num_vcores;
+ uintptr_t env_entry;
+ /* Lists of vcores */
+ struct vcore_tailq online_vcs;
+ struct vcore_tailq bulk_preempted_vcs;
+ struct vcore_tailq inactive_vcs;
+ /* Scheduler mgmt (info, data, whatever) */
+ struct sched_proc_data ksched_data;
/* Cache color map: bitmap of the cache colors currently allocated to this
* process */
uint8_t* cache_colors_map;
size_t next_cache_color;
- /* Info about this process's resources (granted, desired) for each type. */
- struct resource resources[MAX_NUM_RESOURCES];
-
/* Keeps track of this process's current memory allocation
* (i.e. its heap pointer) */
- void* end_text_segment;
- void* end_data_segment;
+ void* heap_top;
// Address space
pde_t *COUNT(NPDENTRIES) env_pgdir; // Kernel virtual address of page dir
physaddr_t env_cr3; // Physical address of page dir
-// struct memregion_list memregions;
+ spinlock_t mm_lock; /* Protects page tables and VMRs (mem mgmt) */
+ struct vmr_tailq vm_regions;
// Per process info and data pages
- procinfo_t *SAFE env_procinfo; // KVA of per-process shared info table (RO)
- procdata_t *SAFE env_procdata; // KVA of per-process shared data table (RW)
+ procinfo_t *SAFE procinfo; // KVA of per-process shared info table (RO)
+ procdata_t *SAFE procdata; // KVA of per-process shared data table (RW)
// The backring pointers for processing asynchronous system calls from the user
// Note this is the actual backring, not a pointer to it somewhere else
// The front ring pointers for pushing asynchronous system events out to the user
// Note this is the actual frontring, not a pointer to it somewhere else
sysevent_front_ring_t syseventfrontring;
+
+ /* Filesystem info */
+ struct namespace *ns;
+ struct fs_struct fs_env;
+ struct files_struct open_files;
+ struct pgrp *pgrp;
+
+ /* UCQ hashlocks */
+ struct hashlock *ucq_hashlock;
+ struct small_hashlock ucq_hl_noref; /* don't reference directly */
+ /* For devalarm */
+ struct proc_alarm_set alarmset;
+ struct cv_lookup_tailq abortable_sleepers;
+ spinlock_t abort_list_lock;
};
+/* Til we remove all Env references */
+#define Env proc
+typedef struct proc env_t;
+
/* Process Flags */
-// None yet
+#define PROC_TRANSITION_TO_M 0x0001
-extern env_t *CT(NENV) RO envs; // All environments
extern atomic_t num_envs; // Number of envs
-// TODO: consider moving this to struct per_cpu_info
-extern env_t * (RO curenvs)[MAX_NUM_CPUS];
-
-static inline env_t *
-get_cpu_curenv() TRUSTED
-{
- return curenvs[core_id()];
-}
-
-static inline void
-set_cpu_curenv(env_t *p) TRUSTED
-{
- curenvs[core_id()] = p;
-}
-
-void env_init(void);
-int env_alloc(env_t *SAFE*SAFE e, envid_t parent_id);
-void env_push_ancillary_state(env_t* e);
-void env_pop_ancillary_state(env_t* e);
-void env_free(env_t *SAFE e);
-void env_user_mem_free(env_t* e);
-void env_segment_alloc(env_t *e, void *SNT va, size_t len);
-void env_segment_free(env_t *e, void *SNT va, size_t len);
-env_t* env_create(uint8_t *COUNT(size) binary, size_t size);
-
-/*
- * Allows the kernel to figure out what process is running on its core.
- * Can be used just like a pointer to a struct process.
- */
-#define current (get_cpu_curenv())
-//#define current (curenvs[core_id()])
-
-int envid2env(envid_t envid, env_t **env_store, bool checkperm);
-// The following three functions do not return
-void env_pop_tf(trapframe_t *tf) __attribute__((noreturn));
-
-
-/* Helper handler for smp_call to dispatch jobs to other cores */
-#ifdef __IVY__
-void run_env_handler(trapframe_t *tf, env_t * data);
-#else
-void run_env_handler(trapframe_t *tf, void * data);
-#endif
+
+int env_setup_vm(env_t *e);
+void env_user_mem_free(env_t* e, void* start, size_t len);
+void env_pagetable_free(env_t* e);
+
+typedef int (*mem_walk_callback_t)(env_t* e, pte_t* pte, void* va, void* arg);
+int env_user_mem_walk(env_t* e, void* start, size_t len, mem_walk_callback_t callback, void* arg);
#endif // !ROS_KERN_ENV_H