aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/bpf/btf.c104
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 */
530static bool btf_type_int_is_regular(const struct btf_type *t) 530static 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
1215static 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
1239static 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
1214static void btf_bitfield_seq_show(void *data, u8 bits_offset, 1280static 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);