1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2024, Vladimir Oltean <olteanv@gmail.com> 3 * Copyright (c) 2024, Intel Corporation. 4 */ 5 #include <kunit/test.h> 6 #include <linux/packing.h> 7 8 struct packing_test_case { 9 const char *desc; 10 const u8 *pbuf; 11 size_t pbuf_size; 12 u64 uval; 13 size_t start_bit; 14 size_t end_bit; 15 u8 quirks; 16 }; 17 18 #define NO_QUIRKS 0 19 20 /** 21 * PBUF - Initialize .pbuf and .pbuf_size 22 * @array: elements of constant physical buffer 23 * 24 * Initializes the .pbuf and .pbuf_size fields of a struct packing_test_case 25 * with a constant array of the specified elements. 26 */ 27 #define PBUF(array...) \ 28 .pbuf = (const u8[]){ array }, \ 29 .pbuf_size = sizeof((const u8 []){ array }) 30 31 static const struct packing_test_case cases[] = { 32 /* These tests pack and unpack a magic 64-bit value 33 * (0xcafedeadbeefcafe) at a fixed logical offset (32) within an 34 * otherwise zero array of 128 bits (16 bytes). They test all possible 35 * bit layouts of the 128 bit buffer. 36 */ 37 { 38 .desc = "no quirks, 16 bytes", 39 PBUF(0x00, 0x00, 0x00, 0x00, 0xca, 0xfe, 0xde, 0xad, 40 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00), 41 .uval = 0xcafedeadbeefcafe, 42 .start_bit = 95, 43 .end_bit = 32, 44 .quirks = NO_QUIRKS, 45 }, 46 { 47 .desc = "lsw32 first, 16 bytes", 48 PBUF(0x00, 0x00, 0x00, 0x00, 0xbe, 0xef, 0xca, 0xfe, 49 0xca, 0xfe, 0xde, 0xad, 0x00, 0x00, 0x00, 0x00), 50 .uval = 0xcafedeadbeefcafe, 51 .start_bit = 95, 52 .end_bit = 32, 53 .quirks = QUIRK_LSW32_IS_FIRST, 54 }, 55 { 56 .desc = "little endian words, 16 bytes", 57 PBUF(0x00, 0x00, 0x00, 0x00, 0xad, 0xde, 0xfe, 0xca, 58 0xfe, 0xca, 0xef, 0xbe, 0x00, 0x00, 0x00, 0x00), 59 .uval = 0xcafedeadbeefcafe, 60 .start_bit = 95, 61 .end_bit = 32, 62 .quirks = QUIRK_LITTLE_ENDIAN, 63 }, 64 { 65 .desc = "lsw32 first + little endian words, 16 bytes", 66 PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, 67 0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00), 68 .uval = 0xcafedeadbeefcafe, 69 .start_bit = 95, 70 .end_bit = 32, 71 .quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 72 }, 73 { 74 .desc = "msb right, 16 bytes", 75 PBUF(0x00, 0x00, 0x00, 0x00, 0x53, 0x7f, 0x7b, 0xb5, 76 0x7d, 0xf7, 0x53, 0x7f, 0x00, 0x00, 0x00, 0x00), 77 .uval = 0xcafedeadbeefcafe, 78 .start_bit = 95, 79 .end_bit = 32, 80 .quirks = QUIRK_MSB_ON_THE_RIGHT, 81 }, 82 { 83 .desc = "msb right + lsw32 first, 16 bytes", 84 PBUF(0x00, 0x00, 0x00, 0x00, 0x7d, 0xf7, 0x53, 0x7f, 85 0x53, 0x7f, 0x7b, 0xb5, 0x00, 0x00, 0x00, 0x00), 86 .uval = 0xcafedeadbeefcafe, 87 .start_bit = 95, 88 .end_bit = 32, 89 .quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST, 90 }, 91 { 92 .desc = "msb right + little endian words, 16 bytes", 93 PBUF(0x00, 0x00, 0x00, 0x00, 0xb5, 0x7b, 0x7f, 0x53, 94 0x7f, 0x53, 0xf7, 0x7d, 0x00, 0x00, 0x00, 0x00), 95 .uval = 0xcafedeadbeefcafe, 96 .start_bit = 95, 97 .end_bit = 32, 98 .quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LITTLE_ENDIAN, 99 }, 100 { 101 .desc = "msb right + lsw32 first + little endian words, 16 bytes", 102 PBUF(0x00, 0x00, 0x00, 0x00, 0x7f, 0x53, 0xf7, 0x7d, 103 0xb5, 0x7b, 0x7f, 0x53, 0x00, 0x00, 0x00, 0x00), 104 .uval = 0xcafedeadbeefcafe, 105 .start_bit = 95, 106 .end_bit = 32, 107 .quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 108 }, 109 /* These tests pack and unpack a magic 64-bit value 110 * (0xcafedeadbeefcafe) at a fixed logical offset (32) within an 111 * otherwise zero array of varying size from 18 bytes to 24 bytes. 112 */ 113 { 114 .desc = "no quirks, 18 bytes", 115 PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xfe, 116 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 117 0x00, 0x00), 118 .uval = 0xcafedeadbeefcafe, 119 .start_bit = 95, 120 .end_bit = 32, 121 .quirks = NO_QUIRKS, 122 }, 123 { 124 .desc = "no quirks, 19 bytes", 125 PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 126 0xfe, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, 127 0x00, 0x00, 0x00), 128 .uval = 0xcafedeadbeefcafe, 129 .start_bit = 95, 130 .end_bit = 32, 131 .quirks = NO_QUIRKS, 132 }, 133 { 134 .desc = "no quirks, 20 bytes", 135 PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 137 0x00, 0x00, 0x00, 0x00), 138 .uval = 0xcafedeadbeefcafe, 139 .start_bit = 95, 140 .end_bit = 32, 141 .quirks = NO_QUIRKS, 142 }, 143 { 144 .desc = "no quirks, 22 bytes", 145 PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 146 0x00, 0x00, 0xca, 0xfe, 0xde, 0xad, 0xbe, 0xef, 147 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00), 148 .uval = 0xcafedeadbeefcafe, 149 .start_bit = 95, 150 .end_bit = 32, 151 .quirks = NO_QUIRKS, 152 }, 153 { 154 .desc = "no quirks, 24 bytes", 155 PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 156 0x00, 0x00, 0x00, 0x00, 0xca, 0xfe, 0xde, 0xad, 157 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00), 158 .uval = 0xcafedeadbeefcafe, 159 .start_bit = 95, 160 .end_bit = 32, 161 .quirks = NO_QUIRKS, 162 }, 163 { 164 .desc = "lsw32 first + little endian words, 18 bytes", 165 PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, 166 0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, 167 0x00, 0x00), 168 .uval = 0xcafedeadbeefcafe, 169 .start_bit = 95, 170 .end_bit = 32, 171 .quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 172 }, 173 { 174 .desc = "lsw32 first + little endian words, 19 bytes", 175 PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, 176 0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, 177 0x00, 0x00, 0x00), 178 .uval = 0xcafedeadbeefcafe, 179 .start_bit = 95, 180 .end_bit = 32, 181 .quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 182 }, 183 { 184 .desc = "lsw32 first + little endian words, 20 bytes", 185 PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, 186 0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, 187 0x00, 0x00, 0x00, 0x00), 188 .uval = 0xcafedeadbeefcafe, 189 .start_bit = 95, 190 .end_bit = 32, 191 .quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 192 }, 193 { 194 .desc = "lsw32 first + little endian words, 22 bytes", 195 PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, 196 0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, 197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), 198 .uval = 0xcafedeadbeefcafe, 199 .start_bit = 95, 200 .end_bit = 32, 201 .quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 202 }, 203 { 204 .desc = "lsw32 first + little endian words, 24 bytes", 205 PBUF(0x00, 0x00, 0x00, 0x00, 0xfe, 0xca, 0xef, 0xbe, 206 0xad, 0xde, 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, 207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), 208 .uval = 0xcafedeadbeefcafe, 209 .start_bit = 95, 210 .end_bit = 32, 211 .quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 212 }, 213 /* These tests pack and unpack a magic 64-bit value 214 * (0x1122334455667788) at an odd starting bit (43) within an 215 * otherwise zero array of 128 bits (16 bytes). They test all possible 216 * bit layouts of the 128 bit buffer. 217 */ 218 { 219 .desc = "no quirks, 16 bytes, non-aligned", 220 PBUF(0x00, 0x00, 0x00, 0x89, 0x11, 0x9a, 0x22, 0xab, 221 0x33, 0xbc, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00), 222 .uval = 0x1122334455667788, 223 .start_bit = 106, 224 .end_bit = 43, 225 .quirks = NO_QUIRKS, 226 }, 227 { 228 .desc = "lsw32 first, 16 bytes, non-aligned", 229 PBUF(0x00, 0x00, 0x00, 0x00, 0x33, 0xbc, 0x40, 0x00, 230 0x11, 0x9a, 0x22, 0xab, 0x00, 0x00, 0x00, 0x89), 231 .uval = 0x1122334455667788, 232 .start_bit = 106, 233 .end_bit = 43, 234 .quirks = QUIRK_LSW32_IS_FIRST, 235 }, 236 { 237 .desc = "little endian words, 16 bytes, non-aligned", 238 PBUF(0x89, 0x00, 0x00, 0x00, 0xab, 0x22, 0x9a, 0x11, 239 0x00, 0x40, 0xbc, 0x33, 0x00, 0x00, 0x00, 0x00), 240 .uval = 0x1122334455667788, 241 .start_bit = 106, 242 .end_bit = 43, 243 .quirks = QUIRK_LITTLE_ENDIAN, 244 }, 245 { 246 .desc = "lsw32 first + little endian words, 16 bytes, non-aligned", 247 PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xbc, 0x33, 248 0xab, 0x22, 0x9a, 0x11, 0x89, 0x00, 0x00, 0x00), 249 .uval = 0x1122334455667788, 250 .start_bit = 106, 251 .end_bit = 43, 252 .quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 253 }, 254 { 255 .desc = "msb right, 16 bytes, non-aligned", 256 PBUF(0x00, 0x00, 0x00, 0x91, 0x88, 0x59, 0x44, 0xd5, 257 0xcc, 0x3d, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00), 258 .uval = 0x1122334455667788, 259 .start_bit = 106, 260 .end_bit = 43, 261 .quirks = QUIRK_MSB_ON_THE_RIGHT, 262 }, 263 { 264 .desc = "msb right + lsw32 first, 16 bytes, non-aligned", 265 PBUF(0x00, 0x00, 0x00, 0x00, 0xcc, 0x3d, 0x02, 0x00, 266 0x88, 0x59, 0x44, 0xd5, 0x00, 0x00, 0x00, 0x91), 267 .uval = 0x1122334455667788, 268 .start_bit = 106, 269 .end_bit = 43, 270 .quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST, 271 }, 272 { 273 .desc = "msb right + little endian words, 16 bytes, non-aligned", 274 PBUF(0x91, 0x00, 0x00, 0x00, 0xd5, 0x44, 0x59, 0x88, 275 0x00, 0x02, 0x3d, 0xcc, 0x00, 0x00, 0x00, 0x00), 276 .uval = 0x1122334455667788, 277 .start_bit = 106, 278 .end_bit = 43, 279 .quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LITTLE_ENDIAN, 280 }, 281 { 282 .desc = "msb right + lsw32 first + little endian words, 16 bytes, non-aligned", 283 PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3d, 0xcc, 284 0xd5, 0x44, 0x59, 0x88, 0x91, 0x00, 0x00, 0x00), 285 .uval = 0x1122334455667788, 286 .start_bit = 106, 287 .end_bit = 43, 288 .quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 289 }, 290 /* These tests pack and unpack a u64 with all bits set 291 * (0xffffffffffffffff) at an odd starting bit (43) within an 292 * otherwise zero array of 128 bits (16 bytes). They test all possible 293 * bit layouts of the 128 bit buffer. 294 */ 295 { 296 .desc = "no quirks, 16 bytes, non-aligned, 0xff", 297 PBUF(0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 298 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00), 299 .uval = 0xffffffffffffffff, 300 .start_bit = 106, 301 .end_bit = 43, 302 .quirks = NO_QUIRKS, 303 }, 304 { 305 .desc = "lsw32 first, 16 bytes, non-aligned, 0xff", 306 PBUF(0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00, 307 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x07, 0xff), 308 .uval = 0xffffffffffffffff, 309 .start_bit = 106, 310 .end_bit = 43, 311 .quirks = QUIRK_LSW32_IS_FIRST, 312 }, 313 { 314 .desc = "little endian words, 16 bytes, non-aligned, 0xff", 315 PBUF(0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 316 0x00, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00), 317 .uval = 0xffffffffffffffff, 318 .start_bit = 106, 319 .end_bit = 43, 320 .quirks = QUIRK_LITTLE_ENDIAN, 321 }, 322 { 323 .desc = "lsw32 first + little endian words, 16 bytes, non-aligned, 0xff", 324 PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 325 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00), 326 .uval = 0xffffffffffffffff, 327 .start_bit = 106, 328 .end_bit = 43, 329 .quirks = QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 330 }, 331 { 332 .desc = "msb right, 16 bytes, non-aligned, 0xff", 333 PBUF(0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 334 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00), 335 .uval = 0xffffffffffffffff, 336 .start_bit = 106, 337 .end_bit = 43, 338 .quirks = QUIRK_MSB_ON_THE_RIGHT, 339 }, 340 { 341 .desc = "msb right + lsw32 first, 16 bytes, non-aligned, 0xff", 342 PBUF(0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1f, 0x00, 343 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xe0, 0xff), 344 .uval = 0xffffffffffffffff, 345 .start_bit = 106, 346 .end_bit = 43, 347 .quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST, 348 }, 349 { 350 .desc = "msb right + little endian words, 16 bytes, non-aligned, 0xff", 351 PBUF(0xff, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 352 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00), 353 .uval = 0xffffffffffffffff, 354 .start_bit = 106, 355 .end_bit = 43, 356 .quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LITTLE_ENDIAN, 357 }, 358 { 359 .desc = "msb right + lsw32 first + little endian words, 16 bytes, non-aligned, 0xff", 360 PBUF(0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 361 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00), 362 .uval = 0xffffffffffffffff, 363 .start_bit = 106, 364 .end_bit = 43, 365 .quirks = QUIRK_MSB_ON_THE_RIGHT | QUIRK_LSW32_IS_FIRST | QUIRK_LITTLE_ENDIAN, 366 }, 367 }; 368 369 KUNIT_ARRAY_PARAM_DESC(packing, cases, desc); 370 371 static void packing_test_pack(struct kunit *test) 372 { 373 const struct packing_test_case *params = test->param_value; 374 u8 *pbuf; 375 int err; 376 377 pbuf = kunit_kzalloc(test, params->pbuf_size, GFP_KERNEL); 378 KUNIT_ASSERT_NOT_NULL(test, pbuf); 379 380 err = pack(pbuf, params->uval, params->start_bit, params->end_bit, 381 params->pbuf_size, params->quirks); 382 383 KUNIT_EXPECT_EQ_MSG(test, err, 0, "pack() returned %pe\n", ERR_PTR(err)); 384 KUNIT_EXPECT_MEMEQ(test, pbuf, params->pbuf, params->pbuf_size); 385 } 386 387 static void packing_test_unpack(struct kunit *test) 388 { 389 const struct packing_test_case *params = test->param_value; 390 u64 uval; 391 int err; 392 393 err = unpack(params->pbuf, &uval, params->start_bit, params->end_bit, 394 params->pbuf_size, params->quirks); 395 KUNIT_EXPECT_EQ_MSG(test, err, 0, "unpack() returned %pe\n", ERR_PTR(err)); 396 KUNIT_EXPECT_EQ(test, uval, params->uval); 397 } 398 399 static struct kunit_case packing_test_cases[] = { 400 KUNIT_CASE_PARAM(packing_test_pack, packing_gen_params), 401 KUNIT_CASE_PARAM(packing_test_unpack, packing_gen_params), 402 {}, 403 }; 404 405 static struct kunit_suite packing_test_suite = { 406 .name = "packing", 407 .test_cases = packing_test_cases, 408 }; 409 410 kunit_test_suite(packing_test_suite); 411 412 MODULE_LICENSE("GPL"); 413 MODULE_DESCRIPTION("KUnit tests for packing library"); 414