162306a36Sopenharmony_ci#!/usr/bin/env python3 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci 462306a36Sopenharmony_cifrom struct import pack 562306a36Sopenharmony_cifrom time import sleep 662306a36Sopenharmony_ci 762306a36Sopenharmony_ciimport errno 862306a36Sopenharmony_ciimport glob 962306a36Sopenharmony_ciimport os 1062306a36Sopenharmony_ciimport subprocess 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_citry: 1362306a36Sopenharmony_ci import pytest 1462306a36Sopenharmony_ciexcept ImportError: 1562306a36Sopenharmony_ci print("Unable to import pytest python module.") 1662306a36Sopenharmony_ci print("\nIf not already installed, you may do so with:") 1762306a36Sopenharmony_ci print("\t\tpip3 install pytest") 1862306a36Sopenharmony_ci exit(1) 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ciSOCKETS = glob.glob('/sys/bus/auxiliary/devices/intel_vsec.sdsi.*') 2162306a36Sopenharmony_ciNUM_SOCKETS = len(SOCKETS) 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciMODULE_NAME = 'intel_sdsi' 2462306a36Sopenharmony_ciDEV_PREFIX = 'intel_vsec.sdsi' 2562306a36Sopenharmony_ciCLASS_DIR = '/sys/bus/auxiliary/devices' 2662306a36Sopenharmony_ciGUID = "0x6dd191" 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cidef read_bin_file(file): 2962306a36Sopenharmony_ci with open(file, mode='rb') as f: 3062306a36Sopenharmony_ci content = f.read() 3162306a36Sopenharmony_ci return content 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cidef get_dev_file_path(socket, file): 3462306a36Sopenharmony_ci return CLASS_DIR + '/' + DEV_PREFIX + '.' + str(socket) + '/' + file 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cidef kmemleak_enabled(): 3762306a36Sopenharmony_ci kmemleak = "/sys/kernel/debug/kmemleak" 3862306a36Sopenharmony_ci return os.path.isfile(kmemleak) 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciclass TestSDSiDriver: 4162306a36Sopenharmony_ci def test_driver_loaded(self): 4262306a36Sopenharmony_ci lsmod_p = subprocess.Popen(('lsmod'), stdout=subprocess.PIPE) 4362306a36Sopenharmony_ci result = subprocess.check_output(('grep', '-q', MODULE_NAME), stdin=lsmod_p.stdout) 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci@pytest.mark.parametrize('socket', range(0, NUM_SOCKETS)) 4662306a36Sopenharmony_ciclass TestSDSiFilesClass: 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci def read_value(self, file): 4962306a36Sopenharmony_ci f = open(file, "r") 5062306a36Sopenharmony_ci value = f.read().strip("\n") 5162306a36Sopenharmony_ci return value 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci def get_dev_folder(self, socket): 5462306a36Sopenharmony_ci return CLASS_DIR + '/' + DEV_PREFIX + '.' + str(socket) + '/' 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci def test_sysfs_files_exist(self, socket): 5762306a36Sopenharmony_ci folder = self.get_dev_folder(socket) 5862306a36Sopenharmony_ci print (folder) 5962306a36Sopenharmony_ci assert os.path.isfile(folder + "guid") == True 6062306a36Sopenharmony_ci assert os.path.isfile(folder + "provision_akc") == True 6162306a36Sopenharmony_ci assert os.path.isfile(folder + "provision_cap") == True 6262306a36Sopenharmony_ci assert os.path.isfile(folder + "state_certificate") == True 6362306a36Sopenharmony_ci assert os.path.isfile(folder + "registers") == True 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci def test_sysfs_file_permissions(self, socket): 6662306a36Sopenharmony_ci folder = self.get_dev_folder(socket) 6762306a36Sopenharmony_ci mode = os.stat(folder + "guid").st_mode & 0o777 6862306a36Sopenharmony_ci assert mode == 0o444 # Read all 6962306a36Sopenharmony_ci mode = os.stat(folder + "registers").st_mode & 0o777 7062306a36Sopenharmony_ci assert mode == 0o400 # Read owner 7162306a36Sopenharmony_ci mode = os.stat(folder + "provision_akc").st_mode & 0o777 7262306a36Sopenharmony_ci assert mode == 0o200 # Read owner 7362306a36Sopenharmony_ci mode = os.stat(folder + "provision_cap").st_mode & 0o777 7462306a36Sopenharmony_ci assert mode == 0o200 # Read owner 7562306a36Sopenharmony_ci mode = os.stat(folder + "state_certificate").st_mode & 0o777 7662306a36Sopenharmony_ci assert mode == 0o400 # Read owner 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci def test_sysfs_file_ownership(self, socket): 7962306a36Sopenharmony_ci folder = self.get_dev_folder(socket) 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci st = os.stat(folder + "guid") 8262306a36Sopenharmony_ci assert st.st_uid == 0 8362306a36Sopenharmony_ci assert st.st_gid == 0 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci st = os.stat(folder + "registers") 8662306a36Sopenharmony_ci assert st.st_uid == 0 8762306a36Sopenharmony_ci assert st.st_gid == 0 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci st = os.stat(folder + "provision_akc") 9062306a36Sopenharmony_ci assert st.st_uid == 0 9162306a36Sopenharmony_ci assert st.st_gid == 0 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci st = os.stat(folder + "provision_cap") 9462306a36Sopenharmony_ci assert st.st_uid == 0 9562306a36Sopenharmony_ci assert st.st_gid == 0 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci st = os.stat(folder + "state_certificate") 9862306a36Sopenharmony_ci assert st.st_uid == 0 9962306a36Sopenharmony_ci assert st.st_gid == 0 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci def test_sysfs_file_sizes(self, socket): 10262306a36Sopenharmony_ci folder = self.get_dev_folder(socket) 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci if self.read_value(folder + "guid") == GUID: 10562306a36Sopenharmony_ci st = os.stat(folder + "registers") 10662306a36Sopenharmony_ci assert st.st_size == 72 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci st = os.stat(folder + "provision_akc") 10962306a36Sopenharmony_ci assert st.st_size == 1024 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci st = os.stat(folder + "provision_cap") 11262306a36Sopenharmony_ci assert st.st_size == 1024 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci st = os.stat(folder + "state_certificate") 11562306a36Sopenharmony_ci assert st.st_size == 4096 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci def test_no_seek_allowed(self, socket): 11862306a36Sopenharmony_ci folder = self.get_dev_folder(socket) 11962306a36Sopenharmony_ci rand_file = bytes(os.urandom(8)) 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci f = open(folder + "provision_cap", "wb", 0) 12262306a36Sopenharmony_ci f.seek(1) 12362306a36Sopenharmony_ci with pytest.raises(OSError) as error: 12462306a36Sopenharmony_ci f.write(rand_file) 12562306a36Sopenharmony_ci assert error.value.errno == errno.ESPIPE 12662306a36Sopenharmony_ci f.close() 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci f = open(folder + "provision_akc", "wb", 0) 12962306a36Sopenharmony_ci f.seek(1) 13062306a36Sopenharmony_ci with pytest.raises(OSError) as error: 13162306a36Sopenharmony_ci f.write(rand_file) 13262306a36Sopenharmony_ci assert error.value.errno == errno.ESPIPE 13362306a36Sopenharmony_ci f.close() 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci def test_registers_seek(self, socket): 13662306a36Sopenharmony_ci folder = self.get_dev_folder(socket) 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci # Check that the value read from an offset of the entire 13962306a36Sopenharmony_ci # file is none-zero and the same as the value read 14062306a36Sopenharmony_ci # from seeking to the same location 14162306a36Sopenharmony_ci f = open(folder + "registers", "rb") 14262306a36Sopenharmony_ci data = f.read() 14362306a36Sopenharmony_ci f.seek(64) 14462306a36Sopenharmony_ci id = f.read() 14562306a36Sopenharmony_ci assert id != bytes(0) 14662306a36Sopenharmony_ci assert data[64:] == id 14762306a36Sopenharmony_ci f.close() 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci@pytest.mark.parametrize('socket', range(0, NUM_SOCKETS)) 15062306a36Sopenharmony_ciclass TestSDSiMailboxCmdsClass: 15162306a36Sopenharmony_ci def test_provision_akc_eoverflow_1017_bytes(self, socket): 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci # The buffer for writes is 1k, of with 8 bytes must be 15462306a36Sopenharmony_ci # reserved for the command, leaving 1016 bytes max. 15562306a36Sopenharmony_ci # Check that we get an overflow error for 1017 bytes. 15662306a36Sopenharmony_ci node = get_dev_file_path(socket, "provision_akc") 15762306a36Sopenharmony_ci rand_file = bytes(os.urandom(1017)) 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci f = open(node, 'wb', 0) 16062306a36Sopenharmony_ci with pytest.raises(OSError) as error: 16162306a36Sopenharmony_ci f.write(rand_file) 16262306a36Sopenharmony_ci assert error.value.errno == errno.EOVERFLOW 16362306a36Sopenharmony_ci f.close() 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci@pytest.mark.parametrize('socket', range(0, NUM_SOCKETS)) 16662306a36Sopenharmony_ciclass TestSdsiDriverLocksClass: 16762306a36Sopenharmony_ci def test_enodev_when_pci_device_removed(self, socket): 16862306a36Sopenharmony_ci node = get_dev_file_path(socket, "provision_akc") 16962306a36Sopenharmony_ci dev_name = DEV_PREFIX + '.' + str(socket) 17062306a36Sopenharmony_ci driver_dir = CLASS_DIR + '/' + dev_name + "/driver/" 17162306a36Sopenharmony_ci rand_file = bytes(os.urandom(8)) 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci f = open(node, 'wb', 0) 17462306a36Sopenharmony_ci g = open(node, 'wb', 0) 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci with open(driver_dir + 'unbind', 'w') as k: 17762306a36Sopenharmony_ci print(dev_name, file = k) 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci with pytest.raises(OSError) as error: 18062306a36Sopenharmony_ci f.write(rand_file) 18162306a36Sopenharmony_ci assert error.value.errno == errno.ENODEV 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci with pytest.raises(OSError) as error: 18462306a36Sopenharmony_ci g.write(rand_file) 18562306a36Sopenharmony_ci assert error.value.errno == errno.ENODEV 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci f.close() 18862306a36Sopenharmony_ci g.close() 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci # Short wait needed to allow file to close before pulling driver 19162306a36Sopenharmony_ci sleep(1) 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci p = subprocess.Popen(('modprobe', '-r', 'intel_sdsi')) 19462306a36Sopenharmony_ci p.wait() 19562306a36Sopenharmony_ci p = subprocess.Popen(('modprobe', '-r', 'intel_vsec')) 19662306a36Sopenharmony_ci p.wait() 19762306a36Sopenharmony_ci p = subprocess.Popen(('modprobe', 'intel_vsec')) 19862306a36Sopenharmony_ci p.wait() 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci # Short wait needed to allow driver time to get inserted 20162306a36Sopenharmony_ci # before continuing tests 20262306a36Sopenharmony_ci sleep(1) 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci def test_memory_leak(self, socket): 20562306a36Sopenharmony_ci if not kmemleak_enabled(): 20662306a36Sopenharmony_ci pytest.skip("kmemleak not enabled in kernel") 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci dev_name = DEV_PREFIX + '.' + str(socket) 20962306a36Sopenharmony_ci driver_dir = CLASS_DIR + '/' + dev_name + "/driver/" 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci with open(driver_dir + 'unbind', 'w') as k: 21262306a36Sopenharmony_ci print(dev_name, file = k) 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci sleep(1) 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci subprocess.check_output(('modprobe', '-r', 'intel_sdsi')) 21762306a36Sopenharmony_ci subprocess.check_output(('modprobe', '-r', 'intel_vsec')) 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci with open('/sys/kernel/debug/kmemleak', 'w') as f: 22062306a36Sopenharmony_ci print('scan', file = f) 22162306a36Sopenharmony_ci sleep(5) 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci assert os.stat('/sys/kernel/debug/kmemleak').st_size == 0 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci subprocess.check_output(('modprobe', 'intel_vsec')) 22662306a36Sopenharmony_ci sleep(1) 227