1 // SPDX-License-Identifier: GPL-2.0 AND MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 6 #include <kunit/static_stub.h> 7 #include <kunit/test.h> 8 #include <kunit/test-bug.h> 9 10 #include "xe_device.h" 11 #include "xe_kunit_helpers.h" 12 #include "xe_pci_test.h" 13 14 #define TEST_RID 1234 15 #define TEST_VFID 5 16 #define TEST_LEN 6 17 #define TEST_ACTION 0xa 18 #define TEST_DATA(n) (0xd0 + (n)) 19 20 static int replacement_relay_get_totalvfs(struct xe_guc_relay *relay) 21 { 22 return TEST_VFID; 23 } 24 25 static int relay_test_init(struct kunit *test) 26 { 27 struct xe_pci_fake_data fake = { 28 .sriov_mode = XE_SRIOV_MODE_PF, 29 .platform = XE_TIGERLAKE, /* some random platform */ 30 .subplatform = XE_SUBPLATFORM_NONE, 31 }; 32 struct xe_guc_relay *relay; 33 struct xe_device *xe; 34 35 test->priv = &fake; 36 xe_kunit_helper_xe_device_test_init(test); 37 38 xe = test->priv; 39 KUNIT_ASSERT_EQ(test, xe_sriov_init(xe), 0); 40 41 relay = &xe_device_get_gt(xe, 0)->uc.guc.relay; 42 kunit_activate_static_stub(test, relay_get_totalvfs, 43 replacement_relay_get_totalvfs); 44 45 KUNIT_ASSERT_EQ(test, xe_guc_relay_init(relay), 0); 46 KUNIT_EXPECT_TRUE(test, relay_is_ready(relay)); 47 relay->last_rid = TEST_RID - 1; 48 49 test->priv = relay; 50 return 0; 51 } 52 53 static const u32 TEST_MSG[TEST_LEN] = { 54 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) | 55 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_EVENT) | 56 FIELD_PREP_CONST(GUC_HXG_EVENT_MSG_0_ACTION, TEST_ACTION) | 57 FIELD_PREP_CONST(GUC_HXG_EVENT_MSG_0_DATA0, TEST_DATA(0)), 58 TEST_DATA(1), TEST_DATA(2), TEST_DATA(3), TEST_DATA(4), 59 }; 60 61 static int replacement_xe_guc_ct_send_recv_always_fails(struct xe_guc_ct *ct, 62 const u32 *msg, u32 len, 63 u32 *response_buffer) 64 { 65 struct kunit *test = kunit_get_current_test(); 66 67 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ct); 68 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, msg); 69 KUNIT_ASSERT_GE(test, len, GUC_HXG_MSG_MIN_LEN); 70 71 return -ECOMM; 72 } 73 74 static int replacement_xe_guc_ct_send_recv_expects_pf2guc_relay(struct xe_guc_ct *ct, 75 const u32 *msg, u32 len, 76 u32 *response_buffer) 77 { 78 struct kunit *test = kunit_get_current_test(); 79 80 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ct); 81 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, msg); 82 KUNIT_ASSERT_GE(test, len, PF2GUC_RELAY_TO_VF_REQUEST_MSG_MIN_LEN); 83 KUNIT_ASSERT_EQ(test, len, PF2GUC_RELAY_TO_VF_REQUEST_MSG_MIN_LEN + TEST_LEN); 84 KUNIT_EXPECT_EQ(test, GUC_HXG_ORIGIN_HOST, FIELD_GET(GUC_HXG_MSG_0_ORIGIN, msg[0])); 85 KUNIT_EXPECT_EQ(test, GUC_HXG_TYPE_REQUEST, FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0])); 86 KUNIT_EXPECT_EQ(test, XE_GUC_ACTION_PF2GUC_RELAY_TO_VF, 87 FIELD_GET(GUC_HXG_REQUEST_MSG_0_ACTION, msg[0])); 88 KUNIT_EXPECT_EQ(test, TEST_VFID, 89 FIELD_GET(PF2GUC_RELAY_TO_VF_REQUEST_MSG_1_VFID, msg[1])); 90 KUNIT_EXPECT_EQ(test, TEST_RID, 91 FIELD_GET(PF2GUC_RELAY_TO_VF_REQUEST_MSG_2_RELAY_ID, msg[2])); 92 KUNIT_EXPECT_MEMEQ(test, TEST_MSG, msg + PF2GUC_RELAY_TO_VF_REQUEST_MSG_MIN_LEN, 93 sizeof(u32) * TEST_LEN); 94 return 0; 95 } 96 97 static const u32 test_guc2pf[GUC2PF_RELAY_FROM_VF_EVENT_MSG_MAX_LEN] = { 98 /* transport */ 99 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_GUC) | 100 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_EVENT) | 101 FIELD_PREP_CONST(GUC_HXG_EVENT_MSG_0_ACTION, XE_GUC_ACTION_GUC2PF_RELAY_FROM_VF), 102 FIELD_PREP_CONST(GUC2PF_RELAY_FROM_VF_EVENT_MSG_1_VFID, TEST_VFID), 103 FIELD_PREP_CONST(GUC2PF_RELAY_FROM_VF_EVENT_MSG_2_RELAY_ID, TEST_RID), 104 /* payload */ 105 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) | 106 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_RESPONSE_SUCCESS), 107 }; 108 109 static const u32 test_guc2vf[GUC2VF_RELAY_FROM_PF_EVENT_MSG_MAX_LEN] = { 110 /* transport */ 111 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_GUC) | 112 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_EVENT) | 113 FIELD_PREP_CONST(GUC_HXG_EVENT_MSG_0_ACTION, XE_GUC_ACTION_GUC2VF_RELAY_FROM_PF), 114 FIELD_PREP_CONST(GUC2VF_RELAY_FROM_PF_EVENT_MSG_1_RELAY_ID, TEST_RID), 115 /* payload */ 116 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) | 117 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_RESPONSE_SUCCESS), 118 }; 119 120 static void pf_rejects_guc2pf_too_short(struct kunit *test) 121 { 122 const u32 len = GUC2PF_RELAY_FROM_VF_EVENT_MSG_MIN_LEN - 1; 123 struct xe_guc_relay *relay = test->priv; 124 const u32 *msg = test_guc2pf; 125 126 KUNIT_ASSERT_EQ(test, -EPROTO, xe_guc_relay_process_guc2pf(relay, msg, len)); 127 } 128 129 static void pf_rejects_guc2pf_too_long(struct kunit *test) 130 { 131 const u32 len = GUC2PF_RELAY_FROM_VF_EVENT_MSG_MAX_LEN + 1; 132 struct xe_guc_relay *relay = test->priv; 133 const u32 *msg = test_guc2pf; 134 135 KUNIT_ASSERT_EQ(test, -EMSGSIZE, xe_guc_relay_process_guc2pf(relay, msg, len)); 136 } 137 138 static void pf_rejects_guc2pf_no_payload(struct kunit *test) 139 { 140 const u32 len = GUC2PF_RELAY_FROM_VF_EVENT_MSG_MIN_LEN; 141 struct xe_guc_relay *relay = test->priv; 142 const u32 *msg = test_guc2pf; 143 144 KUNIT_ASSERT_EQ(test, -EPROTO, xe_guc_relay_process_guc2pf(relay, msg, len)); 145 } 146 147 static void pf_fails_no_payload(struct kunit *test) 148 { 149 struct xe_guc_relay *relay = test->priv; 150 const u32 msg = 0; 151 152 KUNIT_ASSERT_EQ(test, -EPROTO, relay_process_msg(relay, TEST_VFID, TEST_RID, &msg, 0)); 153 } 154 155 static void pf_fails_bad_origin(struct kunit *test) 156 { 157 struct xe_guc_relay *relay = test->priv; 158 static const u32 msg[] = { 159 FIELD_PREP_CONST(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_GUC) | 160 FIELD_PREP_CONST(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_RESPONSE_SUCCESS), 161 }; 162 u32 len = ARRAY_SIZE(msg); 163 164 KUNIT_ASSERT_EQ(test, -EPROTO, relay_process_msg(relay, TEST_VFID, TEST_RID, msg, len)); 165 } 166 167 static void pf_fails_bad_type(struct kunit *test) 168 { 169 struct xe_guc_relay *relay = test->priv; 170 const u32 msg[] = { 171 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) | 172 FIELD_PREP(GUC_HXG_MSG_0_TYPE, 4), /* only 4 is undefined */ 173 }; 174 u32 len = ARRAY_SIZE(msg); 175 176 KUNIT_ASSERT_EQ(test, -EBADRQC, relay_process_msg(relay, TEST_VFID, TEST_RID, msg, len)); 177 } 178 179 static void pf_txn_reports_error(struct kunit *test) 180 { 181 struct xe_guc_relay *relay = test->priv; 182 struct relay_transaction *txn; 183 184 txn = __relay_get_transaction(relay, false, TEST_VFID, TEST_RID, 185 TEST_MSG, TEST_LEN, NULL, 0); 186 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, txn); 187 188 kunit_activate_static_stub(test, xe_guc_ct_send_recv, 189 replacement_xe_guc_ct_send_recv_always_fails); 190 KUNIT_EXPECT_EQ(test, -ECOMM, relay_send_transaction(relay, txn)); 191 192 relay_release_transaction(relay, txn); 193 } 194 195 static void pf_txn_sends_pf2guc(struct kunit *test) 196 { 197 struct xe_guc_relay *relay = test->priv; 198 struct relay_transaction *txn; 199 200 txn = __relay_get_transaction(relay, false, TEST_VFID, TEST_RID, 201 TEST_MSG, TEST_LEN, NULL, 0); 202 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, txn); 203 204 kunit_activate_static_stub(test, xe_guc_ct_send_recv, 205 replacement_xe_guc_ct_send_recv_expects_pf2guc_relay); 206 KUNIT_ASSERT_EQ(test, 0, relay_send_transaction(relay, txn)); 207 208 relay_release_transaction(relay, txn); 209 } 210 211 static void pf_sends_pf2guc(struct kunit *test) 212 { 213 struct xe_guc_relay *relay = test->priv; 214 215 kunit_activate_static_stub(test, xe_guc_ct_send_recv, 216 replacement_xe_guc_ct_send_recv_expects_pf2guc_relay); 217 KUNIT_ASSERT_EQ(test, 0, 218 xe_guc_relay_send_to_vf(relay, TEST_VFID, 219 TEST_MSG, TEST_LEN, NULL, 0)); 220 } 221 222 static int replacement_xe_guc_ct_send_recv_loopback_relay(struct xe_guc_ct *ct, 223 const u32 *msg, u32 len, 224 u32 *response_buffer) 225 { 226 struct kunit *test = kunit_get_current_test(); 227 struct xe_guc_relay *relay = test->priv; 228 u32 *reply = kunit_kzalloc(test, len * sizeof(u32), GFP_KERNEL); 229 int (*guc2relay)(struct xe_guc_relay *, const u32 *, u32); 230 u32 action; 231 int err; 232 233 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ct); 234 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, msg); 235 KUNIT_ASSERT_GE(test, len, GUC_HXG_MSG_MIN_LEN); 236 KUNIT_ASSERT_EQ(test, GUC_HXG_TYPE_REQUEST, 237 FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0])); 238 KUNIT_ASSERT_GE(test, len, GUC_HXG_REQUEST_MSG_MIN_LEN); 239 KUNIT_ASSERT_NOT_NULL(test, reply); 240 241 switch (FIELD_GET(GUC_HXG_REQUEST_MSG_0_ACTION, msg[0])) { 242 case XE_GUC_ACTION_PF2GUC_RELAY_TO_VF: 243 KUNIT_ASSERT_GE(test, len, PF2GUC_RELAY_TO_VF_REQUEST_MSG_MIN_LEN); 244 action = XE_GUC_ACTION_GUC2PF_RELAY_FROM_VF; 245 guc2relay = xe_guc_relay_process_guc2pf; 246 break; 247 case XE_GUC_ACTION_VF2GUC_RELAY_TO_PF: 248 KUNIT_ASSERT_GE(test, len, VF2GUC_RELAY_TO_PF_REQUEST_MSG_MIN_LEN); 249 action = XE_GUC_ACTION_GUC2VF_RELAY_FROM_PF; 250 guc2relay = xe_guc_relay_process_guc2vf; 251 break; 252 default: 253 KUNIT_FAIL(test, "bad RELAY action %#x", msg[0]); 254 return -EINVAL; 255 } 256 257 reply[0] = FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_GUC) | 258 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_EVENT) | 259 FIELD_PREP(GUC_HXG_EVENT_MSG_0_ACTION, action); 260 memcpy(reply + 1, msg + 1, sizeof(u32) * (len - 1)); 261 262 err = guc2relay(relay, reply, len); 263 KUNIT_EXPECT_EQ(test, err, 0); 264 265 return err; 266 } 267 268 static void test_requires_relay_testloop(struct kunit *test) 269 { 270 /* 271 * The debug relay action GUC_RELAY_ACTION_VFXPF_TESTLOOP is available 272 * only on builds with CONFIG_DRM_XE_DEBUG_SRIOV enabled. 273 * See "kunit.py --kconfig_add" option if it's missing. 274 */ 275 if (!IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV)) 276 kunit_skip(test, "requires %s\n", __stringify(CONFIG_DRM_XE_DEBUG_SRIOV)); 277 } 278 279 static void pf_loopback_nop(struct kunit *test) 280 { 281 struct xe_guc_relay *relay = test->priv; 282 u32 request[] = { 283 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) | 284 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) | 285 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VFXPF_TESTLOOP) | 286 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_DATA0, VFXPF_TESTLOOP_OPCODE_NOP), 287 }; 288 u32 response[GUC_HXG_RESPONSE_MSG_MIN_LEN]; 289 int ret; 290 291 test_requires_relay_testloop(test); 292 293 kunit_activate_static_stub(test, relay_kick_worker, relay_process_incoming_action); 294 kunit_activate_static_stub(test, xe_guc_ct_send_recv, 295 replacement_xe_guc_ct_send_recv_loopback_relay); 296 ret = xe_guc_relay_send_to_vf(relay, TEST_VFID, 297 request, ARRAY_SIZE(request), 298 response, ARRAY_SIZE(response)); 299 KUNIT_ASSERT_EQ(test, ret, GUC_HXG_RESPONSE_MSG_MIN_LEN); 300 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_MSG_0_ORIGIN, response[0]), 301 GUC_HXG_ORIGIN_HOST); 302 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_MSG_0_TYPE, response[0]), 303 GUC_HXG_TYPE_RESPONSE_SUCCESS); 304 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_RESPONSE_MSG_0_DATA0, response[0]), 0); 305 } 306 307 static void pf_loopback_echo(struct kunit *test) 308 { 309 struct xe_guc_relay *relay = test->priv; 310 u32 request[] = { 311 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) | 312 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) | 313 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VFXPF_TESTLOOP) | 314 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_DATA0, VFXPF_TESTLOOP_OPCODE_ECHO), 315 TEST_DATA(1), TEST_DATA(2), TEST_DATA(3), TEST_DATA(4), 316 }; 317 u32 response[ARRAY_SIZE(request)]; 318 unsigned int n; 319 int ret; 320 321 test_requires_relay_testloop(test); 322 323 kunit_activate_static_stub(test, relay_kick_worker, relay_process_incoming_action); 324 kunit_activate_static_stub(test, xe_guc_ct_send_recv, 325 replacement_xe_guc_ct_send_recv_loopback_relay); 326 ret = xe_guc_relay_send_to_vf(relay, TEST_VFID, 327 request, ARRAY_SIZE(request), 328 response, ARRAY_SIZE(response)); 329 KUNIT_ASSERT_EQ(test, ret, ARRAY_SIZE(response)); 330 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_MSG_0_ORIGIN, response[0]), 331 GUC_HXG_ORIGIN_HOST); 332 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_MSG_0_TYPE, response[0]), 333 GUC_HXG_TYPE_RESPONSE_SUCCESS); 334 KUNIT_EXPECT_EQ(test, FIELD_GET(GUC_HXG_RESPONSE_MSG_0_DATA0, response[0]), 335 ARRAY_SIZE(response)); 336 for (n = GUC_HXG_RESPONSE_MSG_MIN_LEN; n < ret; n++) 337 KUNIT_EXPECT_EQ(test, request[n], response[n]); 338 } 339 340 static void pf_loopback_fail(struct kunit *test) 341 { 342 struct xe_guc_relay *relay = test->priv; 343 u32 request[] = { 344 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) | 345 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) | 346 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VFXPF_TESTLOOP) | 347 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_DATA0, VFXPF_TESTLOOP_OPCODE_FAIL), 348 }; 349 u32 response[GUC_HXG_RESPONSE_MSG_MIN_LEN]; 350 int ret; 351 352 test_requires_relay_testloop(test); 353 354 kunit_activate_static_stub(test, relay_kick_worker, relay_process_incoming_action); 355 kunit_activate_static_stub(test, xe_guc_ct_send_recv, 356 replacement_xe_guc_ct_send_recv_loopback_relay); 357 ret = xe_guc_relay_send_to_vf(relay, TEST_VFID, 358 request, ARRAY_SIZE(request), 359 response, ARRAY_SIZE(response)); 360 KUNIT_ASSERT_EQ(test, ret, -EREMOTEIO); 361 } 362 363 static void pf_loopback_busy(struct kunit *test) 364 { 365 struct xe_guc_relay *relay = test->priv; 366 u32 request[] = { 367 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) | 368 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) | 369 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VFXPF_TESTLOOP) | 370 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_DATA0, VFXPF_TESTLOOP_OPCODE_BUSY), 371 TEST_DATA(0xb), 372 }; 373 u32 response[GUC_HXG_RESPONSE_MSG_MIN_LEN]; 374 int ret; 375 376 test_requires_relay_testloop(test); 377 378 kunit_activate_static_stub(test, relay_testonly_nop, relay_process_incoming_action); 379 kunit_activate_static_stub(test, relay_kick_worker, relay_process_incoming_action); 380 kunit_activate_static_stub(test, xe_guc_ct_send_recv, 381 replacement_xe_guc_ct_send_recv_loopback_relay); 382 ret = xe_guc_relay_send_to_vf(relay, TEST_VFID, 383 request, ARRAY_SIZE(request), 384 response, ARRAY_SIZE(response)); 385 KUNIT_ASSERT_EQ(test, ret, GUC_HXG_RESPONSE_MSG_MIN_LEN); 386 } 387 388 static void pf_loopback_retry(struct kunit *test) 389 { 390 struct xe_guc_relay *relay = test->priv; 391 u32 request[] = { 392 FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) | 393 FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) | 394 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VFXPF_TESTLOOP) | 395 FIELD_PREP(GUC_HXG_REQUEST_MSG_0_DATA0, VFXPF_TESTLOOP_OPCODE_RETRY), 396 TEST_DATA(0xd), TEST_DATA(0xd), 397 }; 398 u32 response[GUC_HXG_RESPONSE_MSG_MIN_LEN]; 399 int ret; 400 401 test_requires_relay_testloop(test); 402 403 kunit_activate_static_stub(test, relay_kick_worker, relay_process_incoming_action); 404 kunit_activate_static_stub(test, xe_guc_ct_send_recv, 405 replacement_xe_guc_ct_send_recv_loopback_relay); 406 ret = xe_guc_relay_send_to_vf(relay, TEST_VFID, 407 request, ARRAY_SIZE(request), 408 response, ARRAY_SIZE(response)); 409 KUNIT_ASSERT_EQ(test, ret, GUC_HXG_RESPONSE_MSG_MIN_LEN); 410 } 411 412 static struct kunit_case pf_relay_test_cases[] = { 413 KUNIT_CASE(pf_rejects_guc2pf_too_short), 414 KUNIT_CASE(pf_rejects_guc2pf_too_long), 415 KUNIT_CASE(pf_rejects_guc2pf_no_payload), 416 KUNIT_CASE(pf_fails_no_payload), 417 KUNIT_CASE(pf_fails_bad_origin), 418 KUNIT_CASE(pf_fails_bad_type), 419 KUNIT_CASE(pf_txn_reports_error), 420 KUNIT_CASE(pf_txn_sends_pf2guc), 421 KUNIT_CASE(pf_sends_pf2guc), 422 KUNIT_CASE(pf_loopback_nop), 423 KUNIT_CASE(pf_loopback_echo), 424 KUNIT_CASE(pf_loopback_fail), 425 KUNIT_CASE_SLOW(pf_loopback_busy), 426 KUNIT_CASE_SLOW(pf_loopback_retry), 427 {} 428 }; 429 430 static struct kunit_suite pf_relay_suite = { 431 .name = "pf_relay", 432 .test_cases = pf_relay_test_cases, 433 .init = relay_test_init, 434 }; 435 436 static void vf_rejects_guc2vf_too_short(struct kunit *test) 437 { 438 const u32 len = GUC2VF_RELAY_FROM_PF_EVENT_MSG_MIN_LEN - 1; 439 struct xe_guc_relay *relay = test->priv; 440 const u32 *msg = test_guc2vf; 441 442 KUNIT_ASSERT_EQ(test, -EPROTO, xe_guc_relay_process_guc2vf(relay, msg, len)); 443 } 444 445 static void vf_rejects_guc2vf_too_long(struct kunit *test) 446 { 447 const u32 len = GUC2VF_RELAY_FROM_PF_EVENT_MSG_MAX_LEN + 1; 448 struct xe_guc_relay *relay = test->priv; 449 const u32 *msg = test_guc2vf; 450 451 KUNIT_ASSERT_EQ(test, -EMSGSIZE, xe_guc_relay_process_guc2vf(relay, msg, len)); 452 } 453 454 static void vf_rejects_guc2vf_no_payload(struct kunit *test) 455 { 456 const u32 len = GUC2VF_RELAY_FROM_PF_EVENT_MSG_MIN_LEN; 457 struct xe_guc_relay *relay = test->priv; 458 const u32 *msg = test_guc2vf; 459 460 KUNIT_ASSERT_EQ(test, -EPROTO, xe_guc_relay_process_guc2vf(relay, msg, len)); 461 } 462 463 static struct kunit_case vf_relay_test_cases[] = { 464 KUNIT_CASE(vf_rejects_guc2vf_too_short), 465 KUNIT_CASE(vf_rejects_guc2vf_too_long), 466 KUNIT_CASE(vf_rejects_guc2vf_no_payload), 467 {} 468 }; 469 470 static struct kunit_suite vf_relay_suite = { 471 .name = "vf_relay", 472 .test_cases = vf_relay_test_cases, 473 .init = relay_test_init, 474 }; 475 476 static void xe_drops_guc2pf_if_not_ready(struct kunit *test) 477 { 478 struct xe_device *xe = test->priv; 479 struct xe_guc_relay *relay = &xe_device_get_gt(xe, 0)->uc.guc.relay; 480 const u32 *msg = test_guc2pf; 481 u32 len = GUC2PF_RELAY_FROM_VF_EVENT_MSG_MIN_LEN + GUC_RELAY_MSG_MIN_LEN; 482 483 KUNIT_ASSERT_EQ(test, -ENODEV, xe_guc_relay_process_guc2pf(relay, msg, len)); 484 } 485 486 static void xe_drops_guc2vf_if_not_ready(struct kunit *test) 487 { 488 struct xe_device *xe = test->priv; 489 struct xe_guc_relay *relay = &xe_device_get_gt(xe, 0)->uc.guc.relay; 490 const u32 *msg = test_guc2vf; 491 u32 len = GUC2VF_RELAY_FROM_PF_EVENT_MSG_MIN_LEN + GUC_RELAY_MSG_MIN_LEN; 492 493 KUNIT_ASSERT_EQ(test, -ENODEV, xe_guc_relay_process_guc2vf(relay, msg, len)); 494 } 495 496 static void xe_rejects_send_if_not_ready(struct kunit *test) 497 { 498 struct xe_device *xe = test->priv; 499 struct xe_guc_relay *relay = &xe_device_get_gt(xe, 0)->uc.guc.relay; 500 u32 msg[GUC_RELAY_MSG_MIN_LEN]; 501 u32 len = ARRAY_SIZE(msg); 502 503 KUNIT_ASSERT_EQ(test, -ENODEV, xe_guc_relay_send_to_pf(relay, msg, len, NULL, 0)); 504 KUNIT_ASSERT_EQ(test, -ENODEV, relay_send_to(relay, TEST_VFID, msg, len, NULL, 0)); 505 } 506 507 static struct kunit_case no_relay_test_cases[] = { 508 KUNIT_CASE(xe_drops_guc2pf_if_not_ready), 509 KUNIT_CASE(xe_drops_guc2vf_if_not_ready), 510 KUNIT_CASE(xe_rejects_send_if_not_ready), 511 {} 512 }; 513 514 static struct kunit_suite no_relay_suite = { 515 .name = "no_relay", 516 .test_cases = no_relay_test_cases, 517 .init = xe_kunit_helper_xe_device_test_init, 518 }; 519 520 kunit_test_suites(&no_relay_suite, 521 &pf_relay_suite, 522 &vf_relay_suite); 523