Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf maps: Ensure kmap is set up for all inserts

__maps__fixup_overlap_and_insert may split or directly insert a map,
when doing this the map may need to have a kmap set up for the sake of
the kmaps. The missing kmap set up fails the check_invariants test in
maps, later "Internal error" reports from map__kmap and ultimately
causes segfaults.

Similar fixes were added in commit e0e4e0b8b7fa ("perf maps: Add
missing map__set_kmap_maps() when replacing a kernel map") and commit
25d9c0301d36 ("perf maps: Set the kmaps for newly created/added kernel
maps") but they missed cases. To try to reduce the risk of this,
update the kmap directly following any manual insert. This identified
another problem in maps__copy_from.

Fixes: e0e4e0b8b7fa ("perf maps: Add missing map__set_kmap_maps() when replacing a kernel map")
Fixes: 25d9c0301d36 ("perf maps: Set the kmaps for newly created/added kernel maps")
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Ian Rogers and committed by
Namhyung Kim
20c9ccff 7947ad15

+5 -4
+5 -4
tools/perf/util/maps.c
··· 477 477 } 478 478 /* Insert the value at the end. */ 479 479 maps_by_address[nr_maps] = map__get(new); 480 + map__set_kmap_maps(new, maps); 480 481 if (maps_by_name) 481 482 maps_by_name[nr_maps] = map__get(new); 482 483 ··· 502 501 } 503 502 if (map__end(new) < map__start(new)) 504 503 RC_CHK_ACCESS(maps)->ends_broken = true; 505 - 506 - map__set_kmap_maps(new, maps); 507 504 508 505 return 0; 509 506 } ··· 890 891 if (before) { 891 892 map__put(maps_by_address[i]); 892 893 maps_by_address[i] = before; 894 + map__set_kmap_maps(before, maps); 893 895 894 896 if (maps_by_name) { 895 897 map__put(maps_by_name[ni]); ··· 918 918 */ 919 919 map__put(maps_by_address[i]); 920 920 maps_by_address[i] = map__get(new); 921 + map__set_kmap_maps(new, maps); 921 922 922 923 if (maps_by_name) { 923 924 map__put(maps_by_name[ni]); ··· 943 942 */ 944 943 map__put(maps_by_address[i]); 945 944 maps_by_address[i] = map__get(new); 945 + map__set_kmap_maps(new, maps); 946 946 947 947 if (maps_by_name) { 948 948 map__put(maps_by_name[ni]); 949 949 maps_by_name[ni] = map__get(new); 950 950 } 951 - 952 - map__set_kmap_maps(new, maps); 953 951 954 952 check_invariants(maps); 955 953 return err; ··· 1019 1019 err = unwind__prepare_access(dest, new, NULL); 1020 1020 if (!err) { 1021 1021 dest_maps_by_address[i] = new; 1022 + map__set_kmap_maps(new, dest); 1022 1023 if (dest_maps_by_name) 1023 1024 dest_maps_by_name[i] = map__get(new); 1024 1025 RC_CHK_ACCESS(dest)->nr_maps = i + 1;