From 18bbfe297b32870a89698cc1ca20f403f563107a Mon Sep 17 00:00:00 2001 From: Luke Craig Date: Thu, 23 Oct 2025 17:30:16 -0400 Subject: [PATCH 1/5] add portalcall primary logic --- src/portalcall.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/portalcall.rs diff --git a/src/portalcall.rs b/src/portalcall.rs new file mode 100644 index 0000000..8c4ad90 --- /dev/null +++ b/src/portalcall.rs @@ -0,0 +1,46 @@ +use libc::{syscall, SYS_sendto}; + +#[cfg(target_pointer_width = "64")] +const PORTAL_MAGIC: libc::c_ulong = 0xc1d1e1f1; +#[cfg(not(target_pointer_width = "64"))] +const PORTAL_MAGIC: libc::c_int = 0xc1d1e1f1; + +#[inline] +pub fn portal_call(user_magic: u64, argc: i32, args: &[u64]) -> i64 { + unsafe { + syscall( + SYS_sendto, + PORTAL_MAGIC, + user_magic, + argc, + args.as_ptr(), + 0, + 0, + ) as i64 + } +} + +#[inline] +pub fn portal_call1(user_magic: u64, a1: u64) -> i64 { + portal_call(user_magic, 1, &[a1]) +} + +#[inline] +pub fn portal_call2(user_magic: u64, a1: u64, a2: u64) -> i64 { + portal_call(user_magic, 2, &[a1, a2]) +} + +#[inline] +pub fn portal_call3(user_magic: u64, a1: u64, a2: u64, a3: u64) -> i64 { + portal_call(user_magic, 3, &[a1, a2, a3]) +} + +#[inline] +pub fn portal_call4(user_magic: u64, a1: u64, a2: u64, a3: u64, a4: u64) -> i64 { + portal_call(user_magic, 4, &[a1, a2, a3, a4]) +} + +#[inline] +pub fn portal_call5(user_magic: u64, a1: u64, a2: u64, a3: u64, a4: u64, a5: u64) -> i64 { + portal_call(user_magic, 5, &[a1, a2, a3, a4, a5]) +} From ecfd53250721e08823be440f2634dc625e1ee40d Mon Sep 17 00:00:00 2001 From: Luke Craig Date: Thu, 23 Oct 2025 17:32:06 -0400 Subject: [PATCH 2/5] main.rs: make portalcall on init --- src/main.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main.rs b/src/main.rs index aeb4cd2..3abc7d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,9 +11,11 @@ use std::sync::Arc; use serde::{Serialize, Deserialize}; use serde_json; use shlex; +mod portalcall; const BUF_SIZE: usize = 65536; const CMD_TIMEOUT: Duration = Duration::from_secs(10); +const INDIV_DEBUG_PORTALCALL_MAGIC: u64 = 0xfeedbeef; #[derive(Serialize, Deserialize, Debug)] struct CmdResult { @@ -38,6 +40,13 @@ pub struct ListenAddress { #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); + + let init_return = portalcall::portal_call1(INDIV_DEBUG_PORTALCALL_MAGIC, 0); + if init_return != 0 { + error!("Failed to initialize portal call interface, return code {}", init_return); + return Err("Failed to initialize portal call interface".into()); + } + let args = ListenAddress::from_args(); let cid = args.cid.unwrap_or(libc::VMADDR_CID_ANY); let addr = VsockAddr::new(cid, args.port); From 818ddbb8d28bda914702ceafa28fca34eadf70df Mon Sep 17 00:00:00 2001 From: Luke Craig Date: Fri, 24 Oct 2025 10:30:46 -0400 Subject: [PATCH 3/5] fixup portalcall arguments --- src/portalcall.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/portalcall.rs b/src/portalcall.rs index 8c4ad90..7d964b4 100644 --- a/src/portalcall.rs +++ b/src/portalcall.rs @@ -3,7 +3,7 @@ use libc::{syscall, SYS_sendto}; #[cfg(target_pointer_width = "64")] const PORTAL_MAGIC: libc::c_ulong = 0xc1d1e1f1; #[cfg(not(target_pointer_width = "64"))] -const PORTAL_MAGIC: libc::c_int = 0xc1d1e1f1; +const PORTAL_MAGIC: libc::c_uint = 0xc1d1e1f1; #[inline] pub fn portal_call(user_magic: u64, argc: i32, args: &[u64]) -> i64 { @@ -21,26 +21,31 @@ pub fn portal_call(user_magic: u64, argc: i32, args: &[u64]) -> i64 { } #[inline] +#[allow(dead_code)] pub fn portal_call1(user_magic: u64, a1: u64) -> i64 { portal_call(user_magic, 1, &[a1]) } #[inline] +#[allow(dead_code)] pub fn portal_call2(user_magic: u64, a1: u64, a2: u64) -> i64 { portal_call(user_magic, 2, &[a1, a2]) } #[inline] +#[allow(dead_code)] pub fn portal_call3(user_magic: u64, a1: u64, a2: u64, a3: u64) -> i64 { portal_call(user_magic, 3, &[a1, a2, a3]) } #[inline] +#[allow(dead_code)] pub fn portal_call4(user_magic: u64, a1: u64, a2: u64, a3: u64, a4: u64) -> i64 { portal_call(user_magic, 4, &[a1, a2, a3, a4]) } #[inline] +#[allow(dead_code)] pub fn portal_call5(user_magic: u64, a1: u64, a2: u64, a3: u64, a4: u64, a5: u64) -> i64 { portal_call(user_magic, 5, &[a1, a2, a3, a4, a5]) } From f2c8442a0e6eaef57389e73670ad0e536684e2d6 Mon Sep 17 00:00:00 2001 From: Luke Craig Date: Fri, 24 Oct 2025 10:31:59 -0400 Subject: [PATCH 4/5] make init warn not fail --- src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3abc7d8..1c95e16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,8 +43,7 @@ async fn main() -> Result<(), Box> { let init_return = portalcall::portal_call1(INDIV_DEBUG_PORTALCALL_MAGIC, 0); if init_return != 0 { - error!("Failed to initialize portal call interface, return code {}", init_return); - return Err("Failed to initialize portal call interface".into()); + warn!("Failed to initialize portal call interface, return code {}", init_return); } let args = ListenAddress::from_args(); From 6724ad0b155143a7dd314644abeec5d0533fc26e Mon Sep 17 00:00:00 2001 From: Luke Craig Date: Fri, 24 Oct 2025 11:18:51 -0400 Subject: [PATCH 5/5] drop warning log --- src/main.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1c95e16..76a45cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,11 +41,7 @@ pub struct ListenAddress { async fn main() -> Result<(), Box> { env_logger::init(); - let init_return = portalcall::portal_call1(INDIV_DEBUG_PORTALCALL_MAGIC, 0); - if init_return != 0 { - warn!("Failed to initialize portal call interface, return code {}", init_return); - } - + let _: i64 = portalcall::portal_call1(INDIV_DEBUG_PORTALCALL_MAGIC, 0); let args = ListenAddress::from_args(); let cid = args.cid.unwrap_or(libc::VMADDR_CID_ANY); let addr = VsockAddr::new(cid, args.port);