Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation #751

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 45 additions & 2 deletions arch/x86/kvm/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "mmu.h"
#include "trace.h"
#include "pmu.h"
// #include "./vmx/vmx.h"

static u32 xstate_required_size(u64 xstate_bv, bool compacted)
{
Expand Down Expand Up @@ -1013,16 +1014,58 @@ bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
}
EXPORT_SYMBOL_GPL(kvm_cpuid);

u64 totalCycles;
EXPORT_SYMBOL_GPL(totalCycles);

u64 exitCycleArray[EXIT_SIZE];
EXPORT_SYMBOL_GPL(exitCycleArray);

u32 totalCounts;
EXPORT_SYMBOL_GPL(totalCounts);

u32 exitCountArray[EXIT_SIZE];
EXPORT_SYMBOL_GPL(exitCountArray);

int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
{
u32 eax, ebx, ecx, edx;
u32 eax, ebx, ecx, edx, counts, low32, high32;
u64 cycles;

if (cpuid_fault_enabled(vcpu) && !kvm_require_cpl(vcpu, 0))
return 1;

eax = kvm_rax_read(vcpu);
ecx = kvm_rcx_read(vcpu);
kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx, true);

if ( eax == 0x4FFFFFFF ) {
counts = totalCounts;
// printk("0x4FFFFFFF: %u \n", counts);
eax = counts;
} else if ( eax == 0x4FFFFFFE ) {
cycles = totalCycles;
// printk("0x4FFFFFFE: %llu \n", cycles);
low32 = (u32)(cycles & 0xffffffff); // low 32 bit
high32 = (u32)(cycles >> 32); // high 32 bit
// printk("0x4FFFFFFE, low32: %u \n", low32);
// printk("0x4FFFFFFE, high32: %u \n", high32);
ecx = low32;
ebx = high32;
} else if ( eax == 0x4FFFFFFD ) {
counts = exitCountArray[ecx % EXIT_SIZE];
printk("0x4FFFFFFD: %u \n", counts);
eax = counts;
} else if ( eax == 0x4FFFFFFC ) {
cycles = exitCycleArray[ecx % EXIT_SIZE];
// printk("0x4FFFFFFE: %llu \n", cycles);
low32 = (u32)(cycles & 0xffffffff); // low 32 bit
high32 = (u32)(cycles >> 32); // high 32 bit
// printk("0x4FFFFFFE, low32: %u \n", low32);
// printk("0x4FFFFFFE, high32: %u \n", high32);
ecx = low32;
ebx = high32;
} else {
kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx, true);
}
kvm_rax_write(vcpu, eax);
kvm_rbx_write(vcpu, ebx);
kvm_rcx_write(vcpu, ecx);
Expand Down
8 changes: 8 additions & 0 deletions arch/x86/kvm/cpuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,12 @@ static inline bool cpuid_fault_enabled(struct kvm_vcpu *vcpu)
MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
}

#define EXIT_SIZE 100

extern u32 totalCounts;
extern u64 totalCycles;

extern u64 exitCycleArray[EXIT_SIZE];
extern u32 exitCountArray[EXIT_SIZE];

#endif
44 changes: 39 additions & 5 deletions arch/x86/kvm/vmx/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/moduleparam.h>
#include <linux/mod_devicetable.h>
#include <linux/mm.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/sched/smt.h>
#include <linux/slab.h>
Expand All @@ -44,6 +45,7 @@
#include <asm/spec-ctrl.h>
#include <asm/virtext.h>
#include <asm/vmx.h>
#include <asm/timex.h>

#include "capabilities.h"
#include "cpuid.h"
Expand All @@ -61,6 +63,7 @@
#include "vmx.h"
#include "x86.h"


MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");

Expand Down Expand Up @@ -5775,16 +5778,31 @@ void dump_vmcs(void)
vmcs_read16(VIRTUAL_PROCESSOR_ID));
}

static void record(u32 exitReason, clock_t start) {
u64 elapsed_time = (u64)(get_cycles() - start);
u32 index = exitReason % EXIT_SIZE;
mutex_lock(&map_lock);

totalCounts++;
exitCountArray[index]++;

exitCycleArray[index] += elapsed_time;
totalCycles += elapsed_time;

mutex_unlock(&map_lock);
}


/*
* The guest has exited. See if we can fix it or if we need userspace
* assistance.
*/
static int vmx_handle_exit(struct kvm_vcpu *vcpu)
{
clock_t start = get_cycles();
struct vcpu_vmx *vmx = to_vmx(vcpu);
u32 exit_reason = vmx->exit_reason;
u32 vectoring_info = vmx->idt_vectoring_info;

trace_kvm_exit(exit_reason, vcpu, KVM_ISA_VMX);

/*
Expand All @@ -5798,17 +5816,25 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
vmx_flush_pml_buffer(vcpu);

/* If guest state is invalid, start emulating */
if (vmx->emulation_required)
if (vmx->emulation_required) {
// capture exist reason via insturmentation code
record(exit_reason, start);
return handle_invalid_guest_state(vcpu);
}

if (is_guest_mode(vcpu) && nested_vmx_exit_reflected(vcpu, exit_reason))
if (is_guest_mode(vcpu) && nested_vmx_exit_reflected(vcpu, exit_reason)) {
// capture exist reason via insturmentation code
record(exit_reason, start);
return nested_vmx_reflect_vmexit(vcpu, exit_reason);
}

if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
dump_vmcs();
vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY;
vcpu->run->fail_entry.hardware_entry_failure_reason
= exit_reason;
// capture exist reason via insturmentation code
record(exit_reason, start);
return 0;
}

Expand All @@ -5817,6 +5843,8 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
vcpu->run->exit_reason = KVM_EXIT_FAIL_ENTRY;
vcpu->run->fail_entry.hardware_entry_failure_reason
= vmcs_read32(VM_INSTRUCTION_ERROR);
// capture exist reason via insturmentation code
record(exit_reason, start);
return 0;
}

Expand All @@ -5843,6 +5871,8 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
vcpu->run->internal.data[3] =
vmcs_read64(GUEST_PHYSICAL_ADDRESS);
}
// capture exist reason via insturmentation code
record(exit_reason, start);
return 0;
}

Expand All @@ -5866,9 +5896,11 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
}

if (exit_reason < kvm_vmx_max_exit_handlers
&& kvm_vmx_exit_handlers[exit_reason])
&& kvm_vmx_exit_handlers[exit_reason]) {
// capture exist reason via insturmentation code
record(exit_reason, start);
return kvm_vmx_exit_handlers[exit_reason](vcpu);
else {
} else {
vcpu_unimpl(vcpu, "vmx: unexpected exit reason 0x%x\n",
exit_reason);
dump_vmcs();
Expand All @@ -5877,6 +5909,8 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON;
vcpu->run->internal.ndata = 1;
vcpu->run->internal.data[0] = exit_reason;
// capture exist reason via insturmentation code
record(exit_reason, start);
return 0;
}
}
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/kvm/vmx/vmx.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#define __KVM_X86_VMX_H

#include <linux/kvm_host.h>
#include <linux/mutex.h>

#include <asm/kvm.h>
#include <asm/intel_pt.h>
Expand Down Expand Up @@ -499,4 +500,8 @@ static inline void decache_tsc_multiplier(struct vcpu_vmx *vmx)

void dump_vmcs(void);

static DEFINE_MUTEX(map_lock);

#define EXIT_SIZE 100

#endif /* __KVM_X86_VMX_H */
3 changes: 3 additions & 0 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -7333,6 +7333,9 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
kvm_sched_yield(vcpu->kvm, a0);
ret = 0;
break;
case 0x283:
ret = 0x0033383245504D43;
break;
default:
ret = -KVM_ENOSYS;
break;
Expand Down