All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Durrant <paul.durrant@citrix.com>
To: xen-devel@lists.xen.org
Cc: Keir Fraser <keir@xen.org>,
	Ian Campbell <ian.campbell@citrix.com>,
	Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
	Christoph Egger <chegger@amazon.de>,
	Ian Jackson <ian.jackson@eu.citrix.com>,
	Paul Durrant <paul.durrant@citrix.com>
Subject: [PATCH v12 2/2] x86/viridian: Add partition time reference counter MSR support
Date: Tue, 23 Sep 2014 11:40:10 +0100	[thread overview]
Message-ID: <1411468810-40888-3-git-send-email-paul.durrant@citrix.com> (raw)
In-Reply-To: <1411468810-40888-1-git-send-email-paul.durrant@citrix.com>

This patch optionally re-instates support for the partition time reference
counter that was previously introduced by commit
e36cd2cdc9674a7a4855d21fb7b3e6e17c4bb33b and reverted by commit
1cd4fab14ce25859efa4a2af13475e6650a5506c. The previous implementation was
non-optional and flawed.

This implementation uses the tsc of vcpu0, which is preserved across
save/restore as part of the architectural state, and then converts that
to a 100ns tick using the domain's tsc_khz.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Cc: Keir Fraser <keir@xen.org>
Acked-by: Jan Beulich <jbeulich@suse.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Christoph Egger <chegger@amazon.de>
---
 docs/man/xl.cfg.pod.5            |    8 +++++++-
 tools/libxl/libxl_dom.c          |    4 ++++
 tools/libxl/libxl_types.idl      |    1 +
 xen/arch/x86/hvm/viridian.c      |   29 ++++++++++++++++++++++++-----
 xen/arch/x86/time.c              |    4 ++--
 xen/include/asm-x86/perfc_defn.h |    1 +
 xen/include/asm-x86/time.h       |    4 ++++
 xen/include/public/hvm/params.h  |    9 ++++++++-
 8 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index 1bc7fbc..8bba21c 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -1157,10 +1157,16 @@ This group incorporates the TSC and APIC frequency MSRs. These
 enlightenments can improve performance of Windows 7 and Windows
 Server 2008 R2 onwards.
 
+=item B<time_ref_count>
+
+This group incorporates Partition Time Reference Counter MSR. This
+enlightenment can improve performance of Windows 8 and Windows
+Server 2012 onwards.
+
 =item B<defaults>
 
 This is a special value that enables the default set of groups, which
-is currently the B<base> and B<freq> groups.
+is currently the B<base>, B<freq> and B<time_ref_count> groups.
 
 =item B<all>
 
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 2c500ca..bd21841 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -225,6 +225,7 @@ static int hvm_set_viridian_features(libxl__gc *gc, uint32_t domid,
         /* Enable defaults */
         libxl_bitmap_set(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_BASE);
         libxl_bitmap_set(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_FREQ);
+        libxl_bitmap_set(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_TIME_REF_COUNT);
     }
 
     libxl_for_each_set_bit(v, info->u.hvm.viridian_enable) {
@@ -258,6 +259,9 @@ static int hvm_set_viridian_features(libxl__gc *gc, uint32_t domid,
             mask |= HVMPV_no_freq;
     }
 
+    if (libxl_bitmap_test(&enlightenments, LIBXL_VIRIDIAN_ENLIGHTENMENT_TIME_REF_COUNT))
+        mask |= HVMPV_time_ref_count;
+
     if (mask != 0 &&
         xc_hvm_param_set(CTX->xch,
                          domid,
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 1614b11..90d152f 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -182,6 +182,7 @@ libxl_vendor_device = Enumeration("vendor_device", [
 libxl_viridian_enlightenment = Enumeration("viridian_enlightenment", [
     (0, "base"),
     (1, "freq"),
+    (2, "time_ref_count"),
     ])
 
 #
diff --git a/xen/arch/x86/hvm/viridian.c b/xen/arch/x86/hvm/viridian.c
index 28c4479..6726168 100644
--- a/xen/arch/x86/hvm/viridian.c
+++ b/xen/arch/x86/hvm/viridian.c
@@ -36,11 +36,11 @@
 #define HvNotifyLongSpinWait    8
 
 /* Viridian CPUID 4000003, Viridian MSR availability. */
-#define CPUID3A_MSR_REF_COUNT   (1 << 1)
-#define CPUID3A_MSR_APIC_ACCESS (1 << 4)
-#define CPUID3A_MSR_HYPERCALL   (1 << 5)
-#define CPUID3A_MSR_VP_INDEX    (1 << 6)
-#define CPUID3A_MSR_FREQ        (1 << 11)
+#define CPUID3A_MSR_TIME_REF_COUNT (1 << 1)
+#define CPUID3A_MSR_APIC_ACCESS    (1 << 4)
+#define CPUID3A_MSR_HYPERCALL      (1 << 5)
+#define CPUID3A_MSR_VP_INDEX       (1 << 6)
+#define CPUID3A_MSR_FREQ           (1 << 11)
 
 /* Viridian CPUID 4000004, Implementation Recommendations. */
 #define CPUID4A_MSR_BASED_APIC  (1 << 3)
@@ -93,6 +93,8 @@ int cpuid_viridian_leaves(unsigned int leaf, unsigned int *eax,
                 CPUID3A_MSR_VP_INDEX);
         if ( !(viridian_feature_mask(d) & HVMPV_no_freq) )
             *eax |= CPUID3A_MSR_FREQ;
+        if ( viridian_feature_mask(d) & HVMPV_time_ref_count )
+            *eax |= CPUID3A_MSR_TIME_REF_COUNT;
         break;
     case 4:
         /* Recommended hypercall usage. */
@@ -344,6 +346,23 @@ int rdmsr_viridian_regs(uint32_t idx, uint64_t *val)
         *val = v->arch.hvm_vcpu.viridian.apic_assist.raw;
         break;
 
+    case VIRIDIAN_MSR_TIME_REF_COUNT:
+    {
+        uint64_t tsc;
+        struct time_scale tsc_to_ns;
+
+        if ( !(viridian_feature_mask(d) & HVMPV_time_ref_count) )
+            return 0;
+
+        perfc_incr(mshv_rdmsr_time_ref_count);
+        tsc = hvm_get_guest_tsc(pt_global_vcpu_target(d));
+
+        /* convert tsc to count of 100ns periods */
+        set_time_scale(&tsc_to_ns, d->arch.tsc_khz * 1000ul);
+        *val = scale_delta(tsc, &tsc_to_ns) / 100ul;
+        break;
+    }
+
     default:
         return 0;
     }
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index bd89219..74c01e3 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -121,7 +121,7 @@ static inline u32 mul_frac(u32 multiplicand, u32 multiplier)
  * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
  * yielding a 64-bit result.
  */
-static inline u64 scale_delta(u64 delta, struct time_scale *scale)
+u64 scale_delta(u64 delta, struct time_scale *scale)
 {
     u64 product;
 
@@ -272,7 +272,7 @@ static u64 init_pit_and_calibrate_tsc(void)
     return ((end - start) * (u64)CALIBRATE_FRAC);
 }
 
-static void set_time_scale(struct time_scale *ts, u64 ticks_per_sec)
+void set_time_scale(struct time_scale *ts, u64 ticks_per_sec)
 {
     u64 tps64 = ticks_per_sec;
     u32 tps32;
diff --git a/xen/include/asm-x86/perfc_defn.h b/xen/include/asm-x86/perfc_defn.h
index 7d802cc..170da00 100644
--- a/xen/include/asm-x86/perfc_defn.h
+++ b/xen/include/asm-x86/perfc_defn.h
@@ -120,6 +120,7 @@ PERFCOUNTER(mshv_rdmsr_hc_page,         "MS Hv rdmsr hypercall page")
 PERFCOUNTER(mshv_rdmsr_vp_index,        "MS Hv rdmsr vp index")
 PERFCOUNTER(mshv_rdmsr_tsc_frequency,   "MS Hv rdmsr TSC frequency")
 PERFCOUNTER(mshv_rdmsr_apic_frequency,  "MS Hv rdmsr APIC frequency")
+PERFCOUNTER(mshv_rdmsr_time_ref_count,  "MS Hv rdmsr time ref count")
 PERFCOUNTER(mshv_rdmsr_icr,             "MS Hv rdmsr icr")
 PERFCOUNTER(mshv_rdmsr_tpr,             "MS Hv rdmsr tpr")
 PERFCOUNTER(mshv_rdmsr_apic_assist,     "MS Hv rdmsr APIC assist")
diff --git a/xen/include/asm-x86/time.h b/xen/include/asm-x86/time.h
index 420620e..c4d82f6 100644
--- a/xen/include/asm-x86/time.h
+++ b/xen/include/asm-x86/time.h
@@ -76,4 +76,8 @@ void cpuid_time_leaf(uint32_t sub_idx, uint32_t *eax, uint32_t *ebx,
 
 u64 stime2tsc(s_time_t stime);
 
+struct time_scale;
+void set_time_scale(struct time_scale *ts, u64 ticks_per_sec);
+u64 scale_delta(u64 delta, struct time_scale *scale);
+
 #endif /* __X86_TIME_H__ */
diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h
index 68d26fd..3c51072 100644
--- a/xen/include/public/hvm/params.h
+++ b/xen/include/public/hvm/params.h
@@ -88,7 +88,14 @@
 #define _HVMPV_no_freq 1
 #define HVMPV_no_freq  (1 << _HVMPV_no_freq)
 
-#define HVMPV_feature_mask (HVMPV_base_freq|HVMPV_no_freq)
+/* Enable Partition Time Reference Counter (HV_X64_MSR_TIME_REF_COUNT) */
+#define _HVMPV_time_ref_count 2
+#define HVMPV_time_ref_count  (1 << _HVMPV_time_ref_count)
+
+#define HVMPV_feature_mask \
+	(HVMPV_base_freq | \
+	 HVMPV_no_freq | \
+	 HVMPV_time_ref_count)
 
 #endif
 
-- 
1.7.10.4

  parent reply	other threads:[~2014-09-23 10:40 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-23 10:40 [PATCH v12 0/2] x86/viridian improvements Paul Durrant
2014-09-23 10:40 ` [PATCH v12 1/2] x86/viridian: Re-purpose the HVM parameter to be a feature mask Paul Durrant
2014-09-26 14:06   ` Ian Jackson
2014-09-23 10:40 ` Paul Durrant [this message]
2014-09-26 14:07   ` [PATCH v12 2/2] x86/viridian: Add partition time reference counter MSR support Ian Jackson
2014-09-23 14:31 ` [PATCH v12 0/2] x86/viridian improvements Ian Campbell
2014-09-23 14:36   ` Paul Durrant

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1411468810-40888-3-git-send-email-paul.durrant@citrix.com \
    --to=paul.durrant@citrix.com \
    --cc=chegger@amazon.de \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=keir@xen.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.