Skip to content

Commit

Permalink
fix problem in random-hw, 9p and pl011.
Browse files Browse the repository at this point in the history
  • Loading branch information
ken4647 committed Mar 19, 2024
1 parent ce2285f commit ef4b244
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 114 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 4 additions & 9 deletions api/ruxos_posix_api/src/imp/getrandom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ use crate::ctypes::{size_t, ssize_t};

use axerrno::LinuxError;

#[cfg(all(target_arch = "x86_64", feature = "random-hw"))]
use core::arch::x86_64::__cpuid;

static SEED: AtomicU64 = AtomicU64::new(0xae_f3);

/// Returns a 32-bit unsigned pseudo random interger using LCG.
Expand Down Expand Up @@ -54,15 +57,7 @@ fn srand_lcg(seed: u64) {
fn has_rdrand() -> bool {
#[cfg(target_arch = "x86_64")]
{
let mut ecx: u32;
unsafe {
core::arch::asm!(
"mov eax, 1",
"cpuid",
out("ecx") ecx
)
}
ecx & (1 << 30) != 0
unsafe { __cpuid(1).ecx & (1 << 30) != 0 }
}
#[cfg(target_arch = "aarch64")]
{
Expand Down
2 changes: 1 addition & 1 deletion crates/driver_pci/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ repository = "https://github.com/rcore-os/arceos/tree/main/crates/driver_pci"
documentation = "https://rcore-os.github.io/arceos/driver_pci/index.html"

[dependencies]
virtio-drivers = { git = "https://github.com/syswonder/virtio-drivers.git", rev = "256ec4c"}
virtio-drivers = { git = "https://github.com/syswonder/virtio-drivers.git", rev = "62dbe5a"}
2 changes: 1 addition & 1 deletion crates/driver_virtio/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ driver_block = { path = "../driver_block", optional = true }
driver_net = { path = "../driver_net", optional = true }
driver_display = { path = "../driver_display", optional = true}
driver_9p = { path = "../driver_9p", optional = true}
virtio-drivers = { git = "https://github.com/syswonder/virtio-drivers.git", rev = "256ec4c" }
virtio-drivers = { git = "https://github.com/syswonder/virtio-drivers.git", rev = "62dbe5a" }
12 changes: 10 additions & 2 deletions modules/rux9p/src/drv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ impl Drv9pOps {

/// write perform I/O on the file represented by fid.
/// Note that in v9fs, a read(2) or write(2) system call for a chunk of the file that won't fit in a single request is broken up into multiple requests.
pub fn twrite(&mut self, fid: u32, offset: u64, data: &[u8]) -> Result<u8, u8> {
pub fn twrite(&mut self, fid: u32, offset: u64, data: &[u8]) -> Result<usize, u8> {
const MAX_READ_LEN: u32 = _9P_MAX_PSIZE - 32;
let mut writing_len = data.len() as u32;
if writing_len > MAX_READ_LEN {
Expand All @@ -416,7 +416,7 @@ impl Drv9pOps {
}
request.finish();
match self.request(&request.buffer, &mut response_buffer) {
Ok(_) => Ok(lbytes2u64(&response_buffer[7..11]) as u8), // index from 7 to 11 corresponing to total count of writed byte
Ok(_) => Ok(lbytes2u64(&response_buffer[7..11]) as usize), // index from 7 to 11 corresponing to total count of writed byte
Err(ecode) => Err(ecode),
}
}
Expand Down Expand Up @@ -903,6 +903,10 @@ impl FileAttr {
}
}

pub fn get_perm(&self) -> u32 {
self.mode
}

pub fn set_size(&mut self, size: u64) {
self.vaild |= _9P_SETATTR_SIZE;
self.size = size;
Expand Down Expand Up @@ -1018,6 +1022,10 @@ impl UStatFs {
self.name.clone()
}

pub fn get_perm(&self) -> u32 {
self.mode
}

pub fn get_ftype(&self) -> u8 {
match self.qid.ftype {
0x00 => 0o10,
Expand Down
180 changes: 91 additions & 89 deletions modules/rux9p/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@
//!
//! The implementation is based on [`axfs_vfs`].
use crate::drv::{self, Drv9pOps};
use alloc::{
collections::BTreeMap, string::String, string::ToString, sync::Arc, sync::Weak, vec::Vec,
};
use alloc::{string::String, string::ToString, sync::Arc, sync::Weak, vec::Vec};
use axfs_vfs::{
VfsDirEntry, VfsError, VfsNodeAttr, VfsNodeOps, VfsNodeRef, VfsNodeType, VfsOps, VfsResult,
VfsDirEntry, VfsError, VfsNodeAttr, VfsNodeOps, VfsNodePerm, VfsNodeRef, VfsNodeType, VfsOps,
VfsResult,
};
use log::*;
use spin::{once::Once, RwLock};
Expand Down Expand Up @@ -62,8 +61,7 @@ impl _9pFileSystem {
let fid = match dev.write().get_fid() {
Some(id) => id,
None => {
warn!("9pfs: No enough fids! Check fid_MAX constrant or fid leaky.");
0xff_ff_ff_ff
panic!("9pfs: No enough fids! Check fid_MAX constrant or fid leaky.");
}
};

Expand Down Expand Up @@ -120,23 +118,35 @@ impl CommonNode {
dev: Arc<RwLock<Drv9pOps>>,
protocol: Arc<String>,
) -> Arc<Self> {
const OPEN_FLAG: u8 = 0x02;
if *protocol == "9P2000.L" {
match dev.write().l_topen(fid, OPEN_FLAG as u32) {
Ok(_) => {}
Err(errcode) => {
error!("9pfs open failed! error code: {}", errcode);
}
}
const O_RDWR: u8 = 0x02;
const O_RDONLY: u8 = 0x00;
const EISDIR: u8 = 21;

let result = if *protocol == "9P2000.L" {
dev.write().l_topen(fid, O_RDWR as u32)
} else if *protocol == "9P2000.u" {
match dev.write().topen(fid, OPEN_FLAG) {
Ok(_) => {}
Err(errcode) => {
error!("9pfs open failed! error code: {}", errcode);
}
}
dev.write().topen(fid, O_RDWR)
} else {
error!("9pfs open failed! Unsupported protocol version");
Ok(())
};

if let Err(EISDIR) = result {
if *protocol == "9P2000.L" {
handle_result!(
dev.write().l_topen(fid, O_RDONLY as u32),
"9pfs l_topen failed! error code: {}"
);
} else if *protocol == "9P2000.u" {
handle_result!(
dev.write().topen(fid, O_RDONLY),
"9pfs topen failed! error code: {}"
);
} else {
error!("9pfs open failed! Unsupported protocol version");
}
} else if let Err(ecode) = result {
error!("9pfs topen failed! error code: {}", ecode);
}

Arc::new_cyclic(|this| Self {
Expand Down Expand Up @@ -166,8 +176,7 @@ impl CommonNode {
let fid = match self.inner.write().get_fid() {
Some(id) => id,
None => {
error!("No enough fids! Check fid_MAX constrant or fid leaky.");
0xff_ff_ff_ff
panic!("9pfs: No enough fids! Check fid_MAX constrant or fid leaky.");
}
};
match ty {
Expand Down Expand Up @@ -223,8 +232,7 @@ impl CommonNode {
let fid = match self.inner.write().get_fid() {
Some(id) => id,
None => {
warn!("9pfs: No enough fids! Check fid_MAX constrant or fid leaky.");
0xff_ff_ff_ff
panic!("9pfs: No enough fids! Check fid_MAX constrant or fid leaky.");
}
};

Expand Down Expand Up @@ -273,8 +281,7 @@ impl CommonNode {
let new_fid = match self.inner.write().get_fid() {
Some(id) => id,
None => {
warn!("9pfs: No enough fids! Check fid_MAX constrant or fid leaky.");
0xff_ff_ff_ff
panic!("9pfs: No enough fids! Check fid_MAX constrant or fid leaky.");
}
};

Expand All @@ -294,45 +301,6 @@ impl CommonNode {
Err(_) => Err(VfsError::BadState),
}
}

/// Update nodes from host filesystem
fn all_nodes(&self) -> Result<BTreeMap<String, VfsNodeRef>, VfsError> {
let mut node_map: BTreeMap<String, VfsNodeRef> = BTreeMap::new();
debug!("reading all nodes in 9p, fid={}", *self.fid);
let dirents = match self.protocol.as_str() {
"9P2000.L" => match self.inner.write().treaddir(*self.fid) {
Ok(contents) => contents,
Err(errcode) => {
error!("9pfs treaddir failed! error code: {}", errcode);
return Err(VfsError::BadState);
}
},
"9P2000.u" => match self.inner.write().u_treaddir(*self.fid) {
Ok(contents) => contents,
Err(errcode) => {
error!("9pfs u_treaddir failed! error code: {}", errcode);
return Err(VfsError::BadState);
}
},
_ => {
error!("Unsupport 9P protocol version: {}", *self.protocol);
return Err(VfsError::BadState);
}
};

for direntry in dirents {
let fname = direntry.get_name();
if fname.eq("..") || fname.eq(".") {
continue;
}

trace!("9pfs update node {}, type {}", fname, direntry.get_type());

let node: VfsNodeRef = self.try_get(fname).unwrap();
node_map.insert(fname.into(), node);
}
Ok(node_map)
}
}

impl Drop for CommonNode {
Expand Down Expand Up @@ -413,21 +381,33 @@ impl VfsNodeOps for CommonNode {
debug!("get_attr {:?}", resp);
match resp {
Ok(stat) if stat.get_ftype() == 0o4 => {
Ok(VfsNodeAttr::new_dir(stat.get_size(), stat.get_blk_num()))
let mut attr = VfsNodeAttr::new_dir(stat.get_size(), stat.get_blk_num());
let mode = stat.get_perm() as u16 & 0o777_u16;
attr.set_perm(VfsNodePerm::from_bits(mode).unwrap());
Ok(attr)
}
Ok(stat) if stat.get_ftype() == 0o10 => {
Ok(VfsNodeAttr::new_file(stat.get_size(), stat.get_blk_num()))
let mut attr = VfsNodeAttr::new_file(stat.get_size(), stat.get_blk_num());
let mode = stat.get_perm() as u16 & 0o777_u16;
attr.set_perm(VfsNodePerm::from_bits(mode).unwrap());
Ok(attr)
}
_ => Err(VfsError::BadState),
}
} else if *self.protocol == "9P2000.u" {
let resp = self.inner.write().tstat(*self.fid);
match resp {
Ok(stat) if stat.get_ftype() == 0o4 => {
Ok(VfsNodeAttr::new_dir(stat.get_length(), stat.get_blk_num()))
let mut attr = VfsNodeAttr::new_dir(stat.get_length(), stat.get_blk_num());
let mode = stat.get_perm() as u16 & 0o777_u16;
attr.set_perm(VfsNodePerm::from_bits(mode).unwrap());
Ok(attr)
}
Ok(stat) if stat.get_ftype() == 0o10 => {
Ok(VfsNodeAttr::new_file(stat.get_length(), stat.get_blk_num()))
let mut attr = VfsNodeAttr::new_file(stat.get_length(), stat.get_blk_num());
let mode = stat.get_perm() as u16 & 0o777_u16;
attr.set_perm(VfsNodePerm::from_bits(mode).unwrap());
Ok(attr)
}
_ => Err(VfsError::BadState),
}
Expand All @@ -446,39 +426,59 @@ impl VfsNodeOps for CommonNode {
self.try_get(path)
}

fn read_dir(&self, start_idx: usize, dirents: &mut [VfsDirEntry]) -> VfsResult<usize> {
debug!("9pfs reading dirents");
let _9p_map = match self.all_nodes() {
Ok(contents) => contents,
Err(errcode) => {
error!("9pfs all_nodes failed! error code = {}", errcode);
fn read_dir(&self, start_idx: usize, vfs_dirents: &mut [VfsDirEntry]) -> VfsResult<usize> {
debug!("9pfs reading dirents: start_idx = {:x?}", start_idx);
let dirents = match self.protocol.as_str() {
"9P2000.L" => match self.inner.write().treaddir(*self.fid) {
Ok(contents) => contents,
Err(errcode) => {
error!("9pfs treaddir failed! error code: {}", errcode);
return Err(VfsError::BadState);
}
},
"9P2000.u" => match self.inner.write().u_treaddir(*self.fid) {
Ok(contents) => contents,
Err(errcode) => {
error!("9pfs u_treaddir failed! error code: {}", errcode);
return Err(VfsError::BadState);
}
},
_ => {
error!("Unsupport 9P protocol version: {}", *self.protocol);
return Err(VfsError::BadState);
}
};

let mut item_iter = _9p_map.iter().skip(start_idx.max(2) - 2);
for (i, ent) in dirents.iter_mut().enumerate() {
let mut item_iter = dirents
.iter()
.filter(|&e| !(e.get_name().eq(".") || e.get_name().eq("..")))
.skip(start_idx.max(2) - 2); // read from start_idx
for (i, ent) in vfs_dirents.iter_mut().enumerate() {
match i + start_idx {
0 => *ent = VfsDirEntry::new(".", VfsNodeType::Dir),
1 => *ent = VfsDirEntry::new("..", VfsNodeType::Dir),
_ => {
if let Some((name, node)) = item_iter.next() {
let attr = node.get_attr();
let file_type = match attr {
Ok(attr) => attr.file_type(),
Err(ecode) => {
error!("get [{}] attribute failed, error code:{}.", name, ecode);
continue;
}
if let Some(entry) = item_iter.next() {
let file_type = match entry.get_type() {
0o1_u8 => VfsNodeType::Fifo,
0o2_u8 => VfsNodeType::CharDevice,
0o4_u8 => VfsNodeType::Dir,
0o6_u8 => VfsNodeType::BlockDevice,
0o10_u8 => VfsNodeType::File,
0o12_u8 => VfsNodeType::SymLink,
0o14_u8 => VfsNodeType::Socket,
_ => panic!("9pfs: Unexpected file type found!"),
};
*ent = VfsDirEntry::new(name, file_type);
*ent = VfsDirEntry::new(entry.get_name(), file_type);
} else {
debug!("9pfs read dirents finished: start_idx = {:x?}", start_idx);
return Ok(i);
}
}
}
}
Ok(dirents.len())
debug!("9pfs read dirents finished: start_idx = {:x?}", start_idx);
Ok(vfs_dirents.len())
}

fn create(&self, path: &str, ty: VfsNodeType) -> VfsResult {
Expand Down Expand Up @@ -533,6 +533,7 @@ impl VfsNodeOps for CommonNode {

/// Read data from the file at the given offset.
fn read_at(&self, offset: u64, buf: &mut [u8]) -> VfsResult<usize> {
debug!("read 9pid:{} length: {}", self.fid, buf.len());
let mut dev = self.inner.write();
let mut read_len = buf.len();
let mut offset_ptr = 0;
Expand All @@ -552,19 +553,19 @@ impl VfsNodeOps for CommonNode {
read_len -= rlen;
offset_ptr += rlen;
}
debug!("9P Reading {}, length: {}", self.fid, buf.len());
Ok(buf.len())
}

/// Write data to the file at the given offset.
fn write_at(&self, offset: u64, buf: &[u8]) -> VfsResult<usize> {
debug!("write 9pid:{} length: {}", self.fid, buf.len());
let mut dev = self.inner.write();
let mut write_len = buf.len();
let mut offset_ptr = 0;
while write_len > 0 {
let target_buf = &buf[offset_ptr..];
let wlen = match dev.twrite(*self.fid, offset + offset_ptr as u64, target_buf) {
Ok(writed_length) => writed_length as usize,
Ok(writed_length) => writed_length,
Err(_) => return Err(VfsError::BadState),
};
if wlen == 0 {
Expand All @@ -573,6 +574,7 @@ impl VfsNodeOps for CommonNode {
write_len -= wlen;
offset_ptr += wlen;
}

Ok(buf.len())
}

Expand Down
Loading

0 comments on commit ef4b244

Please sign in to comment.