xref: /openbmc/linux/tools/testing/selftests/drivers/sdsi/sdsi_test.py (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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