Skip to content
Open
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
66 changes: 66 additions & 0 deletions arch/x86/include/uapi/asm/pvm_trace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef UAPI_KVM_X86_PVM_TRACE_H
#define UAPI_KVM_X86_PVM_TRACE_H

#include <linux/bitops.h>

#define NMI_VECTOR 0x02
#define PVM_EXIT_REASONS_FAILED_VMENTRY 1025

#define PVM_EXIT_REASONS_SHIFT 16
#define PVM_EXIT_REASONS_SYSCALL BIT(PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_HYPERCALL (2UL << PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_ERETU (3UL << PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_ERETS (4UL << PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_INTERRUPT (5UL << PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_INT80 (6UL << PVM_EXIT_REASONS_SHIFT)

#define PVM_EXIT_REASONS_HC_IRQ_WIN (PVM_EXIT_REASONS_HYPERCALL + 1)
#define PVM_EXIT_REASONS_HC_IRQ_HALT (PVM_EXIT_REASONS_HYPERCALL + 2)
#define PVM_EXIT_REASONS_HC_LOAD_PGTBL (PVM_EXIT_REASONS_HYPERCALL + 3)
#define PVM_EXIT_REASONS_HC_TLB_FLUSH (PVM_EXIT_REASONS_HYPERCALL + 4)
#define PVM_EXIT_REASONS_HC_TLB_FLUSH_CURRENT (PVM_EXIT_REASONS_HYPERCALL + 5)
#define PVM_EXIT_REASONS_HC_TLB_INVLPG (PVM_EXIT_REASONS_HYPERCALL + 6)
#define PVM_EXIT_REASONS_HC_LOAD_GS (PVM_EXIT_REASONS_HYPERCALL + 7)
#define PVM_EXIT_REASONS_HC_RDMSR (PVM_EXIT_REASONS_HYPERCALL + 8)
#define PVM_EXIT_REASONS_HC_WRMSR (PVM_EXIT_REASONS_HYPERCALL + 9)
#define PVM_EXIT_REASONS_HC_LOAD_TLS (PVM_EXIT_REASONS_HYPERCALL + 10)

#define PVM_EXIT_REASONS \
{ DE_VECTOR, "DE excp" }, \
{ DB_VECTOR, "DB excp" }, \
{ NMI_VECTOR, "NMI excp" }, \
{ BP_VECTOR, "BP excp" }, \
{ OF_VECTOR, "OF excp" }, \
{ BR_VECTOR, "BR excp" }, \
{ UD_VECTOR, "UD excp" }, \
{ NM_VECTOR, "NM excp" }, \
{ DF_VECTOR, "DF excp" }, \
{ TS_VECTOR, "TS excp" }, \
{ SS_VECTOR, "SS excp" }, \
{ GP_VECTOR, "GP excp" }, \
{ PF_VECTOR, "PF excp" }, \
{ MF_VECTOR, "MF excp" }, \
{ AC_VECTOR, "AC excp" }, \
{ MC_VECTOR, "MC excp" }, \
{ XM_VECTOR, "XM excp" }, \
{ VE_VECTOR, "VE excp" }, \
{ PVM_EXIT_REASONS_SYSCALL, "SYSCALL" }, \
{ PVM_EXIT_REASONS_HYPERCALL, "HYPERCALL" }, \
{ PVM_EXIT_REASONS_ERETU, "ERETU" }, \
{ PVM_EXIT_REASONS_ERETS, "ERETS" }, \
{ PVM_EXIT_REASONS_INTERRUPT, "INTERRUPT" }, \
{ PVM_EXIT_REASONS_INT80, "INT80" }, \
{ PVM_EXIT_REASONS_HC_IRQ_WIN, "HC_IRQ_WIN" }, \
{ PVM_EXIT_REASONS_HC_IRQ_HALT, "HC_IRQ_HALT" }, \
{ PVM_EXIT_REASONS_HC_LOAD_PGTBL, "HC_LOAD_PGTBL" }, \
{ PVM_EXIT_REASONS_HC_TLB_FLUSH, "HC_TLB_FLUSH" }, \
{ PVM_EXIT_REASONS_HC_TLB_FLUSH_CURRENT, "HC_TLB_FLUSH_CURRENT" },\
{ PVM_EXIT_REASONS_HC_TLB_INVLPG, "HC_TLB_INVLPG" }, \
{ PVM_EXIT_REASONS_HC_LOAD_GS, "HC_LOAD_GS" }, \
{ PVM_EXIT_REASONS_HC_RDMSR, "HC_RDMSR" }, \
{ PVM_EXIT_REASONS_HC_WRMSR, "HC_WRMSR" }, \
{ PVM_EXIT_REASONS_HC_LOAD_TLS, "HC_LOAD_TLS" }, \
{ PVM_EXIT_REASONS_FAILED_VMENTRY, "FAILED_VMENTRY" }

#endif /* UAPI_KVM_X86_PVM_TRACE_H */
33 changes: 33 additions & 0 deletions arch/x86/kvm/pvm/pvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2441,6 +2441,34 @@ static u32 pvm_get_syscall_exit_reason(struct kvm_vcpu *vcpu)
return PVM_EXIT_REASONS_SYSCALL;
}

static u64 pvm_get_hypercall_exit_reason(struct kvm_vcpu *vcpu)
{
switch (kvm_rax_read(vcpu)) {
case PVM_HC_IRQ_WIN:
return PVM_EXIT_REASONS_HC_IRQ_WIN;
case PVM_HC_IRQ_HALT:
return PVM_EXIT_REASONS_HC_IRQ_HALT;
case PVM_HC_LOAD_PGTBL:
return PVM_EXIT_REASONS_HC_LOAD_PGTBL;
case PVM_HC_TLB_FLUSH:
return PVM_EXIT_REASONS_HC_TLB_FLUSH;
case PVM_HC_TLB_FLUSH_CURRENT:
return PVM_EXIT_REASONS_HC_TLB_FLUSH_CURRENT;
case PVM_HC_TLB_INVLPG:
return PVM_EXIT_REASONS_HC_TLB_INVLPG;
case PVM_HC_LOAD_GS:
return PVM_EXIT_REASONS_HC_LOAD_GS;
case PVM_HC_RDMSR:
return PVM_EXIT_REASONS_HC_RDMSR;
case PVM_HC_WRMSR:
return PVM_EXIT_REASONS_HC_WRMSR;
case PVM_HC_LOAD_TLS:
return PVM_EXIT_REASONS_HC_LOAD_TLS;
default:
return 0;
}
}

static void pvm_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason, u64 *info1, u64 *info2,
u32 *intr_info, u32 *error_code)
{
Expand All @@ -2453,12 +2481,17 @@ static void pvm_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason, u64 *info1, u6
else if (pvm->exit_vector >= FIRST_EXTERNAL_VECTOR &&
pvm->exit_vector < NR_VECTORS)
*reason = PVM_EXIT_REASONS_INTERRUPT;
else if (pvm->exit_vector == SWITCH_EXIT_REASONS_FAILED_VMETNRY)
*reason = PVM_FAILED_VMENTRY_VECTOR;
else
*reason = pvm->exit_vector;
*info1 = pvm->exit_vector;
*info2 = pvm->exit_error_code;
*intr_info = pvm->exit_vector;
*error_code = pvm->exit_error_code;

if (*reason == PVM_EXIT_REASONS_HYPERCALL)
*info2 = pvm_get_hypercall_exit_reason(vcpu);
}

static void pvm_handle_exit_irqoff(struct kvm_vcpu *vcpu)
Expand Down
21 changes: 21 additions & 0 deletions arch/x86/kvm/pvm/pvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@
#define PVM_EXIT_REASONS_INTERRUPT (5UL << PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_INT80 (6UL << PVM_EXIT_REASONS_SHIFT)

#define PVM_EXIT_REASONS_HC_IRQ_WIN (PVM_EXIT_REASONS_HYPERCALL + 1)
#define PVM_EXIT_REASONS_HC_IRQ_HALT (PVM_EXIT_REASONS_HYPERCALL + 2)
#define PVM_EXIT_REASONS_HC_LOAD_PGTBL (PVM_EXIT_REASONS_HYPERCALL + 3)
#define PVM_EXIT_REASONS_HC_TLB_FLUSH (PVM_EXIT_REASONS_HYPERCALL + 4)
#define PVM_EXIT_REASONS_HC_TLB_FLUSH_CURRENT (PVM_EXIT_REASONS_HYPERCALL + 5)
#define PVM_EXIT_REASONS_HC_TLB_INVLPG (PVM_EXIT_REASONS_HYPERCALL + 6)
#define PVM_EXIT_REASONS_HC_LOAD_GS (PVM_EXIT_REASONS_HYPERCALL + 7)
#define PVM_EXIT_REASONS_HC_RDMSR (PVM_EXIT_REASONS_HYPERCALL + 8)
#define PVM_EXIT_REASONS_HC_WRMSR (PVM_EXIT_REASONS_HYPERCALL + 9)
#define PVM_EXIT_REASONS_HC_LOAD_TLS (PVM_EXIT_REASONS_HYPERCALL + 10)

#define PVM_EXIT_REASONS \
{ DE_VECTOR, "DE excp" }, \
{ DB_VECTOR, "DB excp" }, \
Expand All @@ -61,6 +72,16 @@
{ PVM_EXIT_REASONS_ERETS, "ERETS" }, \
{ PVM_EXIT_REASONS_INTERRUPT, "INTERRUPT" }, \
{ PVM_EXIT_REASONS_INT80, "INT80" }, \
{ PVM_EXIT_REASONS_HC_IRQ_WIN, "HC_IRQ_WIN" }, \
{ PVM_EXIT_REASONS_HC_IRQ_HALT, "HC_IRQ_HALT" }, \
{ PVM_EXIT_REASONS_HC_LOAD_PGTBL, "HC_LOAD_PGTBL" }, \
{ PVM_EXIT_REASONS_HC_TLB_FLUSH, "HC_TLB_FLUSH" }, \
{ PVM_EXIT_REASONS_HC_TLB_FLUSH_CURRENT, "HC_TLB_FLUSH_CURRENT" },\
{ PVM_EXIT_REASONS_HC_TLB_INVLPG, "HC_TLB_INVLPG" }, \
{ PVM_EXIT_REASONS_HC_LOAD_GS, "HC_LOAD_GS" }, \
{ PVM_EXIT_REASONS_HC_RDMSR, "HC_RDMSR" }, \
{ PVM_EXIT_REASONS_HC_WRMSR, "HC_WRMSR" }, \
{ PVM_EXIT_REASONS_HC_LOAD_TLS, "HC_LOAD_TLS" }, \
{ PVM_FAILED_VMENTRY_VECTOR, "FAILED_VMENTRY" }

#define PT_L4_SHIFT 39
Expand Down
66 changes: 66 additions & 0 deletions tools/arch/x86/include/uapi/asm/pvm_trace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef UAPI_KVM_X86_PVM_TRACE_H
#define UAPI_KVM_X86_PVM_TRACE_H

#include <linux/bitops.h>

#define NMI_VECTOR 0x02
#define PVM_EXIT_REASONS_FAILED_VMENTRY 1025

#define PVM_EXIT_REASONS_SHIFT 16
#define PVM_EXIT_REASONS_SYSCALL BIT(PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_HYPERCALL (2UL << PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_ERETU (3UL << PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_ERETS (4UL << PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_INTERRUPT (5UL << PVM_EXIT_REASONS_SHIFT)
#define PVM_EXIT_REASONS_INT80 (6UL << PVM_EXIT_REASONS_SHIFT)

#define PVM_EXIT_REASONS_HC_IRQ_WIN (PVM_EXIT_REASONS_HYPERCALL + 1)
#define PVM_EXIT_REASONS_HC_IRQ_HALT (PVM_EXIT_REASONS_HYPERCALL + 2)
#define PVM_EXIT_REASONS_HC_LOAD_PGTBL (PVM_EXIT_REASONS_HYPERCALL + 3)
#define PVM_EXIT_REASONS_HC_TLB_FLUSH (PVM_EXIT_REASONS_HYPERCALL + 4)
#define PVM_EXIT_REASONS_HC_TLB_FLUSH_CURRENT (PVM_EXIT_REASONS_HYPERCALL + 5)
#define PVM_EXIT_REASONS_HC_TLB_INVLPG (PVM_EXIT_REASONS_HYPERCALL + 6)
#define PVM_EXIT_REASONS_HC_LOAD_GS (PVM_EXIT_REASONS_HYPERCALL + 7)
#define PVM_EXIT_REASONS_HC_RDMSR (PVM_EXIT_REASONS_HYPERCALL + 8)
#define PVM_EXIT_REASONS_HC_WRMSR (PVM_EXIT_REASONS_HYPERCALL + 9)
#define PVM_EXIT_REASONS_HC_LOAD_TLS (PVM_EXIT_REASONS_HYPERCALL + 10)

#define PVM_EXIT_REASONS \
{ DE_VECTOR, "DE excp" }, \
{ DB_VECTOR, "DB excp" }, \
{ NMI_VECTOR, "NMI excp" }, \
{ BP_VECTOR, "BP excp" }, \
{ OF_VECTOR, "OF excp" }, \
{ BR_VECTOR, "BR excp" }, \
{ UD_VECTOR, "UD excp" }, \
{ NM_VECTOR, "NM excp" }, \
{ DF_VECTOR, "DF excp" }, \
{ TS_VECTOR, "TS excp" }, \
{ SS_VECTOR, "SS excp" }, \
{ GP_VECTOR, "GP excp" }, \
{ PF_VECTOR, "PF excp" }, \
{ MF_VECTOR, "MF excp" }, \
{ AC_VECTOR, "AC excp" }, \
{ MC_VECTOR, "MC excp" }, \
{ XM_VECTOR, "XM excp" }, \
{ VE_VECTOR, "VE excp" }, \
{ PVM_EXIT_REASONS_SYSCALL, "SYSCALL" }, \
{ PVM_EXIT_REASONS_HYPERCALL, "HYPERCALL" }, \
{ PVM_EXIT_REASONS_ERETU, "ERETU" }, \
{ PVM_EXIT_REASONS_ERETS, "ERETS" }, \
{ PVM_EXIT_REASONS_INTERRUPT, "INTERRUPT" }, \
{ PVM_EXIT_REASONS_INT80, "INT80" }, \
{ PVM_EXIT_REASONS_HC_IRQ_WIN, "HC_IRQ_WIN" }, \
{ PVM_EXIT_REASONS_HC_IRQ_HALT, "HC_IRQ_HALT" }, \
{ PVM_EXIT_REASONS_HC_LOAD_PGTBL, "HC_LOAD_PGTBL" }, \
{ PVM_EXIT_REASONS_HC_TLB_FLUSH, "HC_TLB_FLUSH" }, \
{ PVM_EXIT_REASONS_HC_TLB_FLUSH_CURRENT, "HC_TLB_FLUSH_CURRENT" },\
{ PVM_EXIT_REASONS_HC_TLB_INVLPG, "HC_TLB_INVLPG" }, \
{ PVM_EXIT_REASONS_HC_LOAD_GS, "HC_LOAD_GS" }, \
{ PVM_EXIT_REASONS_HC_RDMSR, "HC_RDMSR" }, \
{ PVM_EXIT_REASONS_HC_WRMSR, "HC_WRMSR" }, \
{ PVM_EXIT_REASONS_HC_LOAD_TLS, "HC_LOAD_TLS" }, \
{ PVM_EXIT_REASONS_FAILED_VMENTRY, "FAILED_VMENTRY" }

#endif /* UAPI_KVM_X86_PVM_TRACE_H */
35 changes: 34 additions & 1 deletion tools/perf/arch/x86/util/kvm-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
#include <asm/svm.h>
#include <asm/vmx.h>
#include <asm/kvm.h>
#include <asm/pvm_trace.h>
#include <sys/stat.h>

define_exit_reasons_table(vmx_exit_reasons, VMX_EXIT_REASONS);
define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS);
define_exit_reasons_table(pvm_exit_reasons, PVM_EXIT_REASONS);

static struct kvm_events_ops exit_events = {
.is_begin_event = exit_event_begin,
Expand Down Expand Up @@ -198,9 +201,39 @@ const char * const kvm_skip_events[] = {
NULL,
};

#define INITSTATE_PATH_MAX 256
#define INITSTATE_MAX 16

static bool module_is_live(const char *module_name)
{
char initstate_path[INITSTATE_PATH_MAX];
char initstate[INITSTATE_MAX];
bool ret = false;
struct stat st;
FILE *fp;

snprintf(initstate_path, sizeof(initstate_path),
"/sys/module/%s/initstate", module_name);

if (!stat(initstate_path, &st) && S_ISREG(st.st_mode)) {
fp = fopen(initstate_path, "r");
if (fp) {
if (fgets(initstate, sizeof(initstate), fp))
ret = !strncmp(initstate, "live", 4);

fclose(fp);
}
}

return ret;
}

int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
{
if (strstr(cpuid, "Intel")) {
if (module_is_live("kvm_pvm")) {
kvm->exit_reasons = pvm_exit_reasons;
kvm->exit_reasons_isa = "PVM";
} else if (strstr(cpuid, "Intel")) {
kvm->exit_reasons = vmx_exit_reasons;
kvm->exit_reasons_isa = "VMX";
} else if (strstr(cpuid, "AMD") || strstr(cpuid, "Hygon")) {
Expand Down
5 changes: 5 additions & 0 deletions tools/perf/builtin-kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <sys/stat.h>
#include <fcntl.h>

#include <asm/pvm_trace.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/string.h>
Expand Down Expand Up @@ -620,7 +621,11 @@ void exit_event_get_key(struct evsel *evsel,
struct event_key *key)
{
key->info = 0;
key->info2 = evsel__intval(evsel, sample, "info2");
key->key = evsel__intval(evsel, sample, kvm_exit_reason);

if (key->key == PVM_EXIT_REASONS_HYPERCALL)
key->key = key->info2;
}

bool kvm_exit_event(struct evsel *evsel)
Expand Down
1 change: 1 addition & 0 deletions tools/perf/check-headers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ FILES=(
"arch/powerpc/include/uapi/asm/perf_regs.h"
"arch/s390/include/uapi/asm/perf_regs.h"
"arch/x86/include/uapi/asm/perf_regs.h"
"arch/x86/include/uapi/asm/pvm_trace.h"
"arch/x86/include/uapi/asm/kvm.h"
"arch/x86/include/uapi/asm/kvm_perf.h"
"arch/x86/include/uapi/asm/svm.h"
Expand Down
1 change: 1 addition & 0 deletions tools/perf/util/kvm-stat.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct event_key {
#define INVALID_KEY (~0ULL)
u64 key;
int info;
u64 info2;
struct exit_reasons_table *exit_reasons;
};

Expand Down