Nested kvm_intel broken on pre 3.3 hosts
I have been looking at a report[1] about the kvm_intel module failing to load on linux v3.3 and newer guests when running on a v3.2 host. Bisection turned up the following patch:
commit fee84b079d5ddee2247b5c1f53162c330c622902
Author: Avi Kivity <[email protected]> Date: Thu Nov 10 14:57:25 2011 +0200
KVM: VMX: Intercept RDPMC
Intercept RDPMC and forward it to the PMU emulation code.
It looks like requiring the feature based on cpu fails when the host (outer kvm module) code does not support it. So maybe that should be optional instead of required?
Seems also like kvm_amd does not "suffer" from any test that could fail and should be ok (though I did not test it personally).
-Stefan
[1] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1031090
Quoted 12 lines · Stefan Bader
I have been looking at a report[1] about the
kvm_intelmodule failing to load on linux v3.3 and newer guests when running on a v3.2 host. Bisection turned up the following patch:commit
fee84b079d5ddee2247b5c1f53162c330c622902Author: Avi Kivity <[email protected]> Date: Thu Nov 10 14:57:25 2011 +0200KVM: VMX: Intercept RDPMC
Intercept RDPMC and forward it to the PMU emulation code.
Quoted 7 lines
Signed-off-by Avi Kivity <[email protected]>Signed-off-by Gleb Natapov <[email protected]>Signed-off-by Avi Kivity <[email protected]>It looks like requiring the feature based on cpu fails when the host (outer kvm module) code does not support it. So maybe that should be optional instead of required?
According to Intel SDM there was never CPU that didn't support RDPMC exiting. Looks like unfortunate nested VMX bug.
Quoted 7 lines
Seems also like
kvm_amddoes not "suffer" from any test that could fail and should be ok (though I did not test it personally).-Stefan
[1] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1031090
--
Gleb.
Quoted 17 lines · Gleb Natapov
Quoted 16 lines · Stefan Bader
I have been looking at a report[1] about the
kvm_intelmodule failing to load on linux v3.3 and newer guests when running on a v3.2 host. Bisection turned up the following patch:commit
fee84b079d5ddee2247b5c1f53162c330c622902Author: Avi Kivity <[email protected]> Date: Thu Nov 10 14:57:25 2011 +0200KVM: VMX: Intercept RDPMC
Intercept RDPMC and forward it to the PMU emulation code.
Signed-off-by Avi Kivity <[email protected]>Signed-off-by Gleb Natapov <[email protected]>Signed-off-by Avi Kivity <[email protected]>
Quoted 5 lines
Quoted 3 lines
It looks like requiring the feature based on cpu fails when the host (outer kvm module) code does not support it. So maybe that should be optional instead of required?
According to Intel SDM there was never CPU that didn't support RDPMC exiting. Looks like unfortunate nested VMX bug.
Moreover, that same commit fixes the bug in nested vmx. So if you update your host kernel to the same version as your L1 guest (or, at your option, any later version) it should work.
We could backport that part of the patch, though as nested vmx is still experimential, I don't think it's worth it.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 24 lines · Avi Kivity
Quoted 17 lines · Gleb Natapov
Quoted 16 lines · Stefan Bader
I have been looking at a report[1] about the
kvm_intelmodule failing to load on linux v3.3 and newer guests when running on a v3.2 host. Bisection turned up the following patch:commit
fee84b079d5ddee2247b5c1f53162c330c622902Author: Avi Kivity <[email protected]> Date: Thu Nov 10 14:57:25 2011 +0200KVM: VMX: Intercept RDPMC
Intercept RDPMC and forward it to the PMU emulation code.
Signed-off-by Avi Kivity <[email protected]>Signed-off-by Gleb Natapov <[email protected]>Signed-off-by Avi Kivity <[email protected]>Quoted 5 lines
Quoted 3 lines
It looks like requiring the feature based on cpu fails when the host (outer kvm module) code does not support it. So maybe that should be optional instead of required?
According to Intel SDM there was never CPU that didn't support RDPMC exiting. Looks like unfortunate nested VMX bug.
Quoted 7 lines
Moreover, that same commit fixes the bug in nested vmx. So if you update your host kernel to the same version as your L1 guest (or, at your option, any later version) it should work.
We could backport that part of the patch, though as nested vmx is still experimential, I don't think it's worth it.
Though this is probably what people will (or will have to) do. The host is not always under your control. Even with it being experimental, it was working (at least the module was loadable) before and is now broken on Intel hosts. But ok, so the recommendation is to rather backport support to the host kernel than to try handling this differently in the guest module, right?
Quoted 7 lines · Stefan Bader
Quoted 7 lines
Quoted 2 lines
According to Intel SDM there was never CPU that didn't support RDPMC exiting. Looks like unfortunate nested VMX bug.
Moreover, that same commit fixes the bug in nested vmx. So if you update your host kernel to the same version as your L1 guest (or, at your option, any later version) it should work.
Quoted 8 lines
Quoted 3 lines
We could backport that part of the patch, though as nested vmx is still experimential, I don't think it's worth it.
Though this is probably what people will (or will have to) do. The host is not always under your control. Even with it being experimental, it was working (at least the module was loadable) before and is now broken on Intel hosts. But ok, so the recommendation is to rather backport support to the host kernel than to try handling this differently in the guest module, right?
Right - it's not just kvm-as-a-guest that will trip on this. But there's no point in everyone backporting it on their own. If you're doing the backport, please post it here and we'll forward it to the stable branch.
Signature · 1 line
error compiling committee.c: too many arguments to function
On Wed, Aug 01, 2012, Avi Kivity wrote about "Re: Nested kvm_intel broken on pre 3.3 hosts":
Quoted 4 lines
Right - it's not just kvm-as-a-guest that will trip on this. But there's no point in everyone backporting it on their own. If you're doing the backport, please post it here and we'll forward it to the stable branch.
If I understand correctly, the failure occurs because new versions of KVM refuse to work if the processor doesn't support CPU_BASED_RDPMC_EXITING - which older versions of nested VMX didn't say that they did.
But must the KVM guest refuse to work if this feature isn't supported? I.e., why not move in setup_vmcs_config() the CPU_BASED_RDPMC_EXITING from "min" to "opt"? Isn't losing the PMU feature a lesser evil than not working at all? In any case, perhaps the original reporter can use this as a workaround, at least, because it requires modifying the (L1) guest, not the host.
Signature · 4 lines
Nadav Har'El | Wednesday, Aug 1 2012, 13 Av 5772 [email protected] |----------------------------------------- Phone +972-523-790466, ICQ 13349191 |May you live as long as you want - and http://nadav.harel.org.il |never want as long as you live.
Quoted 10 lines · Nadav Har'El
On Wed, Aug 01, 2012, Avi Kivity wrote about "Re: Nested
kvm_intelbroken on pre 3.3 hosts":Quoted 4 lines
Right - it's not just kvm-as-a-guest that will trip on this. But there's no point in everyone backporting it on their own. If you're doing the backport, please post it here and we'll forward it to the stable branch.
If I understand correctly, the failure occurs because new versions of KVM refuse to work if the processor doesn't support
CPU_BASED_RDPMC_EXITING- which older versions of nested VMX didn't say that they did.
Quoted 8 lines
But must the KVM guest refuse to work if this feature isn't supported? I.e., why not move in
setup_vmcs_config()theCPU_BASED_RDPMC_EXITINGfrom "min" to "opt"? Isn't losing the PMU feature a lesser evil than not working at all? In any case, perhaps the original reporter can use this as a workaround, at least, because it requires modifying the (L1) guest, not the host.
Since L2 or L1 have to be fixed anyway for setup to work it is better to fix L1 to work according to a spec than fixing L2 to workaround L1 bug.
--
Gleb.
Quoted 9 lines · Nadav Har'El
On Wed, Aug 01, 2012, Avi Kivity wrote about "Re: Nested
kvm_intelbroken on pre 3.3 hosts":Quoted 4 lines
Right - it's not just kvm-as-a-guest that will trip on this. But there's no point in everyone backporting it on their own. If you're doing the backport, please post it here and we'll forward it to the stable branch.
If I understand correctly, the failure occurs because new versions of KVM refuse to work if the processor doesn't support
CPU_BASED_RDPMC_EXITING- which older versions of nested VMX didn't say that they did.
Right.
Quoted 6 lines
But must the KVM guest refuse to work if this feature isn't supported? I.e., why not move in
setup_vmcs_config()theCPU_BASED_RDPMC_EXITINGfrom "min" to "opt"? Isn't losing the PMU feature a lesser evil than not working at all? In any case, perhaps the original reporter can use this as a workaround, at least, because it requires modifying the (L1) guest, not the host.
Real processors that don't support RDPMC exiting don't exist (and logically cannot exist unless they also drop support for the RDPMC instruction). Given it's a clear host bug I'd rather fix it than making the guest more complicated, even by a small amount.
The hypervisor needs to be updated on a regular schedule anyway, so there's no risk of locking users out for more than a short while.
Signature · 1 line
error compiling committee.c: too many arguments to function
I started to pick #7 (#6 is in to have things in-sync between SVM and VMX). Most other patches then were needed as dependencies. The only difference here is #2 which I found being applied together with #1 (which is a dependency). Since #2 is rather change to add support than to fix a bug it was applied only to our 3.2 tree. But maybe this would be the time to get it into the upstream 3.2 stable as well. I would leave the decision to you, just that the testing I have done, was basically with that addition. The test was just an installation of a nested guest (so not necessarily testing RDPMC, only the fact that with that applied to 3.2, a 3.5 is able to load the kvm-intel module).
What I also did not do is to look much into the other direction, like what patches may be important as that feature now would be supported in 3.2. I think people on this list are likely in a much better position to decide that.
So here the series I used to compile and test on top of 3.2:
0001-KVM-Move-cpuid-code-to-new-file.patch 0002-KVM-expose-latest-Intel-cpu-new-features-BMI1-BMI2-F.patch 0003-KVM-Expose-kvm_lapic_local_deliver.patch 0004-KVM-Expose-a-version-2-architectural-PMU-to-a-guests.patch 0005-KVM-Add-generic-RDPMC-support.patch 0006-KVM-SVM-Intercept-RDPMC.patch 0007-KVM-VMX-Intercept-RDPMC.patch
PATCH 1/7 KVM: Move cpuid code to new file
From: Avi Kivity <[email protected]>
commit 00b27a3efb116062ca5a276ad5cb01ea1b80b5f6 upstream
The cpuid code has grown; put it into a separate file.
--- arch/x86/kvm/Makefile | 2 +- arch/x86/kvm/cpuid.c | 625 ++++++++++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/cpuid.h | 46 ++++ arch/x86/kvm/lapic.c | 1 + arch/x86/kvm/vmx.c | 1 + arch/x86/kvm/x86.c | 634 +------------------------------------------------ arch/x86/kvm/x86.h | 5 +- 7 files changed, 679 insertions(+), 635 deletions(-) create mode 100644 arch/x86/kvm/cpuid.c create mode 100644 arch/x86/kvm/cpuid.h
arch/x86/kvm/Makefile +1 -1
@@ -12,7 +12,7 @@ kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o) kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o) kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ - i8254.o timer.o + i8254.o timer.o cpuid.o kvm-intel-y += vmx.o kvm-amd-y += svm.o
arch/x86/kvm/cpuid.c new file +625 -0
625 lines not on this page · raw message
arch/x86/kvm/cpuid.h new file +46 -0
46 lines not on this page · raw message
arch/x86/kvm/lapic.c +1 -0
@@ -38,6 +38,7 @@#include "irq.h" #include "trace.h" #include "x86.h" +#include "cpuid.h" #ifndef CONFIG_X86_64 #define mod_64 (x, y) ((x) - (y) * div64_u64(x, y))
arch/x86/kvm/vmx.c +1 -0
@@ -18,6 +18,7 @@#include "irq.h" #include "mmu.h" +#include "cpuid.h" #include <linux/kvm_host.h> #include <linux/module.h>
arch/x86/kvm/x86.c +3 -631
676 lines not on this page · raw message
arch/x86/kvm/x86.h +2 -3
@@ -33,9 +33,6 @@ static inline bool kvm_exception_is_soft(unsigned int nr)return (nr ==BP_VECTOR ) || (nr ==OF_VECTOR ); } -struct kvm_cpuid_entry2 *kvm_find_cpuid_entry (struct kvm_vcpu *vcpu, -u32 function,u32 index); -static inline bool is_protmode (struct kvm_vcpu *vcpu) {return kvm_read_cr0_bits (vcpu,X86_CR0_PE );
@@ -125,4 +122,6 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, gva_t addr, void *val, unsigned int bytes, struct x86_exception *exception); +extern u64 host_xcr0; +#endif
Signature · 1 line
1.7.9.5
PATCH 2/7 KVM: expose latest Intel cpu new features (BMI1/BMI2/FMA/AVX2) to guest
In reply to Stefan BaderFrom: "Liu, Jinsong" <[email protected]>
commit fb215366b3c7320ac25dca766a0152df16534932 upstream
Intel latest cpu add 6 new features, refer http://software.intel.com/file/36945
The new feature cpuid listed as below:
1. FMA CPUID.EAX=01H:ECX.FMA[bit 12]
2. MOVBE CPUID.EAX=01H:ECX.MOVBE[bit 22]
3. BMI1 CPUID.EAX=07H,ECX=0H:EBX.BMI1[bit 3]
4. AVX2 CPUID.EAX=07H,ECX=0H:EBX.AVX2[bit 5]
5. BMI2 CPUID.EAX=07H,ECX=0H:EBX.BMI2[bit 8]
6. LZCNT CPUID.EAX=80000001H:ECX.LZCNT[bit 5]
This patch expose these features to guest.
Among them, FMA/MOVBE/LZCNT has already been defined, MOVBE/LZCNT has already been exposed.
This patch defines BMI1/AVX2/BMI2, and exposes FMA/BMI1/AVX2/BMI2 to guest.
--- arch/x86/include/asm/cpufeature.h | 3 +++ arch/x86/kvm/cpuid.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-)
arch/x86/include/asm/cpufeature.h +3 -0
@@ -197,7 +197,10 @@/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ #define X86_FEATURE_FSGSBASE (9*32+ 0)/* {RD/WR}{FS/GS}BASE instructions*/ +#define X86_FEATURE_BMI1 (9*32+ 3)/* 1st group bit manipulation extensions */ +#define X86_FEATURE_AVX2 (9*32+ 5)/* AVX2 instructions */ #define X86_FEATURE_SMEP (9*32+ 7)/* Supervisor Mode Execution Protection */ +#define X86_FEATURE_BMI2 (9*32+ 8)/* 2nd group bit manipulation extensions */ #define X86_FEATURE_ERMS (9*32+ 9)/* Enhanced REP MOVSB/STOSB */ #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
arch/x86/kvm/cpuid.c +2 -2
@@ -222,7 +222,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,F (XMM3 ) |F (PCLMULQDQ ) |0 /* DTES64, MONITOR */ |0 /* DS-CPL, VMX, SMX, EST */ |0 /* TM2 */ |F (SSSE3 ) |0 /* CNXT-ID */ |0 /* Reserved */ | -0 /* Reserved */ |F (CX16 ) |0 /* xTPR Update, PDCM */ | +F (FMA ) |F (CX16 ) |0 /* xTPR Update, PDCM */ |0 /* Reserved, DCA */ |F (XMM4_1 ) |F (XMM4_2 ) |F (X2APIC ) |F (MOVBE ) |F (POPCNT ) | 0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) |
@@ -242,7 +242,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,/* cpuid 7.0.ebx */ const u32 kvm_supported_word9_x86_features = -F (SMEP ) |F (FSGSBASE ) |F (ERMS ); +F (FSGSBASE ) |F (BMI1 ) |F (AVX2 ) |F (SMEP ) |F (BMI2 ) |F (ERMS );/* all calls to cpuid_count() should be made on the same cpu */ get_cpu ();
Signature · 1 line
1.7.9.5
PATCH 3/7 KVM: Expose kvm_lapic_local_deliver()
In reply to Stefan BaderFrom: Avi Kivity <[email protected]>
commit 893420822192f717af6fde927c9e78c9b82f8327 upstream
Needed to deliver performance monitoring interrupts.
--- arch/x86/kvm/lapic.c | 2 +- arch/x86/kvm/lapic.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
arch/x86/kvm/lapic.c +1 -1
@@ -1121,7 +1121,7 @@ int apic_has_pending_timer(struct kvm_vcpu *vcpu)return 0 ; } -static int kvm_apic_local_deliver (struct kvm_lapic *apic,int lvt_type) +int kvm_apic_local_deliver (struct kvm_lapic *apic,int lvt_type) {u32 reg =apic_get_reg (apic, lvt_type);int vector, mode, trig_mode;
arch/x86/kvm/lapic.h +1 -0
@@ -34,6 +34,7 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu);int kvm_apic_match_physical_addr (struct kvm_lapic *apic,u16 dest);int kvm_apic_match_logical_addr (struct kvm_lapic *apic,u8 mda);int kvm_apic_set_irq (struct kvm_vcpu *vcpu,struct kvm_lapic_irq *irq); +int kvm_apic_local_deliver (struct kvm_lapic *apic,int lvt_type);u64 kvm_get_apic_base (struct kvm_vcpu *vcpu);void kvm_set_apic_base (struct kvm_vcpu *vcpu,u64 data);
Signature · 1 line
1.7.9.5
PATCH 4/7 KVM: Expose a version 2 architectural PMU to a guests
In reply to Stefan BaderFrom: Gleb Natapov <[email protected]>
commit f5132b01386b5a67f1ff673bb2b96a507a3f7e41 upstream
Use perf_events to emulate an architectural PMU, version 2.
Based on PMU version 1 emulation by Avi Kivity.
[avi: adjust for cpuid.c]
[jan: fix anonymous field initialization for older gcc]
--- arch/x86/include/asm/kvm_host.h | 48 ++++ arch/x86/kvm/Kconfig | 1 + arch/x86/kvm/Makefile | 2 +- arch/x86/kvm/cpuid.c | 2 + arch/x86/kvm/pmu.c | 533 +++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.c | 22 +- include/linux/kvm_host.h | 2 + 7 files changed, 600 insertions(+), 10 deletions(-) create mode 100644 arch/x86/kvm/pmu.c
arch/x86/include/asm/kvm_host.h +48 -0
@@ -16,10 +16,12 @@#include <linux/mmu_notifier.h> #include <linux/tracepoint.h> #include <linux/cpumask.h> +#include <linux/irq_work.h> #include <linux/kvm.h> #include <linux/kvm_para.h> #include <linux/kvm_types.h> +#include <linux/perf_event.h> #include <asm/pvclock-abi.h> #include <asm/desc.h>
@@ -294,6 +296,37 @@ struct kvm_mmu {u64 pdptrs[4 ];/* pae */ }; +enum pmc_type { +KVM_PMC_GP =0 , +KVM_PMC_FIXED , +}; + +struct kvm_pmc { +enum pmc_type type; +u8 idx; +u64 counter; +u64 eventsel; +struct perf_event *perf_event; +struct kvm_vcpu *vcpu; +}; + +struct kvm_pmu { +unsigned nr_arch_gp_counters; +unsigned nr_arch_fixed_counters; +unsigned available_event_types; +u64 fixed_ctr_ctrl; +u64 global_ctrl; +u64 global_status; +u64 global_ovf_ctrl; +u64 counter_bitmask[2 ]; +u64 global_ctrl_mask; +u8 version; +struct kvm_pmc gp_counters[X86_PMC_MAX_GENERIC ]; +struct kvm_pmc fixed_counters[X86_PMC_MAX_FIXED ]; +struct irq_work irq_work; +u64 reprogram_pmi; +}; +struct kvm_vcpu_arch {/* * rip and regs accesses must go through
@@ -436,6 +469,8 @@ struct kvm_vcpu_arch {unsigned access;gfn_t mmio_gfn; +struct kvm_pmu pmu; +/* used for guest single stepping over the given code position */ unsigned long singlestep_rip;
@@ -894,4 +929,17 @@ extern bool kvm_find_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn);void kvm_complete_insn_gp (struct kvm_vcpu *vcpu,int err); +int kvm_is_in_guest (void ); + +void kvm_pmu_init (struct kvm_vcpu *vcpu); +void kvm_pmu_destroy (struct kvm_vcpu *vcpu); +void kvm_pmu_reset (struct kvm_vcpu *vcpu); +void kvm_pmu_cpuid_update (struct kvm_vcpu *vcpu); +bool kvm_pmu_msr (struct kvm_vcpu *vcpu,u32 msr); +int kvm_pmu_get_msr (struct kvm_vcpu *vcpu,u32 msr,u64 *data); +int kvm_pmu_set_msr (struct kvm_vcpu *vcpu,u32 msr,u64 data); +int kvm_pmu_read_pmc (struct kvm_vcpu *vcpu,unsigned pmc,u64 *data); +void kvm_handle_pmu_event (struct kvm_vcpu *vcpu); +void kvm_deliver_pmi (struct kvm_vcpu *vcpu); +#endif /* _ASM_X86_KVM_HOST_H */
arch/x86/kvm/Kconfig +1 -0
@@ -35,6 +35,7 @@ config KVM select KVM_MMIO select TASKSTATS select TASK_DELAY_ACCT + select PERF_EVENTS ---help--- Support hosting fully virtualized guest machines using hardware virtualization extensions. You will need a fairly recent
arch/x86/kvm/Makefile +1 -1
@@ -12,7 +12,7 @@ kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o) kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o) kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ - i8254.o timer.o cpuid.o + i8254.o timer.o cpuid.o pmu.o kvm-intel-y += vmx.o kvm-amd-y += svm.o
arch/x86/kvm/cpuid.c +2 -0
@@ -43,6 +43,8 @@ void kvm_update_cpuid(struct kvm_vcpu *vcpu)else apic->lapic_timer.timer_mode_mask =1 <<17 ; } + +kvm_pmu_cpuid_update (vcpu); }static int is_efer_nx (void )
arch/x86/kvm/pmu.c new file +533 -0
533 lines not on this page · raw message
arch/x86/kvm/x86.c +13 -9
@@ -1603,8 +1603,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)* which we perfectly emulate ;-). Any other value should be at least * reported, some guests depend on them. */ -case MSR_P6_EVNTSEL0 : -case MSR_P6_EVNTSEL1 :case MSR_K7_EVNTSEL0 :case MSR_K7_EVNTSEL1 :case MSR_K7_EVNTSEL2 :
@@ -1616,8 +1614,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)/* at least RHEL 4 unconditionally writes to the perfctr registers, * so we ignore writes to make it happy. */ -case MSR_P6_PERFCTR0 : -case MSR_P6_PERFCTR1 :case MSR_K7_PERFCTR0 :case MSR_K7_PERFCTR1 :case MSR_K7_PERFCTR2 :
@@ -1654,6 +1650,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)default :if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))return xen_hvm_config (vcpu, data); +if (kvm_pmu_msr (vcpu, msr)) +return kvm_pmu_set_msr (vcpu, msr, data);if (!ignore_msrs) {pr_unimpl (vcpu,"unhandled wrmsr: 0x%x data %llx\n" , msr, data);
@@ -1816,10 +1814,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)case MSR_K8_SYSCFG :case MSR_K7_HWCR :case MSR_VM_HSAVE_PA : -case MSR_P6_PERFCTR0 : -case MSR_P6_PERFCTR1 : -case MSR_P6_EVNTSEL0 : -case MSR_P6_EVNTSEL1 :case MSR_K7_EVNTSEL0 :case MSR_K7_PERFCTR0 :case MSR_K8_INT_PENDING_MSG :
@@ -1930,6 +1924,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) data =0xbe702111 ;break ;default : +if (kvm_pmu_msr (vcpu, msr)) +return kvm_pmu_get_msr (vcpu, msr, pdata);if (!ignore_msrs) {pr_unimpl (vcpu,"unhandled rdmsr: 0x%x\n" , msr);return 1 ;
@@ -4612,7 +4608,7 @@ static void kvm_timer_init(void) static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu); -static int kvm_is_in_guest (void ) +int kvm_is_in_guest (void ) {return percpu_read (current_vcpu) !=NULL ; }
@@ -5085,6 +5081,10 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)record_steal_time (vcpu);if (kvm_check_request (KVM_REQ_NMI , vcpu))process_nmi (vcpu); +if (kvm_check_request (KVM_REQ_PMU , vcpu)) +kvm_handle_pmu_event (vcpu); +if (kvm_check_request (KVM_REQ_PMI , vcpu)) +kvm_deliver_pmi (vcpu); }
@@ -5823,6 +5823,8 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)kvm_async_pf_hash_reset (vcpu); vcpu->arch.apf.halted = false; +kvm_pmu_reset (vcpu); +return kvm_x86_ops->vcpu_reset (vcpu); }
@@ -5916,6 +5918,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) goto fail_free_mce_banks;kvm_async_pf_hash_reset (vcpu); +kvm_pmu_init (vcpu);return 0 ; fail_free_mce_banks:
@@ -5934,6 +5937,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {int idx; +kvm_pmu_destroy (vcpu);kfree (vcpu->arch.mce_banks);kvm_free_lapic (vcpu); idx =srcu_read_lock (&vcpu->kvm->srcu);
include/linux/kvm_host.h +2 -0
@@ -50,6 +50,8 @@#define KVM_REQ_APF_HALT 12#define KVM_REQ_STEAL_UPDATE 13#define KVM_REQ_NMI 14 +#define KVM_REQ_PMU 16 +#define KVM_REQ_PMI 17#define KVM_USERSPACE_IRQ_SOURCE_ID 0
Signature · 1 line
1.7.9.5
PATCH 5/7 KVM: Add generic RDPMC support
In reply to Stefan BaderFrom: Avi Kivity <[email protected]>
commit 022cd0e84020eec8b589bc119699c935c7b29584 upstream
Add a helper function that emulates the RDPMC instruction operation.
--- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/x86.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+)
arch/x86/include/asm/kvm_host.h +1 -0
@@ -769,6 +769,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);unsigned long kvm_get_rflags (struct kvm_vcpu *vcpu);void kvm_set_rflags (struct kvm_vcpu *vcpu,unsigned long rflags); +bool kvm_rdpmc (struct kvm_vcpu *vcpu);void kvm_queue_exception (struct kvm_vcpu *vcpu,unsigned nr);void kvm_queue_exception_e (struct kvm_vcpu *vcpu,unsigned nr,u32 error_code);
arch/x86/kvm/x86.c +15 -0
@@ -760,6 +760,21 @@ int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) }EXPORT_SYMBOL_GPL (kvm_get_dr); +bool kvm_rdpmc (struct kvm_vcpu *vcpu) +{ +u32 ecx =kvm_register_read (vcpu,VCPU_REGS_RCX ); +u64 data; +int err; + + err =kvm_pmu_read_pmc (vcpu, ecx, &data); +if (err) +return err; +kvm_register_write (vcpu,VCPU_REGS_RAX , (u32 )data); +kvm_register_write (vcpu,VCPU_REGS_RDX , data >>32 ); +return err; +} +EXPORT_SYMBOL_GPL (kvm_rdpmc); +/* * List of msr numbers which we expose to userspace through KVM_GET_MSRS * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST.
Signature · 1 line
1.7.9.5
PATCH 6/7 KVM: SVM: Intercept RDPMC
In reply to Stefan BaderFrom: Avi Kivity <[email protected]>
commit 332b56e4841ef62db4dbf1b4b92195575e1c7338 upstream
Intercept RDPMC and forward it to the PMU emulation code.
--- arch/x86/kvm/svm.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
arch/x86/kvm/svm.c +15 -0
@@ -1019,6 +1019,7 @@ static void init_vmcb(struct vcpu_svm *svm)set_intercept (svm,INTERCEPT_NMI );set_intercept (svm,INTERCEPT_SMI );set_intercept (svm,INTERCEPT_SELECTIVE_CR0 ); +set_intercept (svm,INTERCEPT_RDPMC );set_intercept (svm,INTERCEPT_CPUID );set_intercept (svm,INTERCEPT_INVD );set_intercept (svm,INTERCEPT_HLT );
@@ -2775,6 +2776,19 @@ static int emulate_on_interception(struct vcpu_svm *svm)return emulate_instruction (&svm->vcpu,0 ) ==EMULATE_DONE ; } +static int rdpmc_interception (struct vcpu_svm *svm) +{ +int err; + +if (!static_cpu_has (X86_FEATURE_NRIPS )) +return emulate_on_interception (svm); + + err =kvm_rdpmc (&svm->vcpu); +kvm_complete_insn_gp (&svm->vcpu, err); + +return 1 ; +} +bool check_selective_cr0_intercepted (struct vcpu_svm *svm,unsigned long val) {unsigned long cr0 = svm->vcpu.arch.cr0;
@@ -3195,6 +3209,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_SMI] = nop_on_interception, [SVM_EXIT_INIT] = nop_on_interception, [SVM_EXIT_VINTR] = interrupt_window_interception, + [SVM_EXIT_RDPMC] = rdpmc_interception, [SVM_EXIT_CPUID] = cpuid_interception, [SVM_EXIT_IRET] = iret_interception, [SVM_EXIT_INVD] = emulate_on_interception,
Signature · 1 line
1.7.9.5
PATCH 7/7 KVM: VMX: Intercept RDPMC
In reply to Stefan BaderFrom: Avi Kivity <[email protected]>
commit fee84b079d5ddee2247b5c1f53162c330c622902 upstream
Intercept RDPMC and forward it to the PMU emulation code.
(cherry-picked from fee84b079d5ddee2247b5c1f53162c330c622902 upstream)
--- arch/x86/kvm/vmx.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx.c +14 -1
@@ -1957,6 +1957,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)#endif CPU_BASED_MOV_DR_EXITING |CPU_BASED_UNCOND_IO_EXITING |CPU_BASED_USE_IO_BITMAPS |CPU_BASED_MONITOR_EXITING | +CPU_BASED_RDPMC_EXITING |CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ;/* * We can allow some features even when not supported by the
@@ -2415,7 +2416,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)CPU_BASED_USE_TSC_OFFSETING |CPU_BASED_MWAIT_EXITING |CPU_BASED_MONITOR_EXITING | -CPU_BASED_INVLPG_EXITING ; +CPU_BASED_INVLPG_EXITING | +CPU_BASED_RDPMC_EXITING ;if (yield_on_hlt) min |=CPU_BASED_HLT_EXITING ;
@@ -4614,6 +4616,16 @@ static int handle_invlpg(struct kvm_vcpu *vcpu)return 1 ; } +static int handle_rdpmc (struct kvm_vcpu *vcpu) +{ +int err; + + err =kvm_rdpmc (vcpu); +kvm_complete_insn_gp (vcpu, err); + +return 1 ; +} +static int handle_wbinvd (struct kvm_vcpu *vcpu) {skip_emulated_instruction (vcpu);
@@ -5564,6 +5576,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { [EXIT_REASON_HLT] = handle_halt, [EXIT_REASON_INVD] = handle_invd, [EXIT_REASON_INVLPG] = handle_invlpg, + [EXIT_REASON_RDPMC] = handle_rdpmc, [EXIT_REASON_VMCALL] = handle_vmcall, [EXIT_REASON_VMCLEAR] = handle_vmclear, [EXIT_REASON_VMLAUNCH] = handle_vmlaunch,
Signature · 1 line
1.7.9.5
Quoted 19 lines · Stefan Bader
I started to pick #7 (#6 is in to have things in-sync between SVM and VMX). Most other patches then were needed as dependencies. The only difference here is #2 which I found being applied together with #1 (which is a dependency). Since #2 is rather change to add support than to fix a bug it was applied only to our 3.2 tree. But maybe this would be the time to get it into the upstream 3.2 stable as well. I would leave the decision to you, just that the testing I have done, was basically with that addition. The test was just an installation of a nested guest (so not necessarily testing RDPMC, only the fact that with that applied to 3.2, a 3.5 is able to load the kvm-intel module).
What I also did not do is to look much into the other direction, like what patches may be important as that feature now would be supported in 3.2. I think people on this list are likely in a much better position to decide that.
So here the series I used to compile and test on top of 3.2:
Quoted 7 lines
0001-KVM-Move-cpuid-code-to-new-file.patch 0002-KVM-expose-latest-Intel-cpu-new-features-BMI1-BMI2-F.patch 0003-KVM-Expose-kvm_lapic_local_deliver.patch 0004-KVM-Expose-a-version-2-architectural-PMU-to-a-guests.patch 0005-KVM-Add-generic-RDPMC-support.patch 0006-KVM-SVM-Intercept-RDPMC.patch 0007-KVM-VMX-Intercept-RDPMC.patch
No, you're backporting the entire feature. All we need is to expose RDPMC intercept to the guest.
It should be sufficient to backport the bits in nested_vmx_setup_ctls_msrs() and nested_vmx_exit_handled().
Signature · 1 line
error compiling committee.c: too many arguments to function
(unknown)
Subject: Re: Nested kvm_intel broken on pre 3.3 hosts
Quoted 2 lines
No, you're backporting the entire feature. All we need is to expose RDPMC intercept to the guest.
Oh well, I thought that was the thing you asked for...
Quoted 2 lines
It should be sufficient to backport the bits in
nested_vmx_setup_ctls_msrs()andnested_vmx_exit_handled().
Ok, how about that? It is probably wrong again, but at least it allows to load the kvm-intel module from within a nested guest and not having the feature pretend to fail seems the closest thing to do...
---
Quoted 1 line
From
0aeb99348363b7aeb2b0bd92428cb212159fa468Mon Sep 17 00:00:00 2001
From: Stefan Bader <[email protected]>
Date: Thu, 10 Nov 2011 14:57:25 +0200
Subject: [PATCH] KVM: VMX: Fake intercept RDPMC
Based on commit fee84b079d5ddee2247b5c1f53162c330c622902 upstream.
Intercept RDPMC and forward it to the PMU emulation code.
But drop the requirement for the feature being present and instead of forwarding, cause a GP as if the call had failed.
--- arch/x86/kvm/vmx.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/x86/kvm/vmx.c +10 -0
@@ -1956,6 +1956,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)#endif CPU_BASED_MOV_DR_EXITING |CPU_BASED_UNCOND_IO_EXITING |CPU_BASED_USE_IO_BITMAPS |CPU_BASED_MONITOR_EXITING | +CPU_BASED_RDPMC_EXITING |CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ;/* * We can allow some features even when not supported by the
@@ -4613,6 +4614,14 @@ static int handle_invlpg(struct kvm_vcpu *vcpu)return 1 ; } +static int handle_rdpmc (struct kvm_vcpu *vcpu) +{ +/* Instead of implementing the feature, cause a GP */ +kvm_complete_insn_gp (vcpu,1 ); + +return 1 ; +} +static int handle_wbinvd (struct kvm_vcpu *vcpu) {skip_emulated_instruction (vcpu);
@@ -5563,6 +5572,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { [EXIT_REASON_HLT] = handle_halt, [EXIT_REASON_INVD] = handle_invd, [EXIT_REASON_INVLPG] = handle_invlpg, + [EXIT_REASON_RDPMC] = handle_rdpmc, [EXIT_REASON_VMCALL] = handle_vmcall, [EXIT_REASON_VMCLEAR] = handle_vmclear, [EXIT_REASON_VMLAUNCH] = handle_vmlaunch,
Signature · 1 line
1.7.9.5
Quoted 2 lines
No, you're backporting the entire feature. All we need is to expose RDPMC intercept to the guest.
Oh well, I thought that was the thing you asked for...
Quoted 2 lines
It should be sufficient to backport the bits in
nested_vmx_setup_ctls_msrs()andnested_vmx_exit_handled().
Ok, how about that? It is probably wrong again, but at least it allows to load the kvm-intel module from within a nested guest and not having the feature pretend to fail seems the closest thing to do...
---
Quoted 1 line
From
0aeb99348363b7aeb2b0bd92428cb212159fa468Mon Sep 17 00:00:00 2001
From: Stefan Bader <[email protected]>
Date: Thu, 10 Nov 2011 14:57:25 +0200
Subject: [PATCH] KVM: VMX: Fake intercept RDPMC
Based on commit fee84b079d5ddee2247b5c1f53162c330c622902 upstream.
Intercept RDPMC and forward it to the PMU emulation code.
But drop the requirement for the feature being present and instead of forwarding, cause a GP as if the call had failed.
--- arch/x86/kvm/vmx.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/x86/kvm/vmx.c +10 -0
@@ -1956,6 +1956,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)#endif CPU_BASED_MOV_DR_EXITING |CPU_BASED_UNCOND_IO_EXITING |CPU_BASED_USE_IO_BITMAPS |CPU_BASED_MONITOR_EXITING | +CPU_BASED_RDPMC_EXITING |CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ;/* * We can allow some features even when not supported by the
@@ -4613,6 +4614,14 @@ static int handle_invlpg(struct kvm_vcpu *vcpu)return 1 ; } +static int handle_rdpmc (struct kvm_vcpu *vcpu) +{ +/* Instead of implementing the feature, cause a GP */ +kvm_complete_insn_gp (vcpu,1 ); + +return 1 ; +} +static int handle_wbinvd (struct kvm_vcpu *vcpu) {skip_emulated_instruction (vcpu);
@@ -5563,6 +5572,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { [EXIT_REASON_HLT] = handle_halt, [EXIT_REASON_INVD] = handle_invd, [EXIT_REASON_INVLPG] = handle_invlpg, + [EXIT_REASON_RDPMC] = handle_rdpmc, [EXIT_REASON_VMCALL] = handle_vmcall, [EXIT_REASON_VMCLEAR] = handle_vmclear, [EXIT_REASON_VMLAUNCH] = handle_vmlaunch,
Signature · 1 line
1.7.9.5
Quoted 4 lines · Stefan Bader
Quoted 2 lines
No, you're backporting the entire feature. All we need is to expose RDPMC intercept to the guest.
Oh well, I thought that was the thing you asked for...
Sorry for being unclear.
Quoted 42 lines
Quoted 3 lines
It should be sufficient to backport the bits in
nested_vmx_setup_ctls_msrs()andnested_vmx_exit_handled().Ok, how about that? It is probably wrong again, but at least it allows to load the kvm-intel module from within a nested guest and not having the feature pretend to fail seems the closest thing to do...
---
From
0aeb99348363b7aeb2b0bd92428cb212159fa468Mon Sep 17 00:00:00 2001
From: Stefan Bader <[email protected]>
Date: Thu, 10 Nov 2011 14:57:25 +0200
Subject: [PATCH] KVM: VMX: Fake intercept RDPMCBased on commit
fee84b079d5ddee2247b5c1f53162c330c622902upstream.Intercept RDPMC and forward it to the PMU emulation code.
But drop the requirement for the feature being present and instead of forwarding, cause a GP as if the call had failed.
Signed-off-by Stefan Bader <[email protected]>--- arch/x86/kvm/vmx.c | 10 ++++++++++ 1 file changed, 10 insertions(+)arch/x86/kvm/vmx.c +1
-0@@ -1956,6 +1956,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)#endif CPU_BASED_MOV_DR_EXITING |CPU_BASED_UNCOND_IO_EXITING |CPU_BASED_USE_IO_BITMAPS |CPU_BASED_MONITOR_EXITING | +CPU_BASED_RDPMC_EXITING |CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ;/* * We can allow some features even when not supported by the
arch/x86/kvm/vmx.c static int handle_invlpg(struct kvm_vcpu *vcpu) · line 4623
Quoted 10 lines
arch/x86/kvm/vmx.c +7
-0@@ -4613,6 +4614,14 @@ static int handle_invlpg(struct kvm_vcpu *vcpu)return 1 ; } +static int handle_rdpmc (struct kvm_vcpu *vcpu) +{ +/* Instead of implementing the feature, cause a GP */ +kvm_complete_insn_gp (vcpu,1 ); + +return 1 ; +}
In fact this should never be called, since we never request RDPMC exiting for L1.
arch/x86/kvm/vmx.c static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { · line 5578
Quoted 13 lines
arch/x86/kvm/vmx.c +2
-0+static int handle_wbinvd (struct kvm_vcpu *vcpu) {skip_emulated_instruction (vcpu);@@ -5563,6 +5572,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { [EXIT_REASON_HLT] = handle_halt, [EXIT_REASON_INVD] = handle_invd, [EXIT_REASON_INVLPG] = handle_invlpg, + [EXIT_REASON_RDPMC] = handle_rdpmc, [EXIT_REASON_VMCALL] = handle_vmcall, [EXIT_REASON_VMCLEAR] = handle_vmclear, [EXIT_REASON_VMLAUNCH] = handle_vmlaunch,
Provided you backport the bit in nested_vmx_exit_handled(). That takes the L2->L1 RDPMC exit and forwards it to L1.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 64 lines · Avi Kivity
Quoted 4 lines · Stefan Bader
Quoted 2 lines
No, you're backporting the entire feature. All we need is to expose RDPMC intercept to the guest.
Oh well, I thought that was the thing you asked for...
Sorry for being unclear.
Quoted 42 lines
Quoted 3 lines
It should be sufficient to backport the bits in
nested_vmx_setup_ctls_msrs()andnested_vmx_exit_handled().Ok, how about that? It is probably wrong again, but at least it allows to load the kvm-intel module from within a nested guest and not having the feature pretend to fail seems the closest thing to do...
---
From
0aeb99348363b7aeb2b0bd92428cb212159fa468Mon Sep 17 00:00:00 2001
From: Stefan Bader <[email protected]>
Date: Thu, 10 Nov 2011 14:57:25 +0200
Subject: [PATCH] KVM: VMX: Fake intercept RDPMCBased on commit
fee84b079d5ddee2247b5c1f53162c330c622902upstream.Intercept RDPMC and forward it to the PMU emulation code.
But drop the requirement for the feature being present and instead of forwarding, cause a GP as if the call had failed.
Signed-off-by Stefan Bader <[email protected]>--- arch/x86/kvm/vmx.c | 10 ++++++++++ 1 file changed, 10 insertions(+)arch/x86/kvm/vmx.c +1
-0@@ -1956,6 +1956,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)#endif CPU_BASED_MOV_DR_EXITING |CPU_BASED_UNCOND_IO_EXITING |CPU_BASED_USE_IO_BITMAPS |CPU_BASED_MONITOR_EXITING | +CPU_BASED_RDPMC_EXITING |CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ;/* * We can allow some features even when not supported by the arch/x86/kvm/vmx.c static int handle_invlpg(struct kvm_vcpu *vcpu) · line 4623
Quoted 10 lines
arch/x86/kvm/vmx.c +7
-0@@ -4613,6 +4614,14 @@ static int handle_invlpg(struct kvm_vcpu *vcpu)return 1 ; } +static int handle_rdpmc (struct kvm_vcpu *vcpu) +{ +/* Instead of implementing the feature, cause a GP */ +kvm_complete_insn_gp (vcpu,1 ); + +return 1 ; +}In fact this should never be called, since we never request RDPMC exiting for L1.
Quoted 17 lines
arch/x86/kvm/vmx.c static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { · line 5578
Quoted 13 lines
arch/x86/kvm/vmx.c +2
-0+static int handle_wbinvd (struct kvm_vcpu *vcpu) {skip_emulated_instruction (vcpu);@@ -5563,6 +5572,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { [EXIT_REASON_HLT] = handle_halt, [EXIT_REASON_INVD] = handle_invd, [EXIT_REASON_INVLPG] = handle_invlpg, + [EXIT_REASON_RDPMC] = handle_rdpmc, [EXIT_REASON_VMCALL] = handle_vmcall, [EXIT_REASON_VMCLEAR] = handle_vmclear, [EXIT_REASON_VMLAUNCH] = handle_vmlaunch,Provided you backport the bit in
nested_vmx_exit_handled(). That takes theL2->L1RDPMC exit and forwards it to L1.
The nested_vmx_exit_handled handled function is already there (in 3.1).
commit 644d711aa0e16111d8aba6d289caebec013e26ea
Author: Nadav Har'El <[email protected]> Date: Wed May 25 23:12:35 2011 +0300
KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
Though I checked what happens if I drop anything beside the change in nested_vmx_setup_ctls_msrs. If running "perf test" (which does some RDPMC test) is sufficient to prove things are ok, then it seems to be good enough. That test fails already on the perf_event_open syscall (returning -ENOENT).
So this remaining (attached patch) change would be enough to allow the kvm_intel module get loaded from newer kernels on an 3.2 host.
From b79a5f03b4d9a1a56949d6ef38fd4879ff1b8aee Mon Sep 17 00:00:00 2001
From: Stefan Bader <[email protected]>
Date: Thu, 10 Nov 2011 14:57:25 +0200
Subject: [PATCH] KVM: VMX: Set CPU_BASED_RDPMC_EXITING for nested
Based on commit fee84b079d5ddee2247b5c1f53162c330c622902 upstream.
Intercept RDPMC and forward it to the PMU emulation code.
Newer vmx support will only allow to load the kvm_intel module if RDPMC_EXITING is supported. Even without the actual support this part of the change is required on 3.2 hosts.
--- arch/x86/kvm/vmx.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/kvm/vmx.c +1 -0
@@ -1957,6 +1957,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)#endif CPU_BASED_MOV_DR_EXITING |CPU_BASED_UNCOND_IO_EXITING |CPU_BASED_USE_IO_BITMAPS |CPU_BASED_MONITOR_EXITING | +CPU_BASED_RDPMC_EXITING |CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ;/* * We can allow some features even when not supported by the
Signature · 1 line
1.7.9.5
Quoted 90 lines · Stefan Bader
Quoted 64 lines · Avi Kivity
Quoted 4 lines · Stefan Bader
Quoted 2 lines
No, you're backporting the entire feature. All we need is to expose RDPMC intercept to the guest.
Oh well, I thought that was the thing you asked for...
Sorry for being unclear.
Quoted 42 lines
Quoted 3 lines
It should be sufficient to backport the bits in
nested_vmx_setup_ctls_msrs()andnested_vmx_exit_handled().Ok, how about that? It is probably wrong again, but at least it allows to load the kvm-intel module from within a nested guest and not having the feature pretend to fail seems the closest thing to do...
---
From
0aeb99348363b7aeb2b0bd92428cb212159fa468Mon Sep 17 00:00:00 2001
From: Stefan Bader <[email protected]>
Date: Thu, 10 Nov 2011 14:57:25 +0200
Subject: [PATCH] KVM: VMX: Fake intercept RDPMCBased on commit
fee84b079d5ddee2247b5c1f53162c330c622902upstream.Intercept RDPMC and forward it to the PMU emulation code.
But drop the requirement for the feature being present and instead of forwarding, cause a GP as if the call had failed.
Signed-off-by Stefan Bader <[email protected]>--- arch/x86/kvm/vmx.c | 10 ++++++++++ 1 file changed, 10 insertions(+)arch/x86/kvm/vmx.c +1
-0@@ -1956,6 +1956,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)#endif CPU_BASED_MOV_DR_EXITING |CPU_BASED_UNCOND_IO_EXITING |CPU_BASED_USE_IO_BITMAPS |CPU_BASED_MONITOR_EXITING | +CPU_BASED_RDPMC_EXITING |CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ;/* * We can allow some features even when not supported by the arch/x86/kvm/vmx.c static int handle_invlpg(struct kvm_vcpu *vcpu) · line 4623
Quoted 10 lines
arch/x86/kvm/vmx.c +7
-0@@ -4613,6 +4614,14 @@ static int handle_invlpg(struct kvm_vcpu *vcpu)return 1 ; } +static int handle_rdpmc (struct kvm_vcpu *vcpu) +{ +/* Instead of implementing the feature, cause a GP */ +kvm_complete_insn_gp (vcpu,1 ); + +return 1 ; +}In fact this should never be called, since we never request RDPMC exiting for L1.
Quoted 17 lines
arch/x86/kvm/vmx.c static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { · line 5578
Quoted 13 lines
arch/x86/kvm/vmx.c +2
-0+static int handle_wbinvd (struct kvm_vcpu *vcpu) {skip_emulated_instruction (vcpu);@@ -5563,6 +5572,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { [EXIT_REASON_HLT] = handle_halt, [EXIT_REASON_INVD] = handle_invd, [EXIT_REASON_INVLPG] = handle_invlpg, + [EXIT_REASON_RDPMC] = handle_rdpmc, [EXIT_REASON_VMCALL] = handle_vmcall, [EXIT_REASON_VMCLEAR] = handle_vmclear, [EXIT_REASON_VMLAUNCH] = handle_vmlaunch,Provided you backport the bit in
nested_vmx_exit_handled(). That takes theL2->L1RDPMC exit and forwards it to L1.The
nested_vmx_exit_handledhandled function is already there (in 3.1).commit
644d711aa0e16111d8aba6d289caebec013e26eaAuthor: Nadav Har'El <[email protected]> Date: Wed May 25 23:12:35 2011 +0300KVM: nVMX: Deciding if L0 or L1 should handle an L2 exit
Quoted 9 lines
Though I checked what happens if I drop anything beside the change in
nested_vmx_setup_ctls_msrs. If running "perf test" (which does some RDPMC test) is sufficient to prove things are ok, then it seems to be good enough. That test fails already on theperf_event_opensyscall (returning-ENOENT).So this remaining (attached patch) change would be enough to allow the
kvm_intelmodule get loaded from newer kernels on an 3.2 host.
Avi, was the last version of the patch (only adding the flag to the nested MSRs) good for submitting to stable from your point of view?
(inlining though this will be broken)
From b79a5f03b4d9a1a56949d6ef38fd4879ff1b8aee Mon Sep 17 00:00:00 2001
From: Stefan Bader <[email protected]>
Date: Thu, 10 Nov 2011 14:57:25 +0200
Subject: [PATCH] KVM: VMX: Set CPU_BASED_RDPMC_EXITING for nested
Based on commit fee84b079d5ddee2247b5c1f53162c330c622902 upstream.
Intercept RDPMC and forward it to the PMU emulation code.
Newer vmx support will only allow to load the kvm_intel module if RDPMC_EXITING is supported. Even without the actual support this part of the change is required on 3.2 hosts.
--- arch/x86/kvm/vmx.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/kvm/vmx.c +1 -0
@@ -1957,6 +1957,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)#endif CPU_BASED_MOV_DR_EXITING |CPU_BASED_UNCOND_IO_EXITING |CPU_BASED_USE_IO_BITMAPS |CPU_BASED_MONITOR_EXITING | +CPU_BASED_RDPMC_EXITING |CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ;/* * We can allow some features even when not supported by the
Quoted 3 lines · Stefan Bader
Avi, was the last version of the patch (only adding the flag to the nested MSRs) good for submitting to stable from your point of view?
Yes, it is correct. I forwarded it to stable, thanks.
Signature · 1 line
error compiling committee.c: too many arguments to function