From d90edb0808094ec1357d04bf517b903882fde597 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sat, 1 Jul 2023 15:43:34 +0200 Subject: [PATCH 1/4] Implement improved mmap in vesad. --- Cargo.lock | 2 -- Cargo.toml | 1 + vesad/src/main.rs | 4 +-- vesad/src/scheme.rs | 61 ++++++++++++++++++++++++++++++++++++++------- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 570a1ff16a..6fbac8b5ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1123,8 +1123,6 @@ dependencies = [ [[package]] name = "redox_syscall" version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags 1.3.2", ] diff --git a/Cargo.toml b/Cargo.toml index 2c9b8d6e06..363159b803 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,3 +39,4 @@ lto = "fat" mio = { git = "https://gitlab.redox-os.org/redox-os/mio.git", branch = "redox-unix" } net2 = { git = "https://gitlab.redox-os.org/redox-os/net2-rs.git", branch = "master" } orbclient = { git = "https://gitlab.redox-os.org/redox-os/orbclient.git", version = "0.3.44" } +redox_syscall = { path = "../../kernel/source/syscall" } diff --git a/vesad/src/main.rs b/vesad/src/main.rs index 08046147ca..1b75efc0f4 100644 --- a/vesad/src/main.rs +++ b/vesad/src/main.rs @@ -112,7 +112,7 @@ fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec, spec: &[b if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.can_read(packet.b).is_none() { blocked.push(packet); } else { - scheme.handle(&mut packet); + scheme.do_handle(&mut packet); socket.write(&packet).expect("vesad: failed to write display scheme"); } @@ -122,7 +122,7 @@ fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec, spec: &[b while i < blocked.len() { if scheme.can_read(blocked[i].b).is_some() { let mut packet = blocked.remove(i); - scheme.handle(&mut packet); + scheme.do_handle(&mut packet); socket.write(&packet).expect("vesad: failed to write display scheme"); } else { i += 1; diff --git a/vesad/src/scheme.rs b/vesad/src/scheme.rs index 20d1b45719..e63eea8852 100644 --- a/vesad/src/scheme.rs +++ b/vesad/src/scheme.rs @@ -1,7 +1,8 @@ use std::collections::BTreeMap; use std::{mem, ptr, slice, str}; -use syscall::{Error, EventFlags, EBADF, EINVAL, ENOENT, Map, O_NONBLOCK, Result, SchemeMut, PAGE_SIZE}; +use orbclient::{Event, EventOption}; +use syscall::{Error, EventFlags, EACCES, EBADF, EINVAL, ENOENT, Map, O_NONBLOCK, Result, SchemeMut, PAGE_SIZE, Packet, KSMSG_MMAP_PREP, KSMSG_MMAP, MapFlags, ESKMSG, SKMSG_PROVIDE_MMAP}; use crate::{ display::Display, @@ -213,6 +214,7 @@ impl SchemeMut for DisplayScheme { } } + /* fn fmap(&mut self, id: usize, map: &Map) -> Result { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; @@ -226,14 +228,7 @@ impl SchemeMut for DisplayScheme { Err(Error::new(EBADF)) } - fn fmap_old(&mut self, id: usize, map: &syscall::OldMap) -> syscall::Result { - self.fmap(id, &Map { - offset: map.offset, - size: map.size, - flags: map.flags, - address: 0, - }) - } + */ fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; @@ -383,3 +378,51 @@ impl SchemeMut for DisplayScheme { Ok(0) } } +impl DisplayScheme { + pub fn do_handle(&mut self, packet: &mut Packet) { + match packet.a { + KSMSG_MMAP | KSMSG_MMAP_PREP => { + let off_lo = packet.uid; + let off_hi = packet.gid; + let req_off = u64::from(off_lo) | (u64::from(off_hi) << 32); + let req_flags = MapFlags::from_bits_truncate(packet.c); + let req_file_id = packet.b; + let req_page_count = packet.d; + + let is_lazy_mmap = packet.a == KSMSG_MMAP || req_flags.contains(MapFlags::MAP_LAZY); + + match self.mmap(req_file_id, req_flags, req_page_count * PAGE_SIZE, req_off) { + Ok(res) => if is_lazy_mmap { + packet.a = Error::mux(Err(Error::new(ESKMSG))); + packet.b = SKMSG_PROVIDE_MMAP; + packet.c = res; + packet.d = req_page_count; + + packet.uid = off_lo; + packet.gid = off_hi; + } else { + packet.a = Error::mux(Ok(res)); + }, + Err(err) => { + packet.a = Error::mux(Err(err)); + } + }; + + } + _ => self.handle(packet), + } + } + pub fn mmap(&mut self, id: usize, _flags: MapFlags, size: usize, off: u64) -> Result { + let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; + + if let HandleKind::Screen(vt_i, screen_i) = handle.kind { + if let Some(screens) = self.vts.get(&vt_i) { + if let Some(screen) = screens.get(&screen_i) { + return screen.map(off as usize, size); + } + } + } + + Err(Error::new(EBADF)) + } +} From ca6ea9b81a5dc599618983ec7cd3a61c6425a78e Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Thu, 13 Jul 2023 18:46:18 +0200 Subject: [PATCH 2/4] Use scheme trait for mmap_prep. --- vesad/src/main.rs | 4 ++-- vesad/src/scheme.rs | 37 +------------------------------------ virtio-gpud/src/main.rs | 2 +- virtio-gpud/src/scheme.rs | 34 +++++++++++----------------------- 4 files changed, 15 insertions(+), 62 deletions(-) diff --git a/vesad/src/main.rs b/vesad/src/main.rs index 1b75efc0f4..08046147ca 100644 --- a/vesad/src/main.rs +++ b/vesad/src/main.rs @@ -112,7 +112,7 @@ fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec, spec: &[b if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.can_read(packet.b).is_none() { blocked.push(packet); } else { - scheme.do_handle(&mut packet); + scheme.handle(&mut packet); socket.write(&packet).expect("vesad: failed to write display scheme"); } @@ -122,7 +122,7 @@ fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec, spec: &[b while i < blocked.len() { if scheme.can_read(blocked[i].b).is_some() { let mut packet = blocked.remove(i); - scheme.do_handle(&mut packet); + scheme.handle(&mut packet); socket.write(&packet).expect("vesad: failed to write display scheme"); } else { i += 1; diff --git a/vesad/src/scheme.rs b/vesad/src/scheme.rs index e63eea8852..ddd3f22607 100644 --- a/vesad/src/scheme.rs +++ b/vesad/src/scheme.rs @@ -377,42 +377,7 @@ impl SchemeMut for DisplayScheme { self.handles.remove(&id).ok_or(Error::new(EBADF))?; Ok(0) } -} -impl DisplayScheme { - pub fn do_handle(&mut self, packet: &mut Packet) { - match packet.a { - KSMSG_MMAP | KSMSG_MMAP_PREP => { - let off_lo = packet.uid; - let off_hi = packet.gid; - let req_off = u64::from(off_lo) | (u64::from(off_hi) << 32); - let req_flags = MapFlags::from_bits_truncate(packet.c); - let req_file_id = packet.b; - let req_page_count = packet.d; - - let is_lazy_mmap = packet.a == KSMSG_MMAP || req_flags.contains(MapFlags::MAP_LAZY); - - match self.mmap(req_file_id, req_flags, req_page_count * PAGE_SIZE, req_off) { - Ok(res) => if is_lazy_mmap { - packet.a = Error::mux(Err(Error::new(ESKMSG))); - packet.b = SKMSG_PROVIDE_MMAP; - packet.c = res; - packet.d = req_page_count; - - packet.uid = off_lo; - packet.gid = off_hi; - } else { - packet.a = Error::mux(Ok(res)); - }, - Err(err) => { - packet.a = Error::mux(Err(err)); - } - }; - - } - _ => self.handle(packet), - } - } - pub fn mmap(&mut self, id: usize, _flags: MapFlags, size: usize, off: u64) -> Result { + fn mmap_prep(&mut self, id: usize, _flags: MapFlags, size: usize, off: u64) -> Result { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; if let HandleKind::Screen(vt_i, screen_i) = handle.kind { diff --git a/virtio-gpud/src/main.rs b/virtio-gpud/src/main.rs index 4f1f08eb80..f181b38ff2 100644 --- a/virtio-gpud/src/main.rs +++ b/virtio-gpud/src/main.rs @@ -453,7 +453,7 @@ fn deamon(deamon: redox_daemon::Daemon) -> anyhow::Result<()> { socket_file .read(&mut packet) .expect("virtio-gpud: failed to read disk scheme"); - scheme.handle(&mut packet); + unsafe { scheme.handle(&mut packet); } socket_file .write(&packet) .expect("virtio-gpud: failed to read disk scheme"); diff --git a/virtio-gpud/src/scheme.rs b/virtio-gpud/src/scheme.rs index 7fe379a24c..4669ae2e3f 100644 --- a/virtio-gpud/src/scheme.rs +++ b/virtio-gpud/src/scheme.rs @@ -4,9 +4,9 @@ use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering}; use std::sync::Arc; use inputd::Damage; - use common::dma::Dma; -use syscall::{Error as SysError, SchemeMut, EAGAIN, EINVAL}; + +use syscall::{Error as SysError, SchemeMut, EAGAIN, EINVAL, MapFlags, PAGE_SIZE, KSMSG_MMAP, KSMSG_MMAP_PREP, KSMSG_MSYNC, KSMSG_MUNMAP}; use virtio_core::spec::{Buffer, ChainBuilder, DescriptorFlags}; use virtio_core::transport::{Error, Queue, StandardTransport}; @@ -368,27 +368,6 @@ impl<'a> SchemeMut for Scheme<'a> { } } - fn fmap_old(&mut self, id: usize, map: &syscall::OldMap) -> syscall::Result { - self.fmap( - id, - &syscall::Map { - offset: map.offset, - size: map.size, - flags: map.flags, - address: 0, - }, - ) - } - - fn fmap(&mut self, id: usize, map: &syscall::Map) -> syscall::Result { - match self.handles.get(&id).ok_or(SysError::new(EINVAL))? { - Handle::Vt { display, .. } => { - Ok(futures::executor::block_on(display.map_screen(map.offset)).unwrap()) - } - _ => unreachable!(), - } - } - fn fsync(&mut self, id: usize) -> syscall::Result { match self.handles.get(&id).ok_or(SysError::new(EINVAL))? { Handle::Vt { display, .. } => { @@ -484,4 +463,13 @@ impl<'a> SchemeMut for Scheme<'a> { fn close(&mut self, _id: usize) -> syscall::Result { Ok(0) } + fn mmap_prep(&mut self, id: usize, flags: MapFlags, size: usize, offset: u64) -> syscall::Result { + log::info!("KSMSG MMAP {} {:?} {} {}", id, flags, offset, size); + match self.handles.get(&id).ok_or(SysError::new(EINVAL))? { + Handle::Vt { display, .. } => { + Ok(futures::executor::block_on(display.map_screen(offset as usize)).unwrap()) + } + _ => unreachable!(), + } + } } From fc1dc21b1395f16a8ab33f47ff33c3cbf4b85669 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sat, 22 Jul 2023 10:36:38 +0200 Subject: [PATCH 3/4] Use updated mmap_prep decl. --- vesad/src/scheme.rs | 2 +- virtio-gpud/src/scheme.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vesad/src/scheme.rs b/vesad/src/scheme.rs index ddd3f22607..cc5a70fcd1 100644 --- a/vesad/src/scheme.rs +++ b/vesad/src/scheme.rs @@ -377,7 +377,7 @@ impl SchemeMut for DisplayScheme { self.handles.remove(&id).ok_or(Error::new(EBADF))?; Ok(0) } - fn mmap_prep(&mut self, id: usize, _flags: MapFlags, size: usize, off: u64) -> Result { + fn mmap_prep(&mut self, id: usize, off: u64, size: usize, _flags: MapFlags) -> Result { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; if let HandleKind::Screen(vt_i, screen_i) = handle.kind { diff --git a/virtio-gpud/src/scheme.rs b/virtio-gpud/src/scheme.rs index 4669ae2e3f..6a75c72749 100644 --- a/virtio-gpud/src/scheme.rs +++ b/virtio-gpud/src/scheme.rs @@ -463,7 +463,7 @@ impl<'a> SchemeMut for Scheme<'a> { fn close(&mut self, _id: usize) -> syscall::Result { Ok(0) } - fn mmap_prep(&mut self, id: usize, flags: MapFlags, size: usize, offset: u64) -> syscall::Result { + fn mmap_prep(&mut self, id: usize, offset: u64, size: usize, flags: MapFlags) -> syscall::Result { log::info!("KSMSG MMAP {} {:?} {} {}", id, flags, offset, size); match self.handles.get(&id).ok_or(SysError::new(EINVAL))? { Handle::Vt { display, .. } => { From 625ae7f9e4361b6b55e6938e14dded890062a616 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Thu, 3 Aug 2023 12:46:14 +0200 Subject: [PATCH 4/4] Use syscall git dependency. --- Cargo.lock | 1 + Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 6fbac8b5ce..8102337996 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1123,6 +1123,7 @@ dependencies = [ [[package]] name = "redox_syscall" version = "0.3.5" +source = "git+https://gitlab.redox-os.org/redox-os/syscall.git#a525620c818a801bb7038e111b71033eff56a3ee" dependencies = [ "bitflags 1.3.2", ] diff --git a/Cargo.toml b/Cargo.toml index 363159b803..b68ec3665c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,4 +39,4 @@ lto = "fat" mio = { git = "https://gitlab.redox-os.org/redox-os/mio.git", branch = "redox-unix" } net2 = { git = "https://gitlab.redox-os.org/redox-os/net2-rs.git", branch = "master" } orbclient = { git = "https://gitlab.redox-os.org/redox-os/orbclient.git", version = "0.3.44" } -redox_syscall = { path = "../../kernel/source/syscall" } +redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git" }