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

%fs for userspace tls

上级 ff1eef00
......@@ -1597,6 +1597,35 @@ preads(void)
fprintf(1, "concurrent preads OK\n");
}
void
tls_test(void)
{
u64 buf[128];
for (int i = 0; i < sizeof(buf) / sizeof(buf[0]); i++)
buf[i] = 0x11deadbeef2200 + i;
for (int i = 0; i < sizeof(buf) / sizeof(buf[0]) - 1; i++) {
setfs((uptr) &buf[i]);
u64 x;
u64 exp = 0x11deadbeef2200 + i;
__asm volatile("movq %%fs:0, %0" : "=r" (x));
if (x != buf[i] || x != exp)
fprintf(2, "tls_test: 0x%lx != 0x%lx\n", x, buf[0]);
getpid(); // make sure syscalls don't trash %fs
__asm volatile("movq %%fs:0, %0" : "=r" (x));
if (x != buf[i] || x != exp)
fprintf(2, "tls_test: 0x%lx != 0x%lx again\n", x, buf[0]);
__asm volatile("movq %%fs:8, %0" : "=r" (x));
if (x != buf[i+1] || x != exp+1)
fprintf(2, "tls_test: 0x%lx != 0x%lx next\n", x, buf[0]);
}
fprintf(1, "tls_test ok\n");
}
int
main(int argc, char *argv[])
{
......@@ -1644,6 +1673,7 @@ main(int argc, char *argv[])
bigdir(); // slow
exectest();
tls_test();
exit();
}
......@@ -50,6 +50,7 @@ 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);
long sys_script(void *addr, u64 len, u64 chunk);
long sys_setfs(u64 base);
extern long (*syscalls[])(u64, u64, u64, u64, u64);
// other exported/imported functions
......
......@@ -71,6 +71,7 @@ struct proc : public rcu_freed {
u64 cv_wakeup; // Wakeup time for this process
LIST_ENTRY(proc) cv_waiters; // Linked list of processes waiting for oncv
LIST_ENTRY(proc) cv_sleep; // Linked list of processes sleeping on a cv
u64 user_fs_;
proc(int npid);
~proc(void);
......
......@@ -30,4 +30,5 @@
#define SYS_pread 29
#define SYS_async 30
#define SYS_script 31
#define SYS_ncount 32 /* total number of system calls */
#define SYS_setfs 32
#define SYS_ncount 33 /* total number of system calls */
......@@ -12,7 +12,7 @@ int read(int, void*, int);
int close(int);
int kill(int);
int exec(const char*, const char**);
int open(const char*, int);
int openat(int dirfd, const char *pathname, int omode);
int mknod(const char*, short, short);
int unlink(const char*);
int fstat(int fd, struct stat*);
......@@ -30,7 +30,7 @@ void halt(void);
ssize_t pread(int, void*, size_t, off_t);
int async(int, size_t, off_t, u32, u32);
int script(void *addr, u64 len, u64 chunk);
int openat(int dirfd, const char *pathname, int omode);
int setfs(u64 base);
// ulib.c
int stat(char*, struct stat*);
......@@ -39,6 +39,7 @@ void *memmove(void*, const void*, int);
char* strchr(const char*, char c);
int strcmp(const char*, const char*);
int strncmp(const char *p, const char *q, u32 n);
int open(const char*, int);
char* gets(char*, int max);
unsigned int strlen(const char*);
......
......@@ -60,5 +60,6 @@ long (*syscalls[])(u64, u64, u64, u64, u64) = {
SYSCALL(pread),
SYSCALL(async),
SYSCALL(script),
SYSCALL(setfs),
};
......@@ -127,6 +127,7 @@ switchvm(struct proc *p)
lcr3(v2p(p->vmap->pml4)); // switch to new address space
else
switchkvm();
writemsr(MSR_FS_BASE, p->user_fs_);
popcli();
}
......
......@@ -33,7 +33,8 @@ proc::proc(int npid) :
rcu_freed("proc"), vmap(0), brk(0), kstack(0),
pid(npid), parent(0), tf(0), context(0), killed(0),
cwd(0), tsc(0), curcycles(0), cpuid(0), epoch(0),
on_runq(-1), cpu_pin(0), runq(0), oncv(0), cv_wakeup(0), state_(EMBRYO)
on_runq(-1), cpu_pin(0), runq(0), oncv(0), cv_wakeup(0),
user_fs_(0), state_(EMBRYO)
{
snprintf(lockname, sizeof(lockname), "cv:proc:%d", pid);
initlock(&lock, lockname+3, LOCKSTAT_PROC);
......
......@@ -123,3 +123,12 @@ sys_halt(void)
outb(0x8900, s[i]);
return 0;
}
long
sys_setfs(u64 base)
{
proc *p = myproc();
p->user_fs_ = base;
switchvm(p);
return 0;
}
......@@ -20,8 +20,6 @@ extern u64 trapentry[];
u64
sysentry_c(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
{
u64 r;
writegs(KDSEG);
writemsr(MSR_GS_BASE, (u64)&cpus[cpunum()].cpu);
......@@ -34,7 +32,7 @@ sysentry_c(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
trapframe *tf = (trapframe*) (myproc()->kstack + KSTACKSIZE - sizeof(*tf));
myproc()->tf = tf;
r = syscall(a0, a1, a2, a3, a4, num);
u64 r = syscall(a0, a1, a2, a3, a4, num);
if(myproc()->killed) {
mtstart(trap, myproc());
......
......@@ -47,3 +47,4 @@ SYSCALL(accept)
SYSCALL(pread)
SYSCALL(async)
SYSCALL(script)
SYSCALL(setfs)
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论