|  | @@ -39,7 +39,7 @@ pub struct RFenceContext {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /// Types of remote fence operations supported.
 | 
	
		
			
				|  |  |  #[allow(unused)]
 | 
	
		
			
				|  |  | -#[derive(Clone, Copy, Debug)]
 | 
	
		
			
				|  |  | +#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 | 
	
		
			
				|  |  |  pub enum RFenceType {
 | 
	
		
			
				|  |  |      /// Instruction fence.
 | 
	
		
			
				|  |  |      FenceI,
 | 
	
	
		
			
				|  | @@ -47,13 +47,17 @@ pub enum RFenceType {
 | 
	
		
			
				|  |  |      SFenceVma,
 | 
	
		
			
				|  |  |      /// Supervisor fence for virtual memory with ASID.
 | 
	
		
			
				|  |  |      SFenceVmaAsid,
 | 
	
		
			
				|  |  | +    #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  |      /// Hypervisor fence for guest virtual memory with VMID.
 | 
	
		
			
				|  |  |      HFenceGvmaVmid,
 | 
	
		
			
				|  |  | +    #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  |      /// Hypervisor fence for guest virtual memory.
 | 
	
		
			
				|  |  |      HFenceGvma,
 | 
	
		
			
				|  |  | -    /// Hypervisor fence for virtual machine virtual memory with ASID.
 | 
	
		
			
				|  |  | +    #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +    /// Hypervisor fence for guest virtual memory with ASID.
 | 
	
		
			
				|  |  |      HFenceVvmaAsid,
 | 
	
		
			
				|  |  | -    /// Hypervisor fence for virtual machine virtual memory.
 | 
	
		
			
				|  |  | +    #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +    /// Hypervisor fence for guest virtual memory.
 | 
	
		
			
				|  |  |      HFenceVvma,
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -176,13 +180,13 @@ pub(crate) struct SbiRFence;
 | 
	
		
			
				|  |  |  /// Validates address range for fence operations
 | 
	
		
			
				|  |  |  #[inline(always)]
 | 
	
		
			
				|  |  |  fn validate_address_range(start_addr: usize, size: usize) -> Result<usize, SbiRet> {
 | 
	
		
			
				|  |  | -    // Check page alignment using bitwise AND instead of modulo
 | 
	
		
			
				|  |  | -    if start_addr & 0xFFF != 0 {
 | 
	
		
			
				|  |  | -        return Err(SbiRet::invalid_address());
 | 
	
		
			
				|  |  | +    if !((start_addr == 0 && size == 0) || size == usize::MAX) {
 | 
	
		
			
				|  |  | +        if start_addr & (PAGE_SIZE - 1) != 0 {
 | 
	
		
			
				|  |  | +            return Err(SbiRet::invalid_address());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    // Avoid checked_add by checking for overflow directly
 | 
	
		
			
				|  |  | -    if size > usize::MAX - start_addr {
 | 
	
		
			
				|  |  | +    if start_addr > usize::MAX - size {
 | 
	
		
			
				|  |  |          return Err(SbiRet::invalid_address());
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -198,6 +202,11 @@ fn remote_fence_process(rfence_ctx: RFenceContext, hart_mask: HartMask) -> SbiRe
 | 
	
		
			
				|  |  |      sbi_ret
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +#[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +fn supports_hypervisor_extension() -> bool {
 | 
	
		
			
				|  |  | +    super::features::hart_extension_probe(current_hartid(), super::features::Extension::Hypervisor)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  impl rustsbi::Fence for SbiRFence {
 | 
	
		
			
				|  |  |      /// Remote instruction fence for specified harts.
 | 
	
		
			
				|  |  |      fn remote_fence_i(&self, hart_mask: HartMask) -> SbiRet {
 | 
	
	
		
			
				|  | @@ -259,71 +268,232 @@ impl rustsbi::Fence for SbiRFence {
 | 
	
		
			
				|  |  |              hart_mask,
 | 
	
		
			
				|  |  |          )
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +    fn remote_hfence_gvma_vmid(
 | 
	
		
			
				|  |  | +        &self,
 | 
	
		
			
				|  |  | +        hart_mask: HartMask,
 | 
	
		
			
				|  |  | +        start_addr: usize,
 | 
	
		
			
				|  |  | +        size: usize,
 | 
	
		
			
				|  |  | +        vmid: usize,
 | 
	
		
			
				|  |  | +    ) -> SbiRet {
 | 
	
		
			
				|  |  | +        if !supports_hypervisor_extension() {
 | 
	
		
			
				|  |  | +            return SbiRet::not_supported();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        pmu_firmware_counter_increment(firmware_event::HFENCE_GVMA_VMID_SENT);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let flush_size = match validate_address_range(start_addr, size) {
 | 
	
		
			
				|  |  | +            Ok(s) => s,
 | 
	
		
			
				|  |  | +            Err(e) => return e,
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        remote_fence_process(
 | 
	
		
			
				|  |  | +            RFenceContext {
 | 
	
		
			
				|  |  | +                start_addr,
 | 
	
		
			
				|  |  | +                size: flush_size,
 | 
	
		
			
				|  |  | +                asid: 0,
 | 
	
		
			
				|  |  | +                vmid,
 | 
	
		
			
				|  |  | +                op: RFenceType::HFenceGvmaVmid,
 | 
	
		
			
				|  |  | +            },
 | 
	
		
			
				|  |  | +            hart_mask,
 | 
	
		
			
				|  |  | +        )
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +    fn remote_hfence_gvma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
 | 
	
		
			
				|  |  | +        if !supports_hypervisor_extension() {
 | 
	
		
			
				|  |  | +            return SbiRet::not_supported();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        pmu_firmware_counter_increment(firmware_event::HFENCE_GVMA_SENT);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let flush_size = match validate_address_range(start_addr, size) {
 | 
	
		
			
				|  |  | +            Ok(s) => s,
 | 
	
		
			
				|  |  | +            Err(e) => return e,
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        remote_fence_process(
 | 
	
		
			
				|  |  | +            RFenceContext {
 | 
	
		
			
				|  |  | +                start_addr,
 | 
	
		
			
				|  |  | +                size: flush_size,
 | 
	
		
			
				|  |  | +                asid: 0,
 | 
	
		
			
				|  |  | +                vmid: 0,
 | 
	
		
			
				|  |  | +                op: RFenceType::HFenceGvma,
 | 
	
		
			
				|  |  | +            },
 | 
	
		
			
				|  |  | +            hart_mask,
 | 
	
		
			
				|  |  | +        )
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +    fn remote_hfence_vvma_asid(
 | 
	
		
			
				|  |  | +        &self,
 | 
	
		
			
				|  |  | +        hart_mask: HartMask,
 | 
	
		
			
				|  |  | +        start_addr: usize,
 | 
	
		
			
				|  |  | +        size: usize,
 | 
	
		
			
				|  |  | +        asid: usize,
 | 
	
		
			
				|  |  | +    ) -> SbiRet {
 | 
	
		
			
				|  |  | +        if !supports_hypervisor_extension() {
 | 
	
		
			
				|  |  | +            return SbiRet::not_supported();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        pmu_firmware_counter_increment(firmware_event::HFENCE_VVMA_ASID_SENT);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let flush_size = match validate_address_range(start_addr, size) {
 | 
	
		
			
				|  |  | +            Ok(s) => s,
 | 
	
		
			
				|  |  | +            Err(e) => return e,
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        remote_fence_process(
 | 
	
		
			
				|  |  | +            RFenceContext {
 | 
	
		
			
				|  |  | +                start_addr,
 | 
	
		
			
				|  |  | +                size: flush_size,
 | 
	
		
			
				|  |  | +                asid,
 | 
	
		
			
				|  |  | +                vmid: 0,
 | 
	
		
			
				|  |  | +                op: RFenceType::HFenceVvmaAsid,
 | 
	
		
			
				|  |  | +            },
 | 
	
		
			
				|  |  | +            hart_mask,
 | 
	
		
			
				|  |  | +        )
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +    fn remote_hfence_vvma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
 | 
	
		
			
				|  |  | +        if !supports_hypervisor_extension() {
 | 
	
		
			
				|  |  | +            return SbiRet::not_supported();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        pmu_firmware_counter_increment(firmware_event::HFENCE_VVMA_SENT);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        let flush_size = match validate_address_range(start_addr, size) {
 | 
	
		
			
				|  |  | +            Ok(s) => s,
 | 
	
		
			
				|  |  | +            Err(e) => return e,
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        remote_fence_process(
 | 
	
		
			
				|  |  | +            RFenceContext {
 | 
	
		
			
				|  |  | +                start_addr,
 | 
	
		
			
				|  |  | +                size: flush_size,
 | 
	
		
			
				|  |  | +                asid: 0,
 | 
	
		
			
				|  |  | +                vmid: 0,
 | 
	
		
			
				|  |  | +                op: RFenceType::HFenceVvma,
 | 
	
		
			
				|  |  | +            },
 | 
	
		
			
				|  |  | +            hart_mask,
 | 
	
		
			
				|  |  | +        )
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /// Handles a single remote fence operation.
 | 
	
		
			
				|  |  |  #[inline]
 | 
	
		
			
				|  |  |  pub fn rfence_single_handler() {
 | 
	
		
			
				|  |  | -    let rfence_context = local_rfence().unwrap().get();
 | 
	
		
			
				|  |  | -    if let Some((ctx, id)) = rfence_context {
 | 
	
		
			
				|  |  | +    let local_rf = match local_rfence() {
 | 
	
		
			
				|  |  | +        Some(lr) => lr,
 | 
	
		
			
				|  |  | +        // TODO: Or return an error, depending on expected invariants
 | 
	
		
			
				|  |  | +        None => panic!("rfence_single_handler called with no local rfence context"),
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if let Some((ctx, source_hart_id)) = local_rf.get() {
 | 
	
		
			
				|  |  | +        let full_flush = (ctx.start_addr == 0 && ctx.size == 0)
 | 
	
		
			
				|  |  | +            || (ctx.size == usize::MAX)
 | 
	
		
			
				|  |  | +            || (ctx.size > TLB_FLUSH_LIMIT && ctx.size != usize::MAX);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          match ctx.op {
 | 
	
		
			
				|  |  | -            // Handle instruction fence
 | 
	
		
			
				|  |  | -            RFenceType::FenceI => unsafe {
 | 
	
		
			
				|  |  | +            RFenceType::FenceI => {
 | 
	
		
			
				|  |  |                  pmu_firmware_counter_increment(firmware_event::FENCE_I_RECEIVED);
 | 
	
		
			
				|  |  | -                asm!("fence.i");
 | 
	
		
			
				|  |  | -                remote_rfence(id).unwrap().sub();
 | 
	
		
			
				|  |  | -            },
 | 
	
		
			
				|  |  | -            // Handle virtual memory address fence
 | 
	
		
			
				|  |  | +                unsafe { asm!("fence.i") };
 | 
	
		
			
				|  |  | +                remote_rfence(source_hart_id).unwrap().sub();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |              RFenceType::SFenceVma => {
 | 
	
		
			
				|  |  |                  pmu_firmware_counter_increment(firmware_event::SFENCE_VMA_RECEIVED);
 | 
	
		
			
				|  |  | -                // If the flush size is greater than the maximum limit then simply flush all
 | 
	
		
			
				|  |  | -                if (ctx.start_addr == 0 && ctx.size == 0)
 | 
	
		
			
				|  |  | -                    || (ctx.size == usize::MAX)
 | 
	
		
			
				|  |  | -                    || (ctx.size > TLB_FLUSH_LIMIT)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    unsafe {
 | 
	
		
			
				|  |  | -                        asm!("sfence.vma");
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | +                if full_flush {
 | 
	
		
			
				|  |  | +                    unsafe { asm!("sfence.vma") };
 | 
	
		
			
				|  |  |                  } else {
 | 
	
		
			
				|  |  |                      for offset in (0..ctx.size).step_by(PAGE_SIZE) {
 | 
	
		
			
				|  |  | -                        let addr = ctx.start_addr + offset;
 | 
	
		
			
				|  |  | -                        unsafe {
 | 
	
		
			
				|  |  | -                            asm!("sfence.vma {}", in(reg) addr);
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | +                        let addr = ctx.start_addr.wrapping_add(offset);
 | 
	
		
			
				|  |  | +                        unsafe { asm!("sfence.vma {}", in(reg) addr) };
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                remote_rfence(id).unwrap().sub();
 | 
	
		
			
				|  |  | +                if let Some(remote_cell) = remote_rfence(source_hart_id) {
 | 
	
		
			
				|  |  | +                    remote_cell.sub();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            // Handle virtual memory address fence with ASID
 | 
	
		
			
				|  |  |              RFenceType::SFenceVmaAsid => {
 | 
	
		
			
				|  |  |                  pmu_firmware_counter_increment(firmware_event::SFENCE_VMA_ASID_RECEIVED);
 | 
	
		
			
				|  |  |                  let asid = ctx.asid;
 | 
	
		
			
				|  |  | -                // If the flush size is greater than the maximum limit then simply flush all
 | 
	
		
			
				|  |  | -                if (ctx.start_addr == 0 && ctx.size == 0)
 | 
	
		
			
				|  |  | -                    || (ctx.size == usize::MAX)
 | 
	
		
			
				|  |  | -                    || (ctx.size > TLB_FLUSH_LIMIT)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    unsafe {
 | 
	
		
			
				|  |  | -                        asm!("sfence.vma x0, {}", in(reg) asid);
 | 
	
		
			
				|  |  | +                if full_flush {
 | 
	
		
			
				|  |  | +                    unsafe { asm!("sfence.vma x0, {}", in(reg) asid) };
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    for offset in (0..ctx.size).step_by(PAGE_SIZE) {
 | 
	
		
			
				|  |  | +                        let addr = ctx.start_addr.wrapping_add(offset);
 | 
	
		
			
				|  |  | +                        unsafe { asm!("sfence.vma {}, {}", in(reg) addr, in(reg) asid) };
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if let Some(remote_cell) = remote_rfence(source_hart_id) {
 | 
	
		
			
				|  |  | +                    remote_cell.sub();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +            RFenceType::HFenceGvmaVmid => {
 | 
	
		
			
				|  |  | +                pmu_firmware_counter_increment(firmware_event::HFENCE_GVMA_VMID_RECEIVED);
 | 
	
		
			
				|  |  | +                let vmid = ctx.vmid;
 | 
	
		
			
				|  |  | +                if full_flush {
 | 
	
		
			
				|  |  | +                    unsafe { asm!("hfence.gvma x0, {}", in(reg) vmid) };
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    for offset in (0..ctx.size).step_by(PAGE_SIZE) {
 | 
	
		
			
				|  |  | +                        let addr = ctx.start_addr.wrapping_add(offset);
 | 
	
		
			
				|  |  | +                        unsafe { asm!("hfence.gvma {}, {}", in(reg) addr, in(reg) vmid) };
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if let Some(remote_cell) = remote_rfence(source_hart_id) {
 | 
	
		
			
				|  |  | +                    remote_cell.sub();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +            RFenceType::HFenceGvma => {
 | 
	
		
			
				|  |  | +                pmu_firmware_counter_increment(firmware_event::HFENCE_GVMA_RECEIVED);
 | 
	
		
			
				|  |  | +                if full_flush {
 | 
	
		
			
				|  |  | +                    unsafe { asm!("hfence.gvma x0, x0") };
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    for offset in (0..ctx.size).step_by(PAGE_SIZE) {
 | 
	
		
			
				|  |  | +                        let addr = ctx.start_addr.wrapping_add(offset);
 | 
	
		
			
				|  |  | +                        unsafe { asm!("hfence.gvma {}, x0", in(reg) addr) };
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if let Some(remote_cell) = remote_rfence(source_hart_id) {
 | 
	
		
			
				|  |  | +                    remote_cell.sub();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +            RFenceType::HFenceVvmaAsid => {
 | 
	
		
			
				|  |  | +                pmu_firmware_counter_increment(firmware_event::HFENCE_VVMA_ASID_RECEIVED);
 | 
	
		
			
				|  |  | +                let asid = ctx.asid;
 | 
	
		
			
				|  |  | +                if full_flush {
 | 
	
		
			
				|  |  | +                    unsafe { asm!("hfence.vvma x0, {}", in(reg) asid) };
 | 
	
		
			
				|  |  |                  } else {
 | 
	
		
			
				|  |  |                      for offset in (0..ctx.size).step_by(PAGE_SIZE) {
 | 
	
		
			
				|  |  | -                        let addr = ctx.start_addr + offset;
 | 
	
		
			
				|  |  | -                        unsafe {
 | 
	
		
			
				|  |  | -                            asm!("sfence.vma {}, {}", in(reg) addr, in(reg) asid);
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | +                        let addr = ctx.start_addr.wrapping_add(offset);
 | 
	
		
			
				|  |  | +                        unsafe { asm!("hfence.vvma {}, {}", in(reg) addr, in(reg) asid) };
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                remote_rfence(id).unwrap().sub();
 | 
	
		
			
				|  |  | +                if let Some(remote_cell) = remote_rfence(source_hart_id) {
 | 
	
		
			
				|  |  | +                    remote_cell.sub();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            rfencetype => {
 | 
	
		
			
				|  |  | -                error!("Unsupported RFence Type: {:?}!", rfencetype);
 | 
	
		
			
				|  |  | +            #[cfg(feature = "hypervisor")]
 | 
	
		
			
				|  |  | +            RFenceType::HFenceVvma => {
 | 
	
		
			
				|  |  | +                pmu_firmware_counter_increment(firmware_event::HFENCE_VVMA_RECEIVED);
 | 
	
		
			
				|  |  | +                if full_flush {
 | 
	
		
			
				|  |  | +                    unsafe { asm!("hfence.vvma x0, x0") };
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    for offset in (0..ctx.size).step_by(PAGE_SIZE) {
 | 
	
		
			
				|  |  | +                        let addr = ctx.start_addr.wrapping_add(offset);
 | 
	
		
			
				|  |  | +                        unsafe { asm!("hfence.vvma {}, x0", in(reg) addr) };
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if let Some(remote_cell) = remote_rfence(source_hart_id) {
 | 
	
		
			
				|  |  | +                    remote_cell.sub();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/// Process all pending remote fence operations.
 | 
	
		
			
				|  |  | +/// Process all pending remote fence operations on the current hart.
 | 
	
		
			
				|  |  |  #[inline]
 | 
	
		
			
				|  |  |  pub fn rfence_handler() {
 | 
	
		
			
				|  |  |      while !local_rfence().unwrap().is_empty() {
 |