The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh8-4.18.0-240.1.1.vz8.5.23 ------> commit 1fb36a7c3b577381714bd6bcee5f629839dfad45 Author: Jan Dakinevich <jan.dakinev...@virtuozzo.com> Date: Fri Apr 30 13:21:23 2021 +0300
KVM: x86/vPMU: Ignore access to LBR-related MSRs Windows Server 2016 Essentials (for yet unknown reason) attempts to access MSR_LBR_TOS and other LBR-related registers at startup. These are not currently hadled by KVM so the guest gets #GP and crashes. To prevent that, identify LBR-related MSRs pertinent to the CPU model exposed to the guest, and dummy handle them (ignore writes and return zero on reads). https://jira.sw.ru/browse/PSBM-75679 Signed-off-by: Jan Dakinevich <jan.dakinev...@virtuozzo.com> Commit 29ae48aecec8 in the kernels from VZ7. Done in the scope of https://jira.sw.ru/browse/PSBM-127794. Note. It looks like, the recent mainline kernels (5.12-rcN+) added support for passthrough of LBR registers to the guest systems. It should probably fix the issue described in PSBM-75679 but I haven't tried that. Details: https://lore.kernel.org/kvm/20210201051039.255478-1-like...@linux.intel.com That patchset has more prerequisites and some follow-up fixes. It is likely it has not been tested very thoroughly in production yet, esp. with Windows guests. The kernels 4.18.0-240.* from RHEL8 do not have it yet, by the way. I'd stick with the VZ-specific patches for now, they are less invasive. Signed-off-by: Evgenii Shatokhin <eshatok...@virtuozzo.com> ===================== Patchset description: KVM: x86/vPMU: ignore access to LBR-related MSRs (PSBM-75679) This is the part of patchset from PSBM-75679 which is not present in mainline or RHEL kernels. I have adapted it to VZ8, added handling of new CPU models and simplified the code a bit more. Apart from that the patches have been renamed. The first two were named "perf/x86/intel: make reusable LBR initialization code, part 1/2" and "perf/x86/intel: make reusable LBR initialization code, part 2/2" in VZ7. This confused the tools like 'git format-patch' which stripped the last parts of the names, making them identical. "ms/" prefix was also removed: the patches did not make it into the mainline kernel. They are probably not needed there: It looks like, the recent mainline kernels (5.12-rcN+) added support for passthrough of LBR registers to the guest systems. It should probably fix the issue described in PSBM-75679 but I haven't tried that. Details: https://lore.kernel.org/kvm/20210201051039.255478-1-like...@linux.intel.com That mainline patchset has more prerequisites and some follow-up fixes. It is likely, it has not been tested very thoroughly in production yet, esp. with Windows guests. The kernels 4.18.0-240.* from RHEL8 do not have it yet, by the way. I'd stick with the VZ-specific patches for now, they are less invasive. https://jira.sw.ru/browse/PSBM-75679 Done in the scope of https://jira.sw.ru/browse/PSBM-127794 Signed-off-by: Evgenii Shatokhin <eshatok...@virtuozzo.com> --- arch/x86/include/asm/kvm_host.h | 3 +++ arch/x86/kvm/vmx/pmu_intel.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 66b04b85ec51..65df58b61830 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -37,6 +37,7 @@ #include <asm/kvm_page_track.h> #include <asm/kvm_vcpu_regs.h> #include <asm/hyperv-tlfs.h> +#include <asm/perf_event.h> #define __KVM_HAVE_ARCH_VCPU_DEBUGFS @@ -506,6 +507,8 @@ struct kvm_pmu { * redundant check before cleanup if guest don't use vPMU at all. */ u8 event_count; + + struct x86_pmu_lbr lbr; }; struct kvm_pmu_ops; diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index e1a303fefc16..0df709f5b856 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -12,6 +12,7 @@ #include <linux/kvm_host.h> #include <linux/perf_event.h> #include <asm/perf_event.h> +#include <asm/cpu.h> #include "x86.h" #include "cpuid.h" #include "lapic.h" @@ -150,6 +151,24 @@ static struct kvm_pmc *intel_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu, return &counters[array_index_nospec(idx, num_counters)]; } +static bool intel_is_lbr_msr(struct kvm_vcpu *vcpu, u32 msr) +{ + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); + struct x86_pmu_lbr *lbr = &pmu->lbr; + + if (!lbr->nr) + return false; + + if (msr == lbr->tos) + return true; + if (msr >= lbr->from && msr < lbr->from + lbr->nr) + return true; + if (msr >= lbr->to && msr < lbr->to + lbr->nr) + return true; + + return false; +} + static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) { struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); @@ -163,6 +182,10 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr) ret = pmu->version > 1; break; default: + if (intel_is_lbr_msr(vcpu, msr)) { + ret = true; + break; + } ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0) || get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0) || get_fixed_pmc(pmu, msr); @@ -204,6 +227,10 @@ static int intel_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) msr_info->data = pmu->global_ovf_ctrl; return 0; default: + if (intel_is_lbr_msr(vcpu, msr)) { + msr_info->data = 0; + return 0; + } if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) { u64 val = pmc_read_counter(pmc); msr_info->data = @@ -262,6 +289,8 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) } break; default: + if (intel_is_lbr_msr(vcpu, msr)) + return 0; if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) { if (!msr_info->host_initiated) data = (s64)(s32)data; @@ -354,6 +383,11 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) INTEL_PMC_MAX_GENERIC, pmu->nr_arch_fixed_counters); nested_vmx_pmu_entry_exit_ctls_update(vcpu); + + entry = kvm_find_cpuid_entry(vcpu, 1, 0); + if (entry) + intel_pmu_lbr_fill(&pmu->lbr, + x86_family(entry->eax), x86_model(entry->eax)); } static void intel_pmu_init(struct kvm_vcpu *vcpu) _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel