18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <stdbool.h> 38c2ecf20Sopenharmony_ci#include <linux/err.h> 48c2ecf20Sopenharmony_ci#include <linux/string.h> 58c2ecf20Sopenharmony_ci#include <sys/types.h> 68c2ecf20Sopenharmony_ci#include <sys/stat.h> 78c2ecf20Sopenharmony_ci#include <fcntl.h> 88c2ecf20Sopenharmony_ci#include "evlist.h" 98c2ecf20Sopenharmony_ci#include "evsel.h" 108c2ecf20Sopenharmony_ci#include "thread_map.h" 118c2ecf20Sopenharmony_ci#include "record.h" 128c2ecf20Sopenharmony_ci#include "tests.h" 138c2ecf20Sopenharmony_ci#include "debug.h" 148c2ecf20Sopenharmony_ci#include "util/mmap.h" 158c2ecf20Sopenharmony_ci#include <errno.h> 168c2ecf20Sopenharmony_ci#include <perf/mmap.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#ifndef O_DIRECTORY 198c2ecf20Sopenharmony_ci#define O_DIRECTORY 00200000 208c2ecf20Sopenharmony_ci#endif 218c2ecf20Sopenharmony_ci#ifndef AT_FDCWD 228c2ecf20Sopenharmony_ci#define AT_FDCWD -100 238c2ecf20Sopenharmony_ci#endif 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ciint test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest __maybe_unused) 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci struct record_opts opts = { 288c2ecf20Sopenharmony_ci .target = { 298c2ecf20Sopenharmony_ci .uid = UINT_MAX, 308c2ecf20Sopenharmony_ci .uses_mmap = true, 318c2ecf20Sopenharmony_ci }, 328c2ecf20Sopenharmony_ci .no_buffering = true, 338c2ecf20Sopenharmony_ci .freq = 1, 348c2ecf20Sopenharmony_ci .mmap_pages = 256, 358c2ecf20Sopenharmony_ci .raw_samples = true, 368c2ecf20Sopenharmony_ci }; 378c2ecf20Sopenharmony_ci const char *filename = "/etc/passwd"; 388c2ecf20Sopenharmony_ci int flags = O_RDONLY | O_DIRECTORY; 398c2ecf20Sopenharmony_ci struct evlist *evlist = evlist__new(); 408c2ecf20Sopenharmony_ci struct evsel *evsel; 418c2ecf20Sopenharmony_ci int err = -1, i, nr_events = 0, nr_polls = 0; 428c2ecf20Sopenharmony_ci char sbuf[STRERR_BUFSIZE]; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci if (evlist == NULL) { 458c2ecf20Sopenharmony_ci pr_debug("%s: perf_evlist__new\n", __func__); 468c2ecf20Sopenharmony_ci goto out; 478c2ecf20Sopenharmony_ci } 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci evsel = evsel__newtp("syscalls", "sys_enter_openat"); 508c2ecf20Sopenharmony_ci if (IS_ERR(evsel)) { 518c2ecf20Sopenharmony_ci pr_debug("%s: evsel__newtp\n", __func__); 528c2ecf20Sopenharmony_ci goto out_delete_evlist; 538c2ecf20Sopenharmony_ci } 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci evlist__add(evlist, evsel); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci err = perf_evlist__create_maps(evlist, &opts.target); 588c2ecf20Sopenharmony_ci if (err < 0) { 598c2ecf20Sopenharmony_ci pr_debug("%s: perf_evlist__create_maps\n", __func__); 608c2ecf20Sopenharmony_ci goto out_delete_evlist; 618c2ecf20Sopenharmony_ci } 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci evsel__config(evsel, &opts, NULL); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci perf_thread_map__set_pid(evlist->core.threads, 0, getpid()); 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci err = evlist__open(evlist); 688c2ecf20Sopenharmony_ci if (err < 0) { 698c2ecf20Sopenharmony_ci pr_debug("perf_evlist__open: %s\n", 708c2ecf20Sopenharmony_ci str_error_r(errno, sbuf, sizeof(sbuf))); 718c2ecf20Sopenharmony_ci goto out_delete_evlist; 728c2ecf20Sopenharmony_ci } 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci err = evlist__mmap(evlist, UINT_MAX); 758c2ecf20Sopenharmony_ci if (err < 0) { 768c2ecf20Sopenharmony_ci pr_debug("evlist__mmap: %s\n", 778c2ecf20Sopenharmony_ci str_error_r(errno, sbuf, sizeof(sbuf))); 788c2ecf20Sopenharmony_ci goto out_delete_evlist; 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci evlist__enable(evlist); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci /* 848c2ecf20Sopenharmony_ci * Generate the event: 858c2ecf20Sopenharmony_ci */ 868c2ecf20Sopenharmony_ci openat(AT_FDCWD, filename, flags); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci while (1) { 898c2ecf20Sopenharmony_ci int before = nr_events; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci for (i = 0; i < evlist->core.nr_mmaps; i++) { 928c2ecf20Sopenharmony_ci union perf_event *event; 938c2ecf20Sopenharmony_ci struct mmap *md; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci md = &evlist->mmap[i]; 968c2ecf20Sopenharmony_ci if (perf_mmap__read_init(&md->core) < 0) 978c2ecf20Sopenharmony_ci continue; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci while ((event = perf_mmap__read_event(&md->core)) != NULL) { 1008c2ecf20Sopenharmony_ci const u32 type = event->header.type; 1018c2ecf20Sopenharmony_ci int tp_flags; 1028c2ecf20Sopenharmony_ci struct perf_sample sample; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci ++nr_events; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci if (type != PERF_RECORD_SAMPLE) { 1078c2ecf20Sopenharmony_ci perf_mmap__consume(&md->core); 1088c2ecf20Sopenharmony_ci continue; 1098c2ecf20Sopenharmony_ci } 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci err = evsel__parse_sample(evsel, event, &sample); 1128c2ecf20Sopenharmony_ci if (err) { 1138c2ecf20Sopenharmony_ci pr_debug("Can't parse sample, err = %d\n", err); 1148c2ecf20Sopenharmony_ci goto out_delete_evlist; 1158c2ecf20Sopenharmony_ci } 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci tp_flags = evsel__intval(evsel, &sample, "flags"); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci if (flags != tp_flags) { 1208c2ecf20Sopenharmony_ci pr_debug("%s: Expected flags=%#x, got %#x\n", 1218c2ecf20Sopenharmony_ci __func__, flags, tp_flags); 1228c2ecf20Sopenharmony_ci goto out_delete_evlist; 1238c2ecf20Sopenharmony_ci } 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci goto out_ok; 1268c2ecf20Sopenharmony_ci } 1278c2ecf20Sopenharmony_ci perf_mmap__read_done(&md->core); 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci if (nr_events == before) 1318c2ecf20Sopenharmony_ci evlist__poll(evlist, 10); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci if (++nr_polls > 5) { 1348c2ecf20Sopenharmony_ci pr_debug("%s: no events!\n", __func__); 1358c2ecf20Sopenharmony_ci goto out_delete_evlist; 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci } 1388c2ecf20Sopenharmony_ciout_ok: 1398c2ecf20Sopenharmony_ci err = 0; 1408c2ecf20Sopenharmony_ciout_delete_evlist: 1418c2ecf20Sopenharmony_ci evlist__delete(evlist); 1428c2ecf20Sopenharmony_ciout: 1438c2ecf20Sopenharmony_ci return err; 1448c2ecf20Sopenharmony_ci} 145