Skip to content

Commit

Permalink
Merge 2412575 into 4ca21dc
Browse files Browse the repository at this point in the history
  • Loading branch information
benpigchu committed Sep 25, 2020
2 parents 4ca21dc + 2412575 commit fd9453d
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 109 deletions.
1 change: 1 addition & 0 deletions kernel-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod defs {
const WRITE = 1 << 3;
const EXECUTE = 1 << 4;
const USER = 1 << 5;
const RXW = Self::READ.bits | Self::WRITE.bits | Self::EXECUTE.bits;
}
}
numeric_enum! {
Expand Down
2 changes: 1 addition & 1 deletion linux-loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ async-std = { version = "1.5", features = ["attributes"], optional = true }

[features]
default = ["std"]
std = ["env_logger", "async-std", "kernel-hal-unix", "rcore-fs-hostfs"]
std = ["env_logger", "async-std", "kernel-hal-unix", "rcore-fs-hostfs", "zircon-object/aspace-separate"]
14 changes: 13 additions & 1 deletion scripts/zircon/test-check-passed.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ HandleWaitTest.HandleWaitMultipleThreads
MemoryMappingTest.MmapZerofilledTest
MemoryMappingTest.MmapLenTest
MemoryMappingTest.MmapOffsetTest
MemoryMappingTest.MmapProtExecTest
MemoryMappingTest.MmapFlagsTest
ObjectChildTest.InvalidHandleReturnsBadHandle
ObjectGetInfoTest.OpenValidHandleSuceeds
Expand Down Expand Up @@ -364,9 +363,22 @@ Vmar.DestroyTest
Vmar.BasicAllocateTest
Vmar.MapInCompactTest
Vmar.AllocateOobTest
Vmar.AllocateUnsatisfiableTest
Vmar.DestroyedVmarTest
Vmar.VmarMapRangeOffsetTest
Vmar.UnalignedLenTest
Vmar.UnalignedLenMapTest
Vmar.RightsDropTest
Vmar.VmarMapRangeOffsetTest
Vmar.ObjectInfoTest
Vmar.UnmapSplitTest
Vmar.UnmapMultipleTest
Vmar.UnmapBaseNotMappedTest
Vmar.PartialUnmapAndRead
Vmar.PartialUnmapAndWrite
Vmar.PartialUnmapWithVmarOffset
Vmar.AllowFaultsTest
Vmar.ConcurrentUnmapReadMemory
VmoCloneTestCase.SizeAlign
VmoCloneTestCase.NameProperty
VmoCloneTestCase.Decommit
Expand Down
4 changes: 4 additions & 0 deletions scripts/zircon/testcases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
-Vmar.NestedRegionPermsTest
-Vmar.MapSpecificOverwriteTest
-Vmar.MapOverDestroyedTest
-MemoryMappingTest.MmapProtExecTest
-MemoryMappingTest.MmapProtTest
-VmoTestCase.ReadOnlyMap
-VmoTestCase.NoPermMap
-VmoTestCase.NoPermProtect
Expand All @@ -33,6 +35,8 @@
-VmoTestCase.ResizeHazard
-VmoTestCase.Cache*
-VmoClone2TestCase.PinClonePages
-SocketTest.ReadIntoBadBuffer
-SocketTest.WriteFromBadBuffer
-VersionTest.*
-BadAccessTest.*
-InterruptTest.BindTriggeredIrqToPort
Expand Down
2 changes: 1 addition & 1 deletion zircon-loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ async-std = { version = "1.5", features = ["attributes"], optional = true }

[features]
default = ["std"]
std = ["env_logger", "structopt", "async-std", "kernel-hal-unix"]
std = ["env_logger", "structopt", "async-std", "kernel-hal-unix", "zircon-object/aspace-separate"]
1 change: 1 addition & 0 deletions zircon-object/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ description = "Zircon kernel objects"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
aspace-separate=[]
elf = ["xmas-elf"]
hypervisor = ["rvm"]

Expand Down
110 changes: 65 additions & 45 deletions zircon-object/src/vm/vmar.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use core::sync::atomic::*;
use {
super::*, crate::object::*, alloc::sync::Arc, alloc::vec::Vec, bitflags::bitflags,
kernel_hal::PageTableTrait, spin::Mutex,
Expand Down Expand Up @@ -63,16 +62,21 @@ struct VmarInner {
impl VmAddressRegion {
/// Create a new root VMAR.
pub fn new_root() -> Arc<Self> {
// FIXME: workaround for unix
static VMAR_ID: AtomicUsize = AtomicUsize::new(0);
let i = VMAR_ID.fetch_add(1, Ordering::SeqCst);
let addr: usize = 0x2_00000000 + 0x100_00000000 * i;
#[cfg(feature = "aspace-separate")]
let (addr, size) = {
use core::sync::atomic::*;
static VMAR_ID: AtomicUsize = AtomicUsize::new(0);
let i = VMAR_ID.fetch_add(1, Ordering::SeqCst);
(0x2_00000000 + 0x100_00000000 * i, 0x100_00000000)
};
#[cfg(not(feature = "aspace-separate"))]
let (addr, size) = (USER_ASPACE_BASE as usize, USER_ASPACE_SIZE as usize);
Arc::new(VmAddressRegion {
flags: VmarFlags::ROOT_FLAGS,
base: KObjectBase::new(),
_counter: CountHelper::new(),
addr,
size: 0x100_00000000,
size,
parent: None,
page_table: Arc::new(Mutex::new(kernel_hal::PageTable::new())),
inner: Mutex::new(Some(VmarInner::default())),
Expand All @@ -81,8 +85,8 @@ impl VmAddressRegion {

/// Create a kernel root VMAR.
pub fn new_kernel() -> Arc<Self> {
let kernel_vmar_base = 0xffff_ff02_0000_0000; // Sorry i hard code because i'm lazy
let kernel_vmar_size = 0x8000_00000;
let kernel_vmar_base = KERNEL_ASPACE_BASE as usize; // Sorry i hard code because i'm lazy
let kernel_vmar_size = KERNEL_ASPACE_SIZE as usize;
Arc::new(VmAddressRegion {
flags: VmarFlags::ROOT_FLAGS,
base: KObjectBase::new(),
Expand Down Expand Up @@ -157,44 +161,30 @@ impl VmAddressRegion {
len: usize,
flags: MMUFlags,
) -> ZxResult<VirtAddr> {
self.map_at_ext(vmar_offset, vmo, vmo_offset, len, flags, false, true)
self.map(Some(vmar_offset), vmo, vmo_offset, len, flags)
}

/// Map the `vmo` into this VMAR at given `offset`.
#[allow(clippy::too_many_arguments)]
pub fn map_at_ext(
/// Map the `vmo` into this VMAR.
pub fn map(
&self,
vmar_offset: usize,
vmar_offset: Option<usize>,
vmo: Arc<VmObject>,
vmo_offset: usize,
len: usize,
flags: MMUFlags,
overwrite: bool,
map_range: bool,
) -> ZxResult<VirtAddr> {
self.map_ext(
Some(vmar_offset),
vmar_offset,
vmo,
vmo_offset,
len,
MMUFlags::RXW,
flags,
overwrite,
map_range,
false,
true,
)
}

/// Map the `vmo` into this VMAR.
pub fn map(
&self,
vmar_offset: Option<usize>,
vmo: Arc<VmObject>,
vmo_offset: usize,
len: usize,
flags: MMUFlags,
) -> ZxResult<VirtAddr> {
self.map_ext(vmar_offset, vmo, vmo_offset, len, flags, false, true)
}

/// Map the `vmo` into this VMAR.
#[allow(clippy::too_many_arguments)]
pub fn map_ext(
Expand All @@ -203,13 +193,17 @@ impl VmAddressRegion {
vmo: Arc<VmObject>,
vmo_offset: usize,
len: usize,
permissions: MMUFlags,
flags: MMUFlags,
overwrite: bool,
_map_range: bool,
) -> ZxResult<VirtAddr> {
if !page_aligned(vmo_offset) || !page_aligned(len) || vmo_offset.overflowing_add(len).1 {
return Err(ZxError::INVALID_ARGS);
}
if !permissions.contains(flags & MMUFlags::RXW) {
return Err(ZxError::ACCESS_DENIED);
}
// TODO: allow the mapping extends past the end of vmo
if vmo_offset > vmo.len() || len > vmo.len() - vmo_offset {
return Err(ZxError::INVALID_ARGS);
Expand All @@ -231,7 +225,15 @@ impl VmAddressRegion {
return Err(ZxError::NO_MEMORY);
}
}
let mapping = VmMapping::new(addr, len, vmo, vmo_offset, flags, self.page_table.clone());
let mapping = VmMapping::new(
addr,
len,
vmo,
vmo_offset,
permissions,
flags,
self.page_table.clone(),
);
let map_range = true;
if map_range {
mapping.map()?;
Expand Down Expand Up @@ -287,6 +289,9 @@ impl VmAddressRegion {
/// address space. If the requested range overlaps with a subregion,
/// protect() will fail.
pub fn protect(&self, addr: usize, len: usize, flags: MMUFlags) -> ZxResult {
if !page_aligned(addr) || !page_aligned(len) {
return Err(ZxError::INVALID_ARGS);
}
let mut guard = self.inner.lock();
let inner = guard.as_mut().ok_or(ZxError::BAD_STATE)?;
let end_addr = addr + len;
Expand Down Expand Up @@ -396,6 +401,8 @@ impl VmAddressRegion {
} else {
Err(ZxError::INVALID_ARGS)
}
} else if len > self.size {
Err(ZxError::INVALID_ARGS)
} else {
match self.find_free_area(&inner, 0, len, align) {
Some(offset) => Ok(offset),
Expand Down Expand Up @@ -555,8 +562,10 @@ impl VmAddressRegion {
let map = self.find_mapping(vaddr).ok_or(ZxError::NO_MEMORY)?;
let map_inner = map.inner.lock();
let vmo_offset = vaddr - map_inner.addr + map_inner.vmo_offset;
map.vmo.read(vmo_offset, buf)?;
Ok(buf.len())
let size_limit = map_inner.addr + map_inner.size - vaddr;
let actual_size = buf.len().min(size_limit);
map.vmo.read(vmo_offset, &mut buf[0..actual_size])?;
Ok(actual_size)
}

/// Write to address space.
Expand All @@ -567,8 +576,10 @@ impl VmAddressRegion {
let map = self.find_mapping(vaddr).ok_or(ZxError::NO_MEMORY)?;
let map_inner = map.inner.lock();
let vmo_offset = vaddr - map_inner.addr + map_inner.vmo_offset;
map.vmo.write(vmo_offset, buf)?;
Ok(buf.len())
let size_limit = map_inner.addr + map_inner.size - vaddr;
let actual_size = buf.len().min(size_limit);
map.vmo.write(vmo_offset, &buf[0..actual_size])?;
Ok(actual_size)
}

/// Find mapping of vaddr
Expand Down Expand Up @@ -632,6 +643,9 @@ pub struct VmarInfo {

/// Virtual Memory Mapping
pub struct VmMapping {
/// The permission limitation of the vmar
permissions: MMUFlags,
/// The actual flags used in the mapping
flags: MMUFlags,
vmo: Arc<VmObject>,
page_table: Arc<Mutex<dyn PageTableTrait>>,
Expand Down Expand Up @@ -661,6 +675,7 @@ impl core::fmt::Debug for VmMapping {
f.debug_struct("VmMapping")
.field("addr", &inner.addr)
.field("size", &inner.size)
.field("permissions", &self.permissions)
.field("flags", &self.flags)
.field("vmo_id", &self.vmo.id())
.field("vmo_offset", &inner.vmo_offset)
Expand All @@ -674,6 +689,7 @@ impl VmMapping {
size: usize,
vmo: Arc<VmObject>,
vmo_offset: usize,
permissions: MMUFlags,
flags: MMUFlags,
page_table: Arc<Mutex<dyn PageTableTrait>>,
) -> Arc<Self> {
Expand All @@ -683,6 +699,7 @@ impl VmMapping {
size,
vmo_offset,
}),
permissions,
flags,
page_table,
vmo: vmo.clone(),
Expand Down Expand Up @@ -787,6 +804,7 @@ impl VmMapping {
new_len2,
self.vmo.clone(),
inner.vmo_offset + (end - inner.addr),
self.permissions,
self.flags,
self.page_table.clone(),
))
Expand All @@ -804,16 +822,7 @@ impl VmMapping {
}

fn is_valid_mapping_flags(&self, flags: MMUFlags) -> bool {
if !flags.contains(MMUFlags::READ) && self.flags.contains(MMUFlags::READ) {
return false;
}
if !flags.contains(MMUFlags::WRITE) && self.flags.contains(MMUFlags::WRITE) {
return false;
}
if !flags.contains(MMUFlags::EXECUTE) && self.flags.contains(MMUFlags::EXECUTE) {
return false;
}
true
self.permissions.contains(flags & MMUFlags::RXW)
}

fn protect(&self, flags: MMUFlags) {
Expand Down Expand Up @@ -882,6 +891,7 @@ impl VmMapping {
let new_vmo = self.vmo.create_child(false, 0, self.vmo.len())?;
let mapping = Arc::new(VmMapping {
inner: Mutex::new(self.inner.lock().clone()),
permissions: self.permissions,
flags: self.flags,
page_table,
vmo: new_vmo.clone(),
Expand All @@ -903,6 +913,16 @@ impl Drop for VmMapping {
}
}

/// The base of kernel address space
/// In x86 fuchsia this is 0xffff_ff80_0000_0000 instead
pub const KERNEL_ASPACE_BASE: u64 = 0xffff_ff02_0000_0000;
/// The size of kernel address space
pub const KERNEL_ASPACE_SIZE: u64 = 0x0000_0080_0000_0000;
/// The base of user address space
pub const USER_ASPACE_BASE: u64 = 0x0000_0000_0100_0000;
/// The size of user address space
pub const USER_ASPACE_SIZE: u64 = (1u64 << 47) - 4096 - USER_ASPACE_BASE;

#[cfg(test)]
mod tests {
use super::*;
Expand Down
8 changes: 4 additions & 4 deletions zircon-syscall/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ impl Syscall<'_> {
vaddr: usize,
mut buffer: UserOutPtr<u8>,
buffer_size: usize,
mut actual: UserOutPtr<u32>,
mut actual: UserOutPtr<usize>,
) -> ZxResult {
if buffer.is_null() || buffer_size == 0 || buffer_size > MAX_BLOCK {
return Err(ZxError::INVALID_ARGS);
Expand All @@ -343,7 +343,7 @@ impl Syscall<'_> {
let mut data = vec![0u8; buffer_size];
let len = process.vmar().read_memory(vaddr, &mut data)?;
buffer.write_array(&data[..len])?;
actual.write_if_not_null(len as u32)?;
actual.write(len)?;
Ok(())
}

Expand All @@ -354,7 +354,7 @@ impl Syscall<'_> {
vaddr: usize,
buffer: UserInPtr<u8>,
buffer_size: usize,
mut actual: UserOutPtr<u32>,
mut actual: UserOutPtr<usize>,
) -> ZxResult {
if buffer.is_null() || buffer_size == 0 || buffer_size > MAX_BLOCK {
return Err(ZxError::INVALID_ARGS);
Expand All @@ -364,7 +364,7 @@ impl Syscall<'_> {
proc.get_object_with_rights::<Process>(handle_value, Rights::READ | Rights::WRITE)?;
let data = buffer.read_array(buffer_size)?;
let len = process.vmar().write_memory(vaddr, &data)?;
actual.write_if_not_null(len as u32)?;
actual.write(len)?;
Ok(())
}
}
Expand Down

0 comments on commit fd9453d

Please sign in to comment.