Cleanup and commenting source code

This commit is contained in:
Ali Mashtizadeh 2022-12-09 23:51:45 -05:00
parent 88cbddb3ad
commit f86e4ad966
11 changed files with 221 additions and 126 deletions

View File

@ -40,9 +40,9 @@ src_amd64 = [
src_common = [
"kern/copy.c",
"kern/bufcache.c",
"kern/debug.c",
"kern/disk.c",
"kern/diskcache.c",
"kern/handle.c",
"kern/ktime.c",
"kern/ktimer.c",

View File

@ -17,7 +17,7 @@
#include <sys/thread.h>
#include <sys/disk.h>
#include <sys/diskcache.h>
#include <sys/bufcache.h>
#include <sys/vfs.h>
#include <sys/elf64.h>
@ -163,7 +163,7 @@ void Machine_Init()
PS2_Init();
PCI_Init();
IDE_Init();
DiskCache_Init();
BufCache_Init();
Disk *root = Disk_GetByID(0, 0);
if (!root)

View File

@ -57,8 +57,17 @@ Console_Getc()
Spinlock_Unlock(&consoles.keyLock);
// Support serial debugging if interrupts are disabled
if (Serial_HasData())
return Serial_Getc();
if (Serial_HasData()) {
char key = Serial_Getc();
switch (key) {
case '\r':
return '\n';
case 0x7f:
return '\b';
default:
return key;
}
}
}
}
@ -148,7 +157,7 @@ Console_Read(Handle *handle, void *buf, uint64_t off, uint64_t len)
{
char c = Console_Getc();
Console_Putc(c);
CopyOut(&c, b+i, 1);
Copy_Out(&c, b+i, 1);
}
return len;
@ -164,7 +173,7 @@ Console_Write(Handle *handle, void *buf, uint64_t off, uint64_t len)
while (len > nbytes) {
uint64_t chunksz = len > 512 ? 512 : len;
CopyIn(b + nbytes, &kbuf, chunksz);
Copy_In(b + nbytes, &kbuf, chunksz);
nbytes += chunksz;
for (i = 0; i < chunksz; i++)

View File

@ -8,7 +8,7 @@
#include <sys/kmem.h>
#include <sys/spinlock.h>
#include <sys/disk.h>
#include <sys/diskcache.h>
#include <sys/bufcache.h>
#include <sys/vfs.h>
#include <sys/dirent.h>
#include <sys/thread.h>
@ -43,7 +43,7 @@ O2FS_Mount(Disk *disk)
{
int status;
VFS *fs = VFS_Alloc();
DiskCacheEntry *entry;
BufCacheEntry *entry;
SuperBlock *sb;
ASSERT(sizeof(BDirEntry) == 512);
@ -51,7 +51,7 @@ O2FS_Mount(Disk *disk)
if (!fs)
return NULL;
status = DiskCache_Read(disk, 0, &entry);
status = BufCache_Read(disk, 0, &entry);
if (status < 0) {
Alert(o2fs, "O2FS: Disk cache read failed\n");
return NULL;
@ -61,13 +61,13 @@ O2FS_Mount(Disk *disk)
sb = entry->buffer;
if (memcmp(sb->magic, SUPERBLOCK_MAGIC, 8) != 0) {
Alert(o2fs, "O2FS: Invalid file system\n");
DiskCache_Release(entry);
BufCache_Release(entry);
return NULL;
}
if (sb->versionMajor != O2FS_VERSION_MAJOR ||
sb->versionMinor != O2FS_VERSION_MINOR) {
Alert(o2fs, "O2FS: Unsupported file system version\n");
DiskCache_Release(entry);
BufCache_Release(entry);
return NULL;
}
@ -87,7 +87,7 @@ O2FS_Mount(Disk *disk)
status = O2FS_GetRoot(fs, &fs->root);
if (status < 0) {
Alert(o2fs, "O2FS: Mount failed");
DiskCache_Release(entry);
BufCache_Release(entry);
return NULL;
}
@ -107,9 +107,9 @@ O2FSLoadVNode(VFS *fs, ObjID *objid)
int status;
VNode *vn;
BNode *bn;
DiskCacheEntry *entry;
BufCacheEntry *entry;
status = DiskCache_Read(fs->disk, objid->offset, &entry);
status = BufCache_Read(fs->disk, objid->offset, &entry);
if (status < 0) {
Alert(o2fs, "O2FS: disk read error\n");
return NULL;
@ -118,13 +118,13 @@ O2FSLoadVNode(VFS *fs, ObjID *objid)
bn = entry->buffer;
if (memcmp(&bn->magic, BNODE_MAGIC, 8) != 0) {
Alert(o2fs, "O2FS: bad BNode magic\n");
DiskCache_Release(entry);
BufCache_Release(entry);
return NULL;
}
if (bn->versionMajor != O2FS_VERSION_MAJOR ||
bn->versionMinor != O2FS_VERSION_MINOR) {
Alert(o2fs, "O2FS: unsupported BNode version\n");
DiskCache_Release(entry);
BufCache_Release(entry);
return NULL;
}
@ -154,7 +154,7 @@ O2FSReleaseVNode(VNode *vn)
{
vn->refCount--;
if (vn->refCount == 0) {
DiskCache_Release(vn->fsptr);
BufCache_Release(vn->fsptr);
Spinlock_Destroy(&vn->lock);
VNode_Free(vn);
}
@ -165,7 +165,7 @@ O2FS_GetRoot(VFS *fs, VNode **dn)
{
int status;
VNode *vn;
DiskCacheEntry *entry;
BufCacheEntry *entry;
BNode *bn;
if (fs->root) {
@ -174,7 +174,7 @@ O2FS_GetRoot(VFS *fs, VNode **dn)
return 0;
}
status = DiskCache_Read(fs->disk, fs->fsval, &entry);
status = BufCache_Read(fs->disk, fs->fsval, &entry);
if (status < 0) {
Alert(o2fs, "O2FS: disk read error\n");
return status;
@ -183,13 +183,13 @@ O2FS_GetRoot(VFS *fs, VNode **dn)
bn = entry->buffer;
if (memcmp(&bn->magic, BNODE_MAGIC, 8) != 0) {
Alert(o2fs, "O2FS: bad BNode magic\n");
DiskCache_Release(entry);
BufCache_Release(entry);
return -1;
}
if (bn->versionMajor != O2FS_VERSION_MAJOR ||
bn->versionMinor != O2FS_VERSION_MINOR) {
Alert(o2fs, "O2FS: unsupported BNode version\n");
DiskCache_Release(entry);
BufCache_Release(entry);
return -1;
}
@ -217,9 +217,9 @@ O2FS_Lookup(VNode *dn, VNode **fn, const char *name)
{
int status;
VFS *vfs = dn->vfs;
DiskCacheEntry *sbEntry = (DiskCacheEntry *)vfs->fsptr;
BufCacheEntry *sbEntry = (BufCacheEntry *)vfs->fsptr;
SuperBlock *sb = sbEntry->buffer;
DiskCacheEntry *dirEntry = (DiskCacheEntry *)dn->fsptr;
BufCacheEntry *dirEntry = (BufCacheEntry *)dn->fsptr;
BNode *dirBN = dirEntry->buffer;
uint64_t blocks = (dirBN->size + sb->blockSize - 1) / sb->blockSize;
uint64_t b;
@ -230,9 +230,9 @@ O2FS_Lookup(VNode *dn, VNode **fn, const char *name)
// Read block
int e;
int entryPerBlock = sb->blockSize / sizeof(BDirEntry);
DiskCacheEntry *entry;
BufCacheEntry *entry;
BDirEntry *dir;
status = DiskCache_Read(dn->disk, dirBN->direct[b].offset, &entry);
status = BufCache_Read(dn->disk, dirBN->direct[b].offset, &entry);
if (status < 0)
return status;
@ -248,7 +248,7 @@ O2FS_Lookup(VNode *dn, VNode **fn, const char *name)
}
}
DiskCache_Release(entry);
BufCache_Release(entry);
}
return -1;
@ -270,9 +270,9 @@ int
O2FS_Stat(VNode *fn, struct stat *statinfo)
{
VFS *vfs = fn->vfs;
DiskCacheEntry *sbEntry = (DiskCacheEntry *)vfs->fsptr;
BufCacheEntry *sbEntry = (BufCacheEntry *)vfs->fsptr;
SuperBlock *sb = sbEntry->buffer;
DiskCacheEntry *fileEntry = (DiskCacheEntry *)fn->fsptr;
BufCacheEntry *fileEntry = (BufCacheEntry *)fn->fsptr;
BNode *fileBN = fileEntry->buffer;
statinfo->st_size = fileBN->size;
@ -288,9 +288,9 @@ O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
{
int status;
VFS *vfs = fn->vfs;
DiskCacheEntry *sbEntry = (DiskCacheEntry *)vfs->fsptr;
BufCacheEntry *sbEntry = (BufCacheEntry *)vfs->fsptr;
SuperBlock *sb = sbEntry->buffer;
DiskCacheEntry *fileEntry = (DiskCacheEntry *)fn->fsptr;
BufCacheEntry *fileEntry = (BufCacheEntry *)fn->fsptr;
BNode *fileBN = fileEntry->buffer;
uint64_t blocks = (fileBN->size + sb->blockSize - 1) / sb->blockSize;
uint64_t readBytes = 0;
@ -309,7 +309,7 @@ O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
uint64_t b = off / sb->blockSize;
uint64_t bOff = off % sb->blockSize;
uint64_t bLen;
DiskCacheEntry *entry;
BufCacheEntry *entry;
if (bOff + len > sb->blockSize) {
bLen = sb->blockSize - bOff;
@ -317,12 +317,12 @@ O2FS_Read(VNode *fn, void *buf, uint64_t off, uint64_t len)
bLen = len;
}
status = DiskCache_Read(fn->disk, fileBN->direct[b].offset, &entry);
status = BufCache_Read(fn->disk, fileBN->direct[b].offset, &entry);
if (status < 0)
return status;
memcpy(buf, entry->buffer + bOff, bLen);
DiskCache_Release(entry);
BufCache_Release(entry);
readBytes += bLen;
buf += bLen;
@ -348,7 +348,7 @@ O2FS_ReadDir(VNode *fn, void *buf, uint64_t len, uint64_t *off)
{
int count = 0;
int status;
DiskCacheEntry *fileEntry = (DiskCacheEntry *)fn->fsptr;
BufCacheEntry *fileEntry = (BufCacheEntry *)fn->fsptr;
BNode *fileBN = fileEntry->buffer;
BDirEntry dirEntry;
struct dirent de;
@ -370,7 +370,7 @@ O2FS_ReadDir(VNode *fn, void *buf, uint64_t len, uint64_t *off)
// XXX: Validation and fill in all fields
strcpy(de.d_name, (char *)dirEntry.name);
status = CopyOut(&de, (uintptr_t)buf, sizeof(de));
status = Copy_Out(&de, (uintptr_t)buf, sizeof(de));
if (status != 0)
return status;

23
sys/include/bufcache.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef __SYS_BUFCACHE_H__
#define __SYS_BUFCACHE_H__
#include <sys/queue.h>
typedef struct BufCacheEntry {
Disk *disk;
uint64_t diskOffset;
uint64_t refCount;
void *buffer;
TAILQ_ENTRY(BufCacheEntry) htEntry;
TAILQ_ENTRY(BufCacheEntry) lruEntry;
} BufCacheEntry;
void BufCache_Init();
int BufCache_Alloc(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry);
void BufCache_Release(BufCacheEntry *entry);
int BufCache_Read(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry);
int BufCache_Write(BufCacheEntry *entry);
#endif /* __SYS_BUFCACHE_H__ */

View File

@ -1,23 +0,0 @@
#ifndef __SYS_DISKCACHE_H__
#define __SYS_DISKCACHE_H__
#include <sys/queue.h>
typedef struct DiskCacheEntry {
Disk *disk;
uint64_t diskOffset;
uint64_t refCount;
void *buffer;
TAILQ_ENTRY(DiskCacheEntry) htEntry;
TAILQ_ENTRY(DiskCacheEntry) lruEntry;
} DiskCacheEntry;
void DiskCache_Init();
int DiskCache_Alloc(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry);
void DiskCache_Release(DiskCacheEntry *entry);
int DiskCache_Read(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry);
int DiskCache_Write(DiskCacheEntry *entry);
#endif /* __SYS_DISKCACHE_H__ */

View File

@ -28,6 +28,9 @@
#define SYSCALL_STAT 0x1D
#define SYSCALL_READDIR 0x1E
// IPC
#define SYSCALL_PIPE 0x20
// Threading
#define SYSCALL_THREADCREATE 0x30
#define SYSCALL_GETTID 0x31

View File

@ -123,11 +123,11 @@ uint64_t Handle_Add(Process *proc, Handle *handle);
void Handle_Remove(Process *proc, Handle *handle);
Handle *Handle_Lookup(Process *proc, uint64_t fd);
// CopyIn/CopyOut Functions
int CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len);
int CopyOut(void *fromkernel, uintptr_t touser, uintptr_t len);
int CopyStrIn(uintptr_t fromuser, void *tokernel, uintptr_t len);
int CopyStrOut(void *fromkernel, uintptr_t touser, uintptr_t len);
// Copy_In/Copy_Out Functions
int Copy_In(uintptr_t fromuser, void *tokernel, uintptr_t len);
int Copy_Out(void *fromkernel, uintptr_t touser, uintptr_t len);
int Copy_StrIn(uintptr_t fromuser, void *tokernel, uintptr_t len);
int Copy_StrOut(void *fromkernel, uintptr_t touser, uintptr_t len);
#endif /* __SYS_THREAD_H__ */

View File

@ -1,3 +1,7 @@
/*
* Copyright (c) 2006-2022 Ali Mashtizadeh
* All rights reserved.
*/
#include <stdbool.h>
#include <stdint.h>
@ -8,55 +12,55 @@
#include <sys/kmem.h>
#include <sys/spinlock.h>
#include <sys/disk.h>
#include <sys/diskcache.h>
#include <sys/bufcache.h>
Spinlock cacheLock;
XMem *diskBuf;
static TAILQ_HEAD(CacheHashTable, DiskCacheEntry) *hashTable;
static TAILQ_HEAD(LRUCacheList, DiskCacheEntry) lruList;
static TAILQ_HEAD(CacheHashTable, BufCacheEntry) *hashTable;
static TAILQ_HEAD(LRUCacheList, BufCacheEntry) lruList;
static uint64_t cacheHit;
static uint64_t cacheMiss;
static uint64_t cacheAlloc;
static Slab cacheEntrySlab;
DEFINE_SLAB(DiskCacheEntry, &cacheEntrySlab);
DEFINE_SLAB(BufCacheEntry, &cacheEntrySlab);
#define CACHESIZE (16*1024*1024)
#define HASHTABLEENTRIES 128
#define BLOCKSIZE (16*1024)
void
DiskCache_Init()
BufCache_Init()
{
int i;
Spinlock_Init(&cacheLock, "DiskCache Lock", SPINLOCK_TYPE_NORMAL);
Spinlock_Init(&cacheLock, "BufCache Lock", SPINLOCK_TYPE_NORMAL);
diskBuf = XMem_New();
if (!diskBuf)
Panic("DiskCache: Cannot create XMem region\n");
Panic("BufCache: Cannot create XMem region\n");
if (!XMem_Allocate(diskBuf, CACHESIZE))
Panic("DiskCache: Cannot back XMem region\n");
Panic("BufCache: Cannot back XMem region\n");
TAILQ_INIT(&lruList);
hashTable = PAlloc_AllocPage();
if (!hashTable)
Panic("DiskCache: Cannot allocate hash table\n");
Panic("BufCache: Cannot allocate hash table\n");
for (i = 0; i < HASHTABLEENTRIES; i++) {
TAILQ_INIT(&hashTable[i]);
TAILQ_INIT(&hashTable[i]);
}
Slab_Init(&cacheEntrySlab, "DiskCacheEntry Slab", sizeof(DiskCacheEntry), 16);
Slab_Init(&cacheEntrySlab, "BufCacheEntry Slab", sizeof(BufCacheEntry), 16);
// Initialize cache
uintptr_t bufBase = XMem_GetBase(diskBuf);
for (i = 0; i < CACHESIZE/BLOCKSIZE; i++) {
DiskCacheEntry *e = DiskCacheEntry_Alloc();
BufCacheEntry *e = BufCacheEntry_Alloc();
if (!e) {
Panic("DiskCache: Cannot allocate cache entry\n");
Panic("BufCache: Cannot allocate cache entry\n");
}
memset(e, 0, sizeof(*e));
@ -71,10 +75,10 @@ DiskCache_Init()
}
static int
DiskCacheLookup(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
BufCacheLookup(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry)
{
struct CacheHashTable *table;
DiskCacheEntry *e;
BufCacheEntry *e;
// Check hash table
table = &hashTable[diskOffset % HASHTABLEENTRIES];
@ -94,15 +98,15 @@ DiskCacheLookup(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
}
static int
DiskCacheAlloc(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
BufCacheAlloc(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry)
{
struct CacheHashTable *table;
DiskCacheEntry *e;
BufCacheEntry *e;
// Allocate from LRU list
e = TAILQ_FIRST(&lruList);
if (e == NULL) {
kprintf("DiskCache: No space left!\n");
kprintf("BufCache: No space left!\n");
return -1;
}
TAILQ_REMOVE(&lruList, e, lruEntry);
@ -126,16 +130,24 @@ DiskCacheAlloc(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
return 0;
}
/*
* BufCache_Alloc --
*
* Allocate a buffer cache entry.
*
* Results:
* Returns 0 if successful and sets the entry, otherwise returns an error code.
*/
int
DiskCache_Alloc(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
BufCache_Alloc(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry)
{
int status;
Spinlock_Lock(&cacheLock);
status = DiskCacheLookup(disk, diskOffset, entry);
status = BufCacheLookup(disk, diskOffset, entry);
if (*entry == NULL) {
status = DiskCacheAlloc(disk, diskOffset, entry);
status = BufCacheAlloc(disk, diskOffset, entry);
}
cacheAlloc++;
@ -145,39 +157,56 @@ DiskCache_Alloc(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
return status;
}
/*
* BufCache_Release --
*
* Release a buffer cache entry. If no other references are held the
* buffer cache entry is placed on the LRU list.
*
* Results:
* None.
*/
void
DiskCache_Release(DiskCacheEntry *entry)
BufCache_Release(BufCacheEntry *entry)
{
Spinlock_Lock(&cacheLock);
entry->refCount--;
if (entry->refCount == 0) {
TAILQ_INSERT_TAIL(&lruList, entry, lruEntry);
TAILQ_INSERT_TAIL(&lruList, entry, lruEntry);
}
Spinlock_Unlock(&cacheLock);
}
/*
* BufCache_Read --
*
* Read block from disk into the buffer cache.
*
* Results:
* Returns 0 if successful, otherwise an error code is returned.
*/
int
DiskCache_Read(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
BufCache_Read(Disk *disk, uint64_t diskOffset, BufCacheEntry **entry)
{
int status;
void *buf;
SGArray sga;
Spinlock_Lock(&cacheLock);
status = DiskCacheLookup(disk, diskOffset, entry);
status = BufCacheLookup(disk, diskOffset, entry);
if (*entry != NULL) {
cacheHit++;
Spinlock_Unlock(&cacheLock);
return status;
cacheHit++;
Spinlock_Unlock(&cacheLock);
return status;
}
cacheMiss++;
status = DiskCacheAlloc(disk, diskOffset, entry);
status = BufCacheAlloc(disk, diskOffset, entry);
if (status != 0) {
Spinlock_Unlock(&cacheLock);
return status;
Spinlock_Unlock(&cacheLock);
return status;
}
buf = (*entry)->buffer;
@ -194,8 +223,16 @@ DiskCache_Read(Disk *disk, uint64_t diskOffset, DiskCacheEntry **entry)
return status;
}
/*
* BufCache_Write --
*
* Write a buffer cache entry to disk.
*
* Results:
* Returns 0 if successful, otherwise an error code is returned.
*/
int
DiskCache_Write(DiskCacheEntry *entry)
BufCache_Write(BufCacheEntry *entry)
{
void *buf = entry->buffer;
SGArray sga;
@ -207,12 +244,12 @@ DiskCache_Write(DiskCacheEntry *entry)
}
static void
Debug_DiskCache(int argc, const char *argv[])
Debug_BufCache(int argc, const char *argv[])
{
kprintf("Hits: %lld\n", cacheHit);
kprintf("Misses: %lld\n", cacheMiss);
kprintf("Allocations: %lld\n", cacheAlloc);
}
REGISTER_DBGCMD(diskcache, "Display disk cache statistics", Debug_DiskCache);
REGISTER_DBGCMD(diskcache, "Display disk cache statistics", Debug_BufCache);

View File

@ -1,4 +1,6 @@
/*
* Copyright (c) 2006-2022 Ali Mashtizadeh
* All rights reserved.
* Generic Copyin/Copyout routines
*/
@ -13,84 +15,128 @@
extern int copy_unsafe(void *to_addr, void *from_addr, uintptr_t len);
extern int copystr_unsafe(void *to_addr, void *from_addr, uintptr_t len);
/*
* Copy_In --
* Safely copy memory from userspace. Prevents userspace pointers from
* reading kernel memory.
*
* Results:
* Returns EFAULT if the address is invalid or causes a fault.
*
* Side effects:
* Kernel page fault may have occurred.
*/
int
CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
Copy_In(uintptr_t fromuser, void *tokernel, uintptr_t len)
{
if (len == 0)
return 0;
// Kernel space
if (fromuser >= MEM_USERSPACE_TOP) {
kprintf("CopyIn: address exceeds userspace top\n");
kprintf("Copy_In: address exceeds userspace top\n");
return EFAULT;
}
// Wrap around
if (len > (MEM_USERSPACE_TOP - fromuser)) {
kprintf("CopyIn: length exceeds userspace top\n");
kprintf("Copy_In: length exceeds userspace top\n");
return EFAULT;
}
return copy_unsafe(tokernel, (void *)fromuser, len);
}
/*
* Copy_Out --
* Safely copy memory to userspace. Prevents userspace pointers from
* writing kernel memory.
*
* Results:
* Returns EFAULT if the address is invalid or causes a fault.
*
* Side effects:
* Kernel page fault may have occurred.
*/
int
CopyOut(void *fromkernel, uintptr_t touser, uintptr_t len)
Copy_Out(void *fromkernel, uintptr_t touser, uintptr_t len)
{
if (len == 0)
return 0;
// Kernel space
if (touser >= MEM_USERSPACE_TOP) {
kprintf("CopyOut: address exceeds userspace top\n");
kprintf("Copy_Out: address exceeds userspace top\n");
return EFAULT;
}
// Wrap around
if (len > (MEM_USERSPACE_TOP - touser)) {
kprintf("CopyOut: length exceeds userspace top\n");
kprintf("Copy_Out: length exceeds userspace top\n");
return EFAULT;
}
return copy_unsafe((void *)touser, fromkernel, len);
}
/*
* Copy_StrIn --
* Safely copy a string from userspace. Prevents userspace pointers from
* reading kernel memory.
*
* Results:
* Returns EFAULT if the address is invalid or causes a fault.
*
* Side effects:
* Kernel page fault may have occurred.
*/
int
CopyStrIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
Copy_StrIn(uintptr_t fromuser, void *tokernel, uintptr_t len)
{
if (len == 0)
return 0;
// Kernel space
if (fromuser >= MEM_USERSPACE_TOP) {
kprintf("CopyStrIn: address exceeds userspace top\n");
kprintf("Copy_StrIn: address exceeds userspace top\n");
return EFAULT;
}
// Wrap around
if (len > (MEM_USERSPACE_TOP - fromuser)) {
kprintf("CopyStrIn: length exceeds userspace top\n");
kprintf("Copy_StrIn: length exceeds userspace top\n");
return EFAULT;
}
return copystr_unsafe(tokernel, (void *)fromuser, len);
}
/*
* Copy_StrOut --
* Safely copy a string to userspace. Prevents userspace pointers from
* writing kernel memory.
*
* Results:
* Returns EFAULT if the address is invalid or causes a fault.
*
* Side effects:
* Kernel page fault may have occurred.
*/
int
CopyStrOut(void *fromkernel, uintptr_t touser, uintptr_t len)
Copy_StrOut(void *fromkernel, uintptr_t touser, uintptr_t len)
{
if (len == 0)
return 0;
// Kernel space
if (touser >= MEM_USERSPACE_TOP) {
kprintf("CopyStrOut: address exceeds userspace top\n");
kprintf("Copy_StrOut: address exceeds userspace top\n");
return EFAULT;
}
// Wrap around
if (len > (MEM_USERSPACE_TOP - touser)) {
kprintf("CopyStrOut: length exceeds userspace top\n");
kprintf("Copy_StrOut: length exceeds userspace top\n");
return EFAULT;
}

View File

@ -71,7 +71,7 @@ Syscall_Spawn(uint64_t user_path)
Thread *thr;
Thread *cur;
status = CopyStrIn(user_path, &path, sizeof(path));
status = Copy_StrIn(user_path, &path, sizeof(path));
if (status != 0)
return SYSCALL_PACK(status, 0);
@ -246,7 +246,7 @@ Syscall_Open(uint64_t user_path, uint64_t flags)
int status;
char path[256];
status = CopyStrIn(user_path, &path, sizeof(path));
status = Copy_StrIn(user_path, &path, sizeof(path));
if (status != 0) {
Thread_Release(cur);
return status;
@ -301,7 +301,7 @@ Syscall_Stat(uint64_t user_path, uint64_t user_stat)
char path[256];
struct stat sb;
status = CopyStrIn(user_path, &path, sizeof(path));
status = Copy_StrIn(user_path, &path, sizeof(path));
if (status != 0) {
return status;
}
@ -312,7 +312,7 @@ Syscall_Stat(uint64_t user_path, uint64_t user_stat)
return status;
}
status = CopyOut(&sb, user_stat, sizeof(struct stat));
status = Copy_Out(&sb, user_stat, sizeof(struct stat));
if (status != 0) {
return status;
}
@ -333,7 +333,7 @@ Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off)
return -EBADF;
}
status = CopyIn(user_off, &offset, sizeof(offset));
status = Copy_In(user_off, &offset, sizeof(offset));
if (status != 0) {
Thread_Release(cur);
return status;
@ -350,7 +350,7 @@ Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off)
return rstatus;
}
status = CopyOut(&offset, user_off, sizeof(offset));
status = Copy_Out(&offset, user_off, sizeof(offset));
if (status != 0) {
Thread_Release(cur);
return status;
@ -480,7 +480,7 @@ Syscall_NICStat(uint64_t nicNo, uint64_t user_stat)
return ENOENT;
}
status = CopyOut(nic, user_stat, sizeof(NIC));
status = Copy_Out(nic, user_stat, sizeof(NIC));
if (status != 0) {
return status;
}
@ -495,7 +495,7 @@ Syscall_NICSend(uint64_t nicNo, uint64_t user_mbuf)
NIC *nic;
MBuf mbuf;
status = CopyIn(user_mbuf, &mbuf, sizeof(mbuf));
status = Copy_In(user_mbuf, &mbuf, sizeof(mbuf));
if (status != 0) {
return SYSCALL_PACK(status, 0);
}
@ -519,7 +519,7 @@ Syscall_NICRecv(uint64_t nicNo, uint64_t user_mbuf)
NIC *nic;
MBuf mbuf;
status = CopyIn(user_mbuf, &mbuf, sizeof(mbuf));
status = Copy_In(user_mbuf, &mbuf, sizeof(mbuf));
if (status != 0) {
return SYSCALL_PACK(status, 0);
}
@ -542,7 +542,7 @@ Syscall_SysCtl(uint64_t user_node, uint64_t user_oldval, uint64_t user_newval)
uint64_t status;
char node[64];
status = CopyStrIn(user_node, &node, sizeof(node));
status = Copy_StrIn(user_node, &node, sizeof(node));
if (status != 0) {
return status;
}
@ -555,17 +555,17 @@ Syscall_SysCtl(uint64_t user_node, uint64_t user_oldval, uint64_t user_newval)
switch (scType) {
case SYSCTL_TYPE_STR: {
SysCtlString *scStr = SysCtl_GetObject(node);
status = CopyOut(scStr, user_oldval, sizeof(*scStr));
status = Copy_Out(scStr, user_oldval, sizeof(*scStr));
break;
}
case SYSCTL_TYPE_INT: {
SysCtlInt *scInt = SysCtl_GetObject(node);
status = CopyOut(scInt, user_oldval, sizeof(*scInt));
status = Copy_Out(scInt, user_oldval, sizeof(*scInt));
break;
}
case SYSCTL_TYPE_BOOL: {
SysCtlBool *scBool = SysCtl_GetObject(node);
status = CopyOut(scBool, user_oldval, sizeof(scBool));
status = Copy_Out(scBool, user_oldval, sizeof(scBool));
break;
}
default: {
@ -584,7 +584,7 @@ Syscall_SysCtl(uint64_t user_node, uint64_t user_oldval, uint64_t user_newval)
switch (scType) {
case SYSCTL_TYPE_STR: {
SysCtlString scStr;
status = CopyIn(user_newval, &scStr, sizeof(scStr));
status = Copy_In(user_newval, &scStr, sizeof(scStr));
if (status != 0) {
return status;
}
@ -593,7 +593,7 @@ Syscall_SysCtl(uint64_t user_node, uint64_t user_oldval, uint64_t user_newval)
}
case SYSCTL_TYPE_INT: {
SysCtlInt scInt;
status = CopyIn(user_newval, &scInt, sizeof(scInt));
status = Copy_In(user_newval, &scInt, sizeof(scInt));
if (status != 0) {
return status;
}
@ -602,7 +602,7 @@ Syscall_SysCtl(uint64_t user_node, uint64_t user_oldval, uint64_t user_newval)
}
case SYSCTL_TYPE_BOOL: {
SysCtlBool scBool;
status = CopyIn(user_newval, &scBool, sizeof(scBool));
status = Copy_In(user_newval, &scBool, sizeof(scBool));
if (status != 0) {
return status;
}