Commit 24e09cbf authored by Joerg Roedel's avatar Joerg Roedel Committed by Avi Kivity

KVM: SVM: enable LBR virtualization

This patch implements the Last Branch Record Virtualization (LBRV) feature of
the AMD Barcelona and Phenom processors into the kvm-amd module. It will only
be enabled if the guest enables last branch recording in the DEBUG_CTL MSR. So
there is no increased world switch overhead when the guest doesn't use these
MSRs.
Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
Signed-off-by: default avatarMarkus Rechberger <markus.rechberger@amd.com>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent f65c229c
...@@ -47,6 +47,8 @@ MODULE_LICENSE("GPL"); ...@@ -47,6 +47,8 @@ MODULE_LICENSE("GPL");
#define SVM_FEATURE_LBRV (1 << 1) #define SVM_FEATURE_LBRV (1 << 1)
#define SVM_DEATURE_SVML (1 << 2) #define SVM_DEATURE_SVML (1 << 2)
#define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
/* enable NPT for AMD64 and X86 with PAE */ /* enable NPT for AMD64 and X86 with PAE */
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
static bool npt_enabled = true; static bool npt_enabled = true;
...@@ -387,6 +389,28 @@ static void svm_vcpu_init_msrpm(u32 *msrpm) ...@@ -387,6 +389,28 @@ static void svm_vcpu_init_msrpm(u32 *msrpm)
set_msr_interception(msrpm, MSR_IA32_SYSENTER_EIP, 1, 1); set_msr_interception(msrpm, MSR_IA32_SYSENTER_EIP, 1, 1);
} }
static void svm_enable_lbrv(struct vcpu_svm *svm)
{
u32 *msrpm = svm->msrpm;
svm->vmcb->control.lbr_ctl = 1;
set_msr_interception(msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1);
set_msr_interception(msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1);
set_msr_interception(msrpm, MSR_IA32_LASTINTFROMIP, 1, 1);
set_msr_interception(msrpm, MSR_IA32_LASTINTTOIP, 1, 1);
}
static void svm_disable_lbrv(struct vcpu_svm *svm)
{
u32 *msrpm = svm->msrpm;
svm->vmcb->control.lbr_ctl = 0;
set_msr_interception(msrpm, MSR_IA32_LASTBRANCHFROMIP, 0, 0);
set_msr_interception(msrpm, MSR_IA32_LASTBRANCHTOIP, 0, 0);
set_msr_interception(msrpm, MSR_IA32_LASTINTFROMIP, 0, 0);
set_msr_interception(msrpm, MSR_IA32_LASTINTTOIP, 0, 0);
}
static __init int svm_hardware_setup(void) static __init int svm_hardware_setup(void)
{ {
int cpu; int cpu;
...@@ -1231,8 +1255,19 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) ...@@ -1231,8 +1255,19 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
svm->vmcb->save.sysenter_esp = data; svm->vmcb->save.sysenter_esp = data;
break; break;
case MSR_IA32_DEBUGCTLMSR: case MSR_IA32_DEBUGCTLMSR:
pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTLMSR 0x%llx, nop\n", if (!svm_has(SVM_FEATURE_LBRV)) {
__FUNCTION__, data); pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n",
__FUNCTION__, data);
break;
}
if (data & DEBUGCTL_RESERVED_BITS)
return 1;
svm->vmcb->save.dbgctl = data;
if (data & (1ULL<<0))
svm_enable_lbrv(svm);
else
svm_disable_lbrv(svm);
break; break;
case MSR_K7_EVNTSEL0: case MSR_K7_EVNTSEL0:
case MSR_K7_EVNTSEL1: case MSR_K7_EVNTSEL1:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment