Skip to content

Direct Mapping Supercharged #5871

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: master
Choose a base branch
from

Conversation

Lichtso
Copy link

@Lichtso Lichtso commented Apr 17, 2025

Problem

Direct mapping is very complex and still buggy. So far, we have been trying to match the existing behavior exactly, including things which are undefined behavior from the programs (not the runtimes) perspective. E.g. the runtime allows reads (in the realloc padding) beyond the current length of an account. From a programs perspective this is uninitialized memory and no sane program should be reading from it before writing to it first. If we were to stop supporting this and instead throw InstructionError::AccountDataTooSmall we could significantly simplify the direct mapping feature.

Summary of Changes

Removes:

  • Support for noncontiguous memops syscalls (memcpy, memmov, memset, memcmp)
  • Support for noncontiguous memory mapping in SBPF
  • Automatic update of MemoryRegion::host_addr and MemoryRegion::writable in SBPF
  • Interior mutability of MemoryRegion (Cell<> around host_addr and writable) in SBPF, which prevented declaring proper lifetimes on the results of map / translate calls in this repo
  • Hacks involving Vec::spare_capacity_mut
  • Hacks which temporarily marked MemoryRegion as writable and then reverted that using scopeguard::defer
  • Zeroing of 10 KiB realloc padding during serialization (serialize_parameters_aligned)
  • Zeroing of truncated account length during CPI return (update_caller_account)
  • Zeroing of the spare capacity during CPI return (update_caller_account) when the underlying Vec was reallocated
  • Copying of the realloc padding back to the runtime in CPI call (update_callee_account)
  • Copying of the realloc padding back to the caller in CPI return (update_caller_account)
  • Copying of the realloc padding back to the runtime during deserialization (deserialize_parameters_aligned)
  • Mapping the realloc padding as a MemoryRegion
  • Unused Cargo dependencies, code and tests thereof

Adds:

  • New key for the feature gate
  • Requires a new SBPF release for: Refactor - AccessViolationHandler sbpf#42
  • SBPF memory access violation callback parameters: Address space reserved for the region, access type, VM start address and length
  • Two phase translation of mutable references (AccessType::Store) in syscalls which enables use of the borrow checker to ensure that the AccessViolationHandler can not invalidate translated references during the syscall
  • Realloc and zero fill account immediately in TransactionContext::access_violation_handler() when resize padding is written to (AccessType::Store)
  • EbpfError::AccessViolation error translation to InstructionError::AccountDataTooSmall and InstructionError::InvalidRealloc
  • test_deny_access_beyond_current_length() for InstructionError::AccountDataTooSmall and InstructionError::InvalidRealloc
  • test_access_violation_handler() for the interaction of TransactionContext::access_violation_handler() and create_memory_region_of_account()

Feature Gate Issue: https://github.com/anza-xyz/feature-gate-tracker/issues/16

Copy link

mergify bot commented Apr 17, 2025

The Firedancer team maintains a line-for-line reimplementation of the
native programs, and until native programs are moved to BPF, those
implementations must exactly match their Agave counterparts.
If this PR represents a change to a native program implementation (not
tests), please include a reviewer from the Firedancer team. And please
keep refactors to a minimum.

@Lichtso Lichtso force-pushed the direct_mapping_supercharged branch 4 times, most recently from 9d85e3a to 1cf4e9c Compare April 22, 2025 16:20
@Lichtso Lichtso force-pushed the direct_mapping_supercharged branch 3 times, most recently from 1179878 to 03bf5f3 Compare April 25, 2025 16:37
@Lichtso Lichtso added the feature-gate Pull Request adds or modifies a runtime feature gate label Apr 25, 2025
@Lichtso Lichtso force-pushed the direct_mapping_supercharged branch 5 times, most recently from b4cbde8 to 48c65cd Compare April 27, 2025 10:38
@codecov-commenter
Copy link

codecov-commenter commented Apr 27, 2025

Codecov Report

Attention: Patch coverage is 84.64646% with 76 lines in your changes missing coverage. Please review.

Project coverage is 82.8%. Comparing base (2d83436) to head (7e2054b).
Report is 72 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##           master    #5871     +/-   ##
=========================================
  Coverage    82.8%    82.8%             
=========================================
  Files         847      847             
  Lines      379509   378425   -1084     
=========================================
- Hits       314372   313572    -800     
+ Misses      65137    64853    -284     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Lichtso Lichtso force-pushed the direct_mapping_supercharged branch 2 times, most recently from 3aa050a to 720953f Compare April 29, 2025 11:51
@Lichtso Lichtso force-pushed the direct_mapping_supercharged branch 13 times, most recently from f53af04 to 4d52477 Compare May 14, 2025 14:38
@Lichtso Lichtso added the v2.3 Backport to v2.3 branch label Jun 6, 2025
Copy link

mergify bot commented Jun 6, 2025

Backports to the beta branch are to be avoided unless absolutely necessary for fixing bugs, security issues, and perf regressions. Changes intended for backport should be structured such that a minimum effective diff can be committed separately from any refactoring, plumbing, cleanup, etc that are not strictly necessary to achieve the goal. Any of the latter should go only into master and ride the normal stabilization schedule. Exceptions include CI/metrics changes, CLI improvements and documentation updates on a case by case basis.

@Lichtso Lichtso force-pushed the direct_mapping_supercharged branch from b37984e to 1b3e4bb Compare June 6, 2025 21:44
@Lichtso Lichtso force-pushed the direct_mapping_supercharged branch from 1b3e4bb to f7302df Compare June 6, 2025 22:01
@Lichtso
Copy link
Author

Lichtso commented Jun 10, 2025

We could remove BorrowedAccount::make_data_mut() as well, as it only makes sure to also reserve additional 10 KiB while unsharing / making an account unique. The unsharing still is guaranteed to happen by the other operation which make_data_mut precedes. Since all these special methods on BorrowedAccount are used by built-ins, which don't necessarily go though the serializing ABI at all (as they can be top level instructions) and because we don't need to map in zeros in the reserved address space anymore, this might simply be unnecessary. But, in the interest of keeping this PR smaller, it would be removed later.

Comment on lines +725 to 727
// No other translated references can be live when calling this.
// Meaning it should generally be at the beginning or end of a syscall and
// it should only be called once with all translations passed in one call.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to explicitly say that when using translate_mut all previous translations will be invalidated.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The borrow checker now enforces this via lifetimes, so you can not get to the situation where a previous translation would be invalidated.

@Lichtso Lichtso force-pushed the direct_mapping_supercharged branch from f7302df to f73a122 Compare June 11, 2025 12:51
LucasSte
LucasSte previously approved these changes Jun 13, 2025
new_region.cow_callback_payload = account.get_index_in_transaction() as u32;
}
self.vaddr += new_region.len;
let address_space_reserved_for_account = if self.aligned {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Not necessary for this PR, but renaming aligned would clear a source of confusion.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep aligned here does not refer to the MemoryMapping but the unaligned ABIv0 of loader-v1.
That name has already been in place before this PR, so I would change it separately later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-gate Pull Request adds or modifies a runtime feature gate v2.3 Backport to v2.3 branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants