1 #!/usr/bin/env python3 1 #!/usr/bin/env python3 2 # SPDX-License-Identifier: GPL-2.0 2 # SPDX-License-Identifier: GPL-2.0 3 3 4 from struct import pack 4 from struct import pack 5 from time import sleep 5 from time import sleep 6 6 7 import errno 7 import errno 8 import glob 8 import glob 9 import os 9 import os 10 import subprocess 10 import subprocess 11 11 12 try: 12 try: 13 import pytest 13 import pytest 14 except ImportError: 14 except ImportError: 15 print("Unable to import pytest python modu 15 print("Unable to import pytest python module.") 16 print("\nIf not already installed, you may 16 print("\nIf not already installed, you may do so with:") 17 print("\t\tpip3 install pytest") 17 print("\t\tpip3 install pytest") 18 exit(1) 18 exit(1) 19 19 20 SOCKETS = glob.glob('/sys/bus/auxiliary/device 20 SOCKETS = glob.glob('/sys/bus/auxiliary/devices/intel_vsec.sdsi.*') 21 NUM_SOCKETS = len(SOCKETS) 21 NUM_SOCKETS = len(SOCKETS) 22 22 23 MODULE_NAME = 'intel_sdsi' 23 MODULE_NAME = 'intel_sdsi' 24 DEV_PREFIX = 'intel_vsec.sdsi' 24 DEV_PREFIX = 'intel_vsec.sdsi' 25 CLASS_DIR = '/sys/bus/auxiliary/devices' 25 CLASS_DIR = '/sys/bus/auxiliary/devices' 26 GUID = "0x6dd191" 26 GUID = "0x6dd191" 27 27 28 def read_bin_file(file): 28 def read_bin_file(file): 29 with open(file, mode='rb') as f: 29 with open(file, mode='rb') as f: 30 content = f.read() 30 content = f.read() 31 return content 31 return content 32 32 33 def get_dev_file_path(socket, file): 33 def get_dev_file_path(socket, file): 34 return CLASS_DIR + '/' + DEV_PREFIX + '.' 34 return CLASS_DIR + '/' + DEV_PREFIX + '.' + str(socket) + '/' + file 35 35 36 def kmemleak_enabled(): 36 def kmemleak_enabled(): 37 kmemleak = "/sys/kernel/debug/kmemleak" 37 kmemleak = "/sys/kernel/debug/kmemleak" 38 return os.path.isfile(kmemleak) 38 return os.path.isfile(kmemleak) 39 39 40 class TestSDSiDriver: 40 class TestSDSiDriver: 41 def test_driver_loaded(self): 41 def test_driver_loaded(self): 42 lsmod_p = subprocess.Popen(('lsmod'), 42 lsmod_p = subprocess.Popen(('lsmod'), stdout=subprocess.PIPE) 43 result = subprocess.check_output(('gre 43 result = subprocess.check_output(('grep', '-q', MODULE_NAME), stdin=lsmod_p.stdout) 44 44 45 @pytest.mark.parametrize('socket', range(0, NU 45 @pytest.mark.parametrize('socket', range(0, NUM_SOCKETS)) 46 class TestSDSiFilesClass: 46 class TestSDSiFilesClass: 47 47 48 def read_value(self, file): 48 def read_value(self, file): 49 f = open(file, "r") 49 f = open(file, "r") 50 value = f.read().strip("\n") 50 value = f.read().strip("\n") 51 return value 51 return value 52 52 53 def get_dev_folder(self, socket): 53 def get_dev_folder(self, socket): 54 return CLASS_DIR + '/' + DEV_PREFIX + 54 return CLASS_DIR + '/' + DEV_PREFIX + '.' + str(socket) + '/' 55 55 56 def test_sysfs_files_exist(self, socket): 56 def test_sysfs_files_exist(self, socket): 57 folder = self.get_dev_folder(socket) 57 folder = self.get_dev_folder(socket) 58 print (folder) 58 print (folder) 59 assert os.path.isfile(folder + "guid") 59 assert os.path.isfile(folder + "guid") == True 60 assert os.path.isfile(folder + "provis 60 assert os.path.isfile(folder + "provision_akc") == True 61 assert os.path.isfile(folder + "provis 61 assert os.path.isfile(folder + "provision_cap") == True 62 assert os.path.isfile(folder + "state_ 62 assert os.path.isfile(folder + "state_certificate") == True 63 assert os.path.isfile(folder + "regist 63 assert os.path.isfile(folder + "registers") == True 64 64 65 def test_sysfs_file_permissions(self, sock 65 def test_sysfs_file_permissions(self, socket): 66 folder = self.get_dev_folder(socket) 66 folder = self.get_dev_folder(socket) 67 mode = os.stat(folder + "guid").st_mod 67 mode = os.stat(folder + "guid").st_mode & 0o777 68 assert mode == 0o444 # Read all 68 assert mode == 0o444 # Read all 69 mode = os.stat(folder + "registers").s 69 mode = os.stat(folder + "registers").st_mode & 0o777 70 assert mode == 0o400 # Read owner 70 assert mode == 0o400 # Read owner 71 mode = os.stat(folder + "provision_akc 71 mode = os.stat(folder + "provision_akc").st_mode & 0o777 72 assert mode == 0o200 # Read owner 72 assert mode == 0o200 # Read owner 73 mode = os.stat(folder + "provision_cap 73 mode = os.stat(folder + "provision_cap").st_mode & 0o777 74 assert mode == 0o200 # Read owner 74 assert mode == 0o200 # Read owner 75 mode = os.stat(folder + "state_certifi 75 mode = os.stat(folder + "state_certificate").st_mode & 0o777 76 assert mode == 0o400 # Read owner 76 assert mode == 0o400 # Read owner 77 77 78 def test_sysfs_file_ownership(self, socket 78 def test_sysfs_file_ownership(self, socket): 79 folder = self.get_dev_folder(socket) 79 folder = self.get_dev_folder(socket) 80 80 81 st = os.stat(folder + "guid") 81 st = os.stat(folder + "guid") 82 assert st.st_uid == 0 82 assert st.st_uid == 0 83 assert st.st_gid == 0 83 assert st.st_gid == 0 84 84 85 st = os.stat(folder + "registers") 85 st = os.stat(folder + "registers") 86 assert st.st_uid == 0 86 assert st.st_uid == 0 87 assert st.st_gid == 0 87 assert st.st_gid == 0 88 88 89 st = os.stat(folder + "provision_akc") 89 st = os.stat(folder + "provision_akc") 90 assert st.st_uid == 0 90 assert st.st_uid == 0 91 assert st.st_gid == 0 91 assert st.st_gid == 0 92 92 93 st = os.stat(folder + "provision_cap") 93 st = os.stat(folder + "provision_cap") 94 assert st.st_uid == 0 94 assert st.st_uid == 0 95 assert st.st_gid == 0 95 assert st.st_gid == 0 96 96 97 st = os.stat(folder + "state_certifica 97 st = os.stat(folder + "state_certificate") 98 assert st.st_uid == 0 98 assert st.st_uid == 0 99 assert st.st_gid == 0 99 assert st.st_gid == 0 100 100 101 def test_sysfs_file_sizes(self, socket): 101 def test_sysfs_file_sizes(self, socket): 102 folder = self.get_dev_folder(socket) 102 folder = self.get_dev_folder(socket) 103 103 104 if self.read_value(folder + "guid") == 104 if self.read_value(folder + "guid") == GUID: 105 st = os.stat(folder + "registers") 105 st = os.stat(folder + "registers") 106 assert st.st_size == 72 106 assert st.st_size == 72 107 107 108 st = os.stat(folder + "provision_akc") 108 st = os.stat(folder + "provision_akc") 109 assert st.st_size == 1024 109 assert st.st_size == 1024 110 110 111 st = os.stat(folder + "provision_cap") 111 st = os.stat(folder + "provision_cap") 112 assert st.st_size == 1024 112 assert st.st_size == 1024 113 113 114 st = os.stat(folder + "state_certifica 114 st = os.stat(folder + "state_certificate") 115 assert st.st_size == 4096 115 assert st.st_size == 4096 116 116 117 def test_no_seek_allowed(self, socket): 117 def test_no_seek_allowed(self, socket): 118 folder = self.get_dev_folder(socket) 118 folder = self.get_dev_folder(socket) 119 rand_file = bytes(os.urandom(8)) 119 rand_file = bytes(os.urandom(8)) 120 120 121 f = open(folder + "provision_cap", "wb 121 f = open(folder + "provision_cap", "wb", 0) 122 f.seek(1) 122 f.seek(1) 123 with pytest.raises(OSError) as error: 123 with pytest.raises(OSError) as error: 124 f.write(rand_file) 124 f.write(rand_file) 125 assert error.value.errno == errno.ESPI 125 assert error.value.errno == errno.ESPIPE 126 f.close() 126 f.close() 127 127 128 f = open(folder + "provision_akc", "wb 128 f = open(folder + "provision_akc", "wb", 0) 129 f.seek(1) 129 f.seek(1) 130 with pytest.raises(OSError) as error: 130 with pytest.raises(OSError) as error: 131 f.write(rand_file) 131 f.write(rand_file) 132 assert error.value.errno == errno.ESPI 132 assert error.value.errno == errno.ESPIPE 133 f.close() 133 f.close() 134 134 135 def test_registers_seek(self, socket): 135 def test_registers_seek(self, socket): 136 folder = self.get_dev_folder(socket) 136 folder = self.get_dev_folder(socket) 137 137 138 # Check that the value read from an of 138 # Check that the value read from an offset of the entire 139 # file is none-zero and the same as th 139 # file is none-zero and the same as the value read 140 # from seeking to the same location 140 # from seeking to the same location 141 f = open(folder + "registers", "rb") 141 f = open(folder + "registers", "rb") 142 data = f.read() 142 data = f.read() 143 f.seek(64) 143 f.seek(64) 144 id = f.read() 144 id = f.read() 145 assert id != bytes(0) 145 assert id != bytes(0) 146 assert data[64:] == id 146 assert data[64:] == id 147 f.close() 147 f.close() 148 148 149 @pytest.mark.parametrize('socket', range(0, NU 149 @pytest.mark.parametrize('socket', range(0, NUM_SOCKETS)) 150 class TestSDSiMailboxCmdsClass: 150 class TestSDSiMailboxCmdsClass: 151 def test_provision_akc_eoverflow_1017_byte 151 def test_provision_akc_eoverflow_1017_bytes(self, socket): 152 152 153 # The buffer for writes is 1k, of with 153 # The buffer for writes is 1k, of with 8 bytes must be 154 # reserved for the command, leaving 10 154 # reserved for the command, leaving 1016 bytes max. 155 # Check that we get an overflow error 155 # Check that we get an overflow error for 1017 bytes. 156 node = get_dev_file_path(socket, "prov 156 node = get_dev_file_path(socket, "provision_akc") 157 rand_file = bytes(os.urandom(1017)) 157 rand_file = bytes(os.urandom(1017)) 158 158 159 f = open(node, 'wb', 0) 159 f = open(node, 'wb', 0) 160 with pytest.raises(OSError) as error: 160 with pytest.raises(OSError) as error: 161 f.write(rand_file) 161 f.write(rand_file) 162 assert error.value.errno == errno.EOVE 162 assert error.value.errno == errno.EOVERFLOW 163 f.close() 163 f.close() 164 164 165 @pytest.mark.parametrize('socket', range(0, NU 165 @pytest.mark.parametrize('socket', range(0, NUM_SOCKETS)) 166 class TestSdsiDriverLocksClass: 166 class TestSdsiDriverLocksClass: 167 def test_enodev_when_pci_device_removed(se 167 def test_enodev_when_pci_device_removed(self, socket): 168 node = get_dev_file_path(socket, "prov 168 node = get_dev_file_path(socket, "provision_akc") 169 dev_name = DEV_PREFIX + '.' + str(sock 169 dev_name = DEV_PREFIX + '.' + str(socket) 170 driver_dir = CLASS_DIR + '/' + dev_nam 170 driver_dir = CLASS_DIR + '/' + dev_name + "/driver/" 171 rand_file = bytes(os.urandom(8)) 171 rand_file = bytes(os.urandom(8)) 172 172 173 f = open(node, 'wb', 0) 173 f = open(node, 'wb', 0) 174 g = open(node, 'wb', 0) 174 g = open(node, 'wb', 0) 175 175 176 with open(driver_dir + 'unbind', 'w') 176 with open(driver_dir + 'unbind', 'w') as k: 177 print(dev_name, file = k) 177 print(dev_name, file = k) 178 178 179 with pytest.raises(OSError) as error: 179 with pytest.raises(OSError) as error: 180 f.write(rand_file) 180 f.write(rand_file) 181 assert error.value.errno == errno.ENOD 181 assert error.value.errno == errno.ENODEV 182 182 183 with pytest.raises(OSError) as error: 183 with pytest.raises(OSError) as error: 184 g.write(rand_file) 184 g.write(rand_file) 185 assert error.value.errno == errno.ENOD 185 assert error.value.errno == errno.ENODEV 186 186 187 f.close() 187 f.close() 188 g.close() 188 g.close() 189 189 190 # Short wait needed to allow file to c 190 # Short wait needed to allow file to close before pulling driver 191 sleep(1) 191 sleep(1) 192 192 193 p = subprocess.Popen(('modprobe', '-r' 193 p = subprocess.Popen(('modprobe', '-r', 'intel_sdsi')) 194 p.wait() 194 p.wait() 195 p = subprocess.Popen(('modprobe', '-r' 195 p = subprocess.Popen(('modprobe', '-r', 'intel_vsec')) 196 p.wait() 196 p.wait() 197 p = subprocess.Popen(('modprobe', 'int 197 p = subprocess.Popen(('modprobe', 'intel_vsec')) 198 p.wait() 198 p.wait() 199 199 200 # Short wait needed to allow driver ti 200 # Short wait needed to allow driver time to get inserted 201 # before continuing tests 201 # before continuing tests 202 sleep(1) 202 sleep(1) 203 203 204 def test_memory_leak(self, socket): 204 def test_memory_leak(self, socket): 205 if not kmemleak_enabled(): 205 if not kmemleak_enabled(): 206 pytest.skip("kmemleak not enabled 206 pytest.skip("kmemleak not enabled in kernel") 207 207 208 dev_name = DEV_PREFIX + '.' + str(sock 208 dev_name = DEV_PREFIX + '.' + str(socket) 209 driver_dir = CLASS_DIR + '/' + dev_nam 209 driver_dir = CLASS_DIR + '/' + dev_name + "/driver/" 210 210 211 with open(driver_dir + 'unbind', 'w') 211 with open(driver_dir + 'unbind', 'w') as k: 212 print(dev_name, file = k) 212 print(dev_name, file = k) 213 213 214 sleep(1) 214 sleep(1) 215 215 216 subprocess.check_output(('modprobe', ' 216 subprocess.check_output(('modprobe', '-r', 'intel_sdsi')) 217 subprocess.check_output(('modprobe', ' 217 subprocess.check_output(('modprobe', '-r', 'intel_vsec')) 218 218 219 with open('/sys/kernel/debug/kmemleak' 219 with open('/sys/kernel/debug/kmemleak', 'w') as f: 220 print('scan', file = f) 220 print('scan', file = f) 221 sleep(5) 221 sleep(5) 222 222 223 assert os.stat('/sys/kernel/debug/kmem 223 assert os.stat('/sys/kernel/debug/kmemleak').st_size == 0 224 224 225 subprocess.check_output(('modprobe', ' 225 subprocess.check_output(('modprobe', 'intel_vsec')) 226 sleep(1) 226 sleep(1)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.