bug fix: pthread_mutex page fault

This commit is contained in:
DeathWish5 2022-04-03 18:38:55 +08:00
parent 65eec60ac6
commit d6687d9a65
6 changed files with 55 additions and 76 deletions

View File

@ -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<UserInOutPtr<usize>, 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 => {

View File

@ -83,7 +83,15 @@ impl Syscall<'_> {
val: u32,
timeout_addr: usize,
) -> SysResult {
if let Err(_) = self.into_inout_userptr::<i32>(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::<TimeSpec>(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;

View File

@ -65,8 +65,8 @@ impl Syscall<'_> {
flags: usize,
newsp: usize,
mut parent_tid: UserOutPtr<i32>,
mut child_tid: UserOutPtr<i32>,
newtls: usize,
mut child_tid: UserOutPtr<i32>,
) -> SysResult {
let _flags = CloneFlags::from_bits_truncate(flags);
info!(

View File

@ -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();

View File

@ -1,10 +1,10 @@
################ Arguments ################
ARCH ?= x86_64
ARCH ?= riscv64
PLATFORM ?= qemu
MODE ?= release
LOG ?= warn
LINUX ?=
LOG ?= info
LINUX ?= 1
LIBOS ?=
TEST ?=
GRAPHIC ?=

View File

@ -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")),
}
}
}