Back to home page

OSCL-LXR

 
 

    


0001 #!/usr/bin/env python3
0002 # SPDX-License-Identifier: GPL-2.0
0003 
0004 from struct import pack
0005 from time import sleep
0006 
0007 import errno
0008 import glob
0009 import os
0010 import subprocess
0011 
0012 try:
0013     import pytest
0014 except ImportError:
0015     print("Unable to import pytest python module.")
0016     print("\nIf not already installed, you may do so with:")
0017     print("\t\tpip3 install pytest")
0018     exit(1)
0019 
0020 SOCKETS = glob.glob('/sys/bus/auxiliary/devices/intel_vsec.sdsi.*')
0021 NUM_SOCKETS = len(SOCKETS)
0022 
0023 MODULE_NAME = 'intel_sdsi'
0024 DEV_PREFIX = 'intel_vsec.sdsi'
0025 CLASS_DIR = '/sys/bus/auxiliary/devices'
0026 GUID = "0x6dd191"
0027 
0028 def read_bin_file(file):
0029     with open(file, mode='rb') as f:
0030         content = f.read()
0031     return content
0032 
0033 def get_dev_file_path(socket, file):
0034     return CLASS_DIR + '/' + DEV_PREFIX + '.' + str(socket) + '/' + file
0035 
0036 def kmemleak_enabled():
0037     kmemleak = "/sys/kernel/debug/kmemleak"
0038     return os.path.isfile(kmemleak)
0039 
0040 class TestSDSiDriver:
0041     def test_driver_loaded(self):
0042         lsmod_p = subprocess.Popen(('lsmod'), stdout=subprocess.PIPE)
0043         result = subprocess.check_output(('grep', '-q', MODULE_NAME), stdin=lsmod_p.stdout)
0044 
0045 @pytest.mark.parametrize('socket', range(0, NUM_SOCKETS))
0046 class TestSDSiFilesClass:
0047 
0048     def read_value(self, file):
0049         f = open(file, "r")
0050         value = f.read().strip("\n")
0051         return value
0052 
0053     def get_dev_folder(self, socket):
0054         return CLASS_DIR + '/' + DEV_PREFIX + '.' + str(socket) + '/'
0055 
0056     def test_sysfs_files_exist(self, socket):
0057         folder = self.get_dev_folder(socket)
0058         print (folder)
0059         assert os.path.isfile(folder + "guid") == True
0060         assert os.path.isfile(folder + "provision_akc") == True
0061         assert os.path.isfile(folder + "provision_cap") == True
0062         assert os.path.isfile(folder + "state_certificate") == True
0063         assert os.path.isfile(folder + "registers") == True
0064 
0065     def test_sysfs_file_permissions(self, socket):
0066         folder = self.get_dev_folder(socket)
0067         mode = os.stat(folder + "guid").st_mode & 0o777
0068         assert mode == 0o444    # Read all
0069         mode = os.stat(folder + "registers").st_mode & 0o777
0070         assert mode == 0o400    # Read owner
0071         mode = os.stat(folder + "provision_akc").st_mode & 0o777
0072         assert mode == 0o200    # Read owner
0073         mode = os.stat(folder + "provision_cap").st_mode & 0o777
0074         assert mode == 0o200    # Read owner
0075         mode = os.stat(folder + "state_certificate").st_mode & 0o777
0076         assert mode == 0o400    # Read owner
0077 
0078     def test_sysfs_file_ownership(self, socket):
0079         folder = self.get_dev_folder(socket)
0080 
0081         st = os.stat(folder + "guid")
0082         assert st.st_uid == 0
0083         assert st.st_gid == 0
0084 
0085         st = os.stat(folder + "registers")
0086         assert st.st_uid == 0
0087         assert st.st_gid == 0
0088 
0089         st = os.stat(folder + "provision_akc")
0090         assert st.st_uid == 0
0091         assert st.st_gid == 0
0092 
0093         st = os.stat(folder + "provision_cap")
0094         assert st.st_uid == 0
0095         assert st.st_gid == 0
0096 
0097         st = os.stat(folder + "state_certificate")
0098         assert st.st_uid == 0
0099         assert st.st_gid == 0
0100 
0101     def test_sysfs_file_sizes(self, socket):
0102         folder = self.get_dev_folder(socket)
0103 
0104         if self.read_value(folder + "guid") == GUID:
0105             st = os.stat(folder + "registers")
0106             assert st.st_size == 72
0107 
0108         st = os.stat(folder + "provision_akc")
0109         assert st.st_size == 1024
0110 
0111         st = os.stat(folder + "provision_cap")
0112         assert st.st_size == 1024
0113 
0114         st = os.stat(folder + "state_certificate")
0115         assert st.st_size == 4096
0116 
0117     def test_no_seek_allowed(self, socket):
0118         folder = self.get_dev_folder(socket)
0119         rand_file = bytes(os.urandom(8))
0120 
0121         f = open(folder + "provision_cap", "wb", 0)
0122         f.seek(1)
0123         with pytest.raises(OSError) as error:
0124             f.write(rand_file)
0125         assert error.value.errno == errno.ESPIPE
0126         f.close()
0127 
0128         f = open(folder + "provision_akc", "wb", 0)
0129         f.seek(1)
0130         with pytest.raises(OSError) as error:
0131             f.write(rand_file)
0132         assert error.value.errno == errno.ESPIPE
0133         f.close()
0134 
0135     def test_registers_seek(self, socket):
0136         folder = self.get_dev_folder(socket)
0137 
0138         # Check that the value read from an offset of the entire
0139         # file is none-zero and the same as the value read
0140         # from seeking to the same location
0141         f = open(folder + "registers", "rb")
0142         data = f.read()
0143         f.seek(64)
0144         id = f.read()
0145         assert id != bytes(0)
0146         assert data[64:] == id
0147         f.close()
0148 
0149 @pytest.mark.parametrize('socket', range(0, NUM_SOCKETS))
0150 class TestSDSiMailboxCmdsClass:
0151     def test_provision_akc_eoverflow_1017_bytes(self, socket):
0152 
0153         # The buffer for writes is 1k, of with 8 bytes must be
0154         # reserved for the command, leaving 1016 bytes max.
0155         # Check that we get an overflow error for 1017 bytes.
0156         node = get_dev_file_path(socket, "provision_akc")
0157         rand_file = bytes(os.urandom(1017))
0158 
0159         f = open(node, 'wb', 0)
0160         with pytest.raises(OSError) as error:
0161             f.write(rand_file)
0162         assert error.value.errno == errno.EOVERFLOW
0163         f.close()
0164 
0165 @pytest.mark.parametrize('socket', range(0, NUM_SOCKETS))
0166 class TestSdsiDriverLocksClass:
0167     def test_enodev_when_pci_device_removed(self, socket):
0168         node = get_dev_file_path(socket, "provision_akc")
0169         dev_name = DEV_PREFIX + '.' + str(socket)
0170         driver_dir = CLASS_DIR + '/' + dev_name + "/driver/"
0171         rand_file = bytes(os.urandom(8))
0172 
0173         f = open(node, 'wb', 0)
0174         g = open(node, 'wb', 0)
0175 
0176         with open(driver_dir + 'unbind', 'w') as k:
0177             print(dev_name, file = k)
0178 
0179         with pytest.raises(OSError) as error:
0180             f.write(rand_file)
0181         assert error.value.errno == errno.ENODEV
0182 
0183         with pytest.raises(OSError) as error:
0184             g.write(rand_file)
0185         assert error.value.errno == errno.ENODEV
0186 
0187         f.close()
0188         g.close()
0189 
0190         # Short wait needed to allow file to close before pulling driver
0191         sleep(1)
0192 
0193         p = subprocess.Popen(('modprobe', '-r', 'intel_sdsi'))
0194         p.wait()
0195         p = subprocess.Popen(('modprobe', '-r', 'intel_vsec'))
0196         p.wait()
0197         p = subprocess.Popen(('modprobe', 'intel_vsec'))
0198         p.wait()
0199 
0200         # Short wait needed to allow driver time to get inserted
0201         # before continuing tests
0202         sleep(1)
0203 
0204     def test_memory_leak(self, socket):
0205         if not kmemleak_enabled():
0206             pytest.skip("kmemleak not enabled in kernel")
0207 
0208         dev_name = DEV_PREFIX + '.' + str(socket)
0209         driver_dir = CLASS_DIR + '/' + dev_name + "/driver/"
0210 
0211         with open(driver_dir + 'unbind', 'w') as k:
0212             print(dev_name, file = k)
0213 
0214         sleep(1)
0215 
0216         subprocess.check_output(('modprobe', '-r', 'intel_sdsi'))
0217         subprocess.check_output(('modprobe', '-r', 'intel_vsec'))
0218 
0219         with open('/sys/kernel/debug/kmemleak', 'w') as f:
0220             print('scan', file = f)
0221         sleep(5)
0222 
0223         assert os.stat('/sys/kernel/debug/kmemleak').st_size == 0
0224 
0225         subprocess.check_output(('modprobe', 'intel_vsec'))
0226         sleep(1)