新增系统调用,并对照linux-6.1.9改写sys_wait4 (#440)

* 1. 新增以下系统调用
            - SYS_LSTAT
            - SYS_READV
            - SYS_ACCESS
            - SYS_UNLINK
            - SYS_CHMOD
            - SYS_FCHMOD
            - SYS_UMASK
            - SYS_SYSINFO
            - SYS_CLOCK_GETTIME
            - SYS_FCHMODAT
            - SYS_FACCESSAT

2. 修改sys_wait4,使得其部分符合Linux的行为(还是有些地方不符合的,详情请对比linux-6.1.9的sys_wait4接口)
This commit is contained in:
LoGin
2023-11-13 23:02:21 +08:00
committed by GitHub
parent 9b0abe6da7
commit bf4a48994a
19 changed files with 735 additions and 167 deletions

View File

@ -0,0 +1,57 @@
use crate::arch::mm::LockedFrameAllocator;
use super::{user_access::UserBufferWriter, Syscall, SystemError};
#[repr(C)]
/// 系统信息
///
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/include/uapi/linux/sysinfo.h#8
#[derive(Debug, Default, Copy, Clone)]
pub struct SysInfo {
uptime: u64,
loads: [u64; 3],
totalram: u64,
freeram: u64,
sharedram: u64,
bufferram: u64,
totalswap: u64,
freeswap: u64,
procs: u16,
pad: u16,
totalhigh: u64,
freehigh: u64,
mem_unit: u32,
// 这后面还有一小段,但是我们不需要
}
impl Syscall {
pub fn sysinfo(info: *mut SysInfo) -> Result<usize, SystemError> {
let mut writer = UserBufferWriter::new(info, core::mem::size_of::<SysInfo>(), true)?;
let mut sysinfo = SysInfo::default();
let mem = LockedFrameAllocator.get_usage();
sysinfo.uptime = 0;
sysinfo.loads = [0; 3];
sysinfo.totalram = mem.total().bytes() as u64;
sysinfo.freeram = mem.free().bytes() as u64;
sysinfo.sharedram = 0;
sysinfo.bufferram = 0;
sysinfo.totalswap = 0;
sysinfo.freeswap = 0;
sysinfo.procs = 0;
sysinfo.pad = 0;
sysinfo.totalhigh = 0;
sysinfo.freehigh = 0;
sysinfo.mem_unit = 0;
writer.copy_one_to_user(&sysinfo, 0)?;
return Ok(0);
}
pub fn umask(_mask: u32) -> Result<usize, SystemError> {
kwarn!("SYS_UMASK has not yet been implemented\n");
return Ok(0o777);
}
}

View File

@ -4,7 +4,10 @@ use core::{
};
use crate::{
arch::syscall::{SYS_ACCESS, SYS_FACCESSAT, SYS_FACCESSAT2, SYS_PRLIMIT64},
arch::syscall::{
SYS_ACCESS, SYS_CHMOD, SYS_CLOCK_GETTIME, SYS_FACCESSAT, SYS_FACCESSAT2, SYS_FCHMOD,
SYS_FCHMODAT, SYS_LSTAT, SYS_PRLIMIT64, SYS_READV, SYS_SYSINFO, SYS_UMASK, SYS_UNLINK,
},
libs::{futex::constant::FutexFlag, rand::GRandFlags},
process::{
fork::KernelCloneArgs,
@ -35,8 +38,12 @@ use crate::{
},
};
use self::user_access::{UserBufferReader, UserBufferWriter};
use self::{
misc::SysInfo,
user_access::{UserBufferReader, UserBufferWriter},
};
pub mod misc;
pub mod user_access;
#[repr(i32)]
@ -317,6 +324,9 @@ pub enum SystemError {
EVMPRTLDFailed = 135,
EVMLAUNCHFailed = 136,
KVM_HVA_ERR_BAD = 137,
// === 以下错误码不应该被用户态程序使用 ===
ERESTARTSYS = 512,
}
impl SystemError {
@ -383,7 +393,6 @@ pub const SYS_SOCKET_PAIR: usize = 53;
pub const SYS_SETSOCKOPT: usize = 54;
pub const SYS_GETSOCKOPT: usize = 55;
#[allow(dead_code)]
pub const SYS_CLONE: usize = 56;
pub const SYS_FORK: usize = 57;
pub const SYS_VFORK: usize = 58;
@ -507,7 +516,7 @@ impl Syscall {
let flags = args[1];
let open_flags: FileMode = FileMode::from_bits_truncate(flags as u32);
Self::open(path, open_flags)
Self::open(path, open_flags, true)
};
res
}
@ -657,13 +666,13 @@ impl Syscall {
}
}
SYS_WAIT4 => {
let pid = args[0] as i64;
let pid = args[0] as i32;
let wstatus = args[1] as *mut i32;
let options = args[2] as c_int;
let rusage = args[3] as *mut c_void;
// 权限校验
// todo: 引入rusage之后更正以下权限校验代码中rusage的大小
Self::wait4(pid, wstatus, options, rusage)
Self::wait4(pid.into(), wstatus, options, rusage)
}
SYS_EXIT => {
@ -754,6 +763,11 @@ impl Syscall {
}
}
}
SYS_UNLINK => {
let pathname = args[0] as *const u8;
Self::unlink(pathname)
}
SYS_KILL => {
let pid = Pid::new(args[0]);
let sig = args[1] as c_int;
@ -1093,13 +1107,14 @@ impl Syscall {
Self::do_futex(uaddr, operation, val, timespec, uaddr2, utime as u32, val3)
}
SYS_READV => Self::readv(args[0] as i32, args[1], args[2]),
SYS_WRITEV => Self::writev(args[0] as i32, args[1], args[2]),
SYS_ARCH_PRCTL => Self::arch_prctl(args[0], args[1]),
SYS_SET_TID_ADDR => Self::set_tid_address(args[0]),
SYS_STAT => {
SYS_STAT | SYS_LSTAT => {
let path: &CStr = unsafe { CStr::from_ptr(args[0] as *const c_char) };
let path: Result<&str, core::str::Utf8Error> = path.to_str();
let res = if path.is_err() {
@ -1109,7 +1124,13 @@ impl Syscall {
let kstat = args[1] as *mut PosixKstat;
let vaddr = VirtAddr::new(kstat as usize);
match verify_area(vaddr, core::mem::size_of::<PosixKstat>()) {
Ok(_) => Self::stat(path, kstat),
Ok(_) => {
if syscall_num == SYS_STAT {
Self::stat(path, kstat)
} else {
Self::lstat(path, kstat)
}
}
Err(e) => Err(e),
}
};
@ -1225,6 +1246,39 @@ impl Syscall {
Self::faccessat2(dirfd, pathname, mode, flags)
}
SYS_CLOCK_GETTIME => {
let clockid = args[0] as i32;
let timespec = args[1] as *mut TimeSpec;
Self::clock_gettime(clockid, timespec)
}
SYS_SYSINFO => {
let info = args[0] as *mut SysInfo;
Self::sysinfo(info)
}
SYS_UMASK => {
let mask = args[0] as u32;
Self::umask(mask)
}
SYS_CHMOD => {
let pathname = args[0] as *const u8;
let mode = args[1] as u32;
Self::chmod(pathname, mode)
}
SYS_FCHMOD => {
let fd = args[0] as i32;
let mode = args[1] as u32;
Self::fchmod(fd, mode)
}
SYS_FCHMODAT => {
let dirfd = args[0] as i32;
let pathname = args[1] as *const u8;
let mode = args[2] as u32;
Self::fchmodat(dirfd, pathname, mode)
}
_ => panic!("Unsupported syscall ID: {}", syscall_num),
};
return r;

View File

@ -223,6 +223,17 @@ impl<'a> UserBufferReader<'a> {
return Ok(());
}
/// 把用户空间的数据转换成指定类型的切片
///
/// ## 参数
///
/// - `offset`:字节偏移量
pub fn buffer<T>(&self, offset: usize) -> Result<&[T], SystemError> {
Ok(self
.convert_with_offset::<T>(self.buffer, offset)
.map_err(|_| SystemError::EINVAL)?)
}
fn convert_with_offset<T>(&self, src: &[u8], offset: usize) -> Result<&[T], SystemError> {
if offset >= src.len() {
return Err(SystemError::EINVAL);