diff --git a/chipsec/modules/tools/smm/smm_ptr.py b/chipsec/modules/tools/smm/smm_ptr.py index 4de62e1db7..288e72ba74 100644 --- a/chipsec/modules/tools/smm/smm_ptr.py +++ b/chipsec/modules/tools/smm/smm_ptr.py @@ -148,6 +148,9 @@ # be long-running OUTLIER_THRESHOLD = 33.3 +# Scan mode delay before retry +SCAN_MODE_RETRY_DELAY = 0.01 + # SMI count MSR MSR_SMI_COUNT = 0x00000034 @@ -262,7 +265,7 @@ def add(self, duration, 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()) @@ -277,8 +280,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 @@ -286,6 +288,23 @@ 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 @@ -487,6 +506,7 @@ def smi_fuzz_iter(self, thread_id, _addr, _smi_desc, fill_contents=True, restore # Re-do the call if it was identified as an outlier, due to periodic SMI delays # if scan.is_outlier(duration): + time.sleep(SCAN_MODE_RETRY_DELAY) while True: _, duration = 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.valid_smi_count(): diff --git a/drivers/linux/amd64/cpu.asm b/drivers/linux/amd64/cpu.asm index 3ca56364f8..8fe2832486 100644 --- a/drivers/linux/amd64/cpu.asm +++ b/drivers/linux/amd64/cpu.asm @@ -40,7 +40,6 @@ global __cpuid__ global __swsmi__ global __swsmi_timed__ - global __swsmi_timed_test__ section .text @@ -463,6 +462,8 @@ __swsmi_timed__: ror ax, 8 out 0B3h, al + wbinvd + mfence ; read time-stamp counter mov r9, rax mov r11, rdx diff --git a/drivers/linux/chipsec_km.c b/drivers/linux/chipsec_km.c index dd39a2afe9..ecf5f90645 100644 --- a/drivers/linux/chipsec_km.c +++ b/drivers/linux/chipsec_km.c @@ -1114,9 +1114,12 @@ static long d_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioc break; } + unsigned long flags; unsigned long m_time; preempt_disable(); + local_irq_save(flags); __swsmi_timed__((SMI_CTX *)ptr, &m_time); + local_irq_restore(flags); preempt_enable(); ptrbuf[numargs] = m_time;