Skip to content

Commit

Permalink
Puts due_insn_count into the VM.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed Sep 30, 2023
1 parent d9e33a1 commit 9b1d33f
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 20 deletions.
14 changes: 6 additions & 8 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ pub struct Interpreter<'a, 'b, C: ContextObject> {
pub(crate) executable: &'a Executable<C>,
pub(crate) program: &'a [u8],
pub(crate) program_vm_addr: u64,
pub(crate) due_insn_count: u64,

/// General purpose registers and pc
pub reg: [u64; 12],
Expand All @@ -115,7 +114,6 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
executable,
program,
program_vm_addr,
due_insn_count: 0,
reg: registers,
#[cfg(feature = "debugger")]
debug_state: DebugState::Continue,
Expand Down Expand Up @@ -161,7 +159,7 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
pub fn step(&mut self) -> bool {
let config = &self.executable.get_config();

self.due_insn_count += 1;
self.vm.due_insn_count += 1;
let mut next_pc = self.reg[11] + 1;
if next_pc as usize * ebpf::INSN_SIZE > self.program.len() {
throw_error!(self, EbpfError::ExecutionOverrun);
Expand Down Expand Up @@ -456,7 +454,7 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
}
check_pc!(self, next_pc, (target_pc - self.program_vm_addr) / ebpf::INSN_SIZE as u64);
if self.executable.get_sbpf_version().static_syscalls() && self.executable.get_function_registry().lookup_by_key(next_pc as u32).is_none() {
self.due_insn_count += 1;
self.vm.due_insn_count += 1;
self.reg[11] = next_pc;
throw_error!(self, EbpfError::UnsupportedInstruction);
}
Expand All @@ -476,8 +474,7 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
if let Some((_function_name, function)) = self.executable.get_loader().get_function_registry().lookup_by_key(insn.imm as u32) {
resolved = true;

self.vm.previous_instruction_meter = self.due_insn_count;
self.due_insn_count = 0;
self.vm.due_insn_count = self.vm.previous_instruction_meter - self.vm.due_insn_count;
function(
unsafe { (self.vm as *mut _ as *mut u64).offset(get_runtime_environment_key() as isize) as *mut _ },
self.reg[1],
Expand All @@ -486,6 +483,7 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
self.reg[4],
self.reg[5],
);
self.vm.due_insn_count = 0;
self.reg[0] = match &self.vm.program_result {
ProgramResult::Ok(value) => *value,
ProgramResult::Err(_err) => return false,
Expand All @@ -512,7 +510,7 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {

ebpf::EXIT => {
if self.vm.call_depth == 0 {
if config.enable_instruction_meter && self.due_insn_count > self.vm.previous_instruction_meter {
if config.enable_instruction_meter && self.vm.due_insn_count > self.vm.previous_instruction_meter {
throw_error!(self, EbpfError::ExceededMaxInstructions);
}
self.vm.program_result = ProgramResult::Ok(self.reg[0]);
Expand All @@ -535,7 +533,7 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> {
_ => throw_error!(self, EbpfError::UnsupportedInstruction),
}

if config.enable_instruction_meter && self.due_insn_count >= self.vm.previous_instruction_meter {
if config.enable_instruction_meter && self.vm.due_insn_count >= self.vm.previous_instruction_meter {
self.reg[11] += 1;
throw_error!(self, EbpfError::ExceededMaxInstructions);
}
Expand Down
14 changes: 8 additions & 6 deletions src/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,12 @@ enum RuntimeEnvironmentSlot {
StackPointer = 2,
ContextObjectPointer = 3,
PreviousInstructionMeter = 4,
StopwatchNumerator = 5,
StopwatchDenominator = 6,
Registers = 7,
ProgramResult = 19,
MemoryMapping = 27,
DueInsnCount = 5,
StopwatchNumerator = 6,
StopwatchDenominator = 7,
Registers = 8,
ProgramResult = 20,
MemoryMapping = 28,
}

/* Explaination of the Instruction Meter
Expand Down Expand Up @@ -1386,7 +1387,7 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
self.set_anchor(ANCHOR_EXTERNAL_FUNCTION_CALL);
self.emit_ins(X86Instruction::push_immediate(OperandSize::S64, -1)); // Used as PC value in error case, acts as stack padding otherwise
if self.config.enable_instruction_meter {
self.emit_ins(X86Instruction::alu(OperandSize::S64, 0x29, REGISTER_INSTRUCTION_METER, REGISTER_PTR_TO_VM, 0, Some(X86IndirectAccess::Offset(self.slot_in_vm(RuntimeEnvironmentSlot::PreviousInstructionMeter))))); // *PreviousInstructionMeter -= REGISTER_INSTRUCTION_METER;
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;
}
self.emit_rust_call(Value::Register(REGISTER_SCRATCH), &[
Argument { index: 5, value: Value::Register(ARGUMENT_REGISTERS[5]) },
Expand Down Expand Up @@ -1627,6 +1628,7 @@ mod tests {
check_slot!(env, stack_pointer, StackPointer);
check_slot!(env, context_object_pointer, ContextObjectPointer);
check_slot!(env, previous_instruction_meter, PreviousInstructionMeter);
check_slot!(env, due_insn_count, DueInsnCount);
check_slot!(env, stopwatch_numerator, StopwatchNumerator);
check_slot!(env, stopwatch_denominator, StopwatchDenominator);
check_slot!(env, registers, Registers);
Expand Down
2 changes: 1 addition & 1 deletion src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ macro_rules! declare_builtin_function {
};
let config = vm.loader.get_config();
if config.enable_instruction_meter {
vm.context_object_pointer.consume(vm.previous_instruction_meter);
vm.context_object_pointer.consume(vm.previous_instruction_meter - vm.due_insn_count);
}
let converted_result: $crate::vm::ProgramResult = Self::rust(
vm.context_object_pointer, arg_a, arg_b, arg_c, arg_d, arg_e, &mut vm.memory_mapping,
Expand Down
14 changes: 9 additions & 5 deletions src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ pub struct EbpfVm<'a, C: ContextObject> {
pub context_object_pointer: &'a mut C,
/// Last return value of instruction_meter.get_remaining()
pub previous_instruction_meter: u64,
/// Outstanding value to instruction_meter.consume()
pub due_insn_count: u64,
/// CPU cycles accumulated by the stop watch
pub stopwatch_numerator: u64,
/// Number of times the stop watch was used
Expand Down Expand Up @@ -422,6 +424,7 @@ impl<'a, C: ContextObject> EbpfVm<'a, C> {
stack_pointer,
context_object_pointer: context_object,
previous_instruction_meter: 0,
due_insn_count: 0,
stopwatch_numerator: 0,
stopwatch_denominator: 0,
registers: [0u64; 12],
Expand Down Expand Up @@ -454,8 +457,9 @@ impl<'a, C: ContextObject> EbpfVm<'a, C> {
0
};
self.previous_instruction_meter = initial_insn_count;
self.due_insn_count = 0;
self.program_result = ProgramResult::Ok(0);
let due_insn_count = if interpreted {
if interpreted {
#[cfg(feature = "debugger")]
let debug_port = self.debug_port.clone();
let mut interpreter = Interpreter::new(self, executable, self.registers);
Expand All @@ -467,7 +471,6 @@ impl<'a, C: ContextObject> EbpfVm<'a, C> {
}
#[cfg(not(feature = "debugger"))]
while interpreter.step() {}
interpreter.due_insn_count
} else {
#[cfg(all(feature = "jit", not(target_os = "windows"), target_arch = "x86_64"))]
{
Expand All @@ -480,17 +483,18 @@ impl<'a, C: ContextObject> EbpfVm<'a, C> {
};
let instruction_meter_final =
compiled_program.invoke(config, self, self.registers).max(0) as u64;
self.context_object_pointer
self.due_insn_count = self
.context_object_pointer
.get_remaining()
.saturating_sub(instruction_meter_final)
.saturating_sub(instruction_meter_final);
}
#[cfg(not(all(feature = "jit", not(target_os = "windows"), target_arch = "x86_64")))]
{
return (0, ProgramResult::Err(EbpfError::JitNotCompiled));
}
};
let instruction_count = if config.enable_instruction_meter {
self.context_object_pointer.consume(due_insn_count);
self.context_object_pointer.consume(self.due_insn_count);
initial_insn_count.saturating_sub(self.context_object_pointer.get_remaining())
} else {
0
Expand Down

0 comments on commit 9b1d33f

Please sign in to comment.