diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/btf.c | 104 |
1 files changed, 85 insertions, 19 deletions
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index a2f53642592b..022ef9ca1296 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c | |||
| @@ -157,7 +157,7 @@ | |||
| 157 | * | 157 | * |
| 158 | */ | 158 | */ |
| 159 | 159 | ||
| 160 | #define BITS_PER_U64 (sizeof(u64) * BITS_PER_BYTE) | 160 | #define BITS_PER_U128 (sizeof(u64) * BITS_PER_BYTE * 2) |
| 161 | #define BITS_PER_BYTE_MASK (BITS_PER_BYTE - 1) | 161 | #define BITS_PER_BYTE_MASK (BITS_PER_BYTE - 1) |
| 162 | #define BITS_PER_BYTE_MASKED(bits) ((bits) & BITS_PER_BYTE_MASK) | 162 | #define BITS_PER_BYTE_MASKED(bits) ((bits) & BITS_PER_BYTE_MASK) |
| 163 | #define BITS_ROUNDDOWN_BYTES(bits) ((bits) >> 3) | 163 | #define BITS_ROUNDDOWN_BYTES(bits) ((bits) >> 3) |
| @@ -525,7 +525,7 @@ const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id) | |||
| 525 | 525 | ||
| 526 | /* | 526 | /* |
| 527 | * Regular int is not a bit field and it must be either | 527 | * Regular int is not a bit field and it must be either |
| 528 | * u8/u16/u32/u64. | 528 | * u8/u16/u32/u64 or __int128. |
| 529 | */ | 529 | */ |
| 530 | static bool btf_type_int_is_regular(const struct btf_type *t) | 530 | static bool btf_type_int_is_regular(const struct btf_type *t) |
| 531 | { | 531 | { |
| @@ -538,7 +538,8 @@ static bool btf_type_int_is_regular(const struct btf_type *t) | |||
| 538 | if (BITS_PER_BYTE_MASKED(nr_bits) || | 538 | if (BITS_PER_BYTE_MASKED(nr_bits) || |
| 539 | BTF_INT_OFFSET(int_data) || | 539 | BTF_INT_OFFSET(int_data) || |
| 540 | (nr_bytes != sizeof(u8) && nr_bytes != sizeof(u16) && | 540 | (nr_bytes != sizeof(u8) && nr_bytes != sizeof(u16) && |
| 541 | nr_bytes != sizeof(u32) && nr_bytes != sizeof(u64))) { | 541 | nr_bytes != sizeof(u32) && nr_bytes != sizeof(u64) && |
| 542 | nr_bytes != (2 * sizeof(u64)))) { | ||
| 542 | return false; | 543 | return false; |
| 543 | } | 544 | } |
| 544 | 545 | ||
| @@ -1063,9 +1064,9 @@ static int btf_int_check_member(struct btf_verifier_env *env, | |||
| 1063 | nr_copy_bits = BTF_INT_BITS(int_data) + | 1064 | nr_copy_bits = BTF_INT_BITS(int_data) + |
| 1064 | BITS_PER_BYTE_MASKED(struct_bits_off); | 1065 | BITS_PER_BYTE_MASKED(struct_bits_off); |
| 1065 | 1066 | ||
| 1066 | if (nr_copy_bits > BITS_PER_U64) { | 1067 | if (nr_copy_bits > BITS_PER_U128) { |
| 1067 | btf_verifier_log_member(env, struct_type, member, | 1068 | btf_verifier_log_member(env, struct_type, member, |
| 1068 | "nr_copy_bits exceeds 64"); | 1069 | "nr_copy_bits exceeds 128"); |
| 1069 | return -EINVAL; | 1070 | return -EINVAL; |
| 1070 | } | 1071 | } |
| 1071 | 1072 | ||
| @@ -1119,9 +1120,9 @@ static int btf_int_check_kflag_member(struct btf_verifier_env *env, | |||
| 1119 | 1120 | ||
| 1120 | bytes_offset = BITS_ROUNDDOWN_BYTES(struct_bits_off); | 1121 | bytes_offset = BITS_ROUNDDOWN_BYTES(struct_bits_off); |
| 1121 | nr_copy_bits = nr_bits + BITS_PER_BYTE_MASKED(struct_bits_off); | 1122 | nr_copy_bits = nr_bits + BITS_PER_BYTE_MASKED(struct_bits_off); |
| 1122 | if (nr_copy_bits > BITS_PER_U64) { | 1123 | if (nr_copy_bits > BITS_PER_U128) { |
| 1123 | btf_verifier_log_member(env, struct_type, member, | 1124 | btf_verifier_log_member(env, struct_type, member, |
| 1124 | "nr_copy_bits exceeds 64"); | 1125 | "nr_copy_bits exceeds 128"); |
| 1125 | return -EINVAL; | 1126 | return -EINVAL; |
| 1126 | } | 1127 | } |
| 1127 | 1128 | ||
| @@ -1168,9 +1169,9 @@ static s32 btf_int_check_meta(struct btf_verifier_env *env, | |||
| 1168 | 1169 | ||
| 1169 | nr_bits = BTF_INT_BITS(int_data) + BTF_INT_OFFSET(int_data); | 1170 | nr_bits = BTF_INT_BITS(int_data) + BTF_INT_OFFSET(int_data); |
| 1170 | 1171 | ||
| 1171 | if (nr_bits > BITS_PER_U64) { | 1172 | if (nr_bits > BITS_PER_U128) { |
| 1172 | btf_verifier_log_type(env, t, "nr_bits exceeds %zu", | 1173 | btf_verifier_log_type(env, t, "nr_bits exceeds %zu", |
| 1173 | BITS_PER_U64); | 1174 | BITS_PER_U128); |
| 1174 | return -EINVAL; | 1175 | return -EINVAL; |
| 1175 | } | 1176 | } |
| 1176 | 1177 | ||
| @@ -1211,31 +1212,93 @@ static void btf_int_log(struct btf_verifier_env *env, | |||
| 1211 | btf_int_encoding_str(BTF_INT_ENCODING(int_data))); | 1212 | btf_int_encoding_str(BTF_INT_ENCODING(int_data))); |
| 1212 | } | 1213 | } |
| 1213 | 1214 | ||
| 1215 | static void btf_int128_print(struct seq_file *m, void *data) | ||
| 1216 | { | ||
| 1217 | /* data points to a __int128 number. | ||
| 1218 | * Suppose | ||
| 1219 | * int128_num = *(__int128 *)data; | ||
| 1220 | * The below formulas shows what upper_num and lower_num represents: | ||
| 1221 | * upper_num = int128_num >> 64; | ||
| 1222 | * lower_num = int128_num & 0xffffffffFFFFFFFFULL; | ||
| 1223 | */ | ||
| 1224 | u64 upper_num, lower_num; | ||
| 1225 | |||
| 1226 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 1227 | upper_num = *(u64 *)data; | ||
| 1228 | lower_num = *(u64 *)(data + 8); | ||
| 1229 | #else | ||
| 1230 | upper_num = *(u64 *)(data + 8); | ||
| 1231 | lower_num = *(u64 *)data; | ||
| 1232 | #endif | ||
| 1233 | if (upper_num == 0) | ||
| 1234 | seq_printf(m, "0x%llx", lower_num); | ||
| 1235 | else | ||
| 1236 | seq_printf(m, "0x%llx%016llx", upper_num, lower_num); | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | static void btf_int128_shift(u64 *print_num, u16 left_shift_bits, | ||
| 1240 | u16 right_shift_bits) | ||
| 1241 | { | ||
| 1242 | u64 upper_num, lower_num; | ||
| 1243 | |||
| 1244 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 1245 | upper_num = print_num[0]; | ||
| 1246 | lower_num = print_num[1]; | ||
| 1247 | #else | ||
| 1248 | upper_num = print_num[1]; | ||
| 1249 | lower_num = print_num[0]; | ||
| 1250 | #endif | ||
| 1251 | |||
| 1252 | /* shake out un-needed bits by shift/or operations */ | ||
| 1253 | if (left_shift_bits >= 64) { | ||
| 1254 | upper_num = lower_num << (left_shift_bits - 64); | ||
| 1255 | lower_num = 0; | ||
| 1256 | } else { | ||
| 1257 | upper_num = (upper_num << left_shift_bits) | | ||
| 1258 | (lower_num >> (64 - left_shift_bits)); | ||
| 1259 | lower_num = lower_num << left_shift_bits; | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | if (right_shift_bits >= 64) { | ||
| 1263 | lower_num = upper_num >> (right_shift_bits - 64); | ||
| 1264 | upper_num = 0; | ||
| 1265 | } else { | ||
| 1266 | lower_num = (lower_num >> right_shift_bits) | | ||
| 1267 | (upper_num << (64 - right_shift_bits)); | ||
| 1268 | upper_num = upper_num >> right_shift_bits; | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 1272 | print_num[0] = upper_num; | ||
| 1273 | print_num[1] = lower_num; | ||
| 1274 | #else | ||
| 1275 | print_num[0] = lower_num; | ||
| 1276 | print_num[1] = upper_num; | ||
| 1277 | #endif | ||
| 1278 | } | ||
| 1279 | |||
| 1214 | static void btf_bitfield_seq_show(void *data, u8 bits_offset, | 1280 | static void btf_bitfield_seq_show(void *data, u8 bits_offset, |
| 1215 | u8 nr_bits, struct seq_file *m) | 1281 | u8 nr_bits, struct seq_file *m) |
| 1216 | { | 1282 | { |
| 1217 | u16 left_shift_bits, right_shift_bits; | 1283 | u16 left_shift_bits, right_shift_bits; |
| 1218 | u8 nr_copy_bytes; | 1284 | u8 nr_copy_bytes; |
| 1219 | u8 nr_copy_bits; | 1285 | u8 nr_copy_bits; |
| 1220 | u64 print_num; | 1286 | u64 print_num[2] = {}; |
| 1221 | 1287 | ||
| 1222 | nr_copy_bits = nr_bits + bits_offset; | 1288 | nr_copy_bits = nr_bits + bits_offset; |
| 1223 | nr_copy_bytes = BITS_ROUNDUP_BYTES(nr_copy_bits); | 1289 | nr_copy_bytes = BITS_ROUNDUP_BYTES(nr_copy_bits); |
| 1224 | 1290 | ||
| 1225 | print_num = 0; | 1291 | memcpy(print_num, data, nr_copy_bytes); |
| 1226 | memcpy(&print_num, data, nr_copy_bytes); | ||
| 1227 | 1292 | ||
| 1228 | #ifdef __BIG_ENDIAN_BITFIELD | 1293 | #ifdef __BIG_ENDIAN_BITFIELD |
| 1229 | left_shift_bits = bits_offset; | 1294 | left_shift_bits = bits_offset; |
| 1230 | #else | 1295 | #else |
| 1231 | left_shift_bits = BITS_PER_U64 - nr_copy_bits; | 1296 | left_shift_bits = BITS_PER_U128 - nr_copy_bits; |
| 1232 | #endif | 1297 | #endif |
| 1233 | right_shift_bits = BITS_PER_U64 - nr_bits; | 1298 | right_shift_bits = BITS_PER_U128 - nr_bits; |
| 1234 | |||
| 1235 | print_num <<= left_shift_bits; | ||
| 1236 | print_num >>= right_shift_bits; | ||
| 1237 | 1299 | ||
| 1238 | seq_printf(m, "0x%llx", print_num); | 1300 | btf_int128_shift(print_num, left_shift_bits, right_shift_bits); |
| 1301 | btf_int128_print(m, print_num); | ||
| 1239 | } | 1302 | } |
| 1240 | 1303 | ||
| 1241 | 1304 | ||
| @@ -1250,7 +1313,7 @@ static void btf_int_bits_seq_show(const struct btf *btf, | |||
| 1250 | 1313 | ||
| 1251 | /* | 1314 | /* |
| 1252 | * bits_offset is at most 7. | 1315 | * bits_offset is at most 7. |
| 1253 | * BTF_INT_OFFSET() cannot exceed 64 bits. | 1316 | * BTF_INT_OFFSET() cannot exceed 128 bits. |
| 1254 | */ | 1317 | */ |
| 1255 | total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data); | 1318 | total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data); |
| 1256 | data += BITS_ROUNDDOWN_BYTES(total_bits_offset); | 1319 | data += BITS_ROUNDDOWN_BYTES(total_bits_offset); |
| @@ -1274,6 +1337,9 @@ static void btf_int_seq_show(const struct btf *btf, const struct btf_type *t, | |||
| 1274 | } | 1337 | } |
| 1275 | 1338 | ||
| 1276 | switch (nr_bits) { | 1339 | switch (nr_bits) { |
| 1340 | case 128: | ||
| 1341 | btf_int128_print(m, data); | ||
| 1342 | break; | ||
| 1277 | case 64: | 1343 | case 64: |
| 1278 | if (sign) | 1344 | if (sign) |
| 1279 | seq_printf(m, "%lld", *(s64 *)data); | 1345 | seq_printf(m, "%lld", *(s64 *)data); |
