xv6

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 39352fa0eae25b4d851e9d889c1f88916f32e1ff
parent e1557fbc4ed4ca063b79a1820f7cb8778ed210ed
Author: Brian Swetland <swetland@frotz.net>
Date:   Tue, 31 Dec 2013 09:59:44 -0800

make things (mostly) 64bit safe and compileable

- introduce a new type 'uintp' which is "unsigned integer big enough for
  a pointer to fit
- adjust all code that stuffs pointers in ints or pulls pointers out
  of ints to use this type instead
- should have no impact on the 32bit build (everything builds, runs,
  usertests succeeds)

Diffstat:
Minclude/defs.h | 7++++---
Minclude/memlayout.h | 6+++---
Minclude/mmu.h | 28+++++++++++++++-------------
Minclude/proc.h | 12++++++------
Minclude/types.h | 8+++++++-
Minclude/x86.h | 22++++++++++------------
Mkernel/exec.c | 2+-
Mkernel/kalloc.c | 4++--
Mkernel/main.c | 2+-
Mkernel/mp.c | 2+-
Mkernel/proc.c | 8++++----
Mkernel/spinlock.c | 8++++----
Mkernel/string.c | 2+-
Mkernel/syscall.c | 33++++++++++++++++++++++++---------
Mkernel/sysfile.c | 6+++---
Mkernel/sysproc.c | 8++++----
Mkernel/trap.c | 2+-
Mkernel/vm.c | 24++++++++++++------------
18 files changed, 103 insertions(+), 81 deletions(-)

diff --git a/include/defs.h b/include/defs.h @@ -142,8 +142,9 @@ char* strncpy(char*, const char*, int); int argint(int, int*); int argptr(int, char**, int); int argstr(int, char**); -int fetchint(uint, int*); -int fetchstr(uint, char**); +int arguintp(int, uintp*); +int fetchuintp(uintp, uintp*); +int fetchstr(uintp, char**); void syscall(void); // timer.c @@ -168,7 +169,7 @@ void vmenable(void); pde_t* setupkvm(void); char* uva2ka(pde_t*, char*); int allocuvm(pde_t*, uint, uint); -int deallocuvm(pde_t*, uint, uint); +int deallocuvm(pde_t*, uintp, uintp); void freevm(pde_t*); void inituvm(pde_t*, char*, uint); int loaduvm(pde_t*, char*, struct inode*, uint, uint); diff --git a/include/memlayout.h b/include/memlayout.h @@ -10,12 +10,12 @@ #ifndef __ASSEMBLER__ -static inline uint v2p(void *a) { return ((uint) (a)) - KERNBASE; } -static inline void *p2v(uint a) { return (void *) ((a) + KERNBASE); } +static inline uintp v2p(void *a) { return ((uintp) (a)) - ((uintp)KERNBASE); } +static inline void *p2v(uintp a) { return (void *) ((a) + ((uintp)KERNBASE)); } #endif -#define V2P(a) (((uint) (a)) - KERNBASE) +#define V2P(a) (((uintp) (a)) - KERNBASE) #define P2V(a) (((void *) (a)) + KERNBASE) #define V2P_WO(x) ((x) - KERNBASE) // same as V2P, but without casts diff --git a/include/mmu.h b/include/mmu.h @@ -68,12 +68,12 @@ struct segdesc { // Normal segment #define SEG(type, base, lim, dpl) (struct segdesc) \ { ((lim) >> 12) & 0xffff, (uint)(base) & 0xffff, \ - ((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \ - (uint)(lim) >> 28, 0, 0, 1, 1, (uint)(base) >> 24 } + ((uintp)(base) >> 16) & 0xff, type, 1, dpl, 1, \ + (uintp)(lim) >> 28, 0, 0, 1, 1, (uintp)(base) >> 24 } #define SEG16(type, base, lim, dpl) (struct segdesc) \ -{ (lim) & 0xffff, (uint)(base) & 0xffff, \ - ((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \ - (uint)(lim) >> 16, 0, 0, 1, 0, (uint)(base) >> 24 } +{ (lim) & 0xffff, (uintp)(base) & 0xffff, \ + ((uintp)(base) >> 16) & 0xff, type, 1, dpl, 1, \ + (uintp)(lim) >> 16, 0, 0, 1, 0, (uintp)(base) >> 24 } #endif #define DPL_USER 0x3 // User DPL @@ -109,13 +109,13 @@ struct segdesc { // \--- PDX(va) --/ \--- PTX(va) --/ // page directory index -#define PDX(va) (((uint)(va) >> PDXSHIFT) & 0x3FF) +#define PDX(va) (((uintp)(va) >> PDXSHIFT) & PXMASK) // page table index -#define PTX(va) (((uint)(va) >> PTXSHIFT) & 0x3FF) +#define PTX(va) (((uintp)(va) >> PTXSHIFT) & PXMASK) // construct virtual address from indexes and offset -#define PGADDR(d, t, o) ((uint)((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) +#define PGADDR(d, t, o) ((uintp)((d) << PDXSHIFT | (t) << PTXSHIFT | (o))) // Page directory and page table constants. #define NPDENTRIES 1024 // # directory entries per page directory @@ -126,8 +126,10 @@ struct segdesc { #define PTXSHIFT 12 // offset of PTX in a linear address #define PDXSHIFT 22 // offset of PDX in a linear address -#define PGROUNDUP(sz) (((sz)+PGSIZE-1) & ~(PGSIZE-1)) -#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE-1)) +#define PXMASK 0x3FF + +#define PGROUNDUP(sz) (((sz)+((uintp)PGSIZE-1)) & ~((uintp)(PGSIZE-1))) +#define PGROUNDDOWN(a) (((a)) & ~((uintp)(PGSIZE-1))) // Page table/directory entry flags. #define PTE_P 0x001 // Present @@ -141,11 +143,11 @@ struct segdesc { #define PTE_MBZ 0x180 // Bits must be zero // Address in page table or page directory entry -#define PTE_ADDR(pte) ((uint)(pte) & ~0xFFF) -#define PTE_FLAGS(pte) ((uint)(pte) & 0xFFF) +#define PTE_ADDR(pte) ((uintp)(pte) & ~0xFFF) +#define PTE_FLAGS(pte) ((uintp)(pte) & 0xFFF) #ifndef __ASSEMBLER__ -typedef uint pte_t; +typedef uintp pte_t; // Task state segment format struct taskstate { diff --git a/include/proc.h b/include/proc.h @@ -42,18 +42,18 @@ extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc // at the "Switch stacks" comment. Switch doesn't save eip explicitly, // but it is on the stack and allocproc() manipulates it. struct context { - uint edi; - uint esi; - uint ebx; - uint ebp; - uint eip; + uintp edi; + uintp esi; + uintp ebx; + uintp ebp; + uintp eip; }; enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; // Per-process state struct proc { - uint sz; // Size of process memory (bytes) + uintp sz; // Size of process memory (bytes) pde_t* pgdir; // Page table char *kstack; // Bottom of kernel stack for this process enum procstate state; // Process state diff --git a/include/types.h b/include/types.h @@ -1,4 +1,10 @@ typedef unsigned int uint; typedef unsigned short ushort; typedef unsigned char uchar; -typedef uint pde_t; + +typedef unsigned int uint32; +typedef unsigned long uint64; + +typedef unsigned int uintp; + +typedef uintp pde_t; diff --git a/include/x86.h b/include/x86.h @@ -65,9 +65,8 @@ lgdt(struct segdesc *p, int size) volatile ushort pd[3]; pd[0] = size-1; - pd[1] = (uint)p; - pd[2] = (uint)p >> 16; - + pd[1] = (uintp)p; + pd[2] = (uintp)p >> 16; asm volatile("lgdt (%0)" : : "r" (pd)); } @@ -79,9 +78,8 @@ lidt(struct gatedesc *p, int size) volatile ushort pd[3]; pd[0] = size-1; - pd[1] = (uint)p; - pd[2] = (uint)p >> 16; - + pd[1] = (uintp)p; + pd[2] = (uintp)p >> 16; asm volatile("lidt (%0)" : : "r" (pd)); } @@ -91,10 +89,10 @@ ltr(ushort sel) asm volatile("ltr %0" : : "r" (sel)); } -static inline uint +static inline uintp readeflags(void) { - uint eflags; + uintp eflags; asm volatile("pushfl; popl %0" : "=r" (eflags)); return eflags; } @@ -124,7 +122,7 @@ hlt(void) } static inline uint -xchg(volatile uint *addr, uint newval) +xchg(volatile uint *addr, uintp newval) { uint result; @@ -136,16 +134,16 @@ xchg(volatile uint *addr, uint newval) return result; } -static inline uint +static inline uintp rcr2(void) { - uint val; + uintp val; asm volatile("movl %%cr2,%0" : "=r" (val)); return val; } static inline void -lcr3(uint val) +lcr3(uintp val) { asm volatile("movl %0,%%cr3" : : "r" (val)); } diff --git a/kernel/exec.c b/kernel/exec.c @@ -12,7 +12,7 @@ exec(char *path, char **argv) { char *s, *last; int i, off; - uint argc, sz, sp, ustack[3+MAXARG+1]; + uintp argc, sz, sp, ustack[3+MAXARG+1]; struct elfhdr elf; struct inode *ip; struct proghdr ph; diff --git a/kernel/kalloc.c b/kernel/kalloc.c @@ -46,7 +46,7 @@ void freerange(void *vstart, void *vend) { char *p; - p = (char*)PGROUNDUP((uint)vstart); + p = (char*)PGROUNDUP((uintp)vstart); for(; p + PGSIZE <= (char*)vend; p += PGSIZE) kfree(p); } @@ -61,7 +61,7 @@ kfree(char *v) { struct run *r; - if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP) + if((uintp)v % PGSIZE || v < end || v2p(v) >= PHYSTOP) panic("kfree"); // Fill with junk to catch dangling refs. diff --git a/kernel/main.c b/kernel/main.c @@ -78,7 +78,7 @@ startothers(void) // The linker has placed the image of entryother.S in // _binary_entryother_start. code = p2v(0x7000); - memmove(code, _binary_out_entryother_start, (uint)_binary_out_entryother_size); + memmove(code, _binary_out_entryother_start, (uintp)_binary_out_entryother_size); for(c = cpus; c < cpus+ncpu; c++){ if(c == cpus+cpunum()) // We've started already. diff --git a/kernel/mp.c b/kernel/mp.c @@ -85,7 +85,7 @@ mpconfig(struct mp **pmp) if((mp = mpsearch()) == 0 || mp->physaddr == 0) return 0; - conf = (struct mpconf*) p2v((uint) mp->physaddr); + conf = (struct mpconf*) p2v((uintp) mp->physaddr); if(memcmp(conf, "PCMP", 4) != 0) return 0; if(conf->version != 1 && conf->version != 4) diff --git a/kernel/proc.c b/kernel/proc.c @@ -62,13 +62,13 @@ found: // Set up new context to start executing at forkret, // which returns to trapret. - sp -= 4; - *(uint*)sp = (uint)trapret; + sp -= sizeof(uintp); + *(uintp*)sp = (uintp)trapret; sp -= sizeof *p->context; p->context = (struct context*)sp; memset(p->context, 0, sizeof *p->context); - p->context->eip = (uint)forkret; + p->context->eip = (uintp)forkret; return p; } @@ -85,7 +85,7 @@ userinit(void) initproc = p; if((p->pgdir = setupkvm()) == 0) panic("userinit: out of memory?"); - inituvm(p->pgdir, _binary_out_initcode_start, (int)_binary_out_initcode_size); + inituvm(p->pgdir, _binary_out_initcode_start, (uintp)_binary_out_initcode_size); p->sz = PGSIZE; memset(p->tf, 0, sizeof(*p->tf)); p->tf->cs = (SEG_UCODE << 3) | DPL_USER; diff --git a/kernel/spinlock.c b/kernel/spinlock.c @@ -67,15 +67,15 @@ release(struct spinlock *lk) void getcallerpcs(void *v, uint pcs[]) { - uint *ebp; + uintp *ebp; int i; - ebp = (uint*)v - 2; + ebp = (uintp*)v - 2; for(i = 0; i < 10; i++){ - if(ebp == 0 || ebp < (uint*)KERNBASE || ebp == (uint*)0xffffffff) + if(ebp == 0 || ebp < (uintp*)KERNBASE || ebp == (uintp*)0xffffffff) break; pcs[i] = ebp[1]; // saved %eip - ebp = (uint*)ebp[0]; // saved %ebp + ebp = (uintp*)ebp[0]; // saved %ebp } for(; i < 10; i++) pcs[i] = 0; diff --git a/kernel/string.c b/kernel/string.c @@ -4,7 +4,7 @@ void* memset(void *dst, int c, uint n) { - if ((int)dst%4 == 0 && n%4 == 0){ + if ((uintp)dst%4 == 0 && n%4 == 0){ c &= 0xFF; stosl(dst, (c<<24)|(c<<16)|(c<<8)|c, n/4); } else diff --git a/kernel/syscall.c b/kernel/syscall.c @@ -15,19 +15,28 @@ // Fetch the int at addr from the current process. int -fetchint(uint addr, int *ip) +fetchint(uintp addr, int *ip) { - if(addr >= proc->sz || addr+4 > proc->sz) + if(addr >= proc->sz || addr+sizeof(int) > proc->sz) return -1; *ip = *(int*)(addr); return 0; } +int +fetchuintp(uintp addr, uintp *ip) +{ + if(addr >= proc->sz || addr+sizeof(uintp) > proc->sz) + return -1; + *ip = *(uintp*)(addr); + return 0; +} + // Fetch the nul-terminated string at addr from the current process. // Doesn't actually copy the string - just sets *pp to point at it. // Returns length of string, not including nul. int -fetchstr(uint addr, char **pp) +fetchstr(uintp addr, char **pp) { char *s, *ep; @@ -48,17 +57,23 @@ argint(int n, int *ip) return fetchint(proc->tf->esp + 4 + 4*n, ip); } +int +arguintp(int n, uintp *ip) +{ + return fetchuintp(proc->tf->esp + sizeof(uintp) + sizeof(uintp)*n, ip); +} + // Fetch the nth word-sized system call argument as a pointer // to a block of memory of size n bytes. Check that the pointer // lies within the process address space. int argptr(int n, char **pp, int size) { - int i; - - if(argint(n, &i) < 0) + uintp i; + + if(arguintp(n, &i) < 0) return -1; - if((uint)i >= proc->sz || (uint)i+size > proc->sz) + if(i >= proc->sz || i+size > proc->sz) return -1; *pp = (char*)i; return 0; @@ -71,8 +86,8 @@ argptr(int n, char **pp, int size) int argstr(int n, char **pp) { - int addr; - if(argint(n, &addr) < 0) + uintp addr; + if(arguintp(n, &addr) < 0) return -1; return fetchstr(addr, pp); } diff --git a/kernel/sysfile.c b/kernel/sysfile.c @@ -379,16 +379,16 @@ sys_exec(void) { char *path, *argv[MAXARG]; int i; - uint uargv, uarg; + uintp uargv, uarg; - if(argstr(0, &path) < 0 || argint(1, (int*)&uargv) < 0){ + if(argstr(0, &path) < 0 || arguintp(1, &uargv) < 0){ return -1; } memset(argv, 0, sizeof(argv)); for(i=0;; i++){ if(i >= NELEM(argv)) return -1; - if(fetchint(uargv+4*i, (int*)&uarg) < 0) + if(fetchuintp(uargv+sizeof(uintp)*i, &uarg) < 0) return -1; if(uarg == 0){ argv[i] = 0; diff --git a/kernel/sysproc.c b/kernel/sysproc.c @@ -41,13 +41,13 @@ sys_getpid(void) return proc->pid; } -int +uintp sys_sbrk(void) { - int addr; - int n; + uintp addr; + uintp n; - if(argint(0, &n) < 0) + if(arguintp(0, &n) < 0) return -1; addr = proc->sz; if(growproc(n) < 0) diff --git a/kernel/trap.c b/kernel/trap.c @@ -10,7 +10,7 @@ // Interrupt descriptor table (shared by all CPUs). struct gatedesc idt[256]; -extern uint vectors[]; // in vectors.S: array of 256 entry pointers +extern uintp vectors[]; // in vectors.S: array of 256 entry pointers struct spinlock tickslock; uint ticks; diff --git a/kernel/vm.c b/kernel/vm.c @@ -68,13 +68,13 @@ walkpgdir(pde_t *pgdir, const void *va, int alloc) // physical addresses starting at pa. va and size might not // be page-aligned. static int -mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm) +mappages(pde_t *pgdir, void *va, uintp size, uintp pa, int perm) { char *a, *last; pte_t *pte; - a = (char*)PGROUNDDOWN((uint)va); - last = (char*)PGROUNDDOWN(((uint)va) + size - 1); + a = (char*)PGROUNDDOWN((uintp)va); + last = (char*)PGROUNDDOWN(((uintp)va) + size - 1); for(;;){ if((pte = walkpgdir(pgdir, a, 1)) == 0) return -1; @@ -114,8 +114,8 @@ mappages(pde_t *pgdir, void *va, uint size, uint pa, int perm) // every process's page table. static struct kmap { void *virt; - uint phys_start; - uint phys_end; + uintp phys_start; + uintp phys_end; int perm; } kmap[] = { { (void*)KERNBASE, 0, EXTMEM, PTE_W}, // I/O space @@ -168,7 +168,7 @@ switchuvm(struct proc *p) cpu->gdt[SEG_TSS] = SEG16(STS_T32A, &cpu->ts, sizeof(cpu->ts)-1, 0); cpu->gdt[SEG_TSS].s = 0; cpu->ts.ss0 = SEG_KDATA << 3; - cpu->ts.esp0 = (uint)proc->kstack + KSTACKSIZE; + cpu->ts.esp0 = (uintp)proc->kstack + KSTACKSIZE; ltr(SEG_TSS << 3); if(p->pgdir == 0) panic("switchuvm: no pgdir"); @@ -199,7 +199,7 @@ loaduvm(pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz) uint i, pa, n; pte_t *pte; - if((uint) addr % PGSIZE != 0) + if((uintp) addr % PGSIZE != 0) panic("loaduvm: addr must be page aligned"); for(i = 0; i < sz; i += PGSIZE){ if((pte = walkpgdir(pgdir, addr+i, 0)) == 0) @@ -221,7 +221,7 @@ int allocuvm(pde_t *pgdir, uint oldsz, uint newsz) { char *mem; - uint a; + uintp a; if(newsz >= KERNBASE) return 0; @@ -247,10 +247,10 @@ allocuvm(pde_t *pgdir, uint oldsz, uint newsz) // need to be less than oldsz. oldsz can be larger than the actual // process size. Returns the new process size. int -deallocuvm(pde_t *pgdir, uint oldsz, uint newsz) +deallocuvm(pde_t *pgdir, uintp oldsz, uintp newsz) { pte_t *pte; - uint a, pa; + uintp a, pa; if(newsz >= oldsz) return oldsz; @@ -311,7 +311,7 @@ copyuvm(pde_t *pgdir, uint sz) { pde_t *d; pte_t *pte; - uint pa, i, flags; + uintp pa, i, flags; char *mem; if((d = setupkvm()) == 0) @@ -358,7 +358,7 @@ int copyout(pde_t *pgdir, uint va, void *p, uint len) { char *buf, *pa0; - uint n, va0; + uintp n, va0; buf = (char*)p; while(len > 0){