0001
0002
0003
0004
0005 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0006
0007 #include <kunit/test.h>
0008 #include <linux/device.h>
0009 #include <linux/init.h>
0010 #include <linux/kernel.h>
0011 #include <linux/mm.h>
0012 #include <linux/module.h>
0013 #include <linux/overflow.h>
0014 #include <linux/slab.h>
0015 #include <linux/types.h>
0016 #include <linux/vmalloc.h>
0017
0018 struct some_bytes {
0019 union {
0020 u8 data[32];
0021 struct {
0022 u32 one;
0023 u16 two;
0024 u8 three;
0025
0026 u32 four[4];
0027 };
0028 };
0029 };
0030
0031 #define check(instance, v) do { \
0032 int i; \
0033 BUILD_BUG_ON(sizeof(instance.data) != 32); \
0034 for (i = 0; i < sizeof(instance.data); i++) { \
0035 KUNIT_ASSERT_EQ_MSG(test, instance.data[i], v, \
0036 "line %d: '%s' not initialized to 0x%02x @ %d (saw 0x%02x)\n", \
0037 __LINE__, #instance, v, i, instance.data[i]); \
0038 } \
0039 } while (0)
0040
0041 #define compare(name, one, two) do { \
0042 int i; \
0043 BUILD_BUG_ON(sizeof(one) != sizeof(two)); \
0044 for (i = 0; i < sizeof(one); i++) { \
0045 KUNIT_EXPECT_EQ_MSG(test, one.data[i], two.data[i], \
0046 "line %d: %s.data[%d] (0x%02x) != %s.data[%d] (0x%02x)\n", \
0047 __LINE__, #one, i, one.data[i], #two, i, two.data[i]); \
0048 } \
0049 kunit_info(test, "ok: " TEST_OP "() " name "\n"); \
0050 } while (0)
0051
0052 static void memcpy_test(struct kunit *test)
0053 {
0054 #define TEST_OP "memcpy"
0055 struct some_bytes control = {
0056 .data = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0057 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0058 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0059 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0060 },
0061 };
0062 struct some_bytes zero = { };
0063 struct some_bytes middle = {
0064 .data = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0065 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
0066 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0067 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0068 },
0069 };
0070 struct some_bytes three = {
0071 .data = { 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0072 0x20, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
0073 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0074 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0075 },
0076 };
0077 struct some_bytes dest = { };
0078 int count;
0079 u8 *ptr;
0080
0081
0082 check(control, 0x20);
0083 check(zero, 0);
0084 compare("static initializers", dest, zero);
0085
0086
0087 dest = control;
0088 compare("direct assignment", dest, control);
0089
0090
0091 memcpy(dest.data, zero.data, sizeof(dest.data));
0092 compare("complete overwrite", dest, zero);
0093
0094
0095 dest = control;
0096 memcpy(dest.data + 12, zero.data, 7);
0097 compare("middle overwrite", dest, middle);
0098
0099
0100 dest = control;
0101 ptr = dest.data;
0102 count = 1;
0103 memcpy(ptr++, zero.data, count++);
0104 ptr += 8;
0105 memcpy(ptr++, zero.data, count++);
0106 compare("argument side-effects", dest, three);
0107 #undef TEST_OP
0108 }
0109
0110 static void memmove_test(struct kunit *test)
0111 {
0112 #define TEST_OP "memmove"
0113 struct some_bytes control = {
0114 .data = { 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0115 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0116 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0117 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0118 },
0119 };
0120 struct some_bytes zero = { };
0121 struct some_bytes middle = {
0122 .data = { 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0123 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00,
0124 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99,
0125 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0126 },
0127 };
0128 struct some_bytes five = {
0129 .data = { 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0130 0x99, 0x99, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99,
0131 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0132 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0133 },
0134 };
0135 struct some_bytes overlap = {
0136 .data = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0137 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0138 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0139 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0140 },
0141 };
0142 struct some_bytes overlap_expected = {
0143 .data = { 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x07,
0144 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0145 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0146 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0147 },
0148 };
0149 struct some_bytes dest = { };
0150 int count;
0151 u8 *ptr;
0152
0153
0154 check(control, 0x99);
0155 check(zero, 0);
0156 compare("static initializers", zero, dest);
0157
0158
0159 dest = control;
0160 compare("direct assignment", dest, control);
0161
0162
0163 memmove(dest.data, zero.data, sizeof(dest.data));
0164 compare("complete overwrite", dest, zero);
0165
0166
0167 dest = control;
0168 memmove(dest.data + 12, zero.data, 7);
0169 compare("middle overwrite", dest, middle);
0170
0171
0172 dest = control;
0173 ptr = dest.data;
0174 count = 2;
0175 memmove(ptr++, zero.data, count++);
0176 ptr += 9;
0177 memmove(ptr++, zero.data, count++);
0178 compare("argument side-effects", dest, five);
0179
0180
0181 ptr = &overlap.data[2];
0182 memmove(ptr, overlap.data, 5);
0183 compare("overlapping write", overlap, overlap_expected);
0184 #undef TEST_OP
0185 }
0186
0187 static void memset_test(struct kunit *test)
0188 {
0189 #define TEST_OP "memset"
0190 struct some_bytes control = {
0191 .data = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0192 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0193 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0194 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0195 },
0196 };
0197 struct some_bytes complete = {
0198 .data = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0199 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0200 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0201 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0202 },
0203 };
0204 struct some_bytes middle = {
0205 .data = { 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
0206 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
0207 0x31, 0x31, 0x31, 0x31, 0x30, 0x30, 0x30, 0x30,
0208 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0209 },
0210 };
0211 struct some_bytes three = {
0212 .data = { 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0213 0x30, 0x61, 0x61, 0x30, 0x30, 0x30, 0x30, 0x30,
0214 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0215 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0216 },
0217 };
0218 struct some_bytes after = {
0219 .data = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x72,
0220 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
0221 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
0222 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
0223 },
0224 };
0225 struct some_bytes startat = {
0226 .data = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0227 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
0228 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
0229 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
0230 },
0231 };
0232 struct some_bytes dest = { };
0233 int count, value;
0234 u8 *ptr;
0235
0236
0237 check(control, 0x30);
0238 check(dest, 0);
0239
0240
0241 dest = control;
0242 compare("direct assignment", dest, control);
0243
0244
0245 memset(dest.data, 0xff, sizeof(dest.data));
0246 compare("complete overwrite", dest, complete);
0247
0248
0249 dest = control;
0250 memset(dest.data + 4, 0x31, 16);
0251 compare("middle overwrite", dest, middle);
0252
0253
0254 dest = control;
0255 ptr = dest.data;
0256 value = 0x60;
0257 count = 1;
0258 memset(ptr++, value++, count++);
0259 ptr += 8;
0260 memset(ptr++, value++, count++);
0261 compare("argument side-effects", dest, three);
0262
0263
0264 dest = control;
0265 memset_after(&dest, 0x72, three);
0266 compare("memset_after()", dest, after);
0267
0268
0269 dest = control;
0270 memset_startat(&dest, 0x79, four);
0271 compare("memset_startat()", dest, startat);
0272 #undef TEST_OP
0273 }
0274
0275 static struct kunit_case memcpy_test_cases[] = {
0276 KUNIT_CASE(memset_test),
0277 KUNIT_CASE(memcpy_test),
0278 KUNIT_CASE(memmove_test),
0279 {}
0280 };
0281
0282 static struct kunit_suite memcpy_test_suite = {
0283 .name = "memcpy",
0284 .test_cases = memcpy_test_cases,
0285 };
0286
0287 kunit_test_suite(memcpy_test_suite);
0288
0289 MODULE_LICENSE("GPL");