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