提交 1bb8082e 创建 作者: Frans Kaashoek's avatar Frans Kaashoek

Merge branch 'scale-amd64' of ssh://amsterdam.csail.mit.edu/home/am0/6.828/xv6 into scale-amd64

......@@ -76,6 +76,7 @@ ULIB := $(addprefix $(O)/, $(ULIB))
UPROGS= \
_cat \
_echo \
_init \
_forkexectree \
_forkexecbench \
......@@ -85,7 +86,8 @@ UPROGS= \
_maptest \
_sh \
_thrtest \
_halt
_halt \
_usertests
UPROGS := $(addprefix $(O)/, $(UPROGS))
all: $(O)/kernel
......@@ -125,7 +127,7 @@ xv6memfs.img: bootblock kernelmemfs
$(O)/_%: $(O)/%.o $(ULIB)
@echo " LD $@"
$(Q)$(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
$(Q)$(LD) $(LDFLAGS) -N -e main -Ttext 0x100000 -o $@ $^
$(O)/mkfs: mkfs.c fs.h
gcc -m32 -Werror -Wall -o $@ mkfs.c
......
......@@ -206,10 +206,11 @@ init32e:
movl %eax, %cr3
# Enable IA-32e mode by setting IA32_EFER.LME = 1.
# Also turn on IA32_EFER.SCE (syscall enable).
# Also turn on IA32_EFER.SCE (syscall enable) and
# IA32_EFER.NXE (no-execute enable).
movl $0xc0000080, %ecx
rdmsr
orl $0x101, %eax
orl $((1<<8)|(1<<0)|(1<<11)), %eax
wrmsr
# Enable paging by setting CR0.PG = 1.
......
......@@ -94,7 +94,7 @@ snprintf(char *buf, u32 n, char *fmt, ...)
va_end(ap);
}
void
static void
__cprintf(const char *fmt, ...)
{
va_list ap;
......@@ -124,9 +124,9 @@ cprintf(const char *fmt, ...)
void
puts(const char *s)
{
uint8 *p, *ep;
u8 *p, *ep;
p = (uint8*)s;
p = (u8*)s;
ep = p+strlen(s);
for (; p < ep; p++)
......@@ -192,16 +192,19 @@ kerneltrap(struct trapframe *tf)
;
}
void __noret__
panic(const char *s)
void
panic(const char *fmt, ...)
{
extern void sys_halt();
va_list ap;
cli();
acquire(&cons.lock);
__cprintf("cpu%d: panic: ", mycpu()->id);
__cprintf(s);
va_start(ap, fmt);
vprintfmt(writecons, 0, fmt, ap);
va_end(ap);
__cprintf("\n");
stacktrace();
......
......@@ -27,9 +27,9 @@
#define CRANGE_CHECKING 0
#define MINNLEVEL 10
#define MARKED(x) (((uintptr) (x)) & 0x1)
#define RANGE_MARK(x) ((struct clist_range *) (((uintptr) (x)) | 0x1))
#define RANGE_WOMARK(x) ((struct clist_range *) (((uintptr) (x)) & ~0x1))
#define MARKED(x) (((uptr) (x)) & 0x1)
#define RANGE_MARK(x) ((struct clist_range *) (((uptr) (x)) | 0x1))
#define RANGE_WOMARK(x) ((struct clist_range *) (((uptr) (x)) & ~0x1))
enum { crange_debug = 0 };
......
......@@ -83,34 +83,28 @@ updatepages(pme_t *pml4, void *begin, void *end, int perm)
}
}
static void
pgmap(void *va, void *last, paddr pa)
// Map from 0 to 128Gbytes starting at KBASE.
void
initpg(char* (*alloc)(void))
{
pme_t *pdp;
pme_t *pd;
pme_t *sp;
for (;;) {
pdp = descend(kpml4, va, 0, 1, 3);
pd = descend(pdp, va, 0, 1, 2);
sp = &pd[PX(1,va)];
*sp = pa | PTE_W | PTE_P | PTE_PS;
if(va == last)
break;
extern char end[];
void *va = (void*)KBASE;
paddr pa = 0;
while (va < (void*)(KBASE+(128ull<<30))) {
pme_t *pdp = descend(kpml4, va, 0, 1, 3);
pme_t *pd = descend(pdp, va, 0, 1, 2);
pme_t *sp = &pd[PX(1,va)];
u64 flags = PTE_W | PTE_P | PTE_PS;
// Set NX for non-code pages
if (va >= (void*) end)
flags |= PTE_NX;
*sp = pa | flags;
va += PGSIZE*512;
pa += PGSIZE*512;
}
}
// set up a page table to get off the ground
void
initpg(char* (*alloc)(void))
{
// Map first 4GB to KBASE
pgmap((void *) (KBASE+(1ull<<30)), (void *) (KBASE+(128ull<<30)), (1ull<<30));
// boot.S maps first 1GB to KBASE and gets us running with kpml4
}
// Set up kernel part of a page table.
pml4e_t*
setupkvm(void)
......
......@@ -31,7 +31,7 @@ static struct kmem slabmem[][NCPU] = {
extern char end[]; // first address after kernel loaded from ELF file
char *newend;
enum { kalloc_memset = 0 };
enum { kalloc_memset = 1 };
static int kinited __mpalign__;
......@@ -128,11 +128,15 @@ kfree_pool(struct kmem *m, char *v)
{
struct run *r;
if((uptr)v % PGSIZE || v < end || memsize(v) == -1ull)
panic("kfree_pool");
if ((uptr)v % PGSIZE)
panic("kfree_pool: misaligned %p", v);
if (v < end)
panic("kfree_pool: less than end %p", v);
if (memsize(v) == -1ull)
panic("kfree_pool: unknown region %p", v);
// Fill with junk to catch dangling refs.
if (kinited && kalloc_memset)
if (kinited && kalloc_memset && m->size <= 16384)
memset(v, 1, m->size);
acquire(&m->lock);
......@@ -151,9 +155,9 @@ kmemprint(void)
cprintf("free pages: [ ");
for (u32 i = 0; i < NCPU; i++)
if (i == mycpu()->id)
cprintf("<%d> ", kmems[i].nfree);
cprintf("<%lu> ", kmems[i].nfree);
else
cprintf("%d ", kmems[i].nfree);
cprintf("%lu ", kmems[i].nfree);
cprintf("]\n");
}
......@@ -184,7 +188,7 @@ kmemalloc(struct kmem *km)
mtlabel(mtrace_label_block, r, m->size, "kalloc", sizeof("kalloc"));
if (kalloc_memset)
if (kalloc_memset && m->size <= 16384)
memset(r, 2, m->size);
return (char*)r;
}
......@@ -408,7 +412,7 @@ kmalign(void **p, int align, u64 size)
{
void *mem = kmalloc(size + (align-1) + sizeof(void*));
char *amem = ((char*)mem) + sizeof(void*);
amem += align - ((uintptr)amem & (align - 1));
amem += align - ((uptr)amem & (align - 1));
((void**)amem)[-1] = mem;
*p = amem;
return 0;
......
......@@ -44,8 +44,9 @@ void cv_wakeup(struct condvar *cv);
void cv_tick(void);
// console.c
void cprintf(const char*, ...);
void panic(const char*) __noret__;
void cprintf(const char*, ...) __attribute__((format(printf, 1, 2)));
void panic(const char*, ...)
__noret__ __attribute__((format(printf, 1, 2)));
void kerneltrap(struct trapframe *tf) __noret__;
void snprintf(char *buf, u32 n, char *fmt, ...);
void consoleintr(int(*)(void));
......
......@@ -26,5 +26,7 @@ SECTIONS
.bss : {
*(.bss)
}
/* 2MByte align, because we set NX on 2MByte super pages. */
. = ALIGN(0x200000);
PROVIDE(end = .);
}
......@@ -148,7 +148,7 @@ cpunum(void)
static int n __mpalign__;
if(n == 0) {
n++;
cprintf("cpu called from %lx with interrupts enabled\n",
cprintf("cpu called from %p with interrupts enabled\n",
__builtin_return_address(0));
}
}
......
......@@ -2,7 +2,7 @@
#include "multiboot.h"
#include "kernel.h"
#include "cpu.h"
#include "e820.h"
#include "amd64.h"
extern void initpic(void);
extern void initioapic(void);
......@@ -115,6 +115,7 @@ cmain(u64 mbmagic, u64 mbaddr)
inituser(); // first user process
bootothers(); // start other processors
kpml4[0] = 0; // don't need 1 GB identity mapping anymore
lcr3(rcr3());
scheduler();
panic("Unreachable");
......
......@@ -17,6 +17,7 @@
#define PTE_PS 0x080 // Page Size
#define PTE_MBZ 0x180 // Bits must be zero
#define PTE_COW 0x800 // copy-on-write
#define PTE_NX 0x8000000000000000ull // No-execute enable
#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1))
#define PGROUNDDOWN(a) ((__typeof__(a))((((uptr)(a)) & ~(PGSIZE-1))))
......@@ -123,5 +124,5 @@ struct taskstate
// and type bits.
#define INTDESC(cs, rip, bits) (struct intdesc){ \
(rip)&0xffff, (cs), 0, bits, ((rip)>>16)&0xffff, \
(uint64)(rip)>>32, 0, \
(u64)(rip)>>32, 0, \
}
typedef struct Mbdata Mbdata;
struct Mbdata
{
uint32 flags;
uint32 mem_lower; // flag 0
uint32 mem_upper; // flag 0
uint32 boot_device; // flag 1
uint32 cmdline; // flag 2
uint32 mods_count; // flag 3
uint32 mods_addr;
uint32 syms[4]; // flag 4, 5
uint32 mmap_length; // flag 6
uint32 mmap_addr;
uint32 drives_length; // flag 7
uint32 drives_addr;
uint32 config_table; // flag 8
uint32 boot_loader_name; // flag 9
uint32 apm_table; // flag 10
uint32 vbe_control_info; // flag 11
uint32 vbe_mode_info;
uint32 vbe_mode;
uint32 vbe_interface_seg;
uint32 vbe_interface_off;
uint32 vbe_interface_len;
u32 flags;
u32 mem_lower; // flag 0
u32 mem_upper; // flag 0
u32 boot_device; // flag 1
u32 cmdline; // flag 2
u32 mods_count; // flag 3
u32 mods_addr;
u32 syms[4]; // flag 4, 5
u32 mmap_length; // flag 6
u32 mmap_addr;
u32 drives_length; // flag 7
u32 drives_addr;
u32 config_table; // flag 8
u32 boot_loader_name; // flag 9
u32 apm_table; // flag 10
u32 vbe_control_info; // flag 11
u32 vbe_mode_info;
u32 vbe_mode;
u32 vbe_interface_seg;
u32 vbe_interface_off;
u32 vbe_interface_len;
};
typedef struct Mbmem Mbmem;
struct Mbmem
{
uint64 base;
uint64 length;
uint32 type;
u64 base;
u64 length;
u32 type;
};
typedef struct Mbmod Mbmod;
struct Mbmod
{
uint32 start;
uint32 end;
uint32 name;
};
typedef struct Page Page;
struct Page
{
Page *next; // only valid when page is on free list
u32 start;
u32 end;
u32 name;
};
......@@ -111,7 +111,7 @@ pci_attach_match(u32 key1, u32 key2,
return r;
if (r < 0)
cprintf("pci_attach_match: attaching "
"%x.%x (%p): e\n",
"%x.%x (%p): %d\n",
key1, key2, list[i].attachfn, r);
}
}
......
......@@ -437,7 +437,7 @@ growproc(int n)
// is there space for newstart..newstart+newn?
if(vmap_lookup(m, newstart, newn) != 0){
cprintf("growproc: not enough room in address space; brk %d n %d\n",
cprintf("growproc: not enough room in address space; brk %lx n %d\n",
myproc()->brk, n);
return -1;
}
......@@ -446,7 +446,7 @@ growproc(int n)
// vma? we can't allow that, since then a future sbrk()
// would start to use the next region (e.g. the stack).
if(vmap_lookup(m, PGROUNDUP(newstart+newn), 1) != 0){
cprintf("growproc: would abut next vma; brk %d n %d\n",
cprintf("growproc: would abut next vma; brk %lx n %d\n",
myproc()->brk, n);
return -1;
}
......@@ -530,7 +530,7 @@ void *procdump(void *vk, void *v, void *arg)
if(p->state == SLEEPING){
getcallerpcs((void*)p->context->rbp, pc);
for(int i=0; i<10 && pc[i] != 0; i++)
cprintf(" %p\n", pc[i]);
cprintf(" %lx\n", pc[i]);
}
return 0;
}
......
......@@ -46,8 +46,8 @@ struct proc {
struct file *ofile[NOFILE]; // Open files
struct inode *cwd; // Current directory
char name[16]; // Process name (debugging)
unsigned long long tsc;
unsigned long long curcycles;
u64 tsc;
u64 curcycles;
unsigned cpuid;
struct spinlock lock;
SLIST_HEAD(childlist, proc) childq;
......
......@@ -25,7 +25,7 @@ tryacquire(struct spinlock *lk)
#if SPINLOCK_DEBUG
if(holding(lk)) {
cprintf("%lx\n", __builtin_return_address(0));
cprintf("%p\n", __builtin_return_address(0));
panic("acquire");
}
#endif
......@@ -56,7 +56,7 @@ acquire(struct spinlock *lk)
#if SPINLOCK_DEBUG
if(holding(lk)) {
cprintf("%lx\n", __builtin_return_address(0));
cprintf("%p\n", __builtin_return_address(0));
panic("acquire");
}
#endif
......
......@@ -131,7 +131,7 @@ trap(struct trapframe *tf)
}
// In user space, assume process misbehaved.
cprintf("pid %d %s: trap %d err %d on cpu %d "
cprintf("pid %d %s: trap %lu err %d on cpu %d "
"rip 0x%lx rsp 0x%lx addr 0x%lx--kill proc\n",
myproc()->pid, myproc()->name, tf->trapno, tf->err,
mycpu()->id, tf->rip, tf->rsp, rcr2());
......@@ -163,8 +163,8 @@ trap(struct trapframe *tf)
void
inittrap(void)
{
uint64 entry;
uint32 bits;
u64 entry;
u32 bits;
int i;
bits = INT_P | SEG_INTR64; // present, interrupt gate
......
......@@ -52,6 +52,7 @@ trapcommon:
// XXX(sbw) we should do something with fs, gs, gs.base
movq %rsp, %rdi // first argument to trap
xor %rbp, %rbp
call trap
// Fall through to trapret
......
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef long int64;
typedef unsigned long uint64;
typedef unsigned char uint8;
typedef uint64 uintptr;
typedef unsigned char u8;
typedef char s8;
typedef unsigned short u16;
typedef short s16;
typedef unsigned int u32;
typedef int s32;
typedef unsigned long u64;
typedef long s64;
typedef u64 uptr;
typedef uptr paddr;
typedef uint8 u8;
typedef char s8;
typedef uint16 u16;
typedef short s16;
typedef uint32 u32;
typedef int s32;
typedef int64 s64;
typedef uint64 u64;
typedef uint64 uptr;
typedef uptr paddr;
typedef u64 pme_t; // Page Map Entry (refers to any entry in any level)
typedef pme_t pml4e_t;
// Page Map Entry (refers to any entry in any level)
typedef u64 pme_t;
typedef pme_t pml4e_t;
......@@ -5,7 +5,6 @@
#include "fcntl.h"
#include "syscall.h"
#include "traps.h"
#include "mtrace.h"
char buf[2048];
char name[3];
......@@ -663,7 +662,7 @@ concreate(void)
int i, pid, n, fd;
char fa[40];
struct {
ushort inum;
u16 inum;
char name[14];
} de;
......@@ -1240,7 +1239,7 @@ sbrktest(void)
{
int fds[2], pid, pids[32], ppid;
char *a, *b, *c, *lastaddr, *oldbrk, *p, scratch;
uint amt;
uptr amt;
printf(stdout, "sbrk test\n");
oldbrk = sbrk(0);
......@@ -1275,7 +1274,7 @@ sbrktest(void)
// can one allocate the full 640K?
// less a stack page and an empty page at the top.
a = sbrk(0);
amt = (632 * 1024) - (uint)a;
amt = (632 * 1024) - (uptr)a;
p = sbrk(amt);
if(p != a){
printf(stdout, "sbrk test failed 632K test, p %x a %x\n", p, a);
......@@ -1351,7 +1350,7 @@ sbrktest(void)
for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
if((pids[i] = fork(0)) == 0){
// allocate the full 632K
sbrk((632 * 1024) - (uint)sbrk(0));
sbrk((632 * 1024) - (uptr)sbrk(0));
write(fds[1], "x", 1);
// sit around until killed
for(;;) sleep(1000);
......@@ -1380,31 +1379,22 @@ sbrktest(void)
}
void
validateint(int *p)
{
int res;
__asm("mov %%esp, %%ebx\n\t"
"mov %3, %%esp\n\t"
"int %2\n\t"
"mov %%ebx, %%esp" :
"=a" (res) :
"a" (SYS_sleep), "n" (T_SYSCALL), "c" (p) :
"ebx");
}
void
validatetest(void)
{
int hi, pid;
uint p;
int pid;
uptr lo, hi, p;
printf(stdout, "validate test\n");
hi = 1100*1024;
// Do 16 pages below the bottom of userspace and 16 pages above,
// which should be code pages and read-only
lo = (1024*1024) - 16*4096;
hi = (1024*1024) + 16*4096;
for(p = 0; p <= (uint)hi; p += 4096){
for(p = lo; p <= hi; p += 4096){
if((pid = fork(0)) == 0){
// try to crash the kernel by passing in a badly placed integer
validateint((int*)p);
if (pipe((int*)p) == 0)
printf(stdout, "validatetest failed (pipe succeeded)\n");
exit();
}
sleep(0);
......@@ -1444,9 +1434,8 @@ bsstest(void)
void
bigargtest(void)
{
int pid, ppid;
int pid;
ppid = getpid();
pid = fork(0);
if(pid == 0){
char *args[32+1];
......@@ -1548,8 +1537,6 @@ main(int argc, char *argv[])
{
printf(1, "usertests starting\n");
mtrace_enable_set(1, "xv6-forktest");
if(open("usertests.ran", 0) >= 0){
printf(1, "already ran user tests -- rebuild fs.img\n");
exit();
......@@ -1569,7 +1556,7 @@ main(int argc, char *argv[])
writetest1();
createtest();
mem();
// mem();
pipe1();
preempt();
exitwait();
......
......@@ -217,7 +217,8 @@ pagefault(struct vmap *vmap, uptr va, u32 err)
m = pagefault_ondemand(vmap, va, err, m);
if (vm_debug)
cprintf("pagefault: err 0x%x va 0x%x type %d ref %d pid %d\n", err, va, m->va_type, m->n->ref, myproc()->pid);
cprintf("pagefault: err 0x%x va 0x%lx type %d ref %lu pid %d\n",
err, va, m->va_type, m->n->ref, myproc()->pid);
if (m->va_type == COW && (err & FEC_WR)) {
if (pagefault_wcow(vmap, va, pte, m, npg) < 0) {
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论