From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paul Durrant Subject: [PATCH v12 2/2] x86/viridian: Add partition time reference counter MSR support Date: Tue, 23 Sep 2014 11:40:10 +0100 Message-ID: <1411468810-40888-3-git-send-email-paul.durrant@citrix.com> References: <1411468810-40888-1-git-send-email-paul.durrant@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1411468810-40888-1-git-send-email-paul.durrant@citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: Keir Fraser , Ian Campbell , Stefano Stabellini , Christoph Egger , Ian Jackson , Paul Durrant List-Id: xen-devel@lists.xenproject.org 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 Cc: Keir Fraser Acked-by: Jan Beulich Cc: Ian Campbell Cc: Ian Jackson Cc: Stefano Stabellini Cc: Christoph Egger --- 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 + +This group incorporates Partition Time Reference Counter MSR. This +enlightenment can improve performance of Windows 8 and Windows +Server 2012 onwards. + =item B This is a special value that enables the default set of groups, which -is currently the B and B groups. +is currently the B, B and B groups. =item B 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