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