Files
Nathaniel Mitchell e46b856359 Update test_cpu to match changes in cpu hal
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
2026-01-29 13:42:02 -08:00

361 lines
16 KiB
Python

# CHIPSEC: Platform Security Assessment Framework
# Copyright (c) 2023, Intel Corporation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; Version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Contact information:
# chipsec@intel.com
#
import unittest
from unittest.mock import patch, Mock, MagicMock, call
from chipsec.hal.intel.cpu import CPU
class TestHalCpu(unittest.TestCase):
def test_hal_cpu_init(self):
mock_cs = MagicMock()
dci = CPU(mock_cs)
self.assertIsInstance(dci, CPU)
def test_hal_cpu_read_cr(self):
mock_self = Mock()
test_value = 0x8086
mock_self.helper.read_cr.return_value = test_value
result = CPU.read_cr(mock_self, 0x0, 0x0)
self.assertEqual(result, test_value)
def test_hal_cpu_read_cr_cmd(self):
mock_self = Mock()
test_value = 0x8086
mock_self.helper.read_cr.return_value = test_value
CPU.read_cr(mock_self, 0x16, 0x4)
mock_self.helper.read_cr.assert_called_with(0x16, 0x4)
def test_hal_cpu_write_cr(self):
mock_self = Mock()
expected_result = 0x01
mock_self.helper.write_cr.return_value = expected_result
result = CPU.write_cr(mock_self, 0x0, 0x0, expected_result)
self.assertEqual(result, expected_result)
def test_hal_cpu_write_cr_cmd(self):
mock_self = Mock()
mock_self.helper.write_cr.return_value = 0x1
CPU.write_cr(mock_self, 0x32, 0x9, 0xAFAFAFAF)
mock_self.helper.write_cr.assert_called_with(0x32, 0x9, 0xAFAFAFAF)
def test_hal_cpu_write_cr_mock(self):
mock_self = Mock()
test_value = 0x1
mock_self.helper.write_cr.return_value = test_value
result = CPU.write_cr(mock_self, 0x0, 0x0, 0x0)
self.assertEqual(result, test_value)
def test_hal_cpuid(self):
mock_self = Mock()
expected_result = (0x80, 0x70, 0x60, 0x50)
mock_self.helper.cpuid.return_value = expected_result
result = CPU.cpuid(mock_self, 0x9, 0x4)
self.assertEqual(result, expected_result)
def test_hal_cpuid_cmd(self):
mock_self = Mock()
mock_self.helper.cpuid.return_value = (0x90, 0x80, 0x70, 0x60)
CPU.cpuid(mock_self, 0x4000, 0x9000)
mock_self.helper.cpuid.assert_called_with(0x4000, 0x9000)
def test_hal_cpu_check_vmm_vmm_none(self):
mock_self = Mock()
VMM_NONE = 0x0
expected_value = VMM_NONE
mock_self.cpuid.return_value = (0, 0x3100800, 0x7FFAFBFF, 0xBFEBFBFF)
result = CPU.check_vmm(mock_self)
self.assertEqual(result, expected_value)
def test_hal_cpu_check_vmm_cmd(self):
mock_self = Mock()
mock_self.cpuid.return_value = (0, 0x3100900, 0x7FFAFCFF, 0xBFEBFCFF)
CPU.check_vmm(mock_self)
mock_self.cpuid.assert_called_with(0x1, 0x0)
def test_hal_cpu_check_vmm_vmm_none_vmm(self):
mock_self = Mock()
VMM_NONE = 0x0
expected_value = VMM_NONE
mock_self.cpuid.side_effect = [(0, 0x3100800, 0x80000000, 0xBFEBFBFF),
(0, 0x566E6558, 0x666F736F, 0x4D4D566E)]
result = CPU.check_vmm(mock_self)
self.assertEqual(result, expected_value)
def test_hal_cpu_check_vmm_vmm_xen(self):
mock_self = Mock()
VMM_XEN = 0x1
expected_value = VMM_XEN
mock_self.cpuid.side_effect = [(0, 0x3100800, 0x80000000, 0xBFEBFBFF),
(0, 0x566E6558, 0x65584D4D, 0x4D4D566E)]
result = CPU.check_vmm(mock_self)
self.assertEqual(result, expected_value)
def test_hal_cpu_check_vmm_vmm_hyper_v(self):
from chipsec.library.cpu import VMM_HYPER_V
mock_self = Mock()
expected_value = VMM_HYPER_V
mock_self.cpuid.side_effect = [(0, 0x3100800, 0x80000000, 0xBFEBFBFF),
(0, 0x7263694D, 0x666F736F, 0x76482074)]
result = CPU.check_vmm(mock_self)
self.assertEqual(result, expected_value)
def test_hal_cpu_check_vmm_vmm_vmware(self):
mock_self = Mock()
VMM_VMWARE = 0x3
expected_value = VMM_VMWARE
mock_self.cpuid.side_effect = [(0, 0x3100800, 0x80000000, 0xBFEBFBFF),
(0, 0x61774D56, 0x4D566572, 0x65726177)]
result = CPU.check_vmm(mock_self)
self.assertEqual(result, expected_value)
def test_hal_cpu_check_vmm_vmm_kvm(self):
mock_self = Mock()
VMM_KVM = 0x4
expected_value = VMM_KVM
mock_self.cpuid.side_effect = [(0, 0x3100800, 0x80000000, 0xBFEBFBFF),
(0, 0x4B4D564B, 0x564B4D56, 0x0000004D)]
result = CPU.check_vmm(mock_self)
self.assertEqual(result, expected_value)
def test_hal_cpu_is_HT_active_false(self):
mock_self = Mock()
mock_self.get_number_logical_processor_per_core.return_value = 1
result = CPU.is_HT_active(mock_self)
self.assertFalse(result)
def test_hal_cpu_is_HT_active_true(self):
mock_self = Mock()
mock_self.get_number_logical_processor_per_core.return_value = 4
result = CPU.is_HT_active(mock_self)
self.assertTrue(result)
def test_hal_cpu_get_number_logical_processor_per_core_cmd(self):
mock_self = Mock()
mock_self.cpuid.return_value = (0x32, 0x16, 0x8, 0x4)
CPU.get_number_logical_processor_per_core(mock_self)
mock_self.cpuid.assert_called_with(0xb, 0x0)
def test_hal_cpu_get_number_logical_processor_per_core(self):
mock_self = Mock()
expected_value = 4
mock_self.cpuid.return_value = (0, expected_value, 0, 0)
result = CPU.get_number_logical_processor_per_core(mock_self)
self.assertEqual(result, expected_value)
def test_hal_cpu_get_number_logical_processor_per_package(self):
mock_self = Mock()
expected_value = 16
mock_self.cpuid.return_value = (0, expected_value, 0, 0)
result = CPU.get_number_logical_processor_per_package(mock_self)
self.assertEqual(result, expected_value)
def test_hal_cpu_get_number_logical_processor_per_package_cmd(self):
mock_self = Mock()
mock_self.cpuid.return_value = (0x8000000000000000, 0x7000000000000000, 0x6000000000000000, 0x5000000000000000)
CPU.get_number_logical_processor_per_package(mock_self)
mock_self.cpuid.assert_called_with(0xb, 0x1)
def test_hal_cpu_get_number_physical_processor_per_package(self):
mock_self = Mock()
core = 4
package = 16
expected_value = package // core
mock_self.get_number_logical_processor_per_core.return_value = core
mock_self.get_number_logical_processor_per_package.return_value = package
result = CPU.get_number_physical_processor_per_package(mock_self)
self.assertEqual(result, expected_value)
def test_hal_cpu_get_cpu_topology(self):
mock_cs = Mock()
mock_cs.helper.get_threads_count.return_value = 4
mock_cs.helper.cpuid.side_effect = [(4, 0, 0, 0),
(1, 0, 0, 0),
(4, 0, 0, 2),
(1, 0, 0, 2),
(4, 0, 0, 1),
(1, 0, 0, 1),
(4, 0, 0, 3),
(1, 0, 0, 3),
]
expected_result = {'cores': {0: [0, 2], 1: [1, 3]}, 'packages': {0: [0, 1, 2, 3]}, 'threads': 4}
cpu_hal = CPU(mock_cs)
result = cpu_hal.get_cpu_topology()
self.assertEqual(result, expected_result)
def test_hal_cpu_get_number_sockets_from_APIC_table(self):
mock_self = Mock()
mock_self.get_number_threads_from_APIC_table.return_value = 4
mock_self.get_number_logical_processor_per_package.return_value = 2
result = CPU.get_number_sockets_from_APIC_table(mock_self)
self.assertEqual(result, 2)
def test_hal_cpu_get_SMRR(self):
mock_self = Mock()
mock_self.cs.register.get_list_by_name().read_field.side_effect = [[0x88400000], [0xFFC00000]]
result = CPU.get_SMRR(mock_self)
self.assertEqual(result, (0x88400000, 0xFFC00000))
def test_hal_cpu_get_SMRR_cmd(self):
mock_self = Mock()
mock_self.cs.register.get_list_by_name().read_field.side_effect = [[0x88400000], [0xFFC00000]]
reg_call_1 = call('8086.MSR.IA32_SMRR_PHYSBASE')
reg_call_2 = call('8086.MSR.IA32_SMRR_PHYSMASK')
field_call_1 = call('PHYSBASE', True)
field_call_2 = call('PHYSMASK', True)
CPU.get_SMRR(mock_self)
self.assertEqual(mock_self.cs.register.get_list_by_name.call_args_list, [call(), reg_call_1, reg_call_2])
self.assertEqual(mock_self.cs.register.get_list_by_name().read_field.call_args_list, [field_call_1, field_call_2])
def test_hal_cpu_get_SMRR_SMRAM(self):
mock_self = Mock()
mock_self.get_SMRR.return_value = (0x88400000, 0xFFC00000)
expected_result = (0x88400000, 0x887FFFFF, 0x400000)
result = CPU.get_SMRR_SMRAM(mock_self)
self.assertEqual(result, expected_result)
def test_hal_cpu_get_TSEG_is_server_true_cmd(self):
mock_self = Mock()
reg_call_1 = call('8086.MEMMAP_VTD.TSEG_BASE')
reg_call_2 = call('8086.MEMMAP_VTD.TSEG_LIMIT')
field_call_1 = call('base', True)
field_call_2 = call('limit', True)
mock_self.cs.register.get_list_by_name().read_field.side_effect = [[0x88400000], [0x88700000]]
mock_self.cs.is_server.return_value = True
CPU.get_TSEG(mock_self)
self.assertEqual(mock_self.cs.register.get_list_by_name.call_args_list, [call(), reg_call_1, reg_call_2])
self.assertEqual(mock_self.cs.register.get_list_by_name().read_field.call_args_list, [field_call_1, field_call_2])
def test_hal_cpu_get_TSEG_is_server_true(self):
mock_self = Mock()
mock_self.cs.is_server.return_value = True
mock_self.cs.register.get_list_by_name().read_field.side_effect = [[0x88400000], [0x88700000]]
expected_result = (0x88400000, 0x887FFFFF, 0x400000)
result = CPU.get_TSEG(mock_self)
self.assertEqual(result, expected_result)
def test_hal_cpu_get_TSEG_is_server_false(self):
mock_self = Mock()
mock_self.cs.is_server.return_value = False
mock_self.cs.register.get_list_by_name().read_field.side_effect = [[0x88400000], [0x88800000]]
expected_result = (0x88400000, 0x887FFFFF, 0x400000)
result = CPU.get_TSEG(mock_self)
self.assertEqual(result, expected_result)
def test_hal_cpu_get_TSEG_is_server_false_cmd(self):
mock_self = Mock()
reg_call_1 = call('8086.HOSTCTL.TSEGMB')
reg_call_2 = call('8086.HOSTCTL.BGSM')
field_call_1 = call('TSEGMB', True)
field_call_2 = call('BGSM', True)
mock_self.cs.register.get_list_by_name().read_field.side_effect = [[0x88400000], [0x88800000]]
mock_self.cs.is_server.return_value = False
CPU.get_TSEG(mock_self)
self.assertEqual(mock_self.cs.register.get_list_by_name.call_args_list, [call(), reg_call_1, reg_call_2])
self.assertEqual(mock_self.cs.register.get_list_by_name().read_field.call_args_list, [field_call_1, field_call_2])
def test_hal_cpu_get_SMRAM_smrr_true(self):
mock_self = MagicMock()
mock_self.check_SMRR_supported.__bool__.return_value = True
expected_result = (0x88400000, 0x88400000, 0x400000)
mock_self.get_SMRR_SMRAM.return_value = expected_result
result = CPU.get_SMRAM(mock_self)
self.assertEqual(result, expected_result)
def test_hal_cpu_get_SMRAM_smrr_false(self):
mock_self = MagicMock()
mock_self.check_SMRR_supported.__bool__.return_value = False
expected_result = (0x88400000, 0x88400000, 0x400000)
mock_self.get_TSEG.return_value = expected_result
result = CPU.get_SMRAM(mock_self)
self.assertEqual(result, expected_result)
def test_hal_cpu_check_SMRR_supported_cmd2(self):
mock_self = Mock()
mock_self.cs.register.get_list_by_name().is_any_field_value.return_value = 0
CPU.check_SMRR_supported(mock_self)
mock_self.cs.register.get_list_by_name.assert_called_with('8086.MSR.MTRRCAP')
def test_hal_cpu_check_SMRR_supported_cmd(self):
mock_self = Mock()
CPU.check_SMRR_supported(mock_self)
mock_self.cs.register.get_list_by_name().is_any_field_value.assert_called_with(1, 'SMRR')
def test_hal_cpu_check_SMRR_supported_false(self):
mock_self = Mock()
mock_self.cs.register.get_list_by_name().is_any_field_value.return_value = 0
result = CPU.check_SMRR_supported(mock_self)
self.assertFalse(result)
def test_hal_cpu_check_SMRR_supported_true(self):
mock_self = Mock()
mock_self.cs.register.get_field.return_value = 1
result = CPU.check_SMRR_supported(mock_self)
self.assertTrue(result)
@patch('chipsec.hal.intel.cpu.logger', spec=True)
@patch('chipsec.hal.intel.cpu.paging', spec=True)
def test_hal_cpu_dump_page_tables_none(self, mock_paging, mock_logger):
mock_self = Mock()
mock_paging.c_ia32e_page_tables.return_value = Mock(failure=False)
mock_logger().log_error.return_value = Mock()
CPU.dump_page_tables(mock_self, 0x16B334001, None)
self.assertEqual(5, mock_logger.call_count)
@patch('chipsec.hal.intel.cpu.logger', spec=True)
@patch('chipsec.hal.intel.cpu.paging.c_ia32e_page_tables', spec=True)
def test_hal_cpu_dump_page_tables(self, mock_paging, mock_logger):
mock_self = Mock()
mock_paging.return_value = Mock(failure=False)
CPU.dump_page_tables(mock_self, 0x16B334001, 'cpu0_pt_16B334001')
self.assertEqual(4, mock_logger.call_count)
@patch('chipsec.hal.intel.cpu.logger', spec=True)
@patch('chipsec.hal.intel.cpu.paging.c_ia32e_page_tables', spec=True)
def test_hal_cpu_dump_page_tables_log_error(self, mock_paging, mock_logger):
mock_self = Mock()
mock_paging.return_value = Mock(failure=True)
CPU.dump_page_tables(mock_self, 0x16B334001, 'cpu0_pt_16B334001')
self.assertEqual(5, mock_logger.call_count)
def test_hal_cpu_dump_page_tables_all_1_thread(self):
mock_self = Mock()
threads = 1
mock_self.cs.hals.msr.get_cpu_thread_count.return_value = threads
mock_self.return_value.dump_page_tables.return_value = 1
mock_self.read_cr.side_effect = [0]
CPU.dump_page_tables_all(mock_self)
self.assertEqual(mock_self.dump_page_tables.call_count, threads)
def test_hal_cpu_dump_page_tables_all_4_threads(self):
mock_self = Mock()
threads = 4
mock_self.cs.hals.msr.get_cpu_thread_count.return_value = threads
mock_self.return_value.dump_page_tables.return_value = 1
mock_self.read_cr.side_effect = [0, 1, 2, 3]
CPU.dump_page_tables_all(mock_self)
self.assertEqual(mock_self.dump_page_tables.call_count, threads)
if __name__ == '__main__':
unittest.main()