Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
cde8dcb
drm/asahi: lock only the VM reservation for read-only VM queries
jgoyvaerts Oct 27, 2026
f3cc4a6
drm/asahi: lock only the VM reservation for VA updates
jgoyvaerts Oct 27, 2026
925df2a
drm/asahi: g17: stop cancelling behind a failed command once it has r…
jgoyvaerts Oct 28, 2026
2519646
tools: aurora-sep: share the SELinux device type and let fprintd read…
RyanTheTide Oct 29, 2026
ce4cf99
tools: aurora-sep: fix the Arch checksums of load-driver and XART-SAF…
RyanTheTide Oct 30, 2026
afd5117
Bluetooth: bcm4377: abort suspend if wake IRQ arming fails
RyanTheTide Oct 24, 2026
ab30807
drm/asahi: keep work-queue firmware structures until the context is i…
RyanTheTide Oct 24, 2026
4177ad5
dmaengine: apple-sio: select firmware behavior from compatible data
RyanTheTide Oct 26, 2026
488ad2b
drm/asahi: keep G15 compatible with the shared G16 interfaces
RyanTheTide Oct 26, 2026
d77b2cf
docs: explain Apple s2idle wake paths and qualification
RyanTheTide Oct 30, 2026
14b5515
selftests: apple-dcp: follow the PMP auxiliary buffer in ordered-rx
RyanTheTide Oct 30, 2026
bd4a566
drm/apple: drop an unused probe switch and the M3 notch alias
RyanTheTide Oct 26, 2026
18ee687
docs: gpu: identify the Apple parameter migration license
RyanTheTide Oct 26, 2026
16bf2b1
rust: keep bindgen layout checks in every build
RyanTheTide Oct 30, 2026
010b976
Merge pull request #598 from aurora-silicon/fix/review1030-ordered-rx…
RyanTheTide Oct 30, 2026
97dafeb
tools: asahi: model the T8132 members in the ATCPHY USB3 harness
RyanTheTide Oct 30, 2026
1173b79
Merge pull request #609 from aurora-silicon/conv/atc-usb3-harness
RyanTheTide Oct 30, 2026
b6796c6
Merge pull request #607 from aurora-silicon/conv/rust-bindgen-layout-…
RyanTheTide Oct 30, 2026
202e4d0
Merge pull request #608 from aurora-silicon/conv/drm-apple-drop-notch…
RyanTheTide Oct 30, 2026
febd797
soc: apple: display gate: say why the port controller link stays managed
RyanTheTide Oct 30, 2026
0b79795
Merge pull request #600 from aurora-silicon/conv/bcm4377-wake-arm
RyanTheTide Oct 30, 2026
fa4dc76
Merge pull request #601 from aurora-silicon/conv/asahi-wq-lifetime
RyanTheTide Oct 30, 2026
766d24a
Merge pull request #603 from aurora-silicon/conv/apple-sio-compatible
RyanTheTide Oct 30, 2026
71b3fdb
Merge pull request #604 from aurora-silicon/conv/docs-apple-s2idle
RyanTheTide Oct 30, 2026
e8193ee
wifi: brcmfmac: query assoc_info with a full-sized buffer
RyanTheTide Oct 29, 2026
4bb0840
drm/apple: expose the pixel blend mode of DCP planes
RyanTheTide Oct 29, 2026
5bc9ff6
Bluetooth: hci_bcm4377: handle function resets through the PCI core
RyanTheTide Oct 29, 2026
60b5d0b
arm64: configs: asahi: Cap the page block order at 2 MiB
RyanTheTide Oct 30, 2026
65ee470
Merge pull request #616 from aurora-silicon/fleet10/carry-bootlog-pag…
RyanTheTide Oct 30, 2026
e01cbc2
tools/asahi: follow the CLPC dense GPU floor in the demand test
RyanTheTide Oct 30, 2026
ae8725d
tools/asahi: fall back to rustc when rustup is absent in G15 tests
RyanTheTide Oct 30, 2026
5a12fc0
tools/asahi: pass the engine to work_state acquire in the G17 test
RyanTheTide Oct 30, 2026
ac72d4f
tools/asahi: cover the new RTKit buffers in the OSLog test
RyanTheTide Oct 30, 2026
ff1234c
tools/asahi: model the yielded Type-C port in the tunnel route test
RyanTheTide Oct 30, 2026
dda23b9
tools/asahi: load mt7932_power by path in the 6 GHz policy tool
RyanTheTide Oct 30, 2026
8de86c3
Merge pull request #617 from aurora-silicon/hostfix/clpc-gpu-demand
RyanTheTide Oct 30, 2026
50d84da
Merge pull request #618 from aurora-silicon/hostfix/g15-host-rustc
RyanTheTide Oct 30, 2026
82c6258
Merge pull request #619 from aurora-silicon/hostfix/g17-compute-deadline
RyanTheTide Oct 30, 2026
0b76ae0
Merge pull request #620 from aurora-silicon/hostfix/rtkit-oslog
RyanTheTide Oct 30, 2026
22f44ec
Merge pull request #621 from aurora-silicon/hostfix/tunnel-route
RyanTheTide Oct 30, 2026
f60ee6e
Merge pull request #622 from aurora-silicon/hostfix/mt7932-policy-iso…
RyanTheTide Oct 30, 2026
d031104
tools/asahi: follow the variant table and suspend rollback in the bcm…
RyanTheTide Oct 30, 2026
4d21609
tools/asahi: follow the grown variant table in the bcm4377-id test
RyanTheTide Oct 30, 2026
075e86a
tools/asahi: follow the max3() conversion in the dma-heap-fd test
RyanTheTide Oct 30, 2026
6ea8034
tools/asahi: follow the closed-client logging in the g15-input-error …
RyanTheTide Oct 30, 2026
17cd686
tools/asahi: follow the moved queue info setup in the compute-preempt…
RyanTheTide Oct 30, 2026
d9a2cfe
tools/asahi: follow the IRQ-safe PMP report entries in the T6030 grap…
RyanTheTide Oct 30, 2026
09ac0e8
tools/asahi: follow the AV1 segmentation map tail in the AVD test
RyanTheTide Oct 30, 2026
b198230
tools/asahi: follow the HT capability log in the MT7932 association test
RyanTheTide Oct 30, 2026
f5d693d
tools/asahi: follow 6 GHz policy, USB runtime PM and RX wake in the N…
RyanTheTide Oct 30, 2026
7ae165a
selftests: apple-afkv2: follow compact EPIC and reply lengths in the …
RyanTheTide Oct 30, 2026
4513ada
ci: run every host test on each push and pull request
RyanTheTide Oct 30, 2026
cd893cd
selftests: asahi-m4: find newer UAPI headers in the tree for the layo…
RyanTheTide Oct 30, 2026
24f1fbf
ci: host tests: provide ld.lld and use the pinned rustc everywhere
RyanTheTide Oct 30, 2026
5d7c3e7
Merge pull request #624 from aurora-silicon/ci/host-tests-integ
RyanTheTide Oct 30, 2026
993ad0d
Merge pull request #613 from aurora-silicon/docs/display-gate-managed…
RyanTheTide Oct 30, 2026
97be391
Merge pull request #602 from aurora-silicon/conv/asahi-g15-shared
RyanTheTide Oct 30, 2026
7823a6e
Merge pull request #584 from aurora-silicon/aurora-sep/selinux-shared…
RyanTheTide Oct 30, 2026
23827fe
soc: apple: mailbox: Do not sleep past free FIFO space
RyanTheTide Oct 30, 2026
eea8519
Merge pull request #741 from aurora-silicon/fix/isp-p010-timeout-reco…
RyanTheTide Oct 31, 2026
902745c
Merge pull request #521 from jgoyvaerts/m4pro/asahi-vm-resv-lock
RyanTheTide Oct 31, 2026
41c4055
Merge pull request #556 from jgoyvaerts/m4pro/g17-failed-record-retir…
RyanTheTide Oct 31, 2026
7914941
Merge integration/aurora 41c40553 into aurora-wip
RyanTheTide Oct 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/sep-source.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: SEP source checks
on:
pull_request:
paths:
- 'Makefile'
- 'rust/**'
- 'tools/aurora-bindgen/**'
- 'drivers/soc/apple/**'
- 'include/uapi/linux/apple-sep.h'
- 'tools/aurora-sep/**'
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/asahi/g17/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,11 @@ impl Completion {
drop(lease);
}

/// Whether the command still holds its VM pin: firmware may still own or replay it.
pub(crate) fn retains_vm(&self) -> bool {
self.vm_job.lock().is_some()
}

fn release_healthy(&self) {
if let Some(sources) = &self.sources {
sources.release();
Expand Down
107 changes: 107 additions & 0 deletions drivers/gpu/drm/asahi/g17/dependency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,48 @@ pub(crate) fn replay_status(status: i32) -> Result {
else { Ok(()) }
}

/// Whether a failed command may still run or write: it holds its VM pin until it has physically
/// retired, or was never published.
pub(crate) trait Retention {
fn retained(&self) -> bool;
}

/// The failed ordinals of one engine that later commands must not bypass. A command whose prefix
/// covers one is cancelled, so none runs before a failed producer the firmware may still replay.
/// Once that producer has retired nothing of it can run or write any more, so it stops counting:
/// otherwise one cancelled command cancelled every later command of its queue for good.
pub(crate) struct FailureRecord<T> {
retained: KVec<(u64, T)>,
/// A failure that could not be tracked: it keeps cancelling for good, as all failures once did.
untracked: Option<(u64, T)>,
}

impl<T: Retention + Clone> FailureRecord<T> {
pub(crate) const fn new() -> Self {
Self { retained: KVec::new(), untracked: None }
}

/// A finished frontier entry, at pruning.
pub(crate) fn note(&mut self, sequence: u64, status: i32, entry: &T) {
if status >= 0 || !entry.retained() {
return;
}
if self.retained.push((sequence, entry.clone()), GFP_KERNEL).is_err()
&& self.untracked.as_ref().is_none_or(|(first, _)| sequence < *first)
{
self.untracked = Some((sequence, entry.clone()));
}
}

/// The earliest failure later prefixes must not bypass.
pub(crate) fn earliest(&mut self) -> Option<(u64, &T)> {
self.retained.retain(|(_, entry)| entry.retained());
Iterator::chain(self.retained.iter(), self.untracked.iter())
.min_by_key(|(sequence, _)| *sequence)
.map(|(sequence, entry)| (*sequence, entry))
}
}

pub(crate) struct Frontier {
dependencies: [KickDependency; KICK_BARRIERS_MAX],
sequences: [u64; KICK_BARRIERS_MAX],
Expand Down Expand Up @@ -89,3 +131,68 @@ impl Frontier {
self.insert(sequence, dependency)
}
}

#[kunit_tests(asahi_g17_dependency)]
mod tests {
use super::*;

#[derive(Clone)]
struct Probe(kernel::sync::Arc<core::sync::atomic::AtomicBool>);

impl Probe {
fn new(retained: bool) -> Self {
Self(kernel::sync::Arc::new(core::sync::atomic::AtomicBool::new(retained), GFP_KERNEL).unwrap())
}
fn retire(&self) {
self.0.store(false, core::sync::atomic::Ordering::Relaxed);
}
}

impl Retention for Probe {
fn retained(&self) -> bool {
self.0.load(core::sync::atomic::Ordering::Relaxed)
}
}

fn earliest(record: &mut FailureRecord<Probe>) -> Option<u64> {
record.earliest().map(|(sequence, _)| sequence)
}

#[test]
fn a_cancelled_command_does_not_poison_its_queue() {
// Cancelled or failed before publication: it released its pin and can never run.
let mut record = FailureRecord::new();
record.note(5, ECANCELED.to_errno(), &Probe::new(false));
assert_eq!(earliest(&mut record), None);
}

#[test]
fn a_retained_failure_cancels_until_it_retires() {
let mut record = FailureRecord::new();
let failed = Probe::new(true);
record.note(5, EIO.to_errno(), &failed);
assert_eq!(earliest(&mut record), Some(5));
failed.retire();
assert_eq!(earliest(&mut record), None);
}

#[test]
fn a_later_retained_failure_survives_an_earlier_retirement() {
let mut record = FailureRecord::new();
let (first, second) = (Probe::new(true), Probe::new(true));
record.note(5, EIO.to_errno(), &first);
record.note(9, ECANCELED.to_errno(), &second);
assert_eq!(earliest(&mut record), Some(5));
first.retire();
assert_eq!(earliest(&mut record), Some(9));
second.retire();
assert_eq!(earliest(&mut record), None);
}

#[test]
fn successes_are_not_recorded() {
let mut record = FailureRecord::new();
record.note(5, 1, &Probe::new(true));
assert_eq!(earliest(&mut record), None);
}
}
9 changes: 8 additions & 1 deletion drivers/gpu/drm/asahi/g17/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,13 @@ pub(crate) struct Fences {
pub(crate) ready: Fence,
pub(crate) completed: Fence,
pub(crate) publication: Option<Arc<super::completion::Publication>>,
pub(crate) owner: Arc<Completion>,
}

impl super::dependency::Retention for Fences {
fn retained(&self) -> bool {
self.owner.retains_vm()
}
}

impl Fences {
Expand Down Expand Up @@ -479,6 +486,6 @@ impl<B: Backend> Scheduler<B> {
self.backend.count_backlog(&packet);
}
job.push();
Ok(Fences { ready, completed, publication: host_publication })
Ok(Fences { ready, completed, publication: host_publication, owner: packet.completion.clone() })
}
}
28 changes: 13 additions & 15 deletions drivers/gpu/drm/asahi/g17/queue/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use super::{
command::{Parser, UscWindow, Validated},
completion::{Completion, Destinations, PreparedPublication},
context::Context,
dependency::FailureRecord,
fence::Outputs,
job::{self, Backend, Engine, Fences, Order, Packet, Scheduler},
validation::Proof,
Expand Down Expand Up @@ -99,7 +100,7 @@ pub(crate) struct Queue<B: Backend> {
/// Finished frontier entries pruned during this ioctl. Their last references
/// can tear a whole completion down; that waits until the ioctl has published.
finished: KVec<Fences>,
failures: [Option<(u64, Fence)>; 2],
failures: [FailureRecord<Fences>; 2],
// Closing the userspace queue releases admission even if firmware still
// retains one of its execution contexts or installed physical graphs.
_slot: admission::QueueSlot,
Expand Down Expand Up @@ -143,7 +144,7 @@ impl<B: Backend> Queue<B> {
sequence: [0; 2],
frontiers: core::array::from_fn(|_| KVec::new()),
finished: KVec::new(),
failures: [None, None],
failures: [FailureRecord::new(), FailureRecord::new()],
_slot: slot,
})
}
Expand Down Expand Up @@ -182,11 +183,7 @@ impl<B: Backend> Queue<B> {
if let Some(finished) = finished.as_mut() {
let _ = finished.push_within_capacity(fences.clone());
}
// One earliest failed ordinal covers every later prefix without
// retaining its packet, mappings, or every failed fence.
if status < 0 && failure.as_ref().is_none_or(|(first, _)| *sequence < *first) {
*failure = Some((*sequence, fences.completed.clone()));
}
failure.note(*sequence, status, fences);
false
});
}
Expand Down Expand Up @@ -242,9 +239,9 @@ impl<B: Backend> Queue<B> {
|| fences.ready.raw() != fences.completed.raw()
|| fences.status() > 0
})
&& self.failures.iter().enumerate().all(|(index, failure)| {
failure.as_ref().is_none_or(|(sequence, _)| {
!Order::contains(order.wait_through[index], *sequence)
&& self.failures.iter_mut().enumerate().all(|(index, failure)| {
failure.earliest().is_none_or(|(sequence, _)| {
!Order::contains(order.wait_through[index], sequence)
})
}) {
self.backend.input_sources(inputs)
Expand Down Expand Up @@ -314,11 +311,12 @@ impl<B: Backend> Queue<B> {
.iter()
.filter(|(_, fences)| fences.ready.raw() == fences.completed.raw())
.count();
let failures: [Option<&Fence>; 2] = core::array::from_fn(|index| {
self.failures[index].as_ref().and_then(|(sequence, fence)| {
Order::contains(order.wait_through[index], *sequence).then_some(fence)
})
});
let mut failures: [Option<Fence>; 2] = [None, None];
for (index, failure) in self.failures.iter_mut().enumerate() {
failures[index] = failure.earliest().and_then(|(sequence, fences)| {
Order::contains(order.wait_through[index], sequence).then(|| fences.completed.clone())
});
}
let failure_count = failures.iter().flatten().count();
let mut dependencies = KVec::with_capacity(
inputs.len() + count + timestamp_count + failure_count,
Expand Down
38 changes: 16 additions & 22 deletions drivers/gpu/drm/asahi/mmu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1307,9 +1307,7 @@ impl KernelMapping {
return Err(EINVAL);
}
let address = self.iova().checked_add(offset as u64).ok_or(EOVERFLOW)?;
lock_vm(&self.0.owner, None, false)?
.page_table
.translate_iova(address)
self.0.owner.lock_inner().page_table.translate_iova(address)
}

/// Writes a userspace timestamp through the retained GEM mapping. Aligned results
Expand Down Expand Up @@ -2263,9 +2261,7 @@ impl Vm {
}

pub(crate) fn covers_range(&self, address: u64, size: u64, read: bool, write: bool) -> bool {
let Ok(mut inner) = lock_vm(&self.gpuvm, None, false) else {
return false;
};
let mut inner = self.gpuvm.lock_inner();
Self::covers_range_locked(&mut inner, address, size, read, write)
}

Expand All @@ -2280,9 +2276,7 @@ impl Vm {
if stride <= block_size {
return false;
}
let Ok(mut inner) = lock_vm(&self.gpuvm, None, false) else {
return false;
};
let mut inner = self.gpuvm.lock_inner();
addresses.iter().all(|&address| {
let Some(guard) = address.checked_add(block_size) else {
return false;
Expand All @@ -2292,12 +2286,12 @@ impl Vm {
})
}

/// Checks all exact request tuples under one GPUVM exec lock. Access bit0
/// Checks all exact request tuples under one hold of the VM reservation. Access bit0
/// requests reading and bit1 writing. The epoch names this same snapshot.
pub(crate) fn covers_ranges_batch(&self, ranges: &[(u64, u64, u8)]) -> (bool, Option<u64>) {
let Ok(mut inner) = lock_vm(&self.gpuvm, None, false) else {
return (false, None);
};
// Every mapping change holds the VM reservation, so readers need only that one. The full
// exec lock would also lock every external BO, making each submit O(external BOs).
let mut inner = self.gpuvm.lock_inner();
let epoch = inner.epoch;
let covered = ranges.iter().all(|&(address, size, access)| {
Self::covers_range_locked(&mut inner, address, size, access & 1 != 0, access & 2 != 0)
Expand Down Expand Up @@ -2421,7 +2415,7 @@ impl Vm {
// SAFETY: Vm construction does not retain its initial UniqueRefGpuVm;
// every subsequent access to VM data is serialized by the exec lock.
let mut vm_exec = unsafe {
self.gpuvm.exec_lock(/*Some(gem)*/ None, false)?
self.gpuvm.exec_lock_vm(/*Some(gem)*/ None, false)?
};
let inner = vm_exec.unique_gpuvm.data();

Expand Down Expand Up @@ -2508,7 +2502,7 @@ impl Vm {
// SAFETY: no other UniqRefGpuVm exists so `GpuVm::exec_lock()` is safe
let mut vm_exec = unsafe {
self.gpuvm
.exec_lock(/*Some(&gem)*/ None, false)
.exec_lock_vm(/*Some(&gem)*/ None, false)
.inspect_err(|_| {
dev_err!(self.dev, "map_at(): Failed to exec_lock gpuvm\n");
})?
Expand Down Expand Up @@ -2598,7 +2592,7 @@ impl Vm {
// SAFETY: Vm construction does not retain its initial UniqueRefGpuVm;
// every subsequent access to VM data is serialized by the exec lock.
let mut vm_exec = unsafe {
self.gpuvm.exec_lock(/*Some(&gem)*/ None, false)?
self.gpuvm.exec_lock_vm(/*Some(&gem)*/ None, false)?
};
let inner = vm_exec.unique_gpuvm.data();

Expand Down Expand Up @@ -2671,7 +2665,7 @@ impl Vm {
) -> Result<KernelMapping> {
// SAFETY: Vm construction does not retain its initial UniqueRefGpuVm;
// every subsequent access to VM data is serialized by the exec lock.
let mut vm_exec = unsafe { self.gpuvm.exec_lock(None, false)? };
let mut vm_exec = unsafe { self.gpuvm.exec_lock_vm(None, false)? };

if (iova as usize | phys | size) & UAT_PGMSK != 0 {
dev_err!(
Expand Down Expand Up @@ -2777,7 +2771,7 @@ impl Vm {

// SAFETY: Vm construction does not retain its initial UniqueRefGpuVm;
// every subsequent access to VM data is serialized by the exec lock.
let mut vm_exec = unsafe { self.gpuvm.exec_lock(None, false)? };
let mut vm_exec = unsafe { self.gpuvm.exec_lock_vm(None, false)? };

mod_dev_dbg!(self.dev, "MMU: sm_unmap: {:#x}:{:#x}\n", iova, size);
let _commit = if user {
Expand Down Expand Up @@ -2808,7 +2802,7 @@ impl Vm {
let mut ctx = StepContext::new(None, Prot::default(), &mut resources)?;

// SAFETY: See `lock_vm()`.
let mut vm_exec = match unsafe { self.gpuvm.exec_lock(None, false) } {
let mut vm_exec = match unsafe { self.gpuvm.exec_lock_vm(None, false) } {
Err(error) if error == ENOMEM => return self.drop_mappings_low_memory(gem),
result => result?,
};
Expand Down Expand Up @@ -3187,7 +3181,7 @@ impl Uat {
return Err(EINVAL);
}
let root = {
let owner = lock_vm(&vm.gpuvm, None, false)?;
let owner = vm.gpuvm.lock_inner();
if owner.is_kernel || !Arc::ptr_eq(&owner.uat_inner, &self.inner) {
return Err(EINVAL);
}
Expand Down Expand Up @@ -3332,7 +3326,7 @@ impl Uat {
return Err(EINVAL);
}
{
let owner = lock_vm(&vm.gpuvm, None, false)?;
let owner = vm.gpuvm.lock_inner();
if owner.is_kernel
|| !core::ptr::eq(Arc::as_ptr(&owner.uat_inner), Arc::as_ptr(&self.inner))
{
Expand Down Expand Up @@ -3727,7 +3721,7 @@ impl Vm {
/// Diagnostic reservation occupancy (including guards), not a placement promise.
/// Removal can progress between queries; allocations are excluded by the VM lock.
pub(crate) fn capacity(&self, range: Range<u64>) -> Result<(u64, u64)> {
let inner = lock_vm(&self.gpuvm, None, false)?;
let inner = self.gpuvm.lock_inner();
let mut next = range.start;
let mut used = 0;
let mut largest = 0;
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/asahi/mmu/bind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl Vm {
PreparedUserBindOp::Map(map) => {
// SAFETY: See `lock_vm()`. As in `Vm::bind_object()`, the object itself is
// not locked: the map step may still populate its pages.
let mut inner = unsafe { self.gpuvm.exec_lock(None, true)? };
let mut inner = unsafe { self.gpuvm.exec_lock_vm(None, true)? };
match self.mapping_commit() {
Ok(commit) => {
let (flags, repeat) = if map.single_page {
Expand Down Expand Up @@ -177,7 +177,7 @@ impl Vm {
}
PreparedUserBindOp::Unmap(unmap) => {
// SAFETY: See `lock_vm()`.
let mut inner = unsafe { self.gpuvm.exec_lock(None, true)? };
let mut inner = unsafe { self.gpuvm.exec_lock_vm(None, true)? };
match self.mapping_commit() {
Ok(commit) => {
let mut ctx =
Expand Down
Loading