diff options
| author | Adrian Hunter <adrian.hunter@intel.com> | 2018-05-22 06:54:44 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-05-23 09:26:43 -0400 |
| commit | a1a3a0624e6cd0e2c46a7400800a5e687521a504 (patch) | |
| tree | f8b8312e9d817c1b70043ccf59d7120bf5a6a961 | |
| parent | b4503cdb67098b2f08320c2c83df758ea72a4431 (diff) | |
perf kcore_copy: Copy x86 PTI entry trampoline sections
Identify and copy any sections for x86 PTI entry trampolines.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
Link: http://lkml.kernel.org/r/1526986485-6562-17-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| -rw-r--r-- | tools/perf/util/symbol-elf.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 37d9324c277c..584966913aeb 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
| @@ -1392,6 +1392,11 @@ struct phdr_data { | |||
| 1392 | struct list_head node; | 1392 | struct list_head node; |
| 1393 | }; | 1393 | }; |
| 1394 | 1394 | ||
| 1395 | struct sym_data { | ||
| 1396 | u64 addr; | ||
| 1397 | struct list_head node; | ||
| 1398 | }; | ||
| 1399 | |||
| 1395 | struct kcore_copy_info { | 1400 | struct kcore_copy_info { |
| 1396 | u64 stext; | 1401 | u64 stext; |
| 1397 | u64 etext; | 1402 | u64 etext; |
| @@ -1401,6 +1406,7 @@ struct kcore_copy_info { | |||
| 1401 | u64 last_module_symbol; | 1406 | u64 last_module_symbol; |
| 1402 | size_t phnum; | 1407 | size_t phnum; |
| 1403 | struct list_head phdrs; | 1408 | struct list_head phdrs; |
| 1409 | struct list_head syms; | ||
| 1404 | }; | 1410 | }; |
| 1405 | 1411 | ||
| 1406 | #define kcore_copy__for_each_phdr(k, p) \ | 1412 | #define kcore_copy__for_each_phdr(k, p) \ |
| @@ -1441,6 +1447,29 @@ static void kcore_copy__free_phdrs(struct kcore_copy_info *kci) | |||
| 1441 | } | 1447 | } |
| 1442 | } | 1448 | } |
| 1443 | 1449 | ||
| 1450 | static struct sym_data *kcore_copy__new_sym(struct kcore_copy_info *kci, | ||
| 1451 | u64 addr) | ||
| 1452 | { | ||
| 1453 | struct sym_data *s = zalloc(sizeof(*s)); | ||
| 1454 | |||
| 1455 | if (s) { | ||
| 1456 | s->addr = addr; | ||
| 1457 | list_add_tail(&s->node, &kci->syms); | ||
| 1458 | } | ||
| 1459 | |||
| 1460 | return s; | ||
| 1461 | } | ||
| 1462 | |||
| 1463 | static void kcore_copy__free_syms(struct kcore_copy_info *kci) | ||
| 1464 | { | ||
| 1465 | struct sym_data *s, *tmp; | ||
| 1466 | |||
| 1467 | list_for_each_entry_safe(s, tmp, &kci->syms, node) { | ||
| 1468 | list_del(&s->node); | ||
| 1469 | free(s); | ||
| 1470 | } | ||
| 1471 | } | ||
| 1472 | |||
| 1444 | static int kcore_copy__process_kallsyms(void *arg, const char *name, char type, | 1473 | static int kcore_copy__process_kallsyms(void *arg, const char *name, char type, |
| 1445 | u64 start) | 1474 | u64 start) |
| 1446 | { | 1475 | { |
| @@ -1471,6 +1500,9 @@ static int kcore_copy__process_kallsyms(void *arg, const char *name, char type, | |||
| 1471 | return 0; | 1500 | return 0; |
| 1472 | } | 1501 | } |
| 1473 | 1502 | ||
| 1503 | if (is_entry_trampoline(name) && !kcore_copy__new_sym(kci, start)) | ||
| 1504 | return -1; | ||
| 1505 | |||
| 1474 | return 0; | 1506 | return 0; |
| 1475 | } | 1507 | } |
| 1476 | 1508 | ||
| @@ -1538,6 +1570,7 @@ static int kcore_copy__read_map(u64 start, u64 len, u64 pgoff, void *data) | |||
| 1538 | { | 1570 | { |
| 1539 | struct kcore_copy_info *kci = data; | 1571 | struct kcore_copy_info *kci = data; |
| 1540 | u64 end = start + len; | 1572 | u64 end = start + len; |
| 1573 | struct sym_data *sdat; | ||
| 1541 | 1574 | ||
| 1542 | if (kcore_copy__map(kci, start, end, pgoff, kci->stext, kci->etext)) | 1575 | if (kcore_copy__map(kci, start, end, pgoff, kci->stext, kci->etext)) |
| 1543 | return -1; | 1576 | return -1; |
| @@ -1546,6 +1579,13 @@ static int kcore_copy__read_map(u64 start, u64 len, u64 pgoff, void *data) | |||
| 1546 | kci->last_module_symbol)) | 1579 | kci->last_module_symbol)) |
| 1547 | return -1; | 1580 | return -1; |
| 1548 | 1581 | ||
| 1582 | list_for_each_entry(sdat, &kci->syms, node) { | ||
| 1583 | u64 s = round_down(sdat->addr, page_size); | ||
| 1584 | |||
| 1585 | if (kcore_copy__map(kci, start, end, pgoff, s, s + len)) | ||
| 1586 | return -1; | ||
| 1587 | } | ||
| 1588 | |||
| 1549 | return 0; | 1589 | return 0; |
| 1550 | } | 1590 | } |
| 1551 | 1591 | ||
| @@ -1740,6 +1780,7 @@ int kcore_copy(const char *from_dir, const char *to_dir) | |||
| 1740 | struct phdr_data *p; | 1780 | struct phdr_data *p; |
| 1741 | 1781 | ||
| 1742 | INIT_LIST_HEAD(&kci.phdrs); | 1782 | INIT_LIST_HEAD(&kci.phdrs); |
| 1783 | INIT_LIST_HEAD(&kci.syms); | ||
| 1743 | 1784 | ||
| 1744 | if (kcore_copy__copy_file(from_dir, to_dir, "kallsyms")) | 1785 | if (kcore_copy__copy_file(from_dir, to_dir, "kallsyms")) |
| 1745 | return -1; | 1786 | return -1; |
| @@ -1806,6 +1847,7 @@ out_unlink_kallsyms: | |||
| 1806 | kcore_copy__unlink(to_dir, "kallsyms"); | 1847 | kcore_copy__unlink(to_dir, "kallsyms"); |
| 1807 | 1848 | ||
| 1808 | kcore_copy__free_phdrs(&kci); | 1849 | kcore_copy__free_phdrs(&kci); |
| 1850 | kcore_copy__free_syms(&kci); | ||
| 1809 | 1851 | ||
| 1810 | return err; | 1852 | return err; |
| 1811 | } | 1853 | } |
