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