Skip to content

Commit

Permalink
x86: Prevent interference by Intel perf counters
Browse files Browse the repository at this point in the history
Make it simple but safe: Disable perf counters during setup and prevent
that cells can modify the corresponding MSR. This avoids that we have
to switch the MSR during vmentry/exit, but it also blocks perf & friends
while Jailhouse is active.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
  • Loading branch information
jan-kiszka committed Apr 10, 2015
1 parent a9cf035 commit 25226b5
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 3 deletions.
1 change: 1 addition & 0 deletions hypervisor/arch/x86/include/asm/processor.h
Expand Up @@ -62,6 +62,7 @@
#define MSR_IA32_SYSENTER_CS 0x00000174
#define MSR_IA32_SYSENTER_ESP 0x00000175
#define MSR_IA32_SYSENTER_EIP 0x00000176
#define MSR_IA32_PERF_GLOBAL_CTRL 0x0000038f
#define MSR_IA32_VMX_BASIC 0x00000480
#define MSR_IA32_VMX_PINBASED_CTLS 0x00000481
#define MSR_IA32_VMX_PROCBASED_CTLS 0x00000482
Expand Down
16 changes: 13 additions & 3 deletions hypervisor/arch/x86/vmx.c
@@ -1,7 +1,7 @@
/*
* Jailhouse, a Linux-based partitioning hypervisor
*
* Copyright (c) Siemens AG, 2013
* Copyright (c) Siemens AG, 2013-2015
* Copyright (c) Valentine Sinitsyn, 2014
*
* Authors:
Expand Down Expand Up @@ -56,7 +56,9 @@ static u8 __attribute__((aligned(PAGE_SIZE))) msr_bitmap[][0x2000/8] = {
[ VMX_MSR_BMP_0000_WRITE ] = {
[ 0/8 ... 0x17/8 ] = 0,
[ 0x18/8 ... 0x1f/8 ] = 0x08, /* 0x01b */
[ 0x20/8 ... 0x7ff/8 ] = 0,
[ 0x20/8 ... 0x387/8 ] = 0,
[ 0x388/8 ... 0x38f/8 ] = 0x80, /* 0x38f */
[ 0x390/8 ... 0x7ff/8 ] = 0,
[ 0x808/8 ... 0x80f/8 ] = 0x89, /* 0x808, 0x80b, 0x80f */
[ 0x810/8 ... 0x827/8 ] = 0,
[ 0x828/8 ... 0x82f/8 ] = 0x81, /* 0x828, 0x82f */
Expand Down Expand Up @@ -511,7 +513,7 @@ static bool vmcs_setup(struct per_cpu *cpu_data)

ok &= vmcs_write64(GUEST_IA32_EFER, cpu_data->linux_efer);

// TODO: switch PAT, PERF */
// TODO: switch PAT */

ok &= vmcs_write64(VMCS_LINK_POINTER, -1UL);
ok &= vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0);
Expand Down Expand Up @@ -569,6 +571,10 @@ int vcpu_init(struct per_cpu *cpu_data)
u32 revision_id;
int err;

/* make sure all perf counters are off */
if ((cpuid_eax(0x0a) & 0xff) > 0)
write_msr(MSR_IA32_PERF_GLOBAL_CTRL, 0);

if (cpu_data->linux_cr4 & X86_CR4_VMXE)
return trace_error(-EBUSY);

Expand Down Expand Up @@ -1068,6 +1074,10 @@ void vcpu_handle_exit(struct registers *guest_regs, struct per_cpu *cpu_data)
break;
vcpu_skip_emulated_instruction(X86_INST_LEN_WRMSR);
return;
} else if (guest_regs->rcx == MSR_IA32_PERF_GLOBAL_CTRL) {
/* ignore writes */
vcpu_skip_emulated_instruction(X86_INST_LEN_WRMSR);
return;
}
panic_printk("FATAL: Unhandled MSR write: %08x\n",
guest_regs->rcx);
Expand Down

0 comments on commit 25226b5

Please sign in to comment.