Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / crypto / ccp / test_dbc.py
blobbb0e671be96d57bf53bd0b91c2ac55f8f92ab101
1 #!/usr/bin/python3
2 # SPDX-License-Identifier: GPL-2.0
3 import unittest
4 import os
5 import time
6 import glob
7 import fcntl
8 try:
9 import ioctl_opt as ioctl
10 except ImportError:
11 ioctl = None
12 pass
13 from dbc import *
15 # Artificial delay between set commands
16 SET_DELAY = 0.5
19 class invalid_param(ctypes.Structure):
20 _fields_ = [
21 ("data", ctypes.c_uint8),
25 def system_is_secured() -> bool:
26 fused_part = glob.glob("/sys/bus/pci/drivers/ccp/**/fused_part")[0]
27 if os.path.exists(fused_part):
28 with open(fused_part, "r") as r:
29 return int(r.read()) == 1
30 return True
33 class DynamicBoostControlTest(unittest.TestCase):
34 def __init__(self, data) -> None:
35 self.d = None
36 self.signature = b"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
37 self.uid = b"1111111111111111"
38 super().__init__(data)
40 def setUp(self) -> None:
41 self.d = open(DEVICE_NODE)
42 return super().setUp()
44 def tearDown(self) -> None:
45 if self.d:
46 self.d.close()
47 return super().tearDown()
50 class TestUnsupportedSystem(DynamicBoostControlTest):
51 def setUp(self) -> None:
52 if os.path.exists(DEVICE_NODE):
53 self.skipTest("system is supported")
54 with self.assertRaises(FileNotFoundError) as error:
55 super().setUp()
56 self.assertEqual(error.exception.errno, 2)
58 def test_unauthenticated_nonce(self) -> None:
59 """fetch unauthenticated nonce"""
60 with self.assertRaises(ValueError) as error:
61 get_nonce(self.d, None)
64 class TestInvalidIoctls(DynamicBoostControlTest):
65 def __init__(self, data) -> None:
66 self.data = invalid_param()
67 self.data.data = 1
68 super().__init__(data)
70 def setUp(self) -> None:
71 if not os.path.exists(DEVICE_NODE):
72 self.skipTest("system is unsupported")
73 if not ioctl:
74 self.skipTest("unable to test IOCTLs without ioctl_opt")
76 return super().setUp()
78 def test_invalid_nonce_ioctl(self) -> None:
79 """tries to call get_nonce ioctl with invalid data structures"""
81 # 0x1 (get nonce), and invalid data
82 INVALID1 = ioctl.IOWR(ord("D"), 0x01, invalid_param)
83 with self.assertRaises(OSError) as error:
84 fcntl.ioctl(self.d, INVALID1, self.data, True)
85 self.assertEqual(error.exception.errno, 22)
87 def test_invalid_setuid_ioctl(self) -> None:
88 """tries to call set_uid ioctl with invalid data structures"""
90 # 0x2 (set uid), and invalid data
91 INVALID2 = ioctl.IOW(ord("D"), 0x02, invalid_param)
92 with self.assertRaises(OSError) as error:
93 fcntl.ioctl(self.d, INVALID2, self.data, True)
94 self.assertEqual(error.exception.errno, 22)
96 def test_invalid_setuid_rw_ioctl(self) -> None:
97 """tries to call set_uid ioctl with invalid data structures"""
99 # 0x2 as RW (set uid), and invalid data
100 INVALID3 = ioctl.IOWR(ord("D"), 0x02, invalid_param)
101 with self.assertRaises(OSError) as error:
102 fcntl.ioctl(self.d, INVALID3, self.data, True)
103 self.assertEqual(error.exception.errno, 22)
105 def test_invalid_param_ioctl(self) -> None:
106 """tries to call param ioctl with invalid data structures"""
107 # 0x3 (param), and invalid data
108 INVALID4 = ioctl.IOWR(ord("D"), 0x03, invalid_param)
109 with self.assertRaises(OSError) as error:
110 fcntl.ioctl(self.d, INVALID4, self.data, True)
111 self.assertEqual(error.exception.errno, 22)
113 def test_invalid_call_ioctl(self) -> None:
114 """tries to call the DBC ioctl with invalid data structures"""
115 # 0x4, and invalid data
116 INVALID5 = ioctl.IOWR(ord("D"), 0x04, invalid_param)
117 with self.assertRaises(OSError) as error:
118 fcntl.ioctl(self.d, INVALID5, self.data, True)
119 self.assertEqual(error.exception.errno, 22)
122 class TestInvalidSignature(DynamicBoostControlTest):
123 def setUp(self) -> None:
124 if not os.path.exists(DEVICE_NODE):
125 self.skipTest("system is unsupported")
126 if not system_is_secured():
127 self.skipTest("system is unfused")
128 return super().setUp()
130 def test_unauthenticated_nonce(self) -> None:
131 """fetch unauthenticated nonce"""
132 get_nonce(self.d, None)
134 def test_multiple_unauthenticated_nonce(self) -> None:
135 """ensure state machine always returns nonce"""
136 for count in range(0, 2):
137 get_nonce(self.d, None)
139 def test_authenticated_nonce(self) -> None:
140 """fetch authenticated nonce"""
141 get_nonce(self.d, None)
142 with self.assertRaises(OSError) as error:
143 get_nonce(self.d, self.signature)
144 self.assertEqual(error.exception.errno, 22)
146 def test_set_uid(self) -> None:
147 """set uid"""
148 get_nonce(self.d, None)
149 with self.assertRaises(OSError) as error:
150 set_uid(self.d, self.uid, self.signature)
151 self.assertEqual(error.exception.errno, 1)
153 def test_get_param(self) -> None:
154 """fetch a parameter"""
155 with self.assertRaises(OSError) as error:
156 process_param(self.d, PARAM_GET_SOC_PWR_CUR, self.signature)
157 self.assertEqual(error.exception.errno, 11)
159 def test_set_param(self) -> None:
160 """set a parameter"""
161 with self.assertRaises(OSError) as error:
162 process_param(self.d, PARAM_SET_PWR_CAP, self.signature, 1000)
163 self.assertEqual(error.exception.errno, 11)
166 class TestUnFusedSystem(DynamicBoostControlTest):
167 def setup_identity(self) -> None:
168 """sets up the identity of the caller"""
169 # if already authenticated these may fail
170 try:
171 get_nonce(self.d, None)
172 except PermissionError:
173 pass
174 try:
175 set_uid(self.d, self.uid, self.signature)
176 except BlockingIOError:
177 pass
178 try:
179 get_nonce(self.d, self.signature)
180 except PermissionError:
181 pass
183 def setUp(self) -> None:
184 if not os.path.exists(DEVICE_NODE):
185 self.skipTest("system is unsupported")
186 if system_is_secured():
187 self.skipTest("system is fused")
188 super().setUp()
189 self.setup_identity()
190 time.sleep(SET_DELAY)
192 def test_get_valid_param(self) -> None:
193 """fetch all possible parameters"""
194 # SOC power
195 soc_power_max = process_param(self.d, PARAM_GET_SOC_PWR_MAX, self.signature)
196 soc_power_min = process_param(self.d, PARAM_GET_SOC_PWR_MIN, self.signature)
197 self.assertGreater(soc_power_max[0], soc_power_min[0])
199 # fmax
200 fmax_max = process_param(self.d, PARAM_GET_FMAX_MAX, self.signature)
201 fmax_min = process_param(self.d, PARAM_GET_FMAX_MIN, self.signature)
202 self.assertGreater(fmax_max[0], fmax_min[0])
204 # cap values
205 keys = {
206 "fmax-cap": PARAM_GET_FMAX_CAP,
207 "power-cap": PARAM_GET_PWR_CAP,
208 "current-temp": PARAM_GET_CURR_TEMP,
209 "soc-power-cur": PARAM_GET_SOC_PWR_CUR,
211 for k in keys:
212 result = process_param(self.d, keys[k], self.signature)
213 self.assertGreater(result[0], 0)
215 def test_get_invalid_param(self) -> None:
216 """fetch an invalid parameter"""
217 try:
218 set_uid(self.d, self.uid, self.signature)
219 except OSError:
220 pass
221 with self.assertRaises(OSError) as error:
222 process_param(self.d, (0xF,), self.signature)
223 self.assertEqual(error.exception.errno, 22)
225 def test_set_fmax(self) -> None:
226 """get/set fmax limit"""
227 # fetch current
228 original = process_param(self.d, PARAM_GET_FMAX_CAP, self.signature)
230 # set the fmax
231 target = original[0] - 100
232 process_param(self.d, PARAM_SET_FMAX_CAP, self.signature, target)
233 time.sleep(SET_DELAY)
234 new = process_param(self.d, PARAM_GET_FMAX_CAP, self.signature)
235 self.assertEqual(new[0], target)
237 # revert back to current
238 process_param(self.d, PARAM_SET_FMAX_CAP, self.signature, original[0])
239 time.sleep(SET_DELAY)
240 cur = process_param(self.d, PARAM_GET_FMAX_CAP, self.signature)
241 self.assertEqual(cur[0], original[0])
243 def test_set_power_cap(self) -> None:
244 """get/set power cap limit"""
245 # fetch current
246 original = process_param(self.d, PARAM_GET_PWR_CAP, self.signature)
248 # set the fmax
249 target = original[0] - 10
250 process_param(self.d, PARAM_SET_PWR_CAP, self.signature, target)
251 time.sleep(SET_DELAY)
252 new = process_param(self.d, PARAM_GET_PWR_CAP, self.signature)
253 self.assertEqual(new[0], target)
255 # revert back to current
256 process_param(self.d, PARAM_SET_PWR_CAP, self.signature, original[0])
257 time.sleep(SET_DELAY)
258 cur = process_param(self.d, PARAM_GET_PWR_CAP, self.signature)
259 self.assertEqual(cur[0], original[0])
261 def test_set_3d_graphics_mode(self) -> None:
262 """set/get 3d graphics mode"""
263 # these aren't currently implemented but may be some day
264 # they are *expected* to fail
265 with self.assertRaises(OSError) as error:
266 process_param(self.d, PARAM_GET_GFX_MODE, self.signature)
267 self.assertEqual(error.exception.errno, 2)
269 time.sleep(SET_DELAY)
271 with self.assertRaises(OSError) as error:
272 process_param(self.d, PARAM_SET_GFX_MODE, self.signature, 1)
273 self.assertEqual(error.exception.errno, 2)
276 if __name__ == "__main__":
277 unittest.main()