diff --git a/eBPF_Supermarket/kvm_watcher/include/bpf/kvm_hypercall.h b/eBPF_Supermarket/kvm_watcher/include/bpf/kvm_hypercall.h index b4768d720..723200827 100644 --- a/eBPF_Supermarket/kvm_watcher/include/bpf/kvm_hypercall.h +++ b/eBPF_Supermarket/kvm_watcher/include/bpf/kvm_hypercall.h @@ -53,7 +53,7 @@ struct { __type(value, u32); } hc_count SEC(".maps"); -static int entry_emulate_hypercall(struct kvm_vcpu *vcpu, void *rb, +static int trace_emulate_hypercall(struct kvm_vcpu *vcpu, void *rb, struct common_event *e) { u32 pid = bpf_get_current_pid_tgid() >> 32; u64 nr, a0, a1, a2, a3; diff --git a/eBPF_Supermarket/kvm_watcher/include/common.h b/eBPF_Supermarket/kvm_watcher/include/common.h index d9435e584..8c5f89006 100644 --- a/eBPF_Supermarket/kvm_watcher/include/common.h +++ b/eBPF_Supermarket/kvm_watcher/include/common.h @@ -19,6 +19,16 @@ #ifndef __KVM_WATCHER_H #define __KVM_WATCHER_H +#define SET_KP_OR_FENTRY_LOAD(function_name, module_name) \ + do { \ + if (fentry_can_attach(#function_name, #module_name)) { \ + bpf_program__set_autoload(skel->progs.fentry_##function_name, \ + true); \ + } else { \ + bpf_program__set_autoload(skel->progs.kp_##function_name, true); \ + } \ + } while (0) + static const char binary_path[] = "/bin/qemu-system-x86_64"; #define __ATTACH_UPROBE(skel, sym_name, prog_name, is_retprobe) \ do { \ diff --git a/eBPF_Supermarket/kvm_watcher/src/helpers/trace_helpers.c b/eBPF_Supermarket/kvm_watcher/src/helpers/trace_helpers.c index c84ed19a0..72b78524b 100644 --- a/eBPF_Supermarket/kvm_watcher/src/helpers/trace_helpers.c +++ b/eBPF_Supermarket/kvm_watcher/src/helpers/trace_helpers.c @@ -976,7 +976,7 @@ bool is_kernel_module(const char *name) { return found; } -static bool fentry_try_attach(int id) { +bool fentry_try_attach(int id) { int prog_fd, attach_fd; char error[4096]; struct bpf_insn insns[] = { @@ -1023,7 +1023,7 @@ bool fentry_can_attach(const char *name, const char *mod) { btf__free(module_btf); btf__free(vmlinux_btf); - return id > 0 && fentry_try_attach(id); + return id > 0; } #define DEBUGFS "/sys/kernel/debug/tracing" diff --git a/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.bpf.c b/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.bpf.c index 54352b8de..8e57cb7ae 100644 --- a/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.bpf.c +++ b/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.bpf.c @@ -45,6 +45,13 @@ int BPF_PROG(fentry_kvm_vcpu_halt, struct kvm_vcpu *vcpu) { CHECK_PID(vm_pid); return trace_kvm_vcpu_halt(vcpu); } + +SEC("kprobe/kvm_vcpu_halt") +int BPF_KPROBE(kp_kvm_vcpu_halt, struct kvm_vcpu *vcpu) { + CHECK_PID(vm_pid); + return trace_kvm_vcpu_halt(vcpu); +} + // 追踪vcpu运行信息 SEC("tp/kvm/kvm_vcpu_wakeup") int tp_vcpu_wakeup(struct vcpu_wakeup *ctx) { @@ -67,6 +74,7 @@ SEC("tp/kvm/kvm_entry") int tp_entry(struct exit *ctx) { return trace_kvm_entry(); } + // 记录VCPU调度的信息--进入 SEC("fentry/vmx_vcpu_load") int BPF_PROG(fentry_vmx_vcpu_load, struct kvm_vcpu *vcpu, int cpu) { @@ -74,12 +82,23 @@ int BPF_PROG(fentry_vmx_vcpu_load, struct kvm_vcpu *vcpu, int cpu) { return trace_vmx_vcpu_load(vcpu, cpu); } +SEC("kprobe/vmx_vcpu_load") +int BPF_KPROBE(kp_vmx_vcpu_load, struct kvm_vcpu *vcpu, int cpu) { + CHECK_PID(vm_pid); + return trace_vmx_vcpu_load(vcpu, cpu); +} + // 记录VCPU调度的信息--退出 SEC("fentry/vmx_vcpu_put") int BPF_PROG(fentry_vmx_vcpu_put) { return trace_vmx_vcpu_put(); } +SEC("kprobe/vmx_vcpu_put") +int BPF_KPROBE(kp_vmx_vcpu_put) { + return trace_vmx_vcpu_put(); +} + SEC("fentry/mark_page_dirty_in_slot") int BPF_PROG(fentry_mark_page_dirty_in_slot, struct kvm *kvm, const struct kvm_memory_slot *memslot, gfn_t gfn) { @@ -87,6 +106,13 @@ int BPF_PROG(fentry_mark_page_dirty_in_slot, struct kvm *kvm, return trace_mark_page_dirty_in_slot(kvm, memslot, gfn, &rb, e); } +SEC("kprobe/mark_page_dirty_in_slot") +int BPF_KPROBE(kp_mark_page_dirty_in_slot, struct kvm *kvm, + const struct kvm_memory_slot *memslot, gfn_t gfn) { + CHECK_PID(vm_pid); + return trace_mark_page_dirty_in_slot(kvm, memslot, gfn, &rb, e); +} + SEC("tp/kvm/kvm_page_fault") int tp_page_fault(struct page_fault *ctx) { CHECK_PID(vm_pid); @@ -164,9 +190,15 @@ int BPF_PROG(fexit_vmx_inject_irq, struct kvm_vcpu *vcpu, bool reinjected) { } SEC("fentry/kvm_emulate_hypercall") -int BPF_PROG(fentry_emulate_hypercall, struct kvm_vcpu *vcpu) { +int BPF_PROG(fentry_kvm_emulate_hypercall, struct kvm_vcpu *vcpu) { CHECK_PID(vm_pid); - return entry_emulate_hypercall(vcpu, &rb, e); + return trace_emulate_hypercall(vcpu, &rb, e); +} + +SEC("kprobe/kvm_emulate_hypercall") +int BPF_KPROBE(kp_kvm_emulate_hypercall, struct kvm_vcpu *vcpu) { + CHECK_PID(vm_pid); + return trace_emulate_hypercall(vcpu, &rb, e); } SEC("tp/syscalls/sys_enter_ioctl") @@ -194,8 +226,20 @@ int BPF_PROG(fentry_start_hv_timer, struct kvm_lapic *apic) { return trace_start_hv_timer(apic); } +SEC("kprobe/start_hv_timer") +int BPF_KPROBE(kp_start_hv_timer, struct kvm_lapic *apic) { + CHECK_PID(vm_pid); + return trace_start_hv_timer(apic); +} + SEC("fentry/start_sw_timer") int BPF_PROG(fentry_start_sw_timer, struct kvm_lapic *apic) { CHECK_PID(vm_pid); return trace_start_sw_timer(apic); } + +SEC("kprobe/start_sw_timer") +int BPF_KPROBE(kp_start_sw_timer, struct kvm_lapic *apic) { + CHECK_PID(vm_pid); + return trace_start_sw_timer(apic); +} diff --git a/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.c b/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.c index cc931f9c3..a1e89df5e 100644 --- a/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.c +++ b/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.c @@ -793,16 +793,43 @@ static int print_event_head(struct env *env) { return 0; } -/*通过env结构体的属性真值来判断是否加载某个挂载函数*/ static void set_disable_load(struct kvm_watcher_bpf *skel) { + bpf_program__set_autoload(skel->progs.fentry_vmx_vcpu_load, false); + bpf_program__set_autoload(skel->progs.kp_vmx_vcpu_load, false); + bpf_program__set_autoload(skel->progs.fentry_vmx_vcpu_put, false); + bpf_program__set_autoload(skel->progs.kp_vmx_vcpu_put, false); + bpf_program__set_autoload(skel->progs.fentry_kvm_vcpu_halt, false); + bpf_program__set_autoload(skel->progs.kp_kvm_vcpu_halt, false); + bpf_program__set_autoload(skel->progs.fentry_mark_page_dirty_in_slot, + false); + bpf_program__set_autoload(skel->progs.kp_mark_page_dirty_in_slot, false); + bpf_program__set_autoload(skel->progs.fentry_kvm_emulate_hypercall, false); + bpf_program__set_autoload(skel->progs.kp_kvm_emulate_hypercall, false); + bpf_program__set_autoload(skel->progs.fentry_start_hv_timer, false); + bpf_program__set_autoload(skel->progs.kp_start_hv_timer, false); + bpf_program__set_autoload(skel->progs.fentry_start_sw_timer, false); + bpf_program__set_autoload(skel->progs.kp_start_sw_timer, false); + + if (env.execute_vcpu_load) { + SET_KP_OR_FENTRY_LOAD(vmx_vcpu_load, kvm_intel); + SET_KP_OR_FENTRY_LOAD(vmx_vcpu_put, kvm_intel); + } + if (env.execute_vcpu_wakeup) { + SET_KP_OR_FENTRY_LOAD(kvm_vcpu_halt, kvm); + } + if (env.execute_mark_page_dirty) { + SET_KP_OR_FENTRY_LOAD(mark_page_dirty_in_slot, kvm); + } + if (env.execute_timer) { + SET_KP_OR_FENTRY_LOAD(start_hv_timer, kvm); + SET_KP_OR_FENTRY_LOAD(start_sw_timer, kvm); + } + if (env.execute_hypercall) { + SET_KP_OR_FENTRY_LOAD(kvm_emulate_hypercall, kvm); + } + bpf_program__set_autoload(skel->progs.tp_vcpu_wakeup, env.execute_vcpu_wakeup ? true : false); - bpf_program__set_autoload(skel->progs.fentry_vmx_vcpu_load, - env.execute_vcpu_load ? true : false); - bpf_program__set_autoload(skel->progs.fentry_vmx_vcpu_put, - env.execute_vcpu_load ? true : false); - bpf_program__set_autoload(skel->progs.fentry_kvm_vcpu_halt, - env.execute_vcpu_wakeup ? true : false); bpf_program__set_autoload(skel->progs.tp_exit, env.execute_exit ? true : false); bpf_program__set_autoload(skel->progs.tp_entry, @@ -813,8 +840,6 @@ static void set_disable_load(struct kvm_watcher_bpf *skel) { env.execute_exit ? true : false); bpf_program__set_autoload(skel->progs.tp_kvm_halt_poll_ns, env.execute_halt_poll_ns ? true : false); - bpf_program__set_autoload(skel->progs.fentry_mark_page_dirty_in_slot, - env.execute_mark_page_dirty ? true : false); bpf_program__set_autoload(skel->progs.tp_page_fault, env.execute_page_fault ? true : false); bpf_program__set_autoload(skel->progs.fexit_tdp_page_fault, @@ -839,14 +864,8 @@ static void set_disable_load(struct kvm_watcher_bpf *skel) { env.execute_irq_inject ? true : false); bpf_program__set_autoload(skel->progs.fexit_vmx_inject_irq, env.execute_irq_inject ? true : false); - bpf_program__set_autoload(skel->progs.fentry_emulate_hypercall, - env.execute_hypercall ? true : false); bpf_program__set_autoload(skel->progs.tp_ioctl, env.execute_ioctl ? true : false); - bpf_program__set_autoload(skel->progs.fentry_start_hv_timer, - env.execute_timer ? true : false); - bpf_program__set_autoload(skel->progs.fentry_start_sw_timer, - env.execute_timer ? true : false); } // 函数不接受参数,返回一个静态分配的字符串