mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-22 20:20:05 +07:00
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: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Markus Rechberger <markus.rechberger@amd.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:
parent
f65c229c3e
commit
24e09cbf48
@ -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)
|
|||||||
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,9 +1255,20 @@ 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)) {
|
||||||
|
pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n",
|
||||||
__FUNCTION__, data);
|
__FUNCTION__, data);
|
||||||
break;
|
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;
|
||||||
case MSR_K7_EVNTSEL0:
|
case MSR_K7_EVNTSEL0:
|
||||||
case MSR_K7_EVNTSEL1:
|
case MSR_K7_EVNTSEL1:
|
||||||
case MSR_K7_EVNTSEL2:
|
case MSR_K7_EVNTSEL2:
|
||||||
|
Loading…
Reference in New Issue
Block a user