commit b0f48d2b2cc7ec0e19ce0e16dc59e9169b63b0e0
parent 252b11a01e061fd17821e53a41c8451a1d2c27bd
Author: Louis Burda <quent.burda@gmail.com>
Date: Tue, 10 Jan 2023 17:08:18 +0100
Stash fixups
Diffstat:
7 files changed, 19 insertions(+), 192 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,10 +1,6 @@
build.sh
push.sh
.vscode
-*.o.cmd
-*.o
-*.o.d
-*.out
-*.swp
.cache
+linux-*
compile_commands.json
diff --git a/Makefile b/Makefile
@@ -14,8 +14,8 @@ CFLAGS = -I . -I linux/usr/include -I test -Wunused-variable -Wunknown-pragmas
all: build $(BINS)
clean:
- $(MAKE) -C $(LINUX) SUBDIRS=arch/x86/kvm clean
- $(MAKE) -C $(LINUX) SUBDIRS=crypto clean
+ $(MAKE) -C $(LINUX) clean M=arch/x86/kvm
+ $(MAKE) -C $(LINUX) clean M=crypto
rm $(BINS)
$(LINUX)/arch/x86/kvm/cachepc:
@@ -27,16 +27,14 @@ host:
git -C $(LINUX) add .
git -C $(LINUX) stash
git -C $(LINUX) checkout 0aaa1e5
- $(MAKE) -C $(LINUX) oldconfig
- $(MAKE) -C $(LINUX) prepare
- $(MAKE) -C $(LINUX) -j $(JOBS) -l $(LOAD)
- $(MAKE) -C $(LINUX) -j $(JOBS) -l $(LOAD) headers
+ rm -f $(LINUX)/arch/x86/kvm/cachepc
+ $(MAKE) -C $(LINUX) -j $(JOBS) -l $(LOAD) bindeb-pkg
git -C $(LINUX) checkout master
git -C $(LINUX) stash pop
build: $(LINUX)/arch/x86/kvm/cachepc
$(MAKE) -C $(LINUX) -j $(JOBS) -l $(LOAD) M=arch/x86/kvm modules
- $(MAKE) -C $(LINUX) -j $(JOBS) -l $(LOAD) M=crypto modules
+ #$(MAKE) -C $(LINUX) -j $(JOBS) -l $(LOAD) M=crypto modules
load:
sudo rmmod kvm_amd || true
@@ -52,12 +50,6 @@ freq:
update:
git -C $(LINUX) diff 0aaa1e599bee256b3b15643bbb95e80ce7aa9be5 -G. > patch.diff
-test/aes-detect_%: test/aes-detect_%.c test/aes-detect.c cachepc/uapi.h
- clang -o $@ $< $(CFLAGS) -I test/libkcapi/lib -L test/libkcapi/.libs -lkcapi -static
-
-test/access-detect_%: test/access-detect_%.c cachepc/uapi.h
- clang -o $@ $< $(CFLAGS) -static
-
test/%: test/%.c cachepc/uapi.h
clang -o $@ $< $(CFLAGS) -fsanitize=address
diff --git a/README b/README
@@ -43,3 +43,11 @@ test/qemu-poc:
Demonstrate that AES encryption keys can be leaked from an
unmodified qemu-based linux guest.
+Testing was done on a bare-metal AMD EPYC 72F3 (Family 0x19, Model 0x01).
+
+To successfully build and load the kvm.ko and kvm-amd.ko modules, ensure
+that a host kernel debian package was built using `make host`.
+
+Note: because of bad decisions made in regards to version control,
+the checked out commit of the modified kernel (previously the
+kernel patch file) might be incorrect for older revisions.
diff --git a/cachepc/.gitignore b/cachepc/.gitignore
@@ -0,0 +1,3 @@
+*.o
+*.o.d
+*.o.cmd
diff --git a/cachepc/mmu.c b/cachepc/mmu.c
@@ -1,162 +0,0 @@
-#include "../cachepc/cachepc.h"
-#include "../cachepc/track.h"
-#include "../cachepc/event.h"
-#include "svm/svm.h"
-
-static bool
-cachepc_page_fault_handle(struct kvm_vcpu *vcpu,
- struct kvm_page_fault *fault)
-{
- int modes[] = {
- KVM_PAGE_TRACK_EXEC,
- KVM_PAGE_TRACK_ACCESS,
- };
- struct cpc_fault *tmp, *alloc;
- size_t count, i;
- bool inst_fetch;
-
- /* return true if the page fault was related to tracking and should not be handled,
- * return false if the page fault should be handled */
-
- for (i = 0; i < 2; i++) {
- if (kvm_slot_page_track_is_active(vcpu->kvm,
- fault->slot, fault->gfn, modes[i]))
- break;
- }
- if (i == 2) {
- CPC_INFO("Untracked page fault (gfn:%llu err:%u)\n",
- fault->gfn, fault->error_code);
- return false;
- }
-
- CPC_DBG("Tracked page fault (gfn:%llu err:%u)\n",
- fault->gfn, fault->error_code);
-
- inst_fetch = fault->error_code & PFERR_FETCH_MASK;
- CPC_DBG("Tracked page fault attrs p:%i w:%i x:%i f:%i\n",
- fault->present, fault->write, fault->exec, inst_fetch);
-
- count = 0;
- list_for_each_entry(tmp, &cachepc_faults, list)
- count += 1;
-
- if (cachepc_track_mode == CPC_TRACK_FULL) {
- CPC_INFO("Got %lu. fault gfn:%llu err:%u\n", count + 1,
- fault->gfn, fault->error_code);
-
- cachepc_untrack_single(vcpu, fault->gfn, modes[i]);
-
- alloc = kmalloc(sizeof(struct cpc_fault), GFP_KERNEL);
- BUG_ON(!alloc);
- alloc->gfn = fault->gfn;
- alloc->err = fault->error_code;
- list_add_tail(&alloc->list, &cachepc_faults);
-
- cachepc_single_step = true;
- cachepc_apic_timer = 0;
-
- return false; /* setup untracked page */
- } else if (cachepc_track_mode == CPC_TRACK_EXEC) {
- if (!inst_fetch || !fault->present) return false;
-
- if (count == 1) {
- return false; /* dont untrack, but 'handle' */
- }
-
- CPC_INFO("Got %lu. fault gfn:%llu err:%u\n", count + 1,
- fault->gfn, fault->error_code);
-
- cachepc_untrack_single(vcpu, fault->gfn, modes[i]);
-
- if (modes[i] != KVM_PAGE_TRACK_EXEC)
- CPC_WARN("Wrong page track mode for TRACK_EXEC");
-
- alloc = kmalloc(sizeof(struct cpc_fault), GFP_KERNEL);
- BUG_ON(!alloc);
- alloc->gfn = fault->gfn;
- alloc->err = fault->error_code;
- list_add_tail(&alloc->list, &cachepc_faults);
-
- cachepc_single_step = true;
- cachepc_apic_timer = 0;
- } else if (cachepc_track_mode == CPC_TRACK_STUB) {
- cachepc_send_track_step_event(&cachepc_faults);
- }
-
- return true;
-}
-
-bool
-cachepc_spte_protect(u64 *sptep, bool pt_protect, enum kvm_page_track_mode mode)
-{
- u64 spte;
-
- spte = *sptep;
- if (!is_writable_pte(spte) && !(pt_protect && is_mmu_writable_spte(spte)))
- return false;
-
- if (pt_protect)
- spte &= ~shadow_mmu_writable_mask;
-
- if (mode == KVM_PAGE_TRACK_WRITE) {
- spte &= ~PT_WRITABLE_MASK;
- } else if (mode == KVM_PAGE_TRACK_RESET_ACCESS) {
- spte &= ~PT_ACCESSED_MASK;
- } else if (mode == KVM_PAGE_TRACK_ACCESS) {
- spte &= ~PT_PRESENT_MASK;
- spte &= ~PT_WRITABLE_MASK;
- spte &= ~PT_USER_MASK;
- spte |= (0x1ULL << PT64_NX_SHIFT);
- } else if (mode == KVM_PAGE_TRACK_EXEC) {
- spte |= (0x1ULL << PT64_NX_SHIFT);
- } else if (mode == KVM_PAGE_TRACK_RESET_EXEC) {
- spte &= ~(0x1ULL << PT64_NX_SHIFT);
- }
-
- mmu_spte_update(sptep, spte);
-
- return true;
-}
-EXPORT_SYMBOL(cachepc_spte_protect);
-
-bool cachepc_rmap_protect(struct kvm_rmap_head *rmap_head,
- bool pt_protect, enum kvm_page_track_mode mode)
-{
- struct rmap_iterator iter;
- bool flush;
- u64 *sptep;
-
- flush = false;
- for_each_rmap_spte(rmap_head, &iter, sptep) {
- flush |= cachepc_spte_protect(sptep, pt_protect, mode);
- }
-
- return flush;
-}
-EXPORT_SYMBOL(cachepc_rmap_protect);
-
-bool
-cachepc_kvm_mmu_slot_gfn_protect(struct kvm *kvm, struct kvm_memory_slot *slot,
- uint64_t gfn, int min_level, enum kvm_page_track_mode mode)
-{
- struct kvm_rmap_head *rmap_head;
- bool flush;
- int i;
-
- flush = false;
-
- if (kvm_memslots_have_rmaps(kvm)) {
- for (i = min_level; i <= KVM_MAX_HUGEPAGE_LEVEL; ++i) {
- rmap_head = gfn_to_rmap(gfn, i, slot);
- flush |= cachepc_rmap_protect(rmap_head, true, mode);
- }
- } else if (is_tdp_mmu_enabled(kvm)) {
- flush |= cachepc_tdp_protect_gfn(kvm, slot, gfn, min_level, mode);
- } else {
- CPC_ERR("Tracking unsupported!\n");
- }
-
- return flush;
-}
-EXPORT_SYMBOL(cachepc_kvm_mmu_slot_gfn_protect);
-
diff --git a/cachepc/track.h b/cachepc/track.h
@@ -12,17 +12,6 @@
extern struct kvm* main_vm;
-/* defined in mmu.c as they rely on static mmu-internal functions */
-bool cachepc_spte_protect(u64 *sptep,
- bool pt_protect, enum kvm_page_track_mode mode);
-bool cachepc_rmap_protect(struct kvm_rmap_head *rmap_head,
- bool pt_protect, enum kvm_page_track_mode mode);
-bool cachepc_kvm_mmu_slot_gfn_protect(struct kvm *kvm, struct kvm_memory_slot *slot,
- uint64_t gfn, int min_level, enum kvm_page_track_mode mode);
-
-bool cachepc_tdp_protect_gfn(struct kvm *kvm, struct kvm_memory_slot *slot,
- gfn_t gfn, int min_level, int mode);
-
bool cachepc_track_single(struct kvm_vcpu *vcpu, gfn_t gfn,
enum kvm_page_track_mode mode);
bool cachepc_untrack_single(struct kvm_vcpu *vcpu, gfn_t gfn,
diff --git a/extra/.config b/extra/.config
@@ -27,6 +27,7 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_INIT_ENV_ARG_LIMIT=32
# CONFIG_COMPILE_TEST is not set
# CONFIG_WERROR is not set
+# CONFIG_UAPI_HEADER_TEST is not set
CONFIG_LOCALVERSION="-snp-host-0aaa1e599bee"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_BUILD_SALT="5.10.0-17-amd64"
@@ -10012,7 +10013,7 @@ CONFIG_DEBUG_INFO_NONE=y
CONFIG_FRAME_WARN=2048
CONFIG_STRIP_ASM_SYMS=y
# CONFIG_READABLE_ASM is not set
-# CONFIG_HEADERS_INSTALL is not set
+CONFIG_HEADERS_INSTALL=y
# CONFIG_DEBUG_SECTION_MISMATCH is not set
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set