KVM: nVMX: Add full nested support for "load IA32_PERF_GLOBAL_CTRL" VM-{Entry,Exit} control
v5 cover KVM: nVMX: Add full nested support for "load IA32_PERF_GLOBAL_CTRL" VM-{Entry,Exit} control
[v1] https://lore.kernel.org/r/[email protected]
[v2] https://lore.kernel.org/r/[email protected]
[v3] https://lore.kernel.org/r/[email protected]
[v4] https://lore.kernel.org/r/[email protected]
v1 => v2:
- Add Krish's Co-developed-by and Signed-off-by tags.
- Fix minor nit to kvm-unit-tests to use 'host' local variable throughout test_load_pgc()
- Teach guest_state_test_main() to check guest state from within nested VM
- Update proposed tests to use guest/host state checks, wherein the value is checked from MSR_CORE_PERF_GLOBAL_CTRL.
- Changelog line wrapping
v2 => v3:
- Remove the value unchanged condition from
kvm_is_valid_perf_global_ctrl
- Add line to changelog for patch 3/8
v3 => v4:
- Allow tests to set the guest func multiple times
- Style fixes throughout kvm-unit-tests patches, per Krish's review
v4 => v5:
- Rebased kernel and kvm-unit-tests patches
- Reordered and reworked patches to now WARN on a failed kvm_set_msr()
- Dropped patch to alow resetting guest in kvm-unit-tests, as the functionality is no longer needed.
This patchset exposes the "load IA32_PERF_GLOBAL_CTRL" to guests for nested VM-entry and VM-exit. There already was some existing code that supported the VM-exit ctrl, though it had an issue and was not exposed to the guest anyway. These patches are based on the original set that Krish Sadhukhan sent out earlier this year.
Oliver Upton (6):
KVM: nVMX: Expose load IA32_PERF_GLOBAL_CTRL VM-{Entry,Exit} control
KVM: nVMX: Load GUEST_IA32_PERF_GLOBAL_CTRL MSR on VM-Entry
KVM: nVMX: Use kvm_set_msr to load IA32_PERF_GLOBAL_CTRL on VM-Exit
KVM: nVMX: Check HOST_IA32_PERF_GLOBAL_CTRL on VM-Entry
KVM: nVMX: Check GUEST_IA32_PERF_GLOBAL_CTRL on VM-Entry
KVM: VMX: Add helper to check reserved bits in IA32_PERF_GLOBAL_CTRL
arch/x86/kvm/pmu.h | 6 ++++++ arch/x86/kvm/vmx/nested.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- arch/x86/kvm/vmx/nested.h | 1 + arch/x86/kvm/vmx/pmu_intel.c | 5 ++++-
Signature · 1 line
2.23.0.187.g17f5b7556c-goog
PATCH v5 1/8 KVM: VMX: Add helper to check reserved bits in IA32_PERF_GLOBAL_CTRL
Create a helper function to check the validity of a proposed value for IA32_PERF_GLOBAL_CTRL from the existing check in intel_pmu_set_msr().
Per Intel's SDM, the reserved bits in IA32_PERF_GLOBAL_CTRL must be cleared for the corresponding host/guest state fields.
--- arch/x86/kvm/pmu.h | 6 ++++++ arch/x86/kvm/vmx/pmu_intel.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-)
arch/x86/kvm/pmu.h +6 -0
@@ -79,6 +79,12 @@ static inline bool pmc_is_enabled(struct kvm_pmc *pmc)return kvm_x86_ops->pmu_ops->pmc_is_enabled (pmc); } +static inline bool kvm_valid_perf_global_ctrl (struct kvm_pmu *pmu, +u64 data) +{ +return !(pmu->global_ctrl_mask & data); +} +/* returns general purpose PMC with the specified MSR. Note that it can be * used for both PERFCTRn and EVNTSELn; that is why it accepts base as a * paramenter to tell them apart.
arch/x86/kvm/vmx/pmu_intel.c +1 -1
@@ -223,7 +223,7 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)case MSR_CORE_PERF_GLOBAL_CTRL :if (pmu->global_ctrl == data)return 0 ; -if (!(data & pmu->global_ctrl_mask)) { +if (kvm_valid_perf_global_ctrl (pmu, data)) {global_ctrl_changed (pmu, data);return 0 ; }
Signature · 1 line
2.24.0.rc1.363.gb1bccd3e3d-goog
PATCH v5 2/8 KVM: nVMX: Check GUEST_IA32_PERF_GLOBAL_CTRL on VM-Entry
In reply to Oliver UptonAdd condition to nested_vmx_check_guest_state() to check the validity of GUEST_IA32_PERF_GLOBAL_CTRL. Per Intel's SDM Vol 3 26.3.1.1:
If the "load IA32_PERF_GLOBAL_CTRL" VM-entry control is 1, bits reserved in the IA32_PERF_GLOBAL_CTRL MSR must be 0 in the field for that register.
--- arch/x86/kvm/vmx/nested.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/x86/kvm/vmx/nested.c +6 -0
@@ -10,6 +10,7 @@#include "hyperv.h" #include "mmu.h" #include "nested.h" +#include "pmu.h" #include "trace.h" #include "x86.h"
@@ -2779,6 +2780,11 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,return -EINVAL ; } +if ((vmcs12->vm_entry_controls &VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL ) && +CC (!kvm_valid_perf_global_ctrl (vcpu_to_pmu (vcpu), + vmcs12->guest_ia32_perf_global_ctrl))) +return -EINVAL ; +/* * If the load IA32_EFER VM-entry control is 1, the following checks * are performed on the field for the IA32_EFER MSR:
Signature · 1 line
2.24.0.rc1.363.gb1bccd3e3d-goog
PATCH v5 3/8 KVM: nVMX: Check HOST_IA32_PERF_GLOBAL_CTRL on VM-Entry
In reply to Oliver UptonAdd a consistency check on nested vm-entry for host's IA32_PERF_GLOBAL_CTRL from vmcs12. Per Intel's SDM Vol 3 26.2.2:
If the "load IA32_PERF_GLOBAL_CTRL"
VM-exit control is 1, bits reserved in the IA32_PERF_GLOBAL_CTRL MSR must be 0 in the field for that register"
--- arch/x86/kvm/vmx/nested.c | 5 +++++ 1 file changed, 5 insertions(+)
arch/x86/kvm/vmx/nested.c +5 -0
@@ -2665,6 +2665,11 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu, CC(!kvm_pat_valid(vmcs12->host_ia32_pat)))return -EINVAL ; +if ((vmcs12->vm_exit_controls &VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL ) && +CC (!kvm_valid_perf_global_ctrl (vcpu_to_pmu (vcpu), + vmcs12->host_ia32_perf_global_ctrl))) +return -EINVAL ; +#ifdef CONFIG_X86_64 ia32e = !!(vcpu->arch.efer &EFER_LMA );#else
Signature · 1 line
2.24.0.rc1.363.gb1bccd3e3d-goog
PATCH v5 4/8 KVM: nVMX: Use kvm_set_msr to load IA32_PERF_GLOBAL_CTRL on VM-Exit
In reply to Oliver UptonThe existing implementation for loading the IA32_PERF_GLOBAL_CTRL MSR on VM-exit was incorrect, as the next call to atomic_switch_perf_msrs() could cause this value to be overwritten. Instead, call kvm_set_msr() which will allow atomic_switch_perf_msrs() to correctly set the values.
Define a macro, SET_MSR_OR_WARN(), to set the MSR with kvm_set_msr() and WARN on failure.
--- arch/x86/kvm/vmx/nested.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx/nested.c +12 -2
@@ -28,6 +28,16 @@ module_param(nested_early_check, bool, S_IRUGO); failed; \ }) +#define SET_MSR_OR_WARN (vcpu, idx, data) \ +({ \ + bool failed = kvm_set_msr(vcpu, idx, data); \ + if (failed) \ + pr_warn_ratelimited( \ + "%s cannot write MSR (0x%x, 0x%llx)\n", \ + __func__, idx, data); \ + failed; \ +}) +/* * Hyper-V requires all of these, so mark them as supported even though * they are just treated the same as all-context.
@@ -3867,8 +3877,8 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, vcpu->arch.pat = vmcs12->host_ia32_pat; }if (vmcs12->vm_exit_controls &VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL ) -vmcs_write64 (GUEST_IA32_PERF_GLOBAL_CTRL , - vmcs12->host_ia32_perf_global_ctrl); +SET_MSR_OR_WARN (vcpu,MSR_CORE_PERF_GLOBAL_CTRL , + vmcs12->host_ia32_perf_global_ctrl);/* Set L1 segment info according to Intel SDM 27.5.2 Loading Host Segment and Descriptor-Table Registers */
Signature · 1 line
2.24.0.rc1.363.gb1bccd3e3d-goog
PATCH v5 5/8 KVM: nVMX: Load GUEST_IA32_PERF_GLOBAL_CTRL MSR on VM-Entry
In reply to Oliver UptonAdd condition to prepare_vmcs02 which loads IA32_PERF_GLOBAL_CTRL on VM-entry if the "load IA32_PERF_GLOBAL_CTRL" bit on the VM-entry control is set. Use SET_MSR_OR_WARN() rather than directly writing to the field to avoid overwrite by atomic_switch_perf_msrs().
--- arch/x86/kvm/vmx/nested.c | 5 +++++ 1 file changed, 5 insertions(+)
arch/x86/kvm/vmx/nested.c +5 -0
@@ -2441,6 +2441,11 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,if (!enable_ept) vcpu->arch.walk_mmu->inject_page_fault = vmx_inject_page_fault_nested; +if ((vmcs12->vm_entry_controls &VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL ) && +SET_MSR_OR_WARN (vcpu,MSR_CORE_PERF_GLOBAL_CTRL , + vmcs12->guest_ia32_perf_global_ctrl)) +return -EINVAL ; +kvm_rsp_write (vcpu, vmcs12->guest_rsp);kvm_rip_write (vcpu, vmcs12->guest_rip);return 0 ;
Signature · 1 line
2.24.0.rc1.363.gb1bccd3e3d-goog
PATCH v5 6/8 KVM: nVMX: Expose load IA32_PERF_GLOBAL_CTRL VM-{Entry,Exit} control
In reply to Oliver UptonThe "load IA32_PERF_GLOBAL_CTRL" bit for VM-entry and VM-exit should only be exposed to the guest if IA32_PERF_GLOBAL_CTRL is a valid MSR. Create a new helper to allow pmu_refresh() to update the VM-Entry and VM-Exit controls to ensure PMU values are initialized when performing the is_valid_msr() check.
--- arch/x86/kvm/vmx/nested.c | 21 +++++++++++++++++++++ arch/x86/kvm/vmx/nested.h | 1 + arch/x86/kvm/vmx/pmu_intel.c | 3 +++ 3 files changed, 25 insertions(+)
arch/x86/kvm/vmx/nested.c +21 -0
@@ -4345,6 +4345,27 @@ int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification,return 0 ; } +void nested_vmx_pmu_entry_exit_ctls_update (struct kvm_vcpu *vcpu) +{ +struct vcpu_vmx *vmx; + +if (!nested_vmx_allowed (vcpu)) +return ; + + vmx =to_vmx (vcpu); +if (kvm_x86_ops->pmu_ops->is_valid_msr (vcpu,MSR_CORE_PERF_GLOBAL_CTRL )) { + vmx->nested.msrs.entry_ctls_high |= +VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL ; + vmx->nested.msrs.exit_ctls_high |= +VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL ; + }else { + vmx->nested.msrs.entry_ctls_high &= + ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL ; + vmx->nested.msrs.exit_ctls_high &= + ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL ; + } +} +static int nested_vmx_get_vmptr (struct kvm_vcpu *vcpu,gpa_t *vmpointer) {gva_t gva;
arch/x86/kvm/vmx/nested.h +1 -0
@@ -22,6 +22,7 @@ int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);int vmx_get_vmx_msr (struct nested_vmx_msrs *msrs,u32 msr_index,u64 *pdata);int get_vmx_mem_address (struct kvm_vcpu *vcpu,unsigned long exit_qualification,u32 vmx_instruction_info,bool wr,int len,gva_t *ret); +void nested_vmx_pmu_entry_exit_ctls_update (struct kvm_vcpu *vcpu);static inline struct vmcs12 *get_vmcs12 (struct kvm_vcpu *vcpu) {
arch/x86/kvm/vmx/pmu_intel.c +3 -0
@@ -15,6 +15,7 @@#include "x86.h" #include "cpuid.h" #include "lapic.h" +#include "nested.h" #include "pmu.h" static struct kvm_event_hw_type_mapping intel_arch_events[] = {
@@ -317,6 +318,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) (boot_cpu_has (X86_FEATURE_HLE ) ||boot_cpu_has (X86_FEATURE_RTM )) && (entry->ebx & (X86_FEATURE_HLE|X86_FEATURE_RTM))) pmu->reserved_bits ^= HSW_IN_TX|HSW_IN_TX_CHECKPOINTED; + +nested_vmx_pmu_entry_exit_ctls_update (vcpu); }static void intel_pmu_init (struct kvm_vcpu *vcpu)
Signature · 1 line
2.24.0.rc1.363.gb1bccd3e3d-goog
PATCH v5 7/8 x86: VMX: Make guest_state_test_main() check state from nested VM
In reply to Oliver UptonIntroduce the vmx_state_area_test_data struct for sharing test expectation data with the nested VM.
--- x86/vmx_tests.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
x86/vmx_tests.c +18 -3
@@ -5023,13 +5023,28 @@ static void test_entry_msr_load(void)test_vmx_valid_controls (); } +static struct vmx_state_area_test_data { +u32 msr; +u64 exp; +bool enabled; +} vmx_state_area_test_data; +static void guest_state_test_main (void ) { +u64 obs; +struct vmx_state_area_test_data *data = &vmx_state_area_test_data; +while (1 ) { -if (vmx_get_test_stage () !=2 ) -vmcall (); -else +if (vmx_get_test_stage () ==2 )break ; + +if (data->enabled) { + obs =rdmsr (data->msr); +report ("Guest state is 0x%lx (expected 0x%lx)" , + data->exp == obs, obs, data->exp); + } + +vmcall (); } asmvolatile ("fnop" );
Signature · 1 line
2.24.0.rc1.363.gb1bccd3e3d-goog
PATCH v5 8/8 x86: VMX: Add tests for nested "load IA32_PERF_GLOBAL_CTRL"
In reply to Oliver UptonTests to verify that KVM performs the correct checks on Host/Guest state at VM-entry, as described in SDM 26.3.1.1 "Checks on Guest Control Registers, Debug Registers, and MSRs" and SDM 26.2.2 "Checks on Host Control Registers and MSRs".
Test that KVM does the following:
If the "load IA32_PERF_GLOBAL_CTRL" VM-entry control is 1, the reserved bits of the IA32_PERF_GLOBAL_CTRL MSR must be 0 in the GUEST_IA32_PERF_GLOBAL_CTRL VMCS field. Otherwise, the VM-entry should fail with an exit reason of "VM-entry failure due to invalid guest state" (33). On a successful VM-entry, the correct value should be observed when the nested VM performs an RDMSR on IA32_PERF_GLOBAL_CTRL.
If the "load IA32_PERF_GLOBAL_CTRL" VM-exit control is 1, the reserved bits of the IA32_PERF_GLOBAL_CTRL MSR must be 0 in the HOST_IA32_PERF_GLOBAL_CTRL VMCS field. Otherwise, the VM-entry should fail with a VM-instruction error of "VM entry with invalid host-state field(s)" (8). On a successful VM-exit, the correct value should be observed when L1 performs an RDMSR on IA32_PERF_GLOBAL_CTRL.
--- x86/vmx_tests.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+)
x86/vmx_tests.c +160 -0
@@ -7032,6 +7032,164 @@ static void test_load_host_pat(void)test_pat (HOST_PAT ,"HOST_PAT" ,EXI_CONTROLS ,EXI_LOAD_PAT ); } +union cpuidA_eax { +struct { +unsigned int version_id:8 ; +unsigned int num_counters_gp:8 ; +unsigned int bit_width:8 ; +unsigned int mask_length:8 ; + } split; +unsigned int full; +}; + +union cpuidA_edx { +struct { +unsigned int num_counters_fixed:5 ; +unsigned int bit_width_fixed:8 ; +unsigned int reserved:9 ; + } split; +unsigned int full; +}; + +static bool valid_pgc (u64 val) +{ +struct cpuid id; +union cpuidA_eax eax; +union cpuidA_edx edx; +u64 mask; + + id =cpuid (0xA ); + eax.full = id.a; + edx.full = id.d; + mask = ~(((1ull << eax.split.num_counters_gp) -1 ) | + (((1ull << edx.split.num_counters_fixed) -1 ) <<32 )); + +return !(val & mask); +} + +static void test_pgc_vmlaunch (u32 xerror,u32 xreason,bool xfail,bool host) +{ +u32 inst_err; +u64 obs; +bool success; +struct vmx_state_area_test_data *data = &vmx_state_area_test_data; + +if (host) { + success =vmlaunch_succeeds (); + obs =rdmsr (data->msr); +if (!success) { + inst_err =vmcs_read (VMX_INST_ERROR ); +report ("vmlaunch failed, VMX Inst Error is %d (expected %d)" , + xerror == inst_err, inst_err, xerror); + }else { +report ("Host state is 0x%lx (expected 0x%lx)" , + !data->enabled || data->exp == obs, obs, data->exp); +report ("vmlaunch succeeded" , success != xfail); + } + }else { +if (xfail) { +enter_guest_with_invalid_guest_state (); + }else { +enter_guest (); + } +report_guest_state_test ("load GUEST_PERF_GLOBAL_CTRL" , + xreason,GUEST_PERF_GLOBAL_CTRL , +"GUEST_PERF_GLOBAL_CTRL" ); + } +} + +/* +* test_load_perf_global_ctrl is a generic function for testing the +* "load IA32_PERF_GLOBAL_CTRL" VM-{Entry,Exit} controls. This test function +* tests the provided ctrl_val when disabled and enabled. +* +* @nr: VMCS field number corresponding to the host/guest state field +* @name: Name of the above VMCS field for printing in test report +* @ctrl_nr: VMCS field number corresponding to the VM-{Entry,Exit} control +* @ctrl_val: Bit to set on the ctrl_field +*/ +static void test_perf_global_ctrl (u32 nr,const char *name,u32 ctrl_nr, +const char *ctrl_name,u64 ctrl_val) +{ +u64 ctrl_saved =vmcs_read (ctrl_nr); +u64 pgc_saved =vmcs_read (nr); +u64 i, val; +bool host = nr ==HOST_PERF_GLOBAL_CTRL ; +struct vmx_state_area_test_data *data = &vmx_state_area_test_data; + + data->msr =MSR_CORE_PERF_GLOBAL_CTRL ; +msr_bmp_init (); +vmcs_write (ctrl_nr, ctrl_saved & ~ctrl_val); + data->enabled = false; +report_prefix_pushf ("\"load IA32_PERF_GLOBAL_CTRL\"=0 on %s" , + ctrl_name); + +for (i =0 ; i <64 ; i++) { + val =1ull << i; +vmcs_write (nr, val); +report_prefix_pushf ("%s = 0x%lx" , name, val); +test_pgc_vmlaunch (0 ,VMX_VMCALL , false, host); +report_prefix_pop (); + } +report_prefix_pop (); + +vmcs_write (ctrl_nr, ctrl_saved | ctrl_val); + data->enabled = true; +report_prefix_pushf ("\"load IA32_PERF_GLOBAL_CTRL\"=1 on %s" , + ctrl_name); +for (i =0 ; i <64 ; i++) { + val =1ull << i; + data->exp = val; +vmcs_write (nr, val); +report_prefix_pushf ("%s = 0x%lx" , name, val); +if (valid_pgc (val)) { +test_pgc_vmlaunch (0 ,VMX_VMCALL , false, host); + }else { +if (host) +test_pgc_vmlaunch ( +VMXERR_ENTRY_INVALID_HOST_STATE_FIELD , +0 , + true, + host); +else +test_pgc_vmlaunch ( +0 , +VMX_ENTRY_FAILURE |VMX_FAIL_STATE , + true, + host); + } +report_prefix_pop (); + } + +report_prefix_pop (); +vmcs_write (ctrl_nr, ctrl_saved); +vmcs_write (nr, pgc_saved); +} + +static void test_load_host_perf_global_ctrl (void ) +{ +if (!(ctrl_exit_rev.clr &EXI_LOAD_PERF )) { +printf ("\"load IA32_PERF_GLOBAL_CTRL\" exit control not supported\n" ); +return ; + } + +test_perf_global_ctrl (HOST_PERF_GLOBAL_CTRL ,"HOST_PERF_GLOBAL_CTRL" , +EXI_CONTROLS ,"EXI_CONTROLS" ,EXI_LOAD_PERF ); +} + + +static void test_load_guest_perf_global_ctrl (void ) +{ +if (!(ctrl_enter_rev.clr &ENT_LOAD_PERF )) { +printf ("\"load IA32_PERF_GLOBAL_CTRL\" entry control not supported\n" ); +return ; + } + +test_perf_global_ctrl (GUEST_PERF_GLOBAL_CTRL ,"GUEST_PERF_GLOBAL_CTRL" , +ENT_CONTROLS ,"ENT_CONTROLS" ,ENT_LOAD_PERF ); +} + +/* * test_vmcs_field - test a value for the given VMCS field * @field: VMCS field
@@ -7261,6 +7419,7 @@ static void vmx_host_state_area_test(void)test_host_segment_regs ();test_host_desc_tables ();test_host_addr_size (); +test_load_host_perf_global_ctrl (); }/*
@@ -7296,6 +7455,7 @@ static void vmx_guest_state_area_test(void)test_load_guest_pat ();test_guest_efer (); +test_load_guest_perf_global_ctrl ();/* * Let the guest finish execution
Signature · 1 line
2.24.0.rc1.363.gb1bccd3e3d-goog
Quoted 45 lines · Oliver Upton
[v1] https://lore.kernel.org/r/[email protected]
[v2] https://lore.kernel.org/r/[email protected]
[v3] https://lore.kernel.org/r/[email protected]
[v4] https://lore.kernel.org/r/[email protected]v1 => v2:
- Add Krish's Co-developed-by and Signed-off-by tags.
- Fix minor nit to kvm-unit-tests to use 'host' local variable throughouttest_load_pgc()
- Teachguest_state_test_main()to check guest state from within nested VM
- Update proposed tests to use guest/host state checks, wherein the value is checked fromMSR_CORE_PERF_GLOBAL_CTRL.
- Changelog line wrappingv2 => v3:
- Remove the value unchanged condition from
kvm_is_valid_perf_global_ctrl
- Add line to changelog for patch 3/8v3 => v4:
- Allow tests to set the guest func multiple times
- Style fixes throughout kvm-unit-tests patches, per Krish's reviewv4 => v5:
- Rebased kernel and kvm-unit-tests patches
- Reordered and reworked patches to now WARN on a failedkvm_set_msr()
- Dropped patch to alow resetting guest in kvm-unit-tests, as the functionality is no longer needed.This patchset exposes the "load
IA32_PERF_GLOBAL_CTRL" to guests for nested VM-entry and VM-exit. There already was some existing code that supported the VM-exit ctrl, though it had an issue and was not exposed to the guest anyway. These patches are based on the original set that Krish Sadhukhan sent out earlier this year.Oliver Upton (6):
KVM: nVMX: Expose loadIA32_PERF_GLOBAL_CTRLVM-{Entry,Exit} control
KVM: nVMX: LoadGUEST_IA32_PERF_GLOBAL_CTRLMSR on VM-Entry
KVM: nVMX: Usekvm_set_msrto loadIA32_PERF_GLOBAL_CTRLon VM-Exit
KVM: nVMX: CheckHOST_IA32_PERF_GLOBAL_CTRLon VM-Entry
KVM: nVMX: CheckGUEST_IA32_PERF_GLOBAL_CTRLon VM-Entry
KVM: VMX: Add helper to check reserved bits inIA32_PERF_GLOBAL_CTRL
Quoted 5 lines
arch/x86/kvm/pmu.h | 6 ++++++ arch/x86/kvm/vmx/nested.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- arch/x86/kvm/vmx/nested.h | 1 + arch/x86/kvm/vmx/pmu_intel.c | 5 ++++-
Queued, thanks.
But I had to squash this in patch 8:
x86/vmx_tests.c +0 -0
@@ -7161,6 +7161,7 @@ static void test_perf_global_ctrl(u32 nr, const
char *name, u32 ctrl_nr,
report_prefix_pop();
}
+ data->enabled = false;
report_prefix_pop();
vmcs_write(ctrl_nr, ctrl_saved);
vmcs_write(nr, pgc_saved);
and I'm not sure about how this could have worked for you.
Paolo
Quoted 70 lines · Paolo Bonzini
Quoted 45 lines · Oliver Upton
[v1] https://lore.kernel.org/r/[email protected]
[v2] https://lore.kernel.org/r/[email protected]
[v3] https://lore.kernel.org/r/[email protected]
[v4] https://lore.kernel.org/r/[email protected]v1 => v2:
- Add Krish's Co-developed-by and Signed-off-by tags.
- Fix minor nit to kvm-unit-tests to use 'host' local variable throughouttest_load_pgc()
- Teachguest_state_test_main()to check guest state from within nested VM
- Update proposed tests to use guest/host state checks, wherein the value is checked fromMSR_CORE_PERF_GLOBAL_CTRL.
- Changelog line wrappingv2 => v3:
- Remove the value unchanged condition from
kvm_is_valid_perf_global_ctrl
- Add line to changelog for patch 3/8v3 => v4:
- Allow tests to set the guest func multiple times
- Style fixes throughout kvm-unit-tests patches, per Krish's reviewv4 => v5:
- Rebased kernel and kvm-unit-tests patches
- Reordered and reworked patches to now WARN on a failedkvm_set_msr()
- Dropped patch to alow resetting guest in kvm-unit-tests, as the functionality is no longer needed.This patchset exposes the "load
IA32_PERF_GLOBAL_CTRL" to guests for nested VM-entry and VM-exit. There already was some existing code that supported the VM-exit ctrl, though it had an issue and was not exposed to the guest anyway. These patches are based on the original set that Krish Sadhukhan sent out earlier this year.Oliver Upton (6):
KVM: nVMX: Expose loadIA32_PERF_GLOBAL_CTRLVM-{Entry,Exit} control
KVM: nVMX: LoadGUEST_IA32_PERF_GLOBAL_CTRLMSR on VM-Entry
KVM: nVMX: Usekvm_set_msrto loadIA32_PERF_GLOBAL_CTRLon VM-Exit
KVM: nVMX: CheckHOST_IA32_PERF_GLOBAL_CTRLon VM-Entry
KVM: nVMX: CheckGUEST_IA32_PERF_GLOBAL_CTRLon VM-Entry
KVM: VMX: Add helper to check reserved bits inIA32_PERF_GLOBAL_CTRLQuoted 5 lines
arch/x86/kvm/pmu.h | 6 ++++++ arch/x86/kvm/vmx/nested.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- arch/x86/kvm/vmx/nested.h | 1 + arch/x86/kvm/vmx/pmu_intel.c | 5 ++++-Queued, thanks.
But I had to squash this in patch 8:
x86/vmx_tests.c +1
-0@@ -7161,6 +7161,7 @@ static void test_perf_global_ctrl(u32 nr, const char *name, u32 ctrl_nr,report_prefix_pop (); } + data->enabled = false;report_prefix_pop ();vmcs_write (ctrl_nr, ctrl_saved);
vmcs_write(nr, pgc_saved);
Quoted 3 lines
and I'm not sure about how this could have worked for you.
Paolo
Thanks for the fix. This was an oversight of mine as I had only run the tests I introduced individually. I'll be more thorough in future changes, apologies.
--
Best,
Oliver