提交 723157a5 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

pass syscall args as function args, instead of fishing them out of trapframe

上级 233d2d46
...@@ -17,29 +17,31 @@ void swtch(struct context**, struct context*); ...@@ -17,29 +17,31 @@ void swtch(struct context**, struct context*);
extern struct segdesc bootgdt[NSEGS]; extern struct segdesc bootgdt[NSEGS];
// syscalls // syscalls
long sys_chdir(void); struct stat;
long sys_close(void);
long sys_dup(void); long sys_chdir(const char*);
long sys_exec(void); long sys_close(int);
long sys_dup(int);
long sys_exec(const char*, u64);
long sys_exit(void); long sys_exit(void);
long sys_fork(void); long sys_fork(int);
long sys_fstat(void); long sys_fstat(int, struct stat*);
long sys_getpid(void); long sys_getpid(void);
long sys_kill(void); long sys_kill(int);
long sys_link(void); long sys_link(const char*, const char*);
long sys_mkdir(void); long sys_mkdir(const char*);
long sys_mknod(void); long sys_mknod(const char*, int, int);
long sys_open(void); long sys_open(const char*, int);
long sys_pipe(void); long sys_pipe(int*);
long sys_read(void); long sys_read(int, char*, int);
long sys_sbrk(void); long sys_sbrk(int);
long sys_sleep(void); long sys_sleep(int);
long sys_unlink(void); long sys_unlink(const char*);
long sys_wait(void); long sys_wait(void);
long sys_write(void); long sys_write(int, char*, int);
long sys_uptime(void); long sys_uptime(void);
long sys_map(void); long sys_map(uptr, u64);
long sys_unmap(void); long sys_unmap(uptr, u64);
long sys_halt(void); long sys_halt(void);
long sys_socket(int, int, int); long sys_socket(int, int, int);
long sys_bind(int, void*, int); long sys_bind(int, void*, int);
...@@ -48,7 +50,7 @@ long sys_accept(int, void*, void*); ...@@ -48,7 +50,7 @@ long sys_accept(int, void*, void*);
long sys_pread(int fd, void *ubuf, size_t count, off_t offset); long sys_pread(int fd, void *ubuf, size_t count, off_t offset);
long sys_async(int, size_t, off_t, u32, u32); long sys_async(int, size_t, off_t, u32, u32);
long sys_script(void *addr, u64 len, u64 chunk); long sys_script(void *addr, u64 len, u64 chunk);
extern long (*syscalls[])(u64, u64, u64, u64, u64, u64); extern long (*syscalls[])(u64, u64, u64, u64, u64);
// other exported/imported functions // other exported/imported functions
void cmain(u64 mbmagic, u64 mbaddr); void cmain(u64 mbmagic, u64 mbaddr);
...@@ -60,4 +62,4 @@ void threadhelper(void (*fn)(void *), void *arg); ...@@ -60,4 +62,4 @@ void threadhelper(void (*fn)(void *), void *arg);
struct trapframe; struct trapframe;
void trap(struct trapframe *tf); void trap(struct trapframe *tf);
void sysentry(void); void sysentry(void);
void sysentry_c(void); u64 sysentry_c(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num);
...@@ -84,7 +84,7 @@ int e1000tx(void *buf, u32 len); ...@@ -84,7 +84,7 @@ int e1000tx(void *buf, u32 len);
void e1000hwaddr(u8 *hwaddr); void e1000hwaddr(u8 *hwaddr);
// exec.c // exec.c
int exec(char*, char**); int exec(const char*, char**);
// file.c // file.c
struct file* filealloc(void); struct file* filealloc(void);
...@@ -110,7 +110,7 @@ int readi(struct inode*, char*, u32, u32); ...@@ -110,7 +110,7 @@ int readi(struct inode*, char*, u32, u32);
void stati(struct inode*, struct stat*); void stati(struct inode*, struct stat*);
int writei(struct inode*, char*, u32, u32); int writei(struct inode*, char*, u32, u32);
struct inode* idup(struct inode*); struct inode* idup(struct inode*);
struct inode* nameiparent(char*, char*); struct inode* nameiparent(const char*, char*);
int dirlink(struct inode*, const char*, u32); int dirlink(struct inode*, const char*, u32);
void dir_init(struct inode *dp); void dir_init(struct inode *dp);
void dir_flush(struct inode *dp); void dir_flush(struct inode *dp);
...@@ -210,15 +210,12 @@ void destroylock(struct spinlock *lk); ...@@ -210,15 +210,12 @@ void destroylock(struct spinlock *lk);
void release(struct spinlock*); void release(struct spinlock*);
// syscall.c // syscall.c
int argint64(int, u64*); int argcheckptr(void *argval, int);
int argint32(int n, int *ip); int argcheckstr(const char*);
int argptr(int, char**, int);
int argstr(int, char**);
int fetchint64(uptr, u64*); int fetchint64(uptr, u64*);
int fetchstr(uptr, char**);
int umemcpy(void*, void*, u64); int umemcpy(void*, void*, u64);
int kmemcpy(void*, void*, u64); int kmemcpy(void*, void*, u64);
void syscall(void); u64 syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num);
// string.c // string.c
extern "C" int memcmp(const void*, const void*, u32); extern "C" int memcmp(const void*, const void*, u32);
...@@ -304,39 +301,6 @@ void initsched(void); ...@@ -304,39 +301,6 @@ void initsched(void);
void initlockstat(void); void initlockstat(void);
void initwq(void); void initwq(void);
// syscalls
long sys_chdir(void);
long sys_close(void);
long sys_dup(void);
long sys_exec(void);
long sys_exit(void);
long sys_fork(void);
long sys_fstat(void);
long sys_getpid(void);
long sys_kill(void);
long sys_link(void);
long sys_mkdir(void);
long sys_mknod(void);
long sys_open(void);
long sys_pipe(void);
long sys_read(void);
long sys_sbrk(void);
long sys_sleep(void);
long sys_unlink(void);
long sys_wait(void);
long sys_write(void);
long sys_uptime(void);
long sys_map(void);
long sys_unmap(void);
long sys_halt(void);
long sys_socket(int, int, int);
long sys_bind(int, void*, int);
long sys_listen(int, int);
long sys_accept(int, void*, void*);
long sys_pread(int fd, void *ubuf, size_t count, off_t offset);
long sys_async(int, size_t, off_t, u32, u32);
extern long (*syscalls[])(u64, u64, u64, u64, u64, u64);
// other exported/imported functions // other exported/imported functions
void cmain(u64 mbmagic, u64 mbaddr); void cmain(u64 mbmagic, u64 mbaddr);
void mpboot(void); void mpboot(void);
......
...@@ -28,7 +28,7 @@ struct segdesc __attribute__((aligned(16))) bootgdt[NSEGS] = { ...@@ -28,7 +28,7 @@ struct segdesc __attribute__((aligned(16))) bootgdt[NSEGS] = {
#define SYSCALL(name) [SYS_##name] = (void*)sys_##name #define SYSCALL(name) [SYS_##name] = (void*)sys_##name
long (*syscalls[])(u64, u64, u64, u64, u64, u64) = { long (*syscalls[])(u64, u64, u64, u64, u64) = {
SYSCALL(chdir), SYSCALL(chdir),
SYSCALL(close), SYSCALL(close),
SYSCALL(dup), SYSCALL(dup),
......
...@@ -24,7 +24,7 @@ struct eargs { ...@@ -24,7 +24,7 @@ struct eargs {
struct proc *proc; struct proc *proc;
struct inode *ip; struct inode *ip;
struct vmap *vmap; struct vmap *vmap;
char *path; const char *path;
char **argv; char **argv;
}; };
...@@ -76,7 +76,7 @@ static void dostack(uptr a0, u64 a1) ...@@ -76,7 +76,7 @@ static void dostack(uptr a0, u64 a1)
int argc; int argc;
uptr sp; uptr sp;
uptr ustack[1+MAXARG+1]; uptr ustack[1+MAXARG+1];
char *s, *last; const char *s, *last;
prof_start(dostack_prof); prof_start(dostack_prof);
// Allocate a one-page stack at the top of the (user) address space // Allocate a one-page stack at the top of the (user) address space
...@@ -143,7 +143,7 @@ bad: ...@@ -143,7 +143,7 @@ bad:
} }
int int
exec(char *path, char **argv) exec(const char *path, char **argv)
{ {
struct inode *ip = NULL; struct inode *ip = NULL;
struct vmap *vmp = NULL; struct vmap *vmp = NULL;
......
...@@ -795,7 +795,7 @@ namei(const char *path) ...@@ -795,7 +795,7 @@ namei(const char *path)
} }
struct inode* struct inode*
nameiparent(char *path, char *name) nameiparent(const char *path, char *name)
{ {
return namex(path, 1, name); return namex(path, 1, name);
} }
......
...@@ -32,84 +32,33 @@ fetchint64(uptr addr, u64 *ip) ...@@ -32,84 +32,33 @@ fetchint64(uptr addr, u64 *ip)
// Doesn't actually copy the string - just sets *pp to point at it. // Doesn't actually copy the string - just sets *pp to point at it.
// Returns length of string, not including nul. // Returns length of string, not including nul.
int int
fetchstr(uptr addr, char **pp) argcheckstr(const char *addr)
{ {
char *s = (char *) addr; const char *s = addr;
while(1){ while(1){
if(pagefault(myproc()->vmap, (uptr) s, 0) < 0) if(pagefault(myproc()->vmap, (uptr) s, 0) < 0)
return -1; return -1;
if(*s == 0){ if(*s == 0)
*pp = (char*)addr; return s - addr;
return s - *pp;
}
s++; s++;
} }
return -1; return -1;
} }
// Fetch the nth 64-bit system call argument.
int
argint64(int n, u64 *ip)
{
switch(n) {
case 0: *ip = myproc()->tf->rdi; break;
case 1: *ip = myproc()->tf->rsi; break;
case 2: *ip = myproc()->tf->rdx; break;
case 3: *ip = myproc()->tf->rcx; break;
case 4: *ip = myproc()->tf->r8; break;
// r9 is corrupted by sysentry
// case 5: *ip = myproc()->tf->r9; break;
default:
cprintf("argint64: bad arg %d\n", n);
return -1;
}
return 0;
}
int
argint32(int n, int *ip)
{
int r;
u64 i;
r = argint64(n, &i);
if (r >= 0)
*ip = i;
return r;
}
// Fetch the nth word-sized system call argument as a pointer // Fetch the nth word-sized system call argument as a pointer
// to a block of memory of size n bytes. Check that the pointer // to a block of memory of size n bytes. Check that the pointer
// lies within the process address space. // lies within the process address space.
int int
argptr(int n, char **pp, int size) argcheckptr(void *p, int size)
{ {
u64 i; u64 i = (u64) p;
if(argint64(n, &i) < 0)
return -1;
for(uptr va = PGROUNDDOWN(i); va < i+size; va = va + PGSIZE) for(uptr va = PGROUNDDOWN(i); va < i+size; va = va + PGSIZE)
if(pagefault(myproc()->vmap, va, 0) < 0) if(pagefault(myproc()->vmap, va, 0) < 0)
return -1; return -1;
*pp = (char*)i;
return 0; return 0;
} }
// Fetch the nth word-sized system call argument as a string pointer.
// Check that the pointer is valid and the string is nul-terminated.
// (There is no shared writable memory, so the string can't change
// between this check and being used by the kernel.)
int
argstr(int n, char **pp)
{
uptr addr;
if(argint64(n, &addr) < 0)
return -1;
return fetchstr(addr, pp);
}
static int static int
umemptr(void *umem, void **ret, u64 size) umemptr(void *umem, void **ret, u64 size)
{ {
...@@ -147,24 +96,22 @@ kmemcpy(void *umem, void *src, u64 size) ...@@ -147,24 +96,22 @@ kmemcpy(void *umem, void *src, u64 size)
return 0; return 0;
} }
void u64
syscall(void) syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
{ {
struct trapframe *tf; u64 r;
int num;
tf = myproc()->tf; if(num < SYS_ncount && syscalls[num]) {
num = tf->rax;
if(num >= 0 && num < SYS_ncount && syscalls[num]) {
mtstart(syscalls[num], myproc()); mtstart(syscalls[num], myproc());
mtrec(); mtrec();
tf->rax = syscalls[num](tf->rdi, tf->rsi, tf->rdx, r = syscalls[num](a0, a1, a2, a3, a4);
tf->rcx, tf->r8, tf->r9);
mtstop(myproc()); mtstop(myproc());
mtign(); mtign();
} else { } else {
cprintf("%d %s: unknown sys call %d\n", cprintf("%d %s: unknown sys call %ld\n",
myproc()->pid, myproc()->name, num); myproc()->pid, myproc()->name, num);
tf->rax = -1; r = -1;
} }
return r;
} }
...@@ -15,17 +15,12 @@ ...@@ -15,17 +15,12 @@
// Fetch the nth word-sized system call argument as a file descriptor // Fetch the nth word-sized system call argument as a file descriptor
// and return both the descriptor and the corresponding struct file. // and return both the descriptor and the corresponding struct file.
static int static int
argfd(int n, int *pfd, struct file **pf) argfd(int fd, struct file **pf)
{ {
int fd;
struct file *f; struct file *f;
if(argint32(n, &fd) < 0)
return -1;
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0) if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
return -1; return -1;
if(pfd)
*pfd = fd;
if(pf) if(pf)
*pf = f; *pf = f;
return 0; return 0;
...@@ -48,12 +43,12 @@ fdalloc(struct file *f) ...@@ -48,12 +43,12 @@ fdalloc(struct file *f)
} }
long long
sys_dup(void) sys_dup(int ofd)
{ {
struct file *f; struct file *f;
int fd; int fd;
if(argfd(0, 0, &f) < 0) if(argfd(ofd, &f) < 0)
return -1; return -1;
if((fd=fdalloc(f)) < 0) if((fd=fdalloc(f)) < 0)
return -1; return -1;
...@@ -62,13 +57,11 @@ sys_dup(void) ...@@ -62,13 +57,11 @@ sys_dup(void)
} }
s64 s64
sys_read(void) sys_read(int fd, char *p, int n)
{ {
struct file *f; struct file *f;
int n;
char *p;
if(argfd(0, 0, &f) < 0 || argint32(2, &n) < 0 || argptr(1, &p, n) < 0) if(argfd(fd, &f) < 0 || argcheckptr(p, n) < 0)
return -1; return -1;
return fileread(f, p, n); return fileread(f, p, n);
} }
...@@ -99,24 +92,21 @@ sys_pread(int fd, void *ubuf, size_t count, off_t offset) ...@@ -99,24 +92,21 @@ sys_pread(int fd, void *ubuf, size_t count, off_t offset)
} }
long long
sys_write(void) sys_write(int fd, char *p, int n)
{ {
struct file *f; struct file *f;
int n;
char *p;
if(argfd(0, 0, &f) < 0 || argint32(2, &n) < 0 || argptr(1, &p, n) < 0) if(argfd(fd, &f) < 0 || argcheckptr(p, n) < 0)
return -1; return -1;
return filewrite(f, p, n); return filewrite(f, p, n);
} }
long long
sys_close(void) sys_close(int fd)
{ {
int fd;
struct file *f; struct file *f;
if(argfd(0, &fd, &f) < 0) if(argfd(fd, &f) < 0)
return -1; return -1;
myproc()->ofile[fd] = 0; myproc()->ofile[fd] = 0;
fileclose(f); fileclose(f);
...@@ -124,24 +114,23 @@ sys_close(void) ...@@ -124,24 +114,23 @@ sys_close(void)
} }
long long
sys_fstat(void) sys_fstat(int fd, struct stat *st)
{ {
struct file *f; struct file *f;
struct stat *st;
if(argfd(0, 0, &f) < 0 || argptr(1, (char**)&st, sizeof(*st)) < 0) if(argfd(fd, &f) < 0 || argcheckptr(st, sizeof(*st)) < 0)
return -1; return -1;
return filestat(f, st); return filestat(f, st);
} }
// Create the path new as a link to the same inode as old. // Create the path new as a link to the same inode as old.
long long
sys_link(void) sys_link(const char *old, const char *newn)
{ {
char name[DIRSIZ], *newn, *old; char name[DIRSIZ];
struct inode *dp, *ip; struct inode *dp, *ip;
if(argstr(0, &old) < 0 || argstr(1, &newn) < 0) if(argcheckstr(old) < 0 || argcheckstr(newn) < 0)
return -1; return -1;
if((ip = namei(old)) == 0) if((ip = namei(old)) == 0)
return -1; return -1;
...@@ -189,12 +178,12 @@ isdirempty(struct inode *dp) ...@@ -189,12 +178,12 @@ isdirempty(struct inode *dp)
} }
long long
sys_unlink(void) sys_unlink(const char *path)
{ {
struct inode *ip, *dp; struct inode *ip, *dp;
char name[DIRSIZ], *path; char name[DIRSIZ];
if(argstr(0, &path) < 0) if(argcheckstr(path) < 0)
return -1; return -1;
if((dp = nameiparent(path, name)) == 0) if((dp = nameiparent(path, name)) == 0)
return -1; return -1;
...@@ -245,7 +234,7 @@ sys_unlink(void) ...@@ -245,7 +234,7 @@ sys_unlink(void)
} }
static struct inode* static struct inode*
create(char *path, short type, short major, short minor) create(const char *path, short type, short major, short minor)
{ {
struct inode *ip, *dp; struct inode *ip, *dp;
char name[DIRSIZ]; char name[DIRSIZ];
...@@ -295,14 +284,13 @@ create(char *path, short type, short major, short minor) ...@@ -295,14 +284,13 @@ create(char *path, short type, short major, short minor)
} }
long long
sys_open(void) sys_open(const char *path, int omode)
{ {
char *path; int fd;
int fd, omode;
struct file *f; struct file *f;
struct inode *ip; struct inode *ip;
if(argstr(0, &path) < 0 || argint32(1, &omode) < 0) if(argcheckstr(path) < 0)
return -1; return -1;
if(omode & O_CREATE){ if(omode & O_CREATE){
if((ip = create(path, T_FILE, 0, 0)) == 0) if((ip = create(path, T_FILE, 0, 0)) == 0)
...@@ -343,28 +331,23 @@ sys_open(void) ...@@ -343,28 +331,23 @@ sys_open(void)
} }
long long
sys_mkdir(void) sys_mkdir(const char *path)
{ {
char *path;
struct inode *ip; struct inode *ip;
if(argstr(0, &path) < 0 || (ip = create(path, T_DIR, 0, 0)) == 0) if(argcheckstr(path) < 0 || (ip = create(path, T_DIR, 0, 0)) == 0)
return -1; return -1;
iunlockput(ip); iunlockput(ip);
return 0; return 0;
} }
long long
sys_mknod(void) sys_mknod(const char *path, int major, int minor)
{ {
struct inode *ip; struct inode *ip;
char *path;
int len; int len;
int major, minor;
if((len=argstr(0, &path)) < 0 || if((len=argcheckstr(path)) < 0 ||
argint32(1, &major) < 0 ||
argint32(2, &minor) < 0 ||
(ip = create(path, T_DEV, major, minor)) == 0) (ip = create(path, T_DEV, major, minor)) == 0)
return -1; return -1;
iunlockput(ip); iunlockput(ip);
...@@ -372,12 +355,11 @@ sys_mknod(void) ...@@ -372,12 +355,11 @@ sys_mknod(void)
} }
long long
sys_chdir(void) sys_chdir(const char *path)
{ {
char *path;
struct inode *ip; struct inode *ip;
if(argstr(0, &path) < 0 || (ip = namei(path)) == 0) if(argcheckstr(path) < 0 || (ip = namei(path)) == 0)
return -1; return -1;
ilock(ip, 0); ilock(ip, 0);
if(ip->type != T_DIR){ if(ip->type != T_DIR){
...@@ -391,14 +373,13 @@ sys_chdir(void) ...@@ -391,14 +373,13 @@ sys_chdir(void)
} }
long long
sys_exec(void) sys_exec(const char *path, u64 uargv)
{ {
char *path, *argv[MAXARG]; char *argv[MAXARG];
int i; int i;
uptr uargv;
u64 uarg; u64 uarg;
if(argstr(0, &path) < 0 || argint64(1, &uargv) < 0){ if(argcheckstr(path) < 0) {
return -1; return -1;
} }
memset(argv, 0, sizeof(argv)); memset(argv, 0, sizeof(argv));
...@@ -411,20 +392,20 @@ sys_exec(void) ...@@ -411,20 +392,20 @@ sys_exec(void)
argv[i] = 0; argv[i] = 0;
break; break;
} }
if(fetchstr(uarg, &argv[i]) < 0) argv[i] = (char*) uarg;
if(argcheckstr(argv[i]) < 0)
return -1; return -1;
} }
return exec(path, argv); return exec(path, argv);
} }
long long
sys_pipe(void) sys_pipe(int *fd)
{ {
int *fd;
struct file *rf, *wf; struct file *rf, *wf;
int fd0, fd1; int fd0, fd1;
if(argptr(0, (char**)&fd, 2*sizeof(fd[0])) < 0) if(argcheckptr(fd, 2*sizeof(fd[0])) < 0)
return -1; return -1;
if(pipealloc(&rf, &wf) < 0) if(pipealloc(&rf, &wf) < 0)
return -1; return -1;
......
...@@ -10,12 +10,8 @@ ...@@ -10,12 +10,8 @@
#include "vm.hh" #include "vm.hh"
long long
sys_fork(void) sys_fork(int flags)
{ {
int flags;
if(argint32(0, &flags) < 0)
return -1;
return fork(flags); return fork(flags);
} }
...@@ -33,12 +29,8 @@ sys_wait(void) ...@@ -33,12 +29,8 @@ sys_wait(void)
} }
long long
sys_kill(void) sys_kill(int pid)
{ {
int pid;
if(argint32(0, &pid) < 0)
return -1;
return kill(pid); return kill(pid);
} }
...@@ -49,13 +41,10 @@ sys_getpid(void) ...@@ -49,13 +41,10 @@ sys_getpid(void)
} }
long long
sys_sbrk(void) sys_sbrk(int n)
{ {
uptr addr; uptr addr;
int n;
if(argint32(0, &n) < 0)
return -1;
addr = myproc()->brk; addr = myproc()->brk;
if(growproc(n) < 0) if(growproc(n) < 0)
return -1; return -1;
...@@ -63,13 +52,10 @@ sys_sbrk(void) ...@@ -63,13 +52,10 @@ sys_sbrk(void)
} }
long long
sys_sleep(void) sys_sleep(int n)
{ {
int n;
u32 ticks0; u32 ticks0;
if(argint32(0, &n) < 0)
return -1;
acquire(&tickslock); acquire(&tickslock);
ticks0 = ticks; ticks0 = ticks;
while(ticks - ticks0 < n){ while(ticks - ticks0 < n){
...@@ -97,16 +83,8 @@ sys_uptime(void) ...@@ -97,16 +83,8 @@ sys_uptime(void)
} }
long long
sys_map(void) sys_map(uptr addr, u64 len)
{ {
uptr addr;
u64 len;
if (argint64(0, &addr) < 0)
return -1;
if (argint64(1, &len) < 0)
return -1;
vmnode *vmn = new vmnode(PGROUNDUP(len) / PGSIZE); vmnode *vmn = new vmnode(PGROUNDUP(len) / PGSIZE);
if (vmn == 0) if (vmn == 0)
return -1; return -1;
...@@ -120,16 +98,8 @@ sys_map(void) ...@@ -120,16 +98,8 @@ sys_map(void)
} }
long long
sys_unmap(void) sys_unmap(uptr addr, u64 len)
{ {
uptr addr;
uptr len;
if (argint64(0, &addr) < 0)
return -1;
if (argint64(1, &len) < 0)
return -1;
uptr align_addr = PGROUNDDOWN(addr); uptr align_addr = PGROUNDDOWN(addr);
uptr align_len = PGROUNDUP(addr + len) - align_addr; uptr align_len = PGROUNDUP(addr + len) - align_addr;
if (myproc()->vmap->remove(align_addr, align_len) < 0) if (myproc()->vmap->remove(align_addr, align_len) < 0)
......
...@@ -17,9 +17,11 @@ struct intdesc idt[256] __attribute__((aligned(16))); ...@@ -17,9 +17,11 @@ struct intdesc idt[256] __attribute__((aligned(16)));
// boot.S // boot.S
extern u64 trapentry[]; extern u64 trapentry[];
void u64
sysentry_c() sysentry_c(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
{ {
u64 r;
writegs(KDSEG); writegs(KDSEG);
writemsr(MSR_GS_BASE, (u64)&cpus[cpunum()].cpu); writemsr(MSR_GS_BASE, (u64)&cpus[cpunum()].cpu);
...@@ -32,12 +34,14 @@ sysentry_c() ...@@ -32,12 +34,14 @@ sysentry_c()
trapframe *tf = (trapframe*) (myproc()->kstack + KSTACKSIZE - sizeof(*tf)); trapframe *tf = (trapframe*) (myproc()->kstack + KSTACKSIZE - sizeof(*tf));
myproc()->tf = tf; myproc()->tf = tf;
syscall(); r = syscall(a0, a1, a2, a3, a4, num);
if(myproc()->killed) { if(myproc()->killed) {
mtstart(trap, myproc()); mtstart(trap, myproc());
exit(); exit();
} }
return r;
} }
void void
...@@ -61,7 +65,7 @@ trap(struct trapframe *tf) ...@@ -61,7 +65,7 @@ trap(struct trapframe *tf)
exit(); exit();
} }
myproc()->tf = tf; myproc()->tf = tf;
syscall(); tf->rax = syscall(tf->rdi, tf->rsi, tf->rdx, tf->rcx, tf->r8, tf->rax);
if(myproc()->killed) { if(myproc()->killed) {
mtstart(trap, myproc()); mtstart(trap, myproc());
exit(); exit();
......
...@@ -45,12 +45,12 @@ sysentry: ...@@ -45,12 +45,12 @@ sysentry:
// skip r11 (0x40) // skip r11 (0x40)
// skip r10 (0x48) // skip r10 (0x48)
// skip r9 (0x50) // skip r9 (0x50)
movq %r8, %ss:0x58(%r9) // skip r8 (0x58)
movq %rax, %ss:0x60(%r9) // skip rax (0x60)
movq %r10, %ss:0x68(%r9) // rcx saved by usys.S // skip rcx (0x68)
movq %rdx, %ss:0x70(%r9) // skip rdx (0x70)
movq %rsi, %ss:0x78(%r9) // skip rsi (0x78)
movq %rdi, %ss:0x80(%r9) // skip rdi (0x80)
// skip trapno (0x88) // skip trapno (0x88)
// skip err, padding2 (0x90) // skip err, padding2 (0x90)
movq %rcx, %ss:0x98(%r9) // rip saved by syscall movq %rcx, %ss:0x98(%r9) // rip saved by syscall
...@@ -58,26 +58,28 @@ sysentry: ...@@ -58,26 +58,28 @@ sysentry:
movq %r11, %ss:0xa8(%r9) // eflags saved by syscall movq %r11, %ss:0xa8(%r9) // eflags saved by syscall
movq %rsp, %ss:0xb0(%r9) movq %rsp, %ss:0xb0(%r9)
movw $KDSEG, %ax movw $KDSEG, %cx
movw %ax, %ds movw %cx, %ds
movw %ax, %es movw %cx, %es
movq %r9, %rsp movq %r9, %rsp
movq %r10, %rcx // saved by usys.S
movq %rax, %r9 // syscall# from usys.S
call sysentry_c call sysentry_c
// return using SYSRET // return using SYSRET
cli cli
movq %rsp, %r11 movq %rsp, %r11
movw $UDSEG, %ax movw $UDSEG, %cx
movw %ax, %ds movw %cx, %ds
movw %ax, %es movw %cx, %es
movq %ss:0x10(%r11), %r15 movq %ss:0x10(%r11), %r15
movq %ss:0x18(%r11), %r14 movq %ss:0x18(%r11), %r14
movq %ss:0x20(%r11), %r13 movq %ss:0x20(%r11), %r13
movq %ss:0x28(%r11), %r12 movq %ss:0x28(%r11), %r12
movq %ss:0x30(%r11), %rbp movq %ss:0x30(%r11), %rbp
movq %ss:0x38(%r11), %rbx movq %ss:0x38(%r11), %rbx
movq %ss:0x60(%r11), %rax
movq %ss:0x98(%r11), %rcx // rip to be restored by sysret movq %ss:0x98(%r11), %rcx // rip to be restored by sysret
movq %ss:0xb0(%r11), %rsp movq %ss:0xb0(%r11), %rsp
movq %ss:0xa8(%r11), %r11 // eflags to be restored by sysret movq %ss:0xa8(%r11), %r11 // eflags to be restored by sysret
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论