diff options
Diffstat (limited to '0006-x86-vmx-Calculate-model-specific-LBRs-once-at-start-.patch')
-rw-r--r-- | 0006-x86-vmx-Calculate-model-specific-LBRs-once-at-start-.patch | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/0006-x86-vmx-Calculate-model-specific-LBRs-once-at-start-.patch b/0006-x86-vmx-Calculate-model-specific-LBRs-once-at-start-.patch new file mode 100644 index 0000000..c010110 --- /dev/null +++ b/0006-x86-vmx-Calculate-model-specific-LBRs-once-at-start-.patch @@ -0,0 +1,342 @@ +From 401e9e33a04c2a9887636ef58490c764543f0538 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Tue, 7 Feb 2023 17:04:18 +0100 +Subject: [PATCH 06/61] x86/vmx: Calculate model-specific LBRs once at start of + day + +There is no point repeating this calculation at runtime, especially as it is +in the fallback path of the WRSMR/RDMSR handlers. + +Move the infrastructure higher in vmx.c to avoid forward declarations, +renaming last_branch_msr_get() to get_model_specific_lbr() to highlight that +these are model-specific only. + +No practical change. + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +Reviewed-by: Kevin Tian <kevin.tian@intel.com> +master commit: e94af0d58f86c3a914b9cbbf4d9ed3d43b974771 +master date: 2023-01-12 18:42:00 +0000 +--- + xen/arch/x86/hvm/vmx/vmx.c | 276 +++++++++++++++++++------------------ + 1 file changed, 139 insertions(+), 137 deletions(-) + +diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c +index 3f42765313..bc308d9df2 100644 +--- a/xen/arch/x86/hvm/vmx/vmx.c ++++ b/xen/arch/x86/hvm/vmx/vmx.c +@@ -394,6 +394,142 @@ void vmx_pi_hooks_deassign(struct domain *d) + domain_unpause(d); + } + ++static const struct lbr_info { ++ u32 base, count; ++} p4_lbr[] = { ++ { MSR_P4_LER_FROM_LIP, 1 }, ++ { MSR_P4_LER_TO_LIP, 1 }, ++ { MSR_P4_LASTBRANCH_TOS, 1 }, ++ { MSR_P4_LASTBRANCH_0_FROM_LIP, NUM_MSR_P4_LASTBRANCH_FROM_TO }, ++ { MSR_P4_LASTBRANCH_0_TO_LIP, NUM_MSR_P4_LASTBRANCH_FROM_TO }, ++ { 0, 0 } ++}, c2_lbr[] = { ++ { MSR_IA32_LASTINTFROMIP, 1 }, ++ { MSR_IA32_LASTINTTOIP, 1 }, ++ { MSR_C2_LASTBRANCH_TOS, 1 }, ++ { MSR_C2_LASTBRANCH_0_FROM_IP, NUM_MSR_C2_LASTBRANCH_FROM_TO }, ++ { MSR_C2_LASTBRANCH_0_TO_IP, NUM_MSR_C2_LASTBRANCH_FROM_TO }, ++ { 0, 0 } ++}, nh_lbr[] = { ++ { MSR_IA32_LASTINTFROMIP, 1 }, ++ { MSR_IA32_LASTINTTOIP, 1 }, ++ { MSR_NHL_LBR_SELECT, 1 }, ++ { MSR_NHL_LASTBRANCH_TOS, 1 }, ++ { MSR_P4_LASTBRANCH_0_FROM_LIP, NUM_MSR_P4_LASTBRANCH_FROM_TO }, ++ { MSR_P4_LASTBRANCH_0_TO_LIP, NUM_MSR_P4_LASTBRANCH_FROM_TO }, ++ { 0, 0 } ++}, sk_lbr[] = { ++ { MSR_IA32_LASTINTFROMIP, 1 }, ++ { MSR_IA32_LASTINTTOIP, 1 }, ++ { MSR_NHL_LBR_SELECT, 1 }, ++ { MSR_NHL_LASTBRANCH_TOS, 1 }, ++ { MSR_SKL_LASTBRANCH_0_FROM_IP, NUM_MSR_SKL_LASTBRANCH }, ++ { MSR_SKL_LASTBRANCH_0_TO_IP, NUM_MSR_SKL_LASTBRANCH }, ++ { MSR_SKL_LASTBRANCH_0_INFO, NUM_MSR_SKL_LASTBRANCH }, ++ { 0, 0 } ++}, at_lbr[] = { ++ { MSR_IA32_LASTINTFROMIP, 1 }, ++ { MSR_IA32_LASTINTTOIP, 1 }, ++ { MSR_C2_LASTBRANCH_TOS, 1 }, ++ { MSR_C2_LASTBRANCH_0_FROM_IP, NUM_MSR_ATOM_LASTBRANCH_FROM_TO }, ++ { MSR_C2_LASTBRANCH_0_TO_IP, NUM_MSR_ATOM_LASTBRANCH_FROM_TO }, ++ { 0, 0 } ++}, sm_lbr[] = { ++ { MSR_IA32_LASTINTFROMIP, 1 }, ++ { MSR_IA32_LASTINTTOIP, 1 }, ++ { MSR_SM_LBR_SELECT, 1 }, ++ { MSR_SM_LASTBRANCH_TOS, 1 }, ++ { MSR_C2_LASTBRANCH_0_FROM_IP, NUM_MSR_ATOM_LASTBRANCH_FROM_TO }, ++ { MSR_C2_LASTBRANCH_0_TO_IP, NUM_MSR_ATOM_LASTBRANCH_FROM_TO }, ++ { 0, 0 } ++}, gm_lbr[] = { ++ { MSR_IA32_LASTINTFROMIP, 1 }, ++ { MSR_IA32_LASTINTTOIP, 1 }, ++ { MSR_SM_LBR_SELECT, 1 }, ++ { MSR_SM_LASTBRANCH_TOS, 1 }, ++ { MSR_GM_LASTBRANCH_0_FROM_IP, NUM_MSR_GM_LASTBRANCH_FROM_TO }, ++ { MSR_GM_LASTBRANCH_0_TO_IP, NUM_MSR_GM_LASTBRANCH_FROM_TO }, ++ { 0, 0 } ++}; ++static const struct lbr_info *__read_mostly model_specific_lbr; ++ ++static const struct lbr_info *__init get_model_specific_lbr(void) ++{ ++ switch ( boot_cpu_data.x86 ) ++ { ++ case 6: ++ switch ( boot_cpu_data.x86_model ) ++ { ++ /* Core2 Duo */ ++ case 0x0f: ++ /* Enhanced Core */ ++ case 0x17: ++ /* Xeon 7400 */ ++ case 0x1d: ++ return c2_lbr; ++ /* Nehalem */ ++ case 0x1a: case 0x1e: case 0x1f: case 0x2e: ++ /* Westmere */ ++ case 0x25: case 0x2c: case 0x2f: ++ /* Sandy Bridge */ ++ case 0x2a: case 0x2d: ++ /* Ivy Bridge */ ++ case 0x3a: case 0x3e: ++ /* Haswell */ ++ case 0x3c: case 0x3f: case 0x45: case 0x46: ++ /* Broadwell */ ++ case 0x3d: case 0x47: case 0x4f: case 0x56: ++ return nh_lbr; ++ /* Skylake */ ++ case 0x4e: case 0x5e: ++ /* Xeon Scalable */ ++ case 0x55: ++ /* Cannon Lake */ ++ case 0x66: ++ /* Goldmont Plus */ ++ case 0x7a: ++ /* Ice Lake */ ++ case 0x6a: case 0x6c: case 0x7d: case 0x7e: ++ /* Tiger Lake */ ++ case 0x8c: case 0x8d: ++ /* Tremont */ ++ case 0x86: ++ /* Kaby Lake */ ++ case 0x8e: case 0x9e: ++ /* Comet Lake */ ++ case 0xa5: case 0xa6: ++ return sk_lbr; ++ /* Atom */ ++ case 0x1c: case 0x26: case 0x27: case 0x35: case 0x36: ++ return at_lbr; ++ /* Silvermont */ ++ case 0x37: case 0x4a: case 0x4d: case 0x5a: case 0x5d: ++ /* Xeon Phi Knights Landing */ ++ case 0x57: ++ /* Xeon Phi Knights Mill */ ++ case 0x85: ++ /* Airmont */ ++ case 0x4c: ++ return sm_lbr; ++ /* Goldmont */ ++ case 0x5c: case 0x5f: ++ return gm_lbr; ++ } ++ break; ++ ++ case 15: ++ switch ( boot_cpu_data.x86_model ) ++ { ++ /* Pentium4/Xeon with em64t */ ++ case 3: case 4: case 6: ++ return p4_lbr; ++ } ++ break; ++ } ++ ++ return NULL; ++} ++ + static int vmx_domain_initialise(struct domain *d) + { + static const struct arch_csw csw = { +@@ -2812,6 +2948,7 @@ const struct hvm_function_table * __init start_vmx(void) + vmx_function_table.get_guest_bndcfgs = vmx_get_guest_bndcfgs; + } + ++ model_specific_lbr = get_model_specific_lbr(); + lbr_tsx_fixup_check(); + ler_to_fixup_check(); + +@@ -2958,141 +3095,6 @@ static int vmx_cr_access(cr_access_qual_t qual) + return X86EMUL_OKAY; + } + +-static const struct lbr_info { +- u32 base, count; +-} p4_lbr[] = { +- { MSR_P4_LER_FROM_LIP, 1 }, +- { MSR_P4_LER_TO_LIP, 1 }, +- { MSR_P4_LASTBRANCH_TOS, 1 }, +- { MSR_P4_LASTBRANCH_0_FROM_LIP, NUM_MSR_P4_LASTBRANCH_FROM_TO }, +- { MSR_P4_LASTBRANCH_0_TO_LIP, NUM_MSR_P4_LASTBRANCH_FROM_TO }, +- { 0, 0 } +-}, c2_lbr[] = { +- { MSR_IA32_LASTINTFROMIP, 1 }, +- { MSR_IA32_LASTINTTOIP, 1 }, +- { MSR_C2_LASTBRANCH_TOS, 1 }, +- { MSR_C2_LASTBRANCH_0_FROM_IP, NUM_MSR_C2_LASTBRANCH_FROM_TO }, +- { MSR_C2_LASTBRANCH_0_TO_IP, NUM_MSR_C2_LASTBRANCH_FROM_TO }, +- { 0, 0 } +-}, nh_lbr[] = { +- { MSR_IA32_LASTINTFROMIP, 1 }, +- { MSR_IA32_LASTINTTOIP, 1 }, +- { MSR_NHL_LBR_SELECT, 1 }, +- { MSR_NHL_LASTBRANCH_TOS, 1 }, +- { MSR_P4_LASTBRANCH_0_FROM_LIP, NUM_MSR_P4_LASTBRANCH_FROM_TO }, +- { MSR_P4_LASTBRANCH_0_TO_LIP, NUM_MSR_P4_LASTBRANCH_FROM_TO }, +- { 0, 0 } +-}, sk_lbr[] = { +- { MSR_IA32_LASTINTFROMIP, 1 }, +- { MSR_IA32_LASTINTTOIP, 1 }, +- { MSR_NHL_LBR_SELECT, 1 }, +- { MSR_NHL_LASTBRANCH_TOS, 1 }, +- { MSR_SKL_LASTBRANCH_0_FROM_IP, NUM_MSR_SKL_LASTBRANCH }, +- { MSR_SKL_LASTBRANCH_0_TO_IP, NUM_MSR_SKL_LASTBRANCH }, +- { MSR_SKL_LASTBRANCH_0_INFO, NUM_MSR_SKL_LASTBRANCH }, +- { 0, 0 } +-}, at_lbr[] = { +- { MSR_IA32_LASTINTFROMIP, 1 }, +- { MSR_IA32_LASTINTTOIP, 1 }, +- { MSR_C2_LASTBRANCH_TOS, 1 }, +- { MSR_C2_LASTBRANCH_0_FROM_IP, NUM_MSR_ATOM_LASTBRANCH_FROM_TO }, +- { MSR_C2_LASTBRANCH_0_TO_IP, NUM_MSR_ATOM_LASTBRANCH_FROM_TO }, +- { 0, 0 } +-}, sm_lbr[] = { +- { MSR_IA32_LASTINTFROMIP, 1 }, +- { MSR_IA32_LASTINTTOIP, 1 }, +- { MSR_SM_LBR_SELECT, 1 }, +- { MSR_SM_LASTBRANCH_TOS, 1 }, +- { MSR_C2_LASTBRANCH_0_FROM_IP, NUM_MSR_ATOM_LASTBRANCH_FROM_TO }, +- { MSR_C2_LASTBRANCH_0_TO_IP, NUM_MSR_ATOM_LASTBRANCH_FROM_TO }, +- { 0, 0 } +-}, gm_lbr[] = { +- { MSR_IA32_LASTINTFROMIP, 1 }, +- { MSR_IA32_LASTINTTOIP, 1 }, +- { MSR_SM_LBR_SELECT, 1 }, +- { MSR_SM_LASTBRANCH_TOS, 1 }, +- { MSR_GM_LASTBRANCH_0_FROM_IP, NUM_MSR_GM_LASTBRANCH_FROM_TO }, +- { MSR_GM_LASTBRANCH_0_TO_IP, NUM_MSR_GM_LASTBRANCH_FROM_TO }, +- { 0, 0 } +-}; +- +-static const struct lbr_info *last_branch_msr_get(void) +-{ +- switch ( boot_cpu_data.x86 ) +- { +- case 6: +- switch ( boot_cpu_data.x86_model ) +- { +- /* Core2 Duo */ +- case 0x0f: +- /* Enhanced Core */ +- case 0x17: +- /* Xeon 7400 */ +- case 0x1d: +- return c2_lbr; +- /* Nehalem */ +- case 0x1a: case 0x1e: case 0x1f: case 0x2e: +- /* Westmere */ +- case 0x25: case 0x2c: case 0x2f: +- /* Sandy Bridge */ +- case 0x2a: case 0x2d: +- /* Ivy Bridge */ +- case 0x3a: case 0x3e: +- /* Haswell */ +- case 0x3c: case 0x3f: case 0x45: case 0x46: +- /* Broadwell */ +- case 0x3d: case 0x47: case 0x4f: case 0x56: +- return nh_lbr; +- /* Skylake */ +- case 0x4e: case 0x5e: +- /* Xeon Scalable */ +- case 0x55: +- /* Cannon Lake */ +- case 0x66: +- /* Goldmont Plus */ +- case 0x7a: +- /* Ice Lake */ +- case 0x6a: case 0x6c: case 0x7d: case 0x7e: +- /* Tiger Lake */ +- case 0x8c: case 0x8d: +- /* Tremont */ +- case 0x86: +- /* Kaby Lake */ +- case 0x8e: case 0x9e: +- /* Comet Lake */ +- case 0xa5: case 0xa6: +- return sk_lbr; +- /* Atom */ +- case 0x1c: case 0x26: case 0x27: case 0x35: case 0x36: +- return at_lbr; +- /* Silvermont */ +- case 0x37: case 0x4a: case 0x4d: case 0x5a: case 0x5d: +- /* Xeon Phi Knights Landing */ +- case 0x57: +- /* Xeon Phi Knights Mill */ +- case 0x85: +- /* Airmont */ +- case 0x4c: +- return sm_lbr; +- /* Goldmont */ +- case 0x5c: case 0x5f: +- return gm_lbr; +- } +- break; +- +- case 15: +- switch ( boot_cpu_data.x86_model ) +- { +- /* Pentium4/Xeon with em64t */ +- case 3: case 4: case 6: +- return p4_lbr; +- } +- break; +- } +- +- return NULL; +-} +- + enum + { + LBR_FORMAT_32 = 0x0, /* 32-bit record format */ +@@ -3199,7 +3201,7 @@ static void __init ler_to_fixup_check(void) + + static int is_last_branch_msr(u32 ecx) + { +- const struct lbr_info *lbr = last_branch_msr_get(); ++ const struct lbr_info *lbr = model_specific_lbr; + + if ( lbr == NULL ) + return 0; +@@ -3536,7 +3538,7 @@ static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content) + if ( !(v->arch.hvm.vmx.lbr_flags & LBR_MSRS_INSERTED) && + (msr_content & IA32_DEBUGCTLMSR_LBR) ) + { +- const struct lbr_info *lbr = last_branch_msr_get(); ++ const struct lbr_info *lbr = model_specific_lbr; + + if ( unlikely(!lbr) ) + { +-- +2.40.0 + |