From 1b469c19f41724f4e9028f3fd0fd432c420a41d8 Mon Sep 17 00:00:00 2001 From: Carles Pey Date: Wed, 16 Oct 2024 11:35:40 -0400 Subject: [PATCH] Debugging system noise --- chipsec/modules/tools/smm/smm_ptr.py | 44 ++++++++++++++++++++-------- drivers/linux/amd64/cpu.asm | 13 +++++++- drivers/linux/chipsec_km.c | 3 ++ 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/chipsec/modules/tools/smm/smm_ptr.py b/chipsec/modules/tools/smm/smm_ptr.py index ceaf7ceae6..fad7efa595 100644 --- a/chipsec/modules/tools/smm/smm_ptr.py +++ b/chipsec/modules/tools/smm/smm_ptr.py @@ -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 @@ -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 @@ -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()) @@ -272,8 +272,7 @@ 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 @@ -281,9 +280,26 @@ def is_outlier(self, value): 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) @@ -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 @@ -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 # @@ -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 diff --git a/drivers/linux/amd64/cpu.asm b/drivers/linux/amd64/cpu.asm index 31d33691fb..53c8e94676 100644 --- a/drivers/linux/amd64/cpu.asm +++ b/drivers/linux/amd64/cpu.asm @@ -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 @@ -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 @@ -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 diff --git a/drivers/linux/chipsec_km.c b/drivers/linux/chipsec_km.c index d594cb715b..c2cc5e64ec 100644 --- a/drivers/linux/chipsec_km.c +++ b/drivers/linux/chipsec_km.c @@ -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;