| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- // SPDX-License-Identifier: GPL-2.0
- #include <linux/perf_event.h>
- #include <cpuid.h>
- #include <errno.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/ioctl.h>
- #include <sys/syscall.h>
- #include <unistd.h>
- int main(void)
- {
- struct perf_event_attr ret_attr, mret_attr;
- long long count_rets, count_rets_mispred;
- int rrets_fd, mrrets_fd;
- unsigned int cpuid1_eax, b, c, d;
- __cpuid(1, cpuid1_eax, b, c, d);
- if (cpuid1_eax < 0x00800f00 ||
- cpuid1_eax > 0x00afffff) {
- fprintf(stderr, "This needs to run on a Zen[1-4] machine (CPUID(1).EAX: 0x%x). Exiting...\n", cpuid1_eax);
- exit(EXIT_FAILURE);
- }
- memset(&ret_attr, 0, sizeof(struct perf_event_attr));
- memset(&mret_attr, 0, sizeof(struct perf_event_attr));
- ret_attr.type = mret_attr.type = PERF_TYPE_RAW;
- ret_attr.size = mret_attr.size = sizeof(struct perf_event_attr);
- ret_attr.config = 0xc8;
- mret_attr.config = 0xc9;
- ret_attr.disabled = mret_attr.disabled = 1;
- ret_attr.exclude_user = mret_attr.exclude_user = 1;
- ret_attr.exclude_hv = mret_attr.exclude_hv = 1;
- rrets_fd = syscall(SYS_perf_event_open, &ret_attr, 0, -1, -1, 0);
- if (rrets_fd == -1) {
- perror("opening retired RETs fd");
- exit(EXIT_FAILURE);
- }
- mrrets_fd = syscall(SYS_perf_event_open, &mret_attr, 0, -1, -1, 0);
- if (mrrets_fd == -1) {
- perror("opening retired mispredicted RETs fd");
- exit(EXIT_FAILURE);
- }
- ioctl(rrets_fd, PERF_EVENT_IOC_RESET, 0);
- ioctl(mrrets_fd, PERF_EVENT_IOC_RESET, 0);
- ioctl(rrets_fd, PERF_EVENT_IOC_ENABLE, 0);
- ioctl(mrrets_fd, PERF_EVENT_IOC_ENABLE, 0);
- printf("Sleeping for 10 seconds\n");
- sleep(10);
- ioctl(rrets_fd, PERF_EVENT_IOC_DISABLE, 0);
- ioctl(mrrets_fd, PERF_EVENT_IOC_DISABLE, 0);
- read(rrets_fd, &count_rets, sizeof(long long));
- read(mrrets_fd, &count_rets_mispred, sizeof(long long));
- printf("RETs: (%lld retired <-> %lld mispredicted)\n",
- count_rets, count_rets_mispred);
- printf("SRSO Safe-RET mitigation works correctly if both counts are almost equal.\n");
- return 0;
- }
|