Skip to content

Commit

Permalink
Debugging system noise
Browse files Browse the repository at this point in the history
  • Loading branch information
cpey committed Oct 16, 2024
1 parent e4589b3 commit 1b469c1
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 14 deletions.
44 changes: 31 additions & 13 deletions chipsec/modules/tools/smm/smm_ptr.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
# Fuzz RCX as SMI subfunctions: from 0 to MAX_SMI_FUNCTIONS
# False - better performance, True - smarter fuzzing
FUZZ_SMI_FUNCTIONS_IN_ECX = True
MAX_SMI_FUNCTIONS = 0x10
MAX_SMI_FUNCTIONS = 0x100

# Max value of the value written to SMI data port (0xB3)
MAX_SMI_DATA = 0x100
Expand All @@ -146,10 +146,10 @@

# Defines the time percentage increase at which the SMI call is considered to
# be long-running
OUTLIER_THRESHOLD = 33.3
OUTLIER_THRESHOLD = 10

# Scan mode delay before SMI calls
SCAN_MODE_DELAY = 0
SCAN_MODE_DELAY = 0.01

# MSR numbers
MSR_SMI_COUNT = 0x00000034
Expand Down Expand Up @@ -257,7 +257,7 @@ def add(self, duration, time, code, data, gprs, confirmed=False):
self.max.update(duration, code, data, gprs.copy())
elif duration < self.min.duration:
self.min.update(duration, code, data, gprs.copy())
else:
elif self.is_slow_outlier(duration):
self.outliers += 1
self.outliers_hist += 1
self.outlier.update(duration, code, data, gprs.copy())
Expand All @@ -272,18 +272,34 @@ def avg(self):
self.acc_smi_duration = 0
self.acc_smi_num = 0

def is_outlier(self, value):
self.avg()
def is_slow_outlier(self, value):
ret = False
if self.avg_smi_duration and value > self.avg_smi_duration * (1 + OUTLIER_THRESHOLD / 100):
ret = True
if self.hist_smi_duration and value > self.hist_smi_duration * (1 + OUTLIER_THRESHOLD / 100):
ret = True
return ret

def is_fast_outlier(self, value):
ret = False
if self.avg_smi_duration and value < self.avg_smi_duration * (1 - OUTLIER_THRESHOLD / 100):
ret = True
if self.hist_smi_duration and value < self.hist_smi_duration * (1 - OUTLIER_THRESHOLD / 100):
ret = True
return ret

def is_outlier(self, value):
self.avg()
ret = False
if self.is_slow_outlier(value):
ret = True
if self.is_fast_outlier(value):
ret = True
return ret

def skip(self):
return self.outliers or self.confirmed
#return False
#return self.outliers or self.confirmed
return False

def found_outlier(self):
return bool(self.outliers)
Expand Down Expand Up @@ -478,7 +494,7 @@ def smi_fuzz_iter(self, thread_id, _addr, _smi_desc, fill_contents=True, restore
self.send_smi(thread_id, _smi_desc.smi_code, _smi_desc.smi_data, _smi_desc.name, _smi_desc.desc, _rax, _rbx, _rcx, _rdx, _rsi, _rdi)
else:
while True:
time.sleep(SCAN_MODE_DELAY)
#time.sleep(SCAN_MODE_DELAY)
_, duration, start = self.send_smi_timed(thread_id, _smi_desc.smi_code, _smi_desc.smi_data, _smi_desc.name, _smi_desc.desc, _rax, _rbx, _rcx, _rdx, _rsi, _rdi)
if scan.check_inc_msr():
break
Expand All @@ -487,8 +503,10 @@ def smi_fuzz_iter(self, thread_id, _addr, _smi_desc, fill_contents=True, restore
#
if scan.is_outlier(duration):
while True:
#print("Retrying...")
time.sleep(SCAN_MODE_DELAY)
_, duration, start = self.send_smi_timed(thread_id, _smi_desc.smi_code, _smi_desc.smi_data, _smi_desc.name, _smi_desc.desc, _rax, _rbx, _rcx, _rdx, _rsi, _rdi)
#print(duration)
if scan.check_inc_msr():
break
#
Expand Down Expand Up @@ -589,14 +607,14 @@ def test_fuzz(self, thread_id, smic_start, smic_end, _addr, _addr1, scan_mode=Fa
for smi_code in range(smic_start, smic_end + 1, 1):
_smi_desc.smi_code = smi_code
for smi_data in range(MAX_SMI_DATA):
_smi_desc.smi_data = smi_data
#_smi_desc.smi_data = 0x00
#_smi_desc.smi_data = smi_data
_smi_desc.smi_data = 0x00
self.logger.log(f'\n[*] Fuzzing SMI# 0x{smi_code:02X} (data: 0x{smi_data:02X})')
if FUZZ_SMI_FUNCTIONS_IN_ECX:
for _rcx in range(MAX_SMI_FUNCTIONS):
self.logger.log(f' >> Function (RCX): 0x{_rcx:016X}')
_smi_desc.gprs['rcx'] = _rcx
#_smi_desc.gprs['rcx'] = 0x00
#_smi_desc.gprs['rcx'] = _rcx
_smi_desc.gprs['rcx'] = 0x00
if PTR_IN_ALL_GPRS or scan_mode:
if self.smi_fuzz_iter(thread_id, _addr, _smi_desc, False, True, scan):
bad_ptr_cnt += 1
Expand Down
13 changes: 12 additions & 1 deletion drivers/linux/amd64/cpu.asm
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ __swsmi_timed__:
mov r10, rdi
push r12 ; callee-saved register
push r13 ; callee-saved register
; push r14 ; callee-saved register
mov r12, rsi
mov r13, rdx

Expand All @@ -465,23 +466,32 @@ __swsmi_timed__:
ror ax, 8
out 0B3h, al

wbinvd
mfence
; mov r14, 0x1000
;warmup_loop:
; add eax, 0
; dec r14
; jnz warmup_loop
; read time-stamp counter
mov r9, rax
mov r11, rdx
; lfence
rdtsc
shl rdx, 32
or rax, rdx
mov r8, rax
mov rax, r9
mov rdx, r11

; trigger SMI
ror ax, 8
out 0B2h, al

; measure SMI execution time
; wbinvd
mov r9, rax
mov r11, rdx
; lfence
rdtsc
shl rdx, 32
or rax, rdx
Expand All @@ -499,6 +509,7 @@ __swsmi_timed__:
xchg rsi, [r10+028h] ; rsi_value
xchg rdi, [r10+030h] ; rdi_value

; pop r14
pop r13
pop r12
ret
Expand Down
3 changes: 3 additions & 0 deletions drivers/linux/chipsec_km.c
Original file line number Diff line number Diff line change
Expand Up @@ -1125,9 +1125,12 @@ static long d_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioc

unsigned long i_time;
unsigned long m_time;
unsigned long flags;
preempt_disable();
local_irq_save(flags);
__swsmi_timed__((SMI_CTX *)ptr, &m_time, &i_time);
//__swsmi_timed_test__((SMI_CTX *)ptr, &m_time, &i_time);
local_irq_restore(flags);
preempt_enable();
ptrbuf[numargs] = m_time;
ptrbuf[numargs + 1] = i_time;
Expand Down

0 comments on commit 1b469c1

Please sign in to comment.