Skip to content

Commit 0c00e44

Browse files
committed
riscv: hypervisor extension fences
1 parent 2a84e9a commit 0c00e44

File tree

1 file changed

+200
-8
lines changed
  • crates/core_arch/src/riscv

1 file changed

+200
-8
lines changed

crates/core_arch/src/riscv/mod.rs

+200-8
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub unsafe fn fence_i() {
4242
asm!("fence.i")
4343
}
4444

45-
/// Generates the `SFENCE.VMA` instruction for given virtual address and address space
45+
/// Supervisor memory management fence for given virtual address and address space
4646
///
4747
/// The fence orders only reads and writes made to leaf page table entries corresponding to
4848
/// the virtual address in parameter `vaddr`, for the address space identified by integer parameter
@@ -55,7 +55,7 @@ pub unsafe fn sfence_vma(vaddr: usize, asid: usize) {
5555
asm!("sfence.vma {}, {}", in(reg) vaddr, in(reg) asid)
5656
}
5757

58-
/// Generates the `SFENCE.VMA` instruction for given virtual address
58+
/// Supervisor memory management fence for given virtual address
5959
///
6060
/// The fence orders only reads and writes made to leaf page table entries corresponding to
6161
/// the virtual address in parameter `vaddr`, for all address spaces.
@@ -66,7 +66,7 @@ pub unsafe fn sfence_vma_vaddr(vaddr: usize) {
6666
asm!("sfence.vma {}, x0", in(reg) vaddr)
6767
}
6868

69-
/// Generates the `SFENCE.VMA` instruction for given address space
69+
/// Supervisor memory management fence for given address space
7070
///
7171
/// The fence orders all reads and writes made to any level of the page tables,
7272
/// but only for the address space identified by integer parameter `asid`.
@@ -79,7 +79,7 @@ pub unsafe fn sfence_vma_asid(asid: usize) {
7979
asm!("sfence.vma x0, {}", in(reg) asid)
8080
}
8181

82-
/// Generates the `SFENCE.VMA` instruction for all address spaces and virtual addresses
82+
/// Supervisor memory management fence for all address spaces and virtual addresses
8383
///
8484
/// The fence orders all reads and writes made to any level of the page
8585
/// tables, for all address spaces. The fence also invalidates all address-translation cache entries,
@@ -89,7 +89,7 @@ pub unsafe fn sfence_vma_all() {
8989
asm!("sfence.vma")
9090
}
9191

92-
/// Generates the `SINVAL.VMA` instruction for given virtual address and address space
92+
/// Invalidate supervisor translation cache for given virtual address and address space
9393
///
9494
/// This instruction invalidates any address-translation cache entries that an
9595
/// `SFENCE.VMA` instruction with the same values of `vaddr` and `asid` would invalidate.
@@ -99,7 +99,7 @@ pub unsafe fn sinval_vma(vaddr: usize, asid: usize) {
9999
asm!(".insn r 0x73, 0, 0x0B, x0, {}, {}", in(reg) vaddr, in(reg) asid)
100100
}
101101

102-
/// Generates the `SINVAL.VMA` instruction for given virtual address
102+
/// Invalidate supervisor translation cache for given virtual address
103103
///
104104
/// This instruction invalidates any address-translation cache entries that an
105105
/// `SFENCE.VMA` instruction with the same values of `vaddr` and `asid` would invalidate.
@@ -108,7 +108,7 @@ pub unsafe fn sinval_vma_vaddr(vaddr: usize) {
108108
asm!(".insn r 0x73, 0, 0x0B, x0, {}, x0", in(reg) vaddr)
109109
}
110110

111-
/// Generates the `SINVAL.VMA` instruction for given address space
111+
/// Invalidate supervisor translation cache for given address space
112112
///
113113
/// This instruction invalidates any address-translation cache entries that an
114114
/// `SFENCE.VMA` instruction with the same values of `vaddr` and `asid` would invalidate.
@@ -117,7 +117,7 @@ pub unsafe fn sinval_vma_asid(asid: usize) {
117117
asm!(".insn r 0x73, 0, 0x0B, x0, x0, {}", in(reg) asid)
118118
}
119119

120-
/// Generates the `SINVAL.VMA` instruction for all address spaces and virtual addresses
120+
/// Invalidate supervisor translation cache for all address spaces and virtual addresses
121121
///
122122
/// This instruction invalidates any address-translation cache entries that an
123123
/// `SFENCE.VMA` instruction with the same values of `vaddr` and `asid` would invalidate.
@@ -132,6 +132,7 @@ pub unsafe fn sinval_vma_all() {
132132
/// are ordered before subsequent `SINVAL.VMA` instructions executed by the same hart.
133133
#[inline]
134134
pub unsafe fn sfence_w_inval() {
135+
// asm!("sfence.w.inval")
135136
asm!(".insn i 0x73, 0, x0, x0, 0x180")
136137
}
137138

@@ -141,6 +142,7 @@ pub unsafe fn sfence_w_inval() {
141142
/// are ordered before subsequent implicit references by that hart to the memory-management data structures.
142143
#[inline]
143144
pub unsafe fn sfence_inval_ir() {
145+
// asm!("sfence.inval.ir")
144146
asm!(".insn i 0x73, 0, x0, x0, 0x181")
145147
}
146148

@@ -307,3 +309,193 @@ pub unsafe fn hsv_h(dst: *mut i16, src: i16) {
307309
pub unsafe fn hsv_w(dst: *mut i32, src: i32) {
308310
asm!(".insn r 0x73, 0x4, 0x35, x0, {}, {}", in(reg) dst, in(reg) src);
309311
}
312+
313+
/// Hypervisor memory management fence for given guest virtual address and guest address space
314+
///
315+
/// Guarantees that any previous stores already visible to the current hart are ordered before all
316+
/// implicit reads by that hart done for VS-stage address translation for instructions that:
317+
/// - are subsequent to the `HFENCE.VVMA`, and
318+
/// - execute when `hgatp.VMID` has the same setting as it did when `HFENCE.VVMA` executed.
319+
///
320+
/// This fence specifies a single guest virtual address, and a single guest address-space identifier.
321+
#[inline]
322+
pub unsafe fn hfence_vvma(vaddr: usize, asid: usize) {
323+
// asm!("hfence.vvma {}, {}", in(reg) vaddr, in(reg) asid)
324+
asm!(".insn r 0x73, 0, 0x11, x0, {}, {}", in(reg) vaddr, in(reg) asid)
325+
}
326+
327+
/// Hypervisor memory management fence for given guest virtual address
328+
///
329+
/// Guarantees that any previous stores already visible to the current hart are ordered before all
330+
/// implicit reads by that hart done for VS-stage address translation for instructions that:
331+
/// - are subsequent to the `HFENCE.VVMA`, and
332+
/// - execute when `hgatp.VMID` has the same setting as it did when `HFENCE.VVMA` executed.
333+
///
334+
/// This fence specifies a single guest virtual address.
335+
#[inline]
336+
pub unsafe fn hfence_vvma_vaddr(vaddr: usize) {
337+
asm!(".insn r 0x73, 0, 0x11, x0, {}, x0", in(reg) vaddr)
338+
}
339+
340+
/// Hypervisor memory management fence for given guest address space
341+
///
342+
/// Guarantees that any previous stores already visible to the current hart are ordered before all
343+
/// implicit reads by that hart done for VS-stage address translation for instructions that:
344+
/// - are subsequent to the `HFENCE.VVMA`, and
345+
/// - execute when `hgatp.VMID` has the same setting as it did when `HFENCE.VVMA` executed.
346+
///
347+
/// This fence specifies a single guest address-space identifier.
348+
#[inline]
349+
pub unsafe fn hfence_vvma_asid(asid: usize) {
350+
asm!(".insn r 0x73, 0, 0x11, x0, x0, {}", in(reg) asid)
351+
}
352+
353+
/// Hypervisor memory management fence for all guest address spaces and guest virtual addresses
354+
///
355+
/// Guarantees that any previous stores already visible to the current hart are ordered before all
356+
/// implicit reads by that hart done for VS-stage address translation for instructions that:
357+
/// - are subsequent to the `HFENCE.VVMA`, and
358+
/// - execute when `hgatp.VMID` has the same setting as it did when `HFENCE.VVMA` executed.
359+
///
360+
/// This fence applies to any guest address spaces and guest virtual addresses.
361+
#[inline]
362+
pub unsafe fn hfence_vvma_all() {
363+
asm!(".insn r 0x73, 0, 0x11, x0, x0, x0")
364+
}
365+
366+
/// Hypervisor memory management fence for guest physical address and virtual machine
367+
///
368+
/// Guarantees that any previous stores already visible to the current hart are ordered before all implicit reads
369+
/// by that hart done for G-stage address translation for instructions that follow the HFENCE.GVMA.
370+
///
371+
/// This fence specifies a single guest physical address, **shifted right by 2 bits**, and a single virtual machine
372+
/// by virtual machine identifier (VMID).
373+
#[inline]
374+
pub unsafe fn hfence_gvma(gaddr: usize, vmid: usize) {
375+
// asm!("hfence.gvma {}, {}", in(reg) gaddr, in(reg) vmid)
376+
asm!(".insn r 0x73, 0, 0x31, x0, {}, {}", in(reg) gaddr, in(reg) vmid)
377+
}
378+
379+
/// Hypervisor memory management fence for guest physical address
380+
///
381+
/// Guarantees that any previous stores already visible to the current hart are ordered before all implicit reads
382+
/// by that hart done for G-stage address translation for instructions that follow the HFENCE.GVMA.
383+
///
384+
/// This fence specifies a single guest physical address; **the physical address should be shifted right by 2 bits**.
385+
#[inline]
386+
pub unsafe fn hfence_gvma_gaddr(gaddr: usize) {
387+
asm!(".insn r 0x73, 0, 0x31, x0, {}, x0", in(reg) gaddr)
388+
}
389+
390+
/// Hypervisor memory management fence for given virtual machine
391+
///
392+
/// Guarantees that any previous stores already visible to the current hart are ordered before all implicit reads
393+
/// by that hart done for G-stage address translation for instructions that follow the HFENCE.GVMA.
394+
///
395+
/// This fence specifies a single virtual machine by virtual machine identifier (VMID).
396+
#[inline]
397+
pub unsafe fn hfence_gvma_vmid(vmid: usize) {
398+
asm!(".insn r 0x73, 0, 0x31, x0, x0, {}", in(reg) vmid)
399+
}
400+
401+
/// Hypervisor memory management fence for all virtual machines and guest physical addresses
402+
///
403+
/// Guarantees that any previous stores already visible to the current hart are ordered before all implicit reads
404+
/// by that hart done for G-stage address translation for instructions that follow the HFENCE.GVMA.
405+
///
406+
/// This fence specifies all guest physical addresses and all virtual machines.
407+
#[inline]
408+
pub unsafe fn hfence_gvma_all() {
409+
asm!(".insn r 0x73, 0, 0x31, x0, x0, x0")
410+
}
411+
412+
/// Invalidate hypervisor translation cache for given guest virtual address and guest address space
413+
///
414+
/// This instruction invalidates any address-translation cache entries that an
415+
/// `HFENCE.VVMA` instruction with the same values of `vaddr` and `asid` would invalidate.
416+
///
417+
/// This fence specifies a single guest virtual address, and a single guest address-space identifier.
418+
#[inline]
419+
pub unsafe fn hinval_vvma(vaddr: usize, asid: usize) {
420+
// asm!("hinval.vvma {}, {}", in(reg) vaddr, in(reg) asid)
421+
asm!(".insn r 0x73, 0, 0x13, x0, {}, {}", in(reg) vaddr, in(reg) asid)
422+
}
423+
424+
/// Invalidate hypervisor translation cache for given guest virtual address
425+
///
426+
/// This instruction invalidates any address-translation cache entries that an
427+
/// `HFENCE.VVMA` instruction with the same values of `vaddr` and `asid` would invalidate.
428+
///
429+
/// This fence specifies a single guest virtual address.
430+
#[inline]
431+
pub unsafe fn hinval_vvma_vaddr(vaddr: usize) {
432+
asm!(".insn r 0x73, 0, 0x13, x0, {}, x0", in(reg) vaddr)
433+
}
434+
435+
/// Invalidate hypervisor translation cache for given guest address space
436+
///
437+
/// This instruction invalidates any address-translation cache entries that an
438+
/// `HFENCE.VVMA` instruction with the same values of `vaddr` and `asid` would invalidate.
439+
///
440+
/// This fence specifies a single guest address-space identifier.
441+
#[inline]
442+
pub unsafe fn hinval_vvma_asid(asid: usize) {
443+
asm!(".insn r 0x73, 0, 0x13, x0, x0, {}", in(reg) asid)
444+
}
445+
446+
/// Invalidate hypervisor translation cache for all guest address spaces and guest virtual addresses
447+
///
448+
/// This instruction invalidates any address-translation cache entries that an
449+
/// `HFENCE.VVMA` instruction with the same values of `vaddr` and `asid` would invalidate.
450+
///
451+
/// This fence applies to any guest address spaces and guest virtual addresses.
452+
#[inline]
453+
pub unsafe fn hinval_vvma_all() {
454+
asm!(".insn r 0x73, 0, 0x13, x0, x0, x0")
455+
}
456+
457+
/// Invalidate hypervisor translation cache for guest physical address and virtual machine
458+
///
459+
/// This instruction invalidates any address-translation cache entries that an
460+
/// `HFENCE.GVMA` instruction with the same values of `gaddr` and `vmid` would invalidate.
461+
///
462+
/// This fence specifies a single guest physical address, **shifted right by 2 bits**, and a single virtual machine
463+
/// by virtual machine identifier (VMID).
464+
#[inline]
465+
pub unsafe fn hinval_gvma(gaddr: usize, vmid: usize) {
466+
// asm!("hinval.gvma {}, {}", in(reg) gaddr, in(reg) vmid)
467+
asm!(".insn r 0x73, 0, 0x33, x0, {}, {}", in(reg) gaddr, in(reg) vmid)
468+
}
469+
470+
/// Invalidate hypervisor translation cache for guest physical address
471+
///
472+
/// This instruction invalidates any address-translation cache entries that an
473+
/// `HFENCE.GVMA` instruction with the same values of `gaddr` and `vmid` would invalidate.
474+
///
475+
/// This fence specifies a single guest physical address; **the physical address should be shifted right by 2 bits**.
476+
#[inline]
477+
pub unsafe fn hinval_gvma_gaddr(gaddr: usize) {
478+
asm!(".insn r 0x73, 0, 0x33, x0, {}, x0", in(reg) gaddr)
479+
}
480+
481+
/// Invalidate hypervisor translation cache for given virtual machine
482+
///
483+
/// This instruction invalidates any address-translation cache entries that an
484+
/// `HFENCE.GVMA` instruction with the same values of `gaddr` and `vmid` would invalidate.
485+
///
486+
/// This fence specifies a single virtual machine by virtual machine identifier (VMID).
487+
#[inline]
488+
pub unsafe fn hinval_gvma_vmid(vmid: usize) {
489+
asm!(".insn r 0x73, 0, 0x33, x0, x0, {}", in(reg) vmid)
490+
}
491+
492+
/// Invalidate hypervisor translation cache for all virtual machines and guest physical addresses
493+
///
494+
/// This instruction invalidates any address-translation cache entries that an
495+
/// `HFENCE.GVMA` instruction with the same values of `gaddr` and `vmid` would invalidate.
496+
///
497+
/// This fence specifies all guest physical addresses and all virtual machines.
498+
#[inline]
499+
pub unsafe fn hinval_gvma_all() {
500+
asm!(".insn r 0x73, 0, 0x33, x0, x0, x0")
501+
}

0 commit comments

Comments
 (0)