Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1233849 > unrolled thread
| Started by | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| First post | 2015-09-28 07:40 +0200 |
| Last post | 2015-09-29 06:10 +0200 |
| Articles | 20 on this page of 24 — 5 participants |
Back to article view | Back to linux.kernel
[PATCH 00/12] KVM: x86: add support for VMX TSC scaling Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:40 +0200
[PATCH 07/12] KVM: x86: Move TSC scaling logic out of call-back read_l1_tsc() Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:40 +0200
[PATCH 11/12] KVM: VMX: Use a scaled host TSC for guest readings of MSR_IA32_TSC Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:40 +0200
[PATCH 06/12] KVM: x86: Move TSC scaling logic out of call-back adjust_tsc_offset() Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:40 +0200
Re: [PATCH 06/12] KVM: x86: Move TSC scaling logic out of call-back adjust_tsc_offset() Paolo Bonzini <pbonzini@redhat.com> - 2015-09-28 22:20 +0200
Re: [PATCH 06/12] KVM: x86: Move TSC scaling logic out of call-back adjust_tsc_offset() Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-29 03:50 +0200
[PATCH 01/12] KVM: x86: Collect information for setting TSC scaling ratio Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:40 +0200
Re: [PATCH 01/12] KVM: x86: Collect information for setting TSC scaling ratio Eric Northup <digitaleric@google.com> - 2015-09-29 05:30 +0200
Re: [PATCH 01/12] KVM: x86: Collect information for setting TSC scaling ratio Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-29 06:10 +0200
[PATCH 02/12] KVM: x86: Add a common TSC scaling ratio field in kvm_vcpu_arch Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:50 +0200
Re: [PATCH 02/12] KVM: x86: Add a common TSC scaling ratio field in kvm_vcpu_arch Radim Krčmář <rkrcmar@redhat.com> - 2015-10-05 21:30 +0200
[PATCH 08/12] KVM: x86: Use the correct vcpu's TSC rate to compute time scale Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:50 +0200
Re: [PATCH 08/12] KVM: x86: Use the correct vcpu's TSC rate to compute time scale Radim Krčmář <rkrcmar@redhat.com> - 2015-10-05 22:20 +0200
[PATCH 05/12] KVM: x86: Replace call-back compute_tsc_offset() with a common function Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:50 +0200
[PATCH 03/12] KVM: x86: Add a common TSC scaling function Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:50 +0200
Re: [PATCH 03/12] KVM: x86: Add a common TSC scaling function Paolo Bonzini <pbonzini@redhat.com> - 2015-09-28 22:20 +0200
Re: [PATCH 03/12] KVM: x86: Add a common TSC scaling function Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-29 04:00 +0200
[PATCH 10/12] KVM: VMX: Setup TSC scaling ratio when a vcpu is loaded Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:50 +0200
[PATCH 04/12] KVM: x86: Replace call-back set_tsc_khz() with a common function Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-28 07:50 +0200
Re: [PATCH 04/12] KVM: x86: Replace call-back set_tsc_khz() with a common function Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-29 05:50 +0200
Re: [PATCH 04/12] KVM: x86: Replace call-back set_tsc_khz() with a common function Radim Krčmář <rkrcmar@redhat.com> - 2015-10-05 22:00 +0200
Re: [PATCH 04/12] KVM: x86: Replace call-back set_tsc_khz() with a common function David Matlack <dmatlack@google.com> - 2015-10-05 22:50 +0200
Re: [PATCH 00/12] KVM: x86: add support for VMX TSC scaling Haozhong Zhang <haozhong.zhang@intel.com> - 2015-09-29 06:10 +0200
Re: [PATCH 00/12] KVM: x86: add support for VMX TSC scaling Eric Northup <digitaleric@google.com> - 2015-09-29 06:10 +0200
Page 1 of 2 [1] 2 Next page →
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:40 +0200 |
| Subject | [PATCH 00/12] KVM: x86: add support for VMX TSC scaling |
| Message-ID | <qdzkm-4Rn-5@gated-at.bofh.it> |
This patchset adds support for VMX TSC scaling feature which is available on Intel Skylake CPU. The specification of VMX TSC scaling can be found at http://www.intel.com/content/www/us/en/processors/timestamp-counter-scaling-virtualization-white-paper.html VMX TSC scaling allows guest TSC which is read by guest rdtsc(p) instructions increases in a rate that is customized by the hypervisor and can be different than the host TSC rate. Basically, VMX TSC scaling adds a 64-bit field called TSC multiplier in VMCS so that, if VMX TSC scaling is enabled, TSC read by guest rdtsc(p) instructions will be calculated by the following formula: guest EDX:EAX = (Host TSC * TSC multiplier) >> 48 + VMX TSC Offset where, Host TSC = Host MSR_IA32_TSC + Host MSR_IA32_TSC_ADJUST. This patchset, when cooperating with another QEMU patchset (sent in another email "target-i386: save/restore vcpu's TSC rate during migration"), allows guest programs observe a consistent TSC rate even though they are migrated among machines with different host TSC rates. VMX TSC scaling shares some common logics with SVM TSC scaling which is already supported by KVM. Patch 1 ~ 8 move those common logics from SVM code to the common code. Upon them, patch 9 ~ 12 add VMX-specific support for VMX TSC scaling. Haozhong Zhang (12): KVM: x86: Collect information for setting TSC scaling ratio KVM: x86: Add a common TSC scaling ratio field in kvm_vcpu_arch KVM: x86: Add a common TSC scaling function KVM: x86: Replace call-back set_tsc_khz() with a common function KVM: x86: Replace call-back compute_tsc_offset() with a common function KVM: x86: Move TSC scaling logic out of call-back adjust_tsc_offset() KVM: x86: Move TSC scaling logic out of call-back read_l1_tsc() KVM: x86: Use the correct vcpu's TSC rate to compute time scale KVM: VMX: Enable and initialize VMX TSC scaling KVM: VMX: Setup TSC scaling ratio when a vcpu is loaded KVM: VMX: Use a scaled host TSC for guest readings of MSR_IA32_TSC KVM: VMX: Dump TSC multiplier in dump_vmcs() arch/x86/include/asm/kvm_host.h | 24 +++---- arch/x86/include/asm/vmx.h | 4 +- arch/x86/kvm/lapic.c | 5 +- arch/x86/kvm/svm.c | 113 +++-------------------------- arch/x86/kvm/vmx.c | 60 ++++++++-------- arch/x86/kvm/x86.c | 154 +++++++++++++++++++++++++++++++++++++--- include/linux/kvm_host.h | 21 +++++- 7 files changed, 221 insertions(+), 160 deletions(-) -- 2.4.8 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:40 +0200 |
| Subject | [PATCH 07/12] KVM: x86: Move TSC scaling logic out of call-back read_l1_tsc() |
| Message-ID | <qdzkm-4Rn-7@gated-at.bofh.it> |
| In reply to | #1233849 |
Both VMX and SVM scales the host TSC in the same way in call-back
read_l1_tsc(), so this patch moves the scaling logic from call-back
read_l1_tsc() to a common function kvm_read_l1_tsc().
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
arch/x86/kvm/lapic.c | 5 ++---
arch/x86/kvm/svm.c | 3 +--
arch/x86/kvm/x86.c | 11 ++++++++---
include/linux/kvm_host.h | 2 ++
4 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 8d9013c..b3bb4c9 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1,4 +1,3 @@
-
/*
* Local APIC virtualization
*
@@ -1172,7 +1171,7 @@ void wait_lapic_expire(struct kvm_vcpu *vcpu)
tsc_deadline = apic->lapic_timer.expired_tscdeadline;
apic->lapic_timer.expired_tscdeadline = 0;
- guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu, rdtsc());
+ guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
trace_kvm_wait_lapic_expire(vcpu->vcpu_id, guest_tsc - tsc_deadline);
/* __delay is delay_tsc whenever the hardware has TSC, thus always. */
@@ -1240,7 +1239,7 @@ static void start_apic_timer(struct kvm_lapic *apic)
local_irq_save(flags);
now = apic->lapic_timer.timer.base->get_time();
- guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu, rdtsc());
+ guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
if (likely(tscdeadline > guest_tsc)) {
ns = (tscdeadline - guest_tsc) * 1000000ULL;
do_div(ns, this_tsc_khz);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 239263f3..32ebe76 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3075,8 +3075,7 @@ static int cr8_write_interception(struct vcpu_svm *svm)
static u64 svm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
{
struct vmcb *vmcb = get_host_vmcb(to_svm(vcpu));
- return vmcb->control.tsc_offset +
- kvm_scale_tsc(vcpu, host_tsc);
+ return vmcb->control.tsc_offset + host_tsc;
}
static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7c372ad..d404a7e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1427,6 +1427,12 @@ static u64 kvm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
return target_tsc - tsc;
}
+u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
+{
+ return kvm_x86_ops->read_l1_tsc(vcpu, kvm_scale_tsc(vcpu, host_tsc));
+}
+EXPORT_SYMBOL_GPL(kvm_read_l1_tsc);
+
void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
{
struct kvm *kvm = vcpu->kvm;
@@ -1750,7 +1756,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
kernel_ns = get_kernel_ns();
}
- tsc_timestamp = kvm_x86_ops->read_l1_tsc(v, host_tsc);
+ tsc_timestamp = kvm_read_l1_tsc(v, host_tsc);
/*
* We may have to catch up the TSC to match elapsed wall clock
@@ -6493,8 +6499,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
if (hw_breakpoint_active())
hw_breakpoint_restore();
- vcpu->arch.last_guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu,
- rdtsc());
+ vcpu->arch.last_guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc());
vcpu->mode = OUTSIDE_GUEST_MODE;
smp_wmb();
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 2a21845..75ecb7c 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1146,6 +1146,8 @@ static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
#endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc);
+u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc);
+
extern struct kvm_x86_ops *kvm_x86_ops;
static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
--
2.4.8
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:40 +0200 |
| Subject | [PATCH 11/12] KVM: VMX: Use a scaled host TSC for guest readings of MSR_IA32_TSC |
| Message-ID | <qdzkm-4Rn-17@gated-at.bofh.it> |
| In reply to | #1233849 |
This patch makes kvm-intel to return a scaled host TSC plus the TSC
offset when handling guest readings to MSR_IA32_TSC.
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
arch/x86/kvm/vmx.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index e282eb8..d0a2928 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2245,15 +2245,15 @@ static void setup_msrs(struct vcpu_vmx *vmx)
/*
* reads and returns guest's timestamp counter "register"
- * guest_tsc = host_tsc + tsc_offset -- 21.3
+ * guest_tsc = (host_tsc * tsc multiplier) >> 48 + tsc_offset
*/
-static u64 guest_read_tsc(void)
+static u64 guest_read_tsc(struct kvm_vcpu *vcpu)
{
u64 host_tsc, tsc_offset;
host_tsc = rdtsc();
tsc_offset = vmcs_read64(TSC_OFFSET);
- return host_tsc + tsc_offset;
+ return kvm_scale_tsc(vcpu, host_tsc) + tsc_offset;
}
/*
@@ -2636,7 +2636,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_EFER:
return kvm_get_msr_common(vcpu, msr_info);
case MSR_IA32_TSC:
- msr_info->data = guest_read_tsc();
+ msr_info->data = guest_read_tsc(vcpu);
break;
case MSR_IA32_SYSENTER_CS:
msr_info->data = vmcs_read32(GUEST_SYSENTER_CS);
--
2.4.8
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:40 +0200 |
| Subject | [PATCH 06/12] KVM: x86: Move TSC scaling logic out of call-back adjust_tsc_offset() |
| Message-ID | <qdzkm-4Rn-19@gated-at.bofh.it> |
| In reply to | #1233849 |
For both VMX and SVM, if the 2nd argument of call-back
adjust_tsc_offset() is the host TSC, then adjust_tsc_offset() will scale
it first. This patch moves this common TSC scaling logic to its caller
adjust_tsc_offset_host().
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
arch/x86/include/asm/kvm_host.h | 13 -------------
arch/x86/kvm/svm.c | 6 ------
include/linux/kvm_host.h | 15 +++++++++++++++
3 files changed, 15 insertions(+), 19 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 0bbb2a7..67b4a96 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -895,19 +895,6 @@ struct kvm_arch_async_pf {
bool direct_map;
};
-extern struct kvm_x86_ops *kvm_x86_ops;
-
-static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
- s64 adjustment)
-{
- kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, false);
-}
-
-static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
-{
- kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, true);
-}
-
int kvm_mmu_module_init(void);
void kvm_mmu_module_exit(void);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index c49cd28..239263f3 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1045,12 +1045,6 @@ static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool ho
{
struct vcpu_svm *svm = to_svm(vcpu);
- if (host) {
- if (vcpu->arch.tsc_scaling_ratio != TSC_RATIO_DEFAULT)
- WARN_ON(adjustment < 0);
- adjustment = kvm_scale_tsc(vcpu, (u64)adjustment);
- }
-
svm->vmcb->control.tsc_offset += adjustment;
if (is_guest_mode(vcpu))
svm->nested.hsave->control.tsc_offset += adjustment;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 3c43e3e..2a21845 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1146,5 +1146,20 @@ static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
#endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc);
+extern struct kvm_x86_ops *kvm_x86_ops;
+
+static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
+ s64 adjustment)
+{
+ kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, false);
+}
+
+static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
+{
+ if (vcpu->arch.tsc_scaling_ratio != kvm_default_tsc_scaling_ratio)
+ WARN_ON(adjustment < 0);
+ adjustment = kvm_scale_tsc(vcpu, (u64) adjustment);
+ kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, true);
+}
#endif
--
2.4.8
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2015-09-28 22:20 +0200 |
| Subject | Re: [PATCH 06/12] KVM: x86: Move TSC scaling logic out of call-back adjust_tsc_offset() |
| Message-ID | <qdN3Y-1rA-11@gated-at.bofh.it> |
| In reply to | #1233854 |
On 28/09/2015 07:38, Haozhong Zhang wrote:
> +
> +static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
> + s64 adjustment)
> +{
> + kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, false);
> +}
> +
> +static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
> +{
> + if (vcpu->arch.tsc_scaling_ratio != kvm_default_tsc_scaling_ratio)
> + WARN_ON(adjustment < 0);
> + adjustment = kvm_scale_tsc(vcpu, (u64) adjustment);
> + kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, true);
> +}
You can remove the final argument to the callback (and possibly change
the callback's name to adjust_tsc_offset_guest), because it is now unused.
Paolo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-29 03:50 +0200 |
| Subject | Re: [PATCH 06/12] KVM: x86: Move TSC scaling logic out of call-back adjust_tsc_offset() |
| Message-ID | <qdSdj-kl-5@gated-at.bofh.it> |
| In reply to | #1234416 |
On Mon, Sep 28, 2015 at 10:14:19PM +0200, Paolo Bonzini wrote:
>
>
> On 28/09/2015 07:38, Haozhong Zhang wrote:
> > +
> > +static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
> > + s64 adjustment)
> > +{
> > + kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, false);
> > +}
> > +
> > +static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
> > +{
> > + if (vcpu->arch.tsc_scaling_ratio != kvm_default_tsc_scaling_ratio)
> > + WARN_ON(adjustment < 0);
> > + adjustment = kvm_scale_tsc(vcpu, (u64) adjustment);
> > + kvm_x86_ops->adjust_tsc_offset(vcpu, adjustment, true);
> > +}
>
> You can remove the final argument to the callback (and possibly change
> the callback's name to adjust_tsc_offset_guest), because it is now unused.
>
> Paolo
Thanks! will do it.
- Haozhong
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:40 +0200 |
| Subject | [PATCH 01/12] KVM: x86: Collect information for setting TSC scaling ratio |
| Message-ID | <qdzkm-4Rn-25@gated-at.bofh.it> |
| In reply to | #1233849 |
The number of bits of the fractional part of the 64-bit TSC scaling
ratio in VMX and SVM is different. This patch makes the architecture
code to collect the number of fractional bits and other related
information into variables that can be accessed in the common code.
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
arch/x86/include/asm/kvm_host.h | 8 ++++++++
arch/x86/kvm/svm.c | 5 +++++
arch/x86/kvm/x86.c | 8 ++++++++
3 files changed, 21 insertions(+)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 2beee03..5b9b86e 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -965,6 +965,14 @@ extern bool kvm_has_tsc_control;
extern u32 kvm_min_guest_tsc_khz;
/* maximum supported tsc_khz for guests */
extern u32 kvm_max_guest_tsc_khz;
+/* number of bits of the fractional part of the TSC scaling ratio */
+extern u8 kvm_tsc_scaling_ratio_frac_bits;
+/* reserved bits of TSC scaling ratio (SBZ) */
+extern u64 kvm_tsc_scaling_ratio_rsvd;
+/* default TSC scaling ratio (= 1.0) */
+extern u64 kvm_default_tsc_scaling_ratio;
+/* maximum allowed value of TSC scaling ratio */
+extern u64 kvm_max_tsc_scaling_ratio;
enum emulation_result {
EMULATE_DONE, /* no further processing */
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 94b7d15..eff7db7 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -963,7 +963,12 @@ static __init int svm_hardware_setup(void)
max = min(0x7fffffffULL, __scale_tsc(tsc_khz, TSC_RATIO_MAX));
kvm_max_guest_tsc_khz = max;
+
+ kvm_max_tsc_scaling_ratio = TSC_RATIO_MAX;
+ kvm_tsc_scaling_ratio_frac_bits = 32;
+ kvm_tsc_scaling_ratio_rsvd = TSC_RATIO_RSVD;
}
+ kvm_default_tsc_scaling_ratio = TSC_RATIO_DEFAULT;
if (nested) {
printk(KERN_INFO "kvm: Nested Virtualization enabled\n");
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 991466b..f888225 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -106,6 +106,14 @@ bool kvm_has_tsc_control;
EXPORT_SYMBOL_GPL(kvm_has_tsc_control);
u32 kvm_max_guest_tsc_khz;
EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);
+u8 kvm_tsc_scaling_ratio_frac_bits;
+EXPORT_SYMBOL_GPL(kvm_tsc_scaling_ratio_frac_bits);
+u64 kvm_tsc_scaling_ratio_rsvd;
+EXPORT_SYMBOL_GPL(kvm_tsc_scaling_ratio_rsvd);
+u64 kvm_default_tsc_scaling_ratio;
+EXPORT_SYMBOL_GPL(kvm_default_tsc_scaling_ratio);
+u64 kvm_max_tsc_scaling_ratio;
+EXPORT_SYMBOL_GPL(kvm_max_tsc_scaling_ratio);
/* tsc tolerance in parts per million - default to 1/2 of the NTP threshold */
static u32 tsc_tolerance_ppm = 250;
--
2.4.8
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Eric Northup <digitaleric@google.com> |
|---|---|
| Date | 2015-09-29 05:30 +0200 |
| Subject | Re: [PATCH 01/12] KVM: x86: Collect information for setting TSC scaling ratio |
| Message-ID | <qdTM6-2Kw-5@gated-at.bofh.it> |
| In reply to | #1233856 |
On Sun, Sep 27, 2015 at 10:38 PM, Haozhong Zhang
<haozhong.zhang@intel.com> wrote:
>
> The number of bits of the fractional part of the 64-bit TSC scaling
> ratio in VMX and SVM is different. This patch makes the architecture
> code to collect the number of fractional bits and other related
> information into variables that can be accessed in the common code.
>
> Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
> ---
> arch/x86/include/asm/kvm_host.h | 8 ++++++++
> arch/x86/kvm/svm.c | 5 +++++
> arch/x86/kvm/x86.c | 8 ++++++++
> 3 files changed, 21 insertions(+)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 2beee03..5b9b86e 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -965,6 +965,14 @@ extern bool kvm_has_tsc_control;
> extern u32 kvm_min_guest_tsc_khz;
> /* maximum supported tsc_khz for guests */
> extern u32 kvm_max_guest_tsc_khz;
> +/* number of bits of the fractional part of the TSC scaling ratio */
> +extern u8 kvm_tsc_scaling_ratio_frac_bits;
> +/* reserved bits of TSC scaling ratio (SBZ) */
> +extern u64 kvm_tsc_scaling_ratio_rsvd;
> +/* default TSC scaling ratio (= 1.0) */
> +extern u64 kvm_default_tsc_scaling_ratio;
> +/* maximum allowed value of TSC scaling ratio */
> +extern u64 kvm_max_tsc_scaling_ratio;
Do we need all 3 of kvm_max_guest_tsc_khz, kvm_max_tsc_scaling_ratio,
and kvm_tsc_scaling_ratio_rsvd (since only SVM has reserved bits - and
just for complaining if the high bits are set, which can already be
expressed by max_tsc_scaling ratio)
kvm_max_tsc_scaling_ratio seems to be write-only.
>
> enum emulation_result {
> EMULATE_DONE, /* no further processing */
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index 94b7d15..eff7db7 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -963,7 +963,12 @@ static __init int svm_hardware_setup(void)
> max = min(0x7fffffffULL, __scale_tsc(tsc_khz, TSC_RATIO_MAX));
>
> kvm_max_guest_tsc_khz = max;
> +
> + kvm_max_tsc_scaling_ratio = TSC_RATIO_MAX;
> + kvm_tsc_scaling_ratio_frac_bits = 32;
> + kvm_tsc_scaling_ratio_rsvd = TSC_RATIO_RSVD;
> }
> + kvm_default_tsc_scaling_ratio = TSC_RATIO_DEFAULT;
>
> if (nested) {
> printk(KERN_INFO "kvm: Nested Virtualization enabled\n");
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 991466b..f888225 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -106,6 +106,14 @@ bool kvm_has_tsc_control;
> EXPORT_SYMBOL_GPL(kvm_has_tsc_control);
> u32 kvm_max_guest_tsc_khz;
> EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);
> +u8 kvm_tsc_scaling_ratio_frac_bits;
> +EXPORT_SYMBOL_GPL(kvm_tsc_scaling_ratio_frac_bits);
> +u64 kvm_tsc_scaling_ratio_rsvd;
> +EXPORT_SYMBOL_GPL(kvm_tsc_scaling_ratio_rsvd);
> +u64 kvm_default_tsc_scaling_ratio;
> +EXPORT_SYMBOL_GPL(kvm_default_tsc_scaling_ratio);
> +u64 kvm_max_tsc_scaling_ratio;
> +EXPORT_SYMBOL_GPL(kvm_max_tsc_scaling_ratio);
>
> /* tsc tolerance in parts per million - default to 1/2 of the NTP threshold */
> static u32 tsc_tolerance_ppm = 250;
> --
> 2.4.8
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-29 06:10 +0200 |
| Subject | Re: [PATCH 01/12] KVM: x86: Collect information for setting TSC scaling ratio |
| Message-ID | <qdUoO-3IA-7@gated-at.bofh.it> |
| In reply to | #1234671 |
On Mon, Sep 28, 2015 at 08:28:57PM -0700, Eric Northup wrote:
> On Sun, Sep 27, 2015 at 10:38 PM, Haozhong Zhang
> <haozhong.zhang@intel.com> wrote:
> >
> > The number of bits of the fractional part of the 64-bit TSC scaling
> > ratio in VMX and SVM is different. This patch makes the architecture
> > code to collect the number of fractional bits and other related
> > information into variables that can be accessed in the common code.
> >
> > Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
> > ---
> > arch/x86/include/asm/kvm_host.h | 8 ++++++++
> > arch/x86/kvm/svm.c | 5 +++++
> > arch/x86/kvm/x86.c | 8 ++++++++
> > 3 files changed, 21 insertions(+)
> >
> > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> > index 2beee03..5b9b86e 100644
> > --- a/arch/x86/include/asm/kvm_host.h
> > +++ b/arch/x86/include/asm/kvm_host.h
> > @@ -965,6 +965,14 @@ extern bool kvm_has_tsc_control;
> > extern u32 kvm_min_guest_tsc_khz;
> > /* maximum supported tsc_khz for guests */
> > extern u32 kvm_max_guest_tsc_khz;
> > +/* number of bits of the fractional part of the TSC scaling ratio */
> > +extern u8 kvm_tsc_scaling_ratio_frac_bits;
> > +/* reserved bits of TSC scaling ratio (SBZ) */
> > +extern u64 kvm_tsc_scaling_ratio_rsvd;
> > +/* default TSC scaling ratio (= 1.0) */
> > +extern u64 kvm_default_tsc_scaling_ratio;
> > +/* maximum allowed value of TSC scaling ratio */
> > +extern u64 kvm_max_tsc_scaling_ratio;
>
> Do we need all 3 of kvm_max_guest_tsc_khz, kvm_max_tsc_scaling_ratio,
> and kvm_tsc_scaling_ratio_rsvd (since only SVM has reserved bits - and
> just for complaining if the high bits are set, which can already be
> expressed by max_tsc_scaling ratio)
>
> kvm_max_tsc_scaling_ratio seems to be write-only.
>
You are right. I'll remove kvm_tsc_scaling_ratio_rsvd and just use
kvm_max_tsc_scaling_ratio to verify TSC scaling ratio in
set_tsc_khz().
> >
> > enum emulation_result {
> > EMULATE_DONE, /* no further processing */
> > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> > index 94b7d15..eff7db7 100644
> > --- a/arch/x86/kvm/svm.c
> > +++ b/arch/x86/kvm/svm.c
> > @@ -963,7 +963,12 @@ static __init int svm_hardware_setup(void)
> > max = min(0x7fffffffULL, __scale_tsc(tsc_khz, TSC_RATIO_MAX));
> >
> > kvm_max_guest_tsc_khz = max;
> > +
> > + kvm_max_tsc_scaling_ratio = TSC_RATIO_MAX;
> > + kvm_tsc_scaling_ratio_frac_bits = 32;
> > + kvm_tsc_scaling_ratio_rsvd = TSC_RATIO_RSVD;
> > }
> > + kvm_default_tsc_scaling_ratio = TSC_RATIO_DEFAULT;
> >
> > if (nested) {
> > printk(KERN_INFO "kvm: Nested Virtualization enabled\n");
> > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> > index 991466b..f888225 100644
> > --- a/arch/x86/kvm/x86.c
> > +++ b/arch/x86/kvm/x86.c
> > @@ -106,6 +106,14 @@ bool kvm_has_tsc_control;
> > EXPORT_SYMBOL_GPL(kvm_has_tsc_control);
> > u32 kvm_max_guest_tsc_khz;
> > EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);
> > +u8 kvm_tsc_scaling_ratio_frac_bits;
> > +EXPORT_SYMBOL_GPL(kvm_tsc_scaling_ratio_frac_bits);
> > +u64 kvm_tsc_scaling_ratio_rsvd;
> > +EXPORT_SYMBOL_GPL(kvm_tsc_scaling_ratio_rsvd);
> > +u64 kvm_default_tsc_scaling_ratio;
> > +EXPORT_SYMBOL_GPL(kvm_default_tsc_scaling_ratio);
> > +u64 kvm_max_tsc_scaling_ratio;
> > +EXPORT_SYMBOL_GPL(kvm_max_tsc_scaling_ratio);
> >
> > /* tsc tolerance in parts per million - default to 1/2 of the NTP threshold */
> > static u32 tsc_tolerance_ppm = 250;
> > --
> > 2.4.8
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe kvm" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:50 +0200 |
| Subject | [PATCH 02/12] KVM: x86: Add a common TSC scaling ratio field in kvm_vcpu_arch |
| Message-ID | <qdzu2-52B-3@gated-at.bofh.it> |
| In reply to | #1233849 |
This patch moves the field of TSC scaling ratio from the architecture
struct vcpu_svm to the common struct kvm_vcpu_arch.
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/svm.c | 23 +++++++++--------------
arch/x86/kvm/x86.c | 3 +++
3 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 5b9b86e..4f32c68 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -500,6 +500,7 @@ struct kvm_vcpu_arch {
u32 virtual_tsc_mult;
u32 virtual_tsc_khz;
s64 ia32_tsc_adjust_msr;
+ u64 tsc_scaling_ratio;
atomic_t nmi_queued; /* unprocessed asynchronous NMIs */
unsigned nmi_pending; /* NMI queued after currently running handler */
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index eff7db7..a3186e2 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -157,8 +157,6 @@ struct vcpu_svm {
unsigned int3_injected;
unsigned long int3_rip;
u32 apf_reason;
-
- u64 tsc_ratio;
};
static DEFINE_PER_CPU(u64, current_tsc_ratio);
@@ -1049,24 +1047,22 @@ static u64 __scale_tsc(u64 ratio, u64 tsc)
static u64 svm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
{
- struct vcpu_svm *svm = to_svm(vcpu);
u64 _tsc = tsc;
- if (svm->tsc_ratio != TSC_RATIO_DEFAULT)
- _tsc = __scale_tsc(svm->tsc_ratio, tsc);
+ if (vcpu->arch.tsc_scaling_ratio != TSC_RATIO_DEFAULT)
+ _tsc = __scale_tsc(vcpu->arch.tsc_scaling_ratio, tsc);
return _tsc;
}
static void svm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
{
- struct vcpu_svm *svm = to_svm(vcpu);
u64 ratio;
u64 khz;
/* Guest TSC same frequency as host TSC? */
if (!scale) {
- svm->tsc_ratio = TSC_RATIO_DEFAULT;
+ vcpu->arch.tsc_scaling_ratio = TSC_RATIO_DEFAULT;
return;
}
@@ -1091,7 +1087,7 @@ static void svm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
user_tsc_khz);
return;
}
- svm->tsc_ratio = ratio;
+ vcpu->arch.tsc_scaling_ratio = ratio;
}
static u64 svm_read_tsc_offset(struct kvm_vcpu *vcpu)
@@ -1125,7 +1121,7 @@ static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool ho
struct vcpu_svm *svm = to_svm(vcpu);
if (host) {
- if (svm->tsc_ratio != TSC_RATIO_DEFAULT)
+ if (vcpu->arch.tsc_scaling_ratio != TSC_RATIO_DEFAULT)
WARN_ON(adjustment < 0);
adjustment = svm_scale_tsc(vcpu, (u64)adjustment);
}
@@ -1335,8 +1331,6 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
goto out;
}
- svm->tsc_ratio = TSC_RATIO_DEFAULT;
-
err = kvm_vcpu_init(&svm->vcpu, kvm, id);
if (err)
goto free_svm;
@@ -1406,6 +1400,7 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
int i;
+ u64 tsc_ratio = vcpu->arch.tsc_scaling_ratio;
if (unlikely(cpu != vcpu->cpu)) {
svm->asid_generation = 0;
@@ -1423,9 +1418,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
if (static_cpu_has(X86_FEATURE_TSCRATEMSR) &&
- svm->tsc_ratio != __this_cpu_read(current_tsc_ratio)) {
- __this_cpu_write(current_tsc_ratio, svm->tsc_ratio);
- wrmsrl(MSR_AMD64_TSC_RATIO, svm->tsc_ratio);
+ tsc_ratio != __this_cpu_read(current_tsc_ratio)) {
+ __this_cpu_write(current_tsc_ratio, tsc_ratio);
+ wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
}
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f888225..4a521b4 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7080,6 +7080,9 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
vcpu = kvm_x86_ops->vcpu_create(kvm, id);
+ if (!IS_ERR(vcpu))
+ vcpu->arch.tsc_scaling_ratio = kvm_default_tsc_scaling_ratio;
+
return vcpu;
}
--
2.4.8
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2015-10-05 21:30 +0200 |
| Subject | Re: [PATCH 02/12] KVM: x86: Add a common TSC scaling ratio field in kvm_vcpu_arch |
| Message-ID | <qgjCp-8dv-1@gated-at.bofh.it> |
| In reply to | #1233858 |
2015-09-28 13:38+0800, Haozhong Zhang:
> This patch moves the field of TSC scaling ratio from the architecture
> struct vcpu_svm to the common struct kvm_vcpu_arch.
>
> Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
> ---
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> @@ -7080,6 +7080,9 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
>
> vcpu = kvm_x86_ops->vcpu_create(kvm, id);
>
> + if (!IS_ERR(vcpu))
> + vcpu->arch.tsc_scaling_ratio = kvm_default_tsc_scaling_ratio;
This shouldn't be necessary, (and we can definitely do it without error
checking later)
kvm_arch_vcpu_create
(vmx|svm)_create_vcpu
kvm_vcpu_init
kvm_arch_vcpu_init
kvm_set_tsc_khz
sets vcpu->arch.tsc_scaling_ratio to something reasonable and SVM didn't
overwrite that value. (kvm_set_tsc_khz() only doesn't set the ration if
this_tsc_khz == 0, which we could extend to be extra safe.)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:50 +0200 |
| Subject | [PATCH 08/12] KVM: x86: Use the correct vcpu's TSC rate to compute time scale |
| Message-ID | <qdzu2-52B-5@gated-at.bofh.it> |
| In reply to | #1233849 |
This patch makes KVM use virtual_tsc_khz rather than the host TSC rate
as vcpu's TSC rate to compute the time scale if TSC scaling is enabled.
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
arch/x86/kvm/x86.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d404a7e..a3999b5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1719,7 +1719,7 @@ static void kvm_gen_update_masterclock(struct kvm *kvm)
static int kvm_guest_time_update(struct kvm_vcpu *v)
{
- unsigned long flags, this_tsc_khz;
+ unsigned long flags, this_tsc_khz, tgt_tsc_khz;
struct kvm_vcpu_arch *vcpu = &v->arch;
struct kvm_arch *ka = &v->kvm->arch;
s64 kernel_ns;
@@ -1782,7 +1782,9 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
return 0;
if (unlikely(vcpu->hw_tsc_khz != this_tsc_khz)) {
- kvm_get_time_scale(NSEC_PER_SEC / 1000, this_tsc_khz,
+ tgt_tsc_khz = kvm_has_tsc_control ?
+ vcpu->virtual_tsc_khz : this_tsc_khz;
+ kvm_get_time_scale(NSEC_PER_SEC / 1000, tgt_tsc_khz,
&vcpu->hv_clock.tsc_shift,
&vcpu->hv_clock.tsc_to_system_mul);
vcpu->hw_tsc_khz = this_tsc_khz;
--
2.4.8
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Radim Krčmář <rkrcmar@redhat.com> |
|---|---|
| Date | 2015-10-05 22:20 +0200 |
| Subject | Re: [PATCH 08/12] KVM: x86: Use the correct vcpu's TSC rate to compute time scale |
| Message-ID | <qgkoO-Wa-11@gated-at.bofh.it> |
| In reply to | #1233859 |
2015-09-28 13:38+0800, Haozhong Zhang:
> This patch makes KVM use virtual_tsc_khz rather than the host TSC rate
> as vcpu's TSC rate to compute the time scale if TSC scaling is enabled.
>
> Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
> ---
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> @@ -1782,7 +1782,9 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
> return 0;
>
> if (unlikely(vcpu->hw_tsc_khz != this_tsc_khz)) {
> - kvm_get_time_scale(NSEC_PER_SEC / 1000, this_tsc_khz,
> + tgt_tsc_khz = kvm_has_tsc_control ?
> + vcpu->virtual_tsc_khz : this_tsc_khz;
> + kvm_get_time_scale(NSEC_PER_SEC / 1000, tgt_tsc_khz,
> &vcpu->hv_clock.tsc_shift,
> &vcpu->hv_clock.tsc_to_system_mul);
Good catch, it seems that SVM didn't scale kvmclock correctly ...
I think we'll want this patch in stable.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:50 +0200 |
| Subject | [PATCH 05/12] KVM: x86: Replace call-back compute_tsc_offset() with a common function |
| Message-ID | <qdzu2-52B-7@gated-at.bofh.it> |
| In reply to | #1233849 |
Both VMX and SVM calculate the tsc-offset in the same way, so this
patch removes the call-back compute_tsc_offset() and replaces it with a
common function kvm_compute_tsc_offset().
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
arch/x86/include/asm/kvm_host.h | 1 -
arch/x86/kvm/svm.c | 10 ----------
arch/x86/kvm/vmx.c | 6 ------
arch/x86/kvm/x86.c | 15 ++++++++++++---
4 files changed, 12 insertions(+), 20 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 5a0c435..0bbb2a7 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -845,7 +845,6 @@ struct kvm_x86_ops {
u64 (*read_tsc_offset)(struct kvm_vcpu *vcpu);
void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
- u64 (*compute_tsc_offset)(struct kvm_vcpu *vcpu, u64 target_tsc);
u64 (*read_l1_tsc)(struct kvm_vcpu *vcpu, u64 host_tsc);
void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d46dcf3..c49cd28 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1062,15 +1062,6 @@ static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool ho
mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
}
-static u64 svm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
-{
- u64 tsc;
-
- tsc = kvm_scale_tsc(vcpu, rdtsc());
-
- return target_tsc - tsc;
-}
-
static void svm_set_guest_pat(struct vcpu_svm *svm, u64 *g_pat)
{
struct kvm_vcpu *vcpu = &svm->vcpu;
@@ -4475,7 +4466,6 @@ static struct kvm_x86_ops svm_x86_ops = {
.read_tsc_offset = svm_read_tsc_offset,
.write_tsc_offset = svm_write_tsc_offset,
.adjust_tsc_offset = svm_adjust_tsc_offset,
- .compute_tsc_offset = svm_compute_tsc_offset,
.read_l1_tsc = svm_read_l1_tsc,
.set_tdp_cr3 = set_tdp_cr3,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 1751537..7a71191 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2299,11 +2299,6 @@ static void vmx_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool ho
offset + adjustment);
}
-static u64 vmx_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
-{
- return target_tsc - rdtsc();
-}
-
static bool guest_cpuid_has_vmx(struct kvm_vcpu *vcpu)
{
struct kvm_cpuid_entry2 *best = kvm_find_cpuid_entry(vcpu, 1, 0);
@@ -10367,7 +10362,6 @@ static struct kvm_x86_ops vmx_x86_ops = {
.read_tsc_offset = vmx_read_tsc_offset,
.write_tsc_offset = vmx_write_tsc_offset,
.adjust_tsc_offset = vmx_adjust_tsc_offset,
- .compute_tsc_offset = vmx_compute_tsc_offset,
.read_l1_tsc = vmx_read_l1_tsc,
.set_tdp_cr3 = vmx_set_cr3,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e2e1fdb..7c372ad 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1418,6 +1418,15 @@ u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
}
EXPORT_SYMBOL_GPL(kvm_scale_tsc);
+static u64 kvm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
+{
+ u64 tsc;
+
+ tsc = kvm_scale_tsc(vcpu, rdtsc());
+
+ return target_tsc - tsc;
+}
+
void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
{
struct kvm *kvm = vcpu->kvm;
@@ -1429,7 +1438,7 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
u64 data = msr->data;
raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
- offset = kvm_x86_ops->compute_tsc_offset(vcpu, data);
+ offset = kvm_compute_tsc_offset(vcpu, data);
ns = get_kernel_ns();
elapsed = ns - kvm->arch.last_tsc_nsec;
@@ -1486,7 +1495,7 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
} else {
u64 delta = nsec_to_cycles(vcpu, elapsed);
data += delta;
- offset = kvm_x86_ops->compute_tsc_offset(vcpu, data);
+ offset = kvm_compute_tsc_offset(vcpu, data);
pr_debug("kvm: adjusted tsc offset by %llu\n", delta);
}
matched = true;
@@ -2720,7 +2729,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if (tsc_delta < 0)
mark_tsc_unstable("KVM discovered backwards TSC");
if (check_tsc_unstable()) {
- u64 offset = kvm_x86_ops->compute_tsc_offset(vcpu,
+ u64 offset = kvm_compute_tsc_offset(vcpu,
vcpu->arch.last_guest_tsc);
kvm_x86_ops->write_tsc_offset(vcpu, offset);
vcpu->arch.tsc_catchup = 1;
--
2.4.8
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:50 +0200 |
| Subject | [PATCH 03/12] KVM: x86: Add a common TSC scaling function |
| Message-ID | <qdzu2-52B-9@gated-at.bofh.it> |
| In reply to | #1233849 |
VMX and SVM calculate the TSC scaling ratio in a similar logic, so this
patch generalizes it to a common TSC scaling function.
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
arch/x86/kvm/svm.c | 48 +++------------------------------
arch/x86/kvm/x86.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/kvm_host.h | 4 ++-
3 files changed, 77 insertions(+), 45 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index a3186e2..1a333bd 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -209,7 +209,6 @@ static int nested_svm_intercept(struct vcpu_svm *svm);
static int nested_svm_vmexit(struct vcpu_svm *svm);
static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
bool has_error_code, u32 error_code);
-static u64 __scale_tsc(u64 ratio, u64 tsc);
enum {
VMCB_INTERCEPTS, /* Intercept vectors, TSC offset,
@@ -947,21 +946,7 @@ static __init int svm_hardware_setup(void)
kvm_enable_efer_bits(EFER_FFXSR);
if (boot_cpu_has(X86_FEATURE_TSCRATEMSR)) {
- u64 max;
-
kvm_has_tsc_control = true;
-
- /*
- * Make sure the user can only configure tsc_khz values that
- * fit into a signed integer.
- * A min value is not calculated needed because it will always
- * be 1 on all machines and a value of 0 is used to disable
- * tsc-scaling for the vcpu.
- */
- max = min(0x7fffffffULL, __scale_tsc(tsc_khz, TSC_RATIO_MAX));
-
- kvm_max_guest_tsc_khz = max;
-
kvm_max_tsc_scaling_ratio = TSC_RATIO_MAX;
kvm_tsc_scaling_ratio_frac_bits = 32;
kvm_tsc_scaling_ratio_rsvd = TSC_RATIO_RSVD;
@@ -1030,31 +1015,6 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
seg->base = 0;
}
-static u64 __scale_tsc(u64 ratio, u64 tsc)
-{
- u64 mult, frac, _tsc;
-
- mult = ratio >> 32;
- frac = ratio & ((1ULL << 32) - 1);
-
- _tsc = tsc;
- _tsc *= mult;
- _tsc += (tsc >> 32) * frac;
- _tsc += ((tsc & ((1ULL << 32) - 1)) * frac) >> 32;
-
- return _tsc;
-}
-
-static u64 svm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
-{
- u64 _tsc = tsc;
-
- if (vcpu->arch.tsc_scaling_ratio != TSC_RATIO_DEFAULT)
- _tsc = __scale_tsc(vcpu->arch.tsc_scaling_ratio, tsc);
-
- return _tsc;
-}
-
static void svm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
{
u64 ratio;
@@ -1123,7 +1083,7 @@ static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool ho
if (host) {
if (vcpu->arch.tsc_scaling_ratio != TSC_RATIO_DEFAULT)
WARN_ON(adjustment < 0);
- adjustment = svm_scale_tsc(vcpu, (u64)adjustment);
+ adjustment = kvm_scale_tsc(vcpu, (u64)adjustment);
}
svm->vmcb->control.tsc_offset += adjustment;
@@ -1141,7 +1101,7 @@ static u64 svm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
{
u64 tsc;
- tsc = svm_scale_tsc(vcpu, rdtsc());
+ tsc = kvm_scale_tsc(vcpu, rdtsc());
return target_tsc - tsc;
}
@@ -3166,7 +3126,7 @@ static u64 svm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
{
struct vmcb *vmcb = get_host_vmcb(to_svm(vcpu));
return vmcb->control.tsc_offset +
- svm_scale_tsc(vcpu, host_tsc);
+ kvm_scale_tsc(vcpu, host_tsc);
}
static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
@@ -3176,7 +3136,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
switch (msr_info->index) {
case MSR_IA32_TSC: {
msr_info->data = svm->vmcb->control.tsc_offset +
- svm_scale_tsc(vcpu, rdtsc());
+ kvm_scale_tsc(vcpu, rdtsc());
break;
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4a521b4..920c302 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1321,6 +1321,64 @@ static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset)
vcpu->arch.ia32_tsc_adjust_msr += offset - curr_offset;
}
+/*
+ * Multiply tsc by a fixed point number represented by ratio.
+ *
+ * The most significant 64-N bits (mult) of ratio represent the
+ * integral part of the fixed point number; the remaining N bits
+ * (frac) represent the fractional part, ie. ratio represents a fixed
+ * point number (mult + frac * 2^(-N)).
+ *
+ * N.B: we always assume not all 64 bits of ratio are used for the
+ * fractional part and the ratio has at least 1 bit for the fractional
+ * part, i.e. 0 < N < 64.
+ *
+ * N equals to kvm_tsc_scaling_ratio_frac_bits.
+ */
+static u64 __scale_tsc(u64 ratio, u64 tsc)
+{
+ u64 mult, frac, mask, _tsc;
+ int width, nr;
+
+ BUG_ON(kvm_tsc_scaling_ratio_frac_bits >= 64 ||
+ kvm_tsc_scaling_ratio_frac_bits == 0);
+
+ mult = ratio >> kvm_tsc_scaling_ratio_frac_bits;
+ mask = (1ULL << kvm_tsc_scaling_ratio_frac_bits) - 1;
+ frac = ratio & mask;
+
+ width = 64 - kvm_tsc_scaling_ratio_frac_bits;
+ mask = (1ULL << width) - 1;
+ nr = kvm_tsc_scaling_ratio_frac_bits;
+
+ _tsc = tsc;
+ _tsc *= mult;
+ _tsc += (tsc >> kvm_tsc_scaling_ratio_frac_bits) * frac;
+
+ while (nr >= width) {
+ _tsc += (((tsc >> (nr - width)) & mask) * frac) >> (64 - nr);
+ nr -= width;
+ }
+
+ if (nr > 0)
+ _tsc += ((tsc & ((1ULL << nr) - 1)) * frac) >>
+ kvm_tsc_scaling_ratio_frac_bits;
+
+ return _tsc;
+}
+
+u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
+{
+ u64 _tsc = tsc;
+ u64 ratio = vcpu->arch.tsc_scaling_ratio;
+
+ if (ratio != kvm_default_tsc_scaling_ratio)
+ _tsc = __scale_tsc(ratio, tsc);
+
+ return _tsc;
+}
+EXPORT_SYMBOL_GPL(kvm_scale_tsc);
+
void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
{
struct kvm *kvm = vcpu->kvm;
@@ -7290,6 +7348,18 @@ int kvm_arch_hardware_setup(void)
if (r != 0)
return r;
+ /*
+ * Make sure the user can only configure tsc_khz values that
+ * fit into a signed integer.
+ * A min value is not calculated needed because it will always
+ * be 1 on all machines.
+ */
+ if (kvm_has_tsc_control) {
+ u64 max = min(0x7fffffffULL,
+ __scale_tsc(kvm_max_tsc_scaling_ratio, tsc_khz));
+ kvm_max_guest_tsc_khz = max;
+ }
+
kvm_init_msr_list();
return 0;
}
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 1bef9e2..3c43e3e 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1144,5 +1144,7 @@ static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
{
}
#endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
-#endif
+u64 kvm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc);
+
+#endif
--
2.4.8
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Paolo Bonzini <pbonzini@redhat.com> |
|---|---|
| Date | 2015-09-28 22:20 +0200 |
| Subject | Re: [PATCH 03/12] KVM: x86: Add a common TSC scaling function |
| Message-ID | <qdN3X-1rA-9@gated-at.bofh.it> |
| In reply to | #1233861 |
On 28/09/2015 07:38, Haozhong Zhang wrote:
>
> -static u64 __scale_tsc(u64 ratio, u64 tsc)
> -{
> - u64 mult, frac, _tsc;
> -
> - mult = ratio >> 32;
> - frac = ratio & ((1ULL << 32) - 1);
> -
> - _tsc = tsc;
> - _tsc *= mult;
> - _tsc += (tsc >> 32) * frac;
> - _tsc += ((tsc & ((1ULL << 32) - 1)) * frac) >> 32;
> -
> - return _tsc;
> -}
This is basically
return mul_u64_u64_shr(ratio, tsc,
kvm_tsc_scaling_ratio_frac_bits);
except that Linux has no mul_u64_u64_shr function, only mul_u64_u32_shr.
We should implement that function in include/linux/math64.h instead.
For the x86_64 case (or any other CONFIG_ARCH_SUPPORTS_INT128
architecture) we can just write it directly, as is done already for
mul_u64_u32_shr.
For the 32-bit case, here is an implementation of both the
multiplication and the shift, lifted from QEMU:
static inline void mul64(uint64_t *lo, uint64_t *hi,
uint64_t a, uint64_t b)
{
typedef union {
uint64_t ll;
struct {
#ifdef __BIG_ENDIAN
uint32_t high, low;
#else
uint32_t low, high;
#endif
} l;
} LL;
LL rl, rm, rn, rh, a0, b0;
uint64_t c;
a0.ll = a;
b0.ll = b;
rl.ll = (uint64_t)a0.l.low * b0.l.low;
rm.ll = (uint64_t)a0.l.low * b0.l.high;
rn.ll = (uint64_t)a0.l.high * b0.l.low;
rh.ll = (uint64_t)a0.l.high * b0.l.high;
c = (uint64_t)rl.l.high + rm.l.low + rn.l.low;
rl.l.high = c;
c >>= 32;
c = c + rm.l.high + rn.l.high + rh.l.low;
rh.l.low = c;
rh.l.high += (uint32_t)(c >> 32);
*lo = rl.ll;
*hi = rh.ll;
}
static inline void rshift128(uint64_t *lo, uint64_t *hi, int n)
{
uint64_t h;
if (!n) {
return;
}
h = *hi >> (n & 63);
if (n >= 64) {
*hi = 0;
*lo = h;
} else {
*lo = (*lo >> n) | (*hi << (64 - n));
*hi = h;
}
}
and you can easily reuse this code in Linux with just uintNN_t types
changed to uNN + some extra cleanups when it's placed in a single functions.
Paolo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-29 04:00 +0200 |
| Subject | Re: [PATCH 03/12] KVM: x86: Add a common TSC scaling function |
| Message-ID | <qdSn0-vH-1@gated-at.bofh.it> |
| In reply to | #1234414 |
On Mon, Sep 28, 2015 at 10:12:37PM +0200, Paolo Bonzini wrote:
>
>
> On 28/09/2015 07:38, Haozhong Zhang wrote:
> >
> > -static u64 __scale_tsc(u64 ratio, u64 tsc)
> > -{
> > - u64 mult, frac, _tsc;
> > -
> > - mult = ratio >> 32;
> > - frac = ratio & ((1ULL << 32) - 1);
> > -
> > - _tsc = tsc;
> > - _tsc *= mult;
> > - _tsc += (tsc >> 32) * frac;
> > - _tsc += ((tsc & ((1ULL << 32) - 1)) * frac) >> 32;
> > -
> > - return _tsc;
> > -}
>
> This is basically
>
> return mul_u64_u64_shr(ratio, tsc,
> kvm_tsc_scaling_ratio_frac_bits);
>
> except that Linux has no mul_u64_u64_shr function, only mul_u64_u32_shr.
>
> We should implement that function in include/linux/math64.h instead.
> For the x86_64 case (or any other CONFIG_ARCH_SUPPORTS_INT128
> architecture) we can just write it directly, as is done already for
> mul_u64_u32_shr.
>
> For the 32-bit case, here is an implementation of both the
> multiplication and the shift, lifted from QEMU:
>
> static inline void mul64(uint64_t *lo, uint64_t *hi,
> uint64_t a, uint64_t b)
> {
> typedef union {
> uint64_t ll;
> struct {
> #ifdef __BIG_ENDIAN
> uint32_t high, low;
> #else
> uint32_t low, high;
> #endif
> } l;
> } LL;
> LL rl, rm, rn, rh, a0, b0;
> uint64_t c;
>
> a0.ll = a;
> b0.ll = b;
>
> rl.ll = (uint64_t)a0.l.low * b0.l.low;
> rm.ll = (uint64_t)a0.l.low * b0.l.high;
> rn.ll = (uint64_t)a0.l.high * b0.l.low;
> rh.ll = (uint64_t)a0.l.high * b0.l.high;
>
> c = (uint64_t)rl.l.high + rm.l.low + rn.l.low;
> rl.l.high = c;
> c >>= 32;
> c = c + rm.l.high + rn.l.high + rh.l.low;
> rh.l.low = c;
> rh.l.high += (uint32_t)(c >> 32);
>
> *lo = rl.ll;
> *hi = rh.ll;
> }
>
> static inline void rshift128(uint64_t *lo, uint64_t *hi, int n)
> {
> uint64_t h;
> if (!n) {
> return;
> }
> h = *hi >> (n & 63);
> if (n >= 64) {
> *hi = 0;
> *lo = h;
> } else {
> *lo = (*lo >> n) | (*hi << (64 - n));
> *hi = h;
> }
> }
>
> and you can easily reuse this code in Linux with just uintNN_t types
> changed to uNN + some extra cleanups when it's placed in a single functions.
>
> Paolo
Thanks! I'll add mul_u64_u64_shr() and replace __scale_tsc().
- Haozhong
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:50 +0200 |
| Subject | [PATCH 10/12] KVM: VMX: Setup TSC scaling ratio when a vcpu is loaded |
| Message-ID | <qdzu2-52B-11@gated-at.bofh.it> |
| In reply to | #1233849 |
This patch makes kvm-intel module to load TSC scaling ratio into TSC multiplier field of VMCS when a vcpu is loaded, so that TSC scaling ratio can take effect if VMX TSC scaling is enabled. Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com> --- arch/x86/kvm/vmx.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ef19eb8..e282eb8 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1952,6 +1952,12 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ + + /* Setup TSC multiplier */ + if (cpu_has_vmx_tsc_scaling()) + vmcs_write64(TSC_MULTIPLIER, + vcpu->arch.tsc_scaling_ratio); + vmx->loaded_vmcs->cpu = cpu; } } -- 2.4.8 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-28 07:50 +0200 |
| Subject | [PATCH 04/12] KVM: x86: Replace call-back set_tsc_khz() with a common function |
| Message-ID | <qdzu2-52B-13@gated-at.bofh.it> |
| In reply to | #1233849 |
Both VMX and SVM propagate virtual_tsc_khz in the same way, so this
patch removes the call-back set_tsc_khz() and replaces it with a common
function.
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
arch/x86/include/asm/kvm_host.h | 1 -
arch/x86/kvm/svm.c | 36 ------------------------------------
arch/x86/kvm/vmx.c | 17 -----------------
arch/x86/kvm/x86.c | 41 ++++++++++++++++++++++++++++++++++++++++-
4 files changed, 40 insertions(+), 55 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4f32c68..5a0c435 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -842,7 +842,6 @@ struct kvm_x86_ops {
bool (*has_wbinvd_exit)(void);
- void (*set_tsc_khz)(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale);
u64 (*read_tsc_offset)(struct kvm_vcpu *vcpu);
void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 1a333bd..d46dcf3 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1015,41 +1015,6 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
seg->base = 0;
}
-static void svm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
-{
- u64 ratio;
- u64 khz;
-
- /* Guest TSC same frequency as host TSC? */
- if (!scale) {
- vcpu->arch.tsc_scaling_ratio = TSC_RATIO_DEFAULT;
- return;
- }
-
- /* TSC scaling supported? */
- if (!boot_cpu_has(X86_FEATURE_TSCRATEMSR)) {
- if (user_tsc_khz > tsc_khz) {
- vcpu->arch.tsc_catchup = 1;
- vcpu->arch.tsc_always_catchup = 1;
- } else
- WARN(1, "user requested TSC rate below hardware speed\n");
- return;
- }
-
- khz = user_tsc_khz;
-
- /* TSC scaling required - calculate ratio */
- ratio = khz << 32;
- do_div(ratio, tsc_khz);
-
- if (ratio == 0 || ratio & TSC_RATIO_RSVD) {
- WARN_ONCE(1, "Invalid TSC ratio - virtual-tsc-khz=%u\n",
- user_tsc_khz);
- return;
- }
- vcpu->arch.tsc_scaling_ratio = ratio;
-}
-
static u64 svm_read_tsc_offset(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -4507,7 +4472,6 @@ static struct kvm_x86_ops svm_x86_ops = {
.has_wbinvd_exit = svm_has_wbinvd_exit,
- .set_tsc_khz = svm_set_tsc_khz,
.read_tsc_offset = svm_read_tsc_offset,
.write_tsc_offset = svm_write_tsc_offset,
.adjust_tsc_offset = svm_adjust_tsc_offset,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 6407674..1751537 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2255,22 +2255,6 @@ static u64 vmx_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
return host_tsc + tsc_offset;
}
-/*
- * Engage any workarounds for mis-matched TSC rates. Currently limited to
- * software catchup for faster rates on slower CPUs.
- */
-static void vmx_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
-{
- if (!scale)
- return;
-
- if (user_tsc_khz > tsc_khz) {
- vcpu->arch.tsc_catchup = 1;
- vcpu->arch.tsc_always_catchup = 1;
- } else
- WARN(1, "user requested TSC rate below hardware speed\n");
-}
-
static u64 vmx_read_tsc_offset(struct kvm_vcpu *vcpu)
{
return vmcs_read64(TSC_OFFSET);
@@ -10380,7 +10364,6 @@ static struct kvm_x86_ops vmx_x86_ops = {
.has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
- .set_tsc_khz = vmx_set_tsc_khz,
.read_tsc_offset = vmx_read_tsc_offset,
.write_tsc_offset = vmx_write_tsc_offset,
.adjust_tsc_offset = vmx_adjust_tsc_offset,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 920c302..e2e1fdb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1248,6 +1248,45 @@ static u32 adjust_tsc_khz(u32 khz, s32 ppm)
return v;
}
+static void set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale)
+{
+ u64 ratio, khz;
+ s8 shift;
+
+ /* Guest TSC same frequency as host TSC? */
+ if (!scale) {
+ vcpu->arch.tsc_scaling_ratio = kvm_default_tsc_scaling_ratio;
+ return;
+ }
+
+ /* TSC scaling supported? */
+ if (!kvm_has_tsc_control) {
+ if (user_tsc_khz > tsc_khz) {
+ vcpu->arch.tsc_catchup = 1;
+ vcpu->arch.tsc_always_catchup = 1;
+ } else
+ WARN(1, "user requested TSC rate below hardware speed\n");
+ return;
+ }
+
+ khz = user_tsc_khz;
+
+ /* TSC scaling required - calculate ratio */
+ shift = (kvm_tsc_scaling_ratio_frac_bits <= 32) ?
+ kvm_tsc_scaling_ratio_frac_bits : 32;
+ ratio = khz << shift;
+ do_div(ratio, tsc_khz);
+ ratio <<= (kvm_tsc_scaling_ratio_frac_bits - shift);
+
+ if (ratio == 0 || ratio & kvm_tsc_scaling_ratio_rsvd) {
+ WARN_ONCE(1, "Invalid TSC scaling ratio - virtual-tsc-khz=%u\n",
+ user_tsc_khz);
+ return;
+ }
+
+ vcpu->arch.tsc_scaling_ratio = ratio;
+}
+
static void kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 this_tsc_khz)
{
u32 thresh_lo, thresh_hi;
@@ -1275,7 +1314,7 @@ static void kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 this_tsc_khz)
pr_debug("kvm: requested TSC rate %u falls outside tolerance [%u,%u]\n", this_tsc_khz, thresh_lo, thresh_hi);
use_scaling = 1;
}
- kvm_x86_ops->set_tsc_khz(vcpu, this_tsc_khz, use_scaling);
+ set_tsc_khz(vcpu, this_tsc_khz, use_scaling);
}
static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
--
2.4.8
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Haozhong Zhang <haozhong.zhang@intel.com> |
|---|---|
| Date | 2015-09-29 05:50 +0200 |
| Subject | Re: [PATCH 04/12] KVM: x86: Replace call-back set_tsc_khz() with a common function |
| Message-ID | <qdU5s-373-17@gated-at.bofh.it> |
| In reply to | #1233863 |
On Mon, Sep 28, 2015 at 08:27:02PM -0700, Eric Northup wrote:
> On Sun, Sep 27, 2015 at 10:38 PM, Haozhong Zhang <haozhong.zhang@intel.com>
> wrote:
>
> > Both VMX and SVM propagate virtual_tsc_khz in the same way, so this
> > patch removes the call-back set_tsc_khz() and replaces it with a common
> > function.
> >
> > Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
> > ---
> > arch/x86/include/asm/kvm_host.h | 1 -
> > arch/x86/kvm/svm.c | 36 ------------------------------------
> > arch/x86/kvm/vmx.c | 17 -----------------
> > arch/x86/kvm/x86.c | 41
> > ++++++++++++++++++++++++++++++++++++++++-
> > 4 files changed, 40 insertions(+), 55 deletions(-)
> >
> > diff --git a/arch/x86/include/asm/kvm_host.h
> > b/arch/x86/include/asm/kvm_host.h
> > index 4f32c68..5a0c435 100644
> > --- a/arch/x86/include/asm/kvm_host.h
> > +++ b/arch/x86/include/asm/kvm_host.h
> > @@ -842,7 +842,6 @@ struct kvm_x86_ops {
> >
> > bool (*has_wbinvd_exit)(void);
> >
> > - void (*set_tsc_khz)(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool
> > scale);
> > u64 (*read_tsc_offset)(struct kvm_vcpu *vcpu);
> > void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
> >
> > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> > index 1a333bd..d46dcf3 100644
> > --- a/arch/x86/kvm/svm.c
> > +++ b/arch/x86/kvm/svm.c
> > @@ -1015,41 +1015,6 @@ static void init_sys_seg(struct vmcb_seg *seg,
> > uint32_t type)
> > seg->base = 0;
> > }
> >
> > -static void svm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool
> > scale)
> > -{
> > - u64 ratio;
> > - u64 khz;
> > -
> > - /* Guest TSC same frequency as host TSC? */
> > - if (!scale) {
> > - vcpu->arch.tsc_scaling_ratio = TSC_RATIO_DEFAULT;
> > - return;
> > - }
> > -
> > - /* TSC scaling supported? */
> > - if (!boot_cpu_has(X86_FEATURE_TSCRATEMSR)) {
> > - if (user_tsc_khz > tsc_khz) {
> > - vcpu->arch.tsc_catchup = 1;
> > - vcpu->arch.tsc_always_catchup = 1;
> > - } else
> > - WARN(1, "user requested TSC rate below hardware
> > speed\n");
> > - return;
> > - }
> > -
> > - khz = user_tsc_khz;
> > -
> > - /* TSC scaling required - calculate ratio */
> > - ratio = khz << 32;
> > - do_div(ratio, tsc_khz);
> > -
> > - if (ratio == 0 || ratio & TSC_RATIO_RSVD) {
> > - WARN_ONCE(1, "Invalid TSC ratio - virtual-tsc-khz=%u\n",
> > - user_tsc_khz);
> > - return;
> > - }
> > - vcpu->arch.tsc_scaling_ratio = ratio;
> > -}
> > -
> > static u64 svm_read_tsc_offset(struct kvm_vcpu *vcpu)
> > {
> > struct vcpu_svm *svm = to_svm(vcpu);
> > @@ -4507,7 +4472,6 @@ static struct kvm_x86_ops svm_x86_ops = {
> >
> > .has_wbinvd_exit = svm_has_wbinvd_exit,
> >
> > - .set_tsc_khz = svm_set_tsc_khz,
> > .read_tsc_offset = svm_read_tsc_offset,
> > .write_tsc_offset = svm_write_tsc_offset,
> > .adjust_tsc_offset = svm_adjust_tsc_offset,
> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > index 6407674..1751537 100644
> > --- a/arch/x86/kvm/vmx.c
> > +++ b/arch/x86/kvm/vmx.c
> > @@ -2255,22 +2255,6 @@ static u64 vmx_read_l1_tsc(struct kvm_vcpu *vcpu,
> > u64 host_tsc)
> > return host_tsc + tsc_offset;
> > }
> >
> > -/*
> > - * Engage any workarounds for mis-matched TSC rates. Currently limited to
> > - * software catchup for faster rates on slower CPUs.
> > - */
> > -static void vmx_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool
> > scale)
> > -{
> > - if (!scale)
> > - return;
> > -
> > - if (user_tsc_khz > tsc_khz) {
> > - vcpu->arch.tsc_catchup = 1;
> > - vcpu->arch.tsc_always_catchup = 1;
> > - } else
> > - WARN(1, "user requested TSC rate below hardware speed\n");
> > -}
> > -
> > static u64 vmx_read_tsc_offset(struct kvm_vcpu *vcpu)
> > {
> > return vmcs_read64(TSC_OFFSET);
> > @@ -10380,7 +10364,6 @@ static struct kvm_x86_ops vmx_x86_ops = {
> >
> > .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
> >
> > - .set_tsc_khz = vmx_set_tsc_khz,
> > .read_tsc_offset = vmx_read_tsc_offset,
> > .write_tsc_offset = vmx_write_tsc_offset,
> > .adjust_tsc_offset = vmx_adjust_tsc_offset,
> > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> > index 920c302..e2e1fdb 100644
> > --- a/arch/x86/kvm/x86.c
> > +++ b/arch/x86/kvm/x86.c
> > @@ -1248,6 +1248,45 @@ static u32 adjust_tsc_khz(u32 khz, s32 ppm)
> > return v;
> > }
> >
> > +static void set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool
> > scale)
> > +{
> > + u64 ratio, khz;
> > + s8 shift;
> > +
> > + /* Guest TSC same frequency as host TSC? */
> > + if (!scale) {
> > + vcpu->arch.tsc_scaling_ratio =
> > kvm_default_tsc_scaling_ratio;
> > + return;
> > + }
> > +
> > + /* TSC scaling supported? */
> > + if (!kvm_has_tsc_control) {
> > + if (user_tsc_khz > tsc_khz) {
> > + vcpu->arch.tsc_catchup = 1;
> > + vcpu->arch.tsc_always_catchup = 1;
> > + } else
> > + WARN(1, "user requested TSC rate below hardware
> > speed\n");
> >
>
> It was like this before, but why should KVM_SET_TSC_KHZ ioctl have return
> value of 0 in this case? Failing the request would be better than kernel
> log spew (and below).
>
>
Yes, failing the request is a better way. I'll change this and below.
> > + return;
> > + }
> > +
> > + khz = user_tsc_khz;
> > +
> > + /* TSC scaling required - calculate ratio */
> > + shift = (kvm_tsc_scaling_ratio_frac_bits <= 32) ?
> > + kvm_tsc_scaling_ratio_frac_bits : 32;
> > + ratio = khz << shift;
> > + do_div(ratio, tsc_khz);
> > + ratio <<= (kvm_tsc_scaling_ratio_frac_bits - shift);
> > +
> > + if (ratio == 0 || ratio & kvm_tsc_scaling_ratio_rsvd) {
> > + WARN_ONCE(1, "Invalid TSC scaling ratio -
> > virtual-tsc-khz=%u\n",
> > + user_tsc_khz);
> > + return;
> > + }
> > +
> > + vcpu->arch.tsc_scaling_ratio = ratio;
> > +}
> > +
> > static void kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 this_tsc_khz)
> > {
> > u32 thresh_lo, thresh_hi;
> > @@ -1275,7 +1314,7 @@ static void kvm_set_tsc_khz(struct kvm_vcpu *vcpu,
> > u32 this_tsc_khz)
> > pr_debug("kvm: requested TSC rate %u falls outside
> > tolerance [%u,%u]\n", this_tsc_khz, thresh_lo, thresh_hi);
> > use_scaling = 1;
> > }
> > - kvm_x86_ops->set_tsc_khz(vcpu, this_tsc_khz, use_scaling);
> > + set_tsc_khz(vcpu, this_tsc_khz, use_scaling);
> > }
> >
> > static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
> > --
> > 2.4.8
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe kvm" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web