Skip to content

Commit

Permalink
Fix input-region loading (#104)
Browse files Browse the repository at this point in the history
* use correct config when calling MemoryMapping::new()

* fix extract_input_data_regions to handle eytzinger ordering in UnalignedMemoryMapping

* rustfmt
  • Loading branch information
ravyu-jump authored Sep 5, 2024
1 parent 02a7dd7 commit 4fe3760
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 36 deletions.
53 changes: 36 additions & 17 deletions src/utils/vm/mem_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,40 @@ pub fn setup_input_regions(
them into InputDataRegions. The regions themselves are not copied,
so be mindful of lifetimes. */
pub fn extract_input_data_regions<'a>(mapping: &'a MemoryMapping<'a>) -> Vec<InputDataRegion> {
// Find first region(*) starting at MM_INPUT_START
// Then iterate over the regions and collect the input data regions
// until the end of the regions list.
// * Regions are sorted by vm address.
mapping
.get_regions()
.iter()
.skip_while(|region| region.vm_addr < ebpf::MM_INPUT_START)
.map(|region| InputDataRegion {
content: unsafe {
std::slice::from_raw_parts(region.host_addr.get() as *const u8, region.len as usize)
.to_vec()
},
offset: region.vm_addr - ebpf::MM_INPUT_START,
is_writable: region.state.get() == MemoryState::Writable,
})
.collect()
match mapping {
MemoryMapping::Aligned(mapping) => {
// regions in AlignedMemoryMapping are sorted by vm_addr
mapping
.get_regions()
.iter()
.skip_while(|region| region.vm_addr < ebpf::MM_INPUT_START)
.map(mem_region_to_input_data_region)
.collect()
}
MemoryMapping::Unaligned(mapping) => {
// regions are in eytzinger order, so we need to collect and sort them
let mut input_regions: Vec<InputDataRegion> = mapping
.get_regions()
.iter()
.filter(|region| region.vm_addr >= ebpf::MM_INPUT_START)
.map(mem_region_to_input_data_region)
.collect();

// Sort the vector by `vm_addr`
input_regions.sort_by_key(|region| region.offset);
input_regions
}
_ => vec![],
}
}

fn mem_region_to_input_data_region(region: &MemoryRegion) -> InputDataRegion {
InputDataRegion {
content: unsafe {
std::slice::from_raw_parts(region.host_addr.get() as *const u8, region.len as usize)
.to_vec()
},
offset: region.vm_addr - ebpf::MM_INPUT_START,
is_writable: region.state.get() == MemoryState::Writable,
}
}
14 changes: 6 additions & 8 deletions src/vm_cpi_syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use solana_program_runtime::{
error::StableResult,
memory_region::{MemoryMapping, MemoryRegion},
program::{BuiltinProgram, SBPFVersion},
vm::{Config, ContextObject, EbpfVm},
vm::{ContextObject, EbpfVm},
},
sysvar_cache::SysvarCache,
};
Expand Down Expand Up @@ -191,13 +191,11 @@ fn execute_vm_cpi_syscall(input: SyscallContext) -> Option<SyscallEffects> {
let mut input_data_regions = vm_ctx.input_data_regions.clone();
mem_regions::setup_input_regions(&mut regions, &mut input_data_regions);

let config = &Config {
aligned_memory_mapping: true,
enable_sbpf_v2: false,
..Config::default()
};

let memory_mapping = match MemoryMapping::new(regions, config, &SBPFVersion::V1) {
let memory_mapping = match MemoryMapping::new(
regions,
program_runtime_environment_v1.get_config(),
&SBPFVersion::V1,
) {
Ok(mapping) => mapping,
Err(_) => return None,
};
Expand Down
21 changes: 10 additions & 11 deletions src/vm_syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use solana_program_runtime::{
error::StableResult,
memory_region::{MemoryMapping, MemoryRegion},
program::{BuiltinProgram, SBPFVersion},
vm::{Config, EbpfVm},
vm::EbpfVm,
},
};
use solana_sdk::transaction_context::{TransactionAccount, TransactionContext};
Expand Down Expand Up @@ -64,6 +64,10 @@ fn execute_vm_syscall(input: SyscallContext) -> Option<SyscallEffects> {
let instr_ctx: InstrContext = input.instr_ctx?.try_into().ok()?;
let feature_set = instr_ctx.feature_set;

let program_runtime_environment_v1 =
create_program_runtime_environment_v1(&feature_set, &ComputeBudget::default(), true, false)
.unwrap();

// Create invoke context
// TODO: factor this into common code with lib.rs
let mut transaction_accounts =
Expand Down Expand Up @@ -134,13 +138,11 @@ fn execute_vm_syscall(input: SyscallContext) -> Option<SyscallEffects> {
let mut input_data_regions = vm_ctx.input_data_regions.clone();
mem_regions::setup_input_regions(&mut regions, &mut input_data_regions);

let config = &Config {
aligned_memory_mapping: true,
enable_sbpf_v2: true,
..Config::default()
};

let memory_mapping = match MemoryMapping::new(regions, config, sbpf_version) {
let memory_mapping = match MemoryMapping::new(
regions,
program_runtime_environment_v1.get_config(),
sbpf_version,
) {
Ok(mapping) => mapping,
Err(_) => return None,
};
Expand Down Expand Up @@ -173,9 +175,6 @@ fn execute_vm_syscall(input: SyscallContext) -> Option<SyscallEffects> {
}

// Actually invoke the syscall
let program_runtime_environment_v1 =
create_program_runtime_environment_v1(&feature_set, &ComputeBudget::default(), true, false)
.unwrap();

// Invoke the syscall
let (_, syscall_func) = program_runtime_environment_v1
Expand Down

0 comments on commit 4fe3760

Please sign in to comment.