@@ -21,20 +21,14 @@ use crate::{
21
21
allocate_pages, free_pages, get_system_page_size, protect_pages, round_to_page_size,
22
22
} ,
23
23
memory_region:: { AccessType , MemoryMapping } ,
24
- vm:: { Config , ContextObject , EbpfVm , ProgramResult } ,
24
+ vm:: { get_runtime_environment_key , Config , ContextObject , EbpfVm , ProgramResult } ,
25
25
x86:: * ,
26
26
} ;
27
27
28
- /// Shift the RUNTIME_ENVIRONMENT_KEY by this many bits to the LSB
29
- ///
30
- /// 3 bits for 8 Byte alignment, and 1 bit to have encoding space for the RuntimeEnvironment.
31
- const PROGRAM_ENVIRONMENT_KEY_SHIFT : u32 = 4 ;
32
28
const MAX_EMPTY_PROGRAM_MACHINE_CODE_LENGTH : usize = 4096 ;
33
29
const MAX_MACHINE_CODE_LENGTH_PER_INSTRUCTION : usize = 110 ;
34
30
const MACHINE_CODE_PER_INSTRUCTION_METER_CHECKPOINT : usize = 13 ;
35
31
36
- static RUNTIME_ENVIRONMENT_KEY : std:: sync:: OnceLock < i32 > = std:: sync:: OnceLock :: < i32 > :: new ( ) ;
37
-
38
32
pub struct JitProgram {
39
33
/// OS page size in bytes and the alignment of the sections
40
34
page_size : usize ,
@@ -100,10 +94,8 @@ impl JitProgram {
100
94
_config : & Config ,
101
95
vm : & mut EbpfVm < C > ,
102
96
registers : [ u64 ; 12 ] ,
103
- ) -> i64 {
97
+ ) {
104
98
unsafe {
105
- let mut instruction_meter =
106
- ( vm. previous_instruction_meter as i64 ) . wrapping_add ( registers[ 11 ] as i64 ) ;
107
99
std:: arch:: asm!(
108
100
// RBP and RBX must be saved and restored manually in the current version of rustc and llvm.
109
101
"push rbx" ,
@@ -124,19 +116,17 @@ impl JitProgram {
124
116
"mov rbp, [r11 + 0x50]" ,
125
117
"mov r11, [r11 + 0x58]" ,
126
118
"call r10" ,
127
- "mov rax, rbx" ,
128
119
"pop rbp" ,
129
120
"pop rbx" ,
130
121
host_stack_pointer = in( reg) & mut vm. host_stack_pointer,
131
- inlateout( "rax " ) instruction_meter ,
132
- inlateout( "rdi " ) ( vm as * mut _ as * mut u64 ) . offset ( * RUNTIME_ENVIRONMENT_KEY . get ( ) . unwrap ( ) as isize ) => _,
122
+ inlateout( "rdi " ) ( vm as * mut _ as * mut u64 ) . offset ( get_runtime_environment_key ( ) as isize ) => _ ,
123
+ inlateout( "rax " ) ( vm. previous_instruction_meter as i64 ) . wrapping_add ( registers [ 11 ] as i64 ) => _,
133
124
inlateout( "r10" ) self . pc_section[ registers[ 11 ] as usize ] => _,
134
125
inlateout( "r11" ) & registers => _,
135
126
lateout( "rsi" ) _, lateout( "rdx" ) _, lateout( "rcx" ) _, lateout( "r8" ) _,
136
127
lateout( "r9" ) _, lateout( "r12" ) _, lateout( "r13" ) _, lateout( "r14" ) _, lateout( "r15" ) _,
137
128
// lateout("rbp") _, lateout("rbx") _,
138
129
) ;
139
- instruction_meter
140
130
}
141
131
}
142
132
@@ -255,11 +245,12 @@ enum RuntimeEnvironmentSlot {
255
245
StackPointer = 2 ,
256
246
ContextObjectPointer = 3 ,
257
247
PreviousInstructionMeter = 4 ,
258
- StopwatchNumerator = 5 ,
259
- StopwatchDenominator = 6 ,
260
- Registers = 7 ,
261
- ProgramResult = 19 ,
262
- MemoryMapping = 27 ,
248
+ DueInsnCount = 5 ,
249
+ StopwatchNumerator = 6 ,
250
+ StopwatchDenominator = 7 ,
251
+ Registers = 8 ,
252
+ ProgramResult = 20 ,
253
+ MemoryMapping = 28 ,
263
254
}
264
255
265
256
/* Explaination of the Instruction Meter
@@ -357,13 +348,7 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
357
348
code_length_estimate += pc / config. instruction_meter_checkpoint_distance * MACHINE_CODE_PER_INSTRUCTION_METER_CHECKPOINT ;
358
349
}
359
350
360
- let runtime_environment_key = * RUNTIME_ENVIRONMENT_KEY . get_or_init ( || {
361
- if config. encrypt_runtime_environment {
362
- rand:: thread_rng ( ) . gen :: < i32 > ( ) >> PROGRAM_ENVIRONMENT_KEY_SHIFT
363
- } else {
364
- 0
365
- }
366
- } ) ;
351
+ let runtime_environment_key = get_runtime_environment_key ( ) ;
367
352
let mut diversification_rng = SmallRng :: from_rng ( rand:: thread_rng ( ) ) . map_err ( |_| EbpfError :: JitNotCompiled ) ?;
368
353
369
354
Ok ( Self {
@@ -1326,6 +1311,10 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
1326
1311
if self . config . enable_instruction_meter {
1327
1312
self . emit_ins ( X86Instruction :: alu ( OperandSize :: S64 , 0x81 , 5 , REGISTER_INSTRUCTION_METER , 1 , None ) ) ; // REGISTER_INSTRUCTION_METER -= 1;
1328
1313
self . emit_ins ( X86Instruction :: alu ( OperandSize :: S64 , 0x29 , REGISTER_SCRATCH , REGISTER_INSTRUCTION_METER , 0 , None ) ) ; // REGISTER_INSTRUCTION_METER -= pc;
1314
+ // *DueInsnCount = *PreviousInstructionMeter - REGISTER_INSTRUCTION_METER;
1315
+ self . emit_ins ( X86Instruction :: alu ( OperandSize :: S64 , 0x2B , REGISTER_INSTRUCTION_METER , REGISTER_PTR_TO_VM , 0 , Some ( X86IndirectAccess :: Offset ( self . slot_in_vm ( RuntimeEnvironmentSlot :: PreviousInstructionMeter ) ) ) ) ) ; // REGISTER_INSTRUCTION_METER -= *PreviousInstructionMeter;
1316
+ self . emit_ins ( X86Instruction :: alu ( OperandSize :: S64 , 0xf7 , 3 , REGISTER_INSTRUCTION_METER , 0 , None ) ) ; // REGISTER_INSTRUCTION_METER = -REGISTER_INSTRUCTION_METER;
1317
+ self . emit_ins ( X86Instruction :: store ( OperandSize :: S64 , REGISTER_INSTRUCTION_METER , REGISTER_PTR_TO_VM , X86IndirectAccess :: Offset ( self . slot_in_vm ( RuntimeEnvironmentSlot :: DueInsnCount ) ) ) ) ; // *DueInsnCount = REGISTER_INSTRUCTION_METER;
1329
1318
}
1330
1319
// Print stop watch value
1331
1320
fn stopwatch_result ( numerator : u64 , denominator : u64 ) {
@@ -1398,29 +1387,18 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
1398
1387
self . set_anchor ( ANCHOR_EXTERNAL_FUNCTION_CALL ) ;
1399
1388
self . emit_ins ( X86Instruction :: push_immediate ( OperandSize :: S64 , -1 ) ) ; // Used as PC value in error case, acts as stack padding otherwise
1400
1389
if self . config . enable_instruction_meter {
1401
- // REGISTER_INSTRUCTION_METER = *PreviousInstructionMeter - REGISTER_INSTRUCTION_METER;
1402
- self . emit_ins ( X86Instruction :: alu ( OperandSize :: S64 , 0x2B , REGISTER_INSTRUCTION_METER , REGISTER_PTR_TO_VM , 0 , Some ( X86IndirectAccess :: Offset ( self . slot_in_vm ( RuntimeEnvironmentSlot :: PreviousInstructionMeter ) ) ) ) ) ; // REGISTER_INSTRUCTION_METER -= *PreviousInstructionMeter;
1403
- self . emit_ins ( X86Instruction :: alu ( OperandSize :: S64 , 0xf7 , 3 , REGISTER_INSTRUCTION_METER , 0 , None ) ) ; // REGISTER_INSTRUCTION_METER = -REGISTER_INSTRUCTION_METER;
1404
- self . emit_rust_call ( Value :: Constant64 ( C :: consume as * const u8 as i64 , false ) , & [
1405
- Argument { index : 1 , value : Value :: Register ( REGISTER_INSTRUCTION_METER ) } ,
1406
- Argument { index : 0 , value : Value :: RegisterIndirect ( REGISTER_PTR_TO_VM , self . slot_in_vm ( RuntimeEnvironmentSlot :: ContextObjectPointer ) , false ) } ,
1407
- ] , None ) ;
1390
+ self . emit_ins ( X86Instruction :: store ( OperandSize :: S64 , REGISTER_INSTRUCTION_METER , REGISTER_PTR_TO_VM , X86IndirectAccess :: Offset ( self . slot_in_vm ( RuntimeEnvironmentSlot :: DueInsnCount ) ) ) ) ; // *DueInsnCount = REGISTER_INSTRUCTION_METER;
1408
1391
}
1409
1392
self . emit_rust_call ( Value :: Register ( REGISTER_SCRATCH ) , & [
1410
- Argument { index : 7 , value : Value :: RegisterPlusConstant32 ( REGISTER_PTR_TO_VM , self . slot_in_vm ( RuntimeEnvironmentSlot :: ProgramResult ) , false ) } ,
1411
- Argument { index : 6 , value : Value :: RegisterPlusConstant32 ( REGISTER_PTR_TO_VM , self . slot_in_vm ( RuntimeEnvironmentSlot :: MemoryMapping ) , false ) } ,
1412
1393
Argument { index : 5 , value : Value :: Register ( ARGUMENT_REGISTERS [ 5 ] ) } ,
1413
1394
Argument { index : 4 , value : Value :: Register ( ARGUMENT_REGISTERS [ 4 ] ) } ,
1414
1395
Argument { index : 3 , value : Value :: Register ( ARGUMENT_REGISTERS [ 3 ] ) } ,
1415
1396
Argument { index : 2 , value : Value :: Register ( ARGUMENT_REGISTERS [ 2 ] ) } ,
1416
1397
Argument { index : 1 , value : Value :: Register ( ARGUMENT_REGISTERS [ 1 ] ) } ,
1417
- Argument { index : 0 , value : Value :: RegisterIndirect ( REGISTER_PTR_TO_VM , self . slot_in_vm ( RuntimeEnvironmentSlot :: ContextObjectPointer ) , false ) } ,
1398
+ Argument { index : 0 , value : Value :: Register ( REGISTER_PTR_TO_VM ) } ,
1418
1399
] , None ) ;
1419
1400
if self . config . enable_instruction_meter {
1420
- self . emit_rust_call ( Value :: Constant64 ( C :: get_remaining as * const u8 as i64 , false ) , & [
1421
- Argument { index : 0 , value : Value :: RegisterIndirect ( REGISTER_PTR_TO_VM , self . slot_in_vm ( RuntimeEnvironmentSlot :: ContextObjectPointer ) , false ) } ,
1422
- ] , Some ( REGISTER_INSTRUCTION_METER ) ) ;
1423
- self . emit_ins ( X86Instruction :: store ( OperandSize :: S64 , REGISTER_INSTRUCTION_METER , REGISTER_PTR_TO_VM , X86IndirectAccess :: Offset ( self . slot_in_vm ( RuntimeEnvironmentSlot :: PreviousInstructionMeter ) ) ) ) ; // *PreviousInstructionMeter = REGISTER_INSTRUCTION_METER;
1401
+ self . emit_ins ( X86Instruction :: load ( OperandSize :: S64 , REGISTER_PTR_TO_VM , REGISTER_INSTRUCTION_METER , X86IndirectAccess :: Offset ( self . slot_in_vm ( RuntimeEnvironmentSlot :: PreviousInstructionMeter ) ) ) ) ; // REGISTER_INSTRUCTION_METER = *PreviousInstructionMeter;
1424
1402
}
1425
1403
1426
1404
// Test if result indicates that an error occured
@@ -1650,6 +1628,7 @@ mod tests {
1650
1628
check_slot ! ( env, stack_pointer, StackPointer ) ;
1651
1629
check_slot ! ( env, context_object_pointer, ContextObjectPointer ) ;
1652
1630
check_slot ! ( env, previous_instruction_meter, PreviousInstructionMeter ) ;
1631
+ check_slot ! ( env, due_insn_count, DueInsnCount ) ;
1653
1632
check_slot ! ( env, stopwatch_numerator, StopwatchNumerator ) ;
1654
1633
check_slot ! ( env, stopwatch_denominator, StopwatchDenominator ) ;
1655
1634
check_slot ! ( env, registers, Registers ) ;
0 commit comments