forked from rcore-os/zCore
check pin_count before vmo resize
This commit is contained in:
parent
27f914c43a
commit
39ad173f6c
|
@ -35,7 +35,7 @@ pub trait VMObjectTrait: Sync + Send {
|
|||
fn len(&self) -> usize;
|
||||
|
||||
/// Set the length of VMO.
|
||||
fn set_len(&self, len: usize);
|
||||
fn set_len(&self, len: usize) -> ZxResult;
|
||||
|
||||
/// Unmap physical memory from `page_table`.
|
||||
fn unmap_from(&self, page_table: &mut PageTable, vaddr: VirtAddr, _offset: usize, len: usize) {
|
||||
|
@ -219,8 +219,7 @@ impl VmObject {
|
|||
return Err(ZxError::OUT_OF_RANGE);
|
||||
}
|
||||
if self.resizable {
|
||||
self.inner.set_len(size);
|
||||
Ok(())
|
||||
self.inner.set_len(size)
|
||||
} else {
|
||||
Err(ZxError::UNAVAILABLE)
|
||||
}
|
||||
|
|
|
@ -87,6 +87,8 @@ struct VMObjectPagedInner {
|
|||
cache_policy: CachePolicy,
|
||||
/// A weak reference to myself.
|
||||
self_ref: WeakRef,
|
||||
/// Sum of pin_count
|
||||
pin_count: usize,
|
||||
}
|
||||
|
||||
/// Page state in VMO.
|
||||
|
@ -159,6 +161,7 @@ impl VMObjectPaged {
|
|||
mappings: Vec::new(),
|
||||
cache_policy: CachePolicy::Cached,
|
||||
self_ref: Default::default(),
|
||||
pin_count: 0,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -274,10 +277,14 @@ impl VMObjectTrait for VMObjectPaged {
|
|||
self.inner.lock().size
|
||||
}
|
||||
|
||||
fn set_len(&self, len: usize) {
|
||||
fn set_len(&self, len: usize) -> ZxResult {
|
||||
assert!(page_aligned(len));
|
||||
let mut inner = self.inner.lock();
|
||||
if inner.pin_count > 0 {
|
||||
return Err(ZxError::BAD_STATE);
|
||||
}
|
||||
inner.resize(len);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn commit_page(&self, page_idx: usize, flags: MMUFlags) -> ZxResult<PhysAddr> {
|
||||
|
@ -371,6 +378,7 @@ impl VMObjectTrait for VMObjectPaged {
|
|||
mappings: Vec::new(),
|
||||
cache_policy: my_cache_policy,
|
||||
self_ref: Default::default(),
|
||||
pin_count: 0,
|
||||
});
|
||||
Ok(obj)
|
||||
}
|
||||
|
@ -470,6 +478,7 @@ impl VMObjectTrait for VMObjectPaged {
|
|||
}
|
||||
for i in start_page .. end_page {
|
||||
inner.frames.get_mut(&i).unwrap().pin_count += 1;
|
||||
inner.pin_count += 1;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -477,7 +486,7 @@ impl VMObjectTrait for VMObjectPaged {
|
|||
fn unpin(&self, offset: usize, len: usize) -> ZxResult {
|
||||
{
|
||||
let inner = self.inner.lock();
|
||||
if offset as usize > inner.size || len > inner.size - (offset as usize) {
|
||||
if !in_range(offset, len, inner.size) {
|
||||
return Err(ZxError::OUT_OF_RANGE);
|
||||
}
|
||||
if len == 0 {
|
||||
|
@ -503,6 +512,7 @@ impl VMObjectTrait for VMObjectPaged {
|
|||
return Err(ZxError::UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
assert_ne!(inner.pin_count, 0);
|
||||
for i in start_page..end_page {
|
||||
inner.frames.get_mut(&i).unwrap().pin_count -= 1;
|
||||
}
|
||||
|
@ -838,6 +848,7 @@ impl VMObjectPagedInner {
|
|||
mappings: Vec::new(),
|
||||
cache_policy: CachePolicy::Cached,
|
||||
self_ref: Default::default(),
|
||||
pin_count: 0,
|
||||
});
|
||||
// construct a hidden VMO as shared parent
|
||||
let hidden = VMObjectPaged::wrap(VMObjectPagedInner {
|
||||
|
@ -854,6 +865,7 @@ impl VMObjectPagedInner {
|
|||
mappings: Vec::new(),
|
||||
cache_policy: CachePolicy::Cached,
|
||||
self_ref: Default::default(),
|
||||
pin_count: 0,
|
||||
});
|
||||
// update parent's child
|
||||
if let Some(parent) = self.parent.take() {
|
||||
|
|
|
@ -64,7 +64,7 @@ impl VMObjectTrait for VMObjectPhysical {
|
|||
self.pages * PAGE_SIZE
|
||||
}
|
||||
|
||||
fn set_len(&self, _len: usize) {
|
||||
fn set_len(&self, _len: usize) -> ZxResult {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ impl Syscall<'_> {
|
|||
const MAY_DISCARD: u32 = 1;
|
||||
let never_discard = options & MAY_DISCARD == 0;
|
||||
|
||||
// let test_args = "test\0-f\0Bti\0";
|
||||
// let test_args = "test\0-f\0Bti*\0";
|
||||
let test_args = "";
|
||||
|
||||
let mut msg = if never_discard {
|
||||
|
|
Loading…
Reference in New Issue