summaryrefslogtreecommitdiffstats
path: root/kmod/kvm.c
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2022-10-05 15:05:19 +0200
committerLouis Burda <quent.burda@gmail.com>2022-10-05 15:05:19 +0200
commit58d8565f015f9e06e1e51a0fe4654b966b2c27c0 (patch)
treee862ba1491cb114be46e98022ce8feaf98f8eca2 /kmod/kvm.c
parent8b1535789509812763de132f877b596d01861714 (diff)
downloadcachepc-58d8565f015f9e06e1e51a0fe4654b966b2c27c0.tar.gz
cachepc-58d8565f015f9e06e1e51a0fe4654b966b2c27c0.zip
Refactor sevstep kernel patch into repository
Diffstat (limited to 'kmod/kvm.c')
-rw-r--r--kmod/kvm.c392
1 files changed, 0 insertions, 392 deletions
diff --git a/kmod/kvm.c b/kmod/kvm.c
deleted file mode 100644
index 4deb4fa..0000000
--- a/kmod/kvm.c
+++ /dev/null
@@ -1,392 +0,0 @@
-#include "kvm.h"
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-
-struct proc_ops cachepc_proc_ops;
-
-uint16_t *cachepc_msrmts;
-size_t cachepc_msrmts_count;
-EXPORT_SYMBOL(cachepc_msrmts);
-EXPORT_SYMBOL(cachepc_msrmts_count);
-
-cache_ctx *cachepc_ctx;
-cacheline *cachepc_ds;
-EXPORT_SYMBOL(cachepc_ctx);
-EXPORT_SYMBOL(cachepc_ds);
-
-uint64_t cachepc_regs_tmp[16];
-uint64_t cachepc_regs_vm[16];
-EXPORT_SYMBOL(cachepc_regs_tmp);
-EXPORT_SYMBOL(cachepc_regs_vm);
-
-int
-cachepc_kvm_proc_open(struct inode *inode, struct file *file)
-{
- try_module_get(THIS_MODULE);
-
- return 0;
-}
-
-int
-cachepc_kvm_proc_close(struct inode *inode, struct file *file)
-{
- module_put(THIS_MODULE);
-
- return 0;
-}
-
-ssize_t
-cachepc_kvm_proc_read(struct file *file, char *buf, size_t buflen, loff_t *off)
-{
- size_t len, left;
- size_t size;
-
- printk(KERN_WARNING "CachePC: Reading entries (%lu:%lli)\n",
- buflen, off ? *off : 0);
-
- size = cachepc_msrmts_count * sizeof(uint16_t);
- if (!off || *off >= size || *off < 0)
- return 0;
-
- len = size - *off;
- if (len > buflen) len = buflen;
-
- left = copy_to_user(buf, (uint8_t *) cachepc_msrmts + *off, len);
-
- len -= left;
- *off += len;
-
- return len;
-}
-
-ssize_t
-cachepc_kvm_proc_write(struct file *file, const char *buf, size_t buflen, loff_t *off)
-{
- return 0;
-}
-
-loff_t
-cachepc_kvm_proc_lseek(struct file *file, loff_t off, int mode)
-{
- switch (mode) {
- case SEEK_SET:
- file->f_pos = off;
- break;
- case SEEK_CUR:
- file->f_pos += off;
- break;
- case SEEK_END:
- file->f_pos = cachepc_msrmts_count * sizeof(uint16_t) + off;
- break;
- default:
- return -EINVAL;
- }
-
- return file->f_pos;
-}
-
-void
-cachepc_kvm_prime_probe_test(void *p)
-{
- cacheline *lines;
- cacheline *cl, *head;
- uint32_t count;
- uint32_t *arg;
- int i, max;
-
- arg = p;
-
- /* l2 data cache, hit or miss */
- cachepc_init_pmc(0, 0x64, 0xD8);
-
- lines = cachepc_aligned_alloc(PAGE_SIZE, cachepc_ctx->cache_size);
- BUG_ON(lines == NULL);
-
- max = cachepc_ctx->nr_of_cachelines;
-
- cachepc_cpuid();
- cachepc_mfence();
-
- for (i = 0; i < max; i++)
- asm volatile ("mov (%0), %%rbx" : : "r"(lines + i) : "rbx");
-
- head = cachepc_prime(cachepc_ds);
- cachepc_probe(head);
-
- count = 0;
- cl = head = cachepc_ds;
- do {
- count += cl->count;
- cl = cl->next;
- } while (cl != head);
-
- printk(KERN_WARNING "CachePC: Prime-probe test done (%u vs. %u => %s)\n",
- count, 0, (count == 0) ? "passed" : "failed");
-
- if (arg) *arg = (count == 0);
-
- kfree(lines);
-}
-
-void
-cachepc_kvm_stream_hwpf_test(void *p)
-{
- cacheline *lines;
- uint32_t count;
- uint32_t *arg;
- uint32_t i, max;
-
- arg = p;
-
- /* TODO: accurately detect hwpf */
-
- /* l2 data cache, hit or miss */
- cachepc_init_pmc(0, 0x64, 0xD8);
-
- lines = cachepc_aligned_alloc(PAGE_SIZE, cachepc_ctx->cache_size);
- BUG_ON(lines == NULL);
-
- max = cachepc_ctx->nr_of_cachelines;
-
- cachepc_prime(cachepc_ds);
-
- count -= cachepc_read_pmc(0);
- for (i = 0; i < max; i++)
- asm volatile ("mov (%0), %%rbx" : : "r"(lines + i) : "rbx");
- count += cachepc_read_pmc(0);
-
- printk(KERN_WARNING "CachePC: HWPF test done (%u vs. %u => %s)\n",
- count, max, (count == max) ? "passed" : "failed");
-
- if (arg) *arg = (count == max);
-
- kfree(lines);
-}
-
-void
-cachepc_kvm_single_access_test(void *p)
-{
- cacheline *ptr;
- uint64_t pre, post;
- uint32_t *arg;
-
- /* l2 data cache, hit or miss */
- cachepc_init_pmc(0, 0x64, 0xD8);
-
- arg = p;
-
- WARN_ON(arg && *arg >= L1_SETS);
- if (arg && *arg >= L1_SETS) return;
- ptr = cachepc_prepare_victim(cachepc_ctx, arg ? *arg : 48);
-
- cachepc_prime(cachepc_ds);
-
- pre = cachepc_read_pmc(0);
- cachepc_victim(ptr);
- post = cachepc_read_pmc(0);
-
- printk(KERN_WARNING "CachePC: Single access test done (%llu vs %u => %s)",
- post - pre, 1, (post - pre == 1) ? "passed" : "failed");
-
- if (arg) *arg = post - pre;
-
- cachepc_release_victim(cachepc_ctx, ptr);
-}
-
-void
-cachepc_kvm_single_eviction_test(void *p)
-{
- cacheline *head, *cl, *evicted;
- cacheline *ptr;
- uint32_t target;
- uint32_t *arg;
- int count;
-
- arg = p;
-
- /* l2 data cache, hit or miss */
- cachepc_init_pmc(0, 0x64, 0xD8);
-
- WARN_ON(arg && *arg >= L1_SETS);
- if (arg && *arg >= L1_SETS) return;
- target = arg ? *arg : 48;
-
- ptr = cachepc_prepare_victim(cachepc_ctx, target);
-
- head = cachepc_prime(cachepc_ds);
- cachepc_victim(ptr);
- cachepc_probe(head);
-
- count = 0;
- evicted = NULL;
- cl = head = cachepc_ds;
- do {
- if (IS_FIRST(cl->flags) && cl->count > 0) {
- evicted = cl;
- count += cl->count;
- }
- cl = cl->next;
- } while (cl != head);
-
- printk(KERN_WARNING "CachePC: Single eviction test done (%u vs %u => %s)\n",
- count, 1, (count == 1 && evicted->cache_set == target) ? "passed" : "failed");
- cachepc_save_msrmts(head);
-
- if (arg) *arg = count;
-
- cachepc_release_victim(cachepc_ctx, ptr);
-}
-
-void
-cachepc_kvm_system_setup(void)
-{
- uint64_t reg_addr, val;
- uint32_t lo, hi;
-
- /* disable streaming store */
- reg_addr = 0xc0011020;
- asm volatile ("rdmsr" : "=a"(lo), "=d"(hi) : "c"(reg_addr));
- val = (uint64_t) lo | ((uint64_t) hi << 32);
- val |= 1 << 13;
- asm volatile ("wrmsr" : : "c"(reg_addr), "a"(val), "d"(0x00));
- printk("CachePC: Writing MSR %08llX: %016llX\n", reg_addr, val);
-
- /* disable speculative data cache tlb reloads */
- reg_addr = 0xc0011022;
- asm volatile ("rdmsr" : "=a"(lo), "=d"(hi) : "c"(reg_addr));
- val = (uint64_t) lo | ((uint64_t) hi << 32);
- val |= 1 << 4;
- asm volatile ("wrmsr" : : "c"(reg_addr), "a"(val), "d"(0x00));
- printk("CachePC: Writing MSR %08llX: %016llX\n", reg_addr, val);
-
- /* disable data cache hardware prefetcher */
- reg_addr = 0xc0011022;
- asm volatile ("rdmsr" : "=a"(lo), "=d"(hi) : "c"(reg_addr));
- val = (uint64_t) lo | ((uint64_t) hi << 32);
- val |= 1 << 13;
- asm volatile ("wrmsr" : : "c"(reg_addr), "a"(val), "d"(0x00));
- printk("CachePC: Writing MSR %08llX: %016llX\n", reg_addr, val);
-}
-
-void
-cachepc_kvm_init_pmc_ioctl(void *p)
-{
- uint32_t event;
- uint8_t index, event_no, event_mask;
-
- WARN_ON(p == NULL);
- if (!p) return;
-
- event = *(uint32_t *)p;
-
- index = (event & 0xFF000000) >> 24;
- event_no = (event & 0x0000FF00) >> 8;
- event_mask = (event & 0x000000FF) >> 0;
-
- cachepc_init_pmc(index, event_no, event_mask);
-}
-
-long
-cachepc_kvm_ioctl(struct file *file, unsigned int cmd, unsigned long argp)
-{
- void __user *arg_user;
- uint32_t u32;
- int ret;
-
- arg_user = (void __user *)argp;
- switch (cmd) {
- case CACHEPC_IOCTL_TEST_ACCESS:
- printk(KERN_WARNING "CachePC: Called ioctl access test\n");
- if (!arg_user) return -EINVAL;
- if (copy_from_user(&u32, arg_user, sizeof(uint32_t)))
- return -EFAULT;
- ret = smp_call_function_single(2,
- cachepc_kvm_single_access_test, &u32, true);
- WARN_ON(ret != 0);
- if (copy_to_user(arg_user, &u32, sizeof(uint32_t)))
- return -EFAULT;
- break;
- case CACHEPC_IOCTL_TEST_EVICTION:
- printk(KERN_WARNING "CachePC: Called ioctl eviction test\n");
- if (!arg_user) return -EINVAL;
- if (copy_from_user(&u32, arg_user, sizeof(uint32_t)))
- return -EFAULT;
- ret = smp_call_function_single(2,
- cachepc_kvm_single_eviction_test, &u32, true);
- WARN_ON(ret != 0);
- if (copy_to_user(arg_user, &u32, sizeof(uint32_t)))
- return -EFAULT;
- break;
- case CACHEPC_IOCTL_INIT_PMC:
- printk(KERN_WARNING "CachePC: Called ioctl init counter\n");
- if (!arg_user) return -EINVAL;
- if (copy_from_user(&u32, arg_user, sizeof(uint32_t)))
- return -EFAULT;
- ret = smp_call_function_single(2,
- cachepc_kvm_init_pmc_ioctl, &u32, true);
- WARN_ON(ret != 0);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-void
-cachepc_kvm_setup_test(void *p)
-{
- int cpu;
-
- cpu = get_cpu();
-
- printk(KERN_WARNING "CachePC: Running on core %i\n", cpu);
-
- cachepc_ctx = cachepc_get_ctx(L1);
- cachepc_ds = cachepc_prepare_ds(cachepc_ctx);
-
- cachepc_kvm_system_setup();
-
- cachepc_kvm_prime_probe_test(NULL);
- cachepc_kvm_single_access_test(NULL);
- cachepc_kvm_single_eviction_test(NULL);
- cachepc_kvm_stream_hwpf_test(NULL);
-
- put_cpu();
-}
-
-void
-cachepc_kvm_init(void)
-{
- int ret;
-
- cachepc_msrmts_count = L1_SETS;
- cachepc_msrmts = kzalloc(cachepc_msrmts_count * sizeof(uint16_t), GFP_KERNEL);
- BUG_ON(cachepc_msrmts == NULL);
-
- ret = smp_call_function_single(2, cachepc_kvm_setup_test, NULL, true);
- WARN_ON(ret != 0);
-
- memset(&cachepc_proc_ops, 0, sizeof(cachepc_proc_ops));
- cachepc_proc_ops.proc_open = cachepc_kvm_proc_open;
- cachepc_proc_ops.proc_read = cachepc_kvm_proc_read;
- cachepc_proc_ops.proc_write = cachepc_kvm_proc_write;
- cachepc_proc_ops.proc_lseek = cachepc_kvm_proc_lseek;
- cachepc_proc_ops.proc_release = cachepc_kvm_proc_close;
- cachepc_proc_ops.proc_ioctl = cachepc_kvm_ioctl;
- proc_create("cachepc", 0644, NULL, &cachepc_proc_ops);
-}
-
-void
-cachepc_kvm_exit(void)
-{
- remove_proc_entry("cachepc", NULL);
- kfree(cachepc_msrmts);
-
- cachepc_release_ds(cachepc_ctx, cachepc_ds);
- cachepc_release_ctx(cachepc_ctx);
-}