@@ -33,11 +33,26 @@ pub use arch::{MAX_GPA, MAX_GVA};
3333) ) ]
3434pub use arch:: { SNAPSHOT_PT_GVA_MAX , SNAPSHOT_PT_GVA_MIN } ;
3535
36- // offsets down from the top of scratch memory for various things
3736pub const SCRATCH_TOP_SIZE_OFFSET : u64 = 0x08 ;
3837pub const SCRATCH_TOP_ALLOCATOR_OFFSET : u64 = 0x10 ;
3938pub const SCRATCH_TOP_SNAPSHOT_PT_GPA_BASE_OFFSET : u64 = 0x18 ;
40- pub const SCRATCH_TOP_EXN_STACK_OFFSET : u64 = 0x20 ;
39+ pub const SCRATCH_TOP_G2H_RING_GVA_OFFSET : u64 = 0x20 ;
40+ pub const SCRATCH_TOP_H2G_RING_GVA_OFFSET : u64 = 0x28 ;
41+ pub const SCRATCH_TOP_G2H_QUEUE_DEPTH_OFFSET : u64 = 0x30 ;
42+ pub const SCRATCH_TOP_H2G_QUEUE_DEPTH_OFFSET : u64 = 0x32 ;
43+ pub const SCRATCH_TOP_EXN_STACK_OFFSET : u64 = 0x40 ;
44+
45+ // fields must not overlap, and exception stack address must be 16-byte aligned.
46+ const _: ( ) = {
47+ assert ! ( SCRATCH_TOP_SIZE_OFFSET + 8 <= SCRATCH_TOP_ALLOCATOR_OFFSET ) ;
48+ assert ! ( SCRATCH_TOP_ALLOCATOR_OFFSET + 8 <= SCRATCH_TOP_SNAPSHOT_PT_GPA_BASE_OFFSET ) ;
49+ assert ! ( SCRATCH_TOP_SNAPSHOT_PT_GPA_BASE_OFFSET + 8 <= SCRATCH_TOP_G2H_RING_GVA_OFFSET ) ;
50+ assert ! ( SCRATCH_TOP_G2H_RING_GVA_OFFSET + 8 <= SCRATCH_TOP_H2G_RING_GVA_OFFSET ) ;
51+ assert ! ( SCRATCH_TOP_H2G_RING_GVA_OFFSET + 8 <= SCRATCH_TOP_G2H_QUEUE_DEPTH_OFFSET ) ;
52+ assert ! ( SCRATCH_TOP_G2H_QUEUE_DEPTH_OFFSET + 2 <= SCRATCH_TOP_H2G_QUEUE_DEPTH_OFFSET ) ;
53+ assert ! ( SCRATCH_TOP_H2G_QUEUE_DEPTH_OFFSET + 2 <= SCRATCH_TOP_EXN_STACK_OFFSET ) ;
54+ assert ! ( SCRATCH_TOP_EXN_STACK_OFFSET % 0x10 == 0 ) ;
55+ } ;
4156
4257/// Offset from the top of scratch memory for a shared host-guest u64 counter.
4358///
@@ -55,5 +70,30 @@ pub fn scratch_base_gva(size: usize) -> u64 {
5570 ( MAX_GVA - size + 1 ) as u64
5671}
5772
73+ /// Compute the byte offset from the scratch base to the G2H ring.
74+ ///
75+ /// TODO(ring): Remove input/output
76+ pub const fn g2h_ring_scratch_offset ( input_data_size : usize , output_data_size : usize ) -> usize {
77+ let io_off = input_data_size + output_data_size;
78+ let align = crate :: virtq:: Descriptor :: ALIGN ;
79+
80+ ( io_off + align - 1 ) & !( align - 1 )
81+ }
82+
83+ /// Compute the byte offset from the scratch base to the H2G ring.
84+ ///
85+ /// TODO(ring): Remove input/output
86+ pub const fn h2g_ring_scratch_offset (
87+ input_data_size : usize ,
88+ output_data_size : usize ,
89+ g2h_num_descs : usize ,
90+ ) -> usize {
91+ let g2h_offset = g2h_ring_scratch_offset ( input_data_size, output_data_size) ;
92+ let g2h_size = crate :: virtq:: Layout :: query_size ( g2h_num_descs) ;
93+ let align = crate :: virtq:: Descriptor :: ALIGN ;
94+
95+ ( g2h_offset + g2h_size + align - 1 ) & !( align - 1 )
96+ }
97+
5898/// Compute the minimum scratch region size needed for a sandbox.
5999pub use arch:: min_scratch_size;
0 commit comments