cachepc

Prime+Probe cache-based side-channel attack on AMD SEV-SNP protected virtual machines
git clone https://git.sinitax.com/sinitax/cachepc
Log | Files | Refs | Submodules | README | sfeed.txt

commit d16af2b7f9b0026e2776237dd0ea673d88531e7d
parent 82d56ef77c114ac0b375fef04cea3a50f10f1843
Author: Louis Burda <quent.burda@gmail.com>
Date:   Tue, 22 Nov 2022 15:34:51 +0100

Add program to verify SVME bit is set during VMRUN

Diffstat:
MMakefile | 1+
Mcachepc/cachepc.h | 2+-
Mcachepc/kvm.c | 25+++++++++++++++++++++++++
Mcachepc/mmu.c | 2--
Mcachepc/uapi.h | 1+
Mtest/.gitignore | 1+
Atest/readsvme.c | 26++++++++++++++++++++++++++
7 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,6 +4,7 @@ PWD := $(shell pwd) TARGETS = build test/eviction test/access test/kvm test/sev test/sev-es test/sevstep TARGETS += test/aes-detect_guest test/aes-detect_host TARGETS += test/access-detect_guest test/access-detect_host +TARGETS += test/readsvme CFLAGS = -I . -I test -Wunused-variable -Wunknown-pragmas diff --git a/cachepc/cachepc.h b/cachepc/cachepc.h @@ -278,7 +278,7 @@ cachepc_read_pmc(uint64_t event) : "=a" (lo), "=d" (hi) : "c"(event) ); - res = ((uint64_t) hi << 32) | (uint64_t) lo; + res = (((uint64_t) hi) << 32) | (uint64_t) lo; cachepc_mfence(); cachepc_cpuid(); diff --git a/cachepc/kvm.c b/cachepc/kvm.c @@ -541,6 +541,29 @@ cachepc_kvm_vmsa_read_ioctl(void __user *arg_user) } int +cachepc_kvm_svme_read_ioctl(void __user *arg_user) +{ + uint32_t lo, hi; + uint64_t res; + uint32_t svme; + + if (!arg_user) return -EINVAL; + + asm volatile ( + "rdmsr" + : "=a" (lo), "=d" (hi) + : "c" (0xC0000080) + ); + res = (((uint64_t) hi) << 32) | (uint64_t) lo; + + svme = (res >> 12) & 1; + if (copy_to_user(arg_user, &svme, sizeof(uint32_t))) + return -EFAULT; + + return 0; +} + +int cachepc_kvm_track_all_ioctl(void __user *arg_user) { struct kvm_vcpu *vcpu; @@ -658,6 +681,8 @@ cachepc_kvm_ioctl(struct file *file, unsigned int ioctl, unsigned long arg) return cachepc_kvm_track_mode_ioctl(arg_user); case KVM_CPC_VMSA_READ: return cachepc_kvm_vmsa_read_ioctl(arg_user); + case KVM_CPC_SVME_READ: + return cachepc_kvm_svme_read_ioctl(arg_user); case KVM_CPC_TRACK_PAGE: return cachepc_kvm_track_page_ioctl(arg_user); case KVM_CPC_TRACK_ALL: diff --git a/cachepc/mmu.c b/cachepc/mmu.c @@ -26,8 +26,6 @@ cachepc_page_fault_handle(struct kvm_vcpu *vcpu, /* first fault from instruction fetch */ pr_warn("CachePC: Got inst fault gfn:%llu err:%u\n", fault->gfn, fault->error_code); - //if (!inst_fetch) - // pr_err("CachePC: Expected inst fault but was not on fetch\n"); cachepc_inst_fault_gfn = fault->gfn; cachepc_inst_fault_err = fault->error_code; diff --git a/cachepc/uapi.h b/cachepc/uapi.h @@ -45,6 +45,7 @@ #define KVM_CPC_SINGLE_STEP _IO(KVMIO, 0x29) #define KVM_CPC_TRACK_MODE _IOWR(KVMIO, 0x2A, __u32) #define KVM_CPC_VMSA_READ _IOR(KVMIO, 0x2B, __u64) +#define KVM_CPC_SVME_READ _IOR(KVMIO, 0x2C, __u32) #define KVM_CPC_TRACK_PAGE _IOWR(KVMIO, 0x30, struct cpc_track_config) #define KVM_CPC_TRACK_ALL _IOWR(KVMIO, 0x31, __u64) diff --git a/test/.gitignore b/test/.gitignore @@ -9,3 +9,4 @@ aes-detect_guest aes-detect_host access-detect_guest access-detect_host +readsvme diff --git a/test/readsvme.c b/test/readsvme.c @@ -0,0 +1,26 @@ +#include "cachepc/uapi.h" + +#include <sys/ioctl.h> +#include <err.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, const char **argv) +{ + uint32_t svme; + int kvm_fd; + + kvm_fd = open("/dev/kvm", O_RDWR); + if (kvm_fd < 0) err(1, "open /dev/kvm"); + + if (ioctl(kvm_fd, KVM_CPC_SVME_READ, &svme)) + err(1, "ioctl SVME_READ"); + + printf("%u\n", svme); + + close(kvm_fd); +}