227 lines · python
1#!/usr/bin/env python32# SPDX-License-Identifier: GPL-2.03 4from struct import pack5from time import sleep6 7import errno8import glob9import os10import subprocess11 12try:13 import pytest14except ImportError:15 print("Unable to import pytest python module.")16 print("\nIf not already installed, you may do so with:")17 print("\t\tpip3 install pytest")18 exit(1)19 20SOCKETS = glob.glob('/sys/bus/auxiliary/devices/intel_vsec.sdsi.*')21NUM_SOCKETS = len(SOCKETS)22 23MODULE_NAME = 'intel_sdsi'24DEV_PREFIX = 'intel_vsec.sdsi'25CLASS_DIR = '/sys/bus/auxiliary/devices'26GUID = "0x6dd191"27 28def read_bin_file(file):29 with open(file, mode='rb') as f:30 content = f.read()31 return content32 33def get_dev_file_path(socket, file):34 return CLASS_DIR + '/' + DEV_PREFIX + '.' + str(socket) + '/' + file35 36def kmemleak_enabled():37 kmemleak = "/sys/kernel/debug/kmemleak"38 return os.path.isfile(kmemleak)39 40class TestSDSiDriver:41 def test_driver_loaded(self):42 lsmod_p = subprocess.Popen(('lsmod'), stdout=subprocess.PIPE)43 result = subprocess.check_output(('grep', '-q', MODULE_NAME), stdin=lsmod_p.stdout)44 45@pytest.mark.parametrize('socket', range(0, NUM_SOCKETS))46class TestSDSiFilesClass:47 48 def read_value(self, file):49 f = open(file, "r")50 value = f.read().strip("\n")51 return value52 53 def get_dev_folder(self, socket):54 return CLASS_DIR + '/' + DEV_PREFIX + '.' + str(socket) + '/'55 56 def test_sysfs_files_exist(self, socket):57 folder = self.get_dev_folder(socket)58 print (folder)59 assert os.path.isfile(folder + "guid") == True60 assert os.path.isfile(folder + "provision_akc") == True61 assert os.path.isfile(folder + "provision_cap") == True62 assert os.path.isfile(folder + "state_certificate") == True63 assert os.path.isfile(folder + "registers") == True64 65 def test_sysfs_file_permissions(self, socket):66 folder = self.get_dev_folder(socket)67 mode = os.stat(folder + "guid").st_mode & 0o77768 assert mode == 0o444 # Read all69 mode = os.stat(folder + "registers").st_mode & 0o77770 assert mode == 0o400 # Read owner71 mode = os.stat(folder + "provision_akc").st_mode & 0o77772 assert mode == 0o200 # Read owner73 mode = os.stat(folder + "provision_cap").st_mode & 0o77774 assert mode == 0o200 # Read owner75 mode = os.stat(folder + "state_certificate").st_mode & 0o77776 assert mode == 0o400 # Read owner77 78 def test_sysfs_file_ownership(self, socket):79 folder = self.get_dev_folder(socket)80 81 st = os.stat(folder + "guid")82 assert st.st_uid == 083 assert st.st_gid == 084 85 st = os.stat(folder + "registers")86 assert st.st_uid == 087 assert st.st_gid == 088 89 st = os.stat(folder + "provision_akc")90 assert st.st_uid == 091 assert st.st_gid == 092 93 st = os.stat(folder + "provision_cap")94 assert st.st_uid == 095 assert st.st_gid == 096 97 st = os.stat(folder + "state_certificate")98 assert st.st_uid == 099 assert st.st_gid == 0100 101 def test_sysfs_file_sizes(self, socket):102 folder = self.get_dev_folder(socket)103 104 if self.read_value(folder + "guid") == GUID:105 st = os.stat(folder + "registers")106 assert st.st_size == 72107 108 st = os.stat(folder + "provision_akc")109 assert st.st_size == 1024110 111 st = os.stat(folder + "provision_cap")112 assert st.st_size == 1024113 114 st = os.stat(folder + "state_certificate")115 assert st.st_size == 4096116 117 def test_no_seek_allowed(self, socket):118 folder = self.get_dev_folder(socket)119 rand_file = bytes(os.urandom(8))120 121 f = open(folder + "provision_cap", "wb", 0)122 f.seek(1)123 with pytest.raises(OSError) as error:124 f.write(rand_file)125 assert error.value.errno == errno.ESPIPE126 f.close()127 128 f = open(folder + "provision_akc", "wb", 0)129 f.seek(1)130 with pytest.raises(OSError) as error:131 f.write(rand_file)132 assert error.value.errno == errno.ESPIPE133 f.close()134 135 def test_registers_seek(self, socket):136 folder = self.get_dev_folder(socket)137 138 # Check that the value read from an offset of the entire139 # file is none-zero and the same as the value read140 # from seeking to the same location141 f = open(folder + "registers", "rb")142 data = f.read()143 f.seek(64)144 id = f.read()145 assert id != bytes(0)146 assert data[64:] == id147 f.close()148 149@pytest.mark.parametrize('socket', range(0, NUM_SOCKETS))150class TestSDSiMailboxCmdsClass:151 def test_provision_akc_eoverflow_1017_bytes(self, socket):152 153 # The buffer for writes is 1k, of with 8 bytes must be154 # reserved for the command, leaving 1016 bytes max.155 # Check that we get an overflow error for 1017 bytes.156 node = get_dev_file_path(socket, "provision_akc")157 rand_file = bytes(os.urandom(1017))158 159 f = open(node, 'wb', 0)160 with pytest.raises(OSError) as error:161 f.write(rand_file)162 assert error.value.errno == errno.EOVERFLOW163 f.close()164 165@pytest.mark.parametrize('socket', range(0, NUM_SOCKETS))166class TestSdsiDriverLocksClass:167 def test_enodev_when_pci_device_removed(self, socket):168 node = get_dev_file_path(socket, "provision_akc")169 dev_name = DEV_PREFIX + '.' + str(socket)170 driver_dir = CLASS_DIR + '/' + dev_name + "/driver/"171 rand_file = bytes(os.urandom(8))172 173 f = open(node, 'wb', 0)174 g = open(node, 'wb', 0)175 176 with open(driver_dir + 'unbind', 'w') as k:177 print(dev_name, file = k)178 179 with pytest.raises(OSError) as error:180 f.write(rand_file)181 assert error.value.errno == errno.ENODEV182 183 with pytest.raises(OSError) as error:184 g.write(rand_file)185 assert error.value.errno == errno.ENODEV186 187 f.close()188 g.close()189 190 # Short wait needed to allow file to close before pulling driver191 sleep(1)192 193 p = subprocess.Popen(('modprobe', '-r', 'intel_sdsi'))194 p.wait()195 p = subprocess.Popen(('modprobe', '-r', 'intel_vsec'))196 p.wait()197 p = subprocess.Popen(('modprobe', 'intel_vsec'))198 p.wait()199 200 # Short wait needed to allow driver time to get inserted201 # before continuing tests202 sleep(1)203 204 def test_memory_leak(self, socket):205 if not kmemleak_enabled():206 pytest.skip("kmemleak not enabled in kernel")207 208 dev_name = DEV_PREFIX + '.' + str(socket)209 driver_dir = CLASS_DIR + '/' + dev_name + "/driver/"210 211 with open(driver_dir + 'unbind', 'w') as k:212 print(dev_name, file = k)213 214 sleep(1)215 216 subprocess.check_output(('modprobe', '-r', 'intel_sdsi'))217 subprocess.check_output(('modprobe', '-r', 'intel_vsec'))218 219 with open('/sys/kernel/debug/kmemleak', 'w') as f:220 print('scan', file = f)221 sleep(5)222 223 assert os.stat('/sys/kernel/debug/kmemleak').st_size == 0224 225 subprocess.check_output(('modprobe', 'intel_vsec'))226 sleep(1)227