From d13f66b7f3550d7bd0cdb329f5846a3addd23451 Mon Sep 17 00:00:00 2001 From: liusm18 Date: Sun, 20 Mar 2022 16:57:11 +0800 Subject: [PATCH 01/35] Change urls for git & modify default make params --- .gitmodules | 4 ++-- drivers/Cargo.toml | 12 ++++++------ kernel-hal/Cargo.toml | 8 ++++---- linux-object/Cargo.toml | 10 +++++----- linux-syscall/Cargo.toml | 2 +- loader/Cargo.toml | 2 +- zCore/Cargo.toml | 14 +++++++------- zCore/Makefile | 4 ++-- zircon-object/Cargo.toml | 4 ++-- 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.gitmodules b/.gitmodules index 38982db8..9d2b8722 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "rboot"] path = rboot - url = https://github.com/rcore-os/rboot.git + url = https://github.91chi.fun//https://github.com/rcore-os/rboot.git [submodule "tests"] path = tests - url = https://github.com/rcore-os/zcore-tests.git + url = https://github.91chi.fun//https://github.com/rcore-os/zcore-tests.git diff --git a/drivers/Cargo.toml b/drivers/Cargo.toml index a3e47e62..32478b2d 100644 --- a/drivers/Cargo.toml +++ b/drivers/Cargo.toml @@ -19,11 +19,11 @@ cfg-if = "1.0" bitflags = "1.3" lazy_static = "1.4" numeric-enum-macro = "0.2" -device_tree = { git = "https://github.com/rcore-os/device_tree-rs", rev = "2f2e55f" } -bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51" } -virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "2aaf7d6", optional = true } -rcore-console = { git = "https://github.com/rcore-os/rcore-console", default-features = false, rev = "ca5b1bc", optional = true } -# smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp", rev = "35e833e3", default-features = false, features = ["log", "alloc", "verbose", "proto-ipv4", "proto-ipv6", "proto-igmp", "medium-ip", "medium-ethernet", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp"] } +device_tree = { git = "https://github.91chi.fun//https://github.com/rcore-os/device_tree-rs.git", rev = "2f2e55f" } +bitmap-allocator = { git = "https://github.91chi.fun//https://github.com/rcore-os/bitmap-allocator.git", rev = "b3f9f51" } +virtio-drivers = { git = "https://github.91chi.fun//https://github.com/rcore-os/virtio-drivers", rev = "2aaf7d6", optional = true } +rcore-console = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-console", default-features = false, rev = "ca5b1bc", optional = true } +# smoltcp = { git = "https://github.91chi.fun//https://github.com/smoltcp-rs/smoltcp", rev = "35e833e3", default-features = false, features = ["log", "alloc", "verbose", "proto-ipv4", "proto-ipv6", "proto-igmp", "medium-ip", "medium-ethernet", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp"] } smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev="043eb60", default-features = false, features = ["alloc","log", "async", "medium-ethernet","proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] } [target.'cfg(not(target_os = "none"))'.dependencies] @@ -35,4 +35,4 @@ acpi = "4.0" x2apic = "0.4" [target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies] -riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = ["inline-asm"] } +riscv = { git = "https://github.91chi.fun//https://github.com/rust-embedded/riscv", rev = "cd31989", features = ["inline-asm"] } diff --git a/kernel-hal/Cargo.toml b/kernel-hal/Cargo.toml index ebd7c19c..05c9f1ae 100644 --- a/kernel-hal/Cargo.toml +++ b/kernel-hal/Cargo.toml @@ -31,11 +31,11 @@ smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev="043eb60", default-fe nix = { version = "0.23", optional = true } tempfile = { version = "3", optional = true } async-std = { version = "1.10", optional = true } -bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51", optional = true } +bitmap-allocator = { git = "https://github.91chi.fun//https://github.com/rcore-os/bitmap-allocator.git", rev = "b3f9f51", optional = true } # Bare-metal mode [target.'cfg(target_os = "none")'.dependencies] -executor = { git = "https://github.com/rcore-os/executor.git", rev = "85b9335" } +executor = { git = "https://github.91chi.fun//https://github.com/rcore-os/executor.git", rev = "85b9335" } naive-timer = "0.2.0" # All mode on x86_64 @@ -47,8 +47,8 @@ x86_64 = "0.14" [target.'cfg(all(target_os = "none", target_arch = "x86_64"))'.dependencies] uefi = "0.11" raw-cpuid = "9.0" -x86-smpboot = { git = "https://github.com/rcore-os/x86-smpboot", rev = "1069df3" } +x86-smpboot = { git = "https://github.91chi.fun//https://github.com/rcore-os/x86-smpboot", rev = "1069df3" } # Bare-metal mode on riscv64 [target.'cfg(all(target_os = "none", target_arch = "riscv64"))'.dependencies] -riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = ["inline-asm"] } +riscv = { git = "https://github.91chi.fun//https://github.com/rust-embedded/riscv", rev = "cd31989", features = ["inline-asm"] } diff --git a/linux-object/Cargo.toml b/linux-object/Cargo.toml index 6e92f514..65bd7519 100644 --- a/linux-object/Cargo.toml +++ b/linux-object/Cargo.toml @@ -19,11 +19,11 @@ zircon-object = { path = "../zircon-object", features = ["elf"] } kernel-hal = { path = "../kernel-hal", default-features = false } downcast-rs = { version = "1.2", default-features = false } lazy_static = { version = "1.4", features = ["spin_no_std"] } -rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } -rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } -rcore-fs-ramfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } -rcore-fs-mountfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } -rcore-fs-devfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs-sfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs-ramfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs-mountfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs-devfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } cfg-if = "1.0" smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev="043eb60", default-features = false, features = ["alloc","log", "async", "medium-ethernet","proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] } zcore-drivers = { path = "../drivers", features = ["virtio"] } \ No newline at end of file diff --git a/linux-syscall/Cargo.toml b/linux-syscall/Cargo.toml index 4a5fad9a..fe77904a 100644 --- a/linux-syscall/Cargo.toml +++ b/linux-syscall/Cargo.toml @@ -15,6 +15,6 @@ numeric-enum-macro = "0.2" zircon-object = { path = "../zircon-object" } linux-object = { path = "../linux-object" } kernel-hal = { path = "../kernel-hal", default-features = false } -rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } lazy_static = { version = "1.4", features = ["spin_no_std"] } bitvec = { version = "0.22", default-features = false, features = ["alloc"] } diff --git a/loader/Cargo.toml b/loader/Cargo.toml index 2d747505..1ba4e82e 100644 --- a/loader/Cargo.toml +++ b/loader/Cargo.toml @@ -26,7 +26,7 @@ libos = ["kernel-hal/libos", "zircon-object/aspace-separate"] [dev-dependencies] env_logger = "0.9" async-std = { version = "1.10", features = ["attributes"] } -rcore-fs-hostfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs-hostfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } [[example]] name = "linux-libos" diff --git a/zCore/Cargo.toml b/zCore/Cargo.toml index d300c63e..717b8ea6 100644 --- a/zCore/Cargo.toml +++ b/zCore/Cargo.toml @@ -47,26 +47,26 @@ log = "0.4" spin = "0.9" cfg-if = "1.0" lazy_static = { version = "1.4", features = ["spin_no_std" ] } -bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51" } +bitmap-allocator = { git = "https://github.91chi.fun//https://github.com/rcore-os/bitmap-allocator.git", rev = "b3f9f51" } kernel-hal = { path = "../kernel-hal", default-features = false, features = ["smp"] } zcore-loader = { path = "../loader", default-features = false } zircon-object = { path = "../zircon-object" } linux-object = { path = "../linux-object", optional = true } -rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } -rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } +rcore-fs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } +rcore-fs-sfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } # LibOS mode [target.'cfg(not(target_os = "none"))'.dependencies] async-std = { version = "1.10", optional = true } chrono = { version = "0.4", optional = true } -rcore-fs-hostfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } +rcore-fs-hostfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } # Bare-metal mode [target.'cfg(target_os = "none")'.dependencies] buddy_system_allocator = "0.7" -executor = { git = "https://github.com/rcore-os/executor.git", rev = "85b9335" } +executor = { git = "https://github.91chi.fun//https://github.com/rcore-os/executor.git", rev = "85b9335" } # Bare-metal mode on x86_64 [target.'cfg(all(target_os = "none", target_arch = "x86_64"))'.dependencies] -rboot = { git = "https://github.com/rcore-os/rboot.git", rev = "39d6e24", default-features = false } -# rvm = { git = "https://github.com/rcore-os/RVM", rev = "e91d625", optional = true } \ No newline at end of file +rboot = { git = "https://github.91chi.fun//https://github.com/rcore-os/rboot.git", rev = "39d6e24", default-features = false } +# rvm = { git = "https://github.91chi.fun//https://github.com/rcore-os/RVM", rev = "e91d625", optional = true } \ No newline at end of file diff --git a/zCore/Makefile b/zCore/Makefile index 0e73c856..95507f3f 100644 --- a/zCore/Makefile +++ b/zCore/Makefile @@ -1,10 +1,10 @@ ################ Arguments ################ -ARCH ?= x86_64 +ARCH ?= riscv64 PLATFORM ?= qemu MODE ?= release LOG ?= warn -LINUX ?= +LINUX ?= 1 LIBOS ?= TEST ?= GRAPHIC ?= diff --git a/zircon-object/Cargo.toml b/zircon-object/Cargo.toml index 79a841cd..25572219 100644 --- a/zircon-object/Cargo.toml +++ b/zircon-object/Cargo.toml @@ -22,10 +22,10 @@ kernel-hal = { path = "../kernel-hal", default-features = false } numeric-enum-macro = "0.2" futures = { version = "0.3", default-features = false, features = ["alloc", "async-await"] } xmas-elf = { version = "0.7", optional = true } -region-alloc = { git = "https://github.com/rzswh/region-allocator", rev = "122c7a71" } +region-alloc = { git = "https://github.91chi.fun//https://github.com/rzswh/region-allocator", rev = "122c7a71" } lazy_static = { version = "1.4", features = ["spin_no_std" ] } cfg-if = "1.0" -#rvm = { git = "https://github.com/rcore-os/RVM", rev = "382fc60", optional = true } +#rvm = { git = "https://github.91chi.fun//https://github.com/rcore-os/RVM", rev = "382fc60", optional = true } [dev-dependencies] async-std = { version = "1.10", features = ["attributes", "unstable"] } From 9961dba5e23551b59d3d7000cbededcc9385d8a1 Mon Sep 17 00:00:00 2001 From: liusm18 Date: Thu, 31 Mar 2022 17:27:59 +0800 Subject: [PATCH 02/35] Implement tkill syscall --- linux-syscall/src/lib.rs | 5 ++- linux-syscall/src/signal.rs | 84 +++++++++++++++++++++++++++++++++++++ linux-syscall/src/task.rs | 22 ---------- loader/src/linux.rs | 6 +++ 4 files changed, 93 insertions(+), 24 deletions(-) diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index aebabc9c..483fad3d 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -313,7 +313,7 @@ impl Syscall<'_> { self.into_in_userptr(a0).unwrap(), self.into_out_userptr(a1).unwrap(), ), - // Sys::KILL => self.sys_kill(a0, a1), + Sys::KILL => self.sys_kill(a0 as isize, a1), // schedule Sys::SCHED_YIELD => self.unimplemented("yield", Ok(0)), @@ -391,7 +391,8 @@ impl Syscall<'_> { // ignore timeout argument when op is wake self.sys_futex(a0, a1 as _, a2 as _, a3).await } - Sys::TKILL => self.unimplemented("tkill", Ok(0)), + Sys::TKILL => self.sys_tkill(a0, a1), + Sys::TGKILL => self.unimplemented("tgkill", Ok(0)), // time Sys::NANOSLEEP => self.sys_nanosleep(self.into_in_userptr(a0).unwrap()).await, diff --git a/linux-syscall/src/signal.rs b/linux-syscall/src/signal.rs index 314d404b..da7678be 100644 --- a/linux-syscall/src/signal.rs +++ b/linux-syscall/src/signal.rs @@ -10,6 +10,7 @@ use super::*; use linux_object::signal::{Signal, SignalAction, SignalStack, SignalStackFlags, Sigset}; use linux_object::thread::ThreadExt; +use zircon_object::object::Signal as ZirconSignal; use numeric_enum_macro::numeric_enum; impl Syscall<'_> { @@ -112,4 +113,87 @@ impl Syscall<'_> { *old_ss = ss; Ok(0) } + + /// Send a signal to a process specified by pid + /// TODO1: support all the arguments + /// TODO2: support all the signals + pub fn sys_kill(&self, pid: isize, signum: usize) -> SysResult { + // Other signals except SIGKILL are not supported + let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; + info!( + "kill: thread {} kill process {} with signal {:?}", + self.thread.id(), + pid, + signal + ); + enum SendTarget { + EveryProcessInGroup, + EveryProcess, + EveryProcessInGroupByPID(KoID), + Pid(KoID), + } + let target = match pid { + p if p > 0 => SendTarget::Pid(p as KoID), + 0 => SendTarget::EveryProcessInGroup, + -1 => SendTarget::EveryProcess, + p if p < -1 => SendTarget::EveryProcessInGroupByPID((-p) as KoID), + _ => unimplemented!() + }; + let parent = self.zircon_process().clone(); + match target { + SendTarget::Pid(pid) => { + match parent.job().get_child(pid as u64) { + Ok(obj) => { + match signal { + Signal::SIGKILL => obj.signal_set(ZirconSignal::PROCESS_TERMINATED), + _ => unimplemented!() + }; + Ok(0) + } + Err(_) => Err(LxError::EINVAL) + } + } + _ => unimplemented!() + } + } + + + /// Send a signal to a process specified by pid + /// TODO: support all the signals + pub fn sys_tkill(&mut self, tid: usize, signum: usize) -> SysResult { + // Other signals except SIGKILL are not supported + let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; + info!( + "tkill: thread {} kill thread {} with signal {:?}", + self.thread.id(), + tid, + signum + ); + let parent = self.zircon_process().clone(); + match parent.get_child(tid as u64) { + Ok(obj) => { + match signal { + Signal::SIGRT33 => { + let current_tid = self.thread.id(); + if current_tid == (tid as u64) { + // killing myself + self.sys_exit(-1).unwrap(); + } else { + let thread: Arc = obj.downcast_arc().unwrap(); + let mut thread_linux = thread.lock_linux(); + thread_linux.signal_mask.insert(signal); + drop(thread_linux); + } + }, + _ => unimplemented!() + }; + Ok(0) + } + Err(_) => Err(LxError::EINVAL) + } + } + + + + } diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index afefa777..3f9ace0f 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -210,28 +210,6 @@ impl Syscall<'_> { // Ok(0) // } // - // /// Kill the process - // pub fn sys_kill(&self, pid: usize, sig: usize) -> SysResult { - // info!( - // "kill: thread {} kill process {} with signal {}", - // thread::current().id(), - // pid, - // sig - // ); - // let current_pid = self.process().pid.get().clone(); - // if current_pid == pid { - // // killing myself - // self.sys_exit_group(sig); - // } else { - // if let Some(proc_arc) = PROCESSES.read().get(&pid).and_then(|weak| weak.upgrade()) { - // let mut proc = proc_arc.lock(); - // proc.exit(sig); - // Ok(0) - // } else { - // Err(LxError::EINVAL) - // } - // } - // } /// Get the current thread ID. pub fn sys_gettid(&self) -> SysResult { diff --git a/loader/src/linux.rs b/loader/src/linux.rs index eafd319f..4654ee28 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -59,6 +59,12 @@ async fn run_user(thread: CurrentThread) { break; } + // check the signal if was killed + if thread.inner().lock_linux().signal_mask.contains(linux_object::signal::Signal::SIGRT33) { + thread.exit_linux(-1); + // do not break temporarily + } + // run trace!("go to user: {:#x?}", ctx); ctx.enter_uspace(); From a55017a967d8f6ee63bd3d3e7c2e1fe16e876459 Mon Sep 17 00:00:00 2001 From: liusm18 Date: Fri, 1 Apr 2022 10:54:06 +0800 Subject: [PATCH 03/35] Implement sys_tgkill --- linux-syscall/src/lib.rs | 2 +- linux-syscall/src/signal.rs | 50 ++++++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 483fad3d..2f671e96 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -392,7 +392,7 @@ impl Syscall<'_> { self.sys_futex(a0, a1 as _, a2 as _, a3).await } Sys::TKILL => self.sys_tkill(a0, a1), - Sys::TGKILL => self.unimplemented("tgkill", Ok(0)), + Sys::TGKILL => self.sys_tgkill(a0, a1, a2), // time Sys::NANOSLEEP => self.sys_nanosleep(self.into_in_userptr(a0).unwrap()).await, diff --git a/linux-syscall/src/signal.rs b/linux-syscall/src/signal.rs index da7678be..bd4f27c7 100644 --- a/linux-syscall/src/signal.rs +++ b/linux-syscall/src/signal.rs @@ -10,7 +10,6 @@ use super::*; use linux_object::signal::{Signal, SignalAction, SignalStack, SignalStackFlags, Sigset}; use linux_object::thread::ThreadExt; -use zircon_object::object::Signal as ZirconSignal; use numeric_enum_macro::numeric_enum; impl Syscall<'_> { @@ -145,7 +144,16 @@ impl Syscall<'_> { match parent.job().get_child(pid as u64) { Ok(obj) => { match signal { - Signal::SIGKILL => obj.signal_set(ZirconSignal::PROCESS_TERMINATED), + Signal::SIGKILL => { + let current_pid = parent.id(); + if current_pid == (pid as u64) { + // killing myself + parent.exit(-1); + } else { + let process: Arc = obj.downcast_arc().unwrap(); + process.exit(-1); + } + } _ => unimplemented!() }; Ok(0) @@ -158,7 +166,7 @@ impl Syscall<'_> { } - /// Send a signal to a process specified by pid + /// Send a signal to a thread specified by tid /// TODO: support all the signals pub fn sys_tkill(&mut self, tid: usize, signum: usize) -> SysResult { // Other signals except SIGKILL are not supported @@ -193,6 +201,42 @@ impl Syscall<'_> { } } + /// Send a signal to a thread specified by tgid (i.e., process) and pid + /// TODO: support all the signals + pub fn sys_tgkill(&mut self, tgid: usize, tid: usize, signum: usize) -> SysResult { + // Other signals except SIGKILL are not supported + let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; + info!( + "tkill: thread {} kill thread {} in process {} with signal {:?}", + self.thread.id(), + tid, + tgid, + signum + ); + let parent = self.zircon_process().clone(); + match parent.job().get_child(tgid as u64).map(|proc| proc.get_child(tid as u64)) { + Ok(Ok(obj)) => { + match signal { + Signal::SIGRT33 => { + let current_tgid = parent.id(); + let current_tid = self.thread.id(); + if current_tgid == (tgid as u64) && current_tid == (tid as u64) { + // killing myself + self.sys_exit(-1).unwrap(); + } else { + let thread: Arc = obj.downcast_arc().unwrap(); + let mut thread_linux = thread.lock_linux(); + thread_linux.signal_mask.insert(signal); + drop(thread_linux); + } + }, + _ => unimplemented!() + }; + Ok(0) + } + _ => Err(LxError::EINVAL) + } + } From 65eec60ac679e057d02ac5944504b4958d97c9b6 Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Sun, 3 Apr 2022 00:04:48 +0800 Subject: [PATCH 04/35] Try to fix mutex and robust (still have bugs) --- linux-object/src/error.rs | 3 ++ linux-object/src/lib.rs | 2 +- linux-object/src/process.rs | 24 +++++---- linux-object/src/thread.rs | 48 +++++++++++++++++- linux-syscall/Cargo.toml | 4 ++ linux-syscall/src/lib.rs | 36 ++++++++++++-- linux-syscall/src/misc.rs | 83 +++++++++++++++++++++++-------- linux-syscall/src/task.rs | 28 ++++++++++- loader/src/linux.rs | 2 + zircon-object/src/lib.rs | 2 +- zircon-object/src/signal/futex.rs | 10 ++-- 11 files changed, 198 insertions(+), 44 deletions(-) diff --git a/linux-object/src/error.rs b/linux-object/src/error.rs index c1f970ff..12d2f5ad 100644 --- a/linux-object/src/error.rs +++ b/linux-object/src/error.rs @@ -111,6 +111,8 @@ pub enum LxError { EISCONN = 106, /// Transport endpoint is not connected ENOTCONN = 107, + /// Connection timeout + ETIMEDOUT = 110, /// Connection refused ECONNREFUSED = 111, } @@ -184,6 +186,7 @@ impl From for LxError { ZxError::SHOULD_WAIT => LxError::EAGAIN, ZxError::PEER_CLOSED => LxError::EPIPE, ZxError::BAD_HANDLE => LxError::EBADF, + ZxError::TIMED_OUT => LxError::ETIMEDOUT, _ => unimplemented!("unknown error type: {:?}", e), } } diff --git a/linux-object/src/lib.rs b/linux-object/src/lib.rs index 72264f41..6b35c143 100644 --- a/linux-object/src/lib.rs +++ b/linux-object/src/lib.rs @@ -1,7 +1,7 @@ //! Linux kernel objects #![no_std] -#![deny(warnings, unsafe_code, missing_docs)] +// #![deny(warnings, unsafe_code, missing_docs)] #![allow(clippy::upper_case_acronyms)] #![allow(clippy::uninit_vec)] #![feature(bool_to_option)] diff --git a/linux-object/src/process.rs b/linux-object/src/process.rs index f32ea322..8c455b27 100644 --- a/linux-object/src/process.rs +++ b/linux-object/src/process.rs @@ -241,17 +241,21 @@ impl LinuxProcess { /// Get futex object. #[allow(unsafe_code)] - pub fn get_futex(&self, uaddr: VirtAddr) -> Arc { + pub fn get_futex(&self, uaddr: VirtAddr) -> Option> { let mut inner = self.inner.lock(); - inner - .futexes - .entry(uaddr) - .or_insert_with(|| { - // FIXME: check address - let value = unsafe { &*(uaddr as *const AtomicI32) }; - Futex::new(value) - }) - .clone() + // if uaddr == 683520 { + // return None; + // } + Some( + inner + .futexes + .entry(uaddr) + .or_insert_with(|| { + let value = unsafe { &*(uaddr as *const AtomicI32) }; + Futex::new(value) + }) + .clone(), + ) } /// Get lowest free fd diff --git a/linux-object/src/thread.rs b/linux-object/src/thread.rs index bd22e51b..b792d04b 100644 --- a/linux-object/src/thread.rs +++ b/linux-object/src/thread.rs @@ -1,9 +1,11 @@ //! Linux Thread +use crate::error::LxError; +use crate::error::SysResult; use crate::process::ProcessExt; use crate::signal::{SignalStack, Sigset}; use alloc::sync::Arc; -use kernel_hal::user::{Out, UserOutPtr, UserPtr}; +use kernel_hal::user::{Out, UserInPtr, UserOutPtr, UserPtr}; use kernel_hal::VirtAddr; use spin::{Mutex, MutexGuard}; use zircon_object::task::{CurrentThread, Process, Thread}; @@ -17,6 +19,14 @@ pub trait ThreadExt { fn lock_linux(&self) -> MutexGuard<'_, LinuxThread>; /// Set pointer to thread ID. fn set_tid_address(&self, tidptr: UserOutPtr); + /// Get robust list. + fn get_robust_list( + &self, + head_ptr: UserOutPtr>, + len_ptr: UserOutPtr, + ) -> SysResult; + /// Set robust list. + fn set_robust_list(&self, head: UserInPtr, len: usize); } /// CurrentThread extension for linux @@ -31,6 +41,8 @@ impl ThreadExt for Thread { clear_child_tid: 0.into(), signal_mask: Sigset::default(), signal_alternate_stack: SignalStack::default(), + robust_list: 0.into(), + robust_list_len: 0, }); Thread::create_with_ext(proc, "", linux_thread) } @@ -46,6 +58,24 @@ impl ThreadExt for Thread { fn set_tid_address(&self, tidptr: UserPtr) { self.lock_linux().clear_child_tid = tidptr; } + + fn get_robust_list( + &self, + mut head_ptr: UserOutPtr>, + mut len_ptr: UserOutPtr, + ) -> SysResult { + // if self.lock_linux().robust_list_len == 0 { + // return Err(LxError::EFAULT); + // } + head_ptr = (self.lock_linux().robust_list.as_ptr() as *mut RobustList as usize).into(); + len_ptr = (&self.lock_linux().robust_list_len as *const usize as usize).into(); + Ok(0) + } + + fn set_robust_list(&self, head: UserInPtr, len: usize) { + self.lock_linux().robust_list = head; + self.lock_linux().robust_list_len = len; + } } impl CurrentThreadExt for CurrentThread { @@ -59,13 +89,24 @@ impl CurrentThreadExt for CurrentThread { info!("exit: do futex {:?} wake 1", clear_child_tid); clear_child_tid.write(0).unwrap(); let uaddr = clear_child_tid.as_ptr() as VirtAddr; - let futex = self.proc().linux().get_futex(uaddr); + let futex = self.proc().linux().get_futex(uaddr).unwrap(); futex.wake(1); } self.exit(); } } +/// robust_list +#[derive(Default)] +pub struct RobustList { + /// head + head: usize, + /// off + pub off: isize, + /// pending + pending: usize, +} + /// Linux specific thread information. pub struct LinuxThread { /// Kernel performs futex wake when thread exits. @@ -75,4 +116,7 @@ pub struct LinuxThread { pub signal_mask: Sigset, /// signal alternate stack pub signal_alternate_stack: SignalStack, + /// robust_list + robust_list: UserInPtr, + robust_list_len: usize, } diff --git a/linux-syscall/Cargo.toml b/linux-syscall/Cargo.toml index 4a5fad9a..e3c73a29 100644 --- a/linux-syscall/Cargo.toml +++ b/linux-syscall/Cargo.toml @@ -18,3 +18,7 @@ kernel-hal = { path = "../kernel-hal", default-features = false } rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } lazy_static = { version = "1.4", features = ["spin_no_std"] } bitvec = { version = "0.22", default-features = false, features = ["alloc"] } +futures = { version = "0.3", default-features = false, features = ["alloc", "async-await"] } + +[dev-dependencies] +async-std = { version = "1.10", features = ["unstable"] } diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index aebabc9c..a170c69d 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -15,7 +15,7 @@ //! #![no_std] -#![deny(warnings, unsafe_code, missing_docs)] +// #![deny(warnings, unsafe_code, missing_docs)] #![allow(clippy::upper_case_acronyms)] #[macro_use] @@ -29,8 +29,7 @@ use core::convert::TryFrom; use kernel_hal::user::{IoVecIn, IoVecOut, UserInOutPtr, UserInPtr, UserOutPtr}; #[cfg(target_os = "none")] -use kernel_hal::vm::PagingError; -use kernel_hal::vm::PagingResult; +use kernel_hal::vm::{PagingError, PagingResult}; use kernel_hal::MMUFlags; use linux_object::error::{LxError, SysResult}; use linux_object::fs::FileDesc; @@ -389,9 +388,38 @@ impl Syscall<'_> { Sys::SET_TID_ADDRESS => self.sys_set_tid_address(self.into_out_userptr(a0).unwrap()), Sys::FUTEX => { // ignore timeout argument when op is wake - self.sys_futex(a0, a1 as _, a2 as _, a3).await + warn!( + "All futex parameters: {}, {}, {}, {}, {}, {}", + a0, a1, a2, a3, a4, a5 + ); + let ret: Result, PagingError> = self.into_inout_userptr(a0); + match ret { + Ok(value) => { + let ret = self.sys_futex(a0, a1 as _, a2 as _, a3).await; + warn!("Out from futex!!!"); + ret + } + Err(err) => { + warn!("Futex err: {:?}", err); + Ok(0) + } + } } + // Sys::FUTEX => self.unimplemented("futex", Ok(0)), Sys::TKILL => self.unimplemented("tkill", Ok(0)), + Sys::GET_ROBUST_LIST => { + warn!("{},{},{}", a0, a1, a2); + self.sys_get_robust_list( + a0 as _, + self.into_out_userptr(a1).unwrap(), + self.into_out_userptr(a2).unwrap(), + ) + } + // Sys::GET_ROBUST_LIST => self.unimplemented("get_robust_list", Ok(0)), + Sys::SET_ROBUST_LIST => { + self.sys_set_robust_list(self.into_in_userptr(a0).unwrap(), a1 as _) + } + // Sys::SET_ROBUST_LIST => self.unimplemented("set_robust_list", Ok(0)), // time Sys::NANOSLEEP => self.sys_nanosleep(self.into_in_userptr(a0).unwrap()).await, diff --git a/linux-syscall/src/misc.rs b/linux-syscall/src/misc.rs index b5cf5d4d..5c543f2f 100644 --- a/linux-syscall/src/misc.rs +++ b/linux-syscall/src/misc.rs @@ -1,6 +1,13 @@ use super::*; use bitflags::bitflags; +use core::time::Duration; +use futures::pin_mut; +use kernel_hal::timer::timer_now; use linux_object::time::*; +use zircon_object::{ + task::{IntoResult, ThreadState}, + ZxResult, +}; impl Syscall<'_> { #[cfg(target_arch = "x86_64")] @@ -73,7 +80,7 @@ impl Syscall<'_> { &self, uaddr: usize, op: u32, - val: i32, + val: u32, timeout_addr: usize, ) -> SysResult { let op = FutexFlags::from_bits_truncate(op); @@ -86,33 +93,65 @@ impl Syscall<'_> { Err(_e) => return Err(LxError::EACCES), } }; - info!( - "futex: uaddr: {:#x}, op: {:?}, val: {}, timeout_ptr: {:?}", - uaddr, op, val, timeout + warn!( + "Futex: uaddr: {:#x}, op: {}, val: {}, timeout_ptr: {:?}", + uaddr, + op.bits(), + val, + timeout ); if op.contains(FutexFlags::PRIVATE) { warn!("process-shared futex is unimplemented"); } - let futex = self.linux_process().get_futex(uaddr); - match op.bits & 0xf { - 0 => { - // FIXME: support timeout - let _timeout = timeout.read_if_not_null()?; - match futex.wait(val).await { - Ok(_) => Ok(0), - Err(ZxError::BAD_STATE) => Err(LxError::EAGAIN), - Err(e) => Err(e.into()), + let futex_op = self.linux_process().get_futex(uaddr); + match futex_op { + Some(futex) => { + match op.bits & 0xf { + 0 => { + // FIXME: support timeout + let _timeout = timeout.read_if_not_null()?; + let dur: Duration = match _timeout { + Some(T) => T.into(), + None => Duration::from_secs(0), + }; + if dur.as_millis() == 0 { + match futex.wait(val).await { + Ok(_) => { + return Ok(0); + } + Err(ZxError::BAD_STATE) => { + return Err(LxError::EAGAIN); + } + Err(e) => { + return Err(e.into()); + } + } + } + warn!("dur: {:?}", dur); + let future = futex.wait(val); + pin_mut!(future); + self.thread + .blocking_run( + future, + ThreadState::BlockedFutex, + timer_now() + dur, + None, + ) + .await?; + Ok(0) + } + 1 => { + let woken_up_count = futex.wake(val as usize); + Ok(woken_up_count) + } + _ => { + warn!("unsupported futex operation: {:?}", op); + Err(LxError::ENOSYS) + } } } - 1 => { - let woken_up_count = futex.wake(val as usize); - Ok(woken_up_count) - } - _ => { - warn!("unsupported futex operation: {:?}", op); - Err(LxError::ENOSYS) - } + None => Err(LxError::EAGAIN), } } @@ -179,6 +218,8 @@ bitflags! { const WAIT = 0; /// wakes at most val of the waiters that are waiting on the futex word at the address uaddr. const WAKE = 1; + const LOCK_PI = 6; + const UNLOCK_PI = 7; /// can be employed with all futex operations, tells the kernel that the futex is process-private and not shared with another process const PRIVATE = 0x80; } diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index afefa777..d473be93 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -11,11 +11,12 @@ use super::*; use core::fmt::Debug; +use core::mem::size_of; use bitflags::bitflags; use kernel_hal::context::UserContextField; -use linux_object::thread::{CurrentThreadExt, ThreadExt}; +use linux_object::thread::{CurrentThreadExt, RobustList, ThreadExt}; use linux_object::time::TimeSpec; use linux_object::{fs::INodeExt, loader::LinuxElfLoader}; @@ -295,6 +296,31 @@ impl Syscall<'_> { let tid = self.thread.id(); Ok(tid as usize) } + + pub fn sys_get_robust_list( + &self, + pid: i32, + head_ptr: UserOutPtr>, + len_ptr: UserOutPtr, + ) -> SysResult { + warn!("in1 sys_get_robust_list"); + if pid == 0 { + warn!("in2 sys_get_robust_list"); + return self.thread.get_robust_list(head_ptr, len_ptr); + } else { + warn!("out sys_get_robust_list"); + } + Ok(0) + } + + pub fn sys_set_robust_list(&self, head: UserInPtr, len: usize) -> SysResult { + warn!("in sys_set_robust_list"); + if len != size_of::().into() { + return Err(LxError::EINVAL); + } + self.thread.set_robust_list(head, len); + Ok(0) + } } bitflags! { diff --git a/loader/src/linux.rs b/loader/src/linux.rs index eafd319f..a572f652 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -64,6 +64,8 @@ async fn run_user(thread: CurrentThread) { ctx.enter_uspace(); trace!("back from user: {:#x?}", ctx); + info!("into kernel: thread id = {}", thread.id()); + // handle trap/interrupt/syscall if let Err(err) = handle_user_trap(&thread, ctx).await { thread.exit_linux(err as i32); diff --git a/zircon-object/src/lib.rs b/zircon-object/src/lib.rs index 69a35225..87e62294 100644 --- a/zircon-object/src/lib.rs +++ b/zircon-object/src/lib.rs @@ -6,7 +6,7 @@ //! - `hypervisor`: Enables `zircon_object::hypervisor` (`Guest` and `Vcpu`). #![no_std] -#![deny(warnings, unsafe_code, unused_must_use, missing_docs)] +// #![deny(warnings, unsafe_code, unused_must_use, missing_docs)] #![feature(drain_filter)] #![feature(get_mut_unchecked)] diff --git a/zircon-object/src/signal/futex.rs b/zircon-object/src/signal/futex.rs index f1241123..fad30c64 100644 --- a/zircon-object/src/signal/futex.rs +++ b/zircon-object/src/signal/futex.rs @@ -57,7 +57,7 @@ impl Futex { /// /// [`wait_with_owner`]: Futex::wait_with_owner /// [`wake`]: Futex::wake - pub fn wait(self: &Arc, current_value: i32) -> impl Future { + pub fn wait(self: &Arc, current_value: u32) -> impl Future { self.wait_with_owner(current_value, None, None) } @@ -114,14 +114,14 @@ impl Futex { /// [`wake`]: Futex::wake pub fn wait_with_owner( self: &Arc, - current_value: i32, + current_value: u32, thread: Option>, new_owner: Option>, ) -> impl Future { #[must_use = "wait does nothing unless polled/`await`-ed"] struct FutexFuture { waiter: Arc, - current_value: i32, + current_value: u32, new_owner: Option>, } impl Future for FutexFuture { @@ -139,7 +139,8 @@ impl Futex { if inner.waker.is_none() { // check value let value = inner.futex.value.load(Ordering::SeqCst); - if value != self.current_value { + if value as u32 != self.current_value { + warn!("Futex BAD STATE"); return Poll::Ready(Err(ZxError::BAD_STATE)); } // check new owner @@ -151,6 +152,7 @@ impl Futex { drop(futex); inner.waker.replace(cx.waker().clone()); } + warn!("Futex pending!!!"); Poll::Pending } } From d6687d9a65dd2d4be37b0df10339a91afb71fa25 Mon Sep 17 00:00:00 2001 From: DeathWish5 Date: Sun, 3 Apr 2022 18:38:55 +0800 Subject: [PATCH 05/35] bug fix: pthread_mutex page fault --- linux-syscall/src/lib.rs | 35 +++------------- linux-syscall/src/misc.rs | 85 ++++++++++++++++++++------------------- linux-syscall/src/task.rs | 2 +- loader/src/linux.rs | 1 + zCore/Makefile | 6 +-- zCore/src/utils.rs | 2 + 6 files changed, 55 insertions(+), 76 deletions(-) diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index a170c69d..e04591c0 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -363,17 +363,10 @@ impl Syscall<'_> { } // process - Sys::CLONE => { - // warn!("a2={} a3={}", a2, a3); - // self.sys_clone( - // a0, - // a1, - // self.into_out_userptr(a2).unwrap(), - // self.into_out_userptr(a3).unwrap(), - // a4, - // ) - self.sys_clone(a0, a1, a2.into(), a3.into(), a4) - } + #[cfg(target_arch = "riscv64")] + Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a3, a4.into()), + #[cfg(target_arch = "x86_64")] + Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a4, a3.into()), Sys::EXECVE => self.sys_execve( self.into_in_userptr(a0).unwrap(), self.into_in_userptr(a1).unwrap(), @@ -386,25 +379,7 @@ impl Syscall<'_> { .await } Sys::SET_TID_ADDRESS => self.sys_set_tid_address(self.into_out_userptr(a0).unwrap()), - Sys::FUTEX => { - // ignore timeout argument when op is wake - warn!( - "All futex parameters: {}, {}, {}, {}, {}, {}", - a0, a1, a2, a3, a4, a5 - ); - let ret: Result, PagingError> = self.into_inout_userptr(a0); - match ret { - Ok(value) => { - let ret = self.sys_futex(a0, a1 as _, a2 as _, a3).await; - warn!("Out from futex!!!"); - ret - } - Err(err) => { - warn!("Futex err: {:?}", err); - Ok(0) - } - } - } + Sys::FUTEX => self.sys_futex(a0, a1 as _, a2 as _, a3).await, // Sys::FUTEX => self.unimplemented("futex", Ok(0)), Sys::TKILL => self.unimplemented("tkill", Ok(0)), Sys::GET_ROBUST_LIST => { diff --git a/linux-syscall/src/misc.rs b/linux-syscall/src/misc.rs index 5c543f2f..a2a1839b 100644 --- a/linux-syscall/src/misc.rs +++ b/linux-syscall/src/misc.rs @@ -83,7 +83,15 @@ impl Syscall<'_> { val: u32, timeout_addr: usize, ) -> SysResult { + if let Err(_) = self.into_inout_userptr::(uaddr) { + return Err(LxError::EINVAL); + } let op = FutexFlags::from_bits_truncate(op); + if !op.contains(FutexFlags::PRIVATE) { + warn!("process-shared futex is unimplemented"); + return Err(LxError::ENOPROTOOPT); + } + let op = op - FutexFlags::PRIVATE; let timeout = if op.contains(FutexFlags::WAKE) { self.into_inout_userptr::(0).unwrap() } else { @@ -94,63 +102,54 @@ impl Syscall<'_> { } }; warn!( - "Futex: uaddr: {:#x}, op: {}, val: {}, timeout_ptr: {:?}", + "Futex: uaddr: {:#x}, op: {:x}, val: {}, timeout_ptr: {:x?}", uaddr, op.bits(), val, timeout ); - - if op.contains(FutexFlags::PRIVATE) { - warn!("process-shared futex is unimplemented"); - } let futex_op = self.linux_process().get_futex(uaddr); match futex_op { - Some(futex) => { - match op.bits & 0xf { - 0 => { - // FIXME: support timeout - let _timeout = timeout.read_if_not_null()?; - let dur: Duration = match _timeout { - Some(T) => T.into(), - None => Duration::from_secs(0), - }; - if dur.as_millis() == 0 { - match futex.wait(val).await { - Ok(_) => { - return Ok(0); - } - Err(ZxError::BAD_STATE) => { - return Err(LxError::EAGAIN); - } - Err(e) => { - return Err(e.into()); - } - } - } - warn!("dur: {:?}", dur); - let future = futex.wait(val); + Some(futex) => match op { + FutexFlags::WAIT => { + let timeout = timeout.read_if_not_null()?; + let duration: Duration = match timeout { + Some(T) => T.into(), + None => Duration::from_secs(0), + }; + let into_lxerror = |e: ZxError| match e { + ZxError::BAD_STATE => LxError::EAGAIN, + e => e.into(), + }; + let future = futex.wait(val); + let res = if duration.as_millis() == 0 { + future.await + } else { + warn!("duration: {:?}", duration); pin_mut!(future); self.thread .blocking_run( future, ThreadState::BlockedFutex, - timer_now() + dur, + timer_now() + duration, None, ) - .await?; - Ok(0) - } - 1 => { - let woken_up_count = futex.wake(val as usize); - Ok(woken_up_count) - } - _ => { - warn!("unsupported futex operation: {:?}", op); - Err(LxError::ENOSYS) + .await + }; + match res { + Ok(_) => return Ok(0), + Err(e) => return Err(into_lxerror(e)), } } - } + FutexFlags::WAKE => { + let woken_up_count = futex.wake(val as usize); + Ok(woken_up_count) + } + _ => { + warn!("unsupported futex operation: {:?}", op); + Err(LxError::ENOPROTOOPT) + } + }, None => Err(LxError::EAGAIN), } } @@ -218,7 +217,9 @@ bitflags! { const WAIT = 0; /// wakes at most val of the waiters that are waiting on the futex word at the address uaddr. const WAKE = 1; - const LOCK_PI = 6; + /// + const LOCK_PI = 6; + /// const UNLOCK_PI = 7; /// can be employed with all futex operations, tells the kernel that the futex is process-private and not shared with another process const PRIVATE = 0x80; diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index d473be93..2c99b8b0 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -65,8 +65,8 @@ impl Syscall<'_> { flags: usize, newsp: usize, mut parent_tid: UserOutPtr, - mut child_tid: UserOutPtr, newtls: usize, + mut child_tid: UserOutPtr, ) -> SysResult { let _flags = CloneFlags::from_bits_truncate(flags); info!( diff --git a/loader/src/linux.rs b/loader/src/linux.rs index a572f652..6879459d 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -59,6 +59,7 @@ async fn run_user(thread: CurrentThread) { break; } + info!("back to user: thread id = {}", thread.id()); // run trace!("go to user: {:#x?}", ctx); ctx.enter_uspace(); diff --git a/zCore/Makefile b/zCore/Makefile index 0e73c856..297709b5 100644 --- a/zCore/Makefile +++ b/zCore/Makefile @@ -1,10 +1,10 @@ ################ Arguments ################ -ARCH ?= x86_64 +ARCH ?= riscv64 PLATFORM ?= qemu MODE ?= release -LOG ?= warn -LINUX ?= +LOG ?= info +LINUX ?= 1 LIBOS ?= TEST ?= GRAPHIC ?= diff --git a/zCore/src/utils.rs b/zCore/src/utils.rs index 2b847fea..a8eb7b39 100644 --- a/zCore/src/utils.rs +++ b/zCore/src/utils.rs @@ -61,6 +61,8 @@ pub fn boot_options() -> BootOptions { log_level: String::from(*options.get("LOG").unwrap_or(&"")), #[cfg(feature = "linux")] root_proc: String::from(*options.get("ROOTPROC").unwrap_or(&"/bin/busybox?sh")), + // root_proc: String::from(*options.get("ROOTPROC") + // .unwrap_or(&"/libc-test/functional/pthread_robust.exe")), } } } From 767e9dd745a8bd5abb87ebaafbb53dc05006ec53 Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Mon, 4 Apr 2022 19:30:52 +0800 Subject: [PATCH 06/35] Fix pthread_cond & pthread_tsd & ... --- linux-object/src/lib.rs | 2 +- linux-object/src/process.rs | 23 ++--- linux-object/src/thread.rs | 22 ++--- linux-syscall/src/lib.rs | 16 ++-- linux-syscall/src/misc.rs | 144 ++++++++++++++++++++---------- linux-syscall/src/task.rs | 2 + loader/src/linux.rs | 1 + zCore/src/utils.rs | 2 +- zircon-object/src/signal/futex.rs | 44 +++++++-- zircon-syscall/src/futex.rs | 1 + 10 files changed, 164 insertions(+), 93 deletions(-) diff --git a/linux-object/src/lib.rs b/linux-object/src/lib.rs index 6b35c143..72264f41 100644 --- a/linux-object/src/lib.rs +++ b/linux-object/src/lib.rs @@ -1,7 +1,7 @@ //! Linux kernel objects #![no_std] -// #![deny(warnings, unsafe_code, missing_docs)] +#![deny(warnings, unsafe_code, missing_docs)] #![allow(clippy::upper_case_acronyms)] #![allow(clippy::uninit_vec)] #![feature(bool_to_option)] diff --git a/linux-object/src/process.rs b/linux-object/src/process.rs index 8c455b27..e63568f2 100644 --- a/linux-object/src/process.rs +++ b/linux-object/src/process.rs @@ -241,21 +241,16 @@ impl LinuxProcess { /// Get futex object. #[allow(unsafe_code)] - pub fn get_futex(&self, uaddr: VirtAddr) -> Option> { + pub fn get_futex(&self, uaddr: VirtAddr) -> Arc { let mut inner = self.inner.lock(); - // if uaddr == 683520 { - // return None; - // } - Some( - inner - .futexes - .entry(uaddr) - .or_insert_with(|| { - let value = unsafe { &*(uaddr as *const AtomicI32) }; - Futex::new(value) - }) - .clone(), - ) + inner + .futexes + .entry(uaddr) + .or_insert_with(|| { + let value = unsafe { &*(uaddr as *const AtomicI32) }; + Futex::new(value) + }) + .clone() } /// Get lowest free fd diff --git a/linux-object/src/thread.rs b/linux-object/src/thread.rs index b792d04b..e435207b 100644 --- a/linux-object/src/thread.rs +++ b/linux-object/src/thread.rs @@ -1,6 +1,5 @@ //! Linux Thread -use crate::error::LxError; use crate::error::SysResult; use crate::process::ProcessExt; use crate::signal::{SignalStack, Sigset}; @@ -22,8 +21,8 @@ pub trait ThreadExt { /// Get robust list. fn get_robust_list( &self, - head_ptr: UserOutPtr>, - len_ptr: UserOutPtr, + _head_ptr: UserOutPtr>, + _len_ptr: UserOutPtr, ) -> SysResult; /// Set robust list. fn set_robust_list(&self, head: UserInPtr, len: usize); @@ -61,14 +60,11 @@ impl ThreadExt for Thread { fn get_robust_list( &self, - mut head_ptr: UserOutPtr>, - mut len_ptr: UserOutPtr, + mut _head_ptr: UserOutPtr>, + mut _len_ptr: UserOutPtr, ) -> SysResult { - // if self.lock_linux().robust_list_len == 0 { - // return Err(LxError::EFAULT); - // } - head_ptr = (self.lock_linux().robust_list.as_ptr() as *mut RobustList as usize).into(); - len_ptr = (&self.lock_linux().robust_list_len as *const usize as usize).into(); + _head_ptr = (self.lock_linux().robust_list.as_ptr() as *mut RobustList as usize).into(); + _len_ptr = (&self.lock_linux().robust_list_len as *const usize as usize).into(); Ok(0) } @@ -89,7 +85,7 @@ impl CurrentThreadExt for CurrentThread { info!("exit: do futex {:?} wake 1", clear_child_tid); clear_child_tid.write(0).unwrap(); let uaddr = clear_child_tid.as_ptr() as VirtAddr; - let futex = self.proc().linux().get_futex(uaddr).unwrap(); + let futex = self.proc().linux().get_futex(uaddr); futex.wake(1); } self.exit(); @@ -100,11 +96,11 @@ impl CurrentThreadExt for CurrentThread { #[derive(Default)] pub struct RobustList { /// head - head: usize, + pub head: usize, /// off pub off: isize, /// pending - pending: usize, + pub pending: usize, } /// Linux specific thread information. diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index e04591c0..0caba9c8 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -15,7 +15,7 @@ //! #![no_std] -// #![deny(warnings, unsafe_code, missing_docs)] +#![deny(warnings, unsafe_code, missing_docs)] #![allow(clippy::upper_case_acronyms)] #[macro_use] @@ -363,10 +363,6 @@ impl Syscall<'_> { } // process - #[cfg(target_arch = "riscv64")] - Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a3, a4.into()), - #[cfg(target_arch = "x86_64")] - Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a4, a3.into()), Sys::EXECVE => self.sys_execve( self.into_in_userptr(a0).unwrap(), self.into_in_userptr(a1).unwrap(), @@ -379,7 +375,10 @@ impl Syscall<'_> { .await } Sys::SET_TID_ADDRESS => self.sys_set_tid_address(self.into_out_userptr(a0).unwrap()), - Sys::FUTEX => self.sys_futex(a0, a1 as _, a2 as _, a3).await, + Sys::FUTEX => { + info!("Futex: {} {} {} {} {} {}", a0, a1, a2, a3, a4, a5); + self.sys_futex(a0, a1 as _, a2 as _, a3, a4, a5 as _).await + } // Sys::FUTEX => self.unimplemented("futex", Ok(0)), Sys::TKILL => self.unimplemented("tkill", Ok(0)), Sys::GET_ROBUST_LIST => { @@ -532,6 +531,7 @@ impl Syscall<'_> { Sys::CHOWN => self.unimplemented("chown", Ok(0)), Sys::ARCH_PRCTL => self.sys_arch_prctl(a0 as _, a1), Sys::TIME => self.sys_time(self.into_out_userptr(a0).unwrap()), + Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a4, a3.into()), // Sys::EPOLL_CREATE => self.sys_epoll_create(a0), // Sys::EPOLL_WAIT => self.sys_epoll_wait(a0, a1.into(), a2, a3), _ => self.unknown_syscall(sys_type), @@ -540,10 +540,10 @@ impl Syscall<'_> { #[cfg(target_arch = "riscv64")] async fn riscv64_syscall(&mut self, sys_type: Sys, args: [usize; 6]) -> SysResult { - debug!("riscv64_syscall: {:?}, {:?}", sys_type, args); - //let [a0, a1, a2, a3, a4, _a5] = args; + let [a0, a1, a2, a3, a4, _a5] = args; match sys_type { //Sys::OPEN => self.sys_open(a0.into(), a1, a2), + Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a3, a4.into()), _ => self.unknown_syscall(sys_type), } } diff --git a/linux-syscall/src/misc.rs b/linux-syscall/src/misc.rs index a2a1839b..1b2d2ee7 100644 --- a/linux-syscall/src/misc.rs +++ b/linux-syscall/src/misc.rs @@ -4,10 +4,7 @@ use core::time::Duration; use futures::pin_mut; use kernel_hal::timer::timer_now; use linux_object::time::*; -use zircon_object::{ - task::{IntoResult, ThreadState}, - ZxResult, -}; +use zircon_object::task::ThreadState; impl Syscall<'_> { #[cfg(target_arch = "x86_64")] @@ -82,6 +79,8 @@ impl Syscall<'_> { op: u32, val: u32, timeout_addr: usize, + uaddr2: usize, + _val3: u32, ) -> SysResult { if let Err(_) = self.into_inout_userptr::(uaddr) { return Err(LxError::EINVAL); @@ -89,9 +88,15 @@ impl Syscall<'_> { let op = FutexFlags::from_bits_truncate(op); if !op.contains(FutexFlags::PRIVATE) { warn!("process-shared futex is unimplemented"); - return Err(LxError::ENOPROTOOPT); + // return Err(LxError::ENOPROTOOPT); + } + let mut val2 = 0; + if op.contains(FutexFlags::REQUEUE) { + if let Err(_) = self.into_inout_userptr::(uaddr2) { + return Err(LxError::EINVAL); + } + val2 = timeout_addr; } - let op = op - FutexFlags::PRIVATE; let timeout = if op.contains(FutexFlags::WAKE) { self.into_inout_userptr::(0).unwrap() } else { @@ -102,55 +107,96 @@ impl Syscall<'_> { } }; warn!( - "Futex: uaddr: {:#x}, op: {:x}, val: {}, timeout_ptr: {:x?}", + "Futex: uaddr: {:#x}, op: {:x}, val: {}, timeout_ptr: {:x?}, val2: {}", uaddr, op.bits(), val, - timeout + timeout, + val2, ); - let futex_op = self.linux_process().get_futex(uaddr); - match futex_op { - Some(futex) => match op { - FutexFlags::WAIT => { - let timeout = timeout.read_if_not_null()?; - let duration: Duration = match timeout { - Some(T) => T.into(), - None => Duration::from_secs(0), - }; - let into_lxerror = |e: ZxError| match e { - ZxError::BAD_STATE => LxError::EAGAIN, - e => e.into(), - }; - let future = futex.wait(val); - let res = if duration.as_millis() == 0 { - future.await - } else { - warn!("duration: {:?}", duration); - pin_mut!(future); - self.thread - .blocking_run( - future, - ThreadState::BlockedFutex, - timer_now() + duration, - None, - ) - .await - }; - match res { - Ok(_) => return Ok(0), - Err(e) => return Err(into_lxerror(e)), - } + let futex = self.linux_process().get_futex(uaddr); + let op = op - FutexFlags::PRIVATE; + match op { + FutexFlags::WAIT => { + let timeout = timeout.read_if_not_null()?; + let duration: Duration = match timeout { + Some(t) => t.into(), + None => Duration::from_secs(0), + }; + let into_lxerror = |e: ZxError| match e { + ZxError::BAD_STATE => LxError::EAGAIN, + e => e.into(), + }; + let future = futex.wait(val, false, self.thread.id() as i32); + let res = if duration.as_millis() == 0 { + future.await + } else { + warn!("duration: {:?}", duration); + pin_mut!(future); + self.thread + .blocking_run( + future, + ThreadState::BlockedFutex, + timer_now() + duration, + None, + ) + .await + }; + match res { + Ok(_) => return Ok(0), + Err(e) => return Err(into_lxerror(e)), } - FutexFlags::WAKE => { - let woken_up_count = futex.wake(val as usize); - Ok(woken_up_count) + } + FutexFlags::WAKE => { + let woken_up_count = futex.wake(val as usize); + Ok(woken_up_count) + } + FutexFlags::LOCK_PI => { + let timeout = timeout.read_if_not_null()?; + let duration: Duration = match timeout { + Some(t) => t.into(), + None => Duration::from_secs(0), + }; + let into_lxerror = |e: ZxError| match e { + ZxError::BAD_STATE => LxError::EAGAIN, + e => e.into(), + }; + let future = futex.wait(val, true, self.thread.id() as i32); + let res = if duration.as_millis() == 0 { + future.await + } else { + warn!("duration: {:?}", duration); + pin_mut!(future); + self.thread + .blocking_run( + future, + ThreadState::BlockedFutex, + timer_now() + duration, + None, + ) + .await + }; + match res { + Ok(_) => return Ok(0), + Err(e) => return Err(into_lxerror(e)), } - _ => { - warn!("unsupported futex operation: {:?}", op); - Err(LxError::ENOPROTOOPT) + } + FutexFlags::REQUEUE => { + let requeue_futex = self.linux_process().get_futex(uaddr2); + let into_lxerror = |e: ZxError| match e { + ZxError::BAD_STATE => LxError::EAGAIN, + e => e.into(), + }; + let res = futex.requeue(0, val as usize, val2, &requeue_futex, None, false); + match res { + Ok(_) => return Ok(0), + Err(e) => return Err(into_lxerror(e)), } - }, - None => Err(LxError::EAGAIN), + } + _ => { + warn!("unsupported futex operation: {:?}", op); + Err(LxError::ENOPROTOOPT) + } } } @@ -218,6 +264,8 @@ bitflags! { /// wakes at most val of the waiters that are waiting on the futex word at the address uaddr. const WAKE = 1; /// + const REQUEUE = 3; + /// const LOCK_PI = 6; /// const UNLOCK_PI = 7; diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index 2c99b8b0..e2335573 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -297,6 +297,7 @@ impl Syscall<'_> { Ok(tid as usize) } + /// Get robust list. pub fn sys_get_robust_list( &self, pid: i32, @@ -313,6 +314,7 @@ impl Syscall<'_> { Ok(0) } + /// Set robust list. pub fn sys_set_robust_list(&self, head: UserInPtr, len: usize) -> SysResult { warn!("in sys_set_robust_list"); if len != size_of::().into() { diff --git a/loader/src/linux.rs b/loader/src/linux.rs index 6879459d..82545eeb 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -60,6 +60,7 @@ async fn run_user(thread: CurrentThread) { } info!("back to user: thread id = {}", thread.id()); + // run trace!("go to user: {:#x?}", ctx); ctx.enter_uspace(); diff --git a/zCore/src/utils.rs b/zCore/src/utils.rs index a8eb7b39..74c78364 100644 --- a/zCore/src/utils.rs +++ b/zCore/src/utils.rs @@ -62,7 +62,7 @@ pub fn boot_options() -> BootOptions { #[cfg(feature = "linux")] root_proc: String::from(*options.get("ROOTPROC").unwrap_or(&"/bin/busybox?sh")), // root_proc: String::from(*options.get("ROOTPROC") - // .unwrap_or(&"/libc-test/functional/pthread_robust.exe")), + // .unwrap_or(&"/libc-test/functional/pthread_mutex.exe")), } } } diff --git a/zircon-object/src/signal/futex.rs b/zircon-object/src/signal/futex.rs index fad30c64..a2e943e8 100644 --- a/zircon-object/src/signal/futex.rs +++ b/zircon-object/src/signal/futex.rs @@ -57,8 +57,13 @@ impl Futex { /// /// [`wait_with_owner`]: Futex::wait_with_owner /// [`wake`]: Futex::wake - pub fn wait(self: &Arc, current_value: u32) -> impl Future { - self.wait_with_owner(current_value, None, None) + pub fn wait( + self: &Arc, + current_value: u32, + lock_pi: bool, + thread_id: i32, + ) -> impl Future { + self.wait_with_owner(current_value, None, None, lock_pi, thread_id) } /// Wake some number of threads waiting on a futex. @@ -117,12 +122,16 @@ impl Futex { current_value: u32, thread: Option>, new_owner: Option>, + lock_pi: bool, + thread_id: i32, ) -> impl Future { #[must_use = "wait does nothing unless polled/`await`-ed"] struct FutexFuture { waiter: Arc, current_value: u32, new_owner: Option>, + lock_pi: bool, + thread_id: i32, } impl Future for FutexFuture { type Output = ZxResult; @@ -133,15 +142,29 @@ impl Futex { if inner.woken { // set new owner on success inner.futex.inner.lock().set_owner(self.new_owner.clone()); + warn!("Futex Ready!!!"); return Poll::Ready(Ok(())); } // first time? if inner.waker.is_none() { // check value let value = inner.futex.value.load(Ordering::SeqCst); - if value as u32 != self.current_value { - warn!("Futex BAD STATE"); - return Poll::Ready(Err(ZxError::BAD_STATE)); + if self.lock_pi { + if value as u32 == 0 { + warn!("This is {}", self.thread_id); + inner.futex.value.store(self.thread_id, Ordering::SeqCst); + } else { + inner + .futex + .value + .store((value as u32 | 0x80000000) as i32, Ordering::SeqCst); + } + return Poll::Ready(Ok(())); + } else { + if value as u32 != self.current_value { + warn!("Futex BAD_STATE!!!"); + return Poll::Ready(Err(ZxError::BAD_STATE)); + } } // check new owner let mut futex = inner.futex.inner.lock(); @@ -182,6 +205,8 @@ impl Futex { }), current_value, new_owner, + lock_pi, + thread_id, } } @@ -224,11 +249,14 @@ impl Futex { requeue_count: usize, requeue_futex: &Arc, new_requeue_owner: Option>, + check_value: bool, ) -> ZxResult { let mut inner = self.inner.lock(); - // check value - if self.value.load(Ordering::SeqCst) != current_value { - return Err(ZxError::BAD_STATE); + if check_value { + // check value + if self.value.load(Ordering::SeqCst) != current_value { + return Err(ZxError::BAD_STATE); + } } // wake for _ in 0..wake_count { diff --git a/zircon-syscall/src/futex.rs b/zircon-syscall/src/futex.rs index 726d7479..76950c33 100644 --- a/zircon-syscall/src/futex.rs +++ b/zircon-syscall/src/futex.rs @@ -74,6 +74,7 @@ impl Syscall<'_> { requeue_count as usize, &requeue_futex, new_requeue_owner, + true, )?; Ok(()) } From 9caed0218294d7a44790d60d82cddb59e0155c32 Mon Sep 17 00:00:00 2001 From: liusm18 Date: Tue, 5 Apr 2022 07:44:57 +0800 Subject: [PATCH 07/35] Implement signals --- kernel-hal/src/common/context.rs | 30 ++++-- linux-object/src/fs/mod.rs | 4 +- linux-object/src/signal/action.rs | 15 +++ linux-object/src/signal/mod.rs | 163 +++++++++++++++++++++++------- linux-object/src/thread.rs | 31 +++++- linux-syscall/src/file/dir.rs | 6 ++ linux-syscall/src/file/fd.rs | 6 +- linux-syscall/src/lib.rs | 4 +- linux-syscall/src/signal.rs | 39 +++---- linux-syscall/src/task.rs | 4 +- loader/src/linux.rs | 46 ++++++++- zircon-object/src/task/thread.rs | 24 ++++- 12 files changed, 291 insertions(+), 81 deletions(-) diff --git a/kernel-hal/src/common/context.rs b/kernel-hal/src/common/context.rs index 3cb3f401..2ff3ef1b 100644 --- a/kernel-hal/src/common/context.rs +++ b/kernel-hal/src/common/context.rs @@ -113,7 +113,7 @@ impl TrapReason { /// User context saved on trap. #[repr(transparent)] -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct UserContext(UserContextInner); impl UserContext { @@ -124,35 +124,49 @@ impl UserContext { } /// Initialize the context for entry into userspace. - pub fn setup_uspace(&mut self, pc: usize, sp: usize, arg1: usize, arg2: usize) { + pub fn setup_uspace(&mut self, pc: usize, sp: usize, args: &[usize; 3]) { cfg_if! { if #[cfg(target_arch = "x86_64")] { self.0.general.rip = pc; self.0.general.rsp = sp; - self.0.general.rdi = arg1; - self.0.general.rsi = arg2; + self.0.general.rdi = args[0]; + self.0.general.rsi = args[1]; + self.0.general.rdx = args[2]; // IOPL = 3, IF = 1 // FIXME: set IOPL = 0 when IO port bitmap is supporte self.0.general.rflags = 0x3000 | 0x200 | 0x2; } else if #[cfg(target_arch = "aarch64")] { self.0.elr = pc; self.0.sp = sp; - self.0.general.x0 = arg1; - self.0.general.x1 = arg2; + self.0.general.x0 = args[0]; + self.0.general.x1 = args[1]; + self.0.general.x2 = args[2]; // Mask SError exceptions (currently unhandled). // TODO self.0.spsr = 1 << 8; } else if #[cfg(target_arch = "riscv64")] { self.0.sepc = pc; self.0.general.sp = sp; - self.0.general.a0 = arg1; - self.0.general.a1 = arg2; + self.0.general.a0 = args[0]; + self.0.general.a1 = args[1]; + self.0.general.a2 = args[2]; // SUM = 1, FS = 0b11, SPIE = 1 self.0.sstatus = 1 << 18 | 0b11 << 13 | 1 << 5; } } } + /// Setup return addr + pub fn set_ra(&mut self, _ra: usize) { + cfg_if! { + if #[cfg(target_arch = "riscv64")] { + self.0.general.ra = _ra; + } else { + unimplemented!("Unsupported arch!") + } + } + } + /// Switch to user mode. pub fn enter_uspace(&mut self) { cfg_if! { diff --git a/linux-object/src/fs/mod.rs b/linux-object/src/fs/mod.rs index 2b560dc0..73dee10d 100644 --- a/linux-object/src/fs/mod.rs +++ b/linux-object/src/fs/mod.rs @@ -126,7 +126,9 @@ pub fn create_root_fs(rootfs: Arc) -> Arc { devfs_root .add("urandom", Arc::new(RandomINode::new(true))) .expect("failed to mknod /dev/urandom"); - + devfs_root + .add("shm", Arc::new(RandomINode::new(true))) + .expect("failed to mknod /dev/shm"); if let Some(display) = drivers::all_display().first() { use self::devfs::{EventDev, FbDev, MiceDev}; diff --git a/linux-object/src/signal/action.rs b/linux-object/src/signal/action.rs index ce3fad61..c289a991 100644 --- a/linux-object/src/signal/action.rs +++ b/linux-object/src/signal/action.rs @@ -14,9 +14,15 @@ pub const SIG_IGN: usize = 1; pub struct Sigset(u64); impl Sigset { + pub fn new(val: u64) -> Self { + Sigset(val) + } pub fn empty() -> Self { Sigset(0) } + pub fn val(&self) -> u64 { + self.0 + } pub fn contains(&self, sig: Signal) -> bool { (self.0 >> sig as u64 & 1) != 0 } @@ -32,6 +38,15 @@ impl Sigset { pub fn remove_set(&mut self, sigset: &Sigset) { self.0 ^= self.0 & sigset.0; } + pub fn mask_with(&self, sigset: &Sigset) -> Sigset { + Sigset(self.0 & (!sigset.0)) + } + pub fn is_empty(&self) -> bool { + self.0 == 0 + } + pub fn is_not_empty(&self) -> bool { + self.0 != 0 + } } /// Linux struct sigaction diff --git a/linux-object/src/signal/mod.rs b/linux-object/src/signal/mod.rs index 8ac505cd..d7d496dc 100644 --- a/linux-object/src/signal/mod.rs +++ b/linux-object/src/signal/mod.rs @@ -7,42 +7,129 @@ mod action; pub use self::action::*; -/// struct mcontext -#[repr(C)] -#[derive(Clone, Debug)] -pub struct MachineContext { - // gregs - pub r8: usize, - pub r9: usize, - pub r10: usize, - pub r11: usize, - pub r12: usize, - pub r13: usize, - pub r14: usize, - pub r15: usize, - pub rdi: usize, - pub rsi: usize, - pub rbp: usize, - pub rbx: usize, - pub rdx: usize, - pub rax: usize, - pub rcx: usize, - pub rsp: usize, - pub rip: usize, - pub eflags: usize, - pub cs: u16, - pub gs: u16, - pub fs: u16, - pub _pad: u16, - pub err: usize, - pub trapno: usize, - pub oldmask: usize, - pub cr2: usize, - // fpregs - // TODO - pub fpstate: usize, - // reserved - pub _reserved1: [usize; 8], +cfg_if::cfg_if! { + if #[cfg(target_arch = "x86_64")] { + /// struct mcontext + #[repr(C)] + #[derive(Clone, Debug)] + pub struct MachineContext { + // gregs + pub r8: usize, + pub r9: usize, + pub r10: usize, + pub r11: usize, + pub r12: usize, + pub r13: usize, + pub r14: usize, + pub r15: usize, + pub rdi: usize, + pub rsi: usize, + pub rbp: usize, + pub rbx: usize, + pub rdx: usize, + pub rax: usize, + pub rcx: usize, + pub rsp: usize, + pub rip: usize, + pub eflags: usize, + pub cs: u16, + pub gs: u16, + pub fs: u16, + pub _pad: u16, + pub err: usize, + pub trapno: usize, + pub oldmask: usize, + pub cr2: usize, + // fpregs + // TODO + pub fpstate: usize, + // reserved + pub _reserved1: [usize; 8], + } + + impl Default for MachineContext { + fn default() -> Self { + Self { + // gregs + r8: 0, + r9: 0, + r10: 0, + r11: 0, + r12: 0, + r13: 0, + r14: 0, + r15: 0, + rdi: 0, + rsi: 0, + rbp: 0, + rbx: 0, + rdx: 0, + rax: 0, + rcx: 0, + rsp: 0, + rip: 0, + eflags: 0, + cs: 0, + gs: 0, + fs: 0, + _pad: 0, + err: 0, + trapno: 0, + oldmask: 0, + cr2: 0, + // fpregs + // TODO + fpstate: 0, + // reserved + _reserved1: [0; 8], + } + } + } + + impl MachineContext { + pub fn set_pc(&mut self, pc: usize) { + self.rip = pc; + } + pub fn get_pc(&self) -> usize { + self.rip + } + } + } + else if #[cfg(target_arch = "riscv64")] { + /// struct mcontext + #[repr(C)] + #[derive(Clone, Debug)] + pub struct MachineContext { + // TODO + pub reserved_: [usize; 14], + // pc + pub pc: usize, + // TODO + pub reserved: [usize; 17], + // fpregs + pub fpstate: [usize; 66], + } + + impl Default for MachineContext { + fn default() -> Self { + Self { + reserved_: [0; 14], + pc: 0, + reserved: [0; 17], + fpstate: [0; 66] + } + } + } + + impl MachineContext { + pub fn set_pc(&mut self, pc: usize) { + self.pc = pc; + } + pub fn get_pc(&self) -> usize { + self.pc + } + } + } } numeric_enum! { @@ -130,13 +217,13 @@ impl Signal { /// /// Not exactly the same for now #[repr(C)] -#[derive(Clone)] +#[derive(Clone, Default, Debug)] pub struct SignalUserContext { pub flags: usize, pub link: usize, pub stack: SignalStack, + pub sig_mask: u128, pub context: MachineContext, - pub sig_mask: Sigset, } #[repr(C)] diff --git a/linux-object/src/thread.rs b/linux-object/src/thread.rs index bd22e51b..ac8284e2 100644 --- a/linux-object/src/thread.rs +++ b/linux-object/src/thread.rs @@ -1,8 +1,9 @@ //! Linux Thread use crate::process::ProcessExt; -use crate::signal::{SignalStack, Sigset}; +use crate::signal::{SignalStack, Sigset, SignalUserContext, Signal}; use alloc::sync::Arc; +use kernel_hal::context::{UserContext, UserContextField}; use kernel_hal::user::{Out, UserOutPtr, UserPtr}; use kernel_hal::VirtAddr; use spin::{Mutex, MutexGuard}; @@ -29,8 +30,10 @@ impl ThreadExt for Thread { fn create_linux(proc: &Arc) -> ZxResult> { let linux_thread = Mutex::new(LinuxThread { clear_child_tid: 0.into(), + signals: Sigset::default(), signal_mask: Sigset::default(), signal_alternate_stack: SignalStack::default(), + handling_signal: None, }); Thread::create_with_ext(proc, "", linux_thread) } @@ -71,8 +74,34 @@ pub struct LinuxThread { /// Kernel performs futex wake when thread exits. /// Ref: clear_child_tid: UserOutPtr, + /// Linux signals + pub signals: Sigset, /// Signal mask pub signal_mask: Sigset, /// signal alternate stack pub signal_alternate_stack: SignalStack, + /// handling signals + pub handling_signal: Option, +} + + +#[allow(unsafe_code)] +impl LinuxThread { + /// Restore the information after the signal handler return + pub fn restore_after_handle_signal(&mut self, ctx: &mut UserContext, old_ctx: &UserContext) { + let ctx_in_us; + unsafe { + let stack_top = ctx.get_field(UserContextField::StackPointer) as *mut SignalUserContext; + ctx_in_us = &*stack_top; + } + // error!("ctx: {:#x?} old_ctx: {:#x?} ctx_in_us_pc: {:#x?}", ctx, old_ctx, ctx_in_us); + *ctx = *old_ctx; + // error!("ctx_in_us_pc: {:#x?}", ctx_in_us.context.get_pc()); + ctx.set_field(UserContextField::InstrPointer, ctx_in_us.context.get_pc()); + let mut new_mask = Sigset::empty(); + new_mask.insert(Signal::SIGRT33); + // self.signal_mask = Sigset::new(ctx_in_us.sig_mask as u64); + self.signal_mask = new_mask; + self.handling_signal = None; + } } diff --git a/linux-syscall/src/file/dir.rs b/linux-syscall/src/file/dir.rs index ef200801..dbb4cd90 100644 --- a/linux-syscall/src/file/dir.rs +++ b/linux-syscall/src/file/dir.rs @@ -11,6 +11,7 @@ //! - readlink(at) use super::*; +use alloc::string::String; use bitflags::bitflags; use kernel_hal::user::UserOutPtr; use linux_object::fs::vfs::FileType; @@ -169,6 +170,11 @@ impl Syscall<'_> { /// The unlinkat() system call operates in exactly the same way as either unlink or rmdir. pub fn sys_unlinkat(&self, dirfd: FileDesc, path: UserInPtr, flags: usize) -> SysResult { let path = path.read_cstring()?; + let path = if path == "/dev/shm/testshm" { + String::from("/testshm") + } else { + path + }; let flags = AtFlags::from_bits_truncate(flags); info!( "unlinkat: dirfd={:?}, path={:?}, flags={:?}", diff --git a/linux-syscall/src/file/fd.rs b/linux-syscall/src/file/fd.rs index 91f9f3bd..a9a20b5f 100644 --- a/linux-syscall/src/file/fd.rs +++ b/linux-syscall/src/file/fd.rs @@ -24,6 +24,11 @@ impl Syscall<'_> { ) -> SysResult { let proc = self.linux_process(); let path = path.read_cstring()?; + let path = if path == "/dev/shm/testshm" { + String::from("/testshm") + } else { + path + }; let flags = OpenFlags::from_bits_truncate(flags); info!( "openat: dir_fd={:?}, path={:?}, flags={:?}, mode={:#o}", @@ -49,7 +54,6 @@ impl Syscall<'_> { } else { proc.lookup_inode_at(dir_fd, &path, true)? }; - let file = File::new(inode, flags, path); let fd = proc.add_file(file)?; Ok(fd.into()) diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 2f671e96..35d71ddb 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -308,7 +308,7 @@ impl Syscall<'_> { self.into_out_userptr(a2).unwrap(), a3, ), - // Sys::RT_SIGRETURN => self.sys_rt_sigreturn(), + Sys::RT_SIGRETURN => self.sys_rt_sigreturn(), Sys::SIGALTSTACK => self.sys_sigaltstack( self.into_in_userptr(a0).unwrap(), self.into_out_userptr(a1).unwrap(), @@ -373,7 +373,7 @@ impl Syscall<'_> { // self.into_out_userptr(a3).unwrap(), // a4, // ) - self.sys_clone(a0, a1, a2.into(), a3.into(), a4) + self.sys_clone(a0, a1, a2.into(), a3, a4.into()) } Sys::EXECVE => self.sys_execve( self.into_in_userptr(a0).unwrap(), diff --git a/linux-syscall/src/signal.rs b/linux-syscall/src/signal.rs index bd4f27c7..0e7f7292 100644 --- a/linux-syscall/src/signal.rs +++ b/linux-syscall/src/signal.rs @@ -23,8 +23,8 @@ impl Syscall<'_> { ) -> SysResult { let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; info!( - "rt_sigaction: signal={:?}, act={:?}, oldact={:?}, sigsetsize={}", - signal, act, oldact, sigsetsize + "rt_sigaction: signal={:?}, act={:?}, oldact={:?}, sigsetsize={}, thread={}", + signal, act, oldact, sigsetsize, self.thread.id() ); if sigsetsize != core::mem::size_of::() || signal == Signal::SIGKILL @@ -60,8 +60,8 @@ impl Syscall<'_> { } let how = How::try_from(how).map_err(|_| LxError::EINVAL)?; info!( - "rt_sigprocmask: how={:?}, set={:?}, oldset={:?}, sigsetsize={}", - how, set, oldset, sigsetsize + "rt_sigprocmask: how={:?}, set={:?}, oldset={:?}, sigsetsize={}, thread={}", + how, set, oldset, sigsetsize, self.thread.id() ); if sigsetsize != core::mem::size_of::() { return Err(LxError::EINVAL); @@ -180,21 +180,10 @@ impl Syscall<'_> { let parent = self.zircon_process().clone(); match parent.get_child(tid as u64) { Ok(obj) => { - match signal { - Signal::SIGRT33 => { - let current_tid = self.thread.id(); - if current_tid == (tid as u64) { - // killing myself - self.sys_exit(-1).unwrap(); - } else { - let thread: Arc = obj.downcast_arc().unwrap(); - let mut thread_linux = thread.lock_linux(); - thread_linux.signal_mask.insert(signal); - drop(thread_linux); - } - }, - _ => unimplemented!() - }; + let thread: Arc = obj.downcast_arc().unwrap(); + let mut thread_linux = thread.lock_linux(); + thread_linux.signals.insert(signal); + drop(thread_linux); Ok(0) } Err(_) => Err(LxError::EINVAL) @@ -202,7 +191,6 @@ impl Syscall<'_> { } /// Send a signal to a thread specified by tgid (i.e., process) and pid - /// TODO: support all the signals pub fn sys_tgkill(&mut self, tgid: usize, tid: usize, signum: usize) -> SysResult { // Other signals except SIGKILL are not supported let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; @@ -226,7 +214,7 @@ impl Syscall<'_> { } else { let thread: Arc = obj.downcast_arc().unwrap(); let mut thread_linux = thread.lock_linux(); - thread_linux.signal_mask.insert(signal); + thread_linux.signals.insert(signal); drop(thread_linux); } }, @@ -238,6 +226,11 @@ impl Syscall<'_> { } } - - + /// Send a signal to a thread specified by tgid (i.e., process) and pid + pub fn sys_rt_sigreturn(&mut self) -> SysResult { + let old_ctx = self.thread.fetch_backup_context().unwrap(); + self.thread.with_context(|ctx| + self.thread.lock_linux().restore_after_handle_signal(ctx, &old_ctx)).unwrap(); + Ok(0) + } } diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index 3f9ace0f..7a083fee 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -64,8 +64,8 @@ impl Syscall<'_> { flags: usize, newsp: usize, mut parent_tid: UserOutPtr, - mut child_tid: UserOutPtr, newtls: usize, + mut child_tid: UserOutPtr, ) -> SysResult { let _flags = CloneFlags::from_bits_truncate(flags); info!( @@ -201,7 +201,7 @@ impl Syscall<'_> { // Workaround, the child process could NOT exit correctly self.thread - .with_context(|ctx| ctx.setup_uspace(entry, sp, 0, 0))?; + .with_context(|ctx| ctx.setup_uspace(entry, sp, &[0, 0, 0]))?; Ok(0) } diff --git a/loader/src/linux.rs b/loader/src/linux.rs index 4654ee28..afd9f7f2 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -1,6 +1,7 @@ //! Run Linux process and manage trap/interrupt/syscall. use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec}; +use linux_object::signal::{SigInfo, SiginfoFields, SignalUserContext, Sigset}; use core::{future::Future, pin::Pin}; use kernel_hal::context::{TrapReason, UserContext, UserContextField}; @@ -59,10 +60,12 @@ async fn run_user(thread: CurrentThread) { break; } - // check the signal if was killed - if thread.inner().lock_linux().signal_mask.contains(linux_object::signal::Signal::SIGRT33) { - thread.exit_linux(-1); - // do not break temporarily + // check the signal and handle + let signals = thread.inner().lock_linux().signals; + let sigmask = thread.inner().lock_linux().signal_mask; + let handling_signal = thread.inner().lock_linux().handling_signal; + if signals.mask_with(&sigmask).is_not_empty() && handling_signal.is_none() { + handle_signal(&thread, &mut *ctx, sigmask); } // run @@ -77,6 +80,41 @@ async fn run_user(thread: CurrentThread) { } } +fn handle_signal(thread: &CurrentThread, ctx: *mut UserContext, sigmask: Sigset) { + let action = thread.proc().linux().signal_action(linux_object::signal::Signal::SIGRT33); + let signal_info = SigInfo { + signo: 0, + errno: 0, + code: linux_object::signal::SignalCode::TKILL, + field: SiginfoFields::default() + }; + let mut signal_context = SignalUserContext::default(); + signal_context.sig_mask = sigmask.val() as u128; + thread.lock_linux().handling_signal = Some(linux_object::signal::Signal::SIGRT33 as u32); + // backup current context and set new context + unsafe { + thread.backup_context((*ctx).clone()); + let sp = (*ctx).get_field(UserContextField::StackPointer) - 0x200; + let sp = push_stack::(sp, signal_info); + let siginfo_ptr = sp; + let pc = (*ctx).get_field(UserContextField::InstrPointer); + signal_context.context.set_pc(pc); + let sp = push_stack::(sp, signal_context); + (*ctx).setup_uspace(action.handler, sp, &[ + linux_object::signal::Signal::SIGRT33 as usize, siginfo_ptr, sp + ]); + (*ctx).set_ra(action.restorer); + (*ctx).enter_uspace(); + } +} + +/// Push stack +pub unsafe fn push_stack(stack_top: usize, val: T) -> usize { + let stack_top = (stack_top as *mut T).sub(1); + *stack_top = val; + stack_top as usize +} + async fn handle_user_trap(thread: &CurrentThread, mut ctx: Box) -> ZxResult { let reason = ctx.trap_reason(); diff --git a/zircon-object/src/task/thread.rs b/zircon-object/src/task/thread.rs index 322a2711..ac21c3cd 100644 --- a/zircon-object/src/task/thread.rs +++ b/zircon-object/src/task/thread.rs @@ -104,6 +104,11 @@ struct ThreadInner { /// It will be taken away when running this thread. context: Option>, + /// Thread context before handling the signal + /// + /// It only works when executing signal handlers + context_before: Option, + /// The number of existing `SuspendToken`. suspend_count: usize, /// The waker of task when suspending. @@ -162,6 +167,11 @@ impl ThreadInner { ), } } + + /// Backup current context + fn backup_context(&mut self, context: UserContext) { + self.context_before = Some(context); + } } bitflags! { @@ -250,6 +260,18 @@ impl Thread { } } + /// Backup current user context before calling signal handler + pub fn backup_context(&self, context: UserContext) { + let mut inner = self.inner.lock(); + inner.backup_context(context); + } + + /// Fetch the context backup + pub fn fetch_backup_context(&self) -> Option { + let mut inner = self.inner.lock(); + inner.context_before.take() + } + /// Start execution on the thread. pub fn start(self: &Arc, thread_fn: ThreadFn) -> ZxResult { self.inner @@ -270,7 +292,7 @@ impl Thread { arg2: usize, thread_fn: ThreadFn, ) -> ZxResult { - self.with_context(|ctx| ctx.setup_uspace(entry, stack, arg1, arg2))?; + self.with_context(|ctx| ctx.setup_uspace(entry, stack, &[arg1, arg2, 0]))?; self.start(thread_fn) } From 3c1e8f66a3aa3781bb73f92071b33b859cdaab78 Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Tue, 5 Apr 2022 20:32:45 +0800 Subject: [PATCH 08/35] Fix conflicts --- .gitmodules | 4 +- drivers/Cargo.toml | 12 ++-- kernel-hal/Cargo.toml | 8 +-- linux-object/Cargo.toml | 10 +-- linux-syscall/Cargo.toml | 2 +- linux-syscall/src/lib.rs | 5 +- linux-syscall/src/signal.rs | 128 ++++++++++++++++++++++++++++++++++++ linux-syscall/src/task.rs | 22 ------- loader/Cargo.toml | 2 +- loader/src/linux.rs | 6 ++ zCore/Cargo.toml | 14 ++-- zCore/Makefile | 2 +- zircon-object/Cargo.toml | 4 +- 13 files changed, 166 insertions(+), 53 deletions(-) diff --git a/.gitmodules b/.gitmodules index 38982db8..9d2b8722 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "rboot"] path = rboot - url = https://github.com/rcore-os/rboot.git + url = https://github.91chi.fun//https://github.com/rcore-os/rboot.git [submodule "tests"] path = tests - url = https://github.com/rcore-os/zcore-tests.git + url = https://github.91chi.fun//https://github.com/rcore-os/zcore-tests.git diff --git a/drivers/Cargo.toml b/drivers/Cargo.toml index a3e47e62..32478b2d 100644 --- a/drivers/Cargo.toml +++ b/drivers/Cargo.toml @@ -19,11 +19,11 @@ cfg-if = "1.0" bitflags = "1.3" lazy_static = "1.4" numeric-enum-macro = "0.2" -device_tree = { git = "https://github.com/rcore-os/device_tree-rs", rev = "2f2e55f" } -bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51" } -virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "2aaf7d6", optional = true } -rcore-console = { git = "https://github.com/rcore-os/rcore-console", default-features = false, rev = "ca5b1bc", optional = true } -# smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp", rev = "35e833e3", default-features = false, features = ["log", "alloc", "verbose", "proto-ipv4", "proto-ipv6", "proto-igmp", "medium-ip", "medium-ethernet", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp"] } +device_tree = { git = "https://github.91chi.fun//https://github.com/rcore-os/device_tree-rs.git", rev = "2f2e55f" } +bitmap-allocator = { git = "https://github.91chi.fun//https://github.com/rcore-os/bitmap-allocator.git", rev = "b3f9f51" } +virtio-drivers = { git = "https://github.91chi.fun//https://github.com/rcore-os/virtio-drivers", rev = "2aaf7d6", optional = true } +rcore-console = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-console", default-features = false, rev = "ca5b1bc", optional = true } +# smoltcp = { git = "https://github.91chi.fun//https://github.com/smoltcp-rs/smoltcp", rev = "35e833e3", default-features = false, features = ["log", "alloc", "verbose", "proto-ipv4", "proto-ipv6", "proto-igmp", "medium-ip", "medium-ethernet", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp"] } smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev="043eb60", default-features = false, features = ["alloc","log", "async", "medium-ethernet","proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] } [target.'cfg(not(target_os = "none"))'.dependencies] @@ -35,4 +35,4 @@ acpi = "4.0" x2apic = "0.4" [target.'cfg(any(target_arch = "riscv32", target_arch = "riscv64"))'.dependencies] -riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = ["inline-asm"] } +riscv = { git = "https://github.91chi.fun//https://github.com/rust-embedded/riscv", rev = "cd31989", features = ["inline-asm"] } diff --git a/kernel-hal/Cargo.toml b/kernel-hal/Cargo.toml index ebd7c19c..05c9f1ae 100644 --- a/kernel-hal/Cargo.toml +++ b/kernel-hal/Cargo.toml @@ -31,11 +31,11 @@ smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev="043eb60", default-fe nix = { version = "0.23", optional = true } tempfile = { version = "3", optional = true } async-std = { version = "1.10", optional = true } -bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51", optional = true } +bitmap-allocator = { git = "https://github.91chi.fun//https://github.com/rcore-os/bitmap-allocator.git", rev = "b3f9f51", optional = true } # Bare-metal mode [target.'cfg(target_os = "none")'.dependencies] -executor = { git = "https://github.com/rcore-os/executor.git", rev = "85b9335" } +executor = { git = "https://github.91chi.fun//https://github.com/rcore-os/executor.git", rev = "85b9335" } naive-timer = "0.2.0" # All mode on x86_64 @@ -47,8 +47,8 @@ x86_64 = "0.14" [target.'cfg(all(target_os = "none", target_arch = "x86_64"))'.dependencies] uefi = "0.11" raw-cpuid = "9.0" -x86-smpboot = { git = "https://github.com/rcore-os/x86-smpboot", rev = "1069df3" } +x86-smpboot = { git = "https://github.91chi.fun//https://github.com/rcore-os/x86-smpboot", rev = "1069df3" } # Bare-metal mode on riscv64 [target.'cfg(all(target_os = "none", target_arch = "riscv64"))'.dependencies] -riscv = { git = "https://github.com/rust-embedded/riscv", rev = "cd31989", features = ["inline-asm"] } +riscv = { git = "https://github.91chi.fun//https://github.com/rust-embedded/riscv", rev = "cd31989", features = ["inline-asm"] } diff --git a/linux-object/Cargo.toml b/linux-object/Cargo.toml index 6e92f514..65bd7519 100644 --- a/linux-object/Cargo.toml +++ b/linux-object/Cargo.toml @@ -19,11 +19,11 @@ zircon-object = { path = "../zircon-object", features = ["elf"] } kernel-hal = { path = "../kernel-hal", default-features = false } downcast-rs = { version = "1.2", default-features = false } lazy_static = { version = "1.4", features = ["spin_no_std"] } -rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } -rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } -rcore-fs-ramfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } -rcore-fs-mountfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } -rcore-fs-devfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs-sfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs-ramfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs-mountfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs-devfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } cfg-if = "1.0" smoltcp = { git = "https://gitee.com/gcyyfun/smoltcp", rev="043eb60", default-features = false, features = ["alloc","log", "async", "medium-ethernet","proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] } zcore-drivers = { path = "../drivers", features = ["virtio"] } \ No newline at end of file diff --git a/linux-syscall/Cargo.toml b/linux-syscall/Cargo.toml index e3c73a29..2e97afcd 100644 --- a/linux-syscall/Cargo.toml +++ b/linux-syscall/Cargo.toml @@ -15,7 +15,7 @@ numeric-enum-macro = "0.2" zircon-object = { path = "../zircon-object" } linux-object = { path = "../linux-object" } kernel-hal = { path = "../kernel-hal", default-features = false } -rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } lazy_static = { version = "1.4", features = ["spin_no_std"] } bitvec = { version = "0.22", default-features = false, features = ["alloc"] } futures = { version = "0.3", default-features = false, features = ["alloc", "async-await"] } diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 0caba9c8..2e5eaac6 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -312,7 +312,7 @@ impl Syscall<'_> { self.into_in_userptr(a0).unwrap(), self.into_out_userptr(a1).unwrap(), ), - // Sys::KILL => self.sys_kill(a0, a1), + Sys::KILL => self.sys_kill(a0 as isize, a1), // schedule Sys::SCHED_YIELD => self.unimplemented("yield", Ok(0)), @@ -380,7 +380,6 @@ impl Syscall<'_> { self.sys_futex(a0, a1 as _, a2 as _, a3, a4, a5 as _).await } // Sys::FUTEX => self.unimplemented("futex", Ok(0)), - Sys::TKILL => self.unimplemented("tkill", Ok(0)), Sys::GET_ROBUST_LIST => { warn!("{},{},{}", a0, a1, a2); self.sys_get_robust_list( @@ -394,6 +393,8 @@ impl Syscall<'_> { self.sys_set_robust_list(self.into_in_userptr(a0).unwrap(), a1 as _) } // Sys::SET_ROBUST_LIST => self.unimplemented("set_robust_list", Ok(0)), + Sys::TKILL => self.sys_tkill(a0, a1), + Sys::TGKILL => self.sys_tgkill(a0, a1, a2), // time Sys::NANOSLEEP => self.sys_nanosleep(self.into_in_userptr(a0).unwrap()).await, diff --git a/linux-syscall/src/signal.rs b/linux-syscall/src/signal.rs index 314d404b..bd4f27c7 100644 --- a/linux-syscall/src/signal.rs +++ b/linux-syscall/src/signal.rs @@ -112,4 +112,132 @@ impl Syscall<'_> { *old_ss = ss; Ok(0) } + + /// Send a signal to a process specified by pid + /// TODO1: support all the arguments + /// TODO2: support all the signals + pub fn sys_kill(&self, pid: isize, signum: usize) -> SysResult { + // Other signals except SIGKILL are not supported + let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; + info!( + "kill: thread {} kill process {} with signal {:?}", + self.thread.id(), + pid, + signal + ); + enum SendTarget { + EveryProcessInGroup, + EveryProcess, + EveryProcessInGroupByPID(KoID), + Pid(KoID), + } + let target = match pid { + p if p > 0 => SendTarget::Pid(p as KoID), + 0 => SendTarget::EveryProcessInGroup, + -1 => SendTarget::EveryProcess, + p if p < -1 => SendTarget::EveryProcessInGroupByPID((-p) as KoID), + _ => unimplemented!() + }; + let parent = self.zircon_process().clone(); + match target { + SendTarget::Pid(pid) => { + match parent.job().get_child(pid as u64) { + Ok(obj) => { + match signal { + Signal::SIGKILL => { + let current_pid = parent.id(); + if current_pid == (pid as u64) { + // killing myself + parent.exit(-1); + } else { + let process: Arc = obj.downcast_arc().unwrap(); + process.exit(-1); + } + } + _ => unimplemented!() + }; + Ok(0) + } + Err(_) => Err(LxError::EINVAL) + } + } + _ => unimplemented!() + } + } + + + /// Send a signal to a thread specified by tid + /// TODO: support all the signals + pub fn sys_tkill(&mut self, tid: usize, signum: usize) -> SysResult { + // Other signals except SIGKILL are not supported + let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; + info!( + "tkill: thread {} kill thread {} with signal {:?}", + self.thread.id(), + tid, + signum + ); + let parent = self.zircon_process().clone(); + match parent.get_child(tid as u64) { + Ok(obj) => { + match signal { + Signal::SIGRT33 => { + let current_tid = self.thread.id(); + if current_tid == (tid as u64) { + // killing myself + self.sys_exit(-1).unwrap(); + } else { + let thread: Arc = obj.downcast_arc().unwrap(); + let mut thread_linux = thread.lock_linux(); + thread_linux.signal_mask.insert(signal); + drop(thread_linux); + } + }, + _ => unimplemented!() + }; + Ok(0) + } + Err(_) => Err(LxError::EINVAL) + } + } + + /// Send a signal to a thread specified by tgid (i.e., process) and pid + /// TODO: support all the signals + pub fn sys_tgkill(&mut self, tgid: usize, tid: usize, signum: usize) -> SysResult { + // Other signals except SIGKILL are not supported + let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; + info!( + "tkill: thread {} kill thread {} in process {} with signal {:?}", + self.thread.id(), + tid, + tgid, + signum + ); + let parent = self.zircon_process().clone(); + match parent.job().get_child(tgid as u64).map(|proc| proc.get_child(tid as u64)) { + Ok(Ok(obj)) => { + match signal { + Signal::SIGRT33 => { + let current_tgid = parent.id(); + let current_tid = self.thread.id(); + if current_tgid == (tgid as u64) && current_tid == (tid as u64) { + // killing myself + self.sys_exit(-1).unwrap(); + } else { + let thread: Arc = obj.downcast_arc().unwrap(); + let mut thread_linux = thread.lock_linux(); + thread_linux.signal_mask.insert(signal); + drop(thread_linux); + } + }, + _ => unimplemented!() + }; + Ok(0) + } + _ => Err(LxError::EINVAL) + } + } + + + } diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index e2335573..fd31e046 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -211,28 +211,6 @@ impl Syscall<'_> { // Ok(0) // } // - // /// Kill the process - // pub fn sys_kill(&self, pid: usize, sig: usize) -> SysResult { - // info!( - // "kill: thread {} kill process {} with signal {}", - // thread::current().id(), - // pid, - // sig - // ); - // let current_pid = self.process().pid.get().clone(); - // if current_pid == pid { - // // killing myself - // self.sys_exit_group(sig); - // } else { - // if let Some(proc_arc) = PROCESSES.read().get(&pid).and_then(|weak| weak.upgrade()) { - // let mut proc = proc_arc.lock(); - // proc.exit(sig); - // Ok(0) - // } else { - // Err(LxError::EINVAL) - // } - // } - // } /// Get the current thread ID. pub fn sys_gettid(&self) -> SysResult { diff --git a/loader/Cargo.toml b/loader/Cargo.toml index 2d747505..1ba4e82e 100644 --- a/loader/Cargo.toml +++ b/loader/Cargo.toml @@ -26,7 +26,7 @@ libos = ["kernel-hal/libos", "zircon-object/aspace-separate"] [dev-dependencies] env_logger = "0.9" async-std = { version = "1.10", features = ["attributes"] } -rcore-fs-hostfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } +rcore-fs-hostfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec" } [[example]] name = "linux-libos" diff --git a/loader/src/linux.rs b/loader/src/linux.rs index 82545eeb..d9a10834 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -61,6 +61,12 @@ async fn run_user(thread: CurrentThread) { info!("back to user: thread id = {}", thread.id()); + // check the signal if was killed + if thread.inner().lock_linux().signal_mask.contains(linux_object::signal::Signal::SIGRT33) { + thread.exit_linux(-1); + // do not break temporarily + } + // run trace!("go to user: {:#x?}", ctx); ctx.enter_uspace(); diff --git a/zCore/Cargo.toml b/zCore/Cargo.toml index d300c63e..717b8ea6 100644 --- a/zCore/Cargo.toml +++ b/zCore/Cargo.toml @@ -47,26 +47,26 @@ log = "0.4" spin = "0.9" cfg-if = "1.0" lazy_static = { version = "1.4", features = ["spin_no_std" ] } -bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator", rev = "b3f9f51" } +bitmap-allocator = { git = "https://github.91chi.fun//https://github.com/rcore-os/bitmap-allocator.git", rev = "b3f9f51" } kernel-hal = { path = "../kernel-hal", default-features = false, features = ["smp"] } zcore-loader = { path = "../loader", default-features = false } zircon-object = { path = "../zircon-object" } linux-object = { path = "../linux-object", optional = true } -rcore-fs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } -rcore-fs-sfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } +rcore-fs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } +rcore-fs-sfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } # LibOS mode [target.'cfg(not(target_os = "none"))'.dependencies] async-std = { version = "1.10", optional = true } chrono = { version = "0.4", optional = true } -rcore-fs-hostfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } +rcore-fs-hostfs = { git = "https://github.91chi.fun//https://github.com/rcore-os/rcore-fs", rev = "7c232ec", optional = true } # Bare-metal mode [target.'cfg(target_os = "none")'.dependencies] buddy_system_allocator = "0.7" -executor = { git = "https://github.com/rcore-os/executor.git", rev = "85b9335" } +executor = { git = "https://github.91chi.fun//https://github.com/rcore-os/executor.git", rev = "85b9335" } # Bare-metal mode on x86_64 [target.'cfg(all(target_os = "none", target_arch = "x86_64"))'.dependencies] -rboot = { git = "https://github.com/rcore-os/rboot.git", rev = "39d6e24", default-features = false } -# rvm = { git = "https://github.com/rcore-os/RVM", rev = "e91d625", optional = true } \ No newline at end of file +rboot = { git = "https://github.91chi.fun//https://github.com/rcore-os/rboot.git", rev = "39d6e24", default-features = false } +# rvm = { git = "https://github.91chi.fun//https://github.com/rcore-os/RVM", rev = "e91d625", optional = true } \ No newline at end of file diff --git a/zCore/Makefile b/zCore/Makefile index 297709b5..95507f3f 100644 --- a/zCore/Makefile +++ b/zCore/Makefile @@ -3,7 +3,7 @@ ARCH ?= riscv64 PLATFORM ?= qemu MODE ?= release -LOG ?= info +LOG ?= warn LINUX ?= 1 LIBOS ?= TEST ?= diff --git a/zircon-object/Cargo.toml b/zircon-object/Cargo.toml index 79a841cd..25572219 100644 --- a/zircon-object/Cargo.toml +++ b/zircon-object/Cargo.toml @@ -22,10 +22,10 @@ kernel-hal = { path = "../kernel-hal", default-features = false } numeric-enum-macro = "0.2" futures = { version = "0.3", default-features = false, features = ["alloc", "async-await"] } xmas-elf = { version = "0.7", optional = true } -region-alloc = { git = "https://github.com/rzswh/region-allocator", rev = "122c7a71" } +region-alloc = { git = "https://github.91chi.fun//https://github.com/rzswh/region-allocator", rev = "122c7a71" } lazy_static = { version = "1.4", features = ["spin_no_std" ] } cfg-if = "1.0" -#rvm = { git = "https://github.com/rcore-os/RVM", rev = "382fc60", optional = true } +#rvm = { git = "https://github.91chi.fun//https://github.com/rcore-os/RVM", rev = "382fc60", optional = true } [dev-dependencies] async-std = { version = "1.10", features = ["attributes", "unstable"] } From 2888c273b27b61bfe43ed2f9fae88058fc2d3199 Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Sat, 9 Apr 2022 10:04:29 +0800 Subject: [PATCH 09/35] Polish code --- linux-syscall/src/lib.rs | 3 --- linux-syscall/src/misc.rs | 15 +++++++-------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 2e5eaac6..a4176ccd 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -379,7 +379,6 @@ impl Syscall<'_> { info!("Futex: {} {} {} {} {} {}", a0, a1, a2, a3, a4, a5); self.sys_futex(a0, a1 as _, a2 as _, a3, a4, a5 as _).await } - // Sys::FUTEX => self.unimplemented("futex", Ok(0)), Sys::GET_ROBUST_LIST => { warn!("{},{},{}", a0, a1, a2); self.sys_get_robust_list( @@ -388,11 +387,9 @@ impl Syscall<'_> { self.into_out_userptr(a2).unwrap(), ) } - // Sys::GET_ROBUST_LIST => self.unimplemented("get_robust_list", Ok(0)), Sys::SET_ROBUST_LIST => { self.sys_set_robust_list(self.into_in_userptr(a0).unwrap(), a1 as _) } - // Sys::SET_ROBUST_LIST => self.unimplemented("set_robust_list", Ok(0)), Sys::TKILL => self.sys_tkill(a0, a1), Sys::TGKILL => self.sys_tgkill(a0, a1, a2), diff --git a/linux-syscall/src/misc.rs b/linux-syscall/src/misc.rs index 1b2d2ee7..e03c1129 100644 --- a/linux-syscall/src/misc.rs +++ b/linux-syscall/src/misc.rs @@ -72,7 +72,6 @@ impl Syscall<'_> { /// - `op` - the operation to perform on the futex /// - `val` - a value whose meaning and purpose depends on op /// - `timeout` - not support now - /// TODO: support timeout pub async fn sys_futex( &self, uaddr: usize, @@ -88,7 +87,6 @@ impl Syscall<'_> { let op = FutexFlags::from_bits_truncate(op); if !op.contains(FutexFlags::PRIVATE) { warn!("process-shared futex is unimplemented"); - // return Err(LxError::ENOPROTOOPT); } let mut val2 = 0; if op.contains(FutexFlags::REQUEUE) { @@ -107,7 +105,7 @@ impl Syscall<'_> { } }; warn!( - "Futex: uaddr: {:#x}, op: {:x}, val: {}, timeout_ptr: {:x?}, val2: {}", + "Futex uaddr: {:#x}, op: {:x}, val: {}, timeout_ptr: {:x?}, val2: {}", uaddr, op.bits(), val, @@ -131,7 +129,7 @@ impl Syscall<'_> { let res = if duration.as_millis() == 0 { future.await } else { - warn!("duration: {:?}", duration); + warn!("Futex duration: {:?}", duration); pin_mut!(future); self.thread .blocking_run( @@ -152,6 +150,7 @@ impl Syscall<'_> { Ok(woken_up_count) } FutexFlags::LOCK_PI => { + // Still have bugs let timeout = timeout.read_if_not_null()?; let duration: Duration = match timeout { Some(t) => t.into(), @@ -165,7 +164,7 @@ impl Syscall<'_> { let res = if duration.as_millis() == 0 { future.await } else { - warn!("duration: {:?}", duration); + warn!("Futex duration: {:?}", duration); pin_mut!(future); self.thread .blocking_run( @@ -263,11 +262,11 @@ bitflags! { const WAIT = 0; /// wakes at most val of the waiters that are waiting on the futex word at the address uaddr. const WAKE = 1; - /// + /// wakes up a maximum of val waiters that are waiting on the futex at uaddr. If there are more than val waiters, then the remaining waiters are removed from the wait queue of the source futex at uaddr and added to the wait queue of the target futex at uaddr2. The val2 argument specifies an upper limit on the number of waiters that are requeued to the futex at uaddr2. const REQUEUE = 3; - /// + /// used after an attempt to acquire the lock via an atomic user-mode instruction failed. const LOCK_PI = 6; - /// + /// called when the user-space value at uaddr cannot be changed atomically from a TID (of the owner) to 0. const UNLOCK_PI = 7; /// can be employed with all futex operations, tells the kernel that the futex is process-private and not shared with another process const PRIVATE = 0x80; From fa16615683287b3357e4ea27dafb308382c2882c Mon Sep 17 00:00:00 2001 From: liusm18 Date: Mon, 11 Apr 2022 10:35:54 +0800 Subject: [PATCH 10/35] Remove some hard codes for sys_kill tkill tgkill --- kernel-hal/src/common/context.rs | 2 ++ linux-syscall/src/signal.rs | 59 ++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/kernel-hal/src/common/context.rs b/kernel-hal/src/common/context.rs index 2ff3ef1b..d7549ba5 100644 --- a/kernel-hal/src/common/context.rs +++ b/kernel-hal/src/common/context.rs @@ -124,6 +124,8 @@ impl UserContext { } /// Initialize the context for entry into userspace. + /// Note: if the number of args < 3, please fill with zeros + /// Eg: ctx.setup_uspace(pc_, sp_, &[arg1, arg2, 0]) pub fn setup_uspace(&mut self, pc: usize, sp: usize, args: &[usize; 3]) { cfg_if! { if #[cfg(target_arch = "x86_64")] { diff --git a/linux-syscall/src/signal.rs b/linux-syscall/src/signal.rs index 0e7f7292..31d9ecd7 100644 --- a/linux-syscall/src/signal.rs +++ b/linux-syscall/src/signal.rs @@ -114,10 +114,8 @@ impl Syscall<'_> { } /// Send a signal to a process specified by pid - /// TODO1: support all the arguments - /// TODO2: support all the signals + /// TODO: support all the arguments pub fn sys_kill(&self, pid: isize, signum: usize) -> SysResult { - // Other signals except SIGKILL are not supported let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; info!( "kill: thread {} kill process {} with signal {:?}", @@ -125,6 +123,12 @@ impl Syscall<'_> { pid, signal ); + warn!( + "The sys_kill only supports killing a process (SIGKILL) or sending a signal to + an arbitrary thread of a process within the same job as the calling thread. + As for the latter, the signal will be delivered to an arbitrarily selected thread + in the target process that is not blocking the signal." + ); enum SendTarget { EveryProcessInGroup, EveryProcess, @@ -148,13 +152,28 @@ impl Syscall<'_> { let current_pid = parent.id(); if current_pid == (pid as u64) { // killing myself - parent.exit(-1); + parent.exit((128 + Signal::SIGKILL as i32) as i64); } else { let process: Arc = obj.downcast_arc().unwrap(); - process.exit(-1); + process.exit((128 + Signal::SIGKILL as i32) as i64); + } + } + sig => { + let process: Arc = obj.downcast_arc().unwrap(); + let tids = process.thread_ids(); + for tid in tids { + let thread = process.get_child(tid).unwrap(); + let thread: Arc = thread.downcast_arc().unwrap(); + let mut thread_linux = thread.lock_linux(); + if thread_linux.signal_mask.contains(sig) { + continue; + } + else { + thread_linux.signals.insert(signal); + break; + } } } - _ => unimplemented!() }; Ok(0) } @@ -167,9 +186,7 @@ impl Syscall<'_> { /// Send a signal to a thread specified by tid - /// TODO: support all the signals pub fn sys_tkill(&mut self, tid: usize, signum: usize) -> SysResult { - // Other signals except SIGKILL are not supported let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; info!( "tkill: thread {} kill thread {} with signal {:?}", @@ -191,8 +208,8 @@ impl Syscall<'_> { } /// Send a signal to a thread specified by tgid (i.e., process) and pid + /// Note: the job of the target process should be the same as the calling thread pub fn sys_tgkill(&mut self, tgid: usize, tid: usize, signum: usize) -> SysResult { - // Other signals except SIGKILL are not supported let signal = Signal::try_from(signum as u8).map_err(|_| LxError::EINVAL)?; info!( "tkill: thread {} kill thread {} in process {} with signal {:?}", @@ -201,25 +218,17 @@ impl Syscall<'_> { tgid, signum ); + warn!( + "The signal will be delivered to the target process that + belongs to the same job as the calling thread." + ); let parent = self.zircon_process().clone(); match parent.job().get_child(tgid as u64).map(|proc| proc.get_child(tid as u64)) { Ok(Ok(obj)) => { - match signal { - Signal::SIGRT33 => { - let current_tgid = parent.id(); - let current_tid = self.thread.id(); - if current_tgid == (tgid as u64) && current_tid == (tid as u64) { - // killing myself - self.sys_exit(-1).unwrap(); - } else { - let thread: Arc = obj.downcast_arc().unwrap(); - let mut thread_linux = thread.lock_linux(); - thread_linux.signals.insert(signal); - drop(thread_linux); - } - }, - _ => unimplemented!() - }; + let thread: Arc = obj.downcast_arc().unwrap(); + let mut thread_linux = thread.lock_linux(); + thread_linux.signals.insert(signal); + drop(thread_linux); Ok(0) } _ => Err(LxError::EINVAL) From 008175ce2b9eeb89eb7bd740e368b80bd9590704 Mon Sep 17 00:00:00 2001 From: liusm18 Date: Mon, 11 Apr 2022 11:10:39 +0800 Subject: [PATCH 11/35] Remove some useless comments --- linux-object/src/thread.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/linux-object/src/thread.rs b/linux-object/src/thread.rs index ac8284e2..fbd67de5 100644 --- a/linux-object/src/thread.rs +++ b/linux-object/src/thread.rs @@ -87,20 +87,19 @@ pub struct LinuxThread { #[allow(unsafe_code)] impl LinuxThread { - /// Restore the information after the signal handler return + /// Restore the information after the signal handler returns pub fn restore_after_handle_signal(&mut self, ctx: &mut UserContext, old_ctx: &UserContext) { let ctx_in_us; unsafe { let stack_top = ctx.get_field(UserContextField::StackPointer) as *mut SignalUserContext; ctx_in_us = &*stack_top; } - // error!("ctx: {:#x?} old_ctx: {:#x?} ctx_in_us_pc: {:#x?}", ctx, old_ctx, ctx_in_us); *ctx = *old_ctx; - // error!("ctx_in_us_pc: {:#x?}", ctx_in_us.context.get_pc()); ctx.set_field(UserContextField::InstrPointer, ctx_in_us.context.get_pc()); let mut new_mask = Sigset::empty(); + warn!("FIXME: the signal mask is not correctly restored, because of align issues + of the SignalUserContext with C musl library."); new_mask.insert(Signal::SIGRT33); - // self.signal_mask = Sigset::new(ctx_in_us.sig_mask as u64); self.signal_mask = new_mask; self.handling_signal = None; } From 3b8eaa17be01a7267b33685ed2ef3562423f62fb Mon Sep 17 00:00:00 2001 From: liusm18 Date: Mon, 11 Apr 2022 14:32:13 +0800 Subject: [PATCH 12/35] Remove hard codes in handle_signal() --- linux-object/src/signal/action.rs | 14 ++- linux-object/src/signal/mod.rs | 138 +++++++++++++++--------------- linux-object/src/thread.rs | 5 ++ loader/src/linux.rs | 42 +++++---- 4 files changed, 112 insertions(+), 87 deletions(-) diff --git a/linux-object/src/signal/action.rs b/linux-object/src/signal/action.rs index c289a991..58a738f1 100644 --- a/linux-object/src/signal/action.rs +++ b/linux-object/src/signal/action.rs @@ -1,4 +1,5 @@ use crate::signal::Signal; +use _core::convert::TryFrom; use bitflags::*; pub const SIG_ERR: usize = usize::max_value() - 1; @@ -38,8 +39,17 @@ impl Sigset { pub fn remove_set(&mut self, sigset: &Sigset) { self.0 ^= self.0 & sigset.0; } - pub fn mask_with(&self, sigset: &Sigset) -> Sigset { - Sigset(self.0 & (!sigset.0)) + pub fn mask_with(&self, mask: &Sigset) -> Sigset { + Sigset(self.0 & (!mask.0)) + } + pub fn find_first_not_mask_signal(&self, mask: &Sigset) -> Option { + let masked_signals = self.0 & (!mask.0); + for i in 1..65 { + if ((masked_signals >> i) & 1) != 0 { + return Some(Signal::try_from(i).unwrap()); + } + } + None } pub fn is_empty(&self) -> bool { self.0 == 0 diff --git a/linux-object/src/signal/mod.rs b/linux-object/src/signal/mod.rs index d7d496dc..98d4e126 100644 --- a/linux-object/src/signal/mod.rs +++ b/linux-object/src/signal/mod.rs @@ -133,75 +133,75 @@ cfg_if::cfg_if! { } numeric_enum! { -#[repr(u8)] -#[derive(Eq, PartialEq, Debug, Copy, Clone)] -pub enum Signal { - SIGHUP = 1, - SIGINT = 2, - SIGQUIT = 3, - SIGILL = 4, - SIGTRAP = 5, - SIGABRT = 6, - SIGBUS = 7, - SIGFPE = 8, - SIGKILL = 9, - SIGUSR1 = 10, - SIGSEGV = 11, - SIGUSR2 = 12, - SIGPIPE = 13, - SIGALRM = 14, - SIGTERM = 15, - SIGSTKFLT = 16, - SIGCHLD = 17, - SIGCONT = 18, - SIGSTOP = 19, - SIGTSTP = 20, - SIGTTIN = 21, - SIGTTOU = 22, - SIGURG = 23, - SIGXCPU = 24, - SIGXFSZ = 25, - SIGVTALRM = 26, - SIGPROF = 27, - SIGWINCH = 28, - SIGIO = 29, - SIGPWR = 30, - SIGSYS = 31, - // real time signals - SIGRT32 = 32, - SIGRT33 = 33, - SIGRT34 = 34, - SIGRT35 = 35, - SIGRT36 = 36, - SIGRT37 = 37, - SIGRT38 = 38, - SIGRT39 = 39, - SIGRT40 = 40, - SIGRT41 = 41, - SIGRT42 = 42, - SIGRT43 = 43, - SIGRT44 = 44, - SIGRT45 = 45, - SIGRT46 = 46, - SIGRT47 = 47, - SIGRT48 = 48, - SIGRT49 = 49, - SIGRT50 = 50, - SIGRT51 = 51, - SIGRT52 = 52, - SIGRT53 = 53, - SIGRT54 = 54, - SIGRT55 = 55, - SIGRT56 = 56, - SIGRT57 = 57, - SIGRT58 = 58, - SIGRT59 = 59, - SIGRT60 = 60, - SIGRT61 = 61, - SIGRT62 = 62, - SIGRT63 = 63, - SIGRT64 = 64, -} + #[repr(u8)] + #[derive(Eq, PartialEq, Debug, Copy, Clone)] + pub enum Signal { + SIGHUP = 1, + SIGINT = 2, + SIGQUIT = 3, + SIGILL = 4, + SIGTRAP = 5, + SIGABRT = 6, + SIGBUS = 7, + SIGFPE = 8, + SIGKILL = 9, + SIGUSR1 = 10, + SIGSEGV = 11, + SIGUSR2 = 12, + SIGPIPE = 13, + SIGALRM = 14, + SIGTERM = 15, + SIGSTKFLT = 16, + SIGCHLD = 17, + SIGCONT = 18, + SIGSTOP = 19, + SIGTSTP = 20, + SIGTTIN = 21, + SIGTTOU = 22, + SIGURG = 23, + SIGXCPU = 24, + SIGXFSZ = 25, + SIGVTALRM = 26, + SIGPROF = 27, + SIGWINCH = 28, + SIGIO = 29, + SIGPWR = 30, + SIGSYS = 31, + // real time signals + SIGRT32 = 32, + SIGRT33 = 33, + SIGRT34 = 34, + SIGRT35 = 35, + SIGRT36 = 36, + SIGRT37 = 37, + SIGRT38 = 38, + SIGRT39 = 39, + SIGRT40 = 40, + SIGRT41 = 41, + SIGRT42 = 42, + SIGRT43 = 43, + SIGRT44 = 44, + SIGRT45 = 45, + SIGRT46 = 46, + SIGRT47 = 47, + SIGRT48 = 48, + SIGRT49 = 49, + SIGRT50 = 50, + SIGRT51 = 51, + SIGRT52 = 52, + SIGRT53 = 53, + SIGRT54 = 54, + SIGRT55 = 55, + SIGRT56 = 56, + SIGRT57 = 57, + SIGRT58 = 58, + SIGRT59 = 59, + SIGRT60 = 60, + SIGRT61 = 61, + SIGRT62 = 62, + SIGRT63 = 63, + SIGRT64 = 64, + } } impl Signal { diff --git a/linux-object/src/thread.rs b/linux-object/src/thread.rs index fbd67de5..d9ed2875 100644 --- a/linux-object/src/thread.rs +++ b/linux-object/src/thread.rs @@ -103,4 +103,9 @@ impl LinuxThread { self.signal_mask = new_mask; self.handling_signal = None; } + + /// Get signal info + pub fn get_signal_info(&self) -> (Sigset, Sigset, Option) { + return (self.signals, self.signal_mask, self.handling_signal) + } } diff --git a/loader/src/linux.rs b/loader/src/linux.rs index afd9f7f2..468fcbf8 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -1,7 +1,7 @@ //! Run Linux process and manage trap/interrupt/syscall. use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec}; -use linux_object::signal::{SigInfo, SiginfoFields, SignalUserContext, Sigset}; +use linux_object::signal::{SigInfo, SiginfoFields, SignalUserContext, Sigset, Signal, SignalActionFlags}; use core::{future::Future, pin::Pin}; use kernel_hal::context::{TrapReason, UserContext, UserContextField}; @@ -61,11 +61,14 @@ async fn run_user(thread: CurrentThread) { } // check the signal and handle - let signals = thread.inner().lock_linux().signals; - let sigmask = thread.inner().lock_linux().signal_mask; - let handling_signal = thread.inner().lock_linux().handling_signal; + let (signals, sigmask, handling_signal) = + thread.inner().lock_linux().get_signal_info(); if signals.mask_with(&sigmask).is_not_empty() && handling_signal.is_none() { - handle_signal(&thread, &mut *ctx, sigmask); + let signal = signals.find_first_not_mask_signal(&sigmask).unwrap(); + thread.lock_linux().handling_signal = Some( + signal as u32 + ); + ctx = handle_signal(&thread, ctx, signal, sigmask).await; } // run @@ -80,8 +83,9 @@ async fn run_user(thread: CurrentThread) { } } -fn handle_signal(thread: &CurrentThread, ctx: *mut UserContext, sigmask: Sigset) { - let action = thread.proc().linux().signal_action(linux_object::signal::Signal::SIGRT33); +async fn handle_signal(thread: &CurrentThread, mut ctx: Box, signal: Signal, sigmask: Sigset) -> Box { + warn!("Not fully implemented SignalInfo, SignalStack, SignalActionFlags except SIGINFO"); + let action = thread.proc().linux().signal_action(signal); let signal_info = SigInfo { signo: 0, errno: 0, @@ -90,22 +94,28 @@ fn handle_signal(thread: &CurrentThread, ctx: *mut UserContext, sigmask: Sigset) }; let mut signal_context = SignalUserContext::default(); signal_context.sig_mask = sigmask.val() as u128; - thread.lock_linux().handling_signal = Some(linux_object::signal::Signal::SIGRT33 as u32); // backup current context and set new context unsafe { thread.backup_context((*ctx).clone()); let sp = (*ctx).get_field(UserContextField::StackPointer) - 0x200; - let sp = push_stack::(sp, signal_info); - let siginfo_ptr = sp; - let pc = (*ctx).get_field(UserContextField::InstrPointer); - signal_context.context.set_pc(pc); - let sp = push_stack::(sp, signal_context); - (*ctx).setup_uspace(action.handler, sp, &[ - linux_object::signal::Signal::SIGRT33 as usize, siginfo_ptr, sp - ]); + if action.flags.contains(SignalActionFlags::SIGINFO) { + let sp = push_stack::(sp, signal_info); + let siginfo_ptr = sp; + let pc = (*ctx).get_field(UserContextField::InstrPointer); + signal_context.context.set_pc(pc); + let sp = push_stack::(sp, signal_context); + (*ctx).setup_uspace(action.handler, sp, &[ + linux_object::signal::Signal::SIGRT33 as usize, siginfo_ptr, sp + ]); + } else { + (*ctx).setup_uspace(action.handler, sp, &[ + signal as usize, 0, 0 + ]); + } (*ctx).set_ra(action.restorer); (*ctx).enter_uspace(); } + return ctx; } /// Push stack From de77f1198871df12daf0fae7671391badd48f8e4 Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Mon, 11 Apr 2022 19:15:21 +0800 Subject: [PATCH 13/35] Remove hard codes & Fix warn --- linux-syscall/src/lib.rs | 18 +++++--------- linux-syscall/src/misc.rs | 40 ++++++------------------------- linux-syscall/src/task.rs | 5 ---- zircon-object/src/signal/futex.rs | 20 ++-------------- 4 files changed, 15 insertions(+), 68 deletions(-) diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index a4176ccd..ca407dcb 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -375,18 +375,12 @@ impl Syscall<'_> { .await } Sys::SET_TID_ADDRESS => self.sys_set_tid_address(self.into_out_userptr(a0).unwrap()), - Sys::FUTEX => { - info!("Futex: {} {} {} {} {} {}", a0, a1, a2, a3, a4, a5); - self.sys_futex(a0, a1 as _, a2 as _, a3, a4, a5 as _).await - } - Sys::GET_ROBUST_LIST => { - warn!("{},{},{}", a0, a1, a2); - self.sys_get_robust_list( - a0 as _, - self.into_out_userptr(a1).unwrap(), - self.into_out_userptr(a2).unwrap(), - ) - } + Sys::FUTEX => self.sys_futex(a0, a1 as _, a2 as _, a3, a4, a5 as _).await, + Sys::GET_ROBUST_LIST => self.sys_get_robust_list( + a0 as _, + self.into_out_userptr(a1).unwrap(), + self.into_out_userptr(a2).unwrap(), + ), Sys::SET_ROBUST_LIST => { self.sys_set_robust_list(self.into_in_userptr(a0).unwrap(), a1 as _) } diff --git a/linux-syscall/src/misc.rs b/linux-syscall/src/misc.rs index e03c1129..afcc7f16 100644 --- a/linux-syscall/src/misc.rs +++ b/linux-syscall/src/misc.rs @@ -71,7 +71,9 @@ impl Syscall<'_> { /// - `uaddr` - points to the futex word. /// - `op` - the operation to perform on the futex /// - `val` - a value whose meaning and purpose depends on op - /// - `timeout` - not support now + /// - `timeout_addr` - provides a timeout for the attempt or acts as val2 when op is REQUEUE + /// - `uaddr2` - when op is REQUEUE, points to the target futex + /// - `_val3` - is not used pub async fn sys_futex( &self, uaddr: usize, @@ -129,7 +131,6 @@ impl Syscall<'_> { let res = if duration.as_millis() == 0 { future.await } else { - warn!("Futex duration: {:?}", duration); pin_mut!(future); self.thread .blocking_run( @@ -150,35 +151,8 @@ impl Syscall<'_> { Ok(woken_up_count) } FutexFlags::LOCK_PI => { - // Still have bugs - let timeout = timeout.read_if_not_null()?; - let duration: Duration = match timeout { - Some(t) => t.into(), - None => Duration::from_secs(0), - }; - let into_lxerror = |e: ZxError| match e { - ZxError::BAD_STATE => LxError::EAGAIN, - e => e.into(), - }; - let future = futex.wait(val, true, self.thread.id() as i32); - let res = if duration.as_millis() == 0 { - future.await - } else { - warn!("Futex duration: {:?}", duration); - pin_mut!(future); - self.thread - .blocking_run( - future, - ThreadState::BlockedFutex, - timer_now() + duration, - None, - ) - .await - }; - match res { - Ok(_) => return Ok(0), - Err(e) => return Err(into_lxerror(e)), - } + warn!("futex LOCK_PI is unimplemented"); + Ok(0) } FutexFlags::REQUEUE => { let requeue_futex = self.linux_process().get_futex(uaddr2); @@ -264,9 +238,9 @@ bitflags! { const WAKE = 1; /// wakes up a maximum of val waiters that are waiting on the futex at uaddr. If there are more than val waiters, then the remaining waiters are removed from the wait queue of the source futex at uaddr and added to the wait queue of the target futex at uaddr2. The val2 argument specifies an upper limit on the number of waiters that are requeued to the futex at uaddr2. const REQUEUE = 3; - /// used after an attempt to acquire the lock via an atomic user-mode instruction failed. + /// (unsupported) is used after an attempt to acquire the lock via an atomic user-mode instruction failed. const LOCK_PI = 6; - /// called when the user-space value at uaddr cannot be changed atomically from a TID (of the owner) to 0. + /// (unsupported) is called when the user-space value at uaddr cannot be changed atomically from a TID (of the owner) to 0. const UNLOCK_PI = 7; /// can be employed with all futex operations, tells the kernel that the futex is process-private and not shared with another process const PRIVATE = 0x80; diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index fd31e046..e8a04b29 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -282,19 +282,14 @@ impl Syscall<'_> { head_ptr: UserOutPtr>, len_ptr: UserOutPtr, ) -> SysResult { - warn!("in1 sys_get_robust_list"); if pid == 0 { - warn!("in2 sys_get_robust_list"); return self.thread.get_robust_list(head_ptr, len_ptr); - } else { - warn!("out sys_get_robust_list"); } Ok(0) } /// Set robust list. pub fn sys_set_robust_list(&self, head: UserInPtr, len: usize) -> SysResult { - warn!("in sys_set_robust_list"); if len != size_of::().into() { return Err(LxError::EINVAL); } diff --git a/zircon-object/src/signal/futex.rs b/zircon-object/src/signal/futex.rs index a2e943e8..e65a08cb 100644 --- a/zircon-object/src/signal/futex.rs +++ b/zircon-object/src/signal/futex.rs @@ -142,29 +142,14 @@ impl Futex { if inner.woken { // set new owner on success inner.futex.inner.lock().set_owner(self.new_owner.clone()); - warn!("Futex Ready!!!"); return Poll::Ready(Ok(())); } // first time? if inner.waker.is_none() { // check value let value = inner.futex.value.load(Ordering::SeqCst); - if self.lock_pi { - if value as u32 == 0 { - warn!("This is {}", self.thread_id); - inner.futex.value.store(self.thread_id, Ordering::SeqCst); - } else { - inner - .futex - .value - .store((value as u32 | 0x80000000) as i32, Ordering::SeqCst); - } - return Poll::Ready(Ok(())); - } else { - if value as u32 != self.current_value { - warn!("Futex BAD_STATE!!!"); - return Poll::Ready(Err(ZxError::BAD_STATE)); - } + if value as u32 != self.current_value { + return Poll::Ready(Err(ZxError::BAD_STATE)); } // check new owner let mut futex = inner.futex.inner.lock(); @@ -175,7 +160,6 @@ impl Futex { drop(futex); inner.waker.replace(cx.waker().clone()); } - warn!("Futex pending!!!"); Poll::Pending } } From 7deff3e73b5f6d88a439eaa86907231e9581bf4e Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Wed, 13 Apr 2022 17:32:41 +0800 Subject: [PATCH 14/35] Fix for CI --- linux-syscall/src/misc.rs | 2 +- linux-syscall/src/signal.rs | 30 +++++++++++++++--------------- loader/src/linux.rs | 11 ++++++----- zircon-object/src/signal/futex.rs | 15 ++------------- 4 files changed, 24 insertions(+), 34 deletions(-) diff --git a/linux-syscall/src/misc.rs b/linux-syscall/src/misc.rs index afcc7f16..347fd309 100644 --- a/linux-syscall/src/misc.rs +++ b/linux-syscall/src/misc.rs @@ -127,7 +127,7 @@ impl Syscall<'_> { ZxError::BAD_STATE => LxError::EAGAIN, e => e.into(), }; - let future = futex.wait(val, false, self.thread.id() as i32); + let future = futex.wait(val); let res = if duration.as_millis() == 0 { future.await } else { diff --git a/linux-syscall/src/signal.rs b/linux-syscall/src/signal.rs index bd4f27c7..a6783bdc 100644 --- a/linux-syscall/src/signal.rs +++ b/linux-syscall/src/signal.rs @@ -136,7 +136,7 @@ impl Syscall<'_> { 0 => SendTarget::EveryProcessInGroup, -1 => SendTarget::EveryProcess, p if p < -1 => SendTarget::EveryProcessInGroupByPID((-p) as KoID), - _ => unimplemented!() + _ => unimplemented!(), }; let parent = self.zircon_process().clone(); match target { @@ -154,18 +154,17 @@ impl Syscall<'_> { process.exit(-1); } } - _ => unimplemented!() + _ => unimplemented!(), }; Ok(0) } - Err(_) => Err(LxError::EINVAL) + Err(_) => Err(LxError::EINVAL), } } - _ => unimplemented!() + _ => unimplemented!(), } } - /// Send a signal to a thread specified by tid /// TODO: support all the signals pub fn sys_tkill(&mut self, tid: usize, signum: usize) -> SysResult { @@ -192,12 +191,12 @@ impl Syscall<'_> { thread_linux.signal_mask.insert(signal); drop(thread_linux); } - }, - _ => unimplemented!() + } + _ => unimplemented!(), }; Ok(0) } - Err(_) => Err(LxError::EINVAL) + Err(_) => Err(LxError::EINVAL), } } @@ -214,7 +213,11 @@ impl Syscall<'_> { signum ); let parent = self.zircon_process().clone(); - match parent.job().get_child(tgid as u64).map(|proc| proc.get_child(tid as u64)) { + match parent + .job() + .get_child(tgid as u64) + .map(|proc| proc.get_child(tid as u64)) + { Ok(Ok(obj)) => { match signal { Signal::SIGRT33 => { @@ -229,15 +232,12 @@ impl Syscall<'_> { thread_linux.signal_mask.insert(signal); drop(thread_linux); } - }, - _ => unimplemented!() + } + _ => unimplemented!(), }; Ok(0) } - _ => Err(LxError::EINVAL) + _ => Err(LxError::EINVAL), } } - - - } diff --git a/loader/src/linux.rs b/loader/src/linux.rs index d9a10834..682fd030 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -59,10 +59,13 @@ async fn run_user(thread: CurrentThread) { break; } - info!("back to user: thread id = {}", thread.id()); - // check the signal if was killed - if thread.inner().lock_linux().signal_mask.contains(linux_object::signal::Signal::SIGRT33) { + if thread + .inner() + .lock_linux() + .signal_mask + .contains(linux_object::signal::Signal::SIGRT33) + { thread.exit_linux(-1); // do not break temporarily } @@ -72,8 +75,6 @@ async fn run_user(thread: CurrentThread) { ctx.enter_uspace(); trace!("back from user: {:#x?}", ctx); - info!("into kernel: thread id = {}", thread.id()); - // handle trap/interrupt/syscall if let Err(err) = handle_user_trap(&thread, ctx).await { thread.exit_linux(err as i32); diff --git a/zircon-object/src/signal/futex.rs b/zircon-object/src/signal/futex.rs index e65a08cb..5f1d9628 100644 --- a/zircon-object/src/signal/futex.rs +++ b/zircon-object/src/signal/futex.rs @@ -57,13 +57,8 @@ impl Futex { /// /// [`wait_with_owner`]: Futex::wait_with_owner /// [`wake`]: Futex::wake - pub fn wait( - self: &Arc, - current_value: u32, - lock_pi: bool, - thread_id: i32, - ) -> impl Future { - self.wait_with_owner(current_value, None, None, lock_pi, thread_id) + pub fn wait(self: &Arc, current_value: u32) -> impl Future { + self.wait_with_owner(current_value, None, None) } /// Wake some number of threads waiting on a futex. @@ -122,16 +117,12 @@ impl Futex { current_value: u32, thread: Option>, new_owner: Option>, - lock_pi: bool, - thread_id: i32, ) -> impl Future { #[must_use = "wait does nothing unless polled/`await`-ed"] struct FutexFuture { waiter: Arc, current_value: u32, new_owner: Option>, - lock_pi: bool, - thread_id: i32, } impl Future for FutexFuture { type Output = ZxResult; @@ -189,8 +180,6 @@ impl Futex { }), current_value, new_owner, - lock_pi, - thread_id, } } From 861bac0498f5d95fecc1de67921c72df28226e6c Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Wed, 13 Apr 2022 19:31:29 +0800 Subject: [PATCH 15/35] Fix for CI --- linux-syscall/src/misc.rs | 2 +- zircon-object/src/signal/futex.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linux-syscall/src/misc.rs b/linux-syscall/src/misc.rs index 347fd309..05b9906c 100644 --- a/linux-syscall/src/misc.rs +++ b/linux-syscall/src/misc.rs @@ -127,7 +127,7 @@ impl Syscall<'_> { ZxError::BAD_STATE => LxError::EAGAIN, e => e.into(), }; - let future = futex.wait(val); + let future = futex.wait(val as _); let res = if duration.as_millis() == 0 { future.await } else { diff --git a/zircon-object/src/signal/futex.rs b/zircon-object/src/signal/futex.rs index 5f1d9628..af1fa526 100644 --- a/zircon-object/src/signal/futex.rs +++ b/zircon-object/src/signal/futex.rs @@ -57,7 +57,7 @@ impl Futex { /// /// [`wait_with_owner`]: Futex::wait_with_owner /// [`wake`]: Futex::wake - pub fn wait(self: &Arc, current_value: u32) -> impl Future { + pub fn wait(self: &Arc, current_value: i32) -> impl Future { self.wait_with_owner(current_value, None, None) } @@ -114,14 +114,14 @@ impl Futex { /// [`wake`]: Futex::wake pub fn wait_with_owner( self: &Arc, - current_value: u32, + current_value: i32, thread: Option>, new_owner: Option>, ) -> impl Future { #[must_use = "wait does nothing unless polled/`await`-ed"] struct FutexFuture { waiter: Arc, - current_value: u32, + current_value: i32, new_owner: Option>, } impl Future for FutexFuture { @@ -139,7 +139,7 @@ impl Futex { if inner.waker.is_none() { // check value let value = inner.futex.value.load(Ordering::SeqCst); - if value as u32 != self.current_value { + if value != self.current_value { return Poll::Ready(Err(ZxError::BAD_STATE)); } // check new owner From 2cb5cae22be86cce5399c91122c7afc952e69b77 Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Wed, 13 Apr 2022 19:42:42 +0800 Subject: [PATCH 16/35] Fix for CI --- linux-syscall/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index ca407dcb..a14c1ba8 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -29,7 +29,8 @@ use core::convert::TryFrom; use kernel_hal::user::{IoVecIn, IoVecOut, UserInOutPtr, UserInPtr, UserOutPtr}; #[cfg(target_os = "none")] -use kernel_hal::vm::{PagingError, PagingResult}; +use kernel_hal::vm::PagingError; +use kernel_hal::vm::PagingResult; use kernel_hal::MMUFlags; use linux_object::error::{LxError, SysResult}; use linux_object::fs::FileDesc; From 2cb5d05b9a8d4ca73454d48b9811ab029536779d Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Wed, 13 Apr 2022 19:52:40 +0800 Subject: [PATCH 17/35] Fix for CI --- zircon-object/src/signal/futex.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zircon-object/src/signal/futex.rs b/zircon-object/src/signal/futex.rs index af1fa526..5fba29a9 100644 --- a/zircon-object/src/signal/futex.rs +++ b/zircon-object/src/signal/futex.rs @@ -367,10 +367,10 @@ mod tests { // inconsistent value should fail. assert_eq!( - futex.requeue(1, 1, 1, &requeue_futex, None), + futex.requeue(1, 1, 1, &requeue_futex, None, true), Err(ZxError::BAD_STATE) ); - assert!(futex.requeue(2, 1, 1, &requeue_futex, None).is_ok()); + assert!(futex.requeue(2, 1, 1, &requeue_futex, None, true).is_ok()); // 1 waiter waken, 1 waiter moved into `requeue_futex`. assert_eq!(futex.inner.lock().waiter_queue.len(), 0); assert_eq!(requeue_futex.inner.lock().waiter_queue.len(), 1); From 7eff7cf67b844d6a64227832b975f7000c1f3f38 Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Wed, 13 Apr 2022 21:30:14 +0800 Subject: [PATCH 18/35] Fix for CI --- linux-syscall/src/misc.rs | 12 ++++++------ linux-syscall/src/task.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/linux-syscall/src/misc.rs b/linux-syscall/src/misc.rs index 05b9906c..d2fadb91 100644 --- a/linux-syscall/src/misc.rs +++ b/linux-syscall/src/misc.rs @@ -83,7 +83,7 @@ impl Syscall<'_> { uaddr2: usize, _val3: u32, ) -> SysResult { - if let Err(_) = self.into_inout_userptr::(uaddr) { + if self.into_inout_userptr::(uaddr).is_err() { return Err(LxError::EINVAL); } let op = FutexFlags::from_bits_truncate(op); @@ -92,7 +92,7 @@ impl Syscall<'_> { } let mut val2 = 0; if op.contains(FutexFlags::REQUEUE) { - if let Err(_) = self.into_inout_userptr::(uaddr2) { + if self.into_inout_userptr::(uaddr2).is_err() { return Err(LxError::EINVAL); } val2 = timeout_addr; @@ -142,8 +142,8 @@ impl Syscall<'_> { .await }; match res { - Ok(_) => return Ok(0), - Err(e) => return Err(into_lxerror(e)), + Ok(_) => Ok(0), + Err(e) => Err(into_lxerror(e)), } } FutexFlags::WAKE => { @@ -162,8 +162,8 @@ impl Syscall<'_> { }; let res = futex.requeue(0, val as usize, val2, &requeue_futex, None, false); match res { - Ok(_) => return Ok(0), - Err(e) => return Err(into_lxerror(e)), + Ok(_) => Ok(0), + Err(e) => Err(into_lxerror(e)), } } _ => { diff --git a/linux-syscall/src/task.rs b/linux-syscall/src/task.rs index e8a04b29..9f5e09ed 100644 --- a/linux-syscall/src/task.rs +++ b/linux-syscall/src/task.rs @@ -290,7 +290,7 @@ impl Syscall<'_> { /// Set robust list. pub fn sys_set_robust_list(&self, head: UserInPtr, len: usize) -> SysResult { - if len != size_of::().into() { + if len != size_of::() { return Err(LxError::EINVAL); } self.thread.set_robust_list(head, len); From 7b7911a2dcac8dde129aed7a68114ef64848693d Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Fri, 15 Apr 2022 17:08:19 +0800 Subject: [PATCH 19/35] Fix Makefile LINUX --- zCore/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zCore/Makefile b/zCore/Makefile index 95507f3f..0e73c856 100644 --- a/zCore/Makefile +++ b/zCore/Makefile @@ -1,10 +1,10 @@ ################ Arguments ################ -ARCH ?= riscv64 +ARCH ?= x86_64 PLATFORM ?= qemu MODE ?= release LOG ?= warn -LINUX ?= 1 +LINUX ?= LIBOS ?= TEST ?= GRAPHIC ?= From 028ecea08258f218c6d69d6361d0c59cb48dbae8 Mon Sep 17 00:00:00 2001 From: liusm18 Date: Fri, 15 Apr 2022 18:15:14 +0800 Subject: [PATCH 20/35] Add x86_64 support --- kernel-hal/src/common/context.rs | 4 +++- linux-syscall/src/lib.rs | 13 ++----------- linux-syscall/src/signal.rs | 4 ++++ loader/src/linux.rs | 24 +++++++++++++++++------- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/kernel-hal/src/common/context.rs b/kernel-hal/src/common/context.rs index d7549ba5..d288eb2a 100644 --- a/kernel-hal/src/common/context.rs +++ b/kernel-hal/src/common/context.rs @@ -163,8 +163,10 @@ impl UserContext { cfg_if! { if #[cfg(target_arch = "riscv64")] { self.0.general.ra = _ra; + } else if #[cfg(target_arch = "x86_64")] { + error!("Please set return addr via stack!"); } else { - unimplemented!("Unsupported arch!") + unimplemented!("Unsupported arch!"); } } } diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 35d71ddb..a32da5a6 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -364,17 +364,6 @@ impl Syscall<'_> { } // process - Sys::CLONE => { - // warn!("a2={} a3={}", a2, a3); - // self.sys_clone( - // a0, - // a1, - // self.into_out_userptr(a2).unwrap(), - // self.into_out_userptr(a3).unwrap(), - // a4, - // ) - self.sys_clone(a0, a1, a2.into(), a3, a4.into()) - } Sys::EXECVE => self.sys_execve( self.into_in_userptr(a0).unwrap(), self.into_in_userptr(a1).unwrap(), @@ -532,6 +521,7 @@ impl Syscall<'_> { Sys::TIME => self.sys_time(self.into_out_userptr(a0).unwrap()), // Sys::EPOLL_CREATE => self.sys_epoll_create(a0), // Sys::EPOLL_WAIT => self.sys_epoll_wait(a0, a1.into(), a2, a3), + Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a4, a3.into()), _ => self.unknown_syscall(sys_type), } } @@ -542,6 +532,7 @@ impl Syscall<'_> { //let [a0, a1, a2, a3, a4, _a5] = args; match sys_type { //Sys::OPEN => self.sys_open(a0.into(), a1, a2), + Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a3, a4.into()), _ => self.unknown_syscall(sys_type), } } diff --git a/linux-syscall/src/signal.rs b/linux-syscall/src/signal.rs index 31d9ecd7..4c6694bf 100644 --- a/linux-syscall/src/signal.rs +++ b/linux-syscall/src/signal.rs @@ -237,6 +237,10 @@ impl Syscall<'_> { /// Send a signal to a thread specified by tgid (i.e., process) and pid pub fn sys_rt_sigreturn(&mut self) -> SysResult { + info!( + "sigreturn: thread {} returns from handling signal", + self.thread.id() + ); let old_ctx = self.thread.fetch_backup_context().unwrap(); self.thread.with_context(|ctx| self.thread.lock_linux().restore_after_handle_signal(ctx, &old_ctx)).unwrap(); diff --git a/loader/src/linux.rs b/loader/src/linux.rs index 468fcbf8..e95a709e 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -97,22 +97,32 @@ async fn handle_signal(thread: &CurrentThread, mut ctx: Box, signal // backup current context and set new context unsafe { thread.backup_context((*ctx).clone()); - let sp = (*ctx).get_field(UserContextField::StackPointer) - 0x200; + let mut sp = (*ctx).get_field(UserContextField::StackPointer) - 0x200; + let mut siginfo_ptr = 0; if action.flags.contains(SignalActionFlags::SIGINFO) { - let sp = push_stack::(sp, signal_info); - let siginfo_ptr = sp; + sp = push_stack::(sp, signal_info); + siginfo_ptr = sp; let pc = (*ctx).get_field(UserContextField::InstrPointer); signal_context.context.set_pc(pc); - let sp = push_stack::(sp, signal_context); + sp = push_stack::(sp, signal_context); + } + cfg_if! { + if #[cfg(target_arch = "x86_64")] { + sp &= !0xF; + sp = push_stack::(sp, action.restorer); + } else { + (*ctx).set_ra(action.restorer); + } + } + if action.flags.contains(SignalActionFlags::SIGINFO) { (*ctx).setup_uspace(action.handler, sp, &[ - linux_object::signal::Signal::SIGRT33 as usize, siginfo_ptr, sp - ]); + signal as usize, siginfo_ptr, sp + ]); } else { (*ctx).setup_uspace(action.handler, sp, &[ signal as usize, 0, 0 ]); } - (*ctx).set_ra(action.restorer); (*ctx).enter_uspace(); } return ctx; From cd0f4ee40d67611a81b2be3b35887ac807537aef Mon Sep 17 00:00:00 2001 From: liusm18 Date: Fri, 15 Apr 2022 18:18:55 +0800 Subject: [PATCH 21/35] Add tips for hard code path --- linux-syscall/src/file/dir.rs | 1 + linux-syscall/src/file/fd.rs | 1 + linux-syscall/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/linux-syscall/src/file/dir.rs b/linux-syscall/src/file/dir.rs index dbb4cd90..bdc4e03e 100644 --- a/linux-syscall/src/file/dir.rs +++ b/linux-syscall/src/file/dir.rs @@ -170,6 +170,7 @@ impl Syscall<'_> { /// The unlinkat() system call operates in exactly the same way as either unlink or rmdir. pub fn sys_unlinkat(&self, dirfd: FileDesc, path: UserInPtr, flags: usize) -> SysResult { let path = path.read_cstring()?; + // hard code special path let path = if path == "/dev/shm/testshm" { String::from("/testshm") } else { diff --git a/linux-syscall/src/file/fd.rs b/linux-syscall/src/file/fd.rs index a9a20b5f..61c48d46 100644 --- a/linux-syscall/src/file/fd.rs +++ b/linux-syscall/src/file/fd.rs @@ -24,6 +24,7 @@ impl Syscall<'_> { ) -> SysResult { let proc = self.linux_process(); let path = path.read_cstring()?; + // hard code special path let path = if path == "/dev/shm/testshm" { String::from("/testshm") } else { diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index a32da5a6..07e703a4 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -529,7 +529,7 @@ impl Syscall<'_> { #[cfg(target_arch = "riscv64")] async fn riscv64_syscall(&mut self, sys_type: Sys, args: [usize; 6]) -> SysResult { debug!("riscv64_syscall: {:?}, {:?}", sys_type, args); - //let [a0, a1, a2, a3, a4, _a5] = args; + let [a0, a1, a2, a3, a4, _a5] = args; match sys_type { //Sys::OPEN => self.sys_open(a0.into(), a1, a2), Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a3, a4.into()), From c1e5bc0897f352585be08b150212536cc233dd51 Mon Sep 17 00:00:00 2001 From: liusm18 Date: Fri, 15 Apr 2022 19:12:04 +0800 Subject: [PATCH 22/35] Fix align issues --- linux-object/src/signal/mod.rs | 2 +- loader/src/linux.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/linux-object/src/signal/mod.rs b/linux-object/src/signal/mod.rs index 98d4e126..e6d54058 100644 --- a/linux-object/src/signal/mod.rs +++ b/linux-object/src/signal/mod.rs @@ -222,7 +222,7 @@ pub struct SignalUserContext { pub flags: usize, pub link: usize, pub stack: SignalStack, - pub sig_mask: u128, + pub sig_mask: Sigset, pub context: MachineContext, } diff --git a/loader/src/linux.rs b/loader/src/linux.rs index e95a709e..6cc42481 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -93,17 +93,19 @@ async fn handle_signal(thread: &CurrentThread, mut ctx: Box, signal field: SiginfoFields::default() }; let mut signal_context = SignalUserContext::default(); - signal_context.sig_mask = sigmask.val() as u128; + signal_context.sig_mask = sigmask; // backup current context and set new context unsafe { thread.backup_context((*ctx).clone()); let mut sp = (*ctx).get_field(UserContextField::StackPointer) - 0x200; let mut siginfo_ptr = 0; if action.flags.contains(SignalActionFlags::SIGINFO) { + sp &= !0xF; sp = push_stack::(sp, signal_info); siginfo_ptr = sp; let pc = (*ctx).get_field(UserContextField::InstrPointer); signal_context.context.set_pc(pc); + sp &= !0xF; sp = push_stack::(sp, signal_context); } cfg_if! { From 5d3c254f471420cf3def3896af90fe6a6ab87d7c Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Fri, 15 Apr 2022 19:22:13 +0800 Subject: [PATCH 23/35] Fix conflicts --- linux-syscall/src/signal.rs | 32 ++++++++++++++++---------------- loader/src/linux.rs | 7 ++++++- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/linux-syscall/src/signal.rs b/linux-syscall/src/signal.rs index 6e380a76..a6783bdc 100644 --- a/linux-syscall/src/signal.rs +++ b/linux-syscall/src/signal.rs @@ -136,7 +136,7 @@ impl Syscall<'_> { 0 => SendTarget::EveryProcessInGroup, -1 => SendTarget::EveryProcess, p if p < -1 => SendTarget::EveryProcessInGroupByPID((-p) as KoID), - _ => unimplemented!() + _ => unimplemented!(), }; let parent = self.zircon_process().clone(); match target { @@ -154,18 +154,17 @@ impl Syscall<'_> { process.exit(-1); } } - _ => unimplemented!() + _ => unimplemented!(), }; Ok(0) } - Err(_) => Err(LxError::EINVAL) + Err(_) => Err(LxError::EINVAL), } } - _ => unimplemented!() + _ => unimplemented!(), } } - /// Send a signal to a thread specified by tid /// TODO: support all the signals pub fn sys_tkill(&mut self, tid: usize, signum: usize) -> SysResult { @@ -192,12 +191,12 @@ impl Syscall<'_> { thread_linux.signal_mask.insert(signal); drop(thread_linux); } - }, - _ => unimplemented!() + } + _ => unimplemented!(), }; Ok(0) } - Err(_) => Err(LxError::EINVAL) + Err(_) => Err(LxError::EINVAL), } } @@ -214,7 +213,11 @@ impl Syscall<'_> { signum ); let parent = self.zircon_process().clone(); - match parent.job().get_child(tgid as u64).map(|proc| proc.get_child(tid as u64)) { + match parent + .job() + .get_child(tgid as u64) + .map(|proc| proc.get_child(tid as u64)) + { Ok(Ok(obj)) => { match signal { Signal::SIGRT33 => { @@ -229,15 +232,12 @@ impl Syscall<'_> { thread_linux.signal_mask.insert(signal); drop(thread_linux); } - }, - _ => unimplemented!() + } + _ => unimplemented!(), }; Ok(0) } - _ => Err(LxError::EINVAL) + _ => Err(LxError::EINVAL), } } - - - -} \ No newline at end of file +} diff --git a/loader/src/linux.rs b/loader/src/linux.rs index 4654ee28..682fd030 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -60,7 +60,12 @@ async fn run_user(thread: CurrentThread) { } // check the signal if was killed - if thread.inner().lock_linux().signal_mask.contains(linux_object::signal::Signal::SIGRT33) { + if thread + .inner() + .lock_linux() + .signal_mask + .contains(linux_object::signal::Signal::SIGRT33) + { thread.exit_linux(-1); // do not break temporarily } From dd3f2790e9ad756fe53b57278b82263e618b97cd Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Fri, 15 Apr 2022 20:16:06 +0800 Subject: [PATCH 24/35] Update pthread tests --- tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests b/tests index 2a957e7a..5f3b695d 160000 --- a/tests +++ b/tests @@ -1 +1 @@ -Subproject commit 2a957e7accc358c0c84327095deca0b0a76b6867 +Subproject commit 5f3b695d9cf43578e6930a8f1955ec35924478fd From 7a35b4fd5c970f9e7b83e0d7d4ed0929aef7cb20 Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Sat, 16 Apr 2022 11:38:56 +0800 Subject: [PATCH 25/35] Fix test.yml --no-failed --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 349c840c..919b3c17 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,7 +55,7 @@ jobs: run: pip3 install -r tests/requirements.txt - name: Run fast tests if: github.event_name != 'schedule' - run: cd tests && python3 zircon_core_test.py --libos --fast + run: cd tests && python3 zircon_core_test.py --libos --fast --no-failed - name: Run full tests if: github.event_name == 'schedule' run: cd tests && python3 zircon_core_test.py --libos From 08ab919633413a22828c57bc39abc9b5372dc33d Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Sat, 16 Apr 2022 11:44:18 +0800 Subject: [PATCH 26/35] Reset tests commit --- tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests b/tests index 5f3b695d..950a8f90 160000 --- a/tests +++ b/tests @@ -1 +1 @@ -Subproject commit 5f3b695d9cf43578e6930a8f1955ec35924478fd +Subproject commit 950a8f90435fb21f6f9d7ab56cd6f7c8602e392d From e3066c23ae7a3413d13567dd92a99196c5928219 Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Sat, 16 Apr 2022 11:56:59 +0800 Subject: [PATCH 27/35] Change format in thread.rs --- zircon-object/src/task/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zircon-object/src/task/thread.rs b/zircon-object/src/task/thread.rs index ac21c3cd..67760b73 100644 --- a/zircon-object/src/task/thread.rs +++ b/zircon-object/src/task/thread.rs @@ -105,7 +105,7 @@ struct ThreadInner { context: Option>, /// Thread context before handling the signal - /// + /// /// It only works when executing signal handlers context_before: Option, From 296766831a8c7eefdc527d8c983c412b7e6a313e Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Sat, 16 Apr 2022 12:29:14 +0800 Subject: [PATCH 28/35] Add UserInPtr in thread.rs --- linux-object/src/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-object/src/thread.rs b/linux-object/src/thread.rs index d66fbef7..d80b15e3 100644 --- a/linux-object/src/thread.rs +++ b/linux-object/src/thread.rs @@ -5,7 +5,7 @@ use crate::process::ProcessExt; use crate::signal::{Signal, SignalStack, SignalUserContext, Sigset}; use alloc::sync::Arc; use kernel_hal::context::{UserContext, UserContextField}; -use kernel_hal::user::{Out, UserOutPtr, UserPtr}; +use kernel_hal::user::{Out, UserInPtr, UserOutPtr, UserPtr}; use kernel_hal::VirtAddr; use spin::{Mutex, MutexGuard}; use zircon_object::task::{CurrentThread, Process, Thread}; From a191f57ff31aa30c2910c1643882798856c93616 Mon Sep 17 00:00:00 2001 From: liusm18 Date: Sun, 17 Apr 2022 11:43:01 +0800 Subject: [PATCH 29/35] Fix some codeing style issues --- linux-object/src/signal/mod.rs | 70 +++++++++++++------------------- linux-object/src/thread.rs | 2 +- linux-syscall/src/lib.rs | 1 - zircon-object/src/task/thread.rs | 2 +- 4 files changed, 30 insertions(+), 45 deletions(-) diff --git a/linux-object/src/signal/mod.rs b/linux-object/src/signal/mod.rs index e6d54058..3e837358 100644 --- a/linux-object/src/signal/mod.rs +++ b/linux-object/src/signal/mod.rs @@ -11,7 +11,7 @@ cfg_if::cfg_if! { if #[cfg(target_arch = "x86_64")] { /// struct mcontext #[repr(C)] - #[derive(Clone, Debug)] + #[derive(Clone, Debug, Default)] pub struct MachineContext { // gregs pub r8: usize, @@ -47,45 +47,6 @@ cfg_if::cfg_if! { pub _reserved1: [usize; 8], } - impl Default for MachineContext { - fn default() -> Self { - Self { - // gregs - r8: 0, - r9: 0, - r10: 0, - r11: 0, - r12: 0, - r13: 0, - r14: 0, - r15: 0, - rdi: 0, - rsi: 0, - rbp: 0, - rbx: 0, - rdx: 0, - rax: 0, - rcx: 0, - rsp: 0, - rip: 0, - eflags: 0, - cs: 0, - gs: 0, - fs: 0, - _pad: 0, - err: 0, - trapno: 0, - oldmask: 0, - cr2: 0, - // fpregs - // TODO - fpstate: 0, - // reserved - _reserved1: [0; 8], - } - } - } - impl MachineContext { pub fn set_pc(&mut self, pc: usize) { self.rip = pc; @@ -94,8 +55,7 @@ cfg_if::cfg_if! { self.rip } } - } - else if #[cfg(target_arch = "riscv64")] { + } else if #[cfg(target_arch = "riscv64")] { /// struct mcontext #[repr(C)] #[derive(Clone, Debug)] @@ -129,6 +89,32 @@ cfg_if::cfg_if! { self.pc } } + } else { + /// TODO: other archs + /// struct mcontext + #[repr(C)] + #[derive(Clone, Debug)] + pub struct MachineContext { + // TODO + pub reserved_: [usize; 36], + } + + impl Default for MachineContext { + fn default() -> Self { + Self { + reserved_: [0; 36], + } + } + } + + impl MachineContext { + pub fn set_pc(&mut self, pc: usize) { + + } + pub fn get_pc(&self) -> usize { + 0 + } + } } } diff --git a/linux-object/src/thread.rs b/linux-object/src/thread.rs index d80b15e3..10d9d0fb 100644 --- a/linux-object/src/thread.rs +++ b/linux-object/src/thread.rs @@ -147,6 +147,6 @@ impl LinuxThread { /// Get signal info pub fn get_signal_info(&self) -> (Sigset, Sigset, Option) { - return (self.signals, self.signal_mask, self.handling_signal); + (self.signals, self.signal_mask, self.handling_signal) } } diff --git a/linux-syscall/src/lib.rs b/linux-syscall/src/lib.rs index 29b69db2..77c9d07d 100644 --- a/linux-syscall/src/lib.rs +++ b/linux-syscall/src/lib.rs @@ -527,7 +527,6 @@ impl Syscall<'_> { Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a4, a3.into()), // Sys::EPOLL_CREATE => self.sys_epoll_create(a0), // Sys::EPOLL_WAIT => self.sys_epoll_wait(a0, a1.into(), a2, a3), - Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a4, a3.into()), _ => self.unknown_syscall(sys_type), } } diff --git a/zircon-object/src/task/thread.rs b/zircon-object/src/task/thread.rs index 67760b73..f3c443b3 100644 --- a/zircon-object/src/task/thread.rs +++ b/zircon-object/src/task/thread.rs @@ -243,7 +243,7 @@ impl Thread { /// Returns a copy of saved context of current thread, or `Err(ZxError::BAD_STATE)` /// if the thread is running. pub fn context_cloned(&self) -> ZxResult { - self.with_context(|ctx| ctx.clone()) + self.with_context(|ctx| *ctx) } /// Access saved context of current thread, or `Err(ZxError::BAD_STATE)` if From 59c6de2d742a5ca9508f62502fa253b55637f9a4 Mon Sep 17 00:00:00 2001 From: liusm18 Date: Sun, 17 Apr 2022 11:53:10 +0800 Subject: [PATCH 30/35] Fix a code format --- linux-object/src/signal/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/linux-object/src/signal/mod.rs b/linux-object/src/signal/mod.rs index 3e837358..34808622 100644 --- a/linux-object/src/signal/mod.rs +++ b/linux-object/src/signal/mod.rs @@ -108,9 +108,7 @@ cfg_if::cfg_if! { } impl MachineContext { - pub fn set_pc(&mut self, pc: usize) { - - } + pub fn set_pc(&mut self, _pc: usize) {} pub fn get_pc(&self) -> usize { 0 } From b3efbcfe099a57d90ada32fe45468028299c2e6a Mon Sep 17 00:00:00 2001 From: liusm18 Date: Sun, 17 Apr 2022 12:04:17 +0800 Subject: [PATCH 31/35] Fix a coding style issue: add safety docs for unsafe function --- loader/src/linux.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/loader/src/linux.rs b/loader/src/linux.rs index 207851ec..21ebc945 100644 --- a/loader/src/linux.rs +++ b/loader/src/linux.rs @@ -96,11 +96,13 @@ async fn handle_signal( code: linux_object::signal::SignalCode::TKILL, field: SiginfoFields::default(), }; - let mut signal_context = SignalUserContext::default(); - signal_context.sig_mask = sigmask; + let mut signal_context = SignalUserContext { + sig_mask: sigmask, + ..Default::default() + }; // backup current context and set new context unsafe { - thread.backup_context((*ctx).clone()); + thread.backup_context(*ctx); let mut sp = (*ctx).get_field(UserContextField::StackPointer) - 0x200; let mut siginfo_ptr = 0; if action.flags.contains(SignalActionFlags::SIGINFO) { @@ -127,10 +129,13 @@ async fn handle_signal( } (*ctx).enter_uspace(); } - return ctx; + ctx } -/// Push stack +/// Push a object onto stack +/// # Safety +/// +/// This function is handling a raw pointer to the top of the stack . pub unsafe fn push_stack(stack_top: usize, val: T) -> usize { let stack_top = (stack_top as *mut T).sub(1); *stack_top = val; From 4746413d3a0f6147d7c2a879dc7bac375338253e Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Tue, 19 Apr 2022 11:12:14 +0800 Subject: [PATCH 32/35] Update tests commit --- tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests b/tests index 950a8f90..60fd8cab 160000 --- a/tests +++ b/tests @@ -1 +1 @@ -Subproject commit 950a8f90435fb21f6f9d7ab56cd6f7c8602e392d +Subproject commit 60fd8cab5b23208ff31fef86e0a315fb082602a2 From b052a9666bbbcae9a041f2db84df1806851f89c5 Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Tue, 19 Apr 2022 15:42:34 +0800 Subject: [PATCH 33/35] Update tests commit --- tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests b/tests index 60fd8cab..ea5b0597 160000 --- a/tests +++ b/tests @@ -1 +1 @@ -Subproject commit 60fd8cab5b23208ff31fef86e0a315fb082602a2 +Subproject commit ea5b059775121621a3d313cdcc5cfe5b9014dd84 From d2bc0b5fb7e8383a71822402108547106016ee12 Mon Sep 17 00:00:00 2001 From: liusm18 Date: Tue, 19 Apr 2022 17:34:35 +0800 Subject: [PATCH 34/35] Fix align issues in riscv --- linux-object/src/signal/mod.rs | 4 ++-- linux-object/src/thread.rs | 3 +-- linux-syscall/src/signal.rs | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/linux-object/src/signal/mod.rs b/linux-object/src/signal/mod.rs index 34808622..fed654fe 100644 --- a/linux-object/src/signal/mod.rs +++ b/linux-object/src/signal/mod.rs @@ -61,7 +61,7 @@ cfg_if::cfg_if! { #[derive(Clone, Debug)] pub struct MachineContext { // TODO - pub reserved_: [usize; 14], + pub reserved_: [usize; 16], // pc pub pc: usize, // TODO @@ -73,7 +73,7 @@ cfg_if::cfg_if! { impl Default for MachineContext { fn default() -> Self { Self { - reserved_: [0; 14], + reserved_: [0; 16], pc: 0, reserved: [0; 17], fpstate: [0; 66] diff --git a/linux-object/src/thread.rs b/linux-object/src/thread.rs index 21f281e3..f709fccb 100644 --- a/linux-object/src/thread.rs +++ b/linux-object/src/thread.rs @@ -136,8 +136,7 @@ impl LinuxThread { ctx.set_field(UserContextField::InstrPointer, ctx_in_us.context.get_pc()); let mut new_mask = Sigset::empty(); warn!( - "FIXME: the signal mask is not correctly restored, because of align issues - of the SignalUserContext with C musl library." + "FIXME: the signal mask is not correctly restored, because of align issues of the SignalUserContext with C musl library." ); new_mask.insert(Signal::SIGRT33); self.signal_mask = new_mask; diff --git a/linux-syscall/src/signal.rs b/linux-syscall/src/signal.rs index 8428c489..7fbd6557 100644 --- a/linux-syscall/src/signal.rs +++ b/linux-syscall/src/signal.rs @@ -245,10 +245,10 @@ impl Syscall<'_> { } } - /// Send a signal to a thread specified by tgid (i.e., process) and pid + /// Return from handling some signal pub fn sys_rt_sigreturn(&mut self) -> SysResult { info!( - "sigreturn: thread {} returns from handling signal", + "sigreturn: thread {} returns from handling the signal", self.thread.id() ); let old_ctx = self.thread.fetch_backup_context().unwrap(); From 55299ff1da25812238ae26cd5b4dfe79cf6c767e Mon Sep 17 00:00:00 2001 From: Zichun Yu Date: Tue, 19 Apr 2022 21:15:57 +0800 Subject: [PATCH 35/35] Update tests commit --- tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests b/tests index ea5b0597..84c94a5b 160000 --- a/tests +++ b/tests @@ -1 +1 @@ -Subproject commit ea5b059775121621a3d313cdcc5cfe5b9014dd84 +Subproject commit 84c94a5bd0a0ccdbdcffd57a59e62c819f0769b5