History

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull KVM fixes from Paolo Bonzini: - Doc fixes - selftests fixes - Add runstate information to the new Xen support - Allow compiling out the Xen interface - 32-bit PAE without EPT bugfix - NULL pointer dereference bugfix * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: SVM: Clear the CR4 register on reset KVM: x86/xen: Add support for vCPU runstate information KVM: x86/xen: Fix return code when clearing vcpu_info and vcpu_time_info selftests: kvm: Mmap the entire vcpu mmap area KVM: Documentation: Fix index for KVM_CAP_PPC_DAWR1 KVM: x86: allow compiling out the Xen hypercall interface KVM: xen: flush deferred static key before checking it KVM: x86/mmu: Set SPTE_AD_WRPROT_ONLY_MASK if and only if PML is enabled KVM: x86: hyper-v: Fix Hyper-V context null-ptr-deref KVM: x86: remove misplaced comment on active_mmu_pages KVM: Documentation: rectify rst markup in kvm_run->flags Documentation: kvm: fix messy conversion from .txt to .rst

Linus Torvalds committed 5 years ago

Commit cee407c2 parents c5a58f8 9e46f6c13 files · +633 −76Browse files

Unified · Split

13 files
  1. Documentation/virt/kvm/api.rst +60 −55
  2. arch/x86/include/asm/kvm_host.h +6 −3
  3. arch/x86/kvm/Kconfig +9 −0
  4. arch/x86/kvm/Makefile +2 −1
  5. arch/x86/kvm/hyperv.c +1 −1
  6. arch/x86/kvm/mmu/mmu_internal.h +8 −8
  7. arch/x86/kvm/svm/svm.c +1 −0
  8. arch/x86/kvm/x86.c +21 −1
  9. arch/x86/kvm/xen.c +290 −0
  10. arch/x86/kvm/xen.h +62 −2
  11. include/uapi/linux/kvm.h +13 −0
  12. tools/testing/selftests/kvm/lib/kvm_util.c +4 −2
  13. tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c +156 −3
Documentation/virt/kvm/api.rst+60−55
@@ -3856,49 +3856,20 @@ base 2 of the page size in the bottom 6 bits. · 3855 unmodified lines
3856 -EFAULT if struct kvm_reinject_control cannot be read,3856 -EFAULT if struct kvm_reinject_control cannot be read,
3857 -EINVAL if the supplied shift or flags are invalid,3857 -EINVAL if the supplied shift or flags are invalid,
3858 -ENOMEM if unable to allocate the new HPT,3858 -ENOMEM if unable to allocate the new HPT,
3859 -ENOSPC if there was a hash collision
3860
3861::
3862
3863 struct kvm_ppc_rmmu_info {
3864 struct kvm_ppc_radix_geom {
3865 __u8 page_shift;
3866 __u8 level_bits[4];
3867 __u8 pad[3];
3868 } geometries[8];
3869 __u32 ap_encodings[8];
3870 };
3871
3872The geometries[] field gives up to 8 supported geometries for the
3873radix page table, in terms of the log base 2 of the smallest page
3874size, and the number of bits indexed at each level of the tree, from
3875the PTE level up to the PGD level in that order. Any unused entries
3876will have 0 in the page_shift field.
3877
3878The ap_encodings gives the supported page sizes and their AP field
3879encodings, encoded with the AP value in the top 3 bits and the log
3880base 2 of the page size in the bottom 6 bits.
3881
38824.102 KVM_PPC_RESIZE_HPT_PREPARE
3883--------------------------------
3884
3885:Capability: KVM_CAP_SPAPR_RESIZE_HPT
3886:Architectures: powerpc
3887:Type: vm ioctl
3888:Parameters: struct kvm_ppc_resize_hpt (in)
3889:Returns: 0 on successful completion,
3890 >0 if a new HPT is being prepared, the value is an estimated
3891 number of milliseconds until preparation is complete,
3892 -EFAULT if struct kvm_reinject_control cannot be read,
3893 -EINVAL if the supplied shift or flags are invalid,when moving existing
3894 HPT entries to the new HPT,
3895 -EIO on other error conditions
3896 3859
3897Used to implement the PAPR extension for runtime resizing of a guest's3860Used to implement the PAPR extension for runtime resizing of a guest's
3898Hashed Page Table (HPT). Specifically this starts, stops or monitors3861Hashed Page Table (HPT). Specifically this starts, stops or monitors
3899the preparation of a new potential HPT for the guest, essentially3862the preparation of a new potential HPT for the guest, essentially
3900implementing the H_RESIZE_HPT_PREPARE hypercall.3863implementing the H_RESIZE_HPT_PREPARE hypercall.
3901 3864
3865::
3866
3867 struct kvm_ppc_resize_hpt {
3868 __u64 flags;
3869 __u32 shift;
3870 __u32 pad;
3871 };
3872
3902If called with shift > 0 when there is no pending HPT for the guest,3873If called with shift > 0 when there is no pending HPT for the guest,
3903this begins preparation of a new pending HPT of size 2^(shift) bytes.3874this begins preparation of a new pending HPT of size 2^(shift) bytes.
3904It then returns a positive integer with the estimated number of3875It then returns a positive integer with the estimated number of
@@ -3926,14 +3897,6 @@ Normally this will be called repeatedly with the same parameters until · 21 unmodified lines
3926it returns <= 0. The first call will initiate preparation, subsequent3897it returns <= 0. The first call will initiate preparation, subsequent
3927ones will monitor preparation until it completes or fails.3898ones will monitor preparation until it completes or fails.
3928 3899
3929::
3930
3931 struct kvm_ppc_resize_hpt {
3932 __u64 flags;
3933 __u32 shift;
3934 __u32 pad;
3935 };
3936
39374.103 KVM_PPC_RESIZE_HPT_COMMIT39004.103 KVM_PPC_RESIZE_HPT_COMMIT
3938-------------------------------3901-------------------------------
3939 3902
@@ -3956,6 +3919,14 @@ Hashed Page Table (HPT). Specifically this requests that the guest be · 16 unmodified lines
3956transferred to working with the new HPT, essentially implementing the3919transferred to working with the new HPT, essentially implementing the
3957H_RESIZE_HPT_COMMIT hypercall.3920H_RESIZE_HPT_COMMIT hypercall.
3958 3921
3922::
3923
3924 struct kvm_ppc_resize_hpt {
3925 __u64 flags;
3926 __u32 shift;
3927 __u32 pad;
3928 };
3929
3959This should only be called after KVM_PPC_RESIZE_HPT_PREPARE has3930This should only be called after KVM_PPC_RESIZE_HPT_PREPARE has
3960returned 0 with the same parameters. In other cases3931returned 0 with the same parameters. In other cases
3961KVM_PPC_RESIZE_HPT_COMMIT will return an error (usually -ENXIO or3932KVM_PPC_RESIZE_HPT_COMMIT will return an error (usually -ENXIO or
@@ -3971,14 +3942,6 @@ HPT and the previous HPT will be discarded. · 9 unmodified lines
3971 3942
3972On failure, the guest will still be operating on its previous HPT.3943On failure, the guest will still be operating on its previous HPT.
3973 3944
3974::
3975
3976 struct kvm_ppc_resize_hpt {
3977 __u64 flags;
3978 __u32 shift;
3979 __u32 pad;
3980 };
3981
39824.104 KVM_X86_GET_MCE_CAP_SUPPORTED39454.104 KVM_X86_GET_MCE_CAP_SUPPORTED
3983-----------------------------------3946-----------------------------------
3984 3947
@@ -4915,6 +4878,14 @@ see KVM_XEN_HVM_SET_ATTR above. · 930 unmodified lines
4915 union {4878 union {
4916 __u64 gpa;4879 __u64 gpa;
4917 __u64 pad[4];4880 __u64 pad[4];
4881 struct {
4882 __u64 state;
4883 __u64 state_entry_time;
4884 __u64 time_running;
4885 __u64 time_runnable;
4886 __u64 time_blocked;
4887 __u64 time_offline;
4888 } runstate;
4918 } u;4889 } u;
4919 };4890 };
4920 4891
@@ -4927,6 +4898,31 @@ KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO · 6 unmodified lines
4927 Sets the guest physical address of an additional pvclock structure4898 Sets the guest physical address of an additional pvclock structure
4928 for a given vCPU. This is typically used for guest vsyscall support.4899 for a given vCPU. This is typically used for guest vsyscall support.
4929 4900
4901KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR
4902 Sets the guest physical address of the vcpu_runstate_info for a given
4903 vCPU. This is how a Xen guest tracks CPU state such as steal time.
4904
4905KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT
4906 Sets the runstate (RUNSTATE_running/_runnable/_blocked/_offline) of
4907 the given vCPU from the .u.runstate.state member of the structure.
4908 KVM automatically accounts running and runnable time but blocked
4909 and offline states are only entered explicitly.
4910
4911KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA
4912 Sets all fields of the vCPU runstate data from the .u.runstate member
4913 of the structure, including the current runstate. The state_entry_time
4914 must equal the sum of the other four times.
4915
4916KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST
4917 This *adds* the contents of the .u.runstate members of the structure
4918 to the corresponding members of the given vCPU's runstate data, thus
4919 permitting atomic adjustments to the runstate times. The adjustment
4920 to the state_entry_time must equal the sum of the adjustments to the
4921 other four times. The state field must be set to -1, or to a valid
4922 runstate value (RUNSTATE_running, RUNSTATE_runnable, RUNSTATE_blocked
4923 or RUNSTATE_offline) to set the current accounted state as of the
4924 adjusted state_entry_time.
4925
49304.130 KVM_XEN_VCPU_GET_ATTR49264.130 KVM_XEN_VCPU_GET_ATTR
4931---------------------------4927---------------------------
4932 4928
@@ -4939,6 +4935,9 @@ KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO · 6 unmodified lines
4939Allows Xen vCPU attributes to be read. For the structure and types,4935Allows Xen vCPU attributes to be read. For the structure and types,
4940see KVM_XEN_VCPU_SET_ATTR above.4936see KVM_XEN_VCPU_SET_ATTR above.
4941 4937
4938The KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST type may not be used
4939with the KVM_XEN_VCPU_GET_ATTR ioctl.
4940
49425. The kvm_run structure49415. The kvm_run structure
4943========================4942========================
4944 4943
@@ -5000,7 +4999,8 @@ local APIC is not used. · 55 unmodified lines
5000 __u16 flags;4999 __u16 flags;
5001 5000
5002More architecture-specific flags detailing state of the VCPU that may5001More architecture-specific flags detailing state of the VCPU that may
5003affect the device's behavior. Current defined flags:5002affect the device's behavior. Current defined flags::
5003
5004 /* x86, set if the VCPU is in system management mode */5004 /* x86, set if the VCPU is in system management mode */
5005 #define KVM_RUN_X86_SMM (1 << 0)5005 #define KVM_RUN_X86_SMM (1 << 0)
5006 /* x86, set if bus lock detected in VM */5006 /* x86, set if bus lock detected in VM */
@@ -6217,7 +6217,7 @@ the bus lock vm exit can be preempted by a higher priority VM exit, the exit · 1210 unmodified lines
6217notifications to userspace can be KVM_EXIT_BUS_LOCK or other reasons.6217notifications to userspace can be KVM_EXIT_BUS_LOCK or other reasons.
6218KVM_RUN_BUS_LOCK flag is used to distinguish between them.6218KVM_RUN_BUS_LOCK flag is used to distinguish between them.
6219 6219
62207.22 KVM_CAP_PPC_DAWR162207.23 KVM_CAP_PPC_DAWR1
6221----------------------6221----------------------
6222 6222
6223:Architectures: ppc6223:Architectures: ppc
@@ -6702,6 +6702,7 @@ PVHVM guests. Valid flags are:: · 478 unmodified lines
6702 #define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0)6702 #define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0)
6703 #define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1)6703 #define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1)
6704 #define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)6704 #define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)
6705 #define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 2)
6705 6706
6706The KVM_XEN_HVM_CONFIG_HYPERCALL_MSR flag indicates that the KVM_XEN_HVM_CONFIG6707The KVM_XEN_HVM_CONFIG_HYPERCALL_MSR flag indicates that the KVM_XEN_HVM_CONFIG
6707ioctl is available, for the guest to set its hypercall page.6708ioctl is available, for the guest to set its hypercall page.
@@ -6716,3 +6717,7 @@ KVM_XEN_HVM_SET_ATTR, KVM_XEN_HVM_GET_ATTR, KVM_XEN_VCPU_SET_ATTR and · 8 unmodified lines
6716KVM_XEN_VCPU_GET_ATTR ioctls, as well as the delivery of exception vectors6717KVM_XEN_VCPU_GET_ATTR ioctls, as well as the delivery of exception vectors
6717for event channel upcalls when the evtchn_upcall_pending field of a vcpu's6718for event channel upcalls when the evtchn_upcall_pending field of a vcpu's
6718vcpu_info is set.6719vcpu_info is set.
6720
6721The KVM_XEN_HVM_CONFIG_RUNSTATE flag indicates that the runstate-related
6722features KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR/_CURRENT/_DATA/_ADJUST are
6723supported by the KVM_XEN_VCPU_SET_ATTR/KVM_XEN_VCPU_GET_ATTR ioctls.
arch/x86/include/asm/kvm_host.h+6−3
@@ -535,10 +535,16 @@ struct kvm_vcpu_hv { · 534 unmodified lines
535/* Xen HVM per vcpu emulation context */535/* Xen HVM per vcpu emulation context */
536struct kvm_vcpu_xen {536struct kvm_vcpu_xen {
537 u64 hypercall_rip;537 u64 hypercall_rip;
538 u32 current_runstate;
538 bool vcpu_info_set;539 bool vcpu_info_set;
539 bool vcpu_time_info_set;540 bool vcpu_time_info_set;
541 bool runstate_set;
540 struct gfn_to_hva_cache vcpu_info_cache;542 struct gfn_to_hva_cache vcpu_info_cache;
541 struct gfn_to_hva_cache vcpu_time_info_cache;543 struct gfn_to_hva_cache vcpu_time_info_cache;
544 struct gfn_to_hva_cache runstate_cache;
545 u64 last_steal;
546 u64 runstate_entry_time;
547 u64 runstate_times[4];
542};548};
543 549
544struct kvm_vcpu_arch {550struct kvm_vcpu_arch {
@@ -939,9 +945,6 @@ struct kvm_arch { · 394 unmodified lines
939 unsigned int indirect_shadow_pages;945 unsigned int indirect_shadow_pages;
940 u8 mmu_valid_gen;946 u8 mmu_valid_gen;
941 struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];947 struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
942 /*
943 * Hash table of struct kvm_mmu_page.
944 */
945 struct list_head active_mmu_pages;948 struct list_head active_mmu_pages;
946 struct list_head zapped_obsolete_pages;949 struct list_head zapped_obsolete_pages;
947 struct list_head lpage_disallowed_mmu_pages;950 struct list_head lpage_disallowed_mmu_pages;
arch/x86/kvm/Kconfig+9−0
@@ -103,6 +103,15 @@ config KVM_AMD_SEV · 102 unmodified lines
103 Provides support for launching Encrypted VMs (SEV) and Encrypted VMs103 Provides support for launching Encrypted VMs (SEV) and Encrypted VMs
104 with Encrypted State (SEV-ES) on AMD processors.104 with Encrypted State (SEV-ES) on AMD processors.
105 105
106config KVM_XEN
107 bool "Support for Xen hypercall interface"
108 depends on KVM
109 help
110 Provides KVM support for the hosting Xen HVM guests and
111 passing Xen hypercalls to userspace.
112
113 If in doubt, say "N".
114
106config KVM_MMU_AUDIT115config KVM_MMU_AUDIT
107 bool "Audit KVM MMU"116 bool "Audit KVM MMU"
108 depends on KVM && TRACEPOINTS117 depends on KVM && TRACEPOINTS
arch/x86/kvm/Makefile+2−1
@@ -14,11 +14,12 @@ kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ · 13 unmodified lines
14 $(KVM)/dirty_ring.o14 $(KVM)/dirty_ring.o
15kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o15kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o
16 16
17kvm-y += x86.o emulate.o i8259.o irq.o lapic.o xen.o \17kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \
18 i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \18 i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
19 hyperv.o debugfs.o mmu/mmu.o mmu/page_track.o \19 hyperv.o debugfs.o mmu/mmu.o mmu/page_track.o \
20 mmu/spte.o20 mmu/spte.o
21kvm-$(CONFIG_X86_64) += mmu/tdp_iter.o mmu/tdp_mmu.o21kvm-$(CONFIG_X86_64) += mmu/tdp_iter.o mmu/tdp_mmu.o
22kvm-$(CONFIG_KVM_XEN) += xen.o
22 23
23kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o \24kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o \
24 vmx/evmcs.o vmx/nested.o vmx/posted_intr.o25 vmx/evmcs.o vmx/nested.o vmx/posted_intr.o
arch/x86/kvm/hyperv.c+1−1
@@ -159,7 +159,7 @@ static struct kvm_vcpu_hv_synic *synic_get(struct kvm *kvm, u32 vpidx) · 158 unmodified lines
159 struct kvm_vcpu_hv_synic *synic;159 struct kvm_vcpu_hv_synic *synic;
160 160
161 vcpu = get_vcpu_by_vpidx(kvm, vpidx);161 vcpu = get_vcpu_by_vpidx(kvm, vpidx);
162 if (!vcpu)162 if (!vcpu || !to_hv_vcpu(vcpu))
163 return NULL;163 return NULL;
164 synic = to_hv_synic(vcpu);164 synic = to_hv_synic(vcpu);
165 return (synic->active) ? synic : NULL;165 return (synic->active) ? synic : NULL;
arch/x86/kvm/mmu/mmu_internal.h+8−8
@@ -81,15 +81,15 @@ static inline struct kvm_mmu_page *sptep_to_sp(u64 *sptep) · 80 unmodified lines
81static inline bool kvm_vcpu_ad_need_write_protect(struct kvm_vcpu *vcpu)81static inline bool kvm_vcpu_ad_need_write_protect(struct kvm_vcpu *vcpu)
82{82{
83 /*83 /*
84 * When using the EPT page-modification log, the GPAs in the log84 * When using the EPT page-modification log, the GPAs in the CPU dirty
85 * would come from L2 rather than L1. Therefore, we need to rely85 * log would come from L2 rather than L1. Therefore, we need to rely
86 * on write protection to record dirty pages. This also bypasses86 * on write protection to record dirty pages, which bypasses PML, since
87 * PML, since writes now result in a vmexit. Note, this helper will87 * writes now result in a vmexit. Note, the check on CPU dirty logging
88 * tag SPTEs as needing write-protection even if PML is disabled or88 * being enabled is mandatory as the bits used to denote WP-only SPTEs
89 * unsupported, but that's ok because the tag is consumed if and only89 * are reserved for NPT w/ PAE (32-bit KVM).
90 * if PML is enabled. Omit the PML check to save a few uops.
91 */90 */
92 return vcpu->arch.mmu == &vcpu->arch.guest_mmu;91 return vcpu->arch.mmu == &vcpu->arch.guest_mmu &&
92 kvm_x86_ops.cpu_dirty_log_size;
93}93}
94 94
95bool is_nx_huge_page_enabled(void);95bool is_nx_huge_page_enabled(void);
arch/x86/kvm/svm/svm.c+1−0
@@ -1200,6 +1200,7 @@ static void init_vmcb(struct vcpu_svm *svm) · 1199 unmodified lines
1200 init_sys_seg(&save->ldtr, SEG_TYPE_LDT);1200 init_sys_seg(&save->ldtr, SEG_TYPE_LDT);
1201 init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16);1201 init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16);
1202 1202
1203 svm_set_cr4(&svm->vcpu, 0);
1203 svm_set_efer(&svm->vcpu, 0);1204 svm_set_efer(&svm->vcpu, 0);
1204 save->dr6 = 0xffff0ff0;1205 save->dr6 = 0xffff0ff0;
1205 kvm_set_rflags(&svm->vcpu, X86_EFLAGS_FIXED);1206 kvm_set_rflags(&svm->vcpu, X86_EFLAGS_FIXED);
arch/x86/kvm/x86.c+21−1
@@ -2957,6 +2957,11 @@ static void record_steal_time(struct kvm_vcpu *vcpu) · 2956 unmodified lines
2957 struct kvm_host_map map;2957 struct kvm_host_map map;
2958 struct kvm_steal_time *st;2958 struct kvm_steal_time *st;
2959 2959
2960 if (kvm_xen_msr_enabled(vcpu->kvm)) {
2961 kvm_xen_runstate_set_running(vcpu);
2962 return;
2963 }
2964
2960 if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))2965 if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
2961 return;2966 return;
2962 2967
@@ -3756,11 +3761,15 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 793 unmodified lines
3756 case KVM_CAP_ENFORCE_PV_FEATURE_CPUID:3761 case KVM_CAP_ENFORCE_PV_FEATURE_CPUID:
3757 r = 1;3762 r = 1;
3758 break;3763 break;
3764#ifdef CONFIG_KVM_XEN
3759 case KVM_CAP_XEN_HVM:3765 case KVM_CAP_XEN_HVM:
3760 r = KVM_XEN_HVM_CONFIG_HYPERCALL_MSR |3766 r = KVM_XEN_HVM_CONFIG_HYPERCALL_MSR |
3761 KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL |3767 KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL |
3762 KVM_XEN_HVM_CONFIG_SHARED_INFO;3768 KVM_XEN_HVM_CONFIG_SHARED_INFO;
3769 if (sched_info_on())
3770 r |= KVM_XEN_HVM_CONFIG_RUNSTATE;
3763 break;3771 break;
3772#endif
3764 case KVM_CAP_SYNC_REGS:3773 case KVM_CAP_SYNC_REGS:
3765 r = KVM_SYNC_X86_VALID_FIELDS;3774 r = KVM_SYNC_X86_VALID_FIELDS;
3766 break;3775 break;
@@ -4038,7 +4047,11 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) · 271 unmodified lines
4038 if (vcpu->preempted && !vcpu->arch.guest_state_protected)4047 if (vcpu->preempted && !vcpu->arch.guest_state_protected)
4039 vcpu->arch.preempted_in_kernel = !static_call(kvm_x86_get_cpl)(vcpu);4048 vcpu->arch.preempted_in_kernel = !static_call(kvm_x86_get_cpl)(vcpu);
4040 4049
4041 kvm_steal_time_set_preempted(vcpu);4050 if (kvm_xen_msr_enabled(vcpu->kvm))
4051 kvm_xen_runstate_set_preempted(vcpu);
4052 else
4053 kvm_steal_time_set_preempted(vcpu);
4054
4042 static_call(kvm_x86_vcpu_put)(vcpu);4055 static_call(kvm_x86_vcpu_put)(vcpu);
4043 vcpu->arch.last_host_tsc = rdtsc();4056 vcpu->arch.last_host_tsc = rdtsc();
4044 /*4057 /*
@@ -5013,6 +5026,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 968 unmodified lines
5013 case KVM_GET_SUPPORTED_HV_CPUID:5026 case KVM_GET_SUPPORTED_HV_CPUID:
5014 r = kvm_ioctl_get_supported_hv_cpuid(vcpu, argp);5027 r = kvm_ioctl_get_supported_hv_cpuid(vcpu, argp);
5015 break;5028 break;
5029#ifdef CONFIG_KVM_XEN
5016 case KVM_XEN_VCPU_GET_ATTR: {5030 case KVM_XEN_VCPU_GET_ATTR: {
5017 struct kvm_xen_vcpu_attr xva;5031 struct kvm_xen_vcpu_attr xva;
5018 5032
@@ -5033,6 +5047,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 14 unmodified lines
5033 r = kvm_xen_vcpu_set_attr(vcpu, &xva);5047 r = kvm_xen_vcpu_set_attr(vcpu, &xva);
5034 break;5048 break;
5035 }5049 }
5050#endif
5036 default:5051 default:
5037 r = -EINVAL;5052 r = -EINVAL;
5038 }5053 }
@@ -5654,6 +5669,7 @@ set_pit2_out: · 615 unmodified lines
5654 kvm->arch.bsp_vcpu_id = arg;5669 kvm->arch.bsp_vcpu_id = arg;
5655 mutex_unlock(&kvm->lock);5670 mutex_unlock(&kvm->lock);
5656 break;5671 break;
5672#ifdef CONFIG_KVM_XEN
5657 case KVM_XEN_HVM_CONFIG: {5673 case KVM_XEN_HVM_CONFIG: {
5658 struct kvm_xen_hvm_config xhc;5674 struct kvm_xen_hvm_config xhc;
5659 r = -EFAULT;5675 r = -EFAULT;
@@ -5682,6 +5698,7 @@ set_pit2_out: · 22 unmodified lines
5682 r = kvm_xen_hvm_set_attr(kvm, &xha);5698 r = kvm_xen_hvm_set_attr(kvm, &xha);
5683 break;5699 break;
5684 }5700 }
5701#endif
5685 case KVM_SET_CLOCK: {5702 case KVM_SET_CLOCK: {
5686 struct kvm_clock_data user_ns;5703 struct kvm_clock_data user_ns;
5687 u64 now_ns;5704 u64 now_ns;
@@ -8040,7 +8057,10 @@ void kvm_arch_exit(void) · 2352 unmodified lines
8040 kvm_mmu_module_exit();8057 kvm_mmu_module_exit();
8041 free_percpu(user_return_msrs);8058 free_percpu(user_return_msrs);
8042 kmem_cache_destroy(x86_fpu_cache);8059 kmem_cache_destroy(x86_fpu_cache);
8060#ifdef CONFIG_KVM_XEN
8061 static_key_deferred_flush(&kvm_xen_enabled);
8043 WARN_ON(static_branch_unlikely(&kvm_xen_enabled.key));8062 WARN_ON(static_branch_unlikely(&kvm_xen_enabled.key));
8063#endif
8044}8064}
8045 8065
8046static int __kvm_vcpu_halt(struct kvm_vcpu *vcpu, int state, int reason)8066static int __kvm_vcpu_halt(struct kvm_vcpu *vcpu, int state, int reason)
arch/x86/kvm/xen.c+290−0
@@ -11,9 +11,11 @@ · 10 unmodified lines
11#include "hyperv.h"11#include "hyperv.h"
12 12
13#include <linux/kvm_host.h>13#include <linux/kvm_host.h>
14#include <linux/sched/stat.h>
14 15
15#include <trace/events/kvm.h>16#include <trace/events/kvm.h>
16#include <xen/interface/xen.h>17#include <xen/interface/xen.h>
18#include <xen/interface/vcpu.h>
17 19
18#include "trace.h"20#include "trace.h"
19 21
@@ -61,6 +63,132 @@ out: · 41 unmodified lines
61 return ret;63 return ret;
62}64}
63 65
66static void kvm_xen_update_runstate(struct kvm_vcpu *v, int state)
67{
68 struct kvm_vcpu_xen *vx = &v->arch.xen;
69 u64 now = get_kvmclock_ns(v->kvm);
70 u64 delta_ns = now - vx->runstate_entry_time;
71 u64 run_delay = current->sched_info.run_delay;
72
73 if (unlikely(!vx->runstate_entry_time))
74 vx->current_runstate = RUNSTATE_offline;
75
76 /*
77 * Time waiting for the scheduler isn't "stolen" if the
78 * vCPU wasn't running anyway.
79 */
80 if (vx->current_runstate == RUNSTATE_running) {
81 u64 steal_ns = run_delay - vx->last_steal;
82
83 delta_ns -= steal_ns;
84
85 vx->runstate_times[RUNSTATE_runnable] += steal_ns;
86 }
87 vx->last_steal = run_delay;
88
89 vx->runstate_times[vx->current_runstate] += delta_ns;
90 vx->current_runstate = state;
91 vx->runstate_entry_time = now;
92}
93
94void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state)
95{
96 struct kvm_vcpu_xen *vx = &v->arch.xen;
97 uint64_t state_entry_time;
98 unsigned int offset;
99
100 kvm_xen_update_runstate(v, state);
101
102 if (!vx->runstate_set)
103 return;
104
105 BUILD_BUG_ON(sizeof(struct compat_vcpu_runstate_info) != 0x2c);
106
107 offset = offsetof(struct compat_vcpu_runstate_info, state_entry_time);
108#ifdef CONFIG_X86_64
109 /*
110 * The only difference is alignment of uint64_t in 32-bit.
111 * So the first field 'state' is accessed directly using
112 * offsetof() (where its offset happens to be zero), while the
113 * remaining fields which are all uint64_t, start at 'offset'
114 * which we tweak here by adding 4.
115 */
116 BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, state_entry_time) !=
117 offsetof(struct compat_vcpu_runstate_info, state_entry_time) + 4);
118 BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, time) !=
119 offsetof(struct compat_vcpu_runstate_info, time) + 4);
120
121 if (v->kvm->arch.xen.long_mode)
122 offset = offsetof(struct vcpu_runstate_info, state_entry_time);
123#endif
124 /*
125 * First write the updated state_entry_time at the appropriate
126 * location determined by 'offset'.
127 */
128 state_entry_time = vx->runstate_entry_time;
129 state_entry_time |= XEN_RUNSTATE_UPDATE;
130
131 BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->state_entry_time) !=
132 sizeof(state_entry_time));
133 BUILD_BUG_ON(sizeof(((struct compat_vcpu_runstate_info *)0)->state_entry_time) !=
134 sizeof(state_entry_time));
135
136 if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
137 &state_entry_time, offset,
138 sizeof(state_entry_time)))
139 return;
140 smp_wmb();
141
142 /*
143 * Next, write the new runstate. This is in the *same* place
144 * for 32-bit and 64-bit guests, asserted here for paranoia.
145 */
146 BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, state) !=
147 offsetof(struct compat_vcpu_runstate_info, state));
148 BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->state) !=
149 sizeof(vx->current_runstate));
150 BUILD_BUG_ON(sizeof(((struct compat_vcpu_runstate_info *)0)->state) !=
151 sizeof(vx->current_runstate));
152
153 if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
154 &vx->current_runstate,
155 offsetof(struct vcpu_runstate_info, state),
156 sizeof(vx->current_runstate)))
157 return;
158
159 /*
160 * Write the actual runstate times immediately after the
161 * runstate_entry_time.
162 */
163 BUILD_BUG_ON(offsetof(struct vcpu_runstate_info, state_entry_time) !=
164 offsetof(struct vcpu_runstate_info, time) - sizeof(u64));
165 BUILD_BUG_ON(offsetof(struct compat_vcpu_runstate_info, state_entry_time) !=
166 offsetof(struct compat_vcpu_runstate_info, time) - sizeof(u64));
167 BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->time) !=
168 sizeof(((struct compat_vcpu_runstate_info *)0)->time));
169 BUILD_BUG_ON(sizeof(((struct vcpu_runstate_info *)0)->time) !=
170 sizeof(vx->runstate_times));
171
172 if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
173 &vx->runstate_times[0],
174 offset + sizeof(u64),
175 sizeof(vx->runstate_times)))
176 return;
177
178 smp_wmb();
179
180 /*
181 * Finally, clear the XEN_RUNSTATE_UPDATE bit in the guest's
182 * runstate_entry_time field.
183 */
184
185 state_entry_time &= ~XEN_RUNSTATE_UPDATE;
186 if (kvm_write_guest_offset_cached(v->kvm, &v->arch.xen.runstate_cache,
187 &state_entry_time, offset,
188 sizeof(state_entry_time)))
189 return;
190}
191
64int __kvm_xen_has_interrupt(struct kvm_vcpu *v)192int __kvm_xen_has_interrupt(struct kvm_vcpu *v)
65{193{
66 u8 rc = 0;194 u8 rc = 0;
@@ -187,9 +315,12 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) · 120 unmodified lines
187 /* No compat necessary here. */315 /* No compat necessary here. */
188 BUILD_BUG_ON(sizeof(struct vcpu_info) !=316 BUILD_BUG_ON(sizeof(struct vcpu_info) !=
189 sizeof(struct compat_vcpu_info));317 sizeof(struct compat_vcpu_info));
318 BUILD_BUG_ON(offsetof(struct vcpu_info, time) !=
319 offsetof(struct compat_vcpu_info, time));
190 320
191 if (data->u.gpa == GPA_INVALID) {321 if (data->u.gpa == GPA_INVALID) {
192 vcpu->arch.xen.vcpu_info_set = false;322 vcpu->arch.xen.vcpu_info_set = false;
323 r = 0;
193 break;324 break;
194 }325 }
195 326
@@ -206,6 +337,7 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) · 10 unmodified lines
206 case KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO:337 case KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO:
207 if (data->u.gpa == GPA_INVALID) {338 if (data->u.gpa == GPA_INVALID) {
208 vcpu->arch.xen.vcpu_time_info_set = false;339 vcpu->arch.xen.vcpu_time_info_set = false;
340 r = 0;
209 break;341 break;
210 }342 }
211 343
@@ -219,6 +351,121 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) · 7 unmodified lines
219 }351 }
220 break;352 break;
221 353
354 case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR:
355 if (!sched_info_on()) {
356 r = -EOPNOTSUPP;
357 break;
358 }
359 if (data->u.gpa == GPA_INVALID) {
360 vcpu->arch.xen.runstate_set = false;
361 r = 0;
362 break;
363 }
364
365 r = kvm_gfn_to_hva_cache_init(vcpu->kvm,
366 &vcpu->arch.xen.runstate_cache,
367 data->u.gpa,
368 sizeof(struct vcpu_runstate_info));
369 if (!r) {
370 vcpu->arch.xen.runstate_set = true;
371 }
372 break;
373
374 case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT:
375 if (!sched_info_on()) {
376 r = -EOPNOTSUPP;
377 break;
378 }
379 if (data->u.runstate.state > RUNSTATE_offline) {
380 r = -EINVAL;
381 break;
382 }
383
384 kvm_xen_update_runstate(vcpu, data->u.runstate.state);
385 r = 0;
386 break;
387
388 case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA:
389 if (!sched_info_on()) {
390 r = -EOPNOTSUPP;
391 break;
392 }
393 if (data->u.runstate.state > RUNSTATE_offline) {
394 r = -EINVAL;
395 break;
396 }
397 if (data->u.runstate.state_entry_time !=
398 (data->u.runstate.time_running +
399 data->u.runstate.time_runnable +
400 data->u.runstate.time_blocked +
401 data->u.runstate.time_offline)) {
402 r = -EINVAL;
403 break;
404 }
405 if (get_kvmclock_ns(vcpu->kvm) <
406 data->u.runstate.state_entry_time) {
407 r = -EINVAL;
408 break;
409 }
410
411 vcpu->arch.xen.current_runstate = data->u.runstate.state;
412 vcpu->arch.xen.runstate_entry_time =
413 data->u.runstate.state_entry_time;
414 vcpu->arch.xen.runstate_times[RUNSTATE_running] =
415 data->u.runstate.time_running;
416 vcpu->arch.xen.runstate_times[RUNSTATE_runnable] =
417 data->u.runstate.time_runnable;
418 vcpu->arch.xen.runstate_times[RUNSTATE_blocked] =
419 data->u.runstate.time_blocked;
420 vcpu->arch.xen.runstate_times[RUNSTATE_offline] =
421 data->u.runstate.time_offline;
422 vcpu->arch.xen.last_steal = current->sched_info.run_delay;
423 r = 0;
424 break;
425
426 case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST:
427 if (!sched_info_on()) {
428 r = -EOPNOTSUPP;
429 break;
430 }
431 if (data->u.runstate.state > RUNSTATE_offline &&
432 data->u.runstate.state != (u64)-1) {
433 r = -EINVAL;
434 break;
435 }
436 /* The adjustment must add up */
437 if (data->u.runstate.state_entry_time !=
438 (data->u.runstate.time_running +
439 data->u.runstate.time_runnable +
440 data->u.runstate.time_blocked +
441 data->u.runstate.time_offline)) {
442 r = -EINVAL;
443 break;
444 }
445
446 if (get_kvmclock_ns(vcpu->kvm) <
447 (vcpu->arch.xen.runstate_entry_time +
448 data->u.runstate.state_entry_time)) {
449 r = -EINVAL;
450 break;
451 }
452
453 vcpu->arch.xen.runstate_entry_time +=
454 data->u.runstate.state_entry_time;
455 vcpu->arch.xen.runstate_times[RUNSTATE_running] +=
456 data->u.runstate.time_running;
457 vcpu->arch.xen.runstate_times[RUNSTATE_runnable] +=
458 data->u.runstate.time_runnable;
459 vcpu->arch.xen.runstate_times[RUNSTATE_blocked] +=
460 data->u.runstate.time_blocked;
461 vcpu->arch.xen.runstate_times[RUNSTATE_offline] +=
462 data->u.runstate.time_offline;
463
464 if (data->u.runstate.state <= RUNSTATE_offline)
465 kvm_xen_update_runstate(vcpu, data->u.runstate.state);
466 r = 0;
467 break;
468
222 default:469 default:
223 break;470 break;
224 }471 }
@@ -251,6 +498,49 @@ int kvm_xen_vcpu_get_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) · 26 unmodified lines
251 r = 0;498 r = 0;
252 break;499 break;
253 500
501 case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR:
502 if (!sched_info_on()) {
503 r = -EOPNOTSUPP;
504 break;
505 }
506 if (vcpu->arch.xen.runstate_set) {
507 data->u.gpa = vcpu->arch.xen.runstate_cache.gpa;
508 r = 0;
509 }
510 break;
511
512 case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT:
513 if (!sched_info_on()) {
514 r = -EOPNOTSUPP;
515 break;
516 }
517 data->u.runstate.state = vcpu->arch.xen.current_runstate;
518 r = 0;
519 break;
520
521 case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA:
522 if (!sched_info_on()) {
523 r = -EOPNOTSUPP;
524 break;
525 }
526 data->u.runstate.state = vcpu->arch.xen.current_runstate;
527 data->u.runstate.state_entry_time =
528 vcpu->arch.xen.runstate_entry_time;
529 data->u.runstate.time_running =
530 vcpu->arch.xen.runstate_times[RUNSTATE_running];
531 data->u.runstate.time_runnable =
532 vcpu->arch.xen.runstate_times[RUNSTATE_runnable];
533 data->u.runstate.time_blocked =
534 vcpu->arch.xen.runstate_times[RUNSTATE_blocked];
535 data->u.runstate.time_offline =
536 vcpu->arch.xen.runstate_times[RUNSTATE_offline];
537 r = 0;
538 break;
539
540 case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST:
541 r = -EINVAL;
542 break;
543
254 default:544 default:
255 break;545 break;
256 }546 }
arch/x86/kvm/xen.h+62−2
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#ifndef __ARCH_X86_KVM_XEN_H__9#ifndef __ARCH_X86_KVM_XEN_H__
10#define __ARCH_X86_KVM_XEN_H__10#define __ARCH_X86_KVM_XEN_H__
11 11
12#ifdef CONFIG_KVM_XEN
12#include <linux/jump_label_ratelimit.h>13#include <linux/jump_label_ratelimit.h>
13 14
14extern struct static_key_false_deferred kvm_xen_enabled;15extern struct static_key_false_deferred kvm_xen_enabled;
@@ -18,11 +19,16 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) · 3 unmodified lines
18int kvm_xen_vcpu_get_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data);19int kvm_xen_vcpu_get_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data);
19int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data);20int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data);
20int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data);21int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data);
21int kvm_xen_hypercall(struct kvm_vcpu *vcpu);
22int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data);22int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data);
23int kvm_xen_hvm_config(struct kvm *kvm, struct kvm_xen_hvm_config *xhc);23int kvm_xen_hvm_config(struct kvm *kvm, struct kvm_xen_hvm_config *xhc);
24void kvm_xen_destroy_vm(struct kvm *kvm);24void kvm_xen_destroy_vm(struct kvm *kvm);
25 25
26static inline bool kvm_xen_msr_enabled(struct kvm *kvm)
27{
28 return static_branch_unlikely(&kvm_xen_enabled.key) &&
29 kvm->arch.xen_hvm_config.msr;
30}
31
26static inline bool kvm_xen_hypercall_enabled(struct kvm *kvm)32static inline bool kvm_xen_hypercall_enabled(struct kvm *kvm)
27{33{
28 return static_branch_unlikely(&kvm_xen_enabled.key) &&34 return static_branch_unlikely(&kvm_xen_enabled.key) &&
@@ -38,11 +44,59 @@ static inline int kvm_xen_has_interrupt(struct kvm_vcpu *vcpu) · 9 unmodified lines
38 44
39 return 0;45 return 0;
40}46}
47#else
48static inline int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data)
49{
50 return 1;
51}
52
53static inline void kvm_xen_destroy_vm(struct kvm *kvm)
54{
55}
56
57static inline bool kvm_xen_msr_enabled(struct kvm *kvm)
58{
59 return false;
60}
61
62static inline bool kvm_xen_hypercall_enabled(struct kvm *kvm)
63{
64 return false;
65}
66
67static inline int kvm_xen_has_interrupt(struct kvm_vcpu *vcpu)
68{
69 return 0;
70}
71#endif
72
73int kvm_xen_hypercall(struct kvm_vcpu *vcpu);
41 74
42/* 32-bit compatibility definitions, also used natively in 32-bit build */
43#include <asm/pvclock-abi.h>75#include <asm/pvclock-abi.h>
44#include <asm/xen/interface.h>76#include <asm/xen/interface.h>
77#include <xen/interface/vcpu.h>
78
79void kvm_xen_update_runstate_guest(struct kvm_vcpu *vcpu, int state);
45 80
81static inline void kvm_xen_runstate_set_running(struct kvm_vcpu *vcpu)
82{
83 kvm_xen_update_runstate_guest(vcpu, RUNSTATE_running);
84}
85
86static inline void kvm_xen_runstate_set_preempted(struct kvm_vcpu *vcpu)
87{
88 /*
89 * If the vCPU wasn't preempted but took a normal exit for
90 * some reason (hypercalls, I/O, etc.), that is accounted as
91 * still RUNSTATE_running, as the VMM is still operating on
92 * behalf of the vCPU. Only if the VMM does actually block
93 * does it need to enter RUNSTATE_blocked.
94 */
95 if (vcpu->preempted)
96 kvm_xen_update_runstate_guest(vcpu, RUNSTATE_runnable);
97}
98
99/* 32-bit compatibility definitions, also used natively in 32-bit build */
46struct compat_arch_vcpu_info {100struct compat_arch_vcpu_info {
47 unsigned int cr2;101 unsigned int cr2;
48 unsigned int pad[5];102 unsigned int pad[5];
@@ -75,4 +129,10 @@ struct compat_shared_info { · 26 unmodified lines
75 struct compat_arch_shared_info arch;129 struct compat_arch_shared_info arch;
76};130};
77 131
132struct compat_vcpu_runstate_info {
133 int state;
134 uint64_t state_entry_time;
135 uint64_t time[4];
136} __attribute__((packed));
137
78#endif /* __ARCH_X86_KVM_XEN_H__ */138#endif /* __ARCH_X86_KVM_XEN_H__ */
include/uapi/linux/kvm.h+13−0
@@ -1154,6 +1154,7 @@ struct kvm_x86_mce { · 1153 unmodified lines
1154#define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0)1154#define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0)
1155#define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1)1155#define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1)
1156#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)1156#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)
1157#define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3)
1157 1158
1158struct kvm_xen_hvm_config {1159struct kvm_xen_hvm_config {
1159 __u32 flags;1160 __u32 flags;
@@ -1621,12 +1622,24 @@ struct kvm_xen_vcpu_attr { · 461 unmodified lines
1621 union {1622 union {
1622 __u64 gpa;1623 __u64 gpa;
1623 __u64 pad[8];1624 __u64 pad[8];
1625 struct {
1626 __u64 state;
1627 __u64 state_entry_time;
1628 __u64 time_running;
1629 __u64 time_runnable;
1630 __u64 time_blocked;
1631 __u64 time_offline;
1632 } runstate;
1624 } u;1633 } u;
1625};1634};
1626 1635
1627/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */1636/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */
1628#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x01637#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x0
1629#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO 0x11638#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO 0x1
1639#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR 0x2
1640#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3
1641#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4
1642#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5
1630 1643
1631/* Secure Encrypted Virtualization command */1644/* Secure Encrypted Virtualization command */
1632enum sev_cmd_id {1645enum sev_cmd_id {
tools/testing/selftests/kvm/lib/kvm_util.c+4−2
@@ -21,6 +21,8 @@ · 20 unmodified lines
21#define KVM_UTIL_PGS_PER_HUGEPG 51221#define KVM_UTIL_PGS_PER_HUGEPG 512
22#define KVM_UTIL_MIN_PFN 222#define KVM_UTIL_MIN_PFN 2
23 23
24static int vcpu_mmap_sz(void);
25
24/* Aligns x up to the next multiple of size. Size must be a power of 2. */26/* Aligns x up to the next multiple of size. Size must be a power of 2. */
25static void *align(void *x, size_t size)27static void *align(void *x, size_t size)
26{28{
@@ -509,7 +511,7 @@ static void vm_vcpu_rm(struct kvm_vm *vm, struct vcpu *vcpu) · 482 unmodified lines
509 vcpu->dirty_gfns = NULL;511 vcpu->dirty_gfns = NULL;
510 }512 }
511 513
512 ret = munmap(vcpu->state, sizeof(*vcpu->state));514 ret = munmap(vcpu->state, vcpu_mmap_sz());
513 TEST_ASSERT(ret == 0, "munmap of VCPU fd failed, rc: %i "515 TEST_ASSERT(ret == 0, "munmap of VCPU fd failed, rc: %i "
514 "errno: %i", ret, errno);516 "errno: %i", ret, errno);
515 close(vcpu->fd);517 close(vcpu->fd);
@@ -978,7 +980,7 @@ void vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpuid) · 462 unmodified lines
978 TEST_ASSERT(vcpu_mmap_sz() >= sizeof(*vcpu->state), "vcpu mmap size "980 TEST_ASSERT(vcpu_mmap_sz() >= sizeof(*vcpu->state), "vcpu mmap size "
979 "smaller than expected, vcpu_mmap_sz: %i expected_min: %zi",981 "smaller than expected, vcpu_mmap_sz: %i expected_min: %zi",
980 vcpu_mmap_sz(), sizeof(*vcpu->state));982 vcpu_mmap_sz(), sizeof(*vcpu->state));
981 vcpu->state = (struct kvm_run *) mmap(NULL, sizeof(*vcpu->state),983 vcpu->state = (struct kvm_run *) mmap(NULL, vcpu_mmap_sz(),
982 PROT_READ | PROT_WRITE, MAP_SHARED, vcpu->fd, 0);984 PROT_READ | PROT_WRITE, MAP_SHARED, vcpu->fd, 0);
983 TEST_ASSERT(vcpu->state != MAP_FAILED, "mmap vcpu_state failed, "985 TEST_ASSERT(vcpu->state != MAP_FAILED, "mmap vcpu_state failed, "
984 "vcpu id: %u errno: %i", vcpuid, errno);986 "vcpu id: %u errno: %i", vcpuid, errno);
tools/testing/selftests/kvm/x86_64/xen_shinfo_test.c+156−3
@@ -13,19 +13,27 @@ · 12 unmodified lines
13 13
14#include <stdint.h>14#include <stdint.h>
15#include <time.h>15#include <time.h>
16#include <sched.h>
17#include <sys/syscall.h>
16 18
17#define VCPU_ID 519#define VCPU_ID 5
18 20
21#define SHINFO_REGION_GVA 0xc0000000ULL
19#define SHINFO_REGION_GPA 0xc0000000ULL22#define SHINFO_REGION_GPA 0xc0000000ULL
20#define SHINFO_REGION_SLOT 1023#define SHINFO_REGION_SLOT 10
21#define PAGE_SIZE 409624#define PAGE_SIZE 4096
22 25
23#define PVTIME_ADDR (SHINFO_REGION_GPA + PAGE_SIZE)26#define PVTIME_ADDR (SHINFO_REGION_GPA + PAGE_SIZE)
27#define RUNSTATE_ADDR (SHINFO_REGION_GPA + PAGE_SIZE + 0x20)
28
29#define RUNSTATE_VADDR (SHINFO_REGION_GVA + PAGE_SIZE + 0x20)
24 30
25static struct kvm_vm *vm;31static struct kvm_vm *vm;
26 32
27#define XEN_HYPERCALL_MSR 0x4000000033#define XEN_HYPERCALL_MSR 0x40000000
28 34
35#define MIN_STEAL_TIME 50000
36
29struct pvclock_vcpu_time_info {37struct pvclock_vcpu_time_info {
30 u32 version;38 u32 version;
31 u32 pad0;39 u32 pad0;
@@ -43,11 +51,67 @@ struct pvclock_wall_clock { · 11 unmodified lines
43 u32 nsec;51 u32 nsec;
44} __attribute__((__packed__));52} __attribute__((__packed__));
45 53
54struct vcpu_runstate_info {
55 uint32_t state;
56 uint64_t state_entry_time;
57 uint64_t time[4];
58};
59
60#define RUNSTATE_running 0
61#define RUNSTATE_runnable 1
62#define RUNSTATE_blocked 2
63#define RUNSTATE_offline 3
64
46static void guest_code(void)65static void guest_code(void)
47{66{
67 struct vcpu_runstate_info *rs = (void *)RUNSTATE_VADDR;
68
69 /* Test having the host set runstates manually */
70 GUEST_SYNC(RUNSTATE_runnable);
71 GUEST_ASSERT(rs->time[RUNSTATE_runnable] != 0);
72 GUEST_ASSERT(rs->state == 0);
73
74 GUEST_SYNC(RUNSTATE_blocked);
75 GUEST_ASSERT(rs->time[RUNSTATE_blocked] != 0);
76 GUEST_ASSERT(rs->state == 0);
77
78 GUEST_SYNC(RUNSTATE_offline);
79 GUEST_ASSERT(rs->time[RUNSTATE_offline] != 0);
80 GUEST_ASSERT(rs->state == 0);
81
82 /* Test runstate time adjust */
83 GUEST_SYNC(4);
84 GUEST_ASSERT(rs->time[RUNSTATE_blocked] == 0x5a);
85 GUEST_ASSERT(rs->time[RUNSTATE_offline] == 0x6b6b);
86
87 /* Test runstate time set */
88 GUEST_SYNC(5);
89 GUEST_ASSERT(rs->state_entry_time >= 0x8000);
90 GUEST_ASSERT(rs->time[RUNSTATE_runnable] == 0);
91 GUEST_ASSERT(rs->time[RUNSTATE_blocked] == 0x6b6b);
92 GUEST_ASSERT(rs->time[RUNSTATE_offline] == 0x5a);
93
94 /* sched_yield() should result in some 'runnable' time */
95 GUEST_SYNC(6);
96 GUEST_ASSERT(rs->time[RUNSTATE_runnable] >= MIN_STEAL_TIME);
97
48 GUEST_DONE();98 GUEST_DONE();
49}99}
50 100
101static long get_run_delay(void)
102{
103 char path[64];
104 long val[2];
105 FILE *fp;
106
107 sprintf(path, "/proc/%ld/schedstat", syscall(SYS_gettid));
108 fp = fopen(path, "r");
109 fscanf(fp, "%ld %ld ", &val[0], &val[1]);
110 fclose(fp);
111
112 return val[1];
113}
114
51static int cmp_timespec(struct timespec *a, struct timespec *b)115static int cmp_timespec(struct timespec *a, struct timespec *b)
52{116{
53 if (a->tv_sec > b->tv_sec)117 if (a->tv_sec > b->tv_sec)
@@ -66,12 +130,14 @@ int main(int argc, char *argv[]) · 12 unmodified lines
66{130{
67 struct timespec min_ts, max_ts, vm_ts;131 struct timespec min_ts, max_ts, vm_ts;
68 132
69 if (!(kvm_check_cap(KVM_CAP_XEN_HVM) &133 int xen_caps = kvm_check_cap(KVM_CAP_XEN_HVM);
70 KVM_XEN_HVM_CONFIG_SHARED_INFO) ) {134 if (!(xen_caps & KVM_XEN_HVM_CONFIG_SHARED_INFO) ) {
71 print_skip("KVM_XEN_HVM_CONFIG_SHARED_INFO not available");135 print_skip("KVM_XEN_HVM_CONFIG_SHARED_INFO not available");
72 exit(KSFT_SKIP);136 exit(KSFT_SKIP);
73 }137 }
74 138
139 bool do_runstate_tests = !!(xen_caps & KVM_XEN_HVM_CONFIG_RUNSTATE);
140
75 clock_gettime(CLOCK_REALTIME, &min_ts);141 clock_gettime(CLOCK_REALTIME, &min_ts);
76 142
77 vm = vm_create_default(VCPU_ID, 0, (void *) guest_code);143 vm = vm_create_default(VCPU_ID, 0, (void *) guest_code);
@@ -80,6 +146,7 @@ int main(int argc, char *argv[]) · 2 unmodified lines
80 /* Map a region for the shared_info page */146 /* Map a region for the shared_info page */
81 vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,147 vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
82 SHINFO_REGION_GPA, SHINFO_REGION_SLOT, 2, 0);148 SHINFO_REGION_GPA, SHINFO_REGION_SLOT, 2, 0);
149 virt_map(vm, SHINFO_REGION_GVA, SHINFO_REGION_GPA, 2, 0);
83 150
84 struct kvm_xen_hvm_config hvmc = {151 struct kvm_xen_hvm_config hvmc = {
85 .flags = KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL,152 .flags = KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL,
@@ -111,6 +178,17 @@ int main(int argc, char *argv[]) · 25 unmodified lines
111 };178 };
112 vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_SET_ATTR, &pvclock);179 vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_SET_ATTR, &pvclock);
113 180
181 if (do_runstate_tests) {
182 struct kvm_xen_vcpu_attr st = {
183 .type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR,
184 .u.gpa = RUNSTATE_ADDR,
185 };
186 vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_SET_ATTR, &st);
187 }
188
189 struct vcpu_runstate_info *rs = addr_gpa2hva(vm, RUNSTATE_ADDR);;
190 rs->state = 0x5a;
191
114 for (;;) {192 for (;;) {
115 volatile struct kvm_run *run = vcpu_state(vm, VCPU_ID);193 volatile struct kvm_run *run = vcpu_state(vm, VCPU_ID);
116 struct ucall uc;194 struct ucall uc;
@@ -126,8 +204,56 @@ int main(int argc, char *argv[]) · 9 unmodified lines
126 case UCALL_ABORT:204 case UCALL_ABORT:
127 TEST_FAIL("%s", (const char *)uc.args[0]);205 TEST_FAIL("%s", (const char *)uc.args[0]);
128 /* NOT REACHED */206 /* NOT REACHED */
129 case UCALL_SYNC:207 case UCALL_SYNC: {
208 struct kvm_xen_vcpu_attr rst;
209 long rundelay;
210
211 /* If no runstate support, bail out early */
212 if (!do_runstate_tests)
213 goto done;
214
215 TEST_ASSERT(rs->state_entry_time == rs->time[0] +
216 rs->time[1] + rs->time[2] + rs->time[3],
217 "runstate times don't add up");
218
219 switch (uc.args[1]) {
220 case RUNSTATE_running...RUNSTATE_offline:
221 rst.type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT;
222 rst.u.runstate.state = uc.args[1];
223 vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_SET_ATTR, &rst);
224 break;
225 case 4:
226 rst.type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST;
227 memset(&rst.u, 0, sizeof(rst.u));
228 rst.u.runstate.state = (uint64_t)-1;
229 rst.u.runstate.time_blocked =
230 0x5a - rs->time[RUNSTATE_blocked];
231 rst.u.runstate.time_offline =
232 0x6b6b - rs->time[RUNSTATE_offline];
233 rst.u.runstate.time_runnable = -rst.u.runstate.time_blocked -
234 rst.u.runstate.time_offline;
235 vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_SET_ATTR, &rst);
236 break;
237
238 case 5:
239 rst.type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA;
240 memset(&rst.u, 0, sizeof(rst.u));
241 rst.u.runstate.state = RUNSTATE_running;
242 rst.u.runstate.state_entry_time = 0x6b6b + 0x5a;
243 rst.u.runstate.time_blocked = 0x6b6b;
244 rst.u.runstate.time_offline = 0x5a;
245 vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_SET_ATTR, &rst);
246 break;
247 case 6:
248 /* Yield until scheduler delay exceeds target */
249 rundelay = get_run_delay() + MIN_STEAL_TIME;
250 do {
251 sched_yield();
252 } while (get_run_delay() < rundelay);
253 break;
254 }
130 break;255 break;
256 }
131 case UCALL_DONE:257 case UCALL_DONE:
132 goto done;258 goto done;
133 default:259 default:
@@ -162,6 +288,33 @@ int main(int argc, char *argv[]) · 28 unmodified lines
162 TEST_ASSERT(ti2->version && !(ti2->version & 1),288 TEST_ASSERT(ti2->version && !(ti2->version & 1),
163 "Bad time_info version %x", ti->version);289 "Bad time_info version %x", ti->version);
164 290
291 if (do_runstate_tests) {
292 /*
293 * Fetch runstate and check sanity. Strictly speaking in the
294 * general case we might not expect the numbers to be identical
295 * but in this case we know we aren't running the vCPU any more.
296 */
297 struct kvm_xen_vcpu_attr rst = {
298 .type = KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA,
299 };
300 vcpu_ioctl(vm, VCPU_ID, KVM_XEN_VCPU_GET_ATTR, &rst);
301
302 TEST_ASSERT(rs->state == rst.u.runstate.state, "Runstate mismatch");
303 TEST_ASSERT(rs->state_entry_time == rst.u.runstate.state_entry_time,
304 "State entry time mismatch");
305 TEST_ASSERT(rs->time[RUNSTATE_running] == rst.u.runstate.time_running,
306 "Running time mismatch");
307 TEST_ASSERT(rs->time[RUNSTATE_runnable] == rst.u.runstate.time_runnable,
308 "Runnable time mismatch");
309 TEST_ASSERT(rs->time[RUNSTATE_blocked] == rst.u.runstate.time_blocked,
310 "Blocked time mismatch");
311 TEST_ASSERT(rs->time[RUNSTATE_offline] == rst.u.runstate.time_offline,
312 "Offline time mismatch");
313
314 TEST_ASSERT(rs->state_entry_time == rs->time[0] +
315 rs->time[1] + rs->time[2] + rs->time[3],
316 "runstate times don't add up");
317 }
165 kvm_vm_free(vm);318 kvm_vm_free(vm);
166 return 0;319 return 0;
167}320}