Try kernel userspace memory access faster..

上级 707056ec
......@@ -3,7 +3,6 @@
#include "mmu.h"
#include "atomic.hh"
struct cilkframe;
using std::atomic;
extern atomic<u64> tlbflush_req;
......@@ -16,7 +15,7 @@ struct cpu {
struct segdesc gdt[NSEGS]; // x86 global descriptor table
struct taskstate ts; // Used by x86 to find stack for interrupt
struct context *scheduler; // swtch() here to enter scheduler
struct cilkframe *cilkframe;
int timer_printpc;
atomic<u64> tlbflush_done; // last tlb flush req done on this cpu
struct proc *prev; // The previously-running process
......
......@@ -204,6 +204,7 @@ void release(struct spinlock*);
int argcheckptr(void *argval, int);
int argcheckstr(const char*);
int fetchint64(uptr, u64*);
int fetchstr(char*, const char*, unsigned);
int umemcpy(void*, void*, u64);
int kmemcpy(void*, void*, u64);
u64 syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num);
......
......@@ -81,6 +81,7 @@ struct proc : public rcu_freed {
u64 unmap_tlbreq_;
int exec_cpuid_;
int in_exec_;
int uaccess_;
static proc* alloc();
void set_state(procstate_t s);
......
......@@ -45,6 +45,7 @@ OBJS = \
uwq.o \
vm.o \
trap.o \
uaccess.o \
trapasm.o \
wq.o \
script.o \
......
......@@ -4,6 +4,7 @@
#include "amd64.h"
#include "condvar.h"
#include "proc.hh"
#include "cpu.hh"
#define DEFINE(sym, val) \
asm volatile ("\n#define " #sym " remove%0 " : : "i" (val))
......@@ -13,5 +14,6 @@ asmdefines(void)
{
DEFINE(PROC_KSTACK_OFFSET, __offsetof(struct proc, kstack));
DEFINE(TF_CS, __offsetof(struct trapframe, cs));
DEFINE(PROC_UACCESS, __offsetof(struct proc, uaccess_));
DEFINE(TRAPFRAME_SIZE, sizeof(trapframe));
}
......@@ -41,7 +41,8 @@ proc::proc(int npid) :
pid(npid), parent(0), tf(0), context(0), killed(0),
ftable(0), cwd(0), tsc(0), curcycles(0), cpuid(0), epoch(0),
cpu_pin(0), runq(0), oncv(0), cv_wakeup(0),
user_fs_(0), unmap_tlbreq_(0), in_exec_(0), state_(EMBRYO)
user_fs_(0), unmap_tlbreq_(0), in_exec_(0), uaccess_(0),
state_(EMBRYO)
{
snprintf(lockname, sizeof(lockname), "cv:proc:%d", pid);
initlock(&lock, lockname+3, LOCKSTAT_PROC);
......
......@@ -10,6 +10,16 @@
#include "cpu.hh"
#include "kmtrace.hh"
extern "C" int __fetchstr(char* dst, const char* usrc, unsigned size);
int
fetchstr(char* dst, const char* usrc, unsigned size)
{
if(mycpu()->ncli != 0)
panic("fetchstr: cli'd");
return __fetchstr(dst, usrc, size);
}
// User code makes a system call with INT T_SYSCALL.
// System call number in %eax.
// Arguments on the stack, from the user call to the C
......
......@@ -422,9 +422,13 @@ long
sys_exec(const char *path, u64 uargv)
{
char *argv[MAXARG];
char pbuf[16];
int i;
u64 uarg;
if (fetchstr(pbuf, path, sizeof(pbuf)) < 0)
return -1;
if(argcheckstr(path) < 0) {
return -1;
}
......
......@@ -12,6 +12,8 @@
#include "bits.hh"
#include "kalloc.hh"
extern "C" void __fetch_end(void);
struct intdesc idt[256] __attribute__((aligned(16)));
// boot.S
......@@ -39,6 +41,43 @@ sysentry_c(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
return r;
}
int
do_pagefault(struct trapframe *tf)
{
uptr addr = rcr2();
if (myproc()->uaccess_) {
if (addr >= USERTOP)
panic("Oops");
sti();
if(pagefault(myproc()->vmap, addr, tf->err) >= 0){
#if MTRACE
mtstop(myproc());
if (myproc()->mtrace_stacks.curr >= 0)
mtresume(myproc());
#endif
return 0;
}
cprintf("pagefault: failed in kernel\n");
tf->rax = -1;
tf->rip = (u64)__fetch_end;
return 0;
} else if (tf->err & (1<<2)) {
sti();
if(pagefault(myproc()->vmap, addr, tf->err) >= 0){
#if MTRACE
mtstop(myproc());
if (myproc()->mtrace_stacks.curr >= 0)
mtresume(myproc());
#endif
return 0;
}
cprintf("pagefault: failed in user\n");
cli();
}
return -1;
}
void
trap(struct trapframe *tf)
{
......@@ -139,24 +178,12 @@ trap(struct trapframe *tf)
break;
}
if (tf->trapno == T_PGFLT && do_pagefault(tf) == 0)
return;
if (myproc() == 0 || (tf->cs&3) == 0)
kerneltrap(tf);
if(tf->trapno == T_PGFLT){
uptr addr = rcr2();
sti();
if(pagefault(myproc()->vmap, addr, tf->err) >= 0){
#if MTRACE
mtstop(myproc());
if (myproc()->mtrace_stacks.curr >= 0)
mtresume(myproc());
#endif
return;
}
cprintf("pagefault: failed\n");
cli();
}
// In user space, assume process misbehaved.
cprintf("pid %d %s: trap %lu err %d on cpu %d "
"rip 0x%lx rsp 0x%lx addr 0x%lx--kill proc\n",
......
#include "mmu.h"
#include "asmdefines.h"
.code64
.globl __fetchstr
.align 8
__fetchstr:
mov %gs:0x8, %r11
movl $1, PROC_UACCESS(%r11)
// %rcx is loop instruction index
mov %rdx, %rcx
xor %rax, %rax
1:
movb (%rsi), %r10b
movb %r10b, (%rdi)
// Check for NULL
cmp $0, %r10b
je done
inc %rdi
inc %rsi
loop 1b
// Error
movq $-1, %rax
done:
jmp __fetch_end
.code64
.globl __fetch_end
.align 8
__fetch_end:
movl $0, PROC_UACCESS(%r11)
ret
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论