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
// -- 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
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;
+ // 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;
+}