diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index b804444e16d4..c94f8c4460f1 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -10,7 +10,9 @@ endif KVM := ../../../virt/kvm kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ - $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o + $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o \ + svm/cachepc/cachepc.o svm/cachepc/util.o + kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \ @@ -20,7 +22,8 @@ kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \ kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o \ vmx/evmcs.o vmx/nested.o vmx/posted_intr.o -kvm-amd-y += svm/svm.o svm/vmenter.o svm/pmu.o svm/nested.o svm/avic.o svm/sev.o +kvm-amd-y += svm/svm.o svm/vmenter.o svm/pmu.o svm/nested.o svm/avic.o svm/sev.o \ + svm/cachepc/cachepc.o svm/cachepc/util.o obj-$(CONFIG_KVM) += kvm.o obj-$(CONFIG_KVM_INTEL) += kvm-intel.o diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 7b3cfbe8f7e3..e9a2b1048e28 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -2,6 +2,8 @@ #include +#include "cachepc/cachepc.h" + #include "irq.h" #include "mmu.h" #include "kvm_cache_regs.h" @@ -3785,8 +3787,18 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) { - struct vcpu_svm *svm = to_svm(vcpu); + static struct cache_ctx *ctx = NULL; + static struct cacheline *ds = NULL; + static struct cacheline *head = NULL; + static int run_index = 0; + struct vcpu_svm *svm; + + if (!ctx) ctx = cachepc_get_ctx(L1); + if (!ds) ds = cachepc_prepare_ds(ctx); + + head = cachepc_prime(ds); + svm = to_svm(vcpu); svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX]; svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP]; svm->vmcb->save.rip = vcpu->arch.regs[VCPU_REGS_RIP]; @@ -3912,6 +3925,11 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) if (is_guest_mode(vcpu)) return EXIT_FASTPATH_NONE; + cachepc_probe(head); + cachepc_print_msrmts(head); + + run_index += 1; + return svm_exit_handlers_fastpath(vcpu); } diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 7f2e2a09ebbd..762eb35f19e5 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -35,6 +35,10 @@ #include +extern struct proc_dir_entry *cachepc_msrmts_file; +extern uint8_t cachepc_msrmts[1 << 20]; +extern uint64_t cachepc_msrmts_count; + #ifndef KVM_MAX_VCPU_ID #define KVM_MAX_VCPU_ID KVM_MAX_VCPUS #endif diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2541a17ff1c4..fd7511484011 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,8 @@ /* Worst case buffer size needed for holding an integer. */ #define ITOA_MAX_LEN 12 +#include "../../arch/x86/kvm/svm/cachepc/cachepc.h" + MODULE_AUTHOR("Qumranet"); MODULE_LICENSE("GPL"); @@ -143,6 +146,10 @@ static void hardware_disable_all(void); static void kvm_io_bus_destroy(struct kvm_io_bus *bus); +struct proc_dir_entry *cachepc_msrmts_file; +uint8_t cachepc_msrmts[1 << 20]; +uint64_t cachepc_msrmts_count; + __visible bool kvm_rebooting; EXPORT_SYMBOL_GPL(kvm_rebooting); @@ -4765,10 +4772,29 @@ static void check_processor_compat(void *data) *c->ret = kvm_arch_check_processor_compat(c->opaque); } +ssize_t +kvm_cachepc_read(struct file *file, char *buf, size_t buflen, loff_t *off) +{ + size_t len; + + printk(KERN_INFO "Reading cachepc proc file\n"); + + if (*off >= cachepc_msrmts_count) + return 0; + + len = cachepc_msrmts_count - *off; + if (len > buflen) len = buflen; + + memcpy(buf, cachepc_msrmts + *off, len); + + return len; +} + int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, struct module *module) { struct kvm_cpu_compat_check c; + struct proc_ops proc_ops; int r; int cpu; @@ -4848,6 +4874,15 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, r = kvm_vfio_ops_init(); WARN_ON(r); + cachepc_init_counters(); + cachepc_msrmts_count = 0; + + //memset(&proc_ops, 0, sizeof(proc_ops)); + //proc_ops.proc_read = kvm_cachepc_read; + + //cachepc_msrmts_file = proc_create("cachepc", 0644, NULL, &proc_ops); + //BUG_ON(cachepc_msrmts_file == NULL); + return 0; out_unreg: @@ -4872,6 +4907,7 @@ EXPORT_SYMBOL_GPL(kvm_init); void kvm_exit(void) { + //remove_proc_entry("cachepc", cachepc_msrmts_file); debugfs_remove_recursive(kvm_debugfs_dir); misc_deregister(&kvm_dev); kmem_cache_destroy(kvm_vcpu_cache);