#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
from struct import pack
from time import sleep
import errno
import glob
import os
import subprocess
try :
import pytest
except ImportError:
print("Unable to import pytest python module." )
print("\nIf not already installed, you may do so with:" )
print("\t\tpip3 install pytest" )
exit(1)
SOCKETS = glob.glob('/sys/bus/auxiliary/devices/intel_vsec.sdsi.*' )
NUM_SOCKETS = len(SOCKETS)
MODULE_NAME = 'intel_sdsi'
DEV_PREFIX = 'intel_vsec.sdsi'
CLASS_DIR = '/sys/bus/auxiliary/devices'
GUID = "0x6dd191"
def read_bin_file(file):
with open(file, mode='rb' ) as f:
content = f.read()
return content
def get_dev_file_path(socket, file):
return CLASS_DIR + '/' + DEV_PREFIX + '.' + str(socket) + '/' + file
def kmemleak_enabled():
kmemleak = "/sys/kernel/debug/kmemleak"
return os.path.isfile(kmemleak)
class TestSDSiDriver:
def test_driver_loaded(self):
lsmod_p = subprocess.Popen(('lsmod' ), stdout=subprocess.PIPE)
result = subprocess.check_output(('grep' , '-q' , MODULE_NAME), stdin=lsmod_p.stdout)
@pytest.mark.parametrize('socket' , range(0, NUM_SOCKETS))
class TestSDSiFilesClass:
def read_value(self, file):
f = open(file, "r" )
value = f.read().strip("\n" )
return value
def get_dev_folder(self, socket):
return CLASS_DIR + '/' + DEV_PREFIX + '.' + str(socket) + '/'
def test_sysfs_files_exist(self, socket):
folder = self.get_dev_folder(socket)
print (folder)
assert os.path.isfile(folder + "guid" ) == True
assert os.path.isfile(folder + "provision_akc" ) == True
assert os.path.isfile(folder + "provision_cap" ) == True
assert os.path.isfile(folder + "state_certificate" ) == True
assert os.path.isfile(folder + "registers" ) == True
def test_sysfs_file_permissions(self, socket):
folder = self.get_dev_folder(socket)
mode = os.stat(folder + "guid" ).st_mode & 0o777
assert mode == 0o444 # Read all
mode = os.stat(folder + "registers" ).st_mode & 0o777
assert mode == 0o400 # Read owner
mode = os.stat(folder + "provision_akc" ).st_mode & 0o777
assert mode == 0o200 # Read owner
mode = os.stat(folder + "provision_cap" ).st_mode & 0o777
assert mode == 0o200 # Read owner
mode = os.stat(folder + "state_certificate" ).st_mode & 0o777
assert mode == 0o400 # Read owner
def test_sysfs_file_ownership(self, socket):
folder = self.get_dev_folder(socket)
st = os.stat(folder + "guid" )
assert st.st_uid == 0
assert st.st_gid == 0
st = os.stat(folder + "registers" )
assert st.st_uid == 0
assert st.st_gid == 0
st = os.stat(folder + "provision_akc" )
assert st.st_uid == 0
assert st.st_gid == 0
st = os.stat(folder + "provision_cap" )
assert st.st_uid == 0
assert st.st_gid == 0
st = os.stat(folder + "state_certificate" )
assert st.st_uid == 0
assert st.st_gid == 0
def test_sysfs_file_sizes(self, socket):
folder = self.get_dev_folder(socket)
if self.read_value(folder + "guid" ) == GUID:
st = os.stat(folder + "registers" )
assert st.st_size == 72
st = os.stat(folder + "provision_akc" )
assert st.st_size == 1024
st = os.stat(folder + "provision_cap" )
assert st.st_size == 1024
st = os.stat(folder + "state_certificate" )
assert st.st_size == 4096
def test_no_seek_allowed(self, socket):
folder = self.get_dev_folder(socket)
rand_file = bytes(os.urandom(8))
f = open(folder + "provision_cap" , "wb" , 0)
f.seek(1)
with pytest.raises(OSError) as error:
f.write(rand_file)
assert error.value.errno == errno.ESPIPE
f.close()
f = open(folder + "provision_akc" , "wb" , 0)
f.seek(1)
with pytest.raises(OSError) as error:
f.write(rand_file)
assert error.value.errno == errno.ESPIPE
f.close()
def test_registers_seek(self, socket):
folder = self.get_dev_folder(socket)
# Check that the value read from an offset of the entire
# file is none-zero and the same as the value read
# from seeking to the same location
f = open(folder + "registers" , "rb" )
data = f.read()
f.seek(64)
id = f.read()
assert id != bytes(0)
assert data[64:] == id
f.close()
@pytest.mark.parametrize('socket' , range(0, NUM_SOCKETS))
class TestSDSiMailboxCmdsClass:
def test_provision_akc_eoverflow_1017_bytes(self, socket):
# The buffer for writes is 1k, of with 8 bytes must be
# reserved for the command, leaving 1016 bytes max.
# Check that we get an overflow error for 1017 bytes.
node = get_dev_file_path(socket, "provision_akc" )
rand_file = bytes(os.urandom(1017))
f = open(node, 'wb' , 0)
with pytest.raises(OSError) as error:
f.write(rand_file)
assert error.value.errno == errno.EOVERFLOW
f.close()
@pytest.mark.parametrize('socket' , range(0, NUM_SOCKETS))
class TestSdsiDriverLocksClass:
def test_enodev_when_pci_device_removed(self, socket):
node = get_dev_file_path(socket, "provision_akc" )
dev_name = DEV_PREFIX + '.' + str(socket)
driver_dir = CLASS_DIR + '/' + dev_name + "/driver/"
rand_file = bytes(os.urandom(8))
f = open(node, 'wb' , 0)
g = open(node, 'wb' , 0)
with open(driver_dir + 'unbind' , 'w' ) as k:
print(dev_name, file = k)
with pytest.raises(OSError) as error:
f.write(rand_file)
assert error.value.errno == errno.ENODEV
with pytest.raises(OSError) as error:
g.write(rand_file)
assert error.value.errno == errno.ENODEV
f.close()
g.close()
# Short wait needed to allow file to close before pulling driver
sleep(1)
p = subprocess.Popen(('modprobe' , '-r' , 'intel_sdsi' ))
p.wait()
p = subprocess.Popen(('modprobe' , '-r' , 'intel_vsec' ))
p.wait()
p = subprocess.Popen(('modprobe' , 'intel_vsec' ))
p.wait()
# Short wait needed to allow driver time to get inserted
# before continuing tests
sleep(1)
def test_memory_leak(self, socket):
if not kmemleak_enabled():
pytest.skip("kmemleak not enabled in kernel" )
dev_name = DEV_PREFIX + '.' + str(socket)
driver_dir = CLASS_DIR + '/' + dev_name + "/driver/"
with open(driver_dir + 'unbind' , 'w' ) as k:
print(dev_name, file = k)
sleep(1)
subprocess.check_output(('modprobe' , '-r' , 'intel_sdsi' ))
subprocess.check_output(('modprobe' , '-r' , 'intel_vsec' ))
with open('/sys/kernel/debug/kmemleak' , 'w' ) as f:
print('scan' , file = f)
sleep(5)
assert os.stat('/sys/kernel/debug/kmemleak' ).st_size == 0
subprocess.check_output(('modprobe' , 'intel_vsec' ))
sleep(1)
Messung V0.5 C=93 H=82 G=87
¤ Dauer der Verarbeitung: 0.4 Sekunden
¤
*© Formatika GbR, Deutschland