* [Xen-devel] [PATCH v2 0/6] Implement Hyper-V reference TSC based clock source
@ 2019-12-18 14:42 Wei Liu
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 1/6] x86: import hyperv-tlfs.h from Linux Wei Liu
` (5 more replies)
0 siblings, 6 replies; 18+ messages in thread
From: Wei Liu @ 2019-12-18 14:42 UTC (permalink / raw)
To: Xen Development List
Cc: Wei Liu, Andrew Cooper, Paul Durrant, Michael Kelley,
Jan Beulich, Roger Pau Monné
Hi all
This series adds a clock source based on Hyper-V's reference TSC. The
meat is in the last patch. I also put in some clean up patches to Xen's
viridian code per Paul's request.
With this series, Xen on Hyper-V no longer runs on emulated PIT.
(XEN) Platform timer is 2294.686MHz HYPER-V REFERENCE TSC
Wei.
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Wei Liu <liuwe@microsoft.com>
Cc: Roger Pau Monné <roger.pau@citrix.com>
Cc: Paul Durrant <pdurrant@amazon.com>
Wei Liu (6):
x86: import hyperv-tlfs.h from Linux
x86/viridian: drop duplicate defines from private.h and viridian.c
x86/viridian: drop private copy of definitions from synic.c
x86/viridian: drop private copy of HV_REFERENCE_TSC_PAGE in time.c
x86/hyperv: extract more information from Hyper-V
x86: implement Hyper-V clock source
xen/arch/x86/guest/hyperv/hyperv.c | 17 +
xen/arch/x86/hvm/viridian/private.h | 66 --
xen/arch/x86/hvm/viridian/synic.c | 68 +-
xen/arch/x86/hvm/viridian/time.c | 30 +-
xen/arch/x86/hvm/viridian/viridian.c | 23 +-
xen/arch/x86/time.c | 101 +++
xen/include/asm-x86/guest/hyperv-tlfs.h | 907 ++++++++++++++++++++++++
xen/include/asm-x86/guest/hyperv.h | 12 +
8 files changed, 1070 insertions(+), 154 deletions(-)
create mode 100644 xen/include/asm-x86/guest/hyperv-tlfs.h
--
2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Xen-devel] [PATCH v2 1/6] x86: import hyperv-tlfs.h from Linux
2019-12-18 14:42 [Xen-devel] [PATCH v2 0/6] Implement Hyper-V reference TSC based clock source Wei Liu
@ 2019-12-18 14:42 ` Wei Liu
2019-12-18 14:56 ` Durrant, Paul
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 2/6] x86/viridian: drop duplicate defines from private.h and viridian.c Wei Liu
` (4 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Wei Liu @ 2019-12-18 14:42 UTC (permalink / raw)
To: Xen Development List
Cc: Wei Liu, Wei Liu, Andrew Cooper, Paul Durrant, Michael Kelley,
Jan Beulich, Roger Pau Monné
Take a pristine copy from Linux commit b2d8b167e15bb5ec2691d1119c025630a247f649.
Do the following to fix it up for Xen:
1. include xen/types.h and xen/bitops.h
2. fix up invocations of BIT macro
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
xen/include/asm-x86/guest/hyperv-tlfs.h | 907 ++++++++++++++++++++++++
1 file changed, 907 insertions(+)
create mode 100644 xen/include/asm-x86/guest/hyperv-tlfs.h
diff --git a/xen/include/asm-x86/guest/hyperv-tlfs.h b/xen/include/asm-x86/guest/hyperv-tlfs.h
new file mode 100644
index 0000000000..ccd9850b27
--- /dev/null
+++ b/xen/include/asm-x86/guest/hyperv-tlfs.h
@@ -0,0 +1,907 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file contains definitions from Hyper-V Hypervisor Top-Level Functional
+ * Specification (TLFS):
+ * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs
+ */
+
+#ifndef _ASM_X86_HYPERV_TLFS_H
+#define _ASM_X86_HYPERV_TLFS_H
+
+#include <xen/bitops.h>
+#include <xen/types.h>
+#include <asm/page.h>
+
+/*
+ * While not explicitly listed in the TLFS, Hyper-V always runs with a page size
+ * of 4096. These definitions are used when communicating with Hyper-V using
+ * guest physical pages and guest physical page addresses, since the guest page
+ * size may not be 4096 on all architectures.
+ */
+#define HV_HYP_PAGE_SHIFT 12
+#define HV_HYP_PAGE_SIZE BIT(HV_HYP_PAGE_SHIFT, UL)
+#define HV_HYP_PAGE_MASK (~(HV_HYP_PAGE_SIZE - 1))
+
+/*
+ * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
+ * is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
+ */
+#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS 0x40000000
+#define HYPERV_CPUID_INTERFACE 0x40000001
+#define HYPERV_CPUID_VERSION 0x40000002
+#define HYPERV_CPUID_FEATURES 0x40000003
+#define HYPERV_CPUID_ENLIGHTMENT_INFO 0x40000004
+#define HYPERV_CPUID_IMPLEMENT_LIMITS 0x40000005
+#define HYPERV_CPUID_NESTED_FEATURES 0x4000000A
+
+#define HYPERV_HYPERVISOR_PRESENT_BIT 0x80000000
+#define HYPERV_CPUID_MIN 0x40000005
+#define HYPERV_CPUID_MAX 0x4000ffff
+
+/*
+ * Feature identification. EAX indicates which features are available
+ * to the partition based upon the current partition privileges.
+ * These are HYPERV_CPUID_FEATURES.EAX bits.
+ */
+
+/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */
+#define HV_X64_MSR_VP_RUNTIME_AVAILABLE BIT(0, UL)
+/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
+#define HV_MSR_TIME_REF_COUNT_AVAILABLE BIT(1, UL)
+/*
+ * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
+ * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
+ */
+#define HV_X64_MSR_SYNIC_AVAILABLE BIT(2, UL)
+/*
+ * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through
+ * HV_X64_MSR_STIMER3_COUNT) available
+ */
+#define HV_MSR_SYNTIMER_AVAILABLE BIT(3, UL)
+/*
+ * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
+ * are available
+ */
+#define HV_X64_MSR_APIC_ACCESS_AVAILABLE BIT(4, UL)
+/* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/
+#define HV_X64_MSR_HYPERCALL_AVAILABLE BIT(5, UL)
+/* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/
+#define HV_X64_MSR_VP_INDEX_AVAILABLE BIT(6, UL)
+/* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/
+#define HV_X64_MSR_RESET_AVAILABLE BIT(7, UL)
+/*
+ * Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE,
+ * HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE,
+ * HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available
+ */
+#define HV_X64_MSR_STAT_PAGES_AVAILABLE BIT(8, UL)
+/* Partition reference TSC MSR is available */
+#define HV_MSR_REFERENCE_TSC_AVAILABLE BIT(9, UL)
+/* Partition Guest IDLE MSR is available */
+#define HV_X64_MSR_GUEST_IDLE_AVAILABLE BIT(10, UL)
+/*
+ * There is a single feature flag that signifies if the partition has access
+ * to MSRs with local APIC and TSC frequencies.
+ */
+#define HV_X64_ACCESS_FREQUENCY_MSRS BIT(11, UL)
+/* AccessReenlightenmentControls privilege */
+#define HV_X64_ACCESS_REENLIGHTENMENT BIT(13, UL)
+
+/*
+ * Feature identification: indicates which flags were specified at partition
+ * creation. The format is the same as the partition creation flag structure
+ * defined in section Partition Creation Flags.
+ * These are HYPERV_CPUID_FEATURES.EBX bits.
+ */
+#define HV_X64_CREATE_PARTITIONS BIT(0, UL)
+#define HV_X64_ACCESS_PARTITION_ID BIT(1, UL)
+#define HV_X64_ACCESS_MEMORY_POOL BIT(2, UL)
+#define HV_X64_ADJUST_MESSAGE_BUFFERS BIT(3, UL)
+#define HV_X64_POST_MESSAGES BIT(4, UL)
+#define HV_X64_SIGNAL_EVENTS BIT(5, UL)
+#define HV_X64_CREATE_PORT BIT(6, UL)
+#define HV_X64_CONNECT_PORT BIT(7, UL)
+#define HV_X64_ACCESS_STATS BIT(8, UL)
+#define HV_X64_DEBUGGING BIT(11, UL)
+#define HV_X64_CPU_POWER_MANAGEMENT BIT(12, UL)
+
+/*
+ * Feature identification. EDX indicates which miscellaneous features
+ * are available to the partition.
+ * These are HYPERV_CPUID_FEATURES.EDX bits.
+ */
+/* The MWAIT instruction is available (per section MONITOR / MWAIT) */
+#define HV_X64_MWAIT_AVAILABLE BIT(0, UL)
+/* Guest debugging support is available */
+#define HV_X64_GUEST_DEBUGGING_AVAILABLE BIT(1, UL)
+/* Performance Monitor support is available*/
+#define HV_X64_PERF_MONITOR_AVAILABLE BIT(2, UL)
+/* Support for physical CPU dynamic partitioning events is available*/
+#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE BIT(3, UL)
+/*
+ * Support for passing hypercall input parameter block via XMM
+ * registers is available
+ */
+#define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE BIT(4, UL)
+/* Support for a virtual guest idle state is available */
+#define HV_X64_GUEST_IDLE_STATE_AVAILABLE BIT(5, UL)
+/* Frequency MSRs available */
+#define HV_FEATURE_FREQUENCY_MSRS_AVAILABLE BIT(8, UL)
+/* Crash MSR available */
+#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE BIT(10, UL)
+/* stimer Direct Mode is available */
+#define HV_STIMER_DIRECT_MODE_AVAILABLE BIT(19, UL)
+
+/*
+ * Implementation recommendations. Indicates which behaviors the hypervisor
+ * recommends the OS implement for optimal performance.
+ * These are HYPERV_CPUID_ENLIGHTMENT_INFO.EAX bits.
+ */
+/*
+ * Recommend using hypercall for address space switches rather
+ * than MOV to CR3 instruction
+ */
+#define HV_X64_AS_SWITCH_RECOMMENDED BIT(0, UL)
+/* Recommend using hypercall for local TLB flushes rather
+ * than INVLPG or MOV to CR3 instructions */
+#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED BIT(1, UL)
+/*
+ * Recommend using hypercall for remote TLB flushes rather
+ * than inter-processor interrupts
+ */
+#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED BIT(2, UL)
+/*
+ * Recommend using MSRs for accessing APIC registers
+ * EOI, ICR and TPR rather than their memory-mapped counterparts
+ */
+#define HV_X64_APIC_ACCESS_RECOMMENDED BIT(3, UL)
+/* Recommend using the hypervisor-provided MSR to initiate a system RESET */
+#define HV_X64_SYSTEM_RESET_RECOMMENDED BIT(4, UL)
+/*
+ * Recommend using relaxed timing for this partition. If used,
+ * the VM should disable any watchdog timeouts that rely on the
+ * timely delivery of external interrupts
+ */
+#define HV_X64_RELAXED_TIMING_RECOMMENDED BIT(5, UL)
+
+/*
+ * Recommend not using Auto End-Of-Interrupt feature
+ */
+#define HV_DEPRECATING_AEOI_RECOMMENDED BIT(9, UL)
+
+/*
+ * Recommend using cluster IPI hypercalls.
+ */
+#define HV_X64_CLUSTER_IPI_RECOMMENDED BIT(10, UL)
+
+/* Recommend using the newer ExProcessorMasks interface */
+#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED BIT(11, UL)
+
+/* Recommend using enlightened VMCS */
+#define HV_X64_ENLIGHTENED_VMCS_RECOMMENDED BIT(14, UL)
+
+/*
+ * Virtual processor will never share a physical core with another virtual
+ * processor, except for virtual processors that are reported as sibling SMT
+ * threads.
+ */
+#define HV_X64_NO_NONARCH_CORESHARING BIT(18, UL)
+
+/* Nested features. These are HYPERV_CPUID_NESTED_FEATURES.EAX bits. */
+#define HV_X64_NESTED_DIRECT_FLUSH BIT(17, UL)
+#define HV_X64_NESTED_GUEST_MAPPING_FLUSH BIT(18, UL)
+#define HV_X64_NESTED_MSR_BITMAP BIT(19, UL)
+
+/* Hyper-V specific model specific registers (MSRs) */
+
+/* MSR used to identify the guest OS. */
+#define HV_X64_MSR_GUEST_OS_ID 0x40000000
+
+/* MSR used to setup pages used to communicate with the hypervisor. */
+#define HV_X64_MSR_HYPERCALL 0x40000001
+
+/* MSR used to provide vcpu index */
+#define HV_X64_MSR_VP_INDEX 0x40000002
+
+/* MSR used to reset the guest OS. */
+#define HV_X64_MSR_RESET 0x40000003
+
+/* MSR used to provide vcpu runtime in 100ns units */
+#define HV_X64_MSR_VP_RUNTIME 0x40000010
+
+/* MSR used to read the per-partition time reference counter */
+#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
+
+/* A partition's reference time stamp counter (TSC) page */
+#define HV_X64_MSR_REFERENCE_TSC 0x40000021
+
+/* MSR used to retrieve the TSC frequency */
+#define HV_X64_MSR_TSC_FREQUENCY 0x40000022
+
+/* MSR used to retrieve the local APIC timer frequency */
+#define HV_X64_MSR_APIC_FREQUENCY 0x40000023
+
+/* Define the virtual APIC registers */
+#define HV_X64_MSR_EOI 0x40000070
+#define HV_X64_MSR_ICR 0x40000071
+#define HV_X64_MSR_TPR 0x40000072
+#define HV_X64_MSR_VP_ASSIST_PAGE 0x40000073
+
+/* Define synthetic interrupt controller model specific registers. */
+#define HV_X64_MSR_SCONTROL 0x40000080
+#define HV_X64_MSR_SVERSION 0x40000081
+#define HV_X64_MSR_SIEFP 0x40000082
+#define HV_X64_MSR_SIMP 0x40000083
+#define HV_X64_MSR_EOM 0x40000084
+#define HV_X64_MSR_SINT0 0x40000090
+#define HV_X64_MSR_SINT1 0x40000091
+#define HV_X64_MSR_SINT2 0x40000092
+#define HV_X64_MSR_SINT3 0x40000093
+#define HV_X64_MSR_SINT4 0x40000094
+#define HV_X64_MSR_SINT5 0x40000095
+#define HV_X64_MSR_SINT6 0x40000096
+#define HV_X64_MSR_SINT7 0x40000097
+#define HV_X64_MSR_SINT8 0x40000098
+#define HV_X64_MSR_SINT9 0x40000099
+#define HV_X64_MSR_SINT10 0x4000009A
+#define HV_X64_MSR_SINT11 0x4000009B
+#define HV_X64_MSR_SINT12 0x4000009C
+#define HV_X64_MSR_SINT13 0x4000009D
+#define HV_X64_MSR_SINT14 0x4000009E
+#define HV_X64_MSR_SINT15 0x4000009F
+
+/*
+ * Synthetic Timer MSRs. Four timers per vcpu.
+ */
+#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0
+#define HV_X64_MSR_STIMER0_COUNT 0x400000B1
+#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2
+#define HV_X64_MSR_STIMER1_COUNT 0x400000B3
+#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4
+#define HV_X64_MSR_STIMER2_COUNT 0x400000B5
+#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
+#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
+
+/* Hyper-V guest idle MSR */
+#define HV_X64_MSR_GUEST_IDLE 0x400000F0
+
+/* Hyper-V guest crash notification MSR's */
+#define HV_X64_MSR_CRASH_P0 0x40000100
+#define HV_X64_MSR_CRASH_P1 0x40000101
+#define HV_X64_MSR_CRASH_P2 0x40000102
+#define HV_X64_MSR_CRASH_P3 0x40000103
+#define HV_X64_MSR_CRASH_P4 0x40000104
+#define HV_X64_MSR_CRASH_CTL 0x40000105
+
+/* TSC emulation after migration */
+#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106
+#define HV_X64_MSR_TSC_EMULATION_CONTROL 0x40000107
+#define HV_X64_MSR_TSC_EMULATION_STATUS 0x40000108
+
+/*
+ * Declare the MSR used to setup pages used to communicate with the hypervisor.
+ */
+union hv_x64_msr_hypercall_contents {
+ u64 as_uint64;
+ struct {
+ u64 enable:1;
+ u64 reserved:11;
+ u64 guest_physical_address:52;
+ } __packed;
+};
+
+/*
+ * TSC page layout.
+ */
+struct ms_hyperv_tsc_page {
+ volatile u32 tsc_sequence;
+ u32 reserved1;
+ volatile u64 tsc_scale;
+ volatile s64 tsc_offset;
+ u64 reserved2[509];
+} __packed;
+
+/*
+ * The guest OS needs to register the guest ID with the hypervisor.
+ * The guest ID is a 64 bit entity and the structure of this ID is
+ * specified in the Hyper-V specification:
+ *
+ * msdn.microsoft.com/en-us/library/windows/hardware/ff542653%28v=vs.85%29.aspx
+ *
+ * While the current guideline does not specify how Linux guest ID(s)
+ * need to be generated, our plan is to publish the guidelines for
+ * Linux and other guest operating systems that currently are hosted
+ * on Hyper-V. The implementation here conforms to this yet
+ * unpublished guidelines.
+ *
+ *
+ * Bit(s)
+ * 63 - Indicates if the OS is Open Source or not; 1 is Open Source
+ * 62:56 - Os Type; Linux is 0x100
+ * 55:48 - Distro specific identification
+ * 47:16 - Linux kernel version number
+ * 15:0 - Distro specific identification
+ *
+ *
+ */
+
+#define HV_LINUX_VENDOR_ID 0x8100
+
+struct hv_reenlightenment_control {
+ __u64 vector:8;
+ __u64 reserved1:8;
+ __u64 enabled:1;
+ __u64 reserved2:15;
+ __u64 target_vp:32;
+} __packed;
+
+struct hv_tsc_emulation_control {
+ __u64 enabled:1;
+ __u64 reserved:63;
+} __packed;
+
+struct hv_tsc_emulation_status {
+ __u64 inprogress:1;
+ __u64 reserved:63;
+} __packed;
+
+#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001
+#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12
+#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \
+ (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
+
+/*
+ * Crash notification (HV_X64_MSR_CRASH_CTL) flags.
+ */
+#define HV_CRASH_CTL_CRASH_NOTIFY_MSG BIT_ULL(62)
+#define HV_CRASH_CTL_CRASH_NOTIFY BIT_ULL(63)
+#define HV_X64_MSR_CRASH_PARAMS \
+ (1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0))
+
+#define HV_IPI_LOW_VECTOR 0x10
+#define HV_IPI_HIGH_VECTOR 0xff
+
+/* Declare the various hypercall operations. */
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
+#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HVCALL_SEND_IPI 0x000b
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
+#define HVCALL_SEND_IPI_EX 0x0015
+#define HVCALL_POST_MESSAGE 0x005c
+#define HVCALL_SIGNAL_EVENT 0x005d
+#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
+#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
+
+#define HV_X64_MSR_VP_ASSIST_PAGE_ENABLE 0x00000001
+#define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT 12
+#define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_MASK \
+ (~((1ull << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT) - 1))
+
+/* Hyper-V Enlightened VMCS version mask in nested features CPUID */
+#define HV_X64_ENLIGHTENED_VMCS_VERSION 0xff
+
+#define HV_X64_MSR_TSC_REFERENCE_ENABLE 0x00000001
+#define HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT 12
+
+#define HV_PROCESSOR_POWER_STATE_C0 0
+#define HV_PROCESSOR_POWER_STATE_C1 1
+#define HV_PROCESSOR_POWER_STATE_C2 2
+#define HV_PROCESSOR_POWER_STATE_C3 3
+
+#define HV_FLUSH_ALL_PROCESSORS BIT(0, UL)
+#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1, UL)
+#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2, UL)
+#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3, UL)
+
+enum HV_GENERIC_SET_FORMAT {
+ HV_GENERIC_SET_SPARSE_4K,
+ HV_GENERIC_SET_ALL,
+};
+
+#define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0)
+#define HV_HYPERCALL_FAST_BIT BIT(16, UL)
+#define HV_HYPERCALL_VARHEAD_OFFSET 17
+#define HV_HYPERCALL_REP_COMP_OFFSET 32
+#define HV_HYPERCALL_REP_COMP_MASK GENMASK_ULL(43, 32)
+#define HV_HYPERCALL_REP_START_OFFSET 48
+#define HV_HYPERCALL_REP_START_MASK GENMASK_ULL(59, 48)
+
+/* hypercall status code */
+#define HV_STATUS_SUCCESS 0
+#define HV_STATUS_INVALID_HYPERCALL_CODE 2
+#define HV_STATUS_INVALID_HYPERCALL_INPUT 3
+#define HV_STATUS_INVALID_ALIGNMENT 4
+#define HV_STATUS_INVALID_PARAMETER 5
+#define HV_STATUS_INSUFFICIENT_MEMORY 11
+#define HV_STATUS_INVALID_PORT_ID 17
+#define HV_STATUS_INVALID_CONNECTION_ID 18
+#define HV_STATUS_INSUFFICIENT_BUFFERS 19
+
+/*
+ * The Hyper-V TimeRefCount register and the TSC
+ * page provide a guest VM clock with 100ns tick rate
+ */
+#define HV_CLOCK_HZ (NSEC_PER_SEC/100)
+
+typedef struct _HV_REFERENCE_TSC_PAGE {
+ __u32 tsc_sequence;
+ __u32 res1;
+ __u64 tsc_scale;
+ __s64 tsc_offset;
+} __packed HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
+
+/* Define the number of synthetic interrupt sources. */
+#define HV_SYNIC_SINT_COUNT (16)
+/* Define the expected SynIC version. */
+#define HV_SYNIC_VERSION_1 (0x1)
+/* Valid SynIC vectors are 16-255. */
+#define HV_SYNIC_FIRST_VALID_VECTOR (16)
+
+#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SINT_MASKED (1ULL << 16)
+#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
+#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
+
+#define HV_SYNIC_STIMER_COUNT (4)
+
+/* Define synthetic interrupt controller message constants. */
+#define HV_MESSAGE_SIZE (256)
+#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
+#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
+
+/* Define hypervisor message types. */
+enum hv_message_type {
+ HVMSG_NONE = 0x00000000,
+
+ /* Memory access messages. */
+ HVMSG_UNMAPPED_GPA = 0x80000000,
+ HVMSG_GPA_INTERCEPT = 0x80000001,
+
+ /* Timer notification messages. */
+ HVMSG_TIMER_EXPIRED = 0x80000010,
+
+ /* Error messages. */
+ HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
+ HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021,
+ HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
+
+ /* Trace buffer complete messages. */
+ HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040,
+
+ /* Platform-specific processor intercept messages. */
+ HVMSG_X64_IOPORT_INTERCEPT = 0x80010000,
+ HVMSG_X64_MSR_INTERCEPT = 0x80010001,
+ HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
+ HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003,
+ HVMSG_X64_APIC_EOI = 0x80010004,
+ HVMSG_X64_LEGACY_FP_ERROR = 0x80010005
+};
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+ __u8 asu8;
+ struct {
+ __u8 msg_pending:1;
+ __u8 reserved:7;
+ } __packed;
+};
+
+/* Define port identifier type. */
+union hv_port_id {
+ __u32 asu32;
+ struct {
+ __u32 id:24;
+ __u32 reserved:8;
+ } __packed u;
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+ __u32 message_type;
+ __u8 payload_size;
+ union hv_message_flags message_flags;
+ __u8 reserved[2];
+ union {
+ __u64 sender;
+ union hv_port_id port;
+ };
+} __packed;
+
+/* Define synthetic interrupt controller message format. */
+struct hv_message {
+ struct hv_message_header header;
+ union {
+ __u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+ } u;
+} __packed;
+
+/* Define the synthetic interrupt message page layout. */
+struct hv_message_page {
+ struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
+} __packed;
+
+/* Define timer message payload structure. */
+struct hv_timer_message_payload {
+ __u32 timer_index;
+ __u32 reserved;
+ __u64 expiration_time; /* When the timer expired */
+ __u64 delivery_time; /* When the message was delivered */
+} __packed;
+
+struct hv_nested_enlightenments_control {
+ struct {
+ __u32 directhypercall:1;
+ __u32 reserved:31;
+ } features;
+ struct {
+ __u32 reserved;
+ } hypercallControls;
+} __packed;
+
+/* Define virtual processor assist page structure. */
+struct hv_vp_assist_page {
+ __u32 apic_assist;
+ __u32 reserved1;
+ __u64 vtl_control[3];
+ struct hv_nested_enlightenments_control nested_control;
+ __u8 enlighten_vmentry;
+ __u8 reserved2[7];
+ __u64 current_nested_vmcs;
+} __packed;
+
+struct hv_enlightened_vmcs {
+ u32 revision_id;
+ u32 abort;
+
+ u16 host_es_selector;
+ u16 host_cs_selector;
+ u16 host_ss_selector;
+ u16 host_ds_selector;
+ u16 host_fs_selector;
+ u16 host_gs_selector;
+ u16 host_tr_selector;
+
+ u16 padding16_1;
+
+ u64 host_ia32_pat;
+ u64 host_ia32_efer;
+
+ u64 host_cr0;
+ u64 host_cr3;
+ u64 host_cr4;
+
+ u64 host_ia32_sysenter_esp;
+ u64 host_ia32_sysenter_eip;
+ u64 host_rip;
+ u32 host_ia32_sysenter_cs;
+
+ u32 pin_based_vm_exec_control;
+ u32 vm_exit_controls;
+ u32 secondary_vm_exec_control;
+
+ u64 io_bitmap_a;
+ u64 io_bitmap_b;
+ u64 msr_bitmap;
+
+ u16 guest_es_selector;
+ u16 guest_cs_selector;
+ u16 guest_ss_selector;
+ u16 guest_ds_selector;
+ u16 guest_fs_selector;
+ u16 guest_gs_selector;
+ u16 guest_ldtr_selector;
+ u16 guest_tr_selector;
+
+ u32 guest_es_limit;
+ u32 guest_cs_limit;
+ u32 guest_ss_limit;
+ u32 guest_ds_limit;
+ u32 guest_fs_limit;
+ u32 guest_gs_limit;
+ u32 guest_ldtr_limit;
+ u32 guest_tr_limit;
+ u32 guest_gdtr_limit;
+ u32 guest_idtr_limit;
+
+ u32 guest_es_ar_bytes;
+ u32 guest_cs_ar_bytes;
+ u32 guest_ss_ar_bytes;
+ u32 guest_ds_ar_bytes;
+ u32 guest_fs_ar_bytes;
+ u32 guest_gs_ar_bytes;
+ u32 guest_ldtr_ar_bytes;
+ u32 guest_tr_ar_bytes;
+
+ u64 guest_es_base;
+ u64 guest_cs_base;
+ u64 guest_ss_base;
+ u64 guest_ds_base;
+ u64 guest_fs_base;
+ u64 guest_gs_base;
+ u64 guest_ldtr_base;
+ u64 guest_tr_base;
+ u64 guest_gdtr_base;
+ u64 guest_idtr_base;
+
+ u64 padding64_1[3];
+
+ u64 vm_exit_msr_store_addr;
+ u64 vm_exit_msr_load_addr;
+ u64 vm_entry_msr_load_addr;
+
+ u64 cr3_target_value0;
+ u64 cr3_target_value1;
+ u64 cr3_target_value2;
+ u64 cr3_target_value3;
+
+ u32 page_fault_error_code_mask;
+ u32 page_fault_error_code_match;
+
+ u32 cr3_target_count;
+ u32 vm_exit_msr_store_count;
+ u32 vm_exit_msr_load_count;
+ u32 vm_entry_msr_load_count;
+
+ u64 tsc_offset;
+ u64 virtual_apic_page_addr;
+ u64 vmcs_link_pointer;
+
+ u64 guest_ia32_debugctl;
+ u64 guest_ia32_pat;
+ u64 guest_ia32_efer;
+
+ u64 guest_pdptr0;
+ u64 guest_pdptr1;
+ u64 guest_pdptr2;
+ u64 guest_pdptr3;
+
+ u64 guest_pending_dbg_exceptions;
+ u64 guest_sysenter_esp;
+ u64 guest_sysenter_eip;
+
+ u32 guest_activity_state;
+ u32 guest_sysenter_cs;
+
+ u64 cr0_guest_host_mask;
+ u64 cr4_guest_host_mask;
+ u64 cr0_read_shadow;
+ u64 cr4_read_shadow;
+ u64 guest_cr0;
+ u64 guest_cr3;
+ u64 guest_cr4;
+ u64 guest_dr7;
+
+ u64 host_fs_base;
+ u64 host_gs_base;
+ u64 host_tr_base;
+ u64 host_gdtr_base;
+ u64 host_idtr_base;
+ u64 host_rsp;
+
+ u64 ept_pointer;
+
+ u16 virtual_processor_id;
+ u16 padding16_2[3];
+
+ u64 padding64_2[5];
+ u64 guest_physical_address;
+
+ u32 vm_instruction_error;
+ u32 vm_exit_reason;
+ u32 vm_exit_intr_info;
+ u32 vm_exit_intr_error_code;
+ u32 idt_vectoring_info_field;
+ u32 idt_vectoring_error_code;
+ u32 vm_exit_instruction_len;
+ u32 vmx_instruction_info;
+
+ u64 exit_qualification;
+ u64 exit_io_instruction_ecx;
+ u64 exit_io_instruction_esi;
+ u64 exit_io_instruction_edi;
+ u64 exit_io_instruction_eip;
+
+ u64 guest_linear_address;
+ u64 guest_rsp;
+ u64 guest_rflags;
+
+ u32 guest_interruptibility_info;
+ u32 cpu_based_vm_exec_control;
+ u32 exception_bitmap;
+ u32 vm_entry_controls;
+ u32 vm_entry_intr_info_field;
+ u32 vm_entry_exception_error_code;
+ u32 vm_entry_instruction_len;
+ u32 tpr_threshold;
+
+ u64 guest_rip;
+
+ u32 hv_clean_fields;
+ u32 hv_padding_32;
+ u32 hv_synthetic_controls;
+ struct {
+ u32 nested_flush_hypercall:1;
+ u32 msr_bitmap:1;
+ u32 reserved:30;
+ } __packed hv_enlightenments_control;
+ u32 hv_vp_id;
+
+ u64 hv_vm_id;
+ u64 partition_assist_page;
+ u64 padding64_4[4];
+ u64 guest_bndcfgs;
+ u64 padding64_5[7];
+ u64 xss_exit_bitmap;
+ u64 padding64_6[7];
+} __packed;
+
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE 0
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_IO_BITMAP BIT(0, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP BIT(1, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP2 BIT(2, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_GRP1 BIT(3, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_PROC BIT(4, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EVENT BIT(5, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_ENTRY BIT(6, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_EXCPN BIT(7, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_CRDR BIT(8, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_CONTROL_XLAT BIT(9, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_BASIC BIT(10, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1 BIT(11, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2 BIT(12, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_POINTER BIT(13, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_HOST_GRP1 BIT(14, UL)
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_ENLIGHTENMENTSCONTROL BIT(15, UL)
+
+#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL 0xFFFF
+
+/* Define synthetic interrupt controller flag constants. */
+#define HV_EVENT_FLAGS_COUNT (256 * 8)
+#define HV_EVENT_FLAGS_LONG_COUNT (256 / sizeof(unsigned long))
+
+/*
+ * Synthetic timer configuration.
+ */
+union hv_stimer_config {
+ u64 as_uint64;
+ struct {
+ u64 enable:1;
+ u64 periodic:1;
+ u64 lazy:1;
+ u64 auto_enable:1;
+ u64 apic_vector:8;
+ u64 direct_mode:1;
+ u64 reserved_z0:3;
+ u64 sintx:4;
+ u64 reserved_z1:44;
+ } __packed;
+};
+
+
+/* Define the synthetic interrupt controller event flags format. */
+union hv_synic_event_flags {
+ unsigned long flags[HV_EVENT_FLAGS_LONG_COUNT];
+};
+
+/* Define SynIC control register. */
+union hv_synic_scontrol {
+ u64 as_uint64;
+ struct {
+ u64 enable:1;
+ u64 reserved:63;
+ } __packed;
+};
+
+/* Define synthetic interrupt source. */
+union hv_synic_sint {
+ u64 as_uint64;
+ struct {
+ u64 vector:8;
+ u64 reserved1:8;
+ u64 masked:1;
+ u64 auto_eoi:1;
+ u64 reserved2:46;
+ } __packed;
+};
+
+/* Define the format of the SIMP register */
+union hv_synic_simp {
+ u64 as_uint64;
+ struct {
+ u64 simp_enabled:1;
+ u64 preserved:11;
+ u64 base_simp_gpa:52;
+ } __packed;
+};
+
+/* Define the format of the SIEFP register */
+union hv_synic_siefp {
+ u64 as_uint64;
+ struct {
+ u64 siefp_enabled:1;
+ u64 preserved:11;
+ u64 base_siefp_gpa:52;
+ } __packed;
+};
+
+struct hv_vpset {
+ u64 format;
+ u64 valid_bank_mask;
+ u64 bank_contents[];
+} __packed;
+
+/* HvCallSendSyntheticClusterIpi hypercall */
+struct hv_send_ipi {
+ u32 vector;
+ u32 reserved;
+ u64 cpu_mask;
+} __packed;
+
+/* HvCallSendSyntheticClusterIpiEx hypercall */
+struct hv_send_ipi_ex {
+ u32 vector;
+ u32 reserved;
+ struct hv_vpset vp_set;
+} __packed;
+
+/* HvFlushGuestPhysicalAddressSpace hypercalls */
+struct hv_guest_mapping_flush {
+ u64 address_space;
+ u64 flags;
+} __packed;
+
+/*
+ * HV_MAX_FLUSH_PAGES = "additional_pages" + 1. It's limited
+ * by the bitwidth of "additional_pages" in union hv_gpa_page_range.
+ */
+#define HV_MAX_FLUSH_PAGES (2048)
+
+/* HvFlushGuestPhysicalAddressList hypercall */
+union hv_gpa_page_range {
+ u64 address_space;
+ struct {
+ u64 additional_pages:11;
+ u64 largepage:1;
+ u64 basepfn:52;
+ } page;
+};
+
+/*
+ * All input flush parameters should be in single page. The max flush
+ * count is equal with how many entries of union hv_gpa_page_range can
+ * be populated into the input parameter page.
+ */
+#define HV_MAX_FLUSH_REP_COUNT ((HV_HYP_PAGE_SIZE - 2 * sizeof(u64)) / \
+ sizeof(union hv_gpa_page_range))
+
+struct hv_guest_mapping_flush_list {
+ u64 address_space;
+ u64 flags;
+ union hv_gpa_page_range gpa_list[HV_MAX_FLUSH_REP_COUNT];
+};
+
+/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
+struct hv_tlb_flush {
+ u64 address_space;
+ u64 flags;
+ u64 processor_mask;
+ u64 gva_list[];
+} __packed;
+
+/* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */
+struct hv_tlb_flush_ex {
+ u64 address_space;
+ u64 flags;
+ struct hv_vpset hv_vp_set;
+ u64 gva_list[];
+} __packed;
+
+struct hv_partition_assist_pg {
+ u32 tlb_lock_count;
+};
+#endif
--
2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Xen-devel] [PATCH v2 2/6] x86/viridian: drop duplicate defines from private.h and viridian.c
2019-12-18 14:42 [Xen-devel] [PATCH v2 0/6] Implement Hyper-V reference TSC based clock source Wei Liu
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 1/6] x86: import hyperv-tlfs.h from Linux Wei Liu
@ 2019-12-18 14:42 ` Wei Liu
2019-12-18 14:49 ` Durrant, Paul
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 3/6] x86/viridian: drop private copy of definitions from synic.c Wei Liu
` (3 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Wei Liu @ 2019-12-18 14:42 UTC (permalink / raw)
To: Xen Development List
Cc: Wei Liu, Wei Liu, Paul Durrant, Andrew Cooper, Paul Durrant,
Michael Kelley, Jan Beulich, Roger Pau Monné
No functional change intended.
Signed-off-by: Wei Liu <liuwe@microsoft.com>
---
xen/arch/x86/hvm/viridian/private.h | 66 ----------------------------
xen/arch/x86/hvm/viridian/viridian.c | 23 +++-------
2 files changed, 6 insertions(+), 83 deletions(-)
diff --git a/xen/arch/x86/hvm/viridian/private.h b/xen/arch/x86/hvm/viridian/private.h
index c272c34cda..958a2814c2 100644
--- a/xen/arch/x86/hvm/viridian/private.h
+++ b/xen/arch/x86/hvm/viridian/private.h
@@ -5,72 +5,6 @@
#include <asm/hvm/save.h>
-/* Viridian MSR numbers. */
-#define HV_X64_MSR_GUEST_OS_ID 0x40000000
-#define HV_X64_MSR_HYPERCALL 0x40000001
-#define HV_X64_MSR_VP_INDEX 0x40000002
-#define HV_X64_MSR_RESET 0x40000003
-#define HV_X64_MSR_VP_RUNTIME 0x40000010
-#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
-#define HV_X64_MSR_REFERENCE_TSC 0x40000021
-#define HV_X64_MSR_TSC_FREQUENCY 0x40000022
-#define HV_X64_MSR_APIC_FREQUENCY 0x40000023
-#define HV_X64_MSR_EOI 0x40000070
-#define HV_X64_MSR_ICR 0x40000071
-#define HV_X64_MSR_TPR 0x40000072
-#define HV_X64_MSR_VP_ASSIST_PAGE 0x40000073
-#define HV_X64_MSR_SCONTROL 0x40000080
-#define HV_X64_MSR_SVERSION 0x40000081
-#define HV_X64_MSR_SIEFP 0x40000082
-#define HV_X64_MSR_SIMP 0x40000083
-#define HV_X64_MSR_EOM 0x40000084
-#define HV_X64_MSR_SINT0 0x40000090
-#define HV_X64_MSR_SINT1 0x40000091
-#define HV_X64_MSR_SINT2 0x40000092
-#define HV_X64_MSR_SINT3 0x40000093
-#define HV_X64_MSR_SINT4 0x40000094
-#define HV_X64_MSR_SINT5 0x40000095
-#define HV_X64_MSR_SINT6 0x40000096
-#define HV_X64_MSR_SINT7 0x40000097
-#define HV_X64_MSR_SINT8 0x40000098
-#define HV_X64_MSR_SINT9 0x40000099
-#define HV_X64_MSR_SINT10 0x4000009A
-#define HV_X64_MSR_SINT11 0x4000009B
-#define HV_X64_MSR_SINT12 0x4000009C
-#define HV_X64_MSR_SINT13 0x4000009D
-#define HV_X64_MSR_SINT14 0x4000009E
-#define HV_X64_MSR_SINT15 0x4000009F
-#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0
-#define HV_X64_MSR_STIMER0_COUNT 0x400000B1
-#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2
-#define HV_X64_MSR_STIMER1_COUNT 0x400000B3
-#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4
-#define HV_X64_MSR_STIMER2_COUNT 0x400000B5
-#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
-#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
-#define HV_X64_MSR_POWER_STATE_TRIGGER_C1 0x400000C1
-#define HV_X64_MSR_POWER_STATE_TRIGGER_C2 0x400000C2
-#define HV_X64_MSR_POWER_STATE_TRIGGER_C3 0x400000C3
-#define HV_X64_MSR_POWER_STATE_CONFIG_C1 0x400000D1
-#define HV_X64_MSR_POWER_STATE_CONFIG_C2 0x400000D2
-#define HV_X64_MSR_POWER_STATE_CONFIG_C3 0x400000D3
-#define HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE 0x400000E0
-#define HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE 0x400000E1
-#define HV_X64_MSR_STATS_VP_RETAIL_PAGE 0x400000E2
-#define HV_X64_MSR_STATS_VP_INTERNAL_PAGE 0x400000E3
-#define HV_X64_MSR_GUEST_IDLE 0x400000F0
-#define HV_X64_MSR_SYNTH_DEBUG_CONTROL 0x400000F1
-#define HV_X64_MSR_SYNTH_DEBUG_STATUS 0x400000F2
-#define HV_X64_MSR_SYNTH_DEBUG_SEND_BUFFER 0x400000F3
-#define HV_X64_MSR_SYNTH_DEBUG_RECEIVE_BUFFER 0x400000F4
-#define HV_X64_MSR_SYNTH_DEBUG_PENDING_BUFFER 0x400000F5
-#define HV_X64_MSR_CRASH_P0 0x40000100
-#define HV_X64_MSR_CRASH_P1 0x40000101
-#define HV_X64_MSR_CRASH_P2 0x40000102
-#define HV_X64_MSR_CRASH_P3 0x40000103
-#define HV_X64_MSR_CRASH_P4 0x40000104
-#define HV_X64_MSR_CRASH_CTL 0x40000105
-
int viridian_synic_wrmsr(struct vcpu *v, uint32_t idx, uint64_t val);
int viridian_synic_rdmsr(const struct vcpu *v, uint32_t idx, uint64_t *val);
diff --git a/xen/arch/x86/hvm/viridian/viridian.c b/xen/arch/x86/hvm/viridian/viridian.c
index 4b06b78a27..76f6b6510b 100644
--- a/xen/arch/x86/hvm/viridian/viridian.c
+++ b/xen/arch/x86/hvm/viridian/viridian.c
@@ -10,6 +10,7 @@
#include <xen/hypercall.h>
#include <xen/domain_page.h>
#include <asm/guest_access.h>
+#include <asm/guest/hyperv-tlfs.h>
#include <asm/paging.h>
#include <asm/p2m.h>
#include <asm/apic.h>
@@ -19,22 +20,10 @@
#include "private.h"
-/* Viridian Hypercall Status Codes. */
-#define HV_STATUS_SUCCESS 0x0000
-#define HV_STATUS_INVALID_HYPERCALL_CODE 0x0002
-#define HV_STATUS_INVALID_PARAMETER 0x0005
-
/* Viridian Hypercall Codes. */
-#define HvFlushVirtualAddressSpace 0x0002
-#define HvFlushVirtualAddressList 0x0003
-#define HvNotifyLongSpinWait 0x0008
-#define HvSendSyntheticClusterIpi 0x000b
#define HvGetPartitionId 0x0046
#define HvExtCallQueryCapabilities 0x8001
-/* Viridian Hypercall Flags. */
-#define HV_FLUSH_ALL_PROCESSORS 1
-
/* Viridian Partition Privilege Flags */
typedef struct {
/* Access to virtual MSRs */
@@ -214,7 +203,7 @@ void cpuid_viridian_leaves(const struct vcpu *v, uint32_t leaf,
/*
* This value is the recommended number of attempts to try to
* acquire a spinlock before notifying the hypervisor via the
- * HvNotifyLongSpinWait hypercall.
+ * HVCALL_NOTIFY_LONG_SPIN_WAIT hypercall.
*/
res->b = viridian_spinlock_retry_count;
break;
@@ -583,7 +572,7 @@ int viridian_hypercall(struct cpu_user_regs *regs)
switch ( input.call_code )
{
- case HvNotifyLongSpinWait:
+ case HVCALL_NOTIFY_LONG_SPIN_WAIT:
/*
* See section 14.5.1 of the specification.
*/
@@ -591,8 +580,8 @@ int viridian_hypercall(struct cpu_user_regs *regs)
status = HV_STATUS_SUCCESS;
break;
- case HvFlushVirtualAddressSpace:
- case HvFlushVirtualAddressList:
+ case HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE:
+ case HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST:
{
struct {
uint64_t address_space;
@@ -632,7 +621,7 @@ int viridian_hypercall(struct cpu_user_regs *regs)
break;
}
- case HvSendSyntheticClusterIpi:
+ case HVCALL_SEND_IPI:
{
struct vcpu *v;
uint32_t vector;
--
2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Xen-devel] [PATCH v2 3/6] x86/viridian: drop private copy of definitions from synic.c
2019-12-18 14:42 [Xen-devel] [PATCH v2 0/6] Implement Hyper-V reference TSC based clock source Wei Liu
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 1/6] x86: import hyperv-tlfs.h from Linux Wei Liu
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 2/6] x86/viridian: drop duplicate defines from private.h and viridian.c Wei Liu
@ 2019-12-18 14:42 ` Wei Liu
2019-12-18 14:57 ` Durrant, Paul
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 4/6] x86/viridian: drop private copy of HV_REFERENCE_TSC_PAGE in time.c Wei Liu
` (2 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Wei Liu @ 2019-12-18 14:42 UTC (permalink / raw)
To: Xen Development List
Cc: Wei Liu, Wei Liu, Paul Durrant, Andrew Cooper, Paul Durrant,
Michael Kelley, Jan Beulich, Roger Pau Monné
Use hyperv-tlfs.h instead. No functional change intended.
Signed-off-by: Wei Liu <liuwe@microsoft.com>
---
xen/arch/x86/hvm/viridian/synic.c | 68 ++++++++-----------------------
1 file changed, 16 insertions(+), 52 deletions(-)
diff --git a/xen/arch/x86/hvm/viridian/synic.c b/xen/arch/x86/hvm/viridian/synic.c
index 2791021bcc..54c62f843f 100644
--- a/xen/arch/x86/hvm/viridian/synic.c
+++ b/xen/arch/x86/hvm/viridian/synic.c
@@ -12,58 +12,22 @@
#include <xen/version.h>
#include <asm/apic.h>
+#include <asm/guest/hyperv-tlfs.h>
#include <asm/hvm/support.h>
#include <asm/hvm/vlapic.h>
#include "private.h"
-typedef struct _HV_VIRTUAL_APIC_ASSIST
-{
- uint32_t no_eoi:1;
- uint32_t reserved_zero:31;
-} HV_VIRTUAL_APIC_ASSIST;
-
-typedef union _HV_VP_ASSIST_PAGE
-{
- HV_VIRTUAL_APIC_ASSIST ApicAssist;
- uint8_t ReservedZBytePadding[PAGE_SIZE];
-} HV_VP_ASSIST_PAGE;
-
-typedef enum HV_MESSAGE_TYPE {
- HvMessageTypeNone,
- HvMessageTimerExpired = 0x80000010,
-} HV_MESSAGE_TYPE;
-
-typedef struct HV_MESSAGE_FLAGS {
- uint8_t MessagePending:1;
- uint8_t Reserved:7;
-} HV_MESSAGE_FLAGS;
-
-typedef struct HV_MESSAGE_HEADER {
- HV_MESSAGE_TYPE MessageType;
- uint16_t Reserved1;
- HV_MESSAGE_FLAGS MessageFlags;
- uint8_t PayloadSize;
- uint64_t Reserved2;
-} HV_MESSAGE_HEADER;
-
-#define HV_MESSAGE_SIZE 256
-#define HV_MESSAGE_MAX_PAYLOAD_QWORD_COUNT 30
-
-typedef struct HV_MESSAGE {
- HV_MESSAGE_HEADER Header;
- uint64_t Payload[HV_MESSAGE_MAX_PAYLOAD_QWORD_COUNT];
-} HV_MESSAGE;
void __init __maybe_unused build_assertions(void)
{
- BUILD_BUG_ON(sizeof(HV_MESSAGE) != HV_MESSAGE_SIZE);
+ BUILD_BUG_ON(sizeof(struct hv_message) != HV_MESSAGE_SIZE);
}
void viridian_apic_assist_set(const struct vcpu *v)
{
struct viridian_vcpu *vv = v->arch.hvm.viridian;
- HV_VP_ASSIST_PAGE *ptr = vv->vp_assist.ptr;
+ struct hv_vp_assist_page *ptr = vv->vp_assist.ptr;
if ( !ptr )
return;
@@ -77,18 +41,18 @@ void viridian_apic_assist_set(const struct vcpu *v)
domain_crash(v->domain);
vv->apic_assist_pending = true;
- ptr->ApicAssist.no_eoi = 1;
+ ptr->apic_assist = 1;
}
bool viridian_apic_assist_completed(const struct vcpu *v)
{
struct viridian_vcpu *vv = v->arch.hvm.viridian;
- HV_VP_ASSIST_PAGE *ptr = vv->vp_assist.ptr;
+ struct hv_vp_assist_page *ptr = vv->vp_assist.ptr;
if ( !ptr )
return false;
- if ( vv->apic_assist_pending && !ptr->ApicAssist.no_eoi )
+ if ( vv->apic_assist_pending && !ptr->apic_assist )
{
/* An EOI has been avoided */
vv->apic_assist_pending = false;
@@ -101,12 +65,12 @@ bool viridian_apic_assist_completed(const struct vcpu *v)
void viridian_apic_assist_clear(const struct vcpu *v)
{
struct viridian_vcpu *vv = v->arch.hvm.viridian;
- HV_VP_ASSIST_PAGE *ptr = vv->vp_assist.ptr;
+ struct hv_vp_assist_page *ptr = vv->vp_assist.ptr;
if ( !ptr )
return;
- ptr->ApicAssist.no_eoi = 0;
+ ptr->apic_assist = 0;
vv->apic_assist_pending = false;
}
@@ -358,7 +322,7 @@ bool viridian_synic_deliver_timer_msg(struct vcpu *v, unsigned int sintx,
{
struct viridian_vcpu *vv = v->arch.hvm.viridian;
const union viridian_sint_msr *vs = &vv->sint[sintx];
- HV_MESSAGE *msg = vv->simp.ptr;
+ struct hv_message *msg = vv->simp.ptr;
struct {
uint32_t TimerIndex;
uint32_t Reserved;
@@ -382,19 +346,19 @@ bool viridian_synic_deliver_timer_msg(struct vcpu *v, unsigned int sintx,
msg += sintx;
- if ( msg->Header.MessageType != HvMessageTypeNone )
+ if ( msg->header.message_type != HVMSG_NONE )
{
- msg->Header.MessageFlags.MessagePending = 1;
+ msg->header.message_flags.msg_pending = 1;
__set_bit(sintx, &vv->msg_pending);
return false;
}
- msg->Header.MessageType = HvMessageTimerExpired;
- msg->Header.MessageFlags.MessagePending = 0;
- msg->Header.PayloadSize = sizeof(payload);
+ msg->header.message_type = HVMSG_TIMER_EXPIRED;
+ msg->header.message_flags.msg_pending = 0;
+ msg->header.payload_size = sizeof(payload);
- BUILD_BUG_ON(sizeof(payload) > sizeof(msg->Payload));
- memcpy(msg->Payload, &payload, sizeof(payload));
+ BUILD_BUG_ON(sizeof(payload) > sizeof(msg->u.payload));
+ memcpy(msg->u.payload, &payload, sizeof(payload));
if ( !vs->mask )
vlapic_set_irq(vcpu_vlapic(v), vs->vector, 0);
--
2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Xen-devel] [PATCH v2 4/6] x86/viridian: drop private copy of HV_REFERENCE_TSC_PAGE in time.c
2019-12-18 14:42 [Xen-devel] [PATCH v2 0/6] Implement Hyper-V reference TSC based clock source Wei Liu
` (2 preceding siblings ...)
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 3/6] x86/viridian: drop private copy of definitions from synic.c Wei Liu
@ 2019-12-18 14:42 ` Wei Liu
2019-12-18 15:06 ` Durrant, Paul
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 5/6] x86/hyperv: extract more information from Hyper-V Wei Liu
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source Wei Liu
5 siblings, 1 reply; 18+ messages in thread
From: Wei Liu @ 2019-12-18 14:42 UTC (permalink / raw)
To: Xen Development List
Cc: Wei Liu, Wei Liu, Paul Durrant, Andrew Cooper, Paul Durrant,
Michael Kelley, Jan Beulich, Roger Pau Monné
Use the one defined in hyperv-tlfs.h instead. No functional change
intended.
Signed-off-by: Wei Liu <liuwe@microsoft.com>
---
xen/arch/x86/hvm/viridian/time.c | 30 +++++++++++-------------------
1 file changed, 11 insertions(+), 19 deletions(-)
diff --git a/xen/arch/x86/hvm/viridian/time.c b/xen/arch/x86/hvm/viridian/time.c
index 6ddca29b29..33c15782e4 100644
--- a/xen/arch/x86/hvm/viridian/time.c
+++ b/xen/arch/x86/hvm/viridian/time.c
@@ -13,19 +13,11 @@
#include <asm/apic.h>
#include <asm/event.h>
+#include <asm/guest/hyperv-tlfs.h>
#include <asm/hvm/support.h>
#include "private.h"
-typedef struct _HV_REFERENCE_TSC_PAGE
-{
- uint32_t TscSequence;
- uint32_t Reserved1;
- uint64_t TscScale;
- int64_t TscOffset;
- uint64_t Reserved2[509];
-} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
-
static void update_reference_tsc(const struct domain *d, bool initialize)
{
struct viridian_domain *vd = d->arch.hvm.viridian;
@@ -41,18 +33,18 @@ static void update_reference_tsc(const struct domain *d, bool initialize)
* This enlightenment must be disabled is the host TSC is not invariant.
* However it is also disabled if vtsc is true (which means rdtsc is
* being emulated). This generally happens when guest TSC freq and host
- * TSC freq don't match. The TscScale value could be adjusted to cope
+ * TSC freq don't match. The tsc_scale value could be adjusted to cope
* with this, allowing vtsc to be turned off, but support for this is
* not yet present in the hypervisor. Thus is it is possible that
* migrating a Windows VM between hosts of differing TSC frequencies
* may result in large differences in guest performance. Any jump in
* TSC due to migration down-time can, however, be compensated for by
- * setting the TscOffset value (see below).
+ * setting the tsc_offset value (see below).
*/
if ( !host_tsc_is_safe() || d->arch.vtsc )
{
/*
- * The specification states that valid values of TscSequence range
+ * The specification states that valid values of tsc_sequence range
* from 0 to 0xFFFFFFFE. The value 0xFFFFFFFF is used to indicate
* this mechanism is no longer a reliable source of time and that
* the VM should fall back to a different source.
@@ -61,7 +53,7 @@ static void update_reference_tsc(const struct domain *d, bool initialize)
* violate the spec. and rely on a value of 0 to indicate that this
* enlightenment should no longer be used.
*/
- p->TscSequence = 0;
+ p->tsc_sequence = 0;
printk(XENLOG_G_INFO "d%d: VIRIDIAN REFERENCE_TSC: invalidated\n",
d->domain_id);
@@ -72,29 +64,29 @@ static void update_reference_tsc(const struct domain *d, bool initialize)
* The guest will calculate reference time according to the following
* formula:
*
- * ReferenceTime = ((RDTSC() * TscScale) >> 64) + TscOffset
+ * ReferenceTime = ((RDTSC() * tsc_scale) >> 64) + tsc_offset
*
* Windows uses a 100ns tick, so we need a scale which is cpu
* ticks per 100ns shifted left by 64.
* The offset value is calculated on restore after migration and
* ensures that Windows will not see a large jump in ReferenceTime.
*/
- p->TscScale = ((10000ul << 32) / d->arch.tsc_khz) << 32;
- p->TscOffset = trc->off;
+ p->tsc_scale = ((10000ul << 32) / d->arch.tsc_khz) << 32;
+ p->tsc_offset = trc->off;
smp_wmb();
- seq = p->TscSequence + 1;
+ seq = p->tsc_sequence + 1;
if ( seq == 0xFFFFFFFF || seq == 0 ) /* Avoid both 'invalid' values */
seq = 1;
- p->TscSequence = seq;
+ p->tsc_sequence = seq;
}
/*
* The specification says: "The partition reference time is computed
* by the following formula:
*
- * ReferenceTime = ((VirtualTsc * TscScale) >> 64) + TscOffset
+ * ReferenceTime = ((VirtualTsc * tsc_scale) >> 64) + tsc_offset
*
* The multiplication is a 64 bit multiplication, which results in a
* 128 bit number which is then shifted 64 times to the right to obtain
--
2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Xen-devel] [PATCH v2 5/6] x86/hyperv: extract more information from Hyper-V
2019-12-18 14:42 [Xen-devel] [PATCH v2 0/6] Implement Hyper-V reference TSC based clock source Wei Liu
` (3 preceding siblings ...)
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 4/6] x86/viridian: drop private copy of HV_REFERENCE_TSC_PAGE in time.c Wei Liu
@ 2019-12-18 14:42 ` Wei Liu
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source Wei Liu
5 siblings, 0 replies; 18+ messages in thread
From: Wei Liu @ 2019-12-18 14:42 UTC (permalink / raw)
To: Xen Development List
Cc: Wei Liu, Wei Liu, Andrew Cooper, Paul Durrant, Michael Kelley,
Jan Beulich, Roger Pau Monné
Provide a structure to store that information. The structure will be
accessed from other places later so make it public.
Signed-off-by: Wei Liu <liuwe@microsoft.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
xen/arch/x86/guest/hyperv/hyperv.c | 17 +++++++++++++++++
xen/include/asm-x86/guest/hyperv.h | 12 ++++++++++++
2 files changed, 29 insertions(+)
diff --git a/xen/arch/x86/guest/hyperv/hyperv.c b/xen/arch/x86/guest/hyperv/hyperv.c
index b82ae3833f..2e70b4aa82 100644
--- a/xen/arch/x86/guest/hyperv/hyperv.c
+++ b/xen/arch/x86/guest/hyperv/hyperv.c
@@ -21,6 +21,9 @@
#include <xen/init.h>
#include <asm/guest.h>
+#include <asm/guest/hyperv-tlfs.h>
+
+struct ms_hyperv_info __read_mostly ms_hyperv;
static const struct hypervisor_ops ops = {
.name = "Hyper-V",
@@ -40,6 +43,20 @@ const struct hypervisor_ops *__init hyperv_probe(void)
if ( eax != 0x31237648 ) /* Hv#1 */
return NULL;
+ /* Extract more information from Hyper-V */
+ cpuid(HYPERV_CPUID_FEATURES, &eax, &ebx, &ecx, &edx);
+ ms_hyperv.features = eax;
+ ms_hyperv.misc_features = edx;
+
+ ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
+
+ if ( ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED )
+ ms_hyperv.nested_features = cpuid_eax(HYPERV_CPUID_NESTED_FEATURES);
+
+ cpuid(HYPERV_CPUID_IMPLEMENT_LIMITS, &eax, &ebx, &ecx, &edx);
+ ms_hyperv.max_vp_index = eax;
+ ms_hyperv.max_lp_index = ebx;
+
return &ops;
}
diff --git a/xen/include/asm-x86/guest/hyperv.h b/xen/include/asm-x86/guest/hyperv.h
index 3f88b94c77..cc21b9abfc 100644
--- a/xen/include/asm-x86/guest/hyperv.h
+++ b/xen/include/asm-x86/guest/hyperv.h
@@ -21,8 +21,20 @@
#ifdef CONFIG_HYPERV_GUEST
+#include <xen/types.h>
+
#include <asm/guest/hypervisor.h>
+struct ms_hyperv_info {
+ uint32_t features;
+ uint32_t misc_features;
+ uint32_t hints;
+ uint32_t nested_features;
+ uint32_t max_vp_index;
+ uint32_t max_lp_index;
+};
+extern struct ms_hyperv_info ms_hyperv;
+
const struct hypervisor_ops *hyperv_probe(void);
#else
--
2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source
2019-12-18 14:42 [Xen-devel] [PATCH v2 0/6] Implement Hyper-V reference TSC based clock source Wei Liu
` (4 preceding siblings ...)
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 5/6] x86/hyperv: extract more information from Hyper-V Wei Liu
@ 2019-12-18 14:42 ` Wei Liu
2019-12-18 15:24 ` Durrant, Paul
2019-12-20 16:05 ` Jan Beulich
5 siblings, 2 replies; 18+ messages in thread
From: Wei Liu @ 2019-12-18 14:42 UTC (permalink / raw)
To: Xen Development List
Cc: Wei Liu, Wei Liu, Andrew Cooper, Paul Durrant, Michael Kelley,
Jan Beulich, Roger Pau Monné
Implement a clock source using Hyper-V's reference TSC page.
Signed-off-by: Wei Liu <liuwe@microsoft.com>
---
v2:
1. Address Jan's comments.
Relevant spec:
https://github.com/MicrosoftDocs/Virtualization-Documentation/raw/live/tlfs/Hypervisor%20Top%20Level%20Functional%20Specification%20v5.0C.pdf
Section 12.6.
---
xen/arch/x86/time.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index 216169a025..8b96b2e9a5 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -31,6 +31,7 @@
#include <asm/processor.h>
#include <asm/fixmap.h>
#include <asm/guest.h>
+#include <asm/guest/hyperv-tlfs.h>
#include <asm/mc146818rtc.h>
#include <asm/div64.h>
#include <asm/acpi.h>
@@ -644,6 +645,103 @@ static struct platform_timesource __initdata plt_xen_timer =
};
#endif
+#ifdef CONFIG_HYPERV_GUEST
+/************************************************************
+ * HYPER-V REFERENCE TSC
+ */
+
+static struct ms_hyperv_tsc_page *hyperv_tsc;
+static struct page_info *hyperv_tsc_page;
+
+static int64_t __init init_hyperv_timer(struct platform_timesource *pts)
+{
+ paddr_t maddr;
+ uint64_t tsc_msr, freq;
+
+ if ( !(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE) )
+ return 0;
+
+ hyperv_tsc_page = alloc_domheap_page(NULL, 0);
+ if ( !hyperv_tsc_page )
+ return 0;
+
+ hyperv_tsc = __map_domain_page_global(hyperv_tsc_page);
+ if ( !hyperv_tsc )
+ {
+ free_domheap_page(hyperv_tsc_page);
+ hyperv_tsc_page = NULL;
+ return 0;
+ }
+
+ maddr = page_to_maddr(hyperv_tsc_page);
+
+ /*
+ * Per Hyper-V TLFS:
+ * 1. Read existing MSR value
+ * 2. Preserve bits [11:1]
+ * 3. Set bits [63:12] to be guest physical address of tsc page
+ * 4. Set enabled bit (0)
+ * 5. Write back new MSR value
+ */
+ rdmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr);
+ tsc_msr &= 0xffeULL;
+ tsc_msr |= maddr | 1 /* enabled */;
+ wrmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr);
+
+ /* Get TSC frequency from Hyper-V */
+ rdmsrl(HV_X64_MSR_TSC_FREQUENCY, freq);
+ pts->frequency = freq;
+
+ return freq;
+}
+
+static inline uint64_t read_hyperv_timer(void)
+{
+ uint64_t scale, offset, ret, tsc;
+ uint32_t seq;
+ const struct ms_hyperv_tsc_page *tsc_page = hyperv_tsc;
+
+ do {
+ seq = tsc_page->tsc_sequence;
+
+ /* Seq 0 is special. It means the TSC enlightenment is not
+ * available at the moment. The reference time can only be
+ * obtained from the Reference Counter MSR.
+ */
+ if ( seq == 0 )
+ {
+ rdmsrl(HV_X64_MSR_TIME_REF_COUNT, ret);
+ return ret;
+ }
+
+ /* rdtsc_ordered already contains a load fence */
+ tsc = rdtsc_ordered();
+ scale = tsc_page->tsc_scale;
+ offset = tsc_page->tsc_offset;
+
+ smp_rmb();
+
+ } while (tsc_page->tsc_sequence != seq);
+
+ /* ret = ((tsc * scale) >> 64) + offset; */
+ asm ( "mul %[scale]; add %[offset], %[ret]"
+ : "+a" (tsc), [ret] "=d" (ret)
+ : [scale] "rm" (scale), [offset] "rm" (offset) );
+
+ return ret;
+}
+
+static struct platform_timesource __initdata plt_hyperv_timer =
+{
+ .id = "hyperv",
+ .name = "HYPER-V REFERENCE TSC",
+ .read_counter = read_hyperv_timer,
+ .init = init_hyperv_timer,
+ /* See TSC time source for why counter_bits is set to 63 */
+ .counter_bits = 63,
+};
+#endif
+
/************************************************************
* GENERIC PLATFORM TIMER INFRASTRUCTURE
*/
@@ -793,6 +891,9 @@ static u64 __init init_platform_timer(void)
static struct platform_timesource * __initdata plt_timers[] = {
#ifdef CONFIG_XEN_GUEST
&plt_xen_timer,
+#endif
+#ifdef CONFIG_HYPERV_GUEST
+ &plt_hyperv_timer,
#endif
&plt_hpet, &plt_pmtimer, &plt_pit
};
--
2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 2/6] x86/viridian: drop duplicate defines from private.h and viridian.c
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 2/6] x86/viridian: drop duplicate defines from private.h and viridian.c Wei Liu
@ 2019-12-18 14:49 ` Durrant, Paul
0 siblings, 0 replies; 18+ messages in thread
From: Durrant, Paul @ 2019-12-18 14:49 UTC (permalink / raw)
To: Wei Liu, Xen Development List
Cc: Wei Liu, Paul Durrant, Andrew Cooper, Michael Kelley,
Jan Beulich, Roger Pau Monné
> -----Original Message-----
> From: Wei Liu <wei.liu.xen@gmail.com> On Behalf Of Wei Liu
> Sent: 18 December 2019 14:42
> To: Xen Development List <xen-devel@lists.xenproject.org>
> Cc: Michael Kelley <mikelley@microsoft.com>; Durrant, Paul
> <pdurrant@amazon.com>; Wei Liu <liuwe@microsoft.com>; Paul Durrant
> <paul@xen.org>; Jan Beulich <jbeulich@suse.com>; Andrew Cooper
> <andrew.cooper3@citrix.com>; Wei Liu <wl@xen.org>; Roger Pau Monné
> <roger.pau@citrix.com>
> Subject: [PATCH v2 2/6] x86/viridian: drop duplicate defines from
> private.h and viridian.c
>
> No functional change intended.
>
> Signed-off-by: Wei Liu <liuwe@microsoft.com>
[snip]
> diff --git a/xen/arch/x86/hvm/viridian/viridian.c
> b/xen/arch/x86/hvm/viridian/viridian.c
> index 4b06b78a27..76f6b6510b 100644
> --- a/xen/arch/x86/hvm/viridian/viridian.c
> +++ b/xen/arch/x86/hvm/viridian/viridian.c
> @@ -10,6 +10,7 @@
> #include <xen/hypercall.h>
> #include <xen/domain_page.h>
> #include <asm/guest_access.h>
> +#include <asm/guest/hyperv-tlfs.h>
> #include <asm/paging.h>
> #include <asm/p2m.h>
> #include <asm/apic.h>
> @@ -19,22 +20,10 @@
>
> #include "private.h"
>
> -/* Viridian Hypercall Status Codes. */
> -#define HV_STATUS_SUCCESS 0x0000
> -#define HV_STATUS_INVALID_HYPERCALL_CODE 0x0002
> -#define HV_STATUS_INVALID_PARAMETER 0x0005
> -
> /* Viridian Hypercall Codes. */
> -#define HvFlushVirtualAddressSpace 0x0002
> -#define HvFlushVirtualAddressList 0x0003
> -#define HvNotifyLongSpinWait 0x0008
> -#define HvSendSyntheticClusterIpi 0x000b
> #define HvGetPartitionId 0x0046
> #define HvExtCallQueryCapabilities 0x8001
These ought to be added to hyperv-tlfs.h. After all they are specified in the TLFS.
Paul
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 1/6] x86: import hyperv-tlfs.h from Linux
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 1/6] x86: import hyperv-tlfs.h from Linux Wei Liu
@ 2019-12-18 14:56 ` Durrant, Paul
0 siblings, 0 replies; 18+ messages in thread
From: Durrant, Paul @ 2019-12-18 14:56 UTC (permalink / raw)
To: Wei Liu, Xen Development List
Cc: Andrew Cooper, Roger Pau Monné,
Wei Liu, Jan Beulich, Michael Kelley
> -----Original Message-----
> From: Wei Liu <wei.liu.xen@gmail.com> On Behalf Of Wei Liu
> Sent: 18 December 2019 14:42
> To: Xen Development List <xen-devel@lists.xenproject.org>
> Cc: Michael Kelley <mikelley@microsoft.com>; Durrant, Paul
> <pdurrant@amazon.com>; Wei Liu <liuwe@microsoft.com>; Jan Beulich
> <jbeulich@suse.com>; Andrew Cooper <andrew.cooper3@citrix.com>; Wei Liu
> <wl@xen.org>; Roger Pau Monné <roger.pau@citrix.com>
> Subject: [PATCH v2 1/6] x86: import hyperv-tlfs.h from Linux
>
> Take a pristine copy from Linux commit
> b2d8b167e15bb5ec2691d1119c025630a247f649.
>
> Do the following to fix it up for Xen:
>
> 1. include xen/types.h and xen/bitops.h
> 2. fix up invocations of BIT macro
>
> Signed-off-by: Wei Liu <liuwe@microsoft.com>
> Acked-by: Jan Beulich <jbeulich@suse.com>
[snip]
> +/*
> + * The guest OS needs to register the guest ID with the hypervisor.
> + * The guest ID is a 64 bit entity and the structure of this ID is
> + * specified in the Hyper-V specification:
> + *
> + * msdn.microsoft.com/en-
> us/library/windows/hardware/ff542653%28v=vs.85%29.aspx
> + *
> + * While the current guideline does not specify how Linux guest ID(s)
> + * need to be generated, our plan is to publish the guidelines for
> + * Linux and other guest operating systems that currently are hosted
> + * on Hyper-V. The implementation here conforms to this yet
> + * unpublished guidelines.
> + *
> + *
> + * Bit(s)
> + * 63 - Indicates if the OS is Open Source or not; 1 is Open Source
> + * 62:56 - Os Type; Linux is 0x100
> + * 55:48 - Distro specific identification
> + * 47:16 - Linux kernel version number
> + * 15:0 - Distro specific identification
> + *
> + *
It might be useful to pull the declaration of union viridian_guest_os_id_msr in here since the comment is explaining the format.
Paul
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 3/6] x86/viridian: drop private copy of definitions from synic.c
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 3/6] x86/viridian: drop private copy of definitions from synic.c Wei Liu
@ 2019-12-18 14:57 ` Durrant, Paul
0 siblings, 0 replies; 18+ messages in thread
From: Durrant, Paul @ 2019-12-18 14:57 UTC (permalink / raw)
To: Wei Liu, Xen Development List
Cc: Wei Liu, Paul Durrant, Andrew Cooper, Michael Kelley,
Jan Beulich, Roger Pau Monné
> -----Original Message-----
> From: Wei Liu <wei.liu.xen@gmail.com> On Behalf Of Wei Liu
> Sent: 18 December 2019 14:43
> To: Xen Development List <xen-devel@lists.xenproject.org>
> Cc: Michael Kelley <mikelley@microsoft.com>; Durrant, Paul
> <pdurrant@amazon.com>; Wei Liu <liuwe@microsoft.com>; Paul Durrant
> <paul@xen.org>; Jan Beulich <jbeulich@suse.com>; Andrew Cooper
> <andrew.cooper3@citrix.com>; Wei Liu <wl@xen.org>; Roger Pau Monné
> <roger.pau@citrix.com>
> Subject: [PATCH v2 3/6] x86/viridian: drop private copy of definitions
> from synic.c
>
> Use hyperv-tlfs.h instead. No functional change intended.
>
> Signed-off-by: Wei Liu <liuwe@microsoft.com>
Reviewed-by: Paul Durrant <pdurrant@amazon.com>
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 4/6] x86/viridian: drop private copy of HV_REFERENCE_TSC_PAGE in time.c
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 4/6] x86/viridian: drop private copy of HV_REFERENCE_TSC_PAGE in time.c Wei Liu
@ 2019-12-18 15:06 ` Durrant, Paul
0 siblings, 0 replies; 18+ messages in thread
From: Durrant, Paul @ 2019-12-18 15:06 UTC (permalink / raw)
To: Wei Liu, Xen Development List
Cc: Wei Liu, Paul Durrant, Andrew Cooper, Michael Kelley,
Jan Beulich, Roger Pau Monné
> -----Original Message-----
> From: Wei Liu <wei.liu.xen@gmail.com> On Behalf Of Wei Liu
> Sent: 18 December 2019 14:43
> To: Xen Development List <xen-devel@lists.xenproject.org>
> Cc: Michael Kelley <mikelley@microsoft.com>; Durrant, Paul
> <pdurrant@amazon.com>; Wei Liu <liuwe@microsoft.com>; Paul Durrant
> <paul@xen.org>; Jan Beulich <jbeulich@suse.com>; Andrew Cooper
> <andrew.cooper3@citrix.com>; Wei Liu <wl@xen.org>; Roger Pau Monné
> <roger.pau@citrix.com>
> Subject: [PATCH v2 4/6] x86/viridian: drop private copy of
> HV_REFERENCE_TSC_PAGE in time.c
>
> Use the one defined in hyperv-tlfs.h instead. No functional change
> intended.
>
> Signed-off-by: Wei Liu <liuwe@microsoft.com>
> ---
> xen/arch/x86/hvm/viridian/time.c | 30 +++++++++++-------------------
> 1 file changed, 11 insertions(+), 19 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/viridian/time.c
> b/xen/arch/x86/hvm/viridian/time.c
> index 6ddca29b29..33c15782e4 100644
> --- a/xen/arch/x86/hvm/viridian/time.c
> +++ b/xen/arch/x86/hvm/viridian/time.c
> @@ -13,19 +13,11 @@
>
> #include <asm/apic.h>
> #include <asm/event.h>
> +#include <asm/guest/hyperv-tlfs.h>
> #include <asm/hvm/support.h>
>
> #include "private.h"
>
> -typedef struct _HV_REFERENCE_TSC_PAGE
> -{
> - uint32_t TscSequence;
> - uint32_t Reserved1;
> - uint64_t TscScale;
> - int64_t TscOffset;
> - uint64_t Reserved2[509];
> -} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
> -
> static void update_reference_tsc(const struct domain *d, bool initialize)
> {
> struct viridian_domain *vd = d->arch.hvm.viridian;
> @@ -41,18 +33,18 @@ static void update_reference_tsc(const struct domain
> *d, bool initialize)
> * This enlightenment must be disabled is the host TSC is not
> invariant.
> * However it is also disabled if vtsc is true (which means rdtsc is
> * being emulated). This generally happens when guest TSC freq and
> host
> - * TSC freq don't match. The TscScale value could be adjusted to cope
> + * TSC freq don't match. The tsc_scale value could be adjusted to
> cope
> * with this, allowing vtsc to be turned off, but support for this is
> * not yet present in the hypervisor. Thus is it is possible that
> * migrating a Windows VM between hosts of differing TSC frequencies
> * may result in large differences in guest performance. Any jump in
> * TSC due to migration down-time can, however, be compensated for by
> - * setting the TscOffset value (see below).
> + * setting the tsc_offset value (see below).
> */
> if ( !host_tsc_is_safe() || d->arch.vtsc )
> {
> /*
> - * The specification states that valid values of TscSequence
> range
> + * The specification states that valid values of tsc_sequence
> range
> * from 0 to 0xFFFFFFFE. The value 0xFFFFFFFF is used to indicate
> * this mechanism is no longer a reliable source of time and that
> * the VM should fall back to a different source.
> @@ -61,7 +53,7 @@ static void update_reference_tsc(const struct domain *d,
> bool initialize)
> * violate the spec. and rely on a value of 0 to indicate that
> this
> * enlightenment should no longer be used.
> */
> - p->TscSequence = 0;
> + p->tsc_sequence = 0;
>
> printk(XENLOG_G_INFO "d%d: VIRIDIAN REFERENCE_TSC:
> invalidated\n",
> d->domain_id);
> @@ -72,29 +64,29 @@ static void update_reference_tsc(const struct domain
> *d, bool initialize)
> * The guest will calculate reference time according to the following
> * formula:
> *
> - * ReferenceTime = ((RDTSC() * TscScale) >> 64) + TscOffset
> + * ReferenceTime = ((RDTSC() * tsc_scale) >> 64) + tsc_offset
> *
> * Windows uses a 100ns tick, so we need a scale which is cpu
> * ticks per 100ns shifted left by 64.
> * The offset value is calculated on restore after migration and
> * ensures that Windows will not see a large jump in ReferenceTime.
> */
> - p->TscScale = ((10000ul << 32) / d->arch.tsc_khz) << 32;
> - p->TscOffset = trc->off;
> + p->tsc_scale = ((10000ul << 32) / d->arch.tsc_khz) << 32;
> + p->tsc_offset = trc->off;
> smp_wmb();
>
> - seq = p->TscSequence + 1;
> + seq = p->tsc_sequence + 1;
> if ( seq == 0xFFFFFFFF || seq == 0 ) /* Avoid both 'invalid' values
> */
> seq = 1;
>
> - p->TscSequence = seq;
> + p->tsc_sequence = seq;
> }
>
> /*
> * The specification says: "The partition reference time is computed
> * by the following formula:
> *
> - * ReferenceTime = ((VirtualTsc * TscScale) >> 64) + TscOffset
> + * ReferenceTime = ((VirtualTsc * tsc_scale) >> 64) + tsc_offset
I'd prefer keeping the CamelCase here as it's text lifted from the TLFS and not reliant on the header definitions.
Paul
> *
> * The multiplication is a 64 bit multiplication, which results in a
> * 128 bit number which is then shifted 64 times to the right to obtain
> --
> 2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source Wei Liu
@ 2019-12-18 15:24 ` Durrant, Paul
2019-12-18 20:24 ` Michael Kelley
2019-12-20 16:05 ` Jan Beulich
1 sibling, 1 reply; 18+ messages in thread
From: Durrant, Paul @ 2019-12-18 15:24 UTC (permalink / raw)
To: Wei Liu, Xen Development List
Cc: Andrew Cooper, Roger Pau Monné,
Wei Liu, Jan Beulich, Michael Kelley
> -----Original Message-----
> From: Wei Liu <wei.liu.xen@gmail.com> On Behalf Of Wei Liu
> Sent: 18 December 2019 14:43
> To: Xen Development List <xen-devel@lists.xenproject.org>
> Cc: Michael Kelley <mikelley@microsoft.com>; Durrant, Paul
> <pdurrant@amazon.com>; Wei Liu <liuwe@microsoft.com>; Jan Beulich
> <jbeulich@suse.com>; Andrew Cooper <andrew.cooper3@citrix.com>; Wei Liu
> <wl@xen.org>; Roger Pau Monné <roger.pau@citrix.com>
> Subject: [PATCH v2 6/6] x86: implement Hyper-V clock source
>
> Implement a clock source using Hyper-V's reference TSC page.
>
> Signed-off-by: Wei Liu <liuwe@microsoft.com>
> ---
> v2:
> 1. Address Jan's comments.
>
> Relevant spec:
>
> https://github.com/MicrosoftDocs/Virtualization-
> Documentation/raw/live/tlfs/Hypervisor%20Top%20Level%20Functional%20Specif
> ication%20v5.0C.pdf
>
> Section 12.6.
> ---
> xen/arch/x86/time.c | 101 ++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 101 insertions(+)
>
> diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
> index 216169a025..8b96b2e9a5 100644
> --- a/xen/arch/x86/time.c
> +++ b/xen/arch/x86/time.c
> @@ -31,6 +31,7 @@
> #include <asm/processor.h>
> #include <asm/fixmap.h>
> #include <asm/guest.h>
> +#include <asm/guest/hyperv-tlfs.h>
> #include <asm/mc146818rtc.h>
> #include <asm/div64.h>
> #include <asm/acpi.h>
> @@ -644,6 +645,103 @@ static struct platform_timesource __initdata
> plt_xen_timer =
> };
> #endif
>
> +#ifdef CONFIG_HYPERV_GUEST
> +/************************************************************
> + * HYPER-V REFERENCE TSC
> + */
> +
> +static struct ms_hyperv_tsc_page *hyperv_tsc;
> +static struct page_info *hyperv_tsc_page;
> +
> +static int64_t __init init_hyperv_timer(struct platform_timesource *pts)
> +{
> + paddr_t maddr;
> + uint64_t tsc_msr, freq;
> +
> + if ( !(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE) )
> + return 0;
> +
> + hyperv_tsc_page = alloc_domheap_page(NULL, 0);
> + if ( !hyperv_tsc_page )
> + return 0;
> +
> + hyperv_tsc = __map_domain_page_global(hyperv_tsc_page);
> + if ( !hyperv_tsc )
> + {
> + free_domheap_page(hyperv_tsc_page);
> + hyperv_tsc_page = NULL;
> + return 0;
> + }
> +
> + maddr = page_to_maddr(hyperv_tsc_page);
> +
> + /*
> + * Per Hyper-V TLFS:
> + * 1. Read existing MSR value
> + * 2. Preserve bits [11:1]
> + * 3. Set bits [63:12] to be guest physical address of tsc page
> + * 4. Set enabled bit (0)
> + * 5. Write back new MSR value
> + */
> + rdmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr);
> + tsc_msr &= 0xffeULL;
> + tsc_msr |= maddr | 1 /* enabled */;
> + wrmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr);
> +
You need to check for the HV_X64_ACCESS_FREQUENCY_MSRS feature or you risk a #GP below I think.
> + /* Get TSC frequency from Hyper-V */
> + rdmsrl(HV_X64_MSR_TSC_FREQUENCY, freq);
> + pts->frequency = freq;
> +
> + return freq;
> +}
> +
> +static inline uint64_t read_hyperv_timer(void)
> +{
> + uint64_t scale, offset, ret, tsc;
> + uint32_t seq;
> + const struct ms_hyperv_tsc_page *tsc_page = hyperv_tsc;
> +
> + do {
> + seq = tsc_page->tsc_sequence;
> +
> + /* Seq 0 is special. It means the TSC enlightenment is not
> + * available at the moment. The reference time can only be
> + * obtained from the Reference Counter MSR.
> + */
> + if ( seq == 0 )
Older versions of the spec used to use 0xFFFFFFFF I think, although when I look again they seem to have been retro-actively fixed. In any case I think you should treat both 0xFFFFFFFF and 0 as invalid.
> + {
> + rdmsrl(HV_X64_MSR_TIME_REF_COUNT, ret);
> + return ret;
> + }
> +
> + /* rdtsc_ordered already contains a load fence */
> + tsc = rdtsc_ordered();
> + scale = tsc_page->tsc_scale;
> + offset = tsc_page->tsc_offset;
> +
> + smp_rmb();
> +
> + } while (tsc_page->tsc_sequence != seq);
> +
> + /* ret = ((tsc * scale) >> 64) + offset; */
> + asm ( "mul %[scale]; add %[offset], %[ret]"
> + : "+a" (tsc), [ret] "=d" (ret)
> + : [scale] "rm" (scale), [offset] "rm" (offset) );
> +
It would be nice to common this up with scale_tsc() in viridian/time.c.
Paul
> + return ret;
> +}
> +
> +static struct platform_timesource __initdata plt_hyperv_timer =
> +{
> + .id = "hyperv",
> + .name = "HYPER-V REFERENCE TSC",
> + .read_counter = read_hyperv_timer,
> + .init = init_hyperv_timer,
> + /* See TSC time source for why counter_bits is set to 63 */
> + .counter_bits = 63,
> +};
> +#endif
> +
> /************************************************************
> * GENERIC PLATFORM TIMER INFRASTRUCTURE
> */
> @@ -793,6 +891,9 @@ static u64 __init init_platform_timer(void)
> static struct platform_timesource * __initdata plt_timers[] = {
> #ifdef CONFIG_XEN_GUEST
> &plt_xen_timer,
> +#endif
> +#ifdef CONFIG_HYPERV_GUEST
> + &plt_hyperv_timer,
> #endif
> &plt_hpet, &plt_pmtimer, &plt_pit
> };
> --
> 2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source
2019-12-18 15:24 ` Durrant, Paul
@ 2019-12-18 20:24 ` Michael Kelley
2019-12-18 22:20 ` Wei Liu
0 siblings, 1 reply; 18+ messages in thread
From: Michael Kelley @ 2019-12-18 20:24 UTC (permalink / raw)
To: Durrant, Paul, Wei Liu, Xen Development List
Cc: Andrew Cooper, Wei Liu, Jan Beulich, Roger Pau Monné
From: Durrant, Paul <pdurrant@amazon.com> Sent: Wednesday, December 18, 2019 7:24 AM
> > From: Wei Liu <wei.liu.xen@gmail.com> On Behalf Of Wei Liu
> > Sent: 18 December 2019 14:43
[snip]
> > +
> > +static inline uint64_t read_hyperv_timer(void)
> > +{
> > + uint64_t scale, offset, ret, tsc;
> > + uint32_t seq;
> > + const struct ms_hyperv_tsc_page *tsc_page = hyperv_tsc;
> > +
> > + do {
> > + seq = tsc_page->tsc_sequence;
> > +
> > + /* Seq 0 is special. It means the TSC enlightenment is not
> > + * available at the moment. The reference time can only be
> > + * obtained from the Reference Counter MSR.
> > + */
> > + if ( seq == 0 )
>
> Older versions of the spec used to use 0xFFFFFFFF I think, although when I look again they
> seem to have been retro-actively fixed. In any case I think you should treat both
> 0xFFFFFFFF and 0 as invalid.
FWIW, the 0xFFFFFFFF was just a bug in the spec. Hyper-V implementations only
set the value to 0 to indicate invalid. The equivalent Linux code checks only for 0.
Michael
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source
2019-12-18 20:24 ` Michael Kelley
@ 2019-12-18 22:20 ` Wei Liu
2019-12-19 8:37 ` Durrant, Paul
0 siblings, 1 reply; 18+ messages in thread
From: Wei Liu @ 2019-12-18 22:20 UTC (permalink / raw)
To: Michael Kelley
Cc: Wei Liu, Wei Liu, Andrew Cooper, Durrant, Paul, Jan Beulich,
Xen Development List, Roger Pau Monné
On Wed, 18 Dec 2019 at 20:24, Michael Kelley <mikelley@microsoft.com> wrote:
>
> From: Durrant, Paul <pdurrant@amazon.com> Sent: Wednesday, December 18, 2019 7:24 AM
>
> > > From: Wei Liu <wei.liu.xen@gmail.com> On Behalf Of Wei Liu
> > > Sent: 18 December 2019 14:43
>
> [snip]
>
> > > +
> > > +static inline uint64_t read_hyperv_timer(void)
> > > +{
> > > + uint64_t scale, offset, ret, tsc;
> > > + uint32_t seq;
> > > + const struct ms_hyperv_tsc_page *tsc_page = hyperv_tsc;
> > > +
> > > + do {
> > > + seq = tsc_page->tsc_sequence;
> > > +
> > > + /* Seq 0 is special. It means the TSC enlightenment is not
> > > + * available at the moment. The reference time can only be
> > > + * obtained from the Reference Counter MSR.
> > > + */
> > > + if ( seq == 0 )
> >
> > Older versions of the spec used to use 0xFFFFFFFF I think, although when I look again they
> > seem to have been retro-actively fixed. In any case I think you should treat both
> > 0xFFFFFFFF and 0 as invalid.
>
> FWIW, the 0xFFFFFFFF was just a bug in the spec. Hyper-V implementations only
> set the value to 0 to indicate invalid. The equivalent Linux code checks only for 0.
>
Thanks for chiming in, Michael.
In that case I will submit a fix to change Xen's viridian code to
remove the wrong value there.
Wei.
> Michael
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source
2019-12-18 22:20 ` Wei Liu
@ 2019-12-19 8:37 ` Durrant, Paul
0 siblings, 0 replies; 18+ messages in thread
From: Durrant, Paul @ 2019-12-19 8:37 UTC (permalink / raw)
To: Wei Liu, Michael Kelley
Cc: Xen Development List, Roger Pau Monné,
Wei Liu, Jan Beulich, Andrew Cooper
> -----Original Message-----
> From: Wei Liu <wl@xen.org>
> Sent: 18 December 2019 22:21
> To: Michael Kelley <mikelley@microsoft.com>
> Cc: Durrant, Paul <pdurrant@amazon.com>; Wei Liu <wl@xen.org>; Xen
> Development List <xen-devel@lists.xenproject.org>; Wei Liu
> <liuwe@microsoft.com>; Jan Beulich <jbeulich@suse.com>; Andrew Cooper
> <andrew.cooper3@citrix.com>; Roger Pau Monné <roger.pau@citrix.com>
> Subject: Re: [PATCH v2 6/6] x86: implement Hyper-V clock source
>
> On Wed, 18 Dec 2019 at 20:24, Michael Kelley <mikelley@microsoft.com>
> wrote:
> >
> > From: Durrant, Paul <pdurrant@amazon.com> Sent: Wednesday, December 18,
> 2019 7:24 AM
> >
> > > > From: Wei Liu <wei.liu.xen@gmail.com> On Behalf Of Wei Liu
> > > > Sent: 18 December 2019 14:43
> >
> > [snip]
> >
> > > > +
> > > > +static inline uint64_t read_hyperv_timer(void)
> > > > +{
> > > > + uint64_t scale, offset, ret, tsc;
> > > > + uint32_t seq;
> > > > + const struct ms_hyperv_tsc_page *tsc_page = hyperv_tsc;
> > > > +
> > > > + do {
> > > > + seq = tsc_page->tsc_sequence;
> > > > +
> > > > + /* Seq 0 is special. It means the TSC enlightenment is not
> > > > + * available at the moment. The reference time can only be
> > > > + * obtained from the Reference Counter MSR.
> > > > + */
> > > > + if ( seq == 0 )
> > >
> > > Older versions of the spec used to use 0xFFFFFFFF I think, although
> when I look again they
> > > seem to have been retro-actively fixed. In any case I think you should
> treat both
> > > 0xFFFFFFFF and 0 as invalid.
> >
> > FWIW, the 0xFFFFFFFF was just a bug in the spec. Hyper-V
> implementations only
> > set the value to 0 to indicate invalid. The equivalent Linux code
> checks only for 0.
> >
>
> Thanks for chiming in, Michael.
>
> In that case I will submit a fix to change Xen's viridian code to
> remove the wrong value there.
If no consuming version of Windows is going to be upset seeing all-Fs then that's fine. Thanks for the clarification.
Cheers,
Paul
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source Wei Liu
2019-12-18 15:24 ` Durrant, Paul
@ 2019-12-20 16:05 ` Jan Beulich
2019-12-20 16:07 ` Andrew Cooper
2019-12-20 17:43 ` Wei Liu
1 sibling, 2 replies; 18+ messages in thread
From: Jan Beulich @ 2019-12-20 16:05 UTC (permalink / raw)
To: Wei Liu
Cc: Wei Liu, Andrew Cooper, Paul Durrant, Michael Kelley,
Xen Development List, Roger Pau Monné
On 18.12.2019 15:42, Wei Liu wrote:
> --- a/xen/arch/x86/time.c
> +++ b/xen/arch/x86/time.c
> @@ -31,6 +31,7 @@
> #include <asm/processor.h>
> #include <asm/fixmap.h>
> #include <asm/guest.h>
> +#include <asm/guest/hyperv-tlfs.h>
Can this please move ...
> @@ -644,6 +645,103 @@ static struct platform_timesource __initdata plt_xen_timer =
> };
> #endif
>
> +#ifdef CONFIG_HYPERV_GUEST
... here, to avoid the dependency on the header when the option is
off?
> +/************************************************************
> + * HYPER-V REFERENCE TSC
> + */
> +
> +static struct ms_hyperv_tsc_page *hyperv_tsc;
> +static struct page_info *hyperv_tsc_page;
> +
> +static int64_t __init init_hyperv_timer(struct platform_timesource *pts)
> +{
> + paddr_t maddr;
> + uint64_t tsc_msr, freq;
> +
> + if ( !(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE) )
> + return 0;
> +
> + hyperv_tsc_page = alloc_domheap_page(NULL, 0);
> + if ( !hyperv_tsc_page )
> + return 0;
> +
> + hyperv_tsc = __map_domain_page_global(hyperv_tsc_page);
> + if ( !hyperv_tsc )
> + {
> + free_domheap_page(hyperv_tsc_page);
> + hyperv_tsc_page = NULL;
> + return 0;
> + }
> +
> + maddr = page_to_maddr(hyperv_tsc_page);
> +
> + /*
> + * Per Hyper-V TLFS:
> + * 1. Read existing MSR value
> + * 2. Preserve bits [11:1]
> + * 3. Set bits [63:12] to be guest physical address of tsc page
> + * 4. Set enabled bit (0)
> + * 5. Write back new MSR value
> + */
> + rdmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr);
> + tsc_msr &= 0xffeULL;
There's no real need for the ULL suffix.
> + tsc_msr |= maddr | 1 /* enabled */;
Stray double blank after |= ?
> + wrmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr);
> +
> + /* Get TSC frequency from Hyper-V */
> + rdmsrl(HV_X64_MSR_TSC_FREQUENCY, freq);
> + pts->frequency = freq;
> +
> + return freq;
> +}
> +
> +static inline uint64_t read_hyperv_timer(void)
> +{
> + uint64_t scale, offset, ret, tsc;
> + uint32_t seq;
> + const struct ms_hyperv_tsc_page *tsc_page = hyperv_tsc;
> +
> + do {
> + seq = tsc_page->tsc_sequence;
> +
> + /* Seq 0 is special. It means the TSC enlightenment is not
> + * available at the moment. The reference time can only be
> + * obtained from the Reference Counter MSR.
> + */
> + if ( seq == 0 )
> + {
> + rdmsrl(HV_X64_MSR_TIME_REF_COUNT, ret);
> + return ret;
> + }
> +
> + /* rdtsc_ordered already contains a load fence */
> + tsc = rdtsc_ordered();
> + scale = tsc_page->tsc_scale;
> + offset = tsc_page->tsc_offset;
> +
> + smp_rmb();
> +
> + } while (tsc_page->tsc_sequence != seq);
> +
> + /* ret = ((tsc * scale) >> 64) + offset; */
> + asm ( "mul %[scale]; add %[offset], %[ret]"
> + : "+a" (tsc), [ret] "=d" (ret)
This needs to be "=&d", or else %rdx may be used to address
%[offset] (when in memory).
With these taken care of
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source
2019-12-20 16:05 ` Jan Beulich
@ 2019-12-20 16:07 ` Andrew Cooper
2019-12-20 17:43 ` Wei Liu
1 sibling, 0 replies; 18+ messages in thread
From: Andrew Cooper @ 2019-12-20 16:07 UTC (permalink / raw)
To: Jan Beulich, Wei Liu
Cc: Xen Development List, Paul Durrant, Roger Pau Monné,
Wei Liu, Michael Kelley
On 20/12/2019 16:05, Jan Beulich wrote:
>> + wrmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr);
>> +
>> + /* Get TSC frequency from Hyper-V */
>> + rdmsrl(HV_X64_MSR_TSC_FREQUENCY, freq);
>> + pts->frequency = freq;
>> +
>> + return freq;
>> +}
>> +
>> +static inline uint64_t read_hyperv_timer(void)
>> +{
>> + uint64_t scale, offset, ret, tsc;
>> + uint32_t seq;
>> + const struct ms_hyperv_tsc_page *tsc_page = hyperv_tsc;
>> +
>> + do {
>> + seq = tsc_page->tsc_sequence;
>> +
>> + /* Seq 0 is special. It means the TSC enlightenment is not
>> + * available at the moment. The reference time can only be
>> + * obtained from the Reference Counter MSR.
>> + */
>> + if ( seq == 0 )
>> + {
>> + rdmsrl(HV_X64_MSR_TIME_REF_COUNT, ret);
>> + return ret;
>> + }
>> +
>> + /* rdtsc_ordered already contains a load fence */
>> + tsc = rdtsc_ordered();
>> + scale = tsc_page->tsc_scale;
>> + offset = tsc_page->tsc_offset;
>> +
>> + smp_rmb();
>> +
>> + } while (tsc_page->tsc_sequence != seq);
Style.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source
2019-12-20 16:05 ` Jan Beulich
2019-12-20 16:07 ` Andrew Cooper
@ 2019-12-20 17:43 ` Wei Liu
1 sibling, 0 replies; 18+ messages in thread
From: Wei Liu @ 2019-12-20 17:43 UTC (permalink / raw)
To: Jan Beulich
Cc: Wei Liu, Wei Liu, Andrew Cooper, Paul Durrant, Michael Kelley,
Xen Development List, Roger Pau Monné
On Fri, Dec 20, 2019 at 05:05:24PM +0100, Jan Beulich wrote:
> On 18.12.2019 15:42, Wei Liu wrote:
> > --- a/xen/arch/x86/time.c
> > +++ b/xen/arch/x86/time.c
> > @@ -31,6 +31,7 @@
> > #include <asm/processor.h>
> > #include <asm/fixmap.h>
> > #include <asm/guest.h>
> > +#include <asm/guest/hyperv-tlfs.h>
>
> Can this please move ...
>
> > @@ -644,6 +645,103 @@ static struct platform_timesource __initdata plt_xen_timer =
> > };
> > #endif
> >
> > +#ifdef CONFIG_HYPERV_GUEST
>
> ... here, to avoid the dependency on the header when the option is
> off?
>
> > +/************************************************************
> > + * HYPER-V REFERENCE TSC
> > + */
> > +
> > +static struct ms_hyperv_tsc_page *hyperv_tsc;
> > +static struct page_info *hyperv_tsc_page;
> > +
> > +static int64_t __init init_hyperv_timer(struct platform_timesource *pts)
> > +{
> > + paddr_t maddr;
> > + uint64_t tsc_msr, freq;
> > +
> > + if ( !(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE) )
> > + return 0;
> > +
> > + hyperv_tsc_page = alloc_domheap_page(NULL, 0);
> > + if ( !hyperv_tsc_page )
> > + return 0;
> > +
> > + hyperv_tsc = __map_domain_page_global(hyperv_tsc_page);
> > + if ( !hyperv_tsc )
> > + {
> > + free_domheap_page(hyperv_tsc_page);
> > + hyperv_tsc_page = NULL;
> > + return 0;
> > + }
> > +
> > + maddr = page_to_maddr(hyperv_tsc_page);
> > +
> > + /*
> > + * Per Hyper-V TLFS:
> > + * 1. Read existing MSR value
> > + * 2. Preserve bits [11:1]
> > + * 3. Set bits [63:12] to be guest physical address of tsc page
> > + * 4. Set enabled bit (0)
> > + * 5. Write back new MSR value
> > + */
> > + rdmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr);
> > + tsc_msr &= 0xffeULL;
>
> There's no real need for the ULL suffix.
>
> > + tsc_msr |= maddr | 1 /* enabled */;
>
> Stray double blank after |= ?
>
> > + wrmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr);
> > +
> > + /* Get TSC frequency from Hyper-V */
> > + rdmsrl(HV_X64_MSR_TSC_FREQUENCY, freq);
> > + pts->frequency = freq;
> > +
> > + return freq;
> > +}
> > +
> > +static inline uint64_t read_hyperv_timer(void)
> > +{
> > + uint64_t scale, offset, ret, tsc;
> > + uint32_t seq;
> > + const struct ms_hyperv_tsc_page *tsc_page = hyperv_tsc;
> > +
> > + do {
> > + seq = tsc_page->tsc_sequence;
> > +
> > + /* Seq 0 is special. It means the TSC enlightenment is not
> > + * available at the moment. The reference time can only be
> > + * obtained from the Reference Counter MSR.
> > + */
> > + if ( seq == 0 )
> > + {
> > + rdmsrl(HV_X64_MSR_TIME_REF_COUNT, ret);
> > + return ret;
> > + }
> > +
> > + /* rdtsc_ordered already contains a load fence */
> > + tsc = rdtsc_ordered();
> > + scale = tsc_page->tsc_scale;
> > + offset = tsc_page->tsc_offset;
> > +
> > + smp_rmb();
> > +
> > + } while (tsc_page->tsc_sequence != seq);
> > +
> > + /* ret = ((tsc * scale) >> 64) + offset; */
> > + asm ( "mul %[scale]; add %[offset], %[ret]"
> > + : "+a" (tsc), [ret] "=d" (ret)
>
> This needs to be "=&d", or else %rdx may be used to address
> %[offset] (when in memory).
>
> With these taken care of
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
>
Thanks. I have addressed yours, Andrew's and Paul's comment (checking
HV_X64_ACCESS_FREQUENCY_MSRS) and will push patches that are needed for
this clock source to work (patch 1, 5 and 6).
Patches for cleaning up viridian code (2-4) will be posted separately
with Paul's comments addressed.
Wei.
> Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2019-12-20 17:43 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-18 14:42 [Xen-devel] [PATCH v2 0/6] Implement Hyper-V reference TSC based clock source Wei Liu
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 1/6] x86: import hyperv-tlfs.h from Linux Wei Liu
2019-12-18 14:56 ` Durrant, Paul
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 2/6] x86/viridian: drop duplicate defines from private.h and viridian.c Wei Liu
2019-12-18 14:49 ` Durrant, Paul
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 3/6] x86/viridian: drop private copy of definitions from synic.c Wei Liu
2019-12-18 14:57 ` Durrant, Paul
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 4/6] x86/viridian: drop private copy of HV_REFERENCE_TSC_PAGE in time.c Wei Liu
2019-12-18 15:06 ` Durrant, Paul
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 5/6] x86/hyperv: extract more information from Hyper-V Wei Liu
2019-12-18 14:42 ` [Xen-devel] [PATCH v2 6/6] x86: implement Hyper-V clock source Wei Liu
2019-12-18 15:24 ` Durrant, Paul
2019-12-18 20:24 ` Michael Kelley
2019-12-18 22:20 ` Wei Liu
2019-12-19 8:37 ` Durrant, Paul
2019-12-20 16:05 ` Jan Beulich
2019-12-20 16:07 ` Andrew Cooper
2019-12-20 17:43 ` Wei Liu
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.