1*40153505SBorislav Petkov (AMD) // SPDX-License-Identifier: GPL-2.0
2*40153505SBorislav Petkov (AMD) #include <linux/perf_event.h>
3*40153505SBorislav Petkov (AMD) #include <cpuid.h>
4*40153505SBorislav Petkov (AMD) #include <errno.h>
5*40153505SBorislav Petkov (AMD) #include <stdio.h>
6*40153505SBorislav Petkov (AMD) #include <stdlib.h>
7*40153505SBorislav Petkov (AMD) #include <string.h>
8*40153505SBorislav Petkov (AMD) #include <sys/ioctl.h>
9*40153505SBorislav Petkov (AMD) #include <sys/syscall.h>
10*40153505SBorislav Petkov (AMD) #include <unistd.h>
11*40153505SBorislav Petkov (AMD)
main(void)12*40153505SBorislav Petkov (AMD) int main(void)
13*40153505SBorislav Petkov (AMD) {
14*40153505SBorislav Petkov (AMD) struct perf_event_attr ret_attr, mret_attr;
15*40153505SBorislav Petkov (AMD) long long count_rets, count_rets_mispred;
16*40153505SBorislav Petkov (AMD) int rrets_fd, mrrets_fd;
17*40153505SBorislav Petkov (AMD) unsigned int cpuid1_eax, b, c, d;
18*40153505SBorislav Petkov (AMD)
19*40153505SBorislav Petkov (AMD) __cpuid(1, cpuid1_eax, b, c, d);
20*40153505SBorislav Petkov (AMD)
21*40153505SBorislav Petkov (AMD) if (cpuid1_eax < 0x00800f00 ||
22*40153505SBorislav Petkov (AMD) cpuid1_eax > 0x00afffff) {
23*40153505SBorislav Petkov (AMD) fprintf(stderr, "This needs to run on a Zen[1-4] machine (CPUID(1).EAX: 0x%x). Exiting...\n", cpuid1_eax);
24*40153505SBorislav Petkov (AMD) exit(EXIT_FAILURE);
25*40153505SBorislav Petkov (AMD) }
26*40153505SBorislav Petkov (AMD)
27*40153505SBorislav Petkov (AMD) memset(&ret_attr, 0, sizeof(struct perf_event_attr));
28*40153505SBorislav Petkov (AMD) memset(&mret_attr, 0, sizeof(struct perf_event_attr));
29*40153505SBorislav Petkov (AMD)
30*40153505SBorislav Petkov (AMD) ret_attr.type = mret_attr.type = PERF_TYPE_RAW;
31*40153505SBorislav Petkov (AMD) ret_attr.size = mret_attr.size = sizeof(struct perf_event_attr);
32*40153505SBorislav Petkov (AMD) ret_attr.config = 0xc8;
33*40153505SBorislav Petkov (AMD) mret_attr.config = 0xc9;
34*40153505SBorislav Petkov (AMD) ret_attr.disabled = mret_attr.disabled = 1;
35*40153505SBorislav Petkov (AMD) ret_attr.exclude_user = mret_attr.exclude_user = 1;
36*40153505SBorislav Petkov (AMD) ret_attr.exclude_hv = mret_attr.exclude_hv = 1;
37*40153505SBorislav Petkov (AMD)
38*40153505SBorislav Petkov (AMD) rrets_fd = syscall(SYS_perf_event_open, &ret_attr, 0, -1, -1, 0);
39*40153505SBorislav Petkov (AMD) if (rrets_fd == -1) {
40*40153505SBorislav Petkov (AMD) perror("opening retired RETs fd");
41*40153505SBorislav Petkov (AMD) exit(EXIT_FAILURE);
42*40153505SBorislav Petkov (AMD) }
43*40153505SBorislav Petkov (AMD)
44*40153505SBorislav Petkov (AMD) mrrets_fd = syscall(SYS_perf_event_open, &mret_attr, 0, -1, -1, 0);
45*40153505SBorislav Petkov (AMD) if (mrrets_fd == -1) {
46*40153505SBorislav Petkov (AMD) perror("opening retired mispredicted RETs fd");
47*40153505SBorislav Petkov (AMD) exit(EXIT_FAILURE);
48*40153505SBorislav Petkov (AMD) }
49*40153505SBorislav Petkov (AMD)
50*40153505SBorislav Petkov (AMD) ioctl(rrets_fd, PERF_EVENT_IOC_RESET, 0);
51*40153505SBorislav Petkov (AMD) ioctl(mrrets_fd, PERF_EVENT_IOC_RESET, 0);
52*40153505SBorislav Petkov (AMD)
53*40153505SBorislav Petkov (AMD) ioctl(rrets_fd, PERF_EVENT_IOC_ENABLE, 0);
54*40153505SBorislav Petkov (AMD) ioctl(mrrets_fd, PERF_EVENT_IOC_ENABLE, 0);
55*40153505SBorislav Petkov (AMD)
56*40153505SBorislav Petkov (AMD) printf("Sleeping for 10 seconds\n");
57*40153505SBorislav Petkov (AMD) sleep(10);
58*40153505SBorislav Petkov (AMD)
59*40153505SBorislav Petkov (AMD) ioctl(rrets_fd, PERF_EVENT_IOC_DISABLE, 0);
60*40153505SBorislav Petkov (AMD) ioctl(mrrets_fd, PERF_EVENT_IOC_DISABLE, 0);
61*40153505SBorislav Petkov (AMD)
62*40153505SBorislav Petkov (AMD) read(rrets_fd, &count_rets, sizeof(long long));
63*40153505SBorislav Petkov (AMD) read(mrrets_fd, &count_rets_mispred, sizeof(long long));
64*40153505SBorislav Petkov (AMD)
65*40153505SBorislav Petkov (AMD) printf("RETs: (%lld retired <-> %lld mispredicted)\n",
66*40153505SBorislav Petkov (AMD) count_rets, count_rets_mispred);
67*40153505SBorislav Petkov (AMD) printf("SRSO Safe-RET mitigation works correctly if both counts are almost equal.\n");
68*40153505SBorislav Petkov (AMD)
69*40153505SBorislav Petkov (AMD) return 0;
70*40153505SBorislav Petkov (AMD) }
71