All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.