void SyscallHandler(tSyscallRegs *Regs);
int Syscall_ValidString(const char *Addr);
int Syscall_Valid(int Size, const void *Addr);
+ int Syscall_MM_SetFlags(const void *Addr, Uint Flags, Uint Mask);
// === CODE ===
// TODO: Do sanity checking on arguments, ATM the user can really fuck with the kernel
// -- Get the physical address of a page
case SYS_GETPHYS:
- ret = MM_GetPhysAddr(Regs->Arg1);
+ ret = MM_GetPhysAddr( (void*)Regs->Arg1 );
break;
// -- Map an address
// -- Unmap an address
case SYS_UNMAP: MM_Deallocate(Regs->Arg1); break;
+ // -- Change the protection on an address
+ case SYS_SETFLAGS:
+ ret = Syscall_MM_SetFlags((void*)Regs->Arg1, Regs->Arg2, Regs->Arg3);
+ break;
+
// -- Get Thread/Process IDs
case SYS_GETTID: ret = Threads_GetTID(); break;
case SYS_GETPID: ret = Threads_GetPID(); break;
// -- Check for messages
case SYS_GETMSG:
CHECK_NUM_NULLOK( (Uint*)Regs->Arg1, sizeof(Uint) );
- // NOTE: Can't do range checking as we don't know the size
- // - Should be done by Proc_GetMessage
- if( Regs->Arg2 && Regs->Arg2 != -1 && !MM_IsUser(Regs->Arg2) ) {
- err = -EINVAL; ret = -1; break;
- }
+ if( Regs->Arg3 != -1 )
+ CHECK_NUM_NULLOK((void*)Regs->Arg3, Regs->Arg2);
// *Source, *Data
- ret = Proc_GetMessage((Uint*)Regs->Arg1, (void*)Regs->Arg2);
+ ret = Proc_GetMessage((Uint*)Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3);
break;
// -- Get the current timestamp
ret = -1;
break;
}
- // Sanity check the paths
- if(!Syscall_ValidString((char*)Regs->Arg1)
- || !Syscall_ValidString((char*)Regs->Arg2)
- || !Syscall_ValidString((char*)Regs->Arg3)
- || !Syscall_ValidString((char*)Regs->Arg4) ) {
- err = -EINVAL;
- ret = -1;
- break;
+
+ if( !Regs->Arg1 )
+ {
+ if( !Syscall_ValidString((char*)Regs->Arg2) ) {
+ err = -EINVAL;
+ ret = -1;
+ break;
+ }
+
+ ret = VFS_Unmount((char*)Regs->Arg2);
+ }
+ else
+ {
+ // Sanity check the paths
+ if(!Syscall_ValidString((char*)Regs->Arg1)
+ || !Syscall_ValidString((char*)Regs->Arg2)
+ || (Regs->Arg3 && !Syscall_ValidString((char*)Regs->Arg3))
+ || !Syscall_ValidString((char*)Regs->Arg4) ) {
+ err = -EINVAL;
+ ret = -1;
+ break;
+ }
+ ret = VFS_Mount(
+ (char*)Regs->Arg1, // Device
+ (char*)Regs->Arg2, // Mount point
+ (char*)Regs->Arg3, // Filesystem
+ (char*)Regs->Arg4 // Options
+ );
}
- ret = VFS_Mount(
- (char*)Regs->Arg1, // Device
- (char*)Regs->Arg2, // Mount point
- (char*)Regs->Arg3, // Filesystem
- (char*)Regs->Arg4 // Options
- );
break;
// Wait on a set of handles
return CheckMem( Addr, Size );
}
+
+int Syscall_MM_SetFlags(const void *Addr, Uint Flags, Uint Mask)
+{
+ tPAddr paddr = MM_GetPhysAddr(Addr);
+ Flags &= MM_PFLAG_RO|MM_PFLAG_EXEC;
+ Mask &= MM_PFLAG_RO|MM_PFLAG_EXEC;
+
+ //Log_Debug("Syscalls", "SYS_SETFLAGS: %p %x %x", Addr, Flags, Mask);
+
+ // Enable write?
+ if( (Mask & MM_PFLAG_RO) && !(Flags & MM_PFLAG_RO) ) {
+ void *node;
+ // HACK - Assume that RO mmap'd files are immutable
+ if( MM_GetPageNode(paddr, &node) == 0 && node ) {
+ Flags |= MM_PFLAG_COW;
+ Mask |= MM_PFLAG_COW;
+ }
+ }
+ MM_SetFlags((tVAddr)Addr, Flags, Mask);
+ return 0;
+}