1da650adaSThadeu Lima de Souza Cascardo // SPDX-License-Identifier: GPL-2.0+
2da650adaSThadeu Lima de Souza Cascardo
3da650adaSThadeu Lima de Souza Cascardo /*
4da650adaSThadeu Lima de Souza Cascardo * Copyright 2018 IBM Corporation.
5da650adaSThadeu Lima de Souza Cascardo * Copyright 2020 Canonical Ltd.
6da650adaSThadeu Lima de Souza Cascardo */
7da650adaSThadeu Lima de Souza Cascardo
8da650adaSThadeu Lima de Souza Cascardo #define __SANE_USERSPACE_TYPES__
9da650adaSThadeu Lima de Souza Cascardo
10da650adaSThadeu Lima de Souza Cascardo #include <sys/types.h>
11da650adaSThadeu Lima de Souza Cascardo #include <stdint.h>
12da650adaSThadeu Lima de Souza Cascardo #include <malloc.h>
13da650adaSThadeu Lima de Souza Cascardo #include <unistd.h>
14da650adaSThadeu Lima de Souza Cascardo #include <signal.h>
15da650adaSThadeu Lima de Souza Cascardo #include <stdlib.h>
16da650adaSThadeu Lima de Souza Cascardo #include <string.h>
17da650adaSThadeu Lima de Souza Cascardo #include <stdio.h>
18da650adaSThadeu Lima de Souza Cascardo #include "utils.h"
19da650adaSThadeu Lima de Souza Cascardo #include "flush_utils.h"
20da650adaSThadeu Lima de Souza Cascardo
uaccess_flush_test(void)21da650adaSThadeu Lima de Souza Cascardo int uaccess_flush_test(void)
22da650adaSThadeu Lima de Souza Cascardo {
23da650adaSThadeu Lima de Souza Cascardo char *p;
24da650adaSThadeu Lima de Souza Cascardo int repetitions = 10;
25da650adaSThadeu Lima de Souza Cascardo int fd, passes = 0, iter, rc = 0;
26da650adaSThadeu Lima de Souza Cascardo struct perf_event_read v;
27da650adaSThadeu Lima de Souza Cascardo __u64 l1d_misses_total = 0;
28da650adaSThadeu Lima de Souza Cascardo unsigned long iterations = 100000, zero_size = 24 * 1024;
29da650adaSThadeu Lima de Souza Cascardo unsigned long l1d_misses_expected;
30da650adaSThadeu Lima de Souza Cascardo int rfi_flush_orig;
31da650adaSThadeu Lima de Souza Cascardo int entry_flush_orig;
32da650adaSThadeu Lima de Souza Cascardo int uaccess_flush, uaccess_flush_orig;
33da650adaSThadeu Lima de Souza Cascardo
34da650adaSThadeu Lima de Souza Cascardo SKIP_IF(geteuid() != 0);
35da650adaSThadeu Lima de Souza Cascardo
36da650adaSThadeu Lima de Souza Cascardo // The PMU event we use only works on Power7 or later
37da650adaSThadeu Lima de Souza Cascardo SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
38da650adaSThadeu Lima de Souza Cascardo
39*121d340bSBenjamin Gray if (read_debugfs_int("powerpc/rfi_flush", &rfi_flush_orig) < 0) {
40da650adaSThadeu Lima de Souza Cascardo perror("Unable to read powerpc/rfi_flush debugfs file");
41da650adaSThadeu Lima de Souza Cascardo SKIP_IF(1);
42da650adaSThadeu Lima de Souza Cascardo }
43da650adaSThadeu Lima de Souza Cascardo
44*121d340bSBenjamin Gray if (read_debugfs_int("powerpc/entry_flush", &entry_flush_orig) < 0) {
45da650adaSThadeu Lima de Souza Cascardo perror("Unable to read powerpc/entry_flush debugfs file");
46da650adaSThadeu Lima de Souza Cascardo SKIP_IF(1);
47da650adaSThadeu Lima de Souza Cascardo }
48da650adaSThadeu Lima de Souza Cascardo
49*121d340bSBenjamin Gray if (read_debugfs_int("powerpc/uaccess_flush", &uaccess_flush_orig) < 0) {
50da650adaSThadeu Lima de Souza Cascardo perror("Unable to read powerpc/entry_flush debugfs file");
51da650adaSThadeu Lima de Souza Cascardo SKIP_IF(1);
52da650adaSThadeu Lima de Souza Cascardo }
53da650adaSThadeu Lima de Souza Cascardo
54da650adaSThadeu Lima de Souza Cascardo if (rfi_flush_orig != 0) {
55*121d340bSBenjamin Gray if (write_debugfs_int("powerpc/rfi_flush", 0) < 0) {
56da650adaSThadeu Lima de Souza Cascardo perror("error writing to powerpc/rfi_flush debugfs file");
57da650adaSThadeu Lima de Souza Cascardo FAIL_IF(1);
58da650adaSThadeu Lima de Souza Cascardo }
59da650adaSThadeu Lima de Souza Cascardo }
60da650adaSThadeu Lima de Souza Cascardo
61da650adaSThadeu Lima de Souza Cascardo if (entry_flush_orig != 0) {
62*121d340bSBenjamin Gray if (write_debugfs_int("powerpc/entry_flush", 0) < 0) {
63da650adaSThadeu Lima de Souza Cascardo perror("error writing to powerpc/entry_flush debugfs file");
64da650adaSThadeu Lima de Souza Cascardo FAIL_IF(1);
65da650adaSThadeu Lima de Souza Cascardo }
66da650adaSThadeu Lima de Souza Cascardo }
67da650adaSThadeu Lima de Souza Cascardo
68da650adaSThadeu Lima de Souza Cascardo uaccess_flush = uaccess_flush_orig;
69da650adaSThadeu Lima de Souza Cascardo
70da650adaSThadeu Lima de Souza Cascardo fd = perf_event_open_counter(PERF_TYPE_HW_CACHE, PERF_L1D_READ_MISS_CONFIG, -1);
71da650adaSThadeu Lima de Souza Cascardo FAIL_IF(fd < 0);
72da650adaSThadeu Lima de Souza Cascardo
73da650adaSThadeu Lima de Souza Cascardo p = (char *)memalign(zero_size, CACHELINE_SIZE);
74da650adaSThadeu Lima de Souza Cascardo
75da650adaSThadeu Lima de Souza Cascardo FAIL_IF(perf_event_enable(fd));
76da650adaSThadeu Lima de Souza Cascardo
77da650adaSThadeu Lima de Souza Cascardo // disable L1 prefetching
78da650adaSThadeu Lima de Souza Cascardo set_dscr(1);
79da650adaSThadeu Lima de Souza Cascardo
80da650adaSThadeu Lima de Souza Cascardo iter = repetitions;
81da650adaSThadeu Lima de Souza Cascardo
82da650adaSThadeu Lima de Souza Cascardo /*
83da650adaSThadeu Lima de Souza Cascardo * We expect to see l1d miss for each cacheline access when entry_flush
84da650adaSThadeu Lima de Souza Cascardo * is set. Allow a small variation on this.
85da650adaSThadeu Lima de Souza Cascardo */
86da650adaSThadeu Lima de Souza Cascardo l1d_misses_expected = iterations * (zero_size / CACHELINE_SIZE - 2);
87da650adaSThadeu Lima de Souza Cascardo
88da650adaSThadeu Lima de Souza Cascardo again:
89da650adaSThadeu Lima de Souza Cascardo FAIL_IF(perf_event_reset(fd));
90da650adaSThadeu Lima de Souza Cascardo
91da650adaSThadeu Lima de Souza Cascardo syscall_loop_uaccess(p, iterations, zero_size);
92da650adaSThadeu Lima de Souza Cascardo
93da650adaSThadeu Lima de Souza Cascardo FAIL_IF(read(fd, &v, sizeof(v)) != sizeof(v));
94da650adaSThadeu Lima de Souza Cascardo
95da650adaSThadeu Lima de Souza Cascardo if (uaccess_flush && v.l1d_misses >= l1d_misses_expected)
96da650adaSThadeu Lima de Souza Cascardo passes++;
97da650adaSThadeu Lima de Souza Cascardo else if (!uaccess_flush && v.l1d_misses < (l1d_misses_expected / 2))
98da650adaSThadeu Lima de Souza Cascardo passes++;
99da650adaSThadeu Lima de Souza Cascardo
100da650adaSThadeu Lima de Souza Cascardo l1d_misses_total += v.l1d_misses;
101da650adaSThadeu Lima de Souza Cascardo
102da650adaSThadeu Lima de Souza Cascardo while (--iter)
103da650adaSThadeu Lima de Souza Cascardo goto again;
104da650adaSThadeu Lima de Souza Cascardo
105da650adaSThadeu Lima de Souza Cascardo if (passes < repetitions) {
106da650adaSThadeu Lima de Souza Cascardo printf("FAIL (L1D misses with uaccess_flush=%d: %llu %c %lu) [%d/%d failures]\n",
107da650adaSThadeu Lima de Souza Cascardo uaccess_flush, l1d_misses_total, uaccess_flush ? '<' : '>',
108da650adaSThadeu Lima de Souza Cascardo uaccess_flush ? repetitions * l1d_misses_expected :
109da650adaSThadeu Lima de Souza Cascardo repetitions * l1d_misses_expected / 2,
110da650adaSThadeu Lima de Souza Cascardo repetitions - passes, repetitions);
111da650adaSThadeu Lima de Souza Cascardo rc = 1;
112da650adaSThadeu Lima de Souza Cascardo } else {
113da650adaSThadeu Lima de Souza Cascardo printf("PASS (L1D misses with uaccess_flush=%d: %llu %c %lu) [%d/%d pass]\n",
114da650adaSThadeu Lima de Souza Cascardo uaccess_flush, l1d_misses_total, uaccess_flush ? '>' : '<',
115da650adaSThadeu Lima de Souza Cascardo uaccess_flush ? repetitions * l1d_misses_expected :
116da650adaSThadeu Lima de Souza Cascardo repetitions * l1d_misses_expected / 2,
117da650adaSThadeu Lima de Souza Cascardo passes, repetitions);
118da650adaSThadeu Lima de Souza Cascardo }
119da650adaSThadeu Lima de Souza Cascardo
120da650adaSThadeu Lima de Souza Cascardo if (uaccess_flush == uaccess_flush_orig) {
121da650adaSThadeu Lima de Souza Cascardo uaccess_flush = !uaccess_flush_orig;
122*121d340bSBenjamin Gray if (write_debugfs_int("powerpc/uaccess_flush", uaccess_flush) < 0) {
123da650adaSThadeu Lima de Souza Cascardo perror("error writing to powerpc/uaccess_flush debugfs file");
124da650adaSThadeu Lima de Souza Cascardo return 1;
125da650adaSThadeu Lima de Souza Cascardo }
126da650adaSThadeu Lima de Souza Cascardo iter = repetitions;
127da650adaSThadeu Lima de Souza Cascardo l1d_misses_total = 0;
128da650adaSThadeu Lima de Souza Cascardo passes = 0;
129da650adaSThadeu Lima de Souza Cascardo goto again;
130da650adaSThadeu Lima de Souza Cascardo }
131da650adaSThadeu Lima de Souza Cascardo
132da650adaSThadeu Lima de Souza Cascardo perf_event_disable(fd);
133da650adaSThadeu Lima de Souza Cascardo close(fd);
134da650adaSThadeu Lima de Souza Cascardo
135da650adaSThadeu Lima de Souza Cascardo set_dscr(0);
136da650adaSThadeu Lima de Souza Cascardo
137*121d340bSBenjamin Gray if (write_debugfs_int("powerpc/rfi_flush", rfi_flush_orig) < 0) {
138da650adaSThadeu Lima de Souza Cascardo perror("unable to restore original value of powerpc/rfi_flush debugfs file");
139da650adaSThadeu Lima de Souza Cascardo return 1;
140da650adaSThadeu Lima de Souza Cascardo }
141da650adaSThadeu Lima de Souza Cascardo
142*121d340bSBenjamin Gray if (write_debugfs_int("powerpc/entry_flush", entry_flush_orig) < 0) {
143da650adaSThadeu Lima de Souza Cascardo perror("unable to restore original value of powerpc/entry_flush debugfs file");
144da650adaSThadeu Lima de Souza Cascardo return 1;
145da650adaSThadeu Lima de Souza Cascardo }
146da650adaSThadeu Lima de Souza Cascardo
147*121d340bSBenjamin Gray if (write_debugfs_int("powerpc/uaccess_flush", uaccess_flush_orig) < 0) {
148da650adaSThadeu Lima de Souza Cascardo perror("unable to restore original value of powerpc/uaccess_flush debugfs file");
149da650adaSThadeu Lima de Souza Cascardo return 1;
150da650adaSThadeu Lima de Souza Cascardo }
151da650adaSThadeu Lima de Souza Cascardo
152da650adaSThadeu Lima de Souza Cascardo return rc;
153da650adaSThadeu Lima de Souza Cascardo }
154da650adaSThadeu Lima de Souza Cascardo
main(int argc,char * argv[])155da650adaSThadeu Lima de Souza Cascardo int main(int argc, char *argv[])
156da650adaSThadeu Lima de Souza Cascardo {
157da650adaSThadeu Lima de Souza Cascardo return test_harness(uaccess_flush_test, "uaccess_flush_test");
158da650adaSThadeu Lima de Souza Cascardo }
159