On 10/8/18 2:48 PM, Jan Kiszka wrote: > On 08.10.18 13:36, Ralf Ramsauer wrote: >> In some configurations, MSR_X2APIC_ICR is the most frequently accessed MSR. >> Accounting it allows for getting an overview of its noise. >> >> Achieve this by splitting up the MSR count to msr_x2apic_icr and >> msr_other. The sum of msr_x2apic_icr and msr_other denotes the sum of >> all MSRs. >> >> Instead of accounting MSRs in the vcpu_handle_exit() path, move it over >> to vcpu.c and implement it with a tiny inlined helper, which is called >> by vcpu_handle_msr_{write,read}. With this, we have the same path for >> both, svm and vmx. >> >> Concerning the ABI, move MSR_* exits to the end of the end in order to >> prepare for more individual split ups of MSR accounting. >> >> Signed-off-by: Ralf Ramsauer <ralf.ramsa...@oth-regensburg.de> >> --- >> driver/sysfs.c | 7 ++++-- >> hypervisor/arch/x86/svm.c | 1 - >> hypervisor/arch/x86/vcpu.c | 26 +++++++++++++++++----- >> hypervisor/arch/x86/vmx.c | 2 -- >> include/arch/x86/asm/jailhouse_hypercall.h | 12 +++++----- >> 5 files changed, 32 insertions(+), 16 deletions(-) >> >> diff --git a/driver/sysfs.c b/driver/sysfs.c >> index 876fddc2..4232769e 100644 >> --- a/driver/sysfs.c >> +++ b/driver/sysfs.c >> @@ -104,11 +104,13 @@ JAILHOUSE_CPU_STATS_ATTR(vmexits_hypercall, >> JAILHOUSE_CPU_STATS_ATTR(vmexits_pio, JAILHOUSE_CPU_STAT_VMEXITS_PIO); >> JAILHOUSE_CPU_STATS_ATTR(vmexits_xapic, JAILHOUSE_CPU_STAT_VMEXITS_XAPIC); >> JAILHOUSE_CPU_STATS_ATTR(vmexits_cr, JAILHOUSE_CPU_STAT_VMEXITS_CR); >> -JAILHOUSE_CPU_STATS_ATTR(vmexits_msr, JAILHOUSE_CPU_STAT_VMEXITS_MSR); >> JAILHOUSE_CPU_STATS_ATTR(vmexits_cpuid, JAILHOUSE_CPU_STAT_VMEXITS_CPUID); >> JAILHOUSE_CPU_STATS_ATTR(vmexits_xsetbv, >> JAILHOUSE_CPU_STAT_VMEXITS_XSETBV); >> JAILHOUSE_CPU_STATS_ATTR(vmexits_exception, >> JAILHOUSE_CPU_STAT_VMEXITS_EXCEPTION); >> +JAILHOUSE_CPU_STATS_ATTR(vmexits_msr_other, >> JAILHOUSE_CPU_STAT_VMEXITS_MSR_OTHER); >> +JAILHOUSE_CPU_STATS_ATTR(vmexits_msr_x2apic_icr, >> + JAILHOUSE_CPU_STAT_VMEXITS_MSR_X2APIC_ICR); >> #elif defined(CONFIG_ARM) || defined(CONFIG_ARM64) >> JAILHOUSE_CPU_STATS_ATTR(vmexits_maintenance, >> JAILHOUSE_CPU_STAT_VMEXITS_MAINTENANCE); >> JAILHOUSE_CPU_STATS_ATTR(vmexits_virt_irq, >> JAILHOUSE_CPU_STAT_VMEXITS_VIRQ); >> @@ -128,10 +130,11 @@ static struct attribute *no_attrs[] = { >> &vmexits_pio_attr.kattr.attr, >> &vmexits_xapic_attr.kattr.attr, >> &vmexits_cr_attr.kattr.attr, >> - &vmexits_msr_attr.kattr.attr, >> &vmexits_cpuid_attr.kattr.attr, >> &vmexits_xsetbv_attr.kattr.attr, >> &vmexits_exception_attr.kattr.attr, >> + &vmexits_msr_other_attr.kattr.attr, >> + &vmexits_msr_x2apic_icr_attr.kattr.attr, >> #elif defined(CONFIG_ARM) || defined(CONFIG_ARM64) >> &vmexits_maintenance_attr.kattr.attr, >> &vmexits_virt_irq_attr.kattr.attr, >> diff --git a/hypervisor/arch/x86/svm.c b/hypervisor/arch/x86/svm.c >> index 1808e74e..e40ff0ec 100644 >> --- a/hypervisor/arch/x86/svm.c >> +++ b/hypervisor/arch/x86/svm.c >> @@ -924,7 +924,6 @@ void vcpu_handle_exit(struct per_cpu *cpu_data) >> vcpu_handle_cpuid(); >> goto vmentry; >> case VMEXIT_MSR: >> - cpu_public->stats[JAILHOUSE_CPU_STAT_VMEXITS_MSR]++; > > Now you will need to instrument svm_handle_msr_write /wrt MSR_EFER.
Argh, I see... > >> if (!vmcb->exitinfo1) >> res = vcpu_handle_msr_read(); >> else >> diff --git a/hypervisor/arch/x86/vcpu.c b/hypervisor/arch/x86/vcpu.c >> index 42184e9d..ee21d28e 100644 >> --- a/hypervisor/arch/x86/vcpu.c >> +++ b/hypervisor/arch/x86/vcpu.c >> @@ -265,11 +265,24 @@ invalid_access: >> return false; >> } >> >> +static inline void account_msr_exit(u64 msr) > > Let's do > > static inline void account_msr_exit(struct public_per_cpu *cpu_public, u64 > msr) > > and let the caller pass cpu_data->public. > >> +{ >> + struct public_per_cpu *cpu_public = &this_cpu_data()->public; >> + >> + if (msr == MSR_X2APIC_ICR) >> + cpu_public->stats[JAILHOUSE_CPU_STAT_VMEXITS_MSR_X2APIC_ICR]++; >> + else >> + cpu_public->stats[JAILHOUSE_CPU_STAT_VMEXITS_MSR_OTHER]++; >> +} >> + >> bool vcpu_handle_msr_read(void) >> { >> struct per_cpu *cpu_data = this_cpu_data(); >> + unsigned long msr = cpu_data->guest_regs.rcx; >> + >> + account_msr_exit(msr); >> >> - switch (cpu_data->guest_regs.rcx) { >> + switch (msr) { >> case MSR_X2APIC_BASE ... MSR_X2APIC_END: >> x2apic_handle_read(); >> break; >> @@ -281,8 +294,7 @@ bool vcpu_handle_msr_read(void) >> cpu_data->mtrr_def_type); >> break; >> default: >> - panic_printk("FATAL: Unhandled MSR read: %lx\n", >> - cpu_data->guest_regs.rcx); >> + panic_printk("FATAL: Unhandled MSR read: %lx\n", msr); >> return false; >> } >> >> @@ -293,10 +305,13 @@ bool vcpu_handle_msr_read(void) >> bool vcpu_handle_msr_write(void) >> { >> struct per_cpu *cpu_data = this_cpu_data(); >> + unsigned long msr = cpu_data->guest_regs.rcx; >> unsigned int bit_pos, pa; >> unsigned long val; >> >> - switch (cpu_data->guest_regs.rcx) { >> + account_msr_exit(msr); >> + >> + switch (msr) { >> case MSR_X2APIC_BASE ... MSR_X2APIC_END: >> if (!x2apic_handle_write()) >> return false; >> @@ -329,8 +344,7 @@ bool vcpu_handle_msr_write(void) >> cpu_data->pat : 0); >> break; >> default: >> - panic_printk("FATAL: Unhandled MSR write: %lx\n", >> - cpu_data->guest_regs.rcx); >> + panic_printk("FATAL: Unhandled MSR write: %lx\n", msr); >> return false; >> } >> >> diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c >> index 29967015..e9d66331 100644 >> --- a/hypervisor/arch/x86/vmx.c >> +++ b/hypervisor/arch/x86/vmx.c >> @@ -1183,12 +1183,10 @@ void vcpu_handle_exit(struct per_cpu *cpu_data) >> return; >> break; >> case EXIT_REASON_MSR_READ: >> - cpu_data->public.stats[JAILHOUSE_CPU_STAT_VMEXITS_MSR]++; >> if (vcpu_handle_msr_read()) >> return; >> break; >> case EXIT_REASON_MSR_WRITE: >> - cpu_data->public.stats[JAILHOUSE_CPU_STAT_VMEXITS_MSR]++; >> if (cpu_data->guest_regs.rcx == MSR_IA32_PERF_GLOBAL_CTRL) { >> /* ignore writes */ >> vcpu_skip_emulated_instruction(X86_INST_LEN_WRMSR); > > Same story as with MSR_EFER on AMD. Ok. Hmm. It's probably better to move account_msr_exit() to a header, and call it (again) directly from vcpu_handle_exit(). We need to hook there for EFER in any case. And instead of introducing a corner case for EFER, let's better hold accounting things at one place only. Ralf > >> diff --git a/include/arch/x86/asm/jailhouse_hypercall.h >> b/include/arch/x86/asm/jailhouse_hypercall.h >> index 3a52599f..9e72b277 100644 >> --- a/include/arch/x86/asm/jailhouse_hypercall.h >> +++ b/include/arch/x86/asm/jailhouse_hypercall.h >> @@ -58,11 +58,13 @@ >> #define JAILHOUSE_CPU_STAT_VMEXITS_PIO >> JAILHOUSE_GENERIC_CPU_STATS >> #define JAILHOUSE_CPU_STAT_VMEXITS_XAPIC JAILHOUSE_GENERIC_CPU_STATS + 1 >> #define JAILHOUSE_CPU_STAT_VMEXITS_CR >> JAILHOUSE_GENERIC_CPU_STATS + 2 >> -#define JAILHOUSE_CPU_STAT_VMEXITS_MSR >> JAILHOUSE_GENERIC_CPU_STATS + 3 >> -#define JAILHOUSE_CPU_STAT_VMEXITS_CPUID JAILHOUSE_GENERIC_CPU_STATS + 4 >> -#define JAILHOUSE_CPU_STAT_VMEXITS_XSETBV JAILHOUSE_GENERIC_CPU_STATS + 5 >> -#define JAILHOUSE_CPU_STAT_VMEXITS_EXCEPTION >> JAILHOUSE_GENERIC_CPU_STATS + 6 >> -#define JAILHOUSE_NUM_CPU_STATS >> JAILHOUSE_GENERIC_CPU_STATS + 7 >> +#define JAILHOUSE_CPU_STAT_VMEXITS_CPUID JAILHOUSE_GENERIC_CPU_STATS + 3 >> +#define JAILHOUSE_CPU_STAT_VMEXITS_XSETBV JAILHOUSE_GENERIC_CPU_STATS + 4 >> +#define JAILHOUSE_CPU_STAT_VMEXITS_EXCEPTION >> JAILHOUSE_GENERIC_CPU_STATS + 5 >> +#define JAILHOUSE_CPU_STAT_VMEXITS_MSR_OTHER >> JAILHOUSE_GENERIC_CPU_STATS + 6 >> +#define JAILHOUSE_CPU_STAT_VMEXITS_MSR_X2APIC_ICR \ >> + JAILHOUSE_GENERIC_CPU_STATS + 7 >> +#define JAILHOUSE_NUM_CPU_STATS >> JAILHOUSE_GENERIC_CPU_STATS + 8 >> >> /* CPUID interface */ >> #define JAILHOUSE_CPUID_SIGNATURE 0x40000000 >> > > Jan > -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to jailhouse-dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.